summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-03-24 16:10:15 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-03-24 16:10:15 +0100
commit3b5c0bc0780f1749fed7c07bd8b691400a0282b7 (patch)
tree1022f5553ad5a0aca9b5f3b49ca38a01c2329d20 /src
parentc79918733a194ebbe5a2fe1617c884659f3e4b9f (diff)
parent21f1738a94fc8544ece04b3b1ee03a11986fe59b (diff)
Merge remote-tracking branch 'origin/stable' into dev
Conflicts: src/gui/image/qjpeghandler.cpp Change-Id: I9db3acea7d5c82f5da679c8eaeb29431136665f0
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp169
-rw-r--r--src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro134
-rw-r--r--src/3rdparty/harfbuzz-ng/src/config.h17
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.cc46
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.h8
-rw-r--r--src/3rdparty/harfbuzz.pri121
-rw-r--r--src/3rdparty/harfbuzzng.pri6
-rw-r--r--src/3rdparty/sqlite/shell.c344
-rw-r--r--src/3rdparty/sqlite/sqlite3.c13910
-rw-r--r--src/3rdparty/sqlite/sqlite3.h100
-rw-r--r--src/3rdparty/xkbcommon.pri34
-rw-r--r--src/3rdparty/xkbcommon/NEWS86
-rw-r--r--src/3rdparty/xkbcommon/README47
-rw-r--r--src/3rdparty/xkbcommon/src/atom.c137
-rw-r--r--src/3rdparty/xkbcommon/src/atom.h7
-rw-r--r--src/3rdparty/xkbcommon/src/context-priv.c171
-rw-r--r--src/3rdparty/xkbcommon/src/context.c179
-rw-r--r--src/3rdparty/xkbcommon/src/context.h62
-rw-r--r--src/3rdparty/xkbcommon/src/keymap-priv.c121
-rw-r--r--src/3rdparty/xkbcommon/src/keymap.h29
-rw-r--r--src/3rdparty/xkbcommon/src/keysym-utf.c13
-rw-r--r--src/3rdparty/xkbcommon/src/keysym.c56
-rw-r--r--src/3rdparty/xkbcommon/src/keysym.h6
-rw-r--r--src/3rdparty/xkbcommon/src/ks_tables.h11765
-rw-r--r--src/3rdparty/xkbcommon/src/state.c20
-rw-r--r--src/3rdparty/xkbcommon/src/text.c8
-rw-r--r--src/3rdparty/xkbcommon/src/utils.c107
-rw-r--r--src/3rdparty/xkbcommon/src/utils.h95
-rw-r--r--src/3rdparty/xkbcommon/src/x11/util.c215
-rw-r--r--src/3rdparty/xkbcommon/src/x11/x11-keymap.c1146
-rw-r--r--src/3rdparty/xkbcommon/src/x11/x11-priv.h54
-rw-r--r--src/3rdparty/xkbcommon/src/x11/x11-state.c71
-rw-r--r--src/3rdparty/xkbcommon/src/xkb-keymap.c135
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/action.c91
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c318
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h58
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast.h124
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/compat.c61
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/expr.c170
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/include.c36
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c29
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c22
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keymap.c30
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keywords.c349
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h15
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser.c738
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser.h18
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/rules.c243
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h145
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/scanner.c2982
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/symbols.c122
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/types.c13
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h12
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c38
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h8
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h1
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h166
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h187
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon_workaround.h105
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java2
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java3
-rw-r--r--src/android/java/java.pro14
-rw-r--r--src/android/java/res/layout/splash.xml2
-rw-r--r--src/angle/patches/0014-ANGLE-D3D11-Fix-internal-index-buffer-for-level-9-ha.patch256
-rw-r--r--src/angle/src/d3dcompiler/main.cpp48
-rw-r--r--src/concurrent/doc/src/qtconcurrent-module.qdoc14
-rw-r--r--src/concurrent/qtconcurrentiteratekernel.h2
-rw-r--r--src/corelib/arch/qatomic_armv6.h16
-rw-r--r--src/corelib/doc/qtcore.qdocconf3
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp7
-rw-r--r--src/corelib/global/qglobal.cpp4
-rw-r--r--src/corelib/global/qglobal.h7
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp12
-rw-r--r--src/corelib/global/qnamespace.h2
-rw-r--r--src/corelib/global/qnamespace.qdoc3
-rw-r--r--src/corelib/io/io.pri2
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp48
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp14
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp9
-rw-r--r--src/corelib/io/qloggingregistry.cpp11
-rw-r--r--src/corelib/io/qloggingregistry_p.h1
-rw-r--r--src/corelib/io/qprocess.cpp6
-rw-r--r--src/corelib/io/qprocess_p.h5
-rw-r--r--src/corelib/io/qprocess_unix.cpp85
-rw-r--r--src/corelib/io/qsettings.cpp13
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp1
-rw-r--r--src/corelib/kernel/qcore_unix.cpp43
-rw-r--r--src/corelib/kernel/qcore_unix_p.h8
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp11
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
-rw-r--r--src/corelib/kernel/qjni.cpp16
-rw-r--r--src/corelib/kernel/qmetatype.h7
-rw-r--r--src/corelib/kernel/qobject_impl.h2
-rw-r--r--src/corelib/kernel/qtcore_eval.cpp2
-rw-r--r--src/corelib/tools/qcommandlineparser.cpp72
-rw-r--r--src/corelib/tools/qhash.h24
-rw-r--r--src/corelib/tools/qlist.h9
-rw-r--r--src/corelib/tools/qmap.h9
-rw-r--r--src/corelib/tools/qmargins.cpp12
-rw-r--r--src/corelib/tools/qrect.cpp4
-rw-r--r--src/corelib/tools/qregexp.cpp4
-rw-r--r--src/corelib/tools/qsharedpointer.cpp8
-rw-r--r--src/corelib/tools/qsharedpointer.h2
-rw-r--r--src/corelib/tools/qstring.h11
-rw-r--r--src/corelib/tools/qstringbuilder.h8
-rw-r--r--src/corelib/tools/qtimezoneprivate_mac.mm1
-rw-r--r--src/corelib/tools/qvector.h9
-rw-r--r--src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp2
-rw-r--r--src/gui/image/qjpeghandler.cpp1
-rw-r--r--src/gui/kernel/qevent.cpp10
-rw-r--r--src/gui/kernel/qguiapplication.cpp12
-rw-r--r--src/gui/kernel/qopenglcontext.cpp9
-rw-r--r--src/gui/kernel/qplatformtheme.h1
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp12
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp477
-rw-r--r--src/gui/opengl/qopenglshaderprogram.cpp6
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp14
-rw-r--r--src/gui/opengl/qopengltextureglyphcache.cpp12
-rw-r--r--src/gui/painting/painting.pri4
-rw-r--r--src/gui/painting/qdrawhelper.cpp83
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp7
-rw-r--r--src/gui/painting/qdrawhelper_x86_p.h3
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp273
-rw-r--r--src/gui/painting/qpagedpaintdevice.h160
-rw-r--r--src/gui/painting/qpagedpaintdevice_p.h10
-rw-r--r--src/gui/painting/qpagelayout.cpp971
-rw-r--r--src/gui/painting/qpagelayout.h155
-rw-r--r--src/gui/painting/qpagesize.cpp1882
-rw-r--r--src/gui/painting/qpagesize.h311
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp3
-rw-r--r--src/gui/painting/qpainter.cpp2
-rw-r--r--src/gui/painting/qpdf.cpp104
-rw-r--r--src/gui/painting/qpdf_p.h39
-rw-r--r--src/gui/painting/qpdfwriter.cpp231
-rw-r--r--src/gui/painting/qpdfwriter.h12
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp40
-rw-r--r--src/gui/painting/qregion.cpp2
-rw-r--r--src/gui/text/qcssparser_p.h2
-rw-r--r--src/gui/text/qfontdatabase.cpp91
-rw-r--r--src/gui/text/qfontengine_ft.cpp9
-rw-r--r--src/gui/text/qplatformfontdatabase.cpp32
-rw-r--r--src/gui/text/qplatformfontdatabase.h2
-rw-r--r--src/gui/text/qstatictext.cpp3
-rw-r--r--src/gui/text/qtextengine.cpp4
-rw-r--r--src/gui/text/text.pri2
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp4
-rw-r--r--src/network/access/qhttpnetworkreply.cpp4
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp2
-rw-r--r--src/network/access/qnetworkreplynsurlconnectionimpl.mm1
-rw-r--r--src/network/kernel/qauthenticator.cpp11
-rw-r--r--src/network/socket/qlocalserver_tcp.cpp2
-rw-r--r--src/network/socket/qnativesocketengine_unix.cpp66
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp4
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp10
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager.cpp3
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadermanager_p.h1
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h5
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp17
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h9
-rw-r--r--src/opengl/qgl.cpp22
-rw-r--r--src/opengl/qglfunctions.cpp338
-rw-r--r--src/opengl/qglshaderprogram.cpp6
-rw-r--r--src/platformsupport/cglconvenience/cglconvenience.mm11
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri37
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp1
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp189
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h1
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm49
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h1
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm31
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm2
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm2
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro8
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp20
-rw-r--r--src/plugins/platforminputcontexts/platforminputcontexts.pro5
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp27
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp12
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.h5
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp86
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h7
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.cpp21
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.h3
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp3
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm157
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm28
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm22
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.mm5
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm23
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.h129
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.mm502
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintersupport.h10
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintersupport.mm104
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemsettings.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h15
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm92
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm12
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm40
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm521
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac_p.h26
-rw-r--r--src/plugins/platforms/cocoa/qt_mac_p.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp51
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm62
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm4
-rw-r--r--src/plugins/platforms/ios/quiview_textinput.mm13
-rw-r--r--src/plugins/platforms/qnx/qblackberrytheme.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventthread.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp18
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h1
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.cpp32
-rw-r--r--src/plugins/platforms/winrt/qwinrtbackingstore.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp314
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h19
-rw-r--r--src/plugins/platforms/winrt/qwinrtservices.cpp3
-rw-r--r--src/plugins/platforms/winrt/winrt.pro5
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp15
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp20
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp12
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro5
-rw-r--r--src/plugins/printsupport/cups/cups.pro4
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine.cpp328
-rw-r--r--src/plugins/printsupport/cups/qcupsprintengine_p.h16
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport.cpp109
-rw-r--r--src/plugins/printsupport/cups/qcupsprintersupport_p.h37
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.cpp503
-rw-r--r--src/plugins/printsupport/cups/qppdprintdevice.h124
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintdevice.cpp480
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintdevice.h114
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.cpp45
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintersupport.h14
-rw-r--r--src/plugins/printsupport/windows/windows.pro6
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp701
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix_p.h48
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_win.cpp52
-rw-r--r--src/printsupport/dialogs/qpagesetupwidget.ui14
-rw-r--r--src/printsupport/dialogs/qprintdialog_mac.mm44
-rw-r--r--src/printsupport/dialogs/qprintdialog_unix.cpp167
-rw-r--r--src/printsupport/kernel/kernel.pri5
-rw-r--r--src/printsupport/kernel/qcups.cpp481
-rw-r--r--src/printsupport/kernel/qcups_p.h68
-rw-r--r--src/printsupport/kernel/qpaintengine_alpha.cpp1
-rw-r--r--src/printsupport/kernel/qplatformprintdevice.cpp393
-rw-r--r--src/printsupport/kernel/qplatformprintdevice.h182
-rw-r--r--src/printsupport/kernel/qplatformprintersupport.cpp85
-rw-r--r--src/printsupport/kernel/qplatformprintersupport.h26
-rw-r--r--src/printsupport/kernel/qprint_p.h304
-rw-r--r--src/printsupport/kernel/qprintdevice.cpp255
-rw-r--r--src/printsupport/kernel/qprintdevice_p.h149
-rw-r--r--src/printsupport/kernel/qprintengine.h5
-rw-r--r--src/printsupport/kernel/qprintengine_pdf.cpp164
-rw-r--r--src/printsupport/kernel/qprintengine_pdf_p.h18
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp993
-rw-r--r--src/printsupport/kernel/qprintengine_win_p.h60
-rw-r--r--src/printsupport/kernel/qprinter.cpp713
-rw-r--r--src/printsupport/kernel/qprinter.h167
-rw-r--r--src/printsupport/kernel/qprinter_p.h5
-rw-r--r--src/printsupport/kernel/qprinterinfo.cpp255
-rw-r--r--src/printsupport/kernel/qprinterinfo.h27
-rw-r--r--src/printsupport/kernel/qprinterinfo_p.h23
-rw-r--r--src/printsupport/widgets/qcupsjobwidget.cpp4
-rw-r--r--src/printsupport/widgets/qcupsjobwidget_p.h4
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp35
-rw-r--r--src/sql/kernel/qsqlresult.cpp13
-rw-r--r--src/src.pro12
-rw-r--r--src/testlib/qtestcase.cpp11
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.cpp6
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp72
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h2
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp2
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp10
-rw-r--r--src/widgets/kernel/qapplication.cpp7
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp2
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp2
-rw-r--r--src/widgets/kernel/qtooltip.cpp23
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp6
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp14
-rw-r--r--src/widgets/kernel/qwidgetwindow_qpa_p.h1
-rw-r--r--src/widgets/styles/qcommonstyle.cpp8
-rw-r--r--src/widgets/styles/qfusionstyle.cpp196
-rw-r--r--src/widgets/styles/qgtkstyle.cpp19
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp256
-rw-r--r--src/widgets/styles/qgtkstyle_p_p.h61
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm28
-rw-r--r--src/widgets/styles/qstyle.cpp6
-rw-r--r--src/widgets/styles/qstyle_p.h4
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp8
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp13
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp21
-rw-r--r--src/widgets/styles/qwindowsxpstyle_p_p.h1
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp56
-rw-r--r--src/widgets/widgets/qcombobox.cpp2
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp12
-rw-r--r--src/widgets/widgets/qlineedit_p.h3
-rw-r--r--src/widgets/widgets/qmainwindow.cpp14
-rw-r--r--src/widgets/widgets/qmenu.cpp22
-rw-r--r--src/widgets/widgets/qmenu_p.h4
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp11
-rw-r--r--src/widgets/widgets/qplaintextedit.h1
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp37
-rw-r--r--src/widgets/widgets/qtoolbarlayout_p.h1
-rw-r--r--src/winmain/qtmain_winrt.cpp25
325 files changed, 32043 insertions, 20965 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp
index 31d976dec4..2de477b3bc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp
@@ -1137,6 +1137,84 @@ void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLv
}
}
+template<typename T>
+static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data)
+{
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+}
+
+template<typename T>
+static void fillTriangleFanIndices(GLenum type, unsigned int numTris, const GLvoid *indices, T *data)
+{
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = 0;
+ data[i*3 + 1] = i + 1;
+ data[i*3 + 2] = i + 2;
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ for (unsigned int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+ }
+ break;
+ default: UNREACHABLE();
+ }
+}
+
void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
{
// Get the raw indices for an indexed draw
@@ -1148,10 +1226,12 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
indices = static_cast<const GLubyte*>(storage->getData()) + offset;
}
+ const int indexType = get32BitIndexSupport() ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+
if (!mLineLoopIB)
{
mLineLoopIB = new StreamingIndexBufferInterface(this);
- if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+ if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType))
{
delete mLineLoopIB;
mLineLoopIB = NULL;
@@ -1171,7 +1251,7 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
}
const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
- if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+ if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, indexType))
{
ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
return gl::error(GL_OUT_OF_MEMORY);
@@ -1185,42 +1265,12 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
return gl::error(GL_OUT_OF_MEMORY);
}
- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+ if (indexType == GL_UNSIGNED_SHORT)
+ fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned short*>(mappedMemory));
+ else
+ fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned int*>(mappedMemory));
unsigned int indexBufferOffset = offset;
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
-
if (!mLineLoopIB->unmapBuffer())
{
ERR("Could not unmap index buffer for GL_LINE_LOOP.");
@@ -1251,10 +1301,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
indices = static_cast<const GLubyte*>(storage->getData()) + offset;
}
+ const int indexType = get32BitIndexSupport() ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+
if (!mTriangleFanIB)
{
mTriangleFanIB = new StreamingIndexBufferInterface(this);
- if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+ if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType))
{
delete mTriangleFanIB;
mTriangleFanIB = NULL;
@@ -1276,7 +1328,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
}
const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
- if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+ if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType))
{
ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
return gl::error(GL_OUT_OF_MEMORY);
@@ -1290,45 +1342,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
return gl::error(GL_OUT_OF_MEMORY);
}
- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+ if (indexType == GL_UNSIGNED_SHORT)
+ fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned short*>(mappedMemory));
+ else
+ fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned int*>(mappedMemory));
unsigned int indexBufferOffset = offset;
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = 0;
- data[i*3 + 1] = i + 1;
- data[i*3 + 2] = i + 2;
- }
- break;
- case GL_UNSIGNED_BYTE:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_SHORT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
- }
- break;
- case GL_UNSIGNED_INT:
- for (unsigned int i = 0; i < numTris; i++)
- {
- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
- }
- break;
- default: UNREACHABLE();
- }
if (!mTriangleFanIB->unmapBuffer())
{
diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
new file mode 100644
index 0000000000..7d997d7d8b
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro
@@ -0,0 +1,134 @@
+TARGET = qtharfbuzzng
+TEMPLATE = lib
+
+CONFIG += \
+ static \
+ hide_symbols \
+ exceptions_off rtti_off
+CONFIG -= qt
+
+DESTDIR = $$QT_BUILD_TREE/lib
+
+DEFINES += HAVE_CONFIG_H
+HEADERS += $$PWD/src/config.h
+
+INCLUDEPATH += $$PWD/include
+
+SOURCES += \
+ $$PWD/src/hb-blob.cc \
+ $$PWD/src/hb-buffer.cc \
+ $$PWD/src/hb-buffer-serialize.cc \
+ $$PWD/src/hb-common.cc \
+ $$PWD/src/hb-face.cc \
+ $$PWD/src/hb-font.cc \
+ $$PWD/src/hb-ot-tag.cc \
+ $$PWD/src/hb-set.cc \
+ $$PWD/src/hb-shape.cc \
+ $$PWD/src/hb-shape-plan.cc \
+ $$PWD/src/hb-shaper.cc \
+ $$PWD/src/hb-unicode.cc \
+ $$PWD/src/hb-warning.cc
+
+HEADERS += \
+ $$PWD/src/hb-atomic-private.hh \
+ $$PWD/src/hb-buffer-private.hh \
+ $$PWD/src/hb-buffer-deserialize-json.hh \
+ $$PWD/src/hb-buffer-deserialize-text.hh \
+ $$PWD/src/hb-cache-private.hh \
+ $$PWD/src/hb-face-private.hh \
+ $$PWD/src/hb-font-private.hh \
+ $$PWD/src/hb-mutex-private.hh \
+ $$PWD/src/hb-object-private.hh \
+ $$PWD/src/hb-open-file-private.hh \
+ $$PWD/src/hb-open-type-private.hh \
+ $$PWD/src/hb-ot-head-table.hh \
+ $$PWD/src/hb-ot-hhea-table.hh \
+ $$PWD/src/hb-ot-hmtx-table.hh \
+ $$PWD/src/hb-ot-maxp-table.hh \
+ $$PWD/src/hb-ot-name-table.hh \
+ $$PWD/src/hb-private.hh \
+ $$PWD/src/hb-set-private.hh \
+ $$PWD/src/hb-shape-plan-private.hh \
+ $$PWD/src/hb-shaper-impl-private.hh \
+ $$PWD/src/hb-shaper-list.hh \
+ $$PWD/src/hb-shaper-private.hh \
+ $$PWD/src/hb-unicode-private.hh \
+ $$PWD/src/hb-utf-private.hh
+
+HEADERS += \
+ $$PWD/src/hb.h \
+ $$PWD/src/hb-blob.h \
+ $$PWD/src/hb-buffer.h \
+ $$PWD/src/hb-common.h \
+ $$PWD/src/hb-face.h \
+ $$PWD/src/hb-font.h \
+ $$PWD/src/hb-set.h \
+ $$PWD/src/hb-shape.h \
+ $$PWD/src/hb-shape-plan.h \
+ $$PWD/src/hb-unicode.h \
+ $$PWD/src/hb-version.h
+
+# Open Type
+SOURCES += \
+ $$PWD/src/hb-ot-layout.cc \
+ $$PWD/src/hb-ot-map.cc \
+ $$PWD/src/hb-ot-shape.cc \
+ $$PWD/src/hb-ot-shape-complex-arabic.cc \
+ $$PWD/src/hb-ot-shape-complex-default.cc \
+ $$PWD/src/hb-ot-shape-complex-hangul.cc \
+ $$PWD/src/hb-ot-shape-complex-hebrew.cc \
+ $$PWD/src/hb-ot-shape-complex-indic.cc \
+ $$PWD/src/hb-ot-shape-complex-indic-table.cc \
+ $$PWD/src/hb-ot-shape-complex-myanmar.cc \
+ $$PWD/src/hb-ot-shape-complex-sea.cc \
+ $$PWD/src/hb-ot-shape-complex-thai.cc \
+ $$PWD/src/hb-ot-shape-complex-tibetan.cc \
+ $$PWD/src/hb-ot-shape-fallback.cc \
+ $$PWD/src/hb-ot-shape-normalize.cc
+
+HEADERS += \
+ $$PWD/src/hb-ot-layout-common-private.hh \
+ $$PWD/src/hb-ot-layout-gdef-table.hh \
+ $$PWD/src/hb-ot-layout-gpos-table.hh \
+ $$PWD/src/hb-ot-layout-gsubgpos-private.hh \
+ $$PWD/src/hb-ot-layout-gsub-table.hh \
+ $$PWD/src/hb-ot-layout-jstf-table.hh \
+ $$PWD/src/hb-ot-layout-private.hh \
+ $$PWD/src/hb-ot-map-private.hh \
+ $$PWD/src/hb-ot-shape-complex-arabic-fallback.hh \
+ $$PWD/src/hb-ot-shape-complex-arabic-table.hh \
+ $$PWD/src/hb-ot-shape-complex-indic-machine.hh \
+ $$PWD/src/hb-ot-shape-complex-indic-private.hh \
+ $$PWD/src/hb-ot-shape-complex-myanmar-machine.hh \
+ $$PWD/src/hb-ot-shape-complex-private.hh \
+ $$PWD/src/hb-ot-shape-complex-sea-machine.hh \
+ $$PWD/src/hb-ot-shape-fallback-private.hh \
+ $$PWD/src/hb-ot-shape-normalize-private.hh \
+ $$PWD/src/hb-ot-shape-private.hh
+
+HEADERS += \
+ $$PWD/src/hb-ot.h \
+ $$PWD/src/hb-ot-layout.h \
+ $$PWD/src/hb-ot-shape.h \
+ $$PWD/src/hb-ot-tag.h
+
+mac {
+ # Apple Advanced Typography
+ DEFINES += HAVE_CORETEXT
+
+ SOURCES += \
+ $$PWD/src/hb-coretext.cc
+
+ HEADERS += \
+ $$PWD/src/hb-coretext.h
+
+ ios: \
+ # On iOS CoreText and CoreGraphics are stand-alone frameworks
+ LIBS_PRIVATE += -framework CoreText -framework CoreGraphics
+ else: \
+ # On Mac OS they are part of the ApplicationServices umbrella framework,
+ # even in 10.8 where they were also made available stand-alone.
+ LIBS_PRIVATE += -framework ApplicationServices
+}
+
+TARGET = $$TARGET$$qtPlatformTargetSuffix()
diff --git a/src/3rdparty/harfbuzz-ng/src/config.h b/src/3rdparty/harfbuzz-ng/src/config.h
index db706987fe..cb68ab0e5b 100644
--- a/src/3rdparty/harfbuzz-ng/src/config.h
+++ b/src/3rdparty/harfbuzz-ng/src/config.h
@@ -2,29 +2,14 @@
#define HB_CONFIG_H
#define HAVE_OT
+#define HAVE_ATEXIT
#define HB_NO_MT
#define HB_NO_UNICODE_FUNCS
#define HB_DISABLE_DEPRECATED
-#include <QtCore/qglobal.h>
-
-#ifndef HB_INTERNAL
-# define HB_INTERNAL Q_DECL_HIDDEN
-#endif
-
-#if !defined(QT_NO_DEBUG)
-# define NDEBUG
-#endif
-
// because strdup() is not part of strict Posix, declare it here
extern "C" char *strdup(const char *src);
-#ifndef HAVE_ATEXIT
-# define HAVE_ATEXIT 1
-# include <QtCore/qcoreapplication.h>
-# define atexit qAddPostRoutine
-#endif
-
#endif /* HB_CONFIG_H */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
index 5a34eddecc..40c06371bd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
@@ -32,7 +32,6 @@
#include "hb-coretext.h"
#include "hb-face-private.hh"
-#include <private/qfontengine_p.h>
#ifndef HB_DEBUG_CORETEXT
@@ -44,6 +43,19 @@ HB_SHAPER_DATA_ENSURE_DECLARE(coretext, face)
HB_SHAPER_DATA_ENSURE_DECLARE(coretext, font)
+typedef bool (*qt_get_font_table_func_t) (void *user_data, unsigned int tag, unsigned char *buffer, unsigned int *length);
+
+struct FontEngineFaceData {
+ void *user_data;
+ qt_get_font_table_func_t get_font_table;
+};
+
+struct CoreTextFontEngineData {
+ CTFontRef ctFont;
+ CGFontRef cgFont;
+};
+
+
/*
* shaper face data
*/
@@ -83,25 +95,11 @@ _hb_coretext_shaper_face_data_create (hb_face_t *face)
if (unlikely (!data))
return NULL;
- QFontEngine *fe = (QFontEngine *) ((QFontEngine::FaceData *) face->user_data)->user_data;
- if (fe->type () == QFontEngine::Mac)
- {
- data->cg_font = (CGFontRef) fe->userData ().value<void *> ();
- if (likely (data->cg_font))
- CFRetain (data->cg_font);
- }
- else
- {
- hb_blob_t *blob = hb_face_reference_blob (face);
- unsigned int blob_length;
- const char *blob_data = hb_blob_get_data (blob, &blob_length);
- if (unlikely (!blob_length))
- DEBUG_MSG (CORETEXT, face, "Face has empty blob");
-
- CGDataProviderRef provider = CGDataProviderCreateWithData (blob, blob_data, blob_length, &release_data);
- data->cg_font = CGFontCreateWithDataProvider (provider);
- CGDataProviderRelease (provider);
- }
+ FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data;
+ CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data;
+ data->cg_font = coreTextFontEngineData->cgFont;
+ if (likely (data->cg_font))
+ CFRetain (data->cg_font);
if (unlikely (!data->cg_font)) {
DEBUG_MSG (CORETEXT, face, "Face CGFontCreateWithDataProvider() failed");
@@ -146,9 +144,13 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
return NULL;
hb_face_t *face = font->face;
- hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
- data->ct_font = CTFontCreateWithGraphicsFont (face_data->cg_font, font->y_scale / 64, NULL, NULL);
+ FontEngineFaceData *fontEngineFaceData = (FontEngineFaceData *) face->user_data;
+ CoreTextFontEngineData *coreTextFontEngineData = (CoreTextFontEngineData *) fontEngineFaceData->user_data;
+ data->ct_font = coreTextFontEngineData->ctFont;
+ if (likely (data->ct_font))
+ CFRetain (data->ct_font);
+
if (unlikely (!data->ct_font)) {
DEBUG_MSG (CORETEXT, font, "Font CTFontCreateWithGraphicsFont() failed");
free (data);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
index bcf1de7141..aa4bf69a52 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.h
@@ -29,7 +29,13 @@
#include "hb.h"
-#include <ApplicationServices/ApplicationServices.h>
+#include <TargetConditionals.h>
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+# include <CoreText/CoreText.h>
+# include <CoreGraphics/CoreGraphics.h>
+#else
+# include <ApplicationServices/ApplicationServices.h>
+#endif
HB_BEGIN_DECLS
diff --git a/src/3rdparty/harfbuzz.pri b/src/3rdparty/harfbuzz.pri
deleted file mode 100644
index e61ee7eab6..0000000000
--- a/src/3rdparty/harfbuzz.pri
+++ /dev/null
@@ -1,121 +0,0 @@
-contains(QT_CONFIG, harfbuzz) {
- QT_HARFBUZZ_DIR = $$QT_SOURCE_TREE/src/3rdparty/harfbuzz-ng
-
- INCLUDEPATH += $$QT_HARFBUZZ_DIR/include
-
- SOURCES += \
- $$QT_HARFBUZZ_DIR/src/hb-blob.cc \
- $$QT_HARFBUZZ_DIR/src/hb-buffer.cc \
- $$QT_HARFBUZZ_DIR/src/hb-buffer-serialize.cc \
- $$QT_HARFBUZZ_DIR/src/hb-common.cc \
- $$QT_HARFBUZZ_DIR/src/hb-face.cc \
- $$QT_HARFBUZZ_DIR/src/hb-font.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-tag.cc \
- $$QT_HARFBUZZ_DIR/src/hb-set.cc \
- $$QT_HARFBUZZ_DIR/src/hb-shape.cc \
- $$QT_HARFBUZZ_DIR/src/hb-shape-plan.cc \
- $$QT_HARFBUZZ_DIR/src/hb-shaper.cc \
- $$QT_HARFBUZZ_DIR/src/hb-unicode.cc \
- $$QT_HARFBUZZ_DIR/src/hb-warning.cc
-
- HEADERS += \
- $$QT_HARFBUZZ_DIR/src/hb-atomic-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-buffer-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-buffer-deserialize-json.hh \
- $$QT_HARFBUZZ_DIR/src/hb-buffer-deserialize-text.hh \
- $$QT_HARFBUZZ_DIR/src/hb-cache-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-face-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-font-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-mutex-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-object-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-open-file-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-open-type-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-head-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-hhea-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-hmtx-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-maxp-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-name-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-set-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-shape-plan-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-shaper-impl-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-shaper-list.hh \
- $$QT_HARFBUZZ_DIR/src/hb-shaper-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-unicode-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-utf-private.hh
-
- HEADERS += \
- $$QT_HARFBUZZ_DIR/src/hb.h \
- $$QT_HARFBUZZ_DIR/src/hb-blob.h \
- $$QT_HARFBUZZ_DIR/src/hb-buffer.h \
- $$QT_HARFBUZZ_DIR/src/hb-common.h \
- $$QT_HARFBUZZ_DIR/src/hb-face.h \
- $$QT_HARFBUZZ_DIR/src/hb-font.h \
- $$QT_HARFBUZZ_DIR/src/hb-set.h \
- $$QT_HARFBUZZ_DIR/src/hb-shape.h \
- $$QT_HARFBUZZ_DIR/src/hb-shape-plan.h \
- $$QT_HARFBUZZ_DIR/src/hb-unicode.h \
- $$QT_HARFBUZZ_DIR/src/hb-version.h
-
- # Open Type
- SOURCES += \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-map.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-default.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-hangul.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-hebrew.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-table.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-myanmar.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-sea.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-thai.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-tibetan.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-fallback.cc \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-normalize.cc
-
- HEADERS += \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout-common-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gdef-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gpos-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsubgpos-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout-gsub-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout-jstf-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-map-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic-fallback.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-arabic-table.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-machine.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-indic-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-myanmar-machine.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-complex-sea-machine.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-fallback-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-normalize-private.hh \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape-private.hh
-
- HEADERS += \
- $$QT_HARFBUZZ_DIR/src/hb-ot.h \
- $$QT_HARFBUZZ_DIR/src/hb-ot-layout.h \
- $$QT_HARFBUZZ_DIR/src/hb-ot-shape.h \
- $$QT_HARFBUZZ_DIR/src/hb-ot-tag.h
-
- mac {
- # Apple Advanced Typography
- SOURCES += \
- $$QT_HARFBUZZ_DIR/src/hb-coretext.cc
-
- HEADERS += \
- $$QT_HARFBUZZ_DIR/src/hb-coretext.h
-
- DEFINES += HAVE_CORETEXT
- }
-
- DEFINES += HAVE_CONFIG_H
- QT += core-private
-
- TR_EXCLUDE += $$QT_HARFBUZZ_DIR/*
-} else:contains(QT_CONFIG, system-harfbuzz) {
- LIBS_PRIVATE += -lharfbuzz
-}
diff --git a/src/3rdparty/harfbuzzng.pri b/src/3rdparty/harfbuzzng.pri
new file mode 100644
index 0000000000..74433688f6
--- /dev/null
+++ b/src/3rdparty/harfbuzzng.pri
@@ -0,0 +1,6 @@
+contains(QT_CONFIG, harfbuzz) {
+ INCLUDEPATH += $$PWD/harfbuzz-ng/include
+ LIBS_PRIVATE += -L$$QT_BUILD_TREE/lib -lqtharfbuzzng$$qtPlatformTargetSuffix()
+} else:contains(QT_CONFIG, system-harfbuzz) {
+ LIBS_PRIVATE += -lharfbuzz
+}
diff --git a/src/3rdparty/sqlite/shell.c b/src/3rdparty/sqlite/shell.c
index 480ec5b455..2cff102e91 100644
--- a/src/3rdparty/sqlite/shell.c
+++ b/src/3rdparty/sqlite/shell.c
@@ -45,14 +45,17 @@
# include <sys/types.h>
#endif
-#ifdef HAVE_EDITLINE
-# include <editline/editline.h>
-#endif
-#if defined(HAVE_READLINE) && HAVE_READLINE==1
+#if defined(HAVE_READLINE) && HAVE_READLINE!=0
# include <readline/readline.h>
# include <readline/history.h>
+#else
+# undef HAVE_READLINE
+#endif
+#if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE)
+# define HAVE_READLINE 1
+# include <editline/readline.h>
#endif
-#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1)
+#if !defined(HAVE_READLINE)
# define add_history(X)
# define read_history(X)
# define write_history(X)
@@ -62,7 +65,9 @@
#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#define isatty(h) _isatty(h)
-#define access(f,m) _access((f),(m))
+#ifndef access
+# define access(f,m) _access((f),(m))
+#endif
#undef popen
#define popen _popen
#undef pclose
@@ -413,7 +418,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
zResult = local_getline(zPrior, in);
}else{
zPrompt = isContinuation ? continuePrompt : mainPrompt;
-#if defined(HAVE_READLINE) && HAVE_READLINE==1
+#if defined(HAVE_READLINE)
free(zPrior);
zResult = readline(zPrompt);
if( zResult && *zResult ) add_history(zResult);
@@ -441,6 +446,7 @@ struct previous_mode_data {
struct callback_data {
sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */
+ int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL statement */
int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */
@@ -597,6 +603,7 @@ static void output_c_string(FILE *out, const char *z){
*/
static void output_html_string(FILE *out, const char *z){
int i;
+ if( z==0 ) z = "";
while( *z ){
for(i=0; z[i]
&& z[i]!='<'
@@ -1004,7 +1011,7 @@ static int run_table_dump_query(
int nResult;
int i;
const char *z;
- rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
+ rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
@@ -1176,7 +1183,8 @@ static int str_in_array(const char *zStr, const char **azArray){
**
** * For each "Goto", if the jump destination is earlier in the program
** and ends on one of:
-** Yield SeekGt SeekLt RowSetRead
+** Yield SeekGt SeekLt RowSetRead Rewind
+** or if the P1 parameter is one instead of zero,
** then indent all opcodes between the earlier instruction
** and "Goto" by 2 spaces.
*/
@@ -1188,7 +1196,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
int iOp; /* Index of operation in p->aiIndent[] */
const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
- const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", 0 };
+ const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 };
const char *azGoto[] = { "Goto", 0 };
/* Try to figure out if this is really an EXPLAIN statement. If this
@@ -1224,8 +1232,10 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
if( str_in_array(zOp, azNext) ){
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
}
- if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){
- for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
+ if( str_in_array(zOp, azGoto) && p2op<p->nIndent
+ && (abYield[p2op] || sqlite3_column_int(pSql, 2))
+ ){
+ for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
}
}
@@ -1296,6 +1306,23 @@ static int shell_exec(
fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
}
+ /* Show the EXPLAIN QUERY PLAN if .eqp is on */
+ if( pArg && pArg->autoEQP ){
+ sqlite3_stmt *pExplain;
+ char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
+ rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
+ if( rc==SQLITE_OK ){
+ while( sqlite3_step(pExplain)==SQLITE_ROW ){
+ fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
+ fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
+ fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
+ fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
+ }
+ }
+ sqlite3_finalize(pExplain);
+ sqlite3_free(zEQP);
+ }
+
/* Output TESTCTRL_EXPLAIN text of requested */
if( pArg && pArg->mode==MODE_Explain ){
const char *zExplain = 0;
@@ -1452,7 +1479,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
zTableInfo = appendText(zTableInfo, zTable, '"');
zTableInfo = appendText(zTableInfo, ");", 0);
- rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
+ rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
free(zTableInfo);
if( rc!=SQLITE_OK || !pTableInfo ){
return 1;
@@ -1542,6 +1569,7 @@ static int run_schema_dump_query(
static char zHelp[] =
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
".bail ON|OFF Stop after hitting an error. Default OFF\n"
+ ".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n"
".dump ?TABLE? ... Dump the database in an SQL text format\n"
" If TABLE specified, only dump tables matching\n"
@@ -1581,6 +1609,7 @@ static char zHelp[] =
".quit Exit this program\n"
".read FILENAME Execute SQL in FILENAME\n"
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
+ ".save FILE Write in-memory database into FILE\n"
".schema ?TABLE? Show the CREATE statements\n"
" If TABLE specified, only show tables matching\n"
" LIKE pattern TABLE.\n"
@@ -1836,7 +1865,7 @@ static void csv_append_char(CSVReader *p, int c){
** + Report syntax errors on stderr
*/
static char *csv_read_one_field(CSVReader *p){
- int c, pc;
+ int c, pc, ppc;
int cSep = p->cSeparator;
p->n = 0;
c = fgetc(p->in);
@@ -1847,7 +1876,7 @@ static char *csv_read_one_field(CSVReader *p){
if( c=='"' ){
int startLine = p->nLine;
int cQuote = c;
- pc = 0;
+ pc = ppc = 0;
while( 1 ){
c = fgetc(p->in);
if( c=='\n' ) p->nLine++;
@@ -1859,7 +1888,7 @@ static char *csv_read_one_field(CSVReader *p){
}
if( (c==cSep && pc==cQuote)
|| (c=='\n' && pc==cQuote)
- || (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote)
+ || (c=='\n' && pc=='\r' && ppc==cQuote)
|| (c==EOF && pc==cQuote)
){
do{ p->n--; }while( p->z[p->n]!=cQuote );
@@ -1877,6 +1906,7 @@ static char *csv_read_one_field(CSVReader *p){
break;
}
csv_append_char(p, c);
+ ppc = pc;
pc = c;
}
}else{
@@ -1886,7 +1916,7 @@ static char *csv_read_one_field(CSVReader *p){
}
if( c=='\n' ){
p->nLine++;
- if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
+ if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
}
p->cTerm = c;
}
@@ -1895,6 +1925,219 @@ static char *csv_read_one_field(CSVReader *p){
}
/*
+** Try to transfer data for table zTable. If an error is seen while
+** moving forward, try to go backwards. The backwards movement won't
+** work for WITHOUT ROWID tables.
+*/
+static void tryToCloneData(
+ struct callback_data *p,
+ sqlite3 *newDb,
+ const char *zTable
+){
+ sqlite3_stmt *pQuery = 0;
+ sqlite3_stmt *pInsert = 0;
+ char *zQuery = 0;
+ char *zInsert = 0;
+ int rc;
+ int i, j, n;
+ int nTable = (int)strlen(zTable);
+ int k = 0;
+ int cnt = 0;
+ const int spinRate = 10000;
+
+ zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ fprintf(stderr, "Error %d: %s on [%s]\n",
+ sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
+ zQuery);
+ goto end_data_xfer;
+ }
+ n = sqlite3_column_count(pQuery);
+ zInsert = sqlite3_malloc(200 + nTable + n*3);
+ if( zInsert==0 ){
+ fprintf(stderr, "out of memory\n");
+ goto end_data_xfer;
+ }
+ sqlite3_snprintf(200+nTable,zInsert,
+ "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
+ i = (int)strlen(zInsert);
+ for(j=1; j<n; j++){
+ memcpy(zInsert+i, ",?", 2);
+ i += 2;
+ }
+ memcpy(zInsert+i, ");", 3);
+ rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
+ if( rc ){
+ fprintf(stderr, "Error %d: %s on [%s]\n",
+ sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
+ zQuery);
+ goto end_data_xfer;
+ }
+ for(k=0; k<2; k++){
+ while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
+ for(i=0; i<n; i++){
+ switch( sqlite3_column_type(pQuery, i) ){
+ case SQLITE_NULL: {
+ sqlite3_bind_null(pInsert, i+1);
+ break;
+ }
+ case SQLITE_INTEGER: {
+ sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
+ break;
+ }
+ case SQLITE_FLOAT: {
+ sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
+ break;
+ }
+ case SQLITE_TEXT: {
+ sqlite3_bind_text(pInsert, i+1,
+ (const char*)sqlite3_column_text(pQuery,i),
+ -1, SQLITE_STATIC);
+ break;
+ }
+ case SQLITE_BLOB: {
+ sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
+ sqlite3_column_bytes(pQuery,i),
+ SQLITE_STATIC);
+ break;
+ }
+ }
+ } /* End for */
+ rc = sqlite3_step(pInsert);
+ if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
+ fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
+ sqlite3_errmsg(newDb));
+ }
+ sqlite3_reset(pInsert);
+ cnt++;
+ if( (cnt%spinRate)==0 ){
+ printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
+ fflush(stdout);
+ }
+ } /* End while */
+ if( rc==SQLITE_DONE ) break;
+ sqlite3_finalize(pQuery);
+ sqlite3_free(zQuery);
+ zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
+ zTable);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
+ break;
+ }
+ } /* End for(k=0...) */
+
+end_data_xfer:
+ sqlite3_finalize(pQuery);
+ sqlite3_finalize(pInsert);
+ sqlite3_free(zQuery);
+ sqlite3_free(zInsert);
+}
+
+
+/*
+** Try to transfer all rows of the schema that match zWhere. For
+** each row, invoke xForEach() on the object defined by that row.
+** If an error is encountered while moving forward through the
+** sqlite_master table, try again moving backwards.
+*/
+static void tryToCloneSchema(
+ struct callback_data *p,
+ sqlite3 *newDb,
+ const char *zWhere,
+ void (*xForEach)(struct callback_data*,sqlite3*,const char*)
+){
+ sqlite3_stmt *pQuery = 0;
+ char *zQuery = 0;
+ int rc;
+ const unsigned char *zName;
+ const unsigned char *zSql;
+ char *zErrMsg = 0;
+
+ zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
+ " WHERE %s", zWhere);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ fprintf(stderr, "Error: (%d) %s on [%s]\n",
+ sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
+ zQuery);
+ goto end_schema_xfer;
+ }
+ while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
+ zName = sqlite3_column_text(pQuery, 0);
+ zSql = sqlite3_column_text(pQuery, 1);
+ printf("%s... ", zName); fflush(stdout);
+ sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
+ if( zErrMsg ){
+ fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
+ sqlite3_free(zErrMsg);
+ zErrMsg = 0;
+ }
+ if( xForEach ){
+ xForEach(p, newDb, (const char*)zName);
+ }
+ printf("done\n");
+ }
+ if( rc!=SQLITE_DONE ){
+ sqlite3_finalize(pQuery);
+ sqlite3_free(zQuery);
+ zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
+ " WHERE %s ORDER BY rowid DESC", zWhere);
+ rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
+ if( rc ){
+ fprintf(stderr, "Error: (%d) %s on [%s]\n",
+ sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
+ zQuery);
+ goto end_schema_xfer;
+ }
+ while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
+ zName = sqlite3_column_text(pQuery, 0);
+ zSql = sqlite3_column_text(pQuery, 1);
+ printf("%s... ", zName); fflush(stdout);
+ sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
+ if( zErrMsg ){
+ fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
+ sqlite3_free(zErrMsg);
+ zErrMsg = 0;
+ }
+ if( xForEach ){
+ xForEach(p, newDb, (const char*)zName);
+ }
+ printf("done\n");
+ }
+ }
+end_schema_xfer:
+ sqlite3_finalize(pQuery);
+ sqlite3_free(zQuery);
+}
+
+/*
+** Open a new database file named "zNewDb". Try to recover as much information
+** as possible out of the main database (which might be corrupt) and write it
+** into zNewDb.
+*/
+static void tryToClone(struct callback_data *p, const char *zNewDb){
+ int rc;
+ sqlite3 *newDb = 0;
+ if( access(zNewDb,0)==0 ){
+ fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
+ return;
+ }
+ rc = sqlite3_open(zNewDb, &newDb);
+ if( rc ){
+ fprintf(stderr, "Cannot create output database: %s\n",
+ sqlite3_errmsg(newDb));
+ }else{
+ sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
+ tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
+ tryToCloneSchema(p, newDb, "type!='table'", 0);
+ sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
+ }
+ sqlite3_close(newDb);
+}
+
+/*
** If an input line begins with "." then invoke this routine to
** process that line.
**
@@ -1936,7 +2179,9 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]);
c = azArg[0][0];
- if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
+ if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
+ || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
+ ){
const char *zDestFile = 0;
const char *zDb = 0;
sqlite3 *pDest;
@@ -2001,6 +2246,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
test_breakpoint();
}else
+ if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){
+ tryToClone(p, azArg[1]);
+ }else
+
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
struct callback_data data;
char *zErrMsg = 0;
@@ -2073,6 +2322,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
p->echoOn = booleanValue(azArg[1]);
}else
+ if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){
+ p->autoEQP = booleanValue(azArg[1]);
+ }else
+
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2;
@@ -2173,7 +2426,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
return 1;
}
nByte = strlen30(zSql);
- rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '(';
@@ -2199,7 +2452,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
xCloser(sCsv.in);
return 1;
}
- rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
}
sqlite3_free(zSql);
if( rc ){
@@ -2226,7 +2479,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
}
zSql[j++] = ')';
zSql[j] = 0;
- rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0);
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql);
if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
@@ -2645,6 +2898,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
int i;
fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
+ fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
@@ -3037,7 +3291,10 @@ static int process_input(struct callback_data *p, FILE *in){
seenInterrupt = 0;
}
lineno++;
- if( nSql==0 && _all_whitespace(zLine) ) continue;
+ if( nSql==0 && _all_whitespace(zLine) ){
+ if( p->echoOn ) printf("%s\n", zLine);
+ continue;
+ }
if( zLine && zLine[0]=='.' && nSql==0 ){
if( p->echoOn ) printf("%s\n", zLine);
rc = do_meta_command(zLine, p);
@@ -3099,6 +3356,7 @@ static int process_input(struct callback_data *p, FILE *in){
}
nSql = 0;
}else if( nSql && _all_whitespace(zSql) ){
+ if( p->echoOn ) printf("%s\n", zSql);
nSql = 0;
}
}
@@ -3277,6 +3535,26 @@ static void main_init(struct callback_data *data) {
}
/*
+** Output text to the console in a font that attracts extra attention.
+*/
+#ifdef _WIN32
+static void printBold(const char *zText){
+ HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
+ CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
+ GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
+ SetConsoleTextAttribute(out,
+ FOREGROUND_RED|FOREGROUND_INTENSITY
+ );
+ printf("%s", zText);
+ SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
+}
+#else
+static void printBold(const char *zText){
+ printf("\033[1m%s\033[0m", zText);
+}
+#endif
+
+/*
** Get the argument to an --option. Throw an error and die if no argument
** is available.
*/
@@ -3296,12 +3574,15 @@ int main(int argc, char **argv){
char *zFirstCmd = 0;
int i;
int rc = 0;
+ int warnInmemoryDb = 0;
+#if USE_SYSTEM_SQLITE+0!=1
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1);
}
+#endif
Argv0 = argv[0];
main_init(&data);
stdin_is_interactive = isatty(0);
@@ -3390,10 +3671,16 @@ int main(int argc, char **argv){
if( data.zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:";
+ warnInmemoryDb = argc==1;
#else
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
return 1;
#endif
+#ifdef SQLITE_SHELL_DBNAME_PROC
+ { extern void SQLITE_SHELL_DBNAME_PROC(const char**);
+ SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
+ warnInmemoryDb = 0; }
+#endif
}
data.out = stdout;
@@ -3449,6 +3736,8 @@ int main(int argc, char **argv){
data.showHeader = 0;
}else if( strcmp(z,"-echo")==0 ){
data.echoOn = 1;
+ }else if( strcmp(z,"-eqp")==0 ){
+ data.autoEQP = 1;
}else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1;
}else if( strcmp(z,"-bail")==0 ){
@@ -3526,10 +3815,15 @@ int main(int argc, char **argv){
int nHistory;
printf(
"SQLite version %s %.19s\n" /*extra-version-info*/
- "Enter \".help\" for instructions\n"
- "Enter SQL statements terminated with a \";\"\n",
+ "Enter \".help\" for usage hints.\n",
sqlite3_libversion(), sqlite3_sourceid()
);
+ if( warnInmemoryDb ){
+ printf("Connected to a ");
+ printBold("transient in-memory database");
+ printf(".\nUse \".open FILENAME\" to reopen on a "
+ "persistent database.\n");
+ }
zHome = find_home_dir();
if( zHome ){
nHistory = strlen30(zHome) + 20;
@@ -3537,7 +3831,7 @@ int main(int argc, char **argv){
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
}
}
-#if defined(HAVE_READLINE) && HAVE_READLINE==1
+#if defined(HAVE_READLINE)
if( zHistory ) read_history(zHistory);
#endif
rc = process_input(&data, 0);
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index 9c73927982..a2e37dd48e 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.8.2. By combining all the individual C code files into this
+** version 3.8.4.1. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -25,6 +25,93 @@
#ifndef SQLITE_API
# define SQLITE_API
#endif
+/************** Begin file sqliteInt.h ***************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you find forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Internal interface definitions for SQLite.
+**
+*/
+#ifndef _SQLITEINT_H_
+#define _SQLITEINT_H_
+
+/*
+** These #defines should enable >2GB file support on POSIX if the
+** underlying operating system supports it. If the OS lacks
+** large file support, or if the OS is windows, these should be no-ops.
+**
+** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any
+** system #includes. Hence, this block of code must be the very first
+** code in all source files.
+**
+** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
+** on the compiler command line. This is necessary if you are compiling
+** on a recent machine (ex: Red Hat 7.2) but you want your code to work
+** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2
+** without this option, LFS is enable. But LFS does not exist in the kernel
+** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
+** portability you should omit LFS.
+**
+** The previous paragraph was written in 2005. (This paragraph is written
+** on 2008-11-28.) These days, all Linux kernels support large files, so
+** you should probably leave LFS enabled. But some embedded platforms might
+** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
+**
+** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
+*/
+#ifndef SQLITE_DISABLE_LFS
+# define _LARGE_FILE 1
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+/*
+** For MinGW, check to see if we can include the header file containing its
+** version information, among other things. Normally, this internal MinGW
+** header file would [only] be included automatically by other MinGW header
+** files; however, the contained version information is now required by this
+** header file to work around binary compatibility issues (see below) and
+** this is the only known way to reliably obtain it. This entire #if block
+** would be completely unnecessary if there was any other way of detecting
+** MinGW via their preprocessor (e.g. if they customized their GCC to define
+** some MinGW-specific macros). When compiling for MinGW, either the
+** _HAVE_MINGW_H or _HAVE__MINGW_H (note the extra underscore) macro must be
+** defined; otherwise, detection of conditions specific to MinGW will be
+** disabled.
+*/
+#if defined(_HAVE_MINGW_H)
+# include "mingw.h"
+#elif defined(_HAVE__MINGW_H)
+# include "_mingw.h"
+#endif
+
+/*
+** For MinGW version 4.x (and higher), check to see if the _USE_32BIT_TIME_T
+** define is required to maintain binary compatibility with the MSVC runtime
+** library in use (e.g. for Windows XP).
+*/
+#if !defined(_USE_32BIT_TIME_T) && !defined(_USE_64BIT_TIME_T) && \
+ defined(_WIN32) && !defined(_WIN64) && \
+ defined(__MINGW_MAJOR_VERSION) && __MINGW_MAJOR_VERSION >= 4 && \
+ defined(__MSVCRT__)
+# define _USE_32BIT_TIME_T
+#endif
+
+/* The public SQLite interface. The _FILE_OFFSET_BITS macro must appear
+** first in QNX. Also, the _USE_32BIT_TIME_T macro must appear first for
+** MinGW.
+*/
+/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
/************** Begin file sqlite3.h *****************************************/
/*
** 2001 September 15
@@ -135,9 +222,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.2"
-#define SQLITE_VERSION_NUMBER 3008002
-#define SQLITE_SOURCE_ID "2013-12-06 14:53:30 27392118af4c38c5203a04b8013e1afdb1cebd0d"
+#define SQLITE_VERSION "3.8.4.1"
+#define SQLITE_VERSION_NUMBER 3008004
+#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -519,6 +606,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
+#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -586,7 +674,8 @@ SQLITE_API int sqlite3_exec(
** after reboot following a crash or power loss, the only bytes in a
** file that were written at the application level might have changed
** and that adjacent bytes, even bytes within the same sector are
-** guaranteed to be unchanged.
+** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+** flag indicate that a file cannot be deleted when open.
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -817,15 +906,29 @@ struct sqlite3_io_methods {
** additional information.
**
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
-** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
-** SQLite and sent to all VFSes in place of a call to the xSync method
-** when the database connection has [PRAGMA synchronous] set to OFF.)^
-** Some specialized VFSes need this signal in order to operate correctly
-** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most
-** VFSes do not need this signal and should silently ignore this opcode.
-** Applications should not call [sqlite3_file_control()] with this
-** opcode as doing so may disrupt the operation of the specialized VFSes
-** that do require it.
+** No longer in use.
+**
+** <li>[[SQLITE_FCNTL_SYNC]]
+** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
+** sent to the VFS immediately before the xSync method is invoked on a
+** database file descriptor. Or, if the xSync method is not invoked
+** because the user has configured SQLite with
+** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place
+** of the xSync method. In most cases, the pointer argument passed with
+** this file-control is NULL. However, if the database file is being synced
+** as part of a multi-database commit, the argument points to a nul-terminated
+** string containing the transactions master-journal file name. VFSes that
+** do not need this signal should silently ignore this opcode. Applications
+** should not call [sqlite3_file_control()] with this opcode as doing so may
+** disrupt the operation of the specialized VFSes that do require it.
+**
+** <li>[[SQLITE_FCNTL_COMMIT_PHASETWO]]
+** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite
+** and sent to the VFS after a transaction has been committed immediately
+** but before the database is unlocked. VFSes that do not need this signal
+** should silently ignore this opcode. Applications should not call
+** [sqlite3_file_control()] with this opcode as doing so may disrupt the
+** operation of the specialized VFSes that do require it.
**
** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
@@ -949,6 +1052,12 @@ struct sqlite3_io_methods {
** SQLite stack may generate instances of this file control if
** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
**
+** <li>[[SQLITE_FCNTL_HAS_MOVED]]
+** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
+** pointer to an integer and it writes a boolean into that integer depending
+** on whether or not the file has been renamed, moved, or deleted since it
+** was first opened.
+**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -969,6 +1078,9 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_TEMPFILENAME 16
#define SQLITE_FCNTL_MMAP_SIZE 18
#define SQLITE_FCNTL_TRACE 19
+#define SQLITE_FCNTL_HAS_MOVED 20
+#define SQLITE_FCNTL_SYNC 21
+#define SQLITE_FCNTL_COMMIT_PHASETWO 22
/*
** CAPI3REF: Mutex Handle
@@ -2403,11 +2515,13 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
+** ^If N is less than one, then P can be a NULL pointer.
**
-** ^The first time this routine is invoked (either internally or by
-** the application) the PRNG is seeded using randomness obtained
-** from the xRandomness method of the default [sqlite3_vfs] object.
-** ^On all subsequent invocations, the pseudo-randomness is generated
+** ^If this routine has not been previously called or if the previous
+** call had N less than one, then the PRNG is seeded using randomness
+** obtained from the xRandomness method of the default [sqlite3_vfs] object.
+** ^If the previous call to this routine had an N of 1 or more then
+** the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
@@ -2567,6 +2681,7 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_FUNCTION 31 /* NULL Function Name */
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
#define SQLITE_COPY 0 /* No longer used */
+#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** CAPI3REF: Tracing And Profiling Functions
@@ -3985,15 +4100,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** ^The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
-** its parameters. Every SQL function implementation must be able to work
-** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
-** more efficient with one encoding than another. ^An application may
-** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
-** times with the same function but with different values of eTextRep.
+** its parameters. The application should set this parameter to
+** [SQLITE_UTF16LE] if the function implementation invokes
+** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
+** implementation invokes [sqlite3_value_text16be()] on an input, or
+** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
+** otherwise. ^The same SQL function may be registered multiple times using
+** different preferred text encodings, with different implementations for
+** each encoding.
** ^When multiple implementations of the same function are available, SQLite
** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what text
-** encoding is used, then the fourth argument should be [SQLITE_ANY].
+**
+** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
+** to signal that the function will always return the same result given
+** the same inputs within a single SQL statement. Most SQL functions are
+** deterministic. The built-in [random()] SQL function is an example of a
+** function that is not deterministic. The SQLite query planner is able to
+** perform additional optimizations on deterministic functions, so use
+** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
@@ -4079,10 +4203,20 @@ SQLITE_API int sqlite3_create_function_v2(
#define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3
#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
+#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
+** CAPI3REF: Function Flags
+**
+** These constants may be ORed together with the
+** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
+** to [sqlite3_create_function()], [sqlite3_create_function16()], or
+** [sqlite3_create_function_v2()].
+*/
+#define SQLITE_DETERMINISTIC 0x800
+
+/*
** CAPI3REF: Deprecated Functions
** DEPRECATED
**
@@ -6103,7 +6237,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
-#define SQLITE_TESTCTRL_LAST 20
+#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
+#define SQLITE_TESTCTRL_LAST 21
/*
** CAPI3REF: SQLite Runtime Status
@@ -7366,50 +7501,7 @@ struct sqlite3_rtree_geometry {
/************** End of sqlite3.h *********************************************/
-/************** Begin file sqliteInt.h ***************************************/
-/*
-** 2001 September 15
-**
-** The author disclaims copyright to this source code. In place of
-** a legal notice, here is a blessing:
-**
-** May you do good and not evil.
-** May you find forgiveness for yourself and forgive others.
-** May you share freely, never taking more than you give.
-**
-*************************************************************************
-** Internal interface definitions for SQLite.
-**
-*/
-#ifndef _SQLITEINT_H_
-#define _SQLITEINT_H_
-
-/*
-** These #defines should enable >2GB file support on POSIX if the
-** underlying operating system supports it. If the OS lacks
-** large file support, or if the OS is windows, these should be no-ops.
-**
-** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any
-** system #includes. Hence, this block of code must be the very first
-** code in all source files.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: Red Hat 7.2) but you want your code to work
-** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in Red Hat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
+/************** Continuing where we left off in sqliteInt.h ******************/
/*
** Include the configuration header output by 'configure' if we're using the
@@ -7996,163 +8088,165 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
/************** Continuing where we left off in sqliteInt.h ******************/
/************** Include parse.h in the middle of sqliteInt.h *****************/
/************** Begin file parse.h *******************************************/
-#define TK_SEMI 1
-#define TK_EXPLAIN 2
-#define TK_QUERY 3
-#define TK_PLAN 4
-#define TK_BEGIN 5
-#define TK_TRANSACTION 6
-#define TK_DEFERRED 7
-#define TK_IMMEDIATE 8
-#define TK_EXCLUSIVE 9
-#define TK_COMMIT 10
-#define TK_END 11
-#define TK_ROLLBACK 12
-#define TK_SAVEPOINT 13
-#define TK_RELEASE 14
-#define TK_TO 15
-#define TK_TABLE 16
-#define TK_CREATE 17
-#define TK_IF 18
-#define TK_NOT 19
-#define TK_EXISTS 20
-#define TK_TEMP 21
-#define TK_LP 22
-#define TK_RP 23
-#define TK_AS 24
-#define TK_WITHOUT 25
-#define TK_COMMA 26
-#define TK_ID 27
-#define TK_INDEXED 28
-#define TK_ABORT 29
-#define TK_ACTION 30
-#define TK_AFTER 31
-#define TK_ANALYZE 32
-#define TK_ASC 33
-#define TK_ATTACH 34
-#define TK_BEFORE 35
-#define TK_BY 36
-#define TK_CASCADE 37
-#define TK_CAST 38
-#define TK_COLUMNKW 39
-#define TK_CONFLICT 40
-#define TK_DATABASE 41
-#define TK_DESC 42
-#define TK_DETACH 43
-#define TK_EACH 44
-#define TK_FAIL 45
-#define TK_FOR 46
-#define TK_IGNORE 47
-#define TK_INITIALLY 48
-#define TK_INSTEAD 49
-#define TK_LIKE_KW 50
-#define TK_MATCH 51
-#define TK_NO 52
-#define TK_KEY 53
-#define TK_OF 54
-#define TK_OFFSET 55
-#define TK_PRAGMA 56
-#define TK_RAISE 57
-#define TK_REPLACE 58
-#define TK_RESTRICT 59
-#define TK_ROW 60
-#define TK_TRIGGER 61
-#define TK_VACUUM 62
-#define TK_VIEW 63
-#define TK_VIRTUAL 64
-#define TK_REINDEX 65
-#define TK_RENAME 66
-#define TK_CTIME_KW 67
-#define TK_ANY 68
-#define TK_OR 69
-#define TK_AND 70
-#define TK_IS 71
-#define TK_BETWEEN 72
-#define TK_IN 73
-#define TK_ISNULL 74
-#define TK_NOTNULL 75
-#define TK_NE 76
-#define TK_EQ 77
-#define TK_GT 78
-#define TK_LE 79
-#define TK_LT 80
-#define TK_GE 81
-#define TK_ESCAPE 82
-#define TK_BITAND 83
-#define TK_BITOR 84
-#define TK_LSHIFT 85
-#define TK_RSHIFT 86
-#define TK_PLUS 87
-#define TK_MINUS 88
-#define TK_STAR 89
-#define TK_SLASH 90
-#define TK_REM 91
-#define TK_CONCAT 92
-#define TK_COLLATE 93
-#define TK_BITNOT 94
-#define TK_STRING 95
-#define TK_JOIN_KW 96
-#define TK_CONSTRAINT 97
-#define TK_DEFAULT 98
-#define TK_NULL 99
-#define TK_PRIMARY 100
-#define TK_UNIQUE 101
-#define TK_CHECK 102
-#define TK_REFERENCES 103
-#define TK_AUTOINCR 104
-#define TK_ON 105
-#define TK_INSERT 106
-#define TK_DELETE 107
-#define TK_UPDATE 108
-#define TK_SET 109
-#define TK_DEFERRABLE 110
-#define TK_FOREIGN 111
-#define TK_DROP 112
-#define TK_UNION 113
-#define TK_ALL 114
-#define TK_EXCEPT 115
-#define TK_INTERSECT 116
-#define TK_SELECT 117
-#define TK_DISTINCT 118
-#define TK_DOT 119
-#define TK_FROM 120
-#define TK_JOIN 121
-#define TK_USING 122
-#define TK_ORDER 123
-#define TK_GROUP 124
-#define TK_HAVING 125
-#define TK_LIMIT 126
-#define TK_WHERE 127
-#define TK_INTO 128
-#define TK_VALUES 129
-#define TK_INTEGER 130
-#define TK_FLOAT 131
-#define TK_BLOB 132
-#define TK_REGISTER 133
-#define TK_VARIABLE 134
-#define TK_CASE 135
-#define TK_WHEN 136
-#define TK_THEN 137
-#define TK_ELSE 138
-#define TK_INDEX 139
-#define TK_ALTER 140
-#define TK_ADD 141
-#define TK_TO_TEXT 142
-#define TK_TO_BLOB 143
-#define TK_TO_NUMERIC 144
-#define TK_TO_INT 145
-#define TK_TO_REAL 146
-#define TK_ISNOT 147
-#define TK_END_OF_FILE 148
-#define TK_ILLEGAL 149
-#define TK_SPACE 150
-#define TK_UNCLOSED_STRING 151
-#define TK_FUNCTION 152
-#define TK_COLUMN 153
-#define TK_AGG_FUNCTION 154
-#define TK_AGG_COLUMN 155
-#define TK_UMINUS 156
-#define TK_UPLUS 157
+#define TK_SEMI 1
+#define TK_EXPLAIN 2
+#define TK_QUERY 3
+#define TK_PLAN 4
+#define TK_BEGIN 5
+#define TK_TRANSACTION 6
+#define TK_DEFERRED 7
+#define TK_IMMEDIATE 8
+#define TK_EXCLUSIVE 9
+#define TK_COMMIT 10
+#define TK_END 11
+#define TK_ROLLBACK 12
+#define TK_SAVEPOINT 13
+#define TK_RELEASE 14
+#define TK_TO 15
+#define TK_TABLE 16
+#define TK_CREATE 17
+#define TK_IF 18
+#define TK_NOT 19
+#define TK_EXISTS 20
+#define TK_TEMP 21
+#define TK_LP 22
+#define TK_RP 23
+#define TK_AS 24
+#define TK_WITHOUT 25
+#define TK_COMMA 26
+#define TK_ID 27
+#define TK_INDEXED 28
+#define TK_ABORT 29
+#define TK_ACTION 30
+#define TK_AFTER 31
+#define TK_ANALYZE 32
+#define TK_ASC 33
+#define TK_ATTACH 34
+#define TK_BEFORE 35
+#define TK_BY 36
+#define TK_CASCADE 37
+#define TK_CAST 38
+#define TK_COLUMNKW 39
+#define TK_CONFLICT 40
+#define TK_DATABASE 41
+#define TK_DESC 42
+#define TK_DETACH 43
+#define TK_EACH 44
+#define TK_FAIL 45
+#define TK_FOR 46
+#define TK_IGNORE 47
+#define TK_INITIALLY 48
+#define TK_INSTEAD 49
+#define TK_LIKE_KW 50
+#define TK_MATCH 51
+#define TK_NO 52
+#define TK_KEY 53
+#define TK_OF 54
+#define TK_OFFSET 55
+#define TK_PRAGMA 56
+#define TK_RAISE 57
+#define TK_RECURSIVE 58
+#define TK_REPLACE 59
+#define TK_RESTRICT 60
+#define TK_ROW 61
+#define TK_TRIGGER 62
+#define TK_VACUUM 63
+#define TK_VIEW 64
+#define TK_VIRTUAL 65
+#define TK_WITH 66
+#define TK_REINDEX 67
+#define TK_RENAME 68
+#define TK_CTIME_KW 69
+#define TK_ANY 70
+#define TK_OR 71
+#define TK_AND 72
+#define TK_IS 73
+#define TK_BETWEEN 74
+#define TK_IN 75
+#define TK_ISNULL 76
+#define TK_NOTNULL 77
+#define TK_NE 78
+#define TK_EQ 79
+#define TK_GT 80
+#define TK_LE 81
+#define TK_LT 82
+#define TK_GE 83
+#define TK_ESCAPE 84
+#define TK_BITAND 85
+#define TK_BITOR 86
+#define TK_LSHIFT 87
+#define TK_RSHIFT 88
+#define TK_PLUS 89
+#define TK_MINUS 90
+#define TK_STAR 91
+#define TK_SLASH 92
+#define TK_REM 93
+#define TK_CONCAT 94
+#define TK_COLLATE 95
+#define TK_BITNOT 96
+#define TK_STRING 97
+#define TK_JOIN_KW 98
+#define TK_CONSTRAINT 99
+#define TK_DEFAULT 100
+#define TK_NULL 101
+#define TK_PRIMARY 102
+#define TK_UNIQUE 103
+#define TK_CHECK 104
+#define TK_REFERENCES 105
+#define TK_AUTOINCR 106
+#define TK_ON 107
+#define TK_INSERT 108
+#define TK_DELETE 109
+#define TK_UPDATE 110
+#define TK_SET 111
+#define TK_DEFERRABLE 112
+#define TK_FOREIGN 113
+#define TK_DROP 114
+#define TK_UNION 115
+#define TK_ALL 116
+#define TK_EXCEPT 117
+#define TK_INTERSECT 118
+#define TK_SELECT 119
+#define TK_VALUES 120
+#define TK_DISTINCT 121
+#define TK_DOT 122
+#define TK_FROM 123
+#define TK_JOIN 124
+#define TK_USING 125
+#define TK_ORDER 126
+#define TK_GROUP 127
+#define TK_HAVING 128
+#define TK_LIMIT 129
+#define TK_WHERE 130
+#define TK_INTO 131
+#define TK_INTEGER 132
+#define TK_FLOAT 133
+#define TK_BLOB 134
+#define TK_VARIABLE 135
+#define TK_CASE 136
+#define TK_WHEN 137
+#define TK_THEN 138
+#define TK_ELSE 139
+#define TK_INDEX 140
+#define TK_ALTER 141
+#define TK_ADD 142
+#define TK_TO_TEXT 143
+#define TK_TO_BLOB 144
+#define TK_TO_NUMERIC 145
+#define TK_TO_INT 146
+#define TK_TO_REAL 147
+#define TK_ISNOT 148
+#define TK_END_OF_FILE 149
+#define TK_ILLEGAL 150
+#define TK_SPACE 151
+#define TK_UNCLOSED_STRING 152
+#define TK_FUNCTION 153
+#define TK_COLUMN 154
+#define TK_AGG_FUNCTION 155
+#define TK_AGG_COLUMN 156
+#define TK_UMINUS 157
+#define TK_UPLUS 158
+#define TK_REGISTER 159
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -8583,6 +8677,7 @@ typedef struct LookasideSlot LookasideSlot;
typedef struct Module Module;
typedef struct NameContext NameContext;
typedef struct Parse Parse;
+typedef struct PrintfArguments PrintfArguments;
typedef struct RowSet RowSet;
typedef struct Savepoint Savepoint;
typedef struct Select Select;
@@ -8600,6 +8695,7 @@ typedef struct VTable VTable;
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
typedef struct WhereInfo WhereInfo;
+typedef struct With With;
/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and
@@ -8792,8 +8888,6 @@ SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt);
SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
SQLITE_PRIVATE int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
-SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64);
-SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor*);
SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot, int, int*);
SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*);
@@ -8933,9 +9027,12 @@ struct VdbeOp {
char *zComment; /* Comment to improve readability */
#endif
#ifdef VDBE_PROFILE
- int cnt; /* Number of times this instruction was executed */
+ u32 cnt; /* Number of times this instruction was executed */
u64 cycles; /* Total time spent executing this instruction */
#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ int iSrcLine; /* Source-code line that generated this opcode */
+#endif
};
typedef struct VdbeOp VdbeOp;
@@ -9045,139 +9142,143 @@ typedef struct VdbeOpList VdbeOpList;
#define OP_Gosub 17
#define OP_Return 18
#define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */
-#define OP_Yield 20
-#define OP_HaltIfNull 21 /* synopsis: if r[P3] null then halt */
-#define OP_Halt 22
-#define OP_Integer 23 /* synopsis: r[P2]=P1 */
-#define OP_Int64 24 /* synopsis: r[P2]=P4 */
-#define OP_String 25 /* synopsis: r[P2]='P4' (len=P1) */
-#define OP_Null 26 /* synopsis: r[P2..P3]=NULL */
-#define OP_Blob 27 /* synopsis: r[P2]=P4 (len=P1) */
-#define OP_Variable 28 /* synopsis: r[P2]=parameter(P1,P4) */
-#define OP_Move 29 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_Copy 30 /* synopsis: r[P2@P3]=r[P1@P3] */
-#define OP_SCopy 31 /* synopsis: r[P2]=r[P1] */
-#define OP_ResultRow 32 /* synopsis: output=r[P1@P2] */
-#define OP_CollSeq 33
-#define OP_AddImm 34 /* synopsis: r[P1]=r[P1]+P2 */
-#define OP_MustBeInt 35
-#define OP_RealAffinity 36
-#define OP_Permutation 37
-#define OP_Compare 38
-#define OP_Jump 39
-#define OP_Once 40
-#define OP_If 41
-#define OP_IfNot 42
-#define OP_Column 43 /* synopsis: r[P3]=PX */
-#define OP_Affinity 44 /* synopsis: affinity(r[P1@P2]) */
-#define OP_MakeRecord 45 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
-#define OP_Count 46 /* synopsis: r[P2]=count() */
-#define OP_ReadCookie 47
-#define OP_SetCookie 48
-#define OP_VerifyCookie 49
-#define OP_OpenRead 50 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenWrite 51 /* synopsis: root=P2 iDb=P3 */
-#define OP_OpenAutoindex 52 /* synopsis: nColumn=P2 */
-#define OP_OpenEphemeral 53 /* synopsis: nColumn=P2 */
-#define OP_SorterOpen 54
-#define OP_OpenPseudo 55 /* synopsis: content in r[P2@P3] */
-#define OP_Close 56
-#define OP_SeekLt 57 /* synopsis: key=r[P3@P4] */
-#define OP_SeekLe 58 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGe 59 /* synopsis: key=r[P3@P4] */
-#define OP_SeekGt 60 /* synopsis: key=r[P3@P4] */
-#define OP_Seek 61 /* synopsis: intkey=r[P2] */
-#define OP_NoConflict 62 /* synopsis: key=r[P3@P4] */
-#define OP_NotFound 63 /* synopsis: key=r[P3@P4] */
-#define OP_Found 64 /* synopsis: key=r[P3@P4] */
-#define OP_NotExists 65 /* synopsis: intkey=r[P3] */
-#define OP_Sequence 66 /* synopsis: r[P2]=rowid */
-#define OP_NewRowid 67 /* synopsis: r[P2]=rowid */
-#define OP_Insert 68 /* synopsis: intkey=r[P3] data=r[P2] */
-#define OP_Or 69 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
-#define OP_And 70 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_InsertInt 71 /* synopsis: intkey=P3 data=r[P2] */
-#define OP_Delete 72
-#define OP_ResetCount 73
-#define OP_IsNull 74 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
-#define OP_NotNull 75 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
-#define OP_Ne 76 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
-#define OP_Eq 77 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
-#define OP_Gt 78 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
-#define OP_Le 79 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
-#define OP_Lt 80 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
-#define OP_Ge 81 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
-#define OP_SorterCompare 82 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */
-#define OP_BitAnd 83 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
-#define OP_BitOr 84 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
-#define OP_ShiftLeft 85 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
-#define OP_ShiftRight 86 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
-#define OP_Add 87 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
-#define OP_Subtract 88 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
-#define OP_Multiply 89 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
-#define OP_Divide 90 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
-#define OP_Remainder 91 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
-#define OP_Concat 92 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_SorterData 93 /* synopsis: r[P2]=data */
-#define OP_BitNot 94 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
-#define OP_String8 95 /* same as TK_STRING, synopsis: r[P2]='P4' */
-#define OP_RowKey 96 /* synopsis: r[P2]=key */
-#define OP_RowData 97 /* synopsis: r[P2]=data */
-#define OP_Rowid 98 /* synopsis: r[P2]=rowid */
-#define OP_NullRow 99
-#define OP_Last 100
-#define OP_SorterSort 101
-#define OP_Sort 102
-#define OP_Rewind 103
-#define OP_SorterInsert 104
-#define OP_IdxInsert 105 /* synopsis: key=r[P2] */
-#define OP_IdxDelete 106 /* synopsis: key=r[P2@P3] */
-#define OP_IdxRowid 107 /* synopsis: r[P2]=rowid */
-#define OP_IdxLT 108 /* synopsis: key=r[P3@P4] */
-#define OP_IdxGE 109 /* synopsis: key=r[P3@P4] */
-#define OP_Destroy 110
-#define OP_Clear 111
-#define OP_CreateIndex 112 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_CreateTable 113 /* synopsis: r[P2]=root iDb=P1 */
-#define OP_ParseSchema 114
-#define OP_LoadAnalysis 115
-#define OP_DropTable 116
-#define OP_DropIndex 117
-#define OP_DropTrigger 118
-#define OP_IntegrityCk 119
-#define OP_RowSetAdd 120 /* synopsis: rowset(P1)=r[P2] */
-#define OP_RowSetRead 121 /* synopsis: r[P3]=rowset(P1) */
-#define OP_RowSetTest 122 /* synopsis: if r[P3] in rowset(P1) goto P2 */
-#define OP_Program 123
-#define OP_Param 124
-#define OP_FkCounter 125 /* synopsis: fkctr[P1]+=P2 */
-#define OP_FkIfZero 126 /* synopsis: if fkctr[P1]==0 goto P2 */
-#define OP_MemMax 127 /* synopsis: r[P1]=max(r[P1],r[P2]) */
-#define OP_IfPos 128 /* synopsis: if r[P1]>0 goto P2 */
-#define OP_IfNeg 129 /* synopsis: if r[P1]<0 goto P2 */
-#define OP_IfZero 130 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */
-#define OP_Real 131 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
-#define OP_AggFinal 132 /* synopsis: accum=r[P1] N=P2 */
-#define OP_IncrVacuum 133
-#define OP_Expire 134
-#define OP_TableLock 135 /* synopsis: iDb=P1 root=P2 write=P3 */
-#define OP_VBegin 136
-#define OP_VCreate 137
-#define OP_VDestroy 138
-#define OP_VOpen 139
-#define OP_VColumn 140 /* synopsis: r[P3]=vcolumn(P2) */
-#define OP_VNext 141
-#define OP_ToText 142 /* same as TK_TO_TEXT */
-#define OP_ToBlob 143 /* same as TK_TO_BLOB */
-#define OP_ToNumeric 144 /* same as TK_TO_NUMERIC */
-#define OP_ToInt 145 /* same as TK_TO_INT */
-#define OP_ToReal 146 /* same as TK_TO_REAL */
-#define OP_VRename 147
-#define OP_Pagecount 148
-#define OP_MaxPgcnt 149
-#define OP_Trace 150
-#define OP_Noop 151
-#define OP_Explain 152
+#define OP_InitCoroutine 20
+#define OP_EndCoroutine 21
+#define OP_Yield 22
+#define OP_HaltIfNull 23 /* synopsis: if r[P3]=null halt */
+#define OP_Halt 24
+#define OP_Integer 25 /* synopsis: r[P2]=P1 */
+#define OP_Int64 26 /* synopsis: r[P2]=P4 */
+#define OP_String 27 /* synopsis: r[P2]='P4' (len=P1) */
+#define OP_Null 28 /* synopsis: r[P2..P3]=NULL */
+#define OP_SoftNull 29 /* synopsis: r[P1]=NULL */
+#define OP_Blob 30 /* synopsis: r[P2]=P4 (len=P1) */
+#define OP_Variable 31 /* synopsis: r[P2]=parameter(P1,P4) */
+#define OP_Move 32 /* synopsis: r[P2@P3]=r[P1@P3] */
+#define OP_Copy 33 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
+#define OP_SCopy 34 /* synopsis: r[P2]=r[P1] */
+#define OP_ResultRow 35 /* synopsis: output=r[P1@P2] */
+#define OP_CollSeq 36
+#define OP_AddImm 37 /* synopsis: r[P1]=r[P1]+P2 */
+#define OP_MustBeInt 38
+#define OP_RealAffinity 39
+#define OP_Permutation 40
+#define OP_Compare 41
+#define OP_Jump 42
+#define OP_Once 43
+#define OP_If 44
+#define OP_IfNot 45
+#define OP_Column 46 /* synopsis: r[P3]=PX */
+#define OP_Affinity 47 /* synopsis: affinity(r[P1@P2]) */
+#define OP_MakeRecord 48 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
+#define OP_Count 49 /* synopsis: r[P2]=count() */
+#define OP_ReadCookie 50
+#define OP_SetCookie 51
+#define OP_OpenRead 52 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenWrite 53 /* synopsis: root=P2 iDb=P3 */
+#define OP_OpenAutoindex 54 /* synopsis: nColumn=P2 */
+#define OP_OpenEphemeral 55 /* synopsis: nColumn=P2 */
+#define OP_SorterOpen 56
+#define OP_OpenPseudo 57 /* synopsis: P3 columns in r[P2] */
+#define OP_Close 58
+#define OP_SeekLT 59
+#define OP_SeekLE 60
+#define OP_SeekGE 61
+#define OP_SeekGT 62
+#define OP_Seek 63 /* synopsis: intkey=r[P2] */
+#define OP_NoConflict 64 /* synopsis: key=r[P3@P4] */
+#define OP_NotFound 65 /* synopsis: key=r[P3@P4] */
+#define OP_Found 66 /* synopsis: key=r[P3@P4] */
+#define OP_NotExists 67 /* synopsis: intkey=r[P3] */
+#define OP_Sequence 68 /* synopsis: r[P2]=rowid */
+#define OP_NewRowid 69 /* synopsis: r[P2]=rowid */
+#define OP_Insert 70 /* synopsis: intkey=r[P3] data=r[P2] */
+#define OP_Or 71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
+#define OP_And 72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
+#define OP_InsertInt 73 /* synopsis: intkey=P3 data=r[P2] */
+#define OP_Delete 74
+#define OP_ResetCount 75
+#define OP_IsNull 76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
+#define OP_NotNull 77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
+#define OP_Ne 78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
+#define OP_Eq 79 /* same as TK_EQ, synopsis: if r[P1]==r[P3] goto P2 */
+#define OP_Gt 80 /* same as TK_GT, synopsis: if r[P1]>r[P3] goto P2 */
+#define OP_Le 81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
+#define OP_Lt 82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
+#define OP_Ge 83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
+#define OP_SorterCompare 84 /* synopsis: if key(P1)!=rtrim(r[P3],P4) goto P2 */
+#define OP_BitAnd 85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
+#define OP_BitOr 86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
+#define OP_ShiftLeft 87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
+#define OP_ShiftRight 88 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
+#define OP_Add 89 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
+#define OP_Subtract 90 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
+#define OP_Multiply 91 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
+#define OP_Divide 92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
+#define OP_Remainder 93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
+#define OP_Concat 94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
+#define OP_SorterData 95 /* synopsis: r[P2]=data */
+#define OP_BitNot 96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
+#define OP_String8 97 /* same as TK_STRING, synopsis: r[P2]='P4' */
+#define OP_RowKey 98 /* synopsis: r[P2]=key */
+#define OP_RowData 99 /* synopsis: r[P2]=data */
+#define OP_Rowid 100 /* synopsis: r[P2]=rowid */
+#define OP_NullRow 101
+#define OP_Last 102
+#define OP_SorterSort 103
+#define OP_Sort 104
+#define OP_Rewind 105
+#define OP_SorterInsert 106
+#define OP_IdxInsert 107 /* synopsis: key=r[P2] */
+#define OP_IdxDelete 108 /* synopsis: key=r[P2@P3] */
+#define OP_IdxRowid 109 /* synopsis: r[P2]=rowid */
+#define OP_IdxLE 110 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGT 111 /* synopsis: key=r[P3@P4] */
+#define OP_IdxLT 112 /* synopsis: key=r[P3@P4] */
+#define OP_IdxGE 113 /* synopsis: key=r[P3@P4] */
+#define OP_Destroy 114
+#define OP_Clear 115
+#define OP_CreateIndex 116 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_CreateTable 117 /* synopsis: r[P2]=root iDb=P1 */
+#define OP_ParseSchema 118
+#define OP_LoadAnalysis 119
+#define OP_DropTable 120
+#define OP_DropIndex 121
+#define OP_DropTrigger 122
+#define OP_IntegrityCk 123
+#define OP_RowSetAdd 124 /* synopsis: rowset(P1)=r[P2] */
+#define OP_RowSetRead 125 /* synopsis: r[P3]=rowset(P1) */
+#define OP_RowSetTest 126 /* synopsis: if r[P3] in rowset(P1) goto P2 */
+#define OP_Program 127
+#define OP_Param 128
+#define OP_FkCounter 129 /* synopsis: fkctr[P1]+=P2 */
+#define OP_FkIfZero 130 /* synopsis: if fkctr[P1]==0 goto P2 */
+#define OP_MemMax 131 /* synopsis: r[P1]=max(r[P1],r[P2]) */
+#define OP_IfPos 132 /* synopsis: if r[P1]>0 goto P2 */
+#define OP_Real 133 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
+#define OP_IfNeg 134 /* synopsis: if r[P1]<0 goto P2 */
+#define OP_IfZero 135 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2 */
+#define OP_AggFinal 136 /* synopsis: accum=r[P1] N=P2 */
+#define OP_IncrVacuum 137
+#define OP_Expire 138
+#define OP_TableLock 139 /* synopsis: iDb=P1 root=P2 write=P3 */
+#define OP_VBegin 140
+#define OP_VCreate 141
+#define OP_VDestroy 142
+#define OP_ToText 143 /* same as TK_TO_TEXT */
+#define OP_ToBlob 144 /* same as TK_TO_BLOB */
+#define OP_ToNumeric 145 /* same as TK_TO_NUMERIC */
+#define OP_ToInt 146 /* same as TK_TO_INT */
+#define OP_ToReal 147 /* same as TK_TO_REAL */
+#define OP_VOpen 148
+#define OP_VColumn 149 /* synopsis: r[P3]=vcolumn(P2) */
+#define OP_VNext 150
+#define OP_VRename 151
+#define OP_Pagecount 152
+#define OP_MaxPgcnt 153
+#define OP_Init 154 /* synopsis: Start at P2 */
+#define OP_Noop 155
+#define OP_Explain 156
/* Properties such as "out2" or "jump" that are specified in
@@ -9194,24 +9295,24 @@ typedef struct VdbeOpList VdbeOpList;
#define OPFLG_INITIALIZER {\
/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
/* 8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\
-/* 16 */ 0x01, 0x01, 0x04, 0x24, 0x04, 0x10, 0x00, 0x02,\
-/* 24 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x20,\
-/* 32 */ 0x00, 0x00, 0x04, 0x05, 0x04, 0x00, 0x00, 0x01,\
-/* 40 */ 0x01, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x02,\
-/* 48 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 56 */ 0x00, 0x11, 0x11, 0x11, 0x11, 0x08, 0x11, 0x11,\
-/* 64 */ 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c, 0x4c, 0x00,\
-/* 72 */ 0x00, 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15,\
-/* 80 */ 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
-/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02,\
-/* 96 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x01, 0x01, 0x01,\
-/* 104 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
-/* 112 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
-/* 120 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
-/* 128 */ 0x05, 0x05, 0x05, 0x02, 0x00, 0x01, 0x00, 0x00,\
-/* 136 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x04,\
-/* 144 */ 0x04, 0x04, 0x04, 0x00, 0x02, 0x02, 0x00, 0x00,\
-/* 152 */ 0x00,}
+/* 16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\
+/* 24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\
+/* 32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\
+/* 40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\
+/* 48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\
+/* 56 */ 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x08,\
+/* 64 */ 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x00, 0x4c,\
+/* 72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\
+/* 80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\
+/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\
+/* 96 */ 0x24, 0x02, 0x00, 0x00, 0x02, 0x00, 0x01, 0x01,\
+/* 104 */ 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01, 0x01,\
+/* 112 */ 0x01, 0x01, 0x02, 0x00, 0x02, 0x02, 0x00, 0x00,\
+/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45, 0x15, 0x01,\
+/* 128 */ 0x02, 0x00, 0x01, 0x08, 0x05, 0x02, 0x05, 0x05,\
+/* 136 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,\
+/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x01, 0x00,\
+/* 152 */ 0x02, 0x02, 0x01, 0x00, 0x00,}
/************** End of opcodes.h *********************************************/
/************** Continuing where we left off in vdbe.h ***********************/
@@ -9220,14 +9321,14 @@ typedef struct VdbeOpList VdbeOpList;
** Prototypes for the VDBE interface. See comments on the implementation
** for a description of what each of these routines does.
*/
-SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3*);
+SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*);
SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int);
-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
+SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp, int iLineno);
SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
@@ -9235,6 +9336,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr);
SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
+SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int);
@@ -9267,9 +9369,12 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
#endif
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,const UnpackedRecord*,int);
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
+typedef int (*RecordCompare)(int,const void*,const UnpackedRecord*,int);
+SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
+
#ifndef SQLITE_OMIT_TRIGGER
SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *);
#endif
@@ -9297,6 +9402,43 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
# define VdbeModuleComment(X)
#endif
+/*
+** The VdbeCoverage macros are used to set a coverage testing point
+** for VDBE branch instructions. The coverage testing points are line
+** numbers in the sqlite3.c source file. VDBE branch coverage testing
+** only works with an amalagmation build. That's ok since a VDBE branch
+** coverage build designed for testing the test suite only. No application
+** should ever ship with VDBE branch coverage measuring turned on.
+**
+** VdbeCoverage(v) // Mark the previously coded instruction
+** // as a branch
+**
+** VdbeCoverageIf(v, conditional) // Mark previous if conditional true
+**
+** VdbeCoverageAlwaysTaken(v) // Previous branch is always taken
+**
+** VdbeCoverageNeverTaken(v) // Previous branch is never taken
+**
+** Every VDBE branch operation must be tagged with one of the macros above.
+** If not, then when "make test" is run with -DSQLITE_VDBE_COVERAGE and
+** -DSQLITE_DEBUG then an ALWAYS() will fail in the vdbeTakeBranch()
+** routine in vdbe.c, alerting the developer to the missed tag.
+*/
+#ifdef SQLITE_VDBE_COVERAGE
+SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int);
+# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__)
+# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__)
+# define VdbeCoverageAlwaysTaken(v) sqlite3VdbeSetLineNumber(v,2);
+# define VdbeCoverageNeverTaken(v) sqlite3VdbeSetLineNumber(v,1);
+# define VDBE_OFFSET_LINENO(x) (__LINE__+x)
+#else
+# define VdbeCoverage(v)
+# define VdbeCoverageIf(v,x)
+# define VdbeCoverageAlwaysTaken(v)
+# define VdbeCoverageNeverTaken(v)
+# define VDBE_OFFSET_LINENO(x) 0
+#endif
+
#endif
/************** End of vdbe.h ************************************************/
@@ -9441,6 +9583,7 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage
SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
+SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*);
/* Operations on page references. */
SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
@@ -9455,7 +9598,7 @@ SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*);
SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int);
SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int);
SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*);
-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
+SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster);
SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*);
SQLITE_PRIVATE int sqlite3PagerRollback(Pager*);
SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n);
@@ -10327,7 +10470,7 @@ struct sqlite3 {
#define SQLITE_ColumnCache 0x0002 /* Column cache */
#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
-#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */
+/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */
#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */
@@ -10353,8 +10496,7 @@ struct sqlite3 {
** Return true if it OK to factor constant expressions into the initialization
** code. The argument is a Parse object for the code generator.
*/
-#define ConstFactorOk(P) \
- ((P)->cookieGoto>0 && OptimizationEnabled((P)->db,SQLITE_FactorOutConst))
+#define ConstFactorOk(P) ((P)->okConstFactor)
/*
** Possible values for the sqlite.magic field.
@@ -10580,10 +10722,16 @@ struct CollSeq {
/*
** Additional bit values that can be ORed with an affinity without
** changing the affinity.
+**
+** The SQLITE_NOTNULL flag is a combination of NULLEQ and JUMPIFNULL.
+** It causes an assert() to fire if either operand to a comparison
+** operator is NULL. It is added to certain comparison operators to
+** prove that the operands are always NOT NULL.
*/
#define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */
#define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */
#define SQLITE_NULLEQ 0x80 /* NULL=NULL */
+#define SQLITE_NOTNULL 0x88 /* Assert that operands are never NULL */
/*
** An object of this type is created for each virtual table present in
@@ -10699,7 +10847,7 @@ struct Table {
};
/*
-** Allowed values for Tabe.tabFlags.
+** Allowed values for Table.tabFlags.
*/
#define TF_Readonly 0x01 /* Read-only system table */
#define TF_Ephemeral 0x02 /* An ephemeral table */
@@ -10842,19 +10990,19 @@ struct KeyInfo {
**
** This structure holds a record that has already been disassembled
** into its constituent fields.
+**
+** The r1 and r2 member variables are only used by the optimized comparison
+** functions vdbeRecordCompareInt() and vdbeRecordCompareString().
*/
struct UnpackedRecord {
KeyInfo *pKeyInfo; /* Collation and sort-order information */
u16 nField; /* Number of entries in apMem[] */
- u8 flags; /* Boolean settings. UNPACKED_... below */
+ i8 default_rc; /* Comparison result if keys are equal */
Mem *aMem; /* Values */
+ int r1; /* Value to return if (lhs > rhs) */
+ int r2; /* Value to return if (rhs < lhs) */
};
-/*
-** Allowed values of UnpackedRecord.flags
-*/
-#define UNPACKED_INCRKEY 0x01 /* Make this key an epsilon larger */
-#define UNPACKED_PREFIX_MATCH 0x02 /* A prefix match is considered OK */
/*
** Each SQL index is represented in memory by an
@@ -10959,6 +11107,7 @@ struct AggInfo {
int sortingIdx; /* Cursor number of the sorting index */
int sortingIdxPTab; /* Cursor number of pseudo-table */
int nSortingColumn; /* Number of columns in the sorting index */
+ int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */
ExprList *pGroupBy; /* The group by clause */
struct AggInfo_col { /* For each column used in source tables */
Table *pTab; /* Source table */
@@ -11251,6 +11400,7 @@ typedef u64 Bitmask;
** A bit in a Bitmask
*/
#define MASKBIT(n) (((Bitmask)1)<<(n))
+#define MASKBIT32(n) (((unsigned int)1)<<(n))
/*
** The following structure describes the FROM clause of a SELECT statement.
@@ -11272,8 +11422,8 @@ typedef u64 Bitmask;
** contains more than 63 columns and the 64-th or later column is used.
*/
struct SrcList {
- u8 nSrc; /* Number of tables or subqueries in the FROM clause */
- u8 nAlloc; /* Number of entries allocated in a[] below */
+ int nSrc; /* Number of tables or subqueries in the FROM clause */
+ u32 nAlloc; /* Number of entries allocated in a[] below */
struct SrcList_item {
Schema *pSchema; /* Schema to which this item is fixed */
char *zDatabase; /* Name of database holding this table */
@@ -11283,10 +11433,12 @@ struct SrcList {
Select *pSelect; /* A SELECT statement used in place of a table name */
int addrFillSub; /* Address of subroutine to manifest a subquery */
int regReturn; /* Register holding return address of addrFillSub */
+ int regResult; /* Registers holding results of a co-routine */
u8 jointype; /* Type of join between this able and the previous */
unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */
unsigned isCorrelated :1; /* True if sub-query is correlated */
unsigned viaCoroutine :1; /* Implemented as a co-routine */
+ unsigned isRecursive :1; /* True for recursive reference in WITH */
#ifndef SQLITE_OMIT_EXPLAIN
u8 iSelectId; /* If pSelect!=0, the id of the sub-select in EQP */
#endif
@@ -11410,9 +11562,9 @@ struct Select {
ExprList *pOrderBy; /* The ORDER BY clause */
Select *pPrior; /* Prior select in a compound select statement */
Select *pNext; /* Next select to the left in a compound */
- Select *pRightmost; /* Right-most select in a compound select statement */
Expr *pLimit; /* LIMIT expression. NULL means not used. */
Expr *pOffset; /* OFFSET expression. NULL means not used. */
+ With *pWith; /* WITH clause attached to this select. Or NULL. */
};
/*
@@ -11427,14 +11579,74 @@ struct Select {
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
#define SF_UseSorter 0x0040 /* Sort using a sorter */
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
-#define SF_Materialize 0x0100 /* Force materialization of views */
+#define SF_Materialize 0x0100 /* NOT USED */
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
+#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
+#define SF_Compound 0x1000 /* Part of a compound query */
/*
-** The results of a select can be distributed in several ways. The
-** "SRT" prefix means "SELECT Result Type".
+** The results of a SELECT can be distributed in several ways, as defined
+** by one of the following macros. The "SRT" prefix means "SELECT Result
+** Type".
+**
+** SRT_Union Store results as a key in a temporary index
+** identified by pDest->iSDParm.
+**
+** SRT_Except Remove results from the temporary index pDest->iSDParm.
+**
+** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result
+** set is not empty.
+**
+** SRT_Discard Throw the results away. This is used by SELECT
+** statements within triggers whose only purpose is
+** the side-effects of functions.
+**
+** All of the above are free to ignore their ORDER BY clause. Those that
+** follow must honor the ORDER BY clause.
+**
+** SRT_Output Generate a row of output (using the OP_ResultRow
+** opcode) for each row in the result set.
+**
+** SRT_Mem Only valid if the result is a single column.
+** Store the first column of the first result row
+** in register pDest->iSDParm then abandon the rest
+** of the query. This destination implies "LIMIT 1".
+**
+** SRT_Set The result must be a single column. Store each
+** row of result as the key in table pDest->iSDParm.
+** Apply the affinity pDest->affSdst before storing
+** results. Used to implement "IN (SELECT ...)".
+**
+** SRT_EphemTab Create an temporary table pDest->iSDParm and store
+** the result there. The cursor is left open after
+** returning. This is like SRT_Table except that
+** this destination uses OP_OpenEphemeral to create
+** the table first.
+**
+** SRT_Coroutine Generate a co-routine that returns a new row of
+** results each time it is invoked. The entry point
+** of the co-routine is stored in register pDest->iSDParm
+** and the result row is stored in pDest->nDest registers
+** starting with pDest->iSdst.
+**
+** SRT_Table Store results in temporary table pDest->iSDParm.
+** This is like SRT_EphemTab except that the table
+** is assumed to already be open.
+**
+** SRT_DistTable Store results in a temporary table pDest->iSDParm.
+** But also use temporary table pDest->iSDParm+1 as
+** a record of all prior results and ignore any duplicate
+** rows. Name means: "Distinct Table".
+**
+** SRT_Queue Store results in priority queue pDest->iSDParm (really
+** an index). Append a sequence number so that all entries
+** are distinct.
+**
+** SRT_DistQueue Store results in priority queue pDest->iSDParm only if
+** the same record has never been stored before. The
+** index at pDest->iSDParm+1 hold all prior stores.
*/
#define SRT_Union 1 /* Store result as keys in an index */
#define SRT_Except 2 /* Remove result from a UNION index */
@@ -11447,20 +11659,24 @@ struct Select {
#define SRT_Output 5 /* Output each row of result */
#define SRT_Mem 6 /* Store result in a memory cell */
#define SRT_Set 7 /* Store results as keys in an index */
-#define SRT_Table 8 /* Store result as data with an automatic rowid */
-#define SRT_EphemTab 9 /* Create transient tab and store like SRT_Table */
-#define SRT_Coroutine 10 /* Generate a single row of result */
+#define SRT_EphemTab 8 /* Create transient tab and store like SRT_Table */
+#define SRT_Coroutine 9 /* Generate a single row of result */
+#define SRT_Table 10 /* Store result as data with an automatic rowid */
+#define SRT_DistTable 11 /* Like SRT_Table, but unique results only */
+#define SRT_Queue 12 /* Store result in an queue */
+#define SRT_DistQueue 13 /* Like SRT_Queue, but unique results only */
/*
** An instance of this object describes where to put of the results of
** a SELECT statement.
*/
struct SelectDest {
- u8 eDest; /* How to dispose of the results. On of SRT_* above. */
- char affSdst; /* Affinity used when eDest==SRT_Set */
- int iSDParm; /* A parameter used by the eDest disposal method */
- int iSdst; /* Base register where results are written */
- int nSdst; /* Number of registers allocated */
+ u8 eDest; /* How to dispose of the results. On of SRT_* above. */
+ char affSdst; /* Affinity used when eDest==SRT_Set */
+ int iSDParm; /* A parameter used by the eDest disposal method */
+ int iSdst; /* Base register where results are written */
+ int nSdst; /* Number of registers allocated */
+ ExprList *pOrderBy; /* Key columns for SRT_Queue and SRT_DistQueue */
};
/*
@@ -11546,12 +11762,12 @@ struct Parse {
u8 checkSchema; /* Causes schema cookie check after an error */
u8 nested; /* Number of nested calls to the parser/code generator */
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
- u8 nTempInUse; /* Number of aTempReg[] currently checked out */
u8 nColCache; /* Number of entries in aColCache[] */
u8 iColCache; /* Next entry in aColCache[] to replace */
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
u8 mayAbort; /* True if statement may throw an ABORT exception */
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
+ u8 okConstFactor; /* OK to factor out constants */
int aTempReg[8]; /* Holding area for temporary registers */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
@@ -11560,27 +11776,30 @@ struct Parse {
int nMem; /* Number of memory cells used so far */
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
+ int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
+ int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */
int ckBase; /* Base register of data during check constraints */
int iPartIdxTab; /* Table corresponding to a partial index */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
+ int nLabel; /* Number of labels used */
+ int *aLabel; /* Space to hold the labels */
struct yColCache {
int iTable; /* Table cursor number */
- int iColumn; /* Table column number */
+ i16 iColumn; /* Table column number */
u8 tempReg; /* iReg is a temp register that needs to be freed */
int iLevel; /* Nesting level */
int iReg; /* Reg with value of this column. 0 means none. */
int lru; /* Least recently used entry has the smallest value */
} aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */
ExprList *pConstExpr;/* Constant expressions */
+ Token constraintName;/* Name of the constraint currently being parsed */
yDbMask writeMask; /* Start a write transaction on these databases */
yDbMask cookieMask; /* Bitmask of schema verified databases */
- int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */
int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */
int regRowid; /* Register holding rowid of CREATE TABLE entry */
int regRoot; /* Register holding root page number for new objects */
int nMaxArg; /* Max args passed to user function by sub-program */
- Token constraintName;/* Name of the constraint currently being parsed */
#ifndef SQLITE_OMIT_SHARED_CACHE
int nTableLock; /* Number of locks in aTableLock */
TableLock *aTableLock; /* Required table locks for shared-cache mode */
@@ -11599,12 +11818,17 @@ struct Parse {
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
u8 disableTriggers; /* True to disable triggers */
- /* Above is constant between recursions. Below is reset before and after
- ** each recursion */
+ /************************************************************************
+ ** Above is constant between recursions. Below is reset before and after
+ ** each recursion. The boundary between these two regions is determined
+ ** using offsetof(Parse,nVar) so the nVar field must be the first field
+ ** in the recursive region.
+ ************************************************************************/
int nVar; /* Number of '?' variables seen in the SQL so far */
int nzVar; /* Number of available slots in azVar[] */
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
+ u8 bFreeWith; /* True if pWith should be freed with parser */
u8 explain; /* True if the EXPLAIN flag is found on the query */
#ifndef SQLITE_OMIT_VIRTUALTABLE
u8 declareVtab; /* True if inside sqlite3_declare_vtab() */
@@ -11630,6 +11854,7 @@ struct Parse {
#endif
Table *pZombieTab; /* List of Table objects to delete after code gen */
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
+ With *pWith; /* Current WITH clause, or NULL */
};
/*
@@ -11749,7 +11974,7 @@ struct TriggerStep {
Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
Token target; /* Target table for DELETE, UPDATE, INSERT */
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
- ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */
+ ExprList *pExprList; /* SET clause for UPDATE. */
IdList *pIdList; /* Column names for INSERT */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
@@ -11845,6 +12070,13 @@ struct Sqlite3Config {
void(*xSqllog)(void*,sqlite3*,const char*, int);
void *pSqllogArg;
#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ /* The following callback (if not NULL) is invoked on every VDBE branch
+ ** operation. Set the callback using SQLITE_TESTCTRL_VDBE_COVERAGE.
+ */
+ void (*xVdbeBranch)(void*,int iSrcLine,u8 eThis,u8 eMx); /* Callback */
+ void *pVdbeBranchArg; /* 1st argument */
+#endif
};
/*
@@ -11871,9 +12103,9 @@ struct Sqlite3Config {
struct Walker {
int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */
int (*xSelectCallback)(Walker*,Select*); /* Callback for SELECTs */
+ void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
Parse *pParse; /* Parser context. */
int walkerDepth; /* Number of subqueries */
- u8 bSelectDepthFirst; /* Do subqueries first */
union { /* Extra data for callback */
NameContext *pNC; /* Naming context */
int i; /* Integer value */
@@ -11898,6 +12130,21 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*);
#define WRC_Abort 2 /* Abandon the tree walk */
/*
+** An instance of this structure represents a set of one or more CTEs
+** (common table expressions) created by a single WITH clause.
+*/
+struct With {
+ int nCte; /* Number of CTEs in the WITH clause */
+ With *pOuter; /* Containing WITH clause, or NULL */
+ struct Cte { /* For each CTE in the WITH clause.... */
+ char *zName; /* Name of this CTE */
+ ExprList *pCols; /* List of explicit column names, or NULL */
+ Select *pSelect; /* The definition of this CTE */
+ const char *zErr; /* Error message for circular references */
+ } a[1];
+};
+
+/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
@@ -12036,10 +12283,20 @@ SQLITE_PRIVATE int sqlite3IsNaN(double);
# define sqlite3IsNaN(X) 0
#endif
-SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
-#ifndef SQLITE_OMIT_TRACE
-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, const char*, ...);
-#endif
+/*
+** An instance of the following structure holds information about SQL
+** functions arguments that are the parameters to the printf() function.
+*/
+struct PrintfArguments {
+ int nArg; /* Total number of arguments */
+ int nUsed; /* Number of arguments used so far */
+ sqlite3_value **apArg; /* The argument values */
+};
+
+#define SQLITE_PRINTF_INTERNAL 0x01
+#define SQLITE_PRINTF_SQLFUNC 0x02
+SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
+SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
@@ -12153,8 +12410,7 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
# define sqlite3AutoincrementBegin(X)
# define sqlite3AutoincrementEnd(X)
#endif
-SQLITE_PRIVATE int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*);
-SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
+SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*);
@@ -12201,11 +12457,12 @@ SQLITE_PRIVATE void sqlite3ExprCachePop(Parse*, int);
SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse*, int, int);
SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse*);
SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
-SQLITE_PRIVATE int sqlite3ExprCode(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int);
SQLITE_PRIVATE void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int);
-SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
+SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse*, Expr*, int);
SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8);
#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */
#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */
@@ -12229,7 +12486,6 @@ SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
-SQLITE_PRIVATE void sqlite3PrngResetState(void);
SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int);
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int);
SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
@@ -12244,12 +12500,11 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
-SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
+SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
u8,u8,int,int*);
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
@@ -12293,7 +12548,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, i
SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
- ExprList*,Select*,u8);
+ Select*,u8);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*);
@@ -12388,7 +12643,7 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *);
-SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *);
+SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int);
SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2);
SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
@@ -12398,8 +12653,7 @@ SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \
- defined(SQLITE_DEBUG_OS_TRACE)
+#if defined(SQLITE_TEST)
SQLITE_PRIVATE const char *sqlite3ErrName(int);
#endif
@@ -12429,6 +12683,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8);
SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8);
SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
void(*)(void*));
+SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*);
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
@@ -12494,6 +12749,7 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
+SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
@@ -12585,6 +12841,14 @@ SQLITE_PRIVATE const char *sqlite3JournalModename(int);
SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#endif
+#ifndef SQLITE_OMIT_CTE
+SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*);
+SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*);
+SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8);
+#else
+#define sqlite3WithPush(x,y,z)
+#define sqlite3WithDelete(x,y)
+#endif
/* Declarations for functions in fkey.c. All of these are replaced by
** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign
@@ -13192,6 +13456,9 @@ static const char * const azCompileOpt[] = {
#ifdef SQLITE_OMIT_COMPOUND_SELECT
"OMIT_COMPOUND_SELECT",
#endif
+#ifdef SQLITE_OMIT_CTE
+ "OMIT_CTE",
+#endif
#ifdef SQLITE_OMIT_DATETIME_FUNCS
"OMIT_DATETIME_FUNCS",
#endif
@@ -13483,7 +13750,6 @@ struct VdbeCursor {
Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
Bool isTable:1; /* True if a table requiring integer keys */
Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */
- Bool multiPseudo:1; /* Multi-register pseudo-cursor */
sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */
i64 seqCount; /* Sequence counter */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
@@ -13577,7 +13843,6 @@ struct Mem {
} u;
int n; /* Number of characters in string value, excluding '\0' */
u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
- u8 type; /* One of SQLITE_NULL, SQLITE_TEXT, SQLITE_INTEGER, etc */
u8 enc; /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
#ifdef SQLITE_DEBUG
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
@@ -13604,9 +13869,10 @@ struct Mem {
#define MEM_Int 0x0004 /* Value is an integer */
#define MEM_Real 0x0008 /* Value is a real number */
#define MEM_Blob 0x0010 /* Value is a BLOB */
+#define MEM_AffMask 0x001f /* Mask of affinity bits */
#define MEM_RowSet 0x0020 /* Value is a RowSet object */
#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */
-#define MEM_Invalid 0x0080 /* Value is undefined */
+#define MEM_Undefined 0x0080 /* Value is undefined */
#define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */
#define MEM_TypeMask 0x01ff /* Mask of type bits */
@@ -13617,7 +13883,7 @@ struct Mem {
** string is \000 or \u0000 terminated
*/
#define MEM_Term 0x0200 /* String rep is nul terminated */
-#define MEM_Dyn 0x0400 /* Need to call sqliteFree() on Mem.z */
+#define MEM_Dyn 0x0400 /* Need to call Mem.xDel() on Mem.z */
#define MEM_Static 0x0800 /* Mem.z points to a static string */
#define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */
#define MEM_Agg 0x2000 /* Mem.z points to an agg function context */
@@ -13638,7 +13904,7 @@ struct Mem {
** is for use inside assert() statements only.
*/
#ifdef SQLITE_DEBUG
-#define memIsValid(M) ((M)->flags & MEM_Invalid)==0
+#define memIsValid(M) ((M)->flags & MEM_Undefined)==0
#endif
/*
@@ -13720,12 +13986,9 @@ struct Vdbe {
Mem **apArg; /* Arguments to currently executing user function */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
+ Parse *pParse; /* Parsing context used to create this Vdbe */
int nMem; /* Number of memory locations currently allocated */
int nOp; /* Number of instructions in the program */
- int nOpAlloc; /* Number of slots allocated for aOp[] */
- int nLabel; /* Number of labels used */
- int *aLabel; /* Space to hold the labels */
- u16 nResColumn; /* Number of columns in one row of the result set */
int nCursor; /* Number of slots in apCsr[] */
u32 magic; /* Magic number for sanity checking */
char *zErrMsg; /* Error message written here */
@@ -13738,6 +14001,7 @@ struct Vdbe {
u32 cacheCtr; /* VdbeCursor row cache generation counter */
int pc; /* The program counter */
int rc; /* Value to return */
+ u16 nResColumn; /* Number of columns in one row of the result set */
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
bft explain:2; /* True if EXPLAIN present on SQL command */
@@ -13797,12 +14061,12 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
#endif
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
-SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
+SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,const UnpackedRecord*,int*);
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
@@ -13835,16 +14099,16 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
+#define VdbeMemDynamic(X) \
+ (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
#define VdbeMemRelease(X) \
- if((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame)) \
- sqlite3VdbeMemReleaseExternal(X);
+ if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X);
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
-SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem);
SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
@@ -13865,6 +14129,7 @@ SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*);
#ifdef SQLITE_DEBUG
SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
+SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*);
#endif
#ifndef SQLITE_OMIT_FOREIGN_KEY
@@ -15391,7 +15656,21 @@ SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
** routine has no return value since the return value would be meaningless.
*/
SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
- DO_OS_MALLOC_TEST(id);
+#ifdef SQLITE_TEST
+ if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
+ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
+ ** is using a regular VFS, it is called after the corresponding
+ ** transaction has been committed. Injecting a fault at this point
+ ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
+ ** but the transaction is committed anyway.
+ **
+ ** The core must call OsFileControl() though, not OsFileControlHint(),
+ ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
+ ** means the commit really has failed and an error should be returned
+ ** to the user. */
+ DO_OS_MALLOC_TEST(id);
+ }
+#endif
return id->pMethods->xFileControl(id, op, pArg);
}
SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
@@ -17603,6 +17882,12 @@ static void *memsys5MallocUnsafe(int nByte){
if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
+#ifdef SQLITE_DEBUG
+ /* Make sure the allocated memory does not assume that it is set to zero
+ ** or retains a value from a previous allocation */
+ memset(&mem5.zPool[i*mem5.szAtom], 0xAA, iFullSz);
+#endif
+
/* Return a pointer to the allocated memory. */
return (void*)&mem5.zPool[i*mem5.szAtom];
}
@@ -17660,6 +17945,13 @@ static void memsys5FreeUnsafe(void *pOld){
}
size *= 2;
}
+
+#ifdef SQLITE_DEBUG
+ /* Overwrite freed memory with the 0x55 bit pattern to verify that it is
+ ** not used after being freed */
+ memset(&mem5.zPool[iBlock*mem5.szAtom], 0x55, size);
+#endif
+
memsys5Link(iBlock, iLogsize);
}
@@ -19386,7 +19678,7 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite3 *db, void *p){
- return p && p>=db->lookaside.pStart && p<db->lookaside.pEnd;
+ return p>=db->lookaside.pStart && p<db->lookaside.pEnd;
}
#else
#define isLookaside(A,B) 0
@@ -19402,8 +19694,9 @@ SQLITE_PRIVATE int sqlite3MallocSize(void *p){
return sqlite3GlobalConfig.m.xSize(p);
}
SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
- assert( db==0 || sqlite3_mutex_held(db->mutex) );
- if( db && isLookaside(db, p) ){
+ assert( db!=0 );
+ assert( sqlite3_mutex_held(db->mutex) );
+ if( isLookaside(db, p) ){
return db->lookaside.sz;
}else{
assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
@@ -19887,6 +20180,31 @@ SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){
}
/*
+** Set the StrAccum object to an error mode.
+*/
+static void setStrAccumError(StrAccum *p, u8 eError){
+ p->accError = eError;
+ p->nAlloc = 0;
+}
+
+/*
+** Extra argument values from a PrintfArguments object
+*/
+static sqlite3_int64 getIntArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0;
+ return sqlite3_value_int64(p->apArg[p->nUsed++]);
+}
+static double getDoubleArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0.0;
+ return sqlite3_value_double(p->apArg[p->nUsed++]);
+}
+static char *getTextArg(PrintfArguments *p){
+ if( p->nArg<=p->nUsed ) return 0;
+ return (char*)sqlite3_value_text(p->apArg[p->nUsed++]);
+}
+
+
+/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
*/
@@ -19899,10 +20217,10 @@ SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *pAccum, int N){
** Render a string given by "fmt" into the StrAccum object.
*/
SQLITE_PRIVATE void sqlite3VXPrintf(
- StrAccum *pAccum, /* Accumulate results here */
- int useExtended, /* Allow extended %-conversions */
- const char *fmt, /* Format string */
- va_list ap /* arguments */
+ StrAccum *pAccum, /* Accumulate results here */
+ u32 bFlags, /* SQLITE_PRINTF_* flags */
+ const char *fmt, /* Format string */
+ va_list ap /* arguments */
){
int c; /* Next character in the format string */
char *bufpt; /* Pointer to the conversion buffer */
@@ -19920,6 +20238,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
etByte flag_longlong; /* True if the "ll" flag is present */
etByte done; /* Loop termination flag */
etByte xtype = 0; /* Conversion paradigm */
+ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */
+ u8 useIntern; /* Ok to use internal conversions (ex: %T) */
char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
sqlite_uint64 longvalue; /* Value for integer types */
LONGDOUBLE_TYPE realvalue; /* Value for real types */
@@ -19934,9 +20254,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
etByte flag_dp; /* True if decimal point should be shown */
etByte flag_rtz; /* True if trailing zeros should be removed */
#endif
+ PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
char buf[etBUFSIZE]; /* Conversion buffer */
bufpt = 0;
+ if( bFlags ){
+ if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
+ pArgList = va_arg(ap, PrintfArguments*);
+ }
+ useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
+ }else{
+ bArgList = useIntern = 0;
+ }
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
int amt;
@@ -19968,7 +20297,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
/* Get the field width */
width = 0;
if( c=='*' ){
- width = va_arg(ap,int);
+ if( bArgList ){
+ width = (int)getIntArg(pArgList);
+ }else{
+ width = va_arg(ap,int);
+ }
if( width<0 ){
flag_leftjustify = 1;
width = -width;
@@ -19985,7 +20318,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
precision = 0;
c = *++fmt;
if( c=='*' ){
- precision = va_arg(ap,int);
+ if( bArgList ){
+ precision = (int)getIntArg(pArgList);
+ }else{
+ precision = va_arg(ap,int);
+ }
if( precision<0 ) precision = -precision;
c = *++fmt;
}else{
@@ -20016,7 +20353,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
for(idx=0; idx<ArraySize(fmtinfo); idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
- if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
+ if( useIntern || (infop->flags & FLAG_INTERN)==0 ){
xtype = infop->type;
}else{
return;
@@ -20056,7 +20393,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
case etRADIX:
if( infop->flags & FLAG_SIGNED ){
i64 v;
- if( flag_longlong ){
+ if( bArgList ){
+ v = getIntArg(pArgList);
+ }else if( flag_longlong ){
v = va_arg(ap,i64);
}else if( flag_long ){
v = va_arg(ap,long int);
@@ -20077,7 +20416,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
else prefix = 0;
}
}else{
- if( flag_longlong ){
+ if( bArgList ){
+ longvalue = (u64)getIntArg(pArgList);
+ }else if( flag_longlong ){
longvalue = va_arg(ap,u64);
}else if( flag_long ){
longvalue = va_arg(ap,unsigned long int);
@@ -20097,7 +20438,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
nOut = precision + 10;
zOut = zExtra = sqlite3Malloc( nOut );
if( zOut==0 ){
- pAccum->accError = STRACCUM_NOMEM;
+ setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}
@@ -20137,7 +20478,11 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
case etFLOAT:
case etEXP:
case etGENERIC:
- realvalue = va_arg(ap,double);
+ if( bArgList ){
+ realvalue = getDoubleArg(pArgList);
+ }else{
+ realvalue = va_arg(ap,double);
+ }
#ifdef SQLITE_OMIT_FLOATING_POINT
length = 0;
#else
@@ -20209,7 +20554,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
if( bufpt==0 ){
- pAccum->accError = STRACCUM_NOMEM;
+ setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}
@@ -20292,7 +20637,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */
break;
case etSIZE:
- *(va_arg(ap,int*)) = pAccum->nChar;
+ if( !bArgList ){
+ *(va_arg(ap,int*)) = pAccum->nChar;
+ }
length = width = 0;
break;
case etPERCENT:
@@ -20301,7 +20648,12 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
length = 1;
break;
case etCHARX:
- c = va_arg(ap,int);
+ if( bArgList ){
+ bufpt = getTextArg(pArgList);
+ c = bufpt ? bufpt[0] : 0;
+ }else{
+ c = va_arg(ap,int);
+ }
buf[0] = (char)c;
if( precision>=0 ){
for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
@@ -20313,10 +20665,14 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
break;
case etSTRING:
case etDYNSTRING:
- bufpt = va_arg(ap,char*);
+ if( bArgList ){
+ bufpt = getTextArg(pArgList);
+ }else{
+ bufpt = va_arg(ap,char*);
+ }
if( bufpt==0 ){
bufpt = "";
- }else if( xtype==etDYNSTRING ){
+ }else if( xtype==etDYNSTRING && !bArgList ){
zExtra = bufpt;
}
if( precision>=0 ){
@@ -20332,7 +20688,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
int needQuote;
char ch;
char q = ((xtype==etSQLESCAPE3)?'"':'\''); /* Quote character */
- char *escarg = va_arg(ap,char*);
+ char *escarg;
+
+ if( bArgList ){
+ escarg = getTextArg(pArgList);
+ }else{
+ escarg = va_arg(ap,char*);
+ }
isnull = escarg==0;
if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
k = precision;
@@ -20344,7 +20706,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
if( n>etBUFSIZE ){
bufpt = zExtra = sqlite3Malloc( n );
if( bufpt==0 ){
- pAccum->accError = STRACCUM_NOMEM;
+ setStrAccumError(pAccum, STRACCUM_NOMEM);
return;
}
}else{
@@ -20367,7 +20729,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
}
case etTOKEN: {
Token *pToken = va_arg(ap, Token*);
- if( pToken ){
+ assert( bArgList==0 );
+ if( pToken && pToken->n ){
sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
}
length = width = 0;
@@ -20377,12 +20740,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
SrcList *pSrc = va_arg(ap, SrcList*);
int k = va_arg(ap, int);
struct SrcList_item *pItem = &pSrc->a[k];
+ assert( bArgList==0 );
assert( k>=0 && k<pSrc->nSrc );
if( pItem->zDatabase ){
- sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
+ sqlite3StrAccumAppendAll(pAccum, pItem->zDatabase);
sqlite3StrAccumAppend(pAccum, ".", 1);
}
- sqlite3StrAccumAppend(pAccum, pItem->zName, -1);
+ sqlite3StrAccumAppendAll(pAccum, pItem->zName);
length = width = 0;
break;
}
@@ -20413,7 +20777,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
sqlite3AppendSpace(pAccum, nspace);
}
}
- sqlite3_free(zExtra);
+ if( zExtra ) sqlite3_free(zExtra);
}/* End for loop over the format string */
} /* End of function */
@@ -20421,22 +20785,20 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
** Append N bytes of text from z to the StrAccum object.
*/
SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
- assert( z!=0 || N==0 );
- if( p->accError ){
- testcase(p->accError==STRACCUM_TOOBIG);
- testcase(p->accError==STRACCUM_NOMEM);
- return;
- }
- assert( p->zText!=0 || p->nChar==0 );
- if( N<=0 ){
- if( N==0 || z[0]==0 ) return;
- N = sqlite3Strlen30(z);
- }
+ assert( z!=0 );
+ assert( p->zText!=0 || p->nChar==0 || p->accError );
+ assert( N>=0 );
+ assert( p->accError==0 || p->nAlloc==0 );
if( p->nChar+N >= p->nAlloc ){
char *zNew;
+ if( p->accError ){
+ testcase(p->accError==STRACCUM_TOOBIG);
+ testcase(p->accError==STRACCUM_NOMEM);
+ return;
+ }
if( !p->useMalloc ){
- p->accError = STRACCUM_TOOBIG;
N = p->nAlloc - p->nChar - 1;
+ setStrAccumError(p, STRACCUM_TOOBIG);
if( N<=0 ){
return;
}
@@ -20446,7 +20808,7 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
szNew += N + 1;
if( szNew > p->mxAlloc ){
sqlite3StrAccumReset(p);
- p->accError = STRACCUM_TOOBIG;
+ setStrAccumError(p, STRACCUM_TOOBIG);
return;
}else{
p->nAlloc = (int)szNew;
@@ -20460,8 +20822,8 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
p->zText = zNew;
}else{
- p->accError = STRACCUM_NOMEM;
sqlite3StrAccumReset(p);
+ setStrAccumError(p, STRACCUM_NOMEM);
return;
}
}
@@ -20472,6 +20834,14 @@ SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
}
/*
+** Append the complete text of zero-terminated string z[] to the p string.
+*/
+SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
+ sqlite3StrAccumAppend(p, z, sqlite3Strlen30(z));
+}
+
+
+/*
** Finish off a string by making sure it is zero-terminated.
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
@@ -20488,7 +20858,7 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
if( p->zText ){
memcpy(p->zText, p->zBase, p->nChar+1);
}else{
- p->accError = STRACCUM_NOMEM;
+ setStrAccumError(p, STRACCUM_NOMEM);
}
}
}
@@ -20534,7 +20904,7 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
db->aLimit[SQLITE_LIMIT_LENGTH]);
acc.db = db;
- sqlite3VXPrintf(&acc, 1, zFormat, ap);
+ sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
z = sqlite3StrAccumFinish(&acc);
if( acc.accError==STRACCUM_NOMEM ){
db->mallocFailed = 1;
@@ -20690,17 +21060,15 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
}
#endif
-#ifndef SQLITE_OMIT_TRACE
/*
** variable-argument wrapper around sqlite3VXPrintf().
*/
-SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
+SQLITE_PRIVATE void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
va_list ap;
va_start(ap,zFormat);
- sqlite3VXPrintf(p, 1, zFormat, ap);
+ sqlite3VXPrintf(p, bFlags, zFormat, ap);
va_end(ap);
}
-#endif
/************** End of printf.c **********************************************/
/************** Begin file random.c ******************************************/
@@ -20757,6 +21125,12 @@ SQLITE_API void sqlite3_randomness(int N, void *pBuf){
sqlite3_mutex_enter(mutex);
#endif
+ if( N<=0 ){
+ wsdPrng.isInit = 0;
+ sqlite3_mutex_leave(mutex);
+ return;
+ }
+
/* Initialize the state of the random number generator once,
** the first time this routine is called. The seed value does
** not need to contain a lot of randomness since we are not
@@ -20784,7 +21158,8 @@ SQLITE_API void sqlite3_randomness(int N, void *pBuf){
wsdPrng.isInit = 1;
}
- while( N-- ){
+ assert( N>0 );
+ do{
wsdPrng.i++;
t = wsdPrng.s[wsdPrng.i];
wsdPrng.j += t;
@@ -20792,7 +21167,7 @@ SQLITE_API void sqlite3_randomness(int N, void *pBuf){
wsdPrng.s[wsdPrng.j] = t;
t += wsdPrng.s[wsdPrng.i];
*(zBuf++) = wsdPrng.s[t];
- }
+ }while( --N );
sqlite3_mutex_leave(mutex);
}
@@ -20821,9 +21196,6 @@ SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
sizeof(sqlite3Prng)
);
}
-SQLITE_PRIVATE void sqlite3PrngResetState(void){
- GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
-}
#endif /* SQLITE_OMIT_BUILTIN_TEST */
/************** End of random.c **********************************************/
@@ -21145,7 +21517,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
sqlite3VdbeMemRelease(pMem);
pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
pMem->enc = desiredEnc;
- pMem->flags |= (MEM_Term|MEM_Dyn);
+ pMem->flags |= (MEM_Term);
pMem->z = (char*)zOut;
pMem->zMalloc = pMem->z;
@@ -21273,7 +21645,6 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 e
}
assert( (m.flags & MEM_Term)!=0 || db->mallocFailed );
assert( (m.flags & MEM_Str)!=0 || db->mallocFailed );
- assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed );
assert( m.z || db->mallocFailed );
return m.z;
}
@@ -21475,18 +21846,17 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
** to NULL.
*/
SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
- if( db && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
- db->errCode = err_code;
- if( zFormat ){
- char *z;
- va_list ap;
- va_start(ap, zFormat);
- z = sqlite3VMPrintf(db, zFormat, ap);
- va_end(ap);
- sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
- }else{
- sqlite3ValueSetStr(db->pErr, 0, 0, SQLITE_UTF8, SQLITE_STATIC);
- }
+ assert( db!=0 );
+ db->errCode = err_code;
+ if( zFormat && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
+ char *z;
+ va_list ap;
+ va_start(ap, zFormat);
+ z = sqlite3VMPrintf(db, zFormat, ap);
+ va_end(ap);
+ sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
+ }else if( db->pErr ){
+ sqlite3ValueSetNull(db->pErr);
}
}
@@ -22362,7 +22732,8 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v){
** Read or write a four-byte big-endian integer value.
*/
SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){
- return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
+ testcase( p[0]&0x80 );
+ return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];
}
SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){
p[0] = (u8)(v>>24);
@@ -22483,13 +22854,12 @@ SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){
testcase( iA>0 && LARGEST_INT64 - iA == iB );
testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
- *pA += iB;
}else{
testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
- *pA += iB;
}
+ *pA += iB;
return 0;
}
SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){
@@ -22513,9 +22883,18 @@ SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){
iA0 = iA % TWOPOWER32;
iB1 = iB/TWOPOWER32;
iB0 = iB % TWOPOWER32;
- if( iA1*iB1 != 0 ) return 1;
- assert( iA1*iB0==0 || iA0*iB1==0 );
- r = iA1*iB0 + iA0*iB1;
+ if( iA1==0 ){
+ if( iB1==0 ){
+ *pA *= iB;
+ return 0;
+ }
+ r = iA0*iB1;
+ }else if( iB1==0 ){
+ r = iA1*iB0;
+ }else{
+ /* If both iA1 and iB1 are non-zero, overflow will result */
+ return 1;
+ }
testcase( r==(-TWOPOWER31)-1 );
testcase( r==(-TWOPOWER31) );
testcase( r==TWOPOWER31 );
@@ -22703,7 +23082,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
** The hashing function.
*/
static unsigned int strHash(const char *z, int nKey){
- int h = 0;
+ unsigned int h = 0;
assert( nKey>=0 );
while( nKey > 0 ){
h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
@@ -22961,139 +23340,143 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/* 17 */ "Gosub" OpHelp(""),
/* 18 */ "Return" OpHelp(""),
/* 19 */ "Not" OpHelp("r[P2]= !r[P1]"),
- /* 20 */ "Yield" OpHelp(""),
- /* 21 */ "HaltIfNull" OpHelp("if r[P3] null then halt"),
- /* 22 */ "Halt" OpHelp(""),
- /* 23 */ "Integer" OpHelp("r[P2]=P1"),
- /* 24 */ "Int64" OpHelp("r[P2]=P4"),
- /* 25 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
- /* 26 */ "Null" OpHelp("r[P2..P3]=NULL"),
- /* 27 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
- /* 28 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
- /* 29 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 30 */ "Copy" OpHelp("r[P2@P3]=r[P1@P3]"),
- /* 31 */ "SCopy" OpHelp("r[P2]=r[P1]"),
- /* 32 */ "ResultRow" OpHelp("output=r[P1@P2]"),
- /* 33 */ "CollSeq" OpHelp(""),
- /* 34 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
- /* 35 */ "MustBeInt" OpHelp(""),
- /* 36 */ "RealAffinity" OpHelp(""),
- /* 37 */ "Permutation" OpHelp(""),
- /* 38 */ "Compare" OpHelp(""),
- /* 39 */ "Jump" OpHelp(""),
- /* 40 */ "Once" OpHelp(""),
- /* 41 */ "If" OpHelp(""),
- /* 42 */ "IfNot" OpHelp(""),
- /* 43 */ "Column" OpHelp("r[P3]=PX"),
- /* 44 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
- /* 45 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
- /* 46 */ "Count" OpHelp("r[P2]=count()"),
- /* 47 */ "ReadCookie" OpHelp(""),
- /* 48 */ "SetCookie" OpHelp(""),
- /* 49 */ "VerifyCookie" OpHelp(""),
- /* 50 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
- /* 51 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
- /* 52 */ "OpenAutoindex" OpHelp("nColumn=P2"),
- /* 53 */ "OpenEphemeral" OpHelp("nColumn=P2"),
- /* 54 */ "SorterOpen" OpHelp(""),
- /* 55 */ "OpenPseudo" OpHelp("content in r[P2@P3]"),
- /* 56 */ "Close" OpHelp(""),
- /* 57 */ "SeekLt" OpHelp("key=r[P3@P4]"),
- /* 58 */ "SeekLe" OpHelp("key=r[P3@P4]"),
- /* 59 */ "SeekGe" OpHelp("key=r[P3@P4]"),
- /* 60 */ "SeekGt" OpHelp("key=r[P3@P4]"),
- /* 61 */ "Seek" OpHelp("intkey=r[P2]"),
- /* 62 */ "NoConflict" OpHelp("key=r[P3@P4]"),
- /* 63 */ "NotFound" OpHelp("key=r[P3@P4]"),
- /* 64 */ "Found" OpHelp("key=r[P3@P4]"),
- /* 65 */ "NotExists" OpHelp("intkey=r[P3]"),
- /* 66 */ "Sequence" OpHelp("r[P2]=rowid"),
- /* 67 */ "NewRowid" OpHelp("r[P2]=rowid"),
- /* 68 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
- /* 69 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
- /* 70 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
- /* 71 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
- /* 72 */ "Delete" OpHelp(""),
- /* 73 */ "ResetCount" OpHelp(""),
- /* 74 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
- /* 75 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
- /* 76 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"),
- /* 77 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"),
- /* 78 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"),
- /* 79 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"),
- /* 80 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"),
- /* 81 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"),
- /* 82 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"),
- /* 83 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
- /* 84 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
- /* 85 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
- /* 86 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
- /* 87 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
- /* 88 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
- /* 89 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
- /* 90 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
- /* 91 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
- /* 92 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
- /* 93 */ "SorterData" OpHelp("r[P2]=data"),
- /* 94 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
- /* 95 */ "String8" OpHelp("r[P2]='P4'"),
- /* 96 */ "RowKey" OpHelp("r[P2]=key"),
- /* 97 */ "RowData" OpHelp("r[P2]=data"),
- /* 98 */ "Rowid" OpHelp("r[P2]=rowid"),
- /* 99 */ "NullRow" OpHelp(""),
- /* 100 */ "Last" OpHelp(""),
- /* 101 */ "SorterSort" OpHelp(""),
- /* 102 */ "Sort" OpHelp(""),
- /* 103 */ "Rewind" OpHelp(""),
- /* 104 */ "SorterInsert" OpHelp(""),
- /* 105 */ "IdxInsert" OpHelp("key=r[P2]"),
- /* 106 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
- /* 107 */ "IdxRowid" OpHelp("r[P2]=rowid"),
- /* 108 */ "IdxLT" OpHelp("key=r[P3@P4]"),
- /* 109 */ "IdxGE" OpHelp("key=r[P3@P4]"),
- /* 110 */ "Destroy" OpHelp(""),
- /* 111 */ "Clear" OpHelp(""),
- /* 112 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
- /* 113 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
- /* 114 */ "ParseSchema" OpHelp(""),
- /* 115 */ "LoadAnalysis" OpHelp(""),
- /* 116 */ "DropTable" OpHelp(""),
- /* 117 */ "DropIndex" OpHelp(""),
- /* 118 */ "DropTrigger" OpHelp(""),
- /* 119 */ "IntegrityCk" OpHelp(""),
- /* 120 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
- /* 121 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
- /* 122 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
- /* 123 */ "Program" OpHelp(""),
- /* 124 */ "Param" OpHelp(""),
- /* 125 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
- /* 126 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
- /* 127 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
- /* 128 */ "IfPos" OpHelp("if r[P1]>0 goto P2"),
- /* 129 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"),
- /* 130 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"),
- /* 131 */ "Real" OpHelp("r[P2]=P4"),
- /* 132 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
- /* 133 */ "IncrVacuum" OpHelp(""),
- /* 134 */ "Expire" OpHelp(""),
- /* 135 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
- /* 136 */ "VBegin" OpHelp(""),
- /* 137 */ "VCreate" OpHelp(""),
- /* 138 */ "VDestroy" OpHelp(""),
- /* 139 */ "VOpen" OpHelp(""),
- /* 140 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
- /* 141 */ "VNext" OpHelp(""),
- /* 142 */ "ToText" OpHelp(""),
- /* 143 */ "ToBlob" OpHelp(""),
- /* 144 */ "ToNumeric" OpHelp(""),
- /* 145 */ "ToInt" OpHelp(""),
- /* 146 */ "ToReal" OpHelp(""),
- /* 147 */ "VRename" OpHelp(""),
- /* 148 */ "Pagecount" OpHelp(""),
- /* 149 */ "MaxPgcnt" OpHelp(""),
- /* 150 */ "Trace" OpHelp(""),
- /* 151 */ "Noop" OpHelp(""),
- /* 152 */ "Explain" OpHelp(""),
+ /* 20 */ "InitCoroutine" OpHelp(""),
+ /* 21 */ "EndCoroutine" OpHelp(""),
+ /* 22 */ "Yield" OpHelp(""),
+ /* 23 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
+ /* 24 */ "Halt" OpHelp(""),
+ /* 25 */ "Integer" OpHelp("r[P2]=P1"),
+ /* 26 */ "Int64" OpHelp("r[P2]=P4"),
+ /* 27 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
+ /* 28 */ "Null" OpHelp("r[P2..P3]=NULL"),
+ /* 29 */ "SoftNull" OpHelp("r[P1]=NULL"),
+ /* 30 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
+ /* 31 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
+ /* 32 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
+ /* 33 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
+ /* 34 */ "SCopy" OpHelp("r[P2]=r[P1]"),
+ /* 35 */ "ResultRow" OpHelp("output=r[P1@P2]"),
+ /* 36 */ "CollSeq" OpHelp(""),
+ /* 37 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
+ /* 38 */ "MustBeInt" OpHelp(""),
+ /* 39 */ "RealAffinity" OpHelp(""),
+ /* 40 */ "Permutation" OpHelp(""),
+ /* 41 */ "Compare" OpHelp(""),
+ /* 42 */ "Jump" OpHelp(""),
+ /* 43 */ "Once" OpHelp(""),
+ /* 44 */ "If" OpHelp(""),
+ /* 45 */ "IfNot" OpHelp(""),
+ /* 46 */ "Column" OpHelp("r[P3]=PX"),
+ /* 47 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
+ /* 48 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
+ /* 49 */ "Count" OpHelp("r[P2]=count()"),
+ /* 50 */ "ReadCookie" OpHelp(""),
+ /* 51 */ "SetCookie" OpHelp(""),
+ /* 52 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
+ /* 53 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
+ /* 54 */ "OpenAutoindex" OpHelp("nColumn=P2"),
+ /* 55 */ "OpenEphemeral" OpHelp("nColumn=P2"),
+ /* 56 */ "SorterOpen" OpHelp(""),
+ /* 57 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
+ /* 58 */ "Close" OpHelp(""),
+ /* 59 */ "SeekLT" OpHelp(""),
+ /* 60 */ "SeekLE" OpHelp(""),
+ /* 61 */ "SeekGE" OpHelp(""),
+ /* 62 */ "SeekGT" OpHelp(""),
+ /* 63 */ "Seek" OpHelp("intkey=r[P2]"),
+ /* 64 */ "NoConflict" OpHelp("key=r[P3@P4]"),
+ /* 65 */ "NotFound" OpHelp("key=r[P3@P4]"),
+ /* 66 */ "Found" OpHelp("key=r[P3@P4]"),
+ /* 67 */ "NotExists" OpHelp("intkey=r[P3]"),
+ /* 68 */ "Sequence" OpHelp("r[P2]=rowid"),
+ /* 69 */ "NewRowid" OpHelp("r[P2]=rowid"),
+ /* 70 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
+ /* 71 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"),
+ /* 72 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"),
+ /* 73 */ "InsertInt" OpHelp("intkey=P3 data=r[P2]"),
+ /* 74 */ "Delete" OpHelp(""),
+ /* 75 */ "ResetCount" OpHelp(""),
+ /* 76 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"),
+ /* 77 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"),
+ /* 78 */ "Ne" OpHelp("if r[P1]!=r[P3] goto P2"),
+ /* 79 */ "Eq" OpHelp("if r[P1]==r[P3] goto P2"),
+ /* 80 */ "Gt" OpHelp("if r[P1]>r[P3] goto P2"),
+ /* 81 */ "Le" OpHelp("if r[P1]<=r[P3] goto P2"),
+ /* 82 */ "Lt" OpHelp("if r[P1]<r[P3] goto P2"),
+ /* 83 */ "Ge" OpHelp("if r[P1]>=r[P3] goto P2"),
+ /* 84 */ "SorterCompare" OpHelp("if key(P1)!=rtrim(r[P3],P4) goto P2"),
+ /* 85 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
+ /* 86 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
+ /* 87 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
+ /* 88 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
+ /* 89 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
+ /* 90 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
+ /* 91 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
+ /* 92 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
+ /* 93 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
+ /* 94 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
+ /* 95 */ "SorterData" OpHelp("r[P2]=data"),
+ /* 96 */ "BitNot" OpHelp("r[P1]= ~r[P1]"),
+ /* 97 */ "String8" OpHelp("r[P2]='P4'"),
+ /* 98 */ "RowKey" OpHelp("r[P2]=key"),
+ /* 99 */ "RowData" OpHelp("r[P2]=data"),
+ /* 100 */ "Rowid" OpHelp("r[P2]=rowid"),
+ /* 101 */ "NullRow" OpHelp(""),
+ /* 102 */ "Last" OpHelp(""),
+ /* 103 */ "SorterSort" OpHelp(""),
+ /* 104 */ "Sort" OpHelp(""),
+ /* 105 */ "Rewind" OpHelp(""),
+ /* 106 */ "SorterInsert" OpHelp(""),
+ /* 107 */ "IdxInsert" OpHelp("key=r[P2]"),
+ /* 108 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
+ /* 109 */ "IdxRowid" OpHelp("r[P2]=rowid"),
+ /* 110 */ "IdxLE" OpHelp("key=r[P3@P4]"),
+ /* 111 */ "IdxGT" OpHelp("key=r[P3@P4]"),
+ /* 112 */ "IdxLT" OpHelp("key=r[P3@P4]"),
+ /* 113 */ "IdxGE" OpHelp("key=r[P3@P4]"),
+ /* 114 */ "Destroy" OpHelp(""),
+ /* 115 */ "Clear" OpHelp(""),
+ /* 116 */ "CreateIndex" OpHelp("r[P2]=root iDb=P1"),
+ /* 117 */ "CreateTable" OpHelp("r[P2]=root iDb=P1"),
+ /* 118 */ "ParseSchema" OpHelp(""),
+ /* 119 */ "LoadAnalysis" OpHelp(""),
+ /* 120 */ "DropTable" OpHelp(""),
+ /* 121 */ "DropIndex" OpHelp(""),
+ /* 122 */ "DropTrigger" OpHelp(""),
+ /* 123 */ "IntegrityCk" OpHelp(""),
+ /* 124 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
+ /* 125 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"),
+ /* 126 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"),
+ /* 127 */ "Program" OpHelp(""),
+ /* 128 */ "Param" OpHelp(""),
+ /* 129 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
+ /* 130 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"),
+ /* 131 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
+ /* 132 */ "IfPos" OpHelp("if r[P1]>0 goto P2"),
+ /* 133 */ "Real" OpHelp("r[P2]=P4"),
+ /* 134 */ "IfNeg" OpHelp("if r[P1]<0 goto P2"),
+ /* 135 */ "IfZero" OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"),
+ /* 136 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
+ /* 137 */ "IncrVacuum" OpHelp(""),
+ /* 138 */ "Expire" OpHelp(""),
+ /* 139 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
+ /* 140 */ "VBegin" OpHelp(""),
+ /* 141 */ "VCreate" OpHelp(""),
+ /* 142 */ "VDestroy" OpHelp(""),
+ /* 143 */ "ToText" OpHelp(""),
+ /* 144 */ "ToBlob" OpHelp(""),
+ /* 145 */ "ToNumeric" OpHelp(""),
+ /* 146 */ "ToInt" OpHelp(""),
+ /* 147 */ "ToReal" OpHelp(""),
+ /* 148 */ "VOpen" OpHelp(""),
+ /* 149 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
+ /* 150 */ "VNext" OpHelp(""),
+ /* 151 */ "VRename" OpHelp(""),
+ /* 152 */ "Pagecount" OpHelp(""),
+ /* 153 */ "MaxPgcnt" OpHelp(""),
+ /* 154 */ "Init" OpHelp("Start at P2"),
+ /* 155 */ "Noop" OpHelp(""),
+ /* 156 */ "Explain" OpHelp(""),
};
return azName[i];
}
@@ -23186,32 +23569,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
#endif
/*
-** These #defines should enable >2GB file support on Posix if the
-** underlying operating system supports it. If the OS lacks
-** large file support, these should be no-ops.
-**
-** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch
-** on the compiler command line. This is necessary if you are compiling
-** on a recent machine (ex: RedHat 7.2) but you want your code to work
-** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
-** without this option, LFS is enable. But LFS does not exist in the kernel
-** in RedHat 6.0, so the code won't work. Hence, for maximum binary
-** portability you should omit LFS.
-**
-** The previous paragraph was written in 2005. (This paragraph is written
-** on 2008-11-28.) These days, all Linux kernels support large files, so
-** you should probably leave LFS enabled. But some embedded platforms might
-** lack LFS in which case the SQLITE_DISABLE_LFS macro might still be useful.
-*/
-#ifndef SQLITE_DISABLE_LFS
-# define _LARGE_FILE 1
-# ifndef _FILE_OFFSET_BITS
-# define _FILE_OFFSET_BITS 64
-# endif
-# define _LARGEFILE_SOURCE 1
-#endif
-
-/*
** standard include files.
*/
#include <sys/types.h>
@@ -23362,6 +23719,12 @@ struct unixFile {
#endif
};
+/* This variable holds the process id (pid) from when the xRandomness()
+** method was called. If xOpen() is called from a different process id,
+** indicating that a fork() has occurred, the PRNG will be reset.
+*/
+static int randomnessPid = 0;
+
/*
** Allowed values for the unixFile.ctrlFlags bitmask:
*/
@@ -24625,6 +24988,15 @@ static int findInodeInfo(
return SQLITE_OK;
}
+/*
+** Return TRUE if pFile has been renamed or unlinked since it was first opened.
+*/
+static int fileHasMoved(unixFile *pFile){
+ struct stat buf;
+ return pFile->pInode!=0 &&
+ (osStat(pFile->zPath, &buf)!=0 || buf.st_ino!=pFile->pInode->fileId.ino);
+}
+
/*
** Check a unixFile that is a database. Verify the following:
@@ -24659,10 +25031,7 @@ static void verifyDbFile(unixFile *pFile){
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
}
- if( pFile->pInode!=0
- && ((rc = osStat(pFile->zPath, &buf))!=0
- || buf.st_ino!=pFile->pInode->fileId.ino)
- ){
+ if( fileHasMoved(pFile) ){
sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath);
pFile->ctrlFlags |= UNIXFILE_WARNED;
return;
@@ -27111,6 +27480,10 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
return SQLITE_OK;
}
+ case SQLITE_FCNTL_HAS_MOVED: {
+ *(int*)pArg = fileHasMoved(pFile);
+ return SQLITE_OK;
+ }
#if SQLITE_MAX_MMAP_SIZE>0
case SQLITE_FCNTL_MMAP_SIZE: {
i64 newLimit = *(i64*)pArg;
@@ -27391,7 +27764,7 @@ static int unixShmSystemLock(
#ifdef SQLITE_DEBUG
{ u16 mask;
OSTRACE(("SHM-LOCK "));
- mask = ofst>31 ? 0xffffffff : (1<<(ofst+n)) - (1<<ofst);
+ mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<<ofst);
if( rc==SQLITE_OK ){
if( lockType==F_UNLCK ){
OSTRACE(("unlock %d ok", ofst));
@@ -28142,10 +28515,10 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
** may now be invalid and should be unmapped.
*/
static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
+#if SQLITE_MAX_MMAP_SIZE>0
unixFile *pFd = (unixFile *)fd; /* The underlying database file */
UNUSED_PARAMETER(iOff);
-#if SQLITE_MAX_MMAP_SIZE>0
/* If p==0 (unmap the entire file) then there must be no outstanding
** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
** then there must be at least one outstanding. */
@@ -28161,6 +28534,10 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
}
assert( pFd->nFetchOut>=0 );
+#else
+ UNUSED_PARAMETER(fd);
+ UNUSED_PARAMETER(p);
+ UNUSED_PARAMETER(iOff);
#endif
return SQLITE_OK;
}
@@ -28951,6 +29328,16 @@ static int unixOpen(
|| eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
);
+ /* Detect a pid change and reset the PRNG. There is a race condition
+ ** here such that two or more threads all trying to open databases at
+ ** the same instant might all reset the PRNG. But multiple resets
+ ** are harmless.
+ */
+ if( randomnessPid!=getpid() ){
+ randomnessPid = getpid();
+ sqlite3_randomness(0,0);
+ }
+
memset(p, 0, sizeof(unixFile));
if( eType==SQLITE_OPEN_MAIN_DB ){
@@ -29338,18 +29725,18 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
** tests repeatable.
*/
memset(zBuf, 0, nBuf);
+ randomnessPid = getpid();
#if !defined(SQLITE_TEST)
{
- int pid, fd, got;
+ int fd, got;
fd = robust_open("/dev/urandom", O_RDONLY, 0);
if( fd<0 ){
time_t t;
time(&t);
memcpy(zBuf, &t, sizeof(t));
- pid = getpid();
- memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
- assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
- nBuf = sizeof(t) + sizeof(pid);
+ memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid));
+ assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf );
+ nBuf = sizeof(t) + sizeof(randomnessPid);
}else{
do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
robust_close(0, fd, __LINE__);
@@ -34087,7 +34474,7 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
case SQLITE_FCNTL_VFSNAME: {
- *(char**)pArg = sqlite3_mprintf("win32");
+ *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
return SQLITE_OK;
}
@@ -34169,7 +34556,7 @@ static int winDeviceCharacteristics(sqlite3_file *id){
** During sqlite3_os_init() we do a GetSystemInfo()
** to get the granularity size.
*/
-SYSTEM_INFO winSysInfo;
+static SYSTEM_INFO winSysInfo;
#ifndef SQLITE_OMIT_WAL
@@ -34192,7 +34579,7 @@ static void winShmEnterMutex(void){
static void winShmLeaveMutex(void){
sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
-#ifdef SQLITE_DEBUG
+#ifndef NDEBUG
static int winShmMutexHeld(void) {
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
}
@@ -36103,15 +36490,29 @@ static int winFullPathname(
** Interfaces for opening a shared library, finding entry points
** within the shared library, and closing the shared library.
*/
-/*
-** Interfaces for opening a shared library, finding entry points
-** within the shared library, and closing the shared library.
-*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
+#if defined(__CYGWIN__)
+ int nFull = pVfs->mxPathname+1;
+ char *zFull = sqlite3MallocZero( nFull );
+ void *zConverted = 0;
+ if( zFull==0 ){
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+ return 0;
+ }
+ if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
+ sqlite3_free(zFull);
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+ return 0;
+ }
+ zConverted = winConvertFromUtf8Filename(zFull);
+ sqlite3_free(zFull);
+#else
void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
+#endif
if( zConverted==0 ){
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( osIsNT() ){
@@ -36126,6 +36527,7 @@ static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
h = osLoadLibraryA((char*)zConverted);
}
#endif
+ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
sqlite3_free(zConverted);
return (void*)h;
}
@@ -36134,12 +36536,17 @@ static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
}
static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
+ FARPROC proc;
UNUSED_PARAMETER(pVfs);
- return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
+ proc = osGetProcAddressA((HANDLE)pH, zSym);
+ OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
+ (void*)pH, zSym, (void*)proc));
+ return (void(*)(void))proc;
}
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
UNUSED_PARAMETER(pVfs);
osFreeLibrary((HANDLE)pHandle);
+ OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
}
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
#define winDlOpen 0
@@ -36835,7 +37242,8 @@ struct PCache {
int szCache; /* Configured cache size */
int szPage; /* Size of every page in this cache */
int szExtra; /* Size of extra space for each page */
- int bPurgeable; /* True if pages are on backing store */
+ u8 bPurgeable; /* True if pages are on backing store */
+ u8 eCreate; /* eCreate value for for xFetch() */
int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */
void *pStress; /* Argument to xStress */
sqlite3_pcache *pCache; /* Pluggable cache module */
@@ -36902,6 +37310,10 @@ static void pcacheRemoveFromDirtyList(PgHdr *pPage){
}else{
assert( pPage==p->pDirty );
p->pDirty = pPage->pDirtyNext;
+ if( p->pDirty==0 && p->bPurgeable ){
+ assert( p->eCreate==1 );
+ p->eCreate = 2;
+ }
}
pPage->pDirtyNext = 0;
pPage->pDirtyPrev = 0;
@@ -36922,6 +37334,9 @@ static void pcacheAddToDirtyList(PgHdr *pPage){
if( pPage->pDirtyNext ){
assert( pPage->pDirtyNext->pDirtyPrev==0 );
pPage->pDirtyNext->pDirtyPrev = pPage;
+ }else if( p->bPurgeable ){
+ assert( p->eCreate==2 );
+ p->eCreate = 1;
}
p->pDirty = pPage;
if( !p->pDirtyTail ){
@@ -36991,6 +37406,7 @@ SQLITE_PRIVATE void sqlite3PcacheOpen(
p->szPage = szPage;
p->szExtra = szExtra;
p->bPurgeable = bPurgeable;
+ p->eCreate = 2;
p->xStress = xStress;
p->pStress = pStress;
p->szCache = 100;
@@ -37030,7 +37446,7 @@ SQLITE_PRIVATE int sqlite3PcacheFetch(
int createFlag, /* If true, create page if it does not exist already */
PgHdr **ppPage /* Write the page here */
){
- sqlite3_pcache_page *pPage = 0;
+ sqlite3_pcache_page *pPage;
PgHdr *pPgHdr = 0;
int eCreate;
@@ -37041,8 +37457,12 @@ SQLITE_PRIVATE int sqlite3PcacheFetch(
/* If the pluggable cache (sqlite3_pcache*) has not been allocated,
** allocate it now.
*/
- if( !pCache->pCache && createFlag ){
+ if( !pCache->pCache ){
sqlite3_pcache *p;
+ if( !createFlag ){
+ *ppPage = 0;
+ return SQLITE_OK;
+ }
p = sqlite3GlobalConfig.pcache2.xCreate(
pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
);
@@ -37053,11 +37473,16 @@ SQLITE_PRIVATE int sqlite3PcacheFetch(
pCache->pCache = p;
}
- eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty));
- if( pCache->pCache ){
- pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
- }
-
+ /* eCreate defines what to do if the page does not exist.
+ ** 0 Do not allocate a new page. (createFlag==0)
+ ** 1 Allocate a new page if doing so is inexpensive.
+ ** (createFlag==1 AND bPurgeable AND pDirty)
+ ** 2 Allocate a new page even it doing so is difficult.
+ ** (createFlag==1 AND !(bPurgeable AND pDirty)
+ */
+ eCreate = createFlag==0 ? 0 : pCache->eCreate;
+ assert( (createFlag*(1+(!pCache->bPurgeable||!pCache->pDirty)))==eCreate );
+ pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
if( !pPage && eCreate==1 ){
PgHdr *pPg;
@@ -37529,6 +37954,7 @@ struct PCache1 {
struct PgHdr1 {
sqlite3_pcache_page page;
unsigned int iKey; /* Key value (page number) */
+ u8 isPinned; /* Page in use, not on the LRU list */
PgHdr1 *pNext; /* Next in hash table chain */
PCache1 *pCache; /* Cache that currently owns this page */
PgHdr1 *pLruNext; /* Next in LRU list of unpinned pages */
@@ -37857,34 +38283,32 @@ static int pcache1ResizeHash(PCache1 *p){
** LRU list, then this function is a no-op.
**
** The PGroup mutex must be held when this function is called.
-**
-** If pPage is NULL then this routine is a no-op.
*/
static void pcache1PinPage(PgHdr1 *pPage){
PCache1 *pCache;
PGroup *pGroup;
- if( pPage==0 ) return;
+ assert( pPage!=0 );
+ assert( pPage->isPinned==0 );
pCache = pPage->pCache;
pGroup = pCache->pGroup;
+ assert( pPage->pLruNext || pPage==pGroup->pLruTail );
+ assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
assert( sqlite3_mutex_held(pGroup->mutex) );
- if( pPage->pLruNext || pPage==pGroup->pLruTail ){
- if( pPage->pLruPrev ){
- pPage->pLruPrev->pLruNext = pPage->pLruNext;
- }
- if( pPage->pLruNext ){
- pPage->pLruNext->pLruPrev = pPage->pLruPrev;
- }
- if( pGroup->pLruHead==pPage ){
- pGroup->pLruHead = pPage->pLruNext;
- }
- if( pGroup->pLruTail==pPage ){
- pGroup->pLruTail = pPage->pLruPrev;
- }
- pPage->pLruNext = 0;
- pPage->pLruPrev = 0;
- pPage->pCache->nRecyclable--;
+ if( pPage->pLruPrev ){
+ pPage->pLruPrev->pLruNext = pPage->pLruNext;
+ }else{
+ pGroup->pLruHead = pPage->pLruNext;
}
+ if( pPage->pLruNext ){
+ pPage->pLruNext->pLruPrev = pPage->pLruPrev;
+ }else{
+ pGroup->pLruTail = pPage->pLruPrev;
+ }
+ pPage->pLruNext = 0;
+ pPage->pLruPrev = 0;
+ pPage->isPinned = 1;
+ pCache->nRecyclable--;
}
@@ -37916,6 +38340,7 @@ static void pcache1EnforceMaxPage(PGroup *pGroup){
while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
PgHdr1 *p = pGroup->pLruTail;
assert( p->pCache->pGroup==pGroup );
+ assert( p->isPinned==0 );
pcache1PinPage(p);
pcache1RemoveFromHash(p);
pcache1FreePage(p);
@@ -37943,7 +38368,7 @@ static void pcache1TruncateUnsafe(
if( pPage->iKey>=iLimit ){
pCache->nPage--;
*pp = pPage->pNext;
- pcache1PinPage(pPage);
+ if( !pPage->isPinned ) pcache1PinPage(pPage);
pcache1FreePage(pPage);
}else{
pp = &pPage->pNext;
@@ -38153,6 +38578,7 @@ static sqlite3_pcache_page *pcache1Fetch(
PGroup *pGroup;
PgHdr1 *pPage = 0;
+ assert( offsetof(PgHdr1,page)==0 );
assert( pCache->bPurgeable || createFlag!=1 );
assert( pCache->bPurgeable || pCache->nMin==0 );
assert( pCache->bPurgeable==0 || pCache->nMin==10 );
@@ -38166,8 +38592,11 @@ static sqlite3_pcache_page *pcache1Fetch(
}
/* Step 2: Abort if no existing page is found and createFlag is 0 */
- if( pPage || createFlag==0 ){
- pcache1PinPage(pPage);
+ if( pPage ){
+ if( !pPage->isPinned ) pcache1PinPage(pPage);
+ goto fetch_out;
+ }
+ if( createFlag==0 ){
goto fetch_out;
}
@@ -38208,6 +38637,7 @@ static sqlite3_pcache_page *pcache1Fetch(
)){
PCache1 *pOther;
pPage = pGroup->pLruTail;
+ assert( pPage->isPinned==0 );
pcache1RemoveFromHash(pPage);
pcache1PinPage(pPage);
pOther = pPage->pCache;
@@ -38244,6 +38674,7 @@ static sqlite3_pcache_page *pcache1Fetch(
pPage->pCache = pCache;
pPage->pLruPrev = 0;
pPage->pLruNext = 0;
+ pPage->isPinned = 1;
*(void **)pPage->page.pExtra = 0;
pCache->apHash[h] = pPage;
}
@@ -38253,7 +38684,7 @@ fetch_out:
pCache->iMaxKey = iKey;
}
pcache1LeaveMutex(pGroup);
- return &pPage->page;
+ return (sqlite3_pcache_page*)pPage;
}
@@ -38279,6 +38710,7 @@ static void pcache1Unpin(
*/
assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
+ assert( pPage->isPinned==1 );
if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
pcache1RemoveFromHash(pPage);
@@ -38294,6 +38726,7 @@ static void pcache1Unpin(
pGroup->pLruHead = pPage;
}
pCache->nRecyclable++;
+ pPage->isPinned = 0;
}
pcache1LeaveMutex(pCache->pGroup);
@@ -38420,6 +38853,7 @@ SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
#ifdef SQLITE_PCACHE_SEPARATE_HEADER
nFree += sqlite3MemSize(p);
#endif
+ assert( p->isPinned==0 );
pcache1PinPage(p);
pcache1RemoveFromHash(p);
pcache1FreePage(p);
@@ -38444,6 +38878,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
PgHdr1 *p;
int nRecyclable = 0;
for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
+ assert( p->isPinned==0 );
nRecyclable++;
}
*pnCurrent = pcache1.grp.nCurrentPage;
@@ -40130,15 +40565,12 @@ static char *print_pager_state(Pager *p){
static int subjRequiresPage(PgHdr *pPg){
Pager *pPager = pPg->pPager;
PagerSavepoint *p;
- Pgno pgno;
+ Pgno pgno = pPg->pgno;
int i;
- if( pPager->nSavepoint ){
- pgno = pPg->pgno;
- for(i=0; i<pPager->nSavepoint; i++){
- p = &pPager->aSavepoint[i];
- if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
- return 1;
- }
+ for(i=0; i<pPager->nSavepoint; i++){
+ p = &pPager->aSavepoint[i];
+ if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
+ return 1;
}
}
return 0;
@@ -40147,8 +40579,8 @@ static int subjRequiresPage(PgHdr *pPg){
/*
** Return true if the page is already in the journal file.
*/
-static int pageInJournal(PgHdr *pPg){
- return sqlite3BitvecTest(pPg->pPager->pInJournal, pPg->pgno);
+static int pageInJournal(Pager *pPager, PgHdr *pPg){
+ return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno);
}
/*
@@ -40355,6 +40787,7 @@ static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
|| szJ<16
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
|| len>=nMaster
+ || len==0
|| SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
|| SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
|| memcmp(aMagic, aJournalMagic, 8)
@@ -40791,7 +41224,7 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
** already in memory.
*/
static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
- PgHdr *p; /* Return value */
+ PgHdr *p = 0; /* Return value */
/* It is not possible for a call to PcacheFetch() with createFlag==0 to
** fail, since no attempt to allocate dynamic memory will be made.
@@ -41095,7 +41528,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
PgHdr *p = pager_lookup(pPager, 1);
if( p ){
p->pageHash = 0;
- sqlite3PagerUnref(p);
+ sqlite3PagerUnrefNotNull(p);
}
}
#endif
@@ -41124,6 +41557,11 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
rc = pager_truncate(pPager, pPager->dbSize);
}
+ if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+ }
+
if( !pPager->exclusiveMode
&& (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
){
@@ -41937,7 +42375,7 @@ end_playback:
if( rc==SQLITE_OK
&& (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
){
- rc = sqlite3PagerSync(pPager);
+ rc = sqlite3PagerSync(pPager, 0);
}
if( rc==SQLITE_OK ){
rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
@@ -42083,7 +42521,7 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){
if( rc==SQLITE_OK ){
pPager->xReiniter(pPg);
}
- sqlite3PagerUnref(pPg);
+ sqlite3PagerUnrefNotNull(pPg);
}
}
@@ -43438,7 +43876,7 @@ static int subjournalPage(PgHdr *pPg){
assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
assert( pagerUseWal(pPager)
- || pageInJournal(pPg)
+ || pageInJournal(pPager, pPg)
|| pPg->pgno>pPager->dbOrigSize
);
rc = openSubJournal(pPager);
@@ -43903,6 +44341,30 @@ SQLITE_PRIVATE int sqlite3PagerOpen(
}
+/* Verify that the database file has not be deleted or renamed out from
+** under the pager. Return SQLITE_OK if the database is still were it ought
+** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error
+** code from sqlite3OsAccess()) if the database has gone missing.
+*/
+static int databaseIsUnmoved(Pager *pPager){
+ int bHasMoved = 0;
+ int rc;
+
+ if( pPager->tempFile ) return SQLITE_OK;
+ if( pPager->dbSize==0 ) return SQLITE_OK;
+ assert( pPager->zFilename && pPager->zFilename[0] );
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
+ if( rc==SQLITE_NOTFOUND ){
+ /* If the HAS_MOVED file-control is unimplemented, assume that the file
+ ** has not been moved. That is the historical behavior of SQLite: prior to
+ ** version 3.8.3, it never checked */
+ rc = SQLITE_OK;
+ }else if( rc==SQLITE_OK && bHasMoved ){
+ rc = SQLITE_READONLY_DBMOVED;
+ }
+ return rc;
+}
+
/*
** This function is called after transitioning from PAGER_UNLOCK to
@@ -43968,15 +44430,17 @@ static int hasHotJournal(Pager *pPager, int *pExists){
if( rc==SQLITE_OK && !locked ){
Pgno nPage; /* Number of pages in database file */
- /* Check the size of the database file. If it consists of 0 pages,
- ** then delete the journal file. See the header comment above for
- ** the reasoning here. Delete the obsolete journal file under
- ** a RESERVED lock to avoid race conditions and to avoid violating
- ** [H33020].
- */
rc = pagerPagecount(pPager, &nPage);
if( rc==SQLITE_OK ){
- if( nPage==0 ){
+ /* If the database is zero pages in size, that means that either (1) the
+ ** journal is a remnant from a prior database with the same name where
+ ** the database file but not the journal was deleted, or (2) the initial
+ ** transaction that populates a new database is being rolled back.
+ ** In either case, the journal file can be deleted. However, take care
+ ** not to delete the journal file if it is already open due to
+ ** journal_mode=PERSIST.
+ */
+ if( nPage==0 && !jrnlOpen ){
sqlite3BeginBenignMalloc();
if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
sqlite3OsDelete(pVfs, pPager->zJournal, 0);
@@ -44374,7 +44838,7 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
if( rc!=SQLITE_OK ) goto pager_acquire_err;
}
- if( iFrame==0 && bMmapOk ){
+ if( bMmapOk && iFrame==0 ){
void *pData = 0;
rc = sqlite3OsFetch(pPager->fd,
@@ -44515,16 +44979,19 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
** are released, a rollback occurs and the lock on the database is
** removed.
*/
-SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
- if( pPg ){
- Pager *pPager = pPg->pPager;
- if( pPg->flags & PGHDR_MMAP ){
- pagerReleaseMapPage(pPg);
- }else{
- sqlite3PcacheRelease(pPg);
- }
- pagerUnlockIfUnused(pPager);
+SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
+ Pager *pPager;
+ assert( pPg!=0 );
+ pPager = pPg->pPager;
+ if( pPg->flags & PGHDR_MMAP ){
+ pagerReleaseMapPage(pPg);
+ }else{
+ sqlite3PcacheRelease(pPg);
}
+ pagerUnlockIfUnused(pPager);
+}
+SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
+ if( pPg ) sqlite3PagerUnrefNotNull(pPg);
}
/*
@@ -44579,13 +45046,19 @@ static int pager_open_journal(Pager *pPager){
(SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
(SQLITE_OPEN_MAIN_JOURNAL)
);
- #ifdef SQLITE_ENABLE_ATOMIC_WRITE
- rc = sqlite3JournalOpen(
- pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
- );
- #else
- rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
- #endif
+
+ /* Verify that the database still has the same name as it did when
+ ** it was originally opened. */
+ rc = databaseIsUnmoved(pPager);
+ if( rc==SQLITE_OK ){
+#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+ rc = sqlite3JournalOpen(
+ pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
+ );
+#else
+ rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
+#endif
+ }
}
assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
}
@@ -44706,9 +45179,9 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory
** of any open savepoints as appropriate.
*/
static int pager_write(PgHdr *pPg){
- void *pData = pPg->pData;
Pager *pPager = pPg->pPager;
int rc = SQLITE_OK;
+ int inJournal;
/* This routine is not called unless a write-transaction has already
** been started. The journal file may or may not be open at this point.
@@ -44719,14 +45192,8 @@ static int pager_write(PgHdr *pPg){
|| pPager->eState==PAGER_WRITER_DBMOD
);
assert( assert_pager_state(pPager) );
-
- /* If an error has been previously detected, report the same error
- ** again. This should not happen, but the check provides robustness. */
- if( NEVER(pPager->errCode) ) return pPager->errCode;
-
- /* Higher-level routines never call this function if database is not
- ** writable. But check anyway, just for robustness. */
- if( NEVER(pPager->readOnly) ) return SQLITE_PERM;
+ assert( pPager->errCode==0 );
+ assert( pPager->readOnly==0 );
CHECK_PAGE(pPg);
@@ -44750,7 +45217,8 @@ static int pager_write(PgHdr *pPg){
** to the journal then we can return right away.
*/
sqlite3PcacheMakeDirty(pPg);
- if( pageInJournal(pPg) && !subjRequiresPage(pPg) ){
+ inJournal = pageInJournal(pPager, pPg);
+ if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){
assert( !pagerUseWal(pPager) );
}else{
@@ -44758,7 +45226,7 @@ static int pager_write(PgHdr *pPg){
** EXCLUSIVE lock on the main database file. Write the current page to
** the transaction journal if it is not there already.
*/
- if( !pageInJournal(pPg) && !pagerUseWal(pPager) ){
+ if( !inJournal && !pagerUseWal(pPager) ){
assert( pagerUseWal(pPager)==0 );
if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
u32 cksum;
@@ -44771,7 +45239,7 @@ static int pager_write(PgHdr *pPg){
assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
assert( pPager->journalHdr<=pPager->journalOff );
- CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+ CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
cksum = pager_cksum(pPager, (u8*)pData2);
/* Even if an IO or diskfull error occurs while journalling the
@@ -44823,7 +45291,7 @@ static int pager_write(PgHdr *pPg){
** the statement journal format differs from the standard journal format
** in that it omits the checksums and the header.
*/
- if( subjRequiresPage(pPg) ){
+ if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){
rc = subjournalPage(pPg);
}
}
@@ -44855,19 +45323,19 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
PgHdr *pPg = pDbPage;
Pager *pPager = pPg->pPager;
- Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
assert( (pPg->flags & PGHDR_MMAP)==0 );
assert( pPager->eState>=PAGER_WRITER_LOCKED );
assert( pPager->eState!=PAGER_ERROR );
assert( assert_pager_state(pPager) );
- if( nPagePerSector>1 ){
+ if( pPager->sectorSize > (u32)pPager->pageSize ){
Pgno nPageCount; /* Total number of pages in database file */
Pgno pg1; /* First page of the sector pPg is located on. */
int nPage = 0; /* Number of pages starting at pg1 to journal */
int ii; /* Loop counter */
int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */
+ Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
/* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
** a journal header to be written between the pages journaled by
@@ -44906,14 +45374,14 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
if( pPage->flags&PGHDR_NEED_SYNC ){
needSync = 1;
}
- sqlite3PagerUnref(pPage);
+ sqlite3PagerUnrefNotNull(pPage);
}
}
}else if( (pPage = pager_lookup(pPager, pg))!=0 ){
if( pPage->flags&PGHDR_NEED_SYNC ){
needSync = 1;
}
- sqlite3PagerUnref(pPage);
+ sqlite3PagerUnrefNotNull(pPage);
}
}
@@ -44929,7 +45397,7 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
PgHdr *pPage = pager_lookup(pPager, pg1+ii);
if( pPage ){
pPage->flags |= PGHDR_NEED_SYNC;
- sqlite3PagerUnref(pPage);
+ sqlite3PagerUnrefNotNull(pPage);
}
}
}
@@ -45082,17 +45550,17 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
** If successful, or if called on a pager for which it is a no-op, this
** function returns SQLITE_OK. Otherwise, an IO error code is returned.
*/
-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){
+SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
int rc = SQLITE_OK;
- if( !pPager->noSync ){
+
+ if( isOpen(pPager->fd) ){
+ void *pArg = (void*)zMaster;
+ rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
+ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+ }
+ if( rc==SQLITE_OK && !pPager->noSync ){
assert( !MEMDB );
rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
- }else if( isOpen(pPager->fd) ){
- assert( !MEMDB );
- rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0);
- if( rc==SQLITE_NOTFOUND ){
- rc = SQLITE_OK;
- }
}
return rc;
}
@@ -45291,7 +45759,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
/* Finally, sync the database file. */
if( !noSync ){
- rc = sqlite3PagerSync(pPager);
+ rc = sqlite3PagerSync(pPager, zMaster);
}
IOTRACE(("DBSYNC %p\n", pPager))
}
@@ -45420,7 +45888,9 @@ SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
- || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR );
+ || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR
+ || rc==SQLITE_CANTOPEN
+ );
/* If an error occurs during a ROLLBACK, we can no longer trust the pager
** cache. So call pager_error() on the way out to make any error persistent.
@@ -45823,7 +46293,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
needSyncPgno = pPg->pgno;
assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
- pageInJournal(pPg) || pPg->pgno>pPager->dbOrigSize );
+ pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
assert( pPg->flags&PGHDR_DIRTY );
}
@@ -45857,7 +46327,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
if( MEMDB ){
assert( pPgOld );
sqlite3PcacheMove(pPgOld, origPgno);
- sqlite3PagerUnref(pPgOld);
+ sqlite3PagerUnrefNotNull(pPgOld);
}
if( needSyncPgno ){
@@ -45886,7 +46356,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
}
pPgHdr->flags |= PGHDR_NEED_SYNC;
sqlite3PcacheMakeDirty(pPgHdr);
- sqlite3PagerUnref(pPgHdr);
+ sqlite3PagerUnrefNotNull(pPgHdr);
}
return SQLITE_OK;
@@ -47602,7 +48072,7 @@ SQLITE_PRIVATE int sqlite3WalOpen(
sqlite3OsClose(pRet->pWalFd);
sqlite3_free(pRet);
}else{
- int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd);
+ int iDC = sqlite3OsDeviceCharacteristics(pDbFd);
if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
pRet->padToSectorBoundary = 0;
@@ -48973,7 +49443,7 @@ static int walWriteToLog(
iAmt -= iFirstAmt;
pContent = (void*)(iFirstAmt + (char*)pContent);
assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
- rc = sqlite3OsSync(p->pFd, p->syncFlags);
+ rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
if( iAmt==0 || rc ) return rc;
}
rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
@@ -49911,7 +50381,6 @@ struct BtCursor {
Pgno *aOverflow; /* Cache of overflow page locations */
#endif
Pgno pgnoRoot; /* The root page of this tree */
- sqlite3_int64 cachedRowid; /* Next rowid cache. 0 means not valid */
CellInfo info; /* A parse of the cell we are pointing at */
i64 nKey; /* Size of pKey, or last integer key */
void *pKey; /* Saved key that was cursor's last known position */
@@ -51895,13 +52364,12 @@ static void zeroPage(MemPage *pPage, int flags){
memset(&data[hdr], 0, pBt->usableSize - hdr);
}
data[hdr] = (char)flags;
- first = hdr + 8 + 4*((flags&PTF_LEAF)==0 ?1:0);
+ first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8);
memset(&data[hdr+1], 0, 4);
data[hdr+7] = 0;
put2byte(&data[hdr+5], pBt->usableSize);
pPage->nFree = (u16)(pBt->usableSize - first);
decodeFlags(pPage, flags);
- pPage->hdrOffset = hdr;
pPage->cellOffset = first;
pPage->aDataEnd = &data[pBt->usableSize];
pPage->aCellIdx = &data[first];
@@ -52005,7 +52473,7 @@ static int getAndInitPage(
rc = SQLITE_CORRUPT_BKPT;
}else{
rc = btreeGetPage(pBt, pgno, ppPage, bReadonly);
- if( rc==SQLITE_OK ){
+ if( rc==SQLITE_OK && (*ppPage)->isInit==0 ){
rc = btreeInitPage(*ppPage);
if( rc!=SQLITE_OK ){
releasePage(*ppPage);
@@ -52026,10 +52494,11 @@ static void releasePage(MemPage *pPage){
if( pPage ){
assert( pPage->aData );
assert( pPage->pBt );
+ assert( pPage->pDbPage!=0 );
assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage );
assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
- sqlite3PagerUnref(pPage->pDbPage);
+ sqlite3PagerUnrefNotNull(pPage->pDbPage);
}
}
@@ -53984,7 +54453,6 @@ static int btreeCursor(
}
pBt->pCursor = pCur;
pCur->eState = CURSOR_INVALID;
- pCur->cachedRowid = 0;
return SQLITE_OK;
}
SQLITE_PRIVATE int sqlite3BtreeCursor(
@@ -54026,36 +54494,6 @@ SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){
}
/*
-** Set the cached rowid value of every cursor in the same database file
-** as pCur and having the same root page number as pCur. The value is
-** set to iRowid.
-**
-** Only positive rowid values are considered valid for this cache.
-** The cache is initialized to zero, indicating an invalid cache.
-** A btree will work fine with zero or negative rowids. We just cannot
-** cache zero or negative rowids, which means tables that use zero or
-** negative rowids might run a little slower. But in practice, zero
-** or negative rowids are very uncommon so this should not be a problem.
-*/
-SQLITE_PRIVATE void sqlite3BtreeSetCachedRowid(BtCursor *pCur, sqlite3_int64 iRowid){
- BtCursor *p;
- for(p=pCur->pBt->pCursor; p; p=p->pNext){
- if( p->pgnoRoot==pCur->pgnoRoot ) p->cachedRowid = iRowid;
- }
- assert( pCur->cachedRowid==iRowid );
-}
-
-/*
-** Return the cached rowid for the given cursor. A negative or zero
-** return value indicates that the rowid cache is invalid and should be
-** ignored. If the rowid cache has never before been set, then a
-** zero is returned.
-*/
-SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeGetCachedRowid(BtCursor *pCur){
- return pCur->cachedRowid;
-}
-
-/*
** Close a cursor. The read lock on the database file is released
** when the last cursor is closed.
*/
@@ -54106,7 +54544,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
int iPage = pCur->iPage;
memset(&info, 0, sizeof(info));
btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info);
- assert( memcmp(&info, &pCur->info, sizeof(info))==0 );
+ assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
}
#else
#define assertCellInfo(x)
@@ -54545,10 +54983,10 @@ SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *p
/*
** Return a pointer to payload information from the entry that the
** pCur cursor is pointing to. The pointer is to the beginning of
-** the key if skipKey==0 and it points to the beginning of data if
-** skipKey==1. The number of bytes of available key/data is written
-** into *pAmt. If *pAmt==0, then the value returned will not be
-** a valid pointer.
+** the key if index btrees (pPage->intKey==0) and is the data for
+** table btrees (pPage->intKey==1). The number of bytes of available
+** key/data is written into *pAmt. If *pAmt==0, then the value
+** returned will not be a valid pointer.
**
** This routine is an optimization. It is common for the entire key
** and data to fit on the local page and for there to be no overflow
@@ -54561,41 +54999,21 @@ SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *p
** page of the database. The data might change or move the next time
** any btree routine is called.
*/
-static const unsigned char *fetchPayload(
+static const void *fetchPayload(
BtCursor *pCur, /* Cursor pointing to entry to read from */
- u32 *pAmt, /* Write the number of available bytes here */
- int skipKey /* read beginning at data if this is true */
+ u32 *pAmt /* Write the number of available bytes here */
){
- unsigned char *aPayload;
- MemPage *pPage;
- u32 nKey;
- u32 nLocal;
-
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
+ assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
assert( cursorHoldsMutex(pCur) );
- pPage = pCur->apPage[pCur->iPage];
- assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
+ assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
if( pCur->info.nSize==0 ){
btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
&pCur->info);
}
- aPayload = pCur->info.pCell;
- aPayload += pCur->info.nHeader;
- if( pPage->intKey ){
- nKey = 0;
- }else{
- nKey = (int)pCur->info.nKey;
- }
- if( skipKey ){
- aPayload += nKey;
- nLocal = pCur->info.nLocal - nKey;
- }else{
- nLocal = pCur->info.nLocal;
- assert( nLocal<=nKey );
- }
- *pAmt = nLocal;
- return aPayload;
+ *pAmt = pCur->info.nLocal;
+ return (void*)(pCur->info.pCell + pCur->info.nHeader);
}
@@ -54614,22 +55032,10 @@ static const unsigned char *fetchPayload(
** in the common case where no overflow pages are used.
*/
SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){
- const void *p = 0;
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( cursorHoldsMutex(pCur) );
- if( ALWAYS(pCur->eState==CURSOR_VALID) ){
- p = (const void*)fetchPayload(pCur, pAmt, 0);
- }
- return p;
+ return fetchPayload(pCur, pAmt);
}
SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){
- const void *p = 0;
- assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
- assert( cursorHoldsMutex(pCur) );
- if( ALWAYS(pCur->eState==CURSOR_VALID) ){
- p = (const void*)fetchPayload(pCur, pAmt, 1);
- }
- return p;
+ return fetchPayload(pCur, pAmt);
}
@@ -54748,8 +55154,6 @@ static void moveToParent(BtCursor *pCur){
static int moveToRoot(BtCursor *pCur){
MemPage *pRoot;
int rc = SQLITE_OK;
- Btree *p = pCur->pBtree;
- BtShared *pBt = p->pBt;
assert( cursorHoldsMutex(pCur) );
assert( CURSOR_INVALID < CURSOR_REQUIRESEEK );
@@ -54764,56 +55168,52 @@ static int moveToRoot(BtCursor *pCur){
}
if( pCur->iPage>=0 ){
- int i;
- for(i=1; i<=pCur->iPage; i++){
- releasePage(pCur->apPage[i]);
- }
- pCur->iPage = 0;
+ while( pCur->iPage ) releasePage(pCur->apPage[pCur->iPage--]);
}else if( pCur->pgnoRoot==0 ){
pCur->eState = CURSOR_INVALID;
return SQLITE_OK;
}else{
- rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0],
+ rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->apPage[0],
pCur->wrFlag==0 ? PAGER_GET_READONLY : 0);
if( rc!=SQLITE_OK ){
pCur->eState = CURSOR_INVALID;
return rc;
}
pCur->iPage = 0;
-
- /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
- ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
- ** NULL, the caller expects a table b-tree. If this is not the case,
- ** return an SQLITE_CORRUPT error. */
- assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 );
- if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){
- return SQLITE_CORRUPT_BKPT;
- }
}
-
- /* Assert that the root page is of the correct type. This must be the
- ** case as the call to this function that loaded the root-page (either
- ** this call or a previous invocation) would have detected corruption
- ** if the assumption were not true, and it is not possible for the flags
- ** byte to have been modified while this cursor is holding a reference
- ** to the page. */
pRoot = pCur->apPage[0];
assert( pRoot->pgno==pCur->pgnoRoot );
- assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey );
+
+ /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor
+ ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is
+ ** NULL, the caller expects a table b-tree. If this is not the case,
+ ** return an SQLITE_CORRUPT error.
+ **
+ ** Earlier versions of SQLite assumed that this test could not fail
+ ** if the root page was already loaded when this function was called (i.e.
+ ** if pCur->iPage>=0). But this is not so if the database is corrupted
+ ** in such a way that page pRoot is linked into a second b-tree table
+ ** (or the freelist). */
+ assert( pRoot->intKey==1 || pRoot->intKey==0 );
+ if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){
+ return SQLITE_CORRUPT_BKPT;
+ }
pCur->aiIdx[0] = 0;
pCur->info.nSize = 0;
pCur->atLast = 0;
pCur->validNKey = 0;
- if( pRoot->nCell==0 && !pRoot->leaf ){
+ if( pRoot->nCell>0 ){
+ pCur->eState = CURSOR_VALID;
+ }else if( !pRoot->leaf ){
Pgno subpage;
if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT;
subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]);
pCur->eState = CURSOR_VALID;
rc = moveToChild(pCur, subpage);
}else{
- pCur->eState = ((pRoot->nCell>0)?CURSOR_VALID:CURSOR_INVALID);
+ pCur->eState = CURSOR_INVALID;
}
return rc;
}
@@ -54969,6 +55369,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
int *pRes /* Write search results here */
){
int rc;
+ RecordCompare xRecordCompare;
assert( cursorHoldsMutex(pCur) );
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
@@ -54990,6 +55391,16 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
}
}
+ if( pIdxKey ){
+ xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
+ assert( pIdxKey->default_rc==1
+ || pIdxKey->default_rc==0
+ || pIdxKey->default_rc==-1
+ );
+ }else{
+ xRecordCompare = 0; /* All keys are integers */
+ }
+
rc = moveToRoot(pCur);
if( rc ){
return rc;
@@ -55022,7 +55433,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
assert( biasRight==0 || biasRight==1 );
idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
pCur->aiIdx[pCur->iPage] = (u16)idx;
- if( pPage->intKey ){
+ if( xRecordCompare==0 ){
for(;;){
i64 nCellKey;
pCell = findCell(pPage, idx) + pPage->childPtrSize;
@@ -55069,22 +55480,19 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
** 2 bytes of the cell.
*/
nCell = pCell[0];
- if( nCell<=pPage->max1bytePayload
- /* && (pCell+nCell)<pPage->aDataEnd */
- ){
+ if( nCell<=pPage->max1bytePayload ){
/* This branch runs if the record-size field of the cell is a
** single byte varint and the record fits entirely on the main
** b-tree page. */
testcase( pCell+nCell+1==pPage->aDataEnd );
- c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
+ c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey, 0);
}else if( !(pCell[1] & 0x80)
&& (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
- /* && (pCell+nCell+2)<=pPage->aDataEnd */
){
/* The record-size field is a 2 byte varint and the record
** fits entirely on the main b-tree page. */
testcase( pCell+nCell+2==pPage->aDataEnd );
- c = sqlite3VdbeRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
+ c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey, 0);
}else{
/* The record flows over onto one or more overflow pages. In
** this case the whole cell needs to be parsed, a buffer allocated
@@ -55105,7 +55513,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
sqlite3_free(pCellKey);
goto moveto_finish;
}
- c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
+ c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
sqlite3_free(pCellKey);
}
if( c<0 ){
@@ -55170,6 +55578,15 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
** successful then set *pRes=0. If the cursor
** was already pointing to the last entry in the database before
** this routine was called, then set *pRes=1.
+**
+** The calling function will set *pRes to 0 or 1. The initial *pRes value
+** will be 1 if the cursor being stepped corresponds to an SQL index and
+** if this routine could have been skipped if that SQL index had been
+** a unique index. Otherwise the caller will have set *pRes to zero.
+** Zero is the common case. The btree implementation is free to use the
+** initial *pRes value as a hint to improve performance, but the current
+** SQLite btree implementation does not. (Note that the comdb2 btree
+** implementation does use this hint, however.)
*/
SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
int rc;
@@ -55178,6 +55595,7 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
assert( cursorHoldsMutex(pCur) );
assert( pRes!=0 );
+ assert( *pRes==0 || *pRes==1 );
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
if( pCur->eState!=CURSOR_VALID ){
rc = restoreCursorPosition(pCur);
@@ -55256,6 +55674,15 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
** successful then set *pRes=0. If the cursor
** was already pointing to the first entry in the database before
** this routine was called, then set *pRes=1.
+**
+** The calling function will set *pRes to 0 or 1. The initial *pRes value
+** will be 1 if the cursor being stepped corresponds to an SQL index and
+** if this routine could have been skipped if that SQL index had been
+** a unique index. Otherwise the caller will have set *pRes to zero.
+** Zero is the common case. The btree implementation is free to use the
+** initial *pRes value as a hint to improve performance, but the current
+** SQLite btree implementation does not. (Note that the comdb2 btree
+** implementation does use this hint, however.)
*/
SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
int rc;
@@ -55263,6 +55690,7 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
assert( cursorHoldsMutex(pCur) );
assert( pRes!=0 );
+ assert( *pRes==0 || *pRes==1 );
assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
pCur->atLast = 0;
if( pCur->eState!=CURSOR_VALID ){
@@ -55642,6 +56070,7 @@ end_allocate_page:
if( rc==SQLITE_OK ){
if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
releasePage(*ppPage);
+ *ppPage = 0;
return SQLITE_CORRUPT_BKPT;
}
(*ppPage)->isInit = 0;
@@ -55903,7 +56332,7 @@ static int fillInCell(
nHeader += 4;
}
if( pPage->hasData ){
- nHeader += putVarint(&pCell[nHeader], nData+nZero);
+ nHeader += putVarint32(&pCell[nHeader], nData+nZero);
}else{
nData = nZero = 0;
}
@@ -56031,7 +56460,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
u32 pc; /* Offset to cell content of cell being deleted */
u8 *data; /* pPage->aData */
u8 *ptr; /* Used to move bytes around within data[] */
- u8 *endPtr; /* End of loop */
int rc; /* The return code */
int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
@@ -56056,13 +56484,8 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
*pRC = rc;
return;
}
- endPtr = &pPage->aCellIdx[2*pPage->nCell - 2];
- assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
- while( ptr<endPtr ){
- *(u16*)ptr = *(u16*)&ptr[2];
- ptr += 2;
- }
pPage->nCell--;
+ memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
put2byte(&data[hdr+3], pPage->nCell);
pPage->nFree += 2;
}
@@ -56099,9 +56522,6 @@ static void insertCell(
int ins; /* Index in data[] where new cell pointer is inserted */
int cellOffset; /* Address of first cell pointer in data[] */
u8 *data; /* The content of the whole page */
- u8 *ptr; /* Used for moving information around in data[] */
- u8 *endPtr; /* End of the loop */
-
int nSkip = (iChild ? 4 : 0);
if( *pRC ) return;
@@ -56152,13 +56572,7 @@ static void insertCell(
if( iChild ){
put4byte(&data[idx], iChild);
}
- ptr = &data[end];
- endPtr = &data[ins];
- assert( (SQLITE_PTR_TO_INT(ptr)&1)==0 ); /* ptr is always 2-byte aligned */
- while( ptr>endPtr ){
- *(u16*)ptr = *(u16*)&ptr[-2];
- ptr -= 2;
- }
+ memmove(&data[ins+2], &data[ins], end-ins);
put2byte(&data[ins], idx);
put2byte(&data[pPage->hdrOffset+3], pPage->nCell);
#ifndef SQLITE_OMIT_AUTOVACUUM
@@ -57373,11 +57787,17 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur);
if( rc ) return rc;
- /* If this is an insert into a table b-tree, invalidate any incrblob
- ** cursors open on the row being replaced (assuming this is a replace
- ** operation - if it is not, the following is a no-op). */
if( pCur->pKeyInfo==0 ){
+ /* If this is an insert into a table b-tree, invalidate any incrblob
+ ** cursors open on the row being replaced */
invalidateIncrblobCursors(p, nKey, 0);
+
+ /* If the cursor is currently on the last row and we are appending a
+ ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
+ ** call */
+ if( pCur->validNKey && nKey>0 && pCur->info.nKey==nKey-1 ){
+ loc = -1;
+ }
}
if( !loc ){
@@ -57447,8 +57867,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
** row without seeking the cursor. This can be a big performance boost.
*/
pCur->info.nSize = 0;
- pCur->validNKey = 0;
if( rc==SQLITE_OK && pPage->nOverflow ){
+ pCur->validNKey = 0;
rc = balance(pCur);
/* Must make sure nOverflow is reset to zero even if the balance()
@@ -57503,7 +57923,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
** sub-tree headed by the child page of the cell being deleted. This makes
** balancing the tree following the delete operation easier. */
if( !pPage->leaf ){
- int notUsed;
+ int notUsed = 0;
rc = sqlite3BtreePrevious(pCur, &notUsed);
if( rc ) return rc;
}
@@ -57756,6 +58176,7 @@ static int clearDatabasePage(
int rc;
unsigned char *pCell;
int i;
+ int hdr;
assert( sqlite3_mutex_held(pBt->mutex) );
if( pgno>btreePagecount(pBt) ){
@@ -57764,6 +58185,7 @@ static int clearDatabasePage(
rc = getAndInitPage(pBt, pgno, &pPage, 0);
if( rc ) return rc;
+ hdr = pPage->hdrOffset;
for(i=0; i<pPage->nCell; i++){
pCell = findCell(pPage, i);
if( !pPage->leaf ){
@@ -57774,7 +58196,7 @@ static int clearDatabasePage(
if( rc ) goto cleardatabasepage_out;
}
if( !pPage->leaf ){
- rc = clearDatabasePage(pBt, get4byte(&pPage->aData[8]), 1, pnChange);
+ rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
if( rc ) goto cleardatabasepage_out;
}else if( pnChange ){
assert( pPage->intKey );
@@ -57783,7 +58205,7 @@ static int clearDatabasePage(
if( freePageFlag ){
freePage(pPage, &rc);
}else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
- zeroPage(pPage, pPage->aData[0] | PTF_LEAF);
+ zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF);
}
cleardatabasepage_out:
@@ -58120,7 +58542,7 @@ static void checkAppendMsg(
sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
}
if( zMsg1 ){
- sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1);
+ sqlite3StrAccumAppendAll(&pCheck->errMsg, zMsg1);
}
sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
va_end(ap);
@@ -59414,7 +59836,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
/* Sync the database file to disk. */
if( rc==SQLITE_OK ){
- rc = sqlite3PagerSync(pDestPager);
+ rc = sqlite3PagerSync(pDestPager, 0);
}
}else{
sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
@@ -59489,10 +59911,10 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
/* Set the error code of the destination database handle. */
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
- sqlite3Error(p->pDestDb, rc, 0);
-
- /* Exit the mutexes and free the backup context structure. */
if( p->pDestDb ){
+ sqlite3Error(p->pDestDb, rc, 0);
+
+ /* Exit the mutexes and free the backup context structure. */
sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
}
sqlite3BtreeLeave(p->pSrc);
@@ -59655,6 +60077,42 @@ copy_finished:
** name sqlite_value
*/
+#ifdef SQLITE_DEBUG
+/*
+** Check invariants on a Mem object.
+**
+** This routine is intended for use inside of assert() statements, like
+** this: assert( sqlite3VdbeCheckMemInvariants(pMem) );
+*/
+SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
+ /* The MEM_Dyn bit is set if and only if Mem.xDel is a non-NULL destructor
+ ** function for Mem.z
+ */
+ assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
+ assert( (p->flags & MEM_Dyn)!=0 || p->xDel==0 );
+
+ /* If p holds a string or blob, the Mem.z must point to exactly
+ ** one of the following:
+ **
+ ** (1) Memory in Mem.zMalloc and managed by the Mem object
+ ** (2) Memory to be freed using Mem.xDel
+ ** (3) An ephermal string or blob
+ ** (4) A static string or blob
+ */
+ if( (p->flags & (MEM_Str|MEM_Blob)) && p->z!=0 ){
+ assert(
+ ((p->z==p->zMalloc)? 1 : 0) +
+ ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
+ ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1
+ );
+ }
+
+ return 1;
+}
+#endif
+
+
/*
** If pMem is an object with a valid string representation, this routine
** ensures the internal encoding for the string representation is
@@ -59696,57 +60154,51 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
/*
** Make sure pMem->z points to a writable allocation of at least
-** n bytes.
-**
-** If the third argument passed to this function is true, then memory
-** cell pMem must contain a string or blob. In this case the content is
-** preserved. Otherwise, if the third parameter to this function is false,
-** any current string or blob value may be discarded.
-**
-** This function sets the MEM_Dyn flag and clears any xDel callback.
-** It also clears MEM_Ephem and MEM_Static. If the preserve flag is
-** not set, Mem.n is zeroed.
-*/
-SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){
- assert( 1 >=
- ((pMem->zMalloc && pMem->zMalloc==pMem->z) ? 1 : 0) +
- (((pMem->flags&MEM_Dyn)&&pMem->xDel) ? 1 : 0) +
- ((pMem->flags&MEM_Ephem) ? 1 : 0) +
- ((pMem->flags&MEM_Static) ? 1 : 0)
- );
+** min(n,32) bytes.
+**
+** If the bPreserve argument is true, then copy of the content of
+** pMem->z into the new allocation. pMem must be either a string or
+** blob if bPreserve is true. If bPreserve is false, any prior content
+** in pMem->z is discarded.
+*/
+SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
+ assert( sqlite3VdbeCheckMemInvariants(pMem) );
assert( (pMem->flags&MEM_RowSet)==0 );
- /* If the preserve flag is set to true, then the memory cell must already
+ /* If the bPreserve flag is set to true, then the memory cell must already
** contain a valid string or blob value. */
- assert( preserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
+ assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
+ testcase( bPreserve && pMem->z==0 );
- if( n<32 ) n = 32;
- if( sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
- if( preserve && pMem->z==pMem->zMalloc ){
+ if( pMem->zMalloc==0 || sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
+ if( n<32 ) n = 32;
+ if( bPreserve && pMem->z==pMem->zMalloc ){
pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
- preserve = 0;
+ bPreserve = 0;
}else{
sqlite3DbFree(pMem->db, pMem->zMalloc);
pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
}
+ if( pMem->zMalloc==0 ){
+ VdbeMemRelease(pMem);
+ pMem->z = 0;
+ pMem->flags = MEM_Null;
+ return SQLITE_NOMEM;
+ }
}
- if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){
+ if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
memcpy(pMem->zMalloc, pMem->z, pMem->n);
}
- if( pMem->flags&MEM_Dyn && pMem->xDel ){
- assert( pMem->xDel!=SQLITE_DYNAMIC );
+ if( (pMem->flags&MEM_Dyn)!=0 ){
+ assert( pMem->xDel!=0 && pMem->xDel!=SQLITE_DYNAMIC );
pMem->xDel((void *)(pMem->z));
}
pMem->z = pMem->zMalloc;
- if( pMem->z==0 ){
- pMem->flags = MEM_Null;
- }else{
- pMem->flags &= ~(MEM_Ephem|MEM_Static);
- }
+ pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static);
pMem->xDel = 0;
- return (pMem->z ? SQLITE_OK : SQLITE_NOMEM);
+ return SQLITE_OK;
}
/*
@@ -59913,9 +60365,9 @@ SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
sqlite3VdbeMemFinalize(p, p->u.pDef);
assert( (p->flags & MEM_Agg)==0 );
sqlite3VdbeMemRelease(p);
- }else if( p->flags&MEM_Dyn && p->xDel ){
+ }else if( p->flags&MEM_Dyn ){
assert( (p->flags&MEM_RowSet)==0 );
- assert( p->xDel!=SQLITE_DYNAMIC );
+ assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
p->xDel((void *)p->z);
p->xDel = 0;
}else if( p->flags&MEM_RowSet ){
@@ -59928,14 +60380,17 @@ SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
/*
** Release any memory held by the Mem. This may leave the Mem in an
** inconsistent state, for example with (Mem.z==0) and
-** (Mem.type==SQLITE_TEXT).
+** (Mem.flags==MEM_Str).
*/
SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
+ assert( sqlite3VdbeCheckMemInvariants(p) );
VdbeMemRelease(p);
- sqlite3DbFree(p->db, p->zMalloc);
+ if( p->zMalloc ){
+ sqlite3DbFree(p->db, p->zMalloc);
+ p->zMalloc = 0;
+ }
p->z = 0;
- p->zMalloc = 0;
- p->xDel = 0;
+ assert( p->xDel==0 ); /* Zeroed by VdbeMemRelease() above */
}
/*
@@ -60117,7 +60572,9 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
sqlite3RowSetClear(pMem->u.pRowSet);
}
MemSetTypeFlag(pMem, MEM_Null);
- pMem->type = SQLITE_NULL;
+}
+SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){
+ sqlite3VdbeMemSetNull((Mem*)p);
}
/*
@@ -60127,7 +60584,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
sqlite3VdbeMemRelease(pMem);
pMem->flags = MEM_Blob|MEM_Zero;
- pMem->type = SQLITE_BLOB;
pMem->n = 0;
if( n<0 ) n = 0;
pMem->u.nZero = n;
@@ -60150,7 +60606,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
sqlite3VdbeMemRelease(pMem);
pMem->u.i = val;
pMem->flags = MEM_Int;
- pMem->type = SQLITE_INTEGER;
}
#ifndef SQLITE_OMIT_FLOATING_POINT
@@ -60165,7 +60620,6 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
sqlite3VdbeMemRelease(pMem);
pMem->r = val;
pMem->flags = MEM_Real;
- pMem->type = SQLITE_FLOAT;
}
}
#endif
@@ -60221,7 +60675,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
Mem *pX;
for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
- pX->flags |= MEM_Invalid;
+ pX->flags |= MEM_Undefined;
pX->pScopyFrom = 0;
}
}
@@ -60232,7 +60686,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
/*
** Size of struct Mem not including the Mem.zMalloc member.
*/
-#define MEMCELLSIZE (size_t)(&(((Mem *)0)->zMalloc))
+#define MEMCELLSIZE offsetof(Mem,zMalloc)
/*
** Make an shallow copy of pFrom into pTo. Prior contents of
@@ -60263,6 +60717,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
VdbeMemRelease(pTo);
memcpy(pTo, pFrom, MEMCELLSIZE);
pTo->flags &= ~MEM_Dyn;
+ pTo->xDel = 0;
if( pTo->flags&(MEM_Str|MEM_Blob) ){
if( 0==(pFrom->flags&MEM_Static) ){
@@ -60373,7 +60828,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
pMem->n = nByte;
pMem->flags = flags;
pMem->enc = (enc==0 ? SQLITE_UTF8 : enc);
- pMem->type = (enc==0 ? SQLITE_BLOB : SQLITE_TEXT);
#ifndef SQLITE_OMIT_UTF16
if( pMem->enc!=SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){
@@ -60389,119 +60843,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
}
/*
-** Compare the values contained by the two memory cells, returning
-** negative, zero or positive if pMem1 is less than, equal to, or greater
-** than pMem2. Sorting order is NULL's first, followed by numbers (integers
-** and reals) sorted numerically, followed by text ordered by the collating
-** sequence pColl and finally blob's ordered by memcmp().
-**
-** Two NULL values are considered equal by this function.
-*/
-SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
- int rc;
- int f1, f2;
- int combined_flags;
-
- f1 = pMem1->flags;
- f2 = pMem2->flags;
- combined_flags = f1|f2;
- assert( (combined_flags & MEM_RowSet)==0 );
-
- /* If one value is NULL, it is less than the other. If both values
- ** are NULL, return 0.
- */
- if( combined_flags&MEM_Null ){
- return (f2&MEM_Null) - (f1&MEM_Null);
- }
-
- /* If one value is a number and the other is not, the number is less.
- ** If both are numbers, compare as reals if one is a real, or as integers
- ** if both values are integers.
- */
- if( combined_flags&(MEM_Int|MEM_Real) ){
- double r1, r2;
- if( (f1 & f2 & MEM_Int)!=0 ){
- if( pMem1->u.i < pMem2->u.i ) return -1;
- if( pMem1->u.i > pMem2->u.i ) return 1;
- return 0;
- }
- if( (f1&MEM_Real)!=0 ){
- r1 = pMem1->r;
- }else if( (f1&MEM_Int)!=0 ){
- r1 = (double)pMem1->u.i;
- }else{
- return 1;
- }
- if( (f2&MEM_Real)!=0 ){
- r2 = pMem2->r;
- }else if( (f2&MEM_Int)!=0 ){
- r2 = (double)pMem2->u.i;
- }else{
- return -1;
- }
- if( r1<r2 ) return -1;
- if( r1>r2 ) return 1;
- return 0;
- }
-
- /* If one value is a string and the other is a blob, the string is less.
- ** If both are strings, compare using the collating functions.
- */
- if( combined_flags&MEM_Str ){
- if( (f1 & MEM_Str)==0 ){
- return 1;
- }
- if( (f2 & MEM_Str)==0 ){
- return -1;
- }
-
- assert( pMem1->enc==pMem2->enc );
- assert( pMem1->enc==SQLITE_UTF8 ||
- pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
-
- /* The collation sequence must be defined at this point, even if
- ** the user deletes the collation sequence after the vdbe program is
- ** compiled (this was not always the case).
- */
- assert( !pColl || pColl->xCmp );
-
- if( pColl ){
- if( pMem1->enc==pColl->enc ){
- /* The strings are already in the correct encoding. Call the
- ** comparison function directly */
- return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
- }else{
- const void *v1, *v2;
- int n1, n2;
- Mem c1;
- Mem c2;
- memset(&c1, 0, sizeof(c1));
- memset(&c2, 0, sizeof(c2));
- sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
- sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
- v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
- n1 = v1==0 ? 0 : c1.n;
- v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
- n2 = v2==0 ? 0 : c2.n;
- rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
- sqlite3VdbeMemRelease(&c1);
- sqlite3VdbeMemRelease(&c2);
- return rc;
- }
- }
- /* If a NULL pointer was passed as the collate function, fall through
- ** to the blob case and use memcmp(). */
- }
-
- /* Both values must be blobs. Compare using memcmp(). */
- rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
- if( rc==0 ){
- rc = pMem1->n - pMem2->n;
- }
- return rc;
-}
-
-/*
** Move data out of a btree key or data field and into a Mem structure.
** The data or key is taken from the entry that pCur is currently pointing
** to. offset and amt determine what portion of the data or key to retrieve.
@@ -60541,22 +60882,22 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
sqlite3VdbeMemRelease(pMem);
pMem->z = &zData[offset];
pMem->flags = MEM_Blob|MEM_Ephem;
+ pMem->n = (int)amt;
}else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
- pMem->flags = MEM_Blob|MEM_Dyn|MEM_Term;
- pMem->enc = 0;
- pMem->type = SQLITE_BLOB;
if( key ){
rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
}else{
rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
}
- pMem->z[amt] = 0;
- pMem->z[amt+1] = 0;
- if( rc!=SQLITE_OK ){
+ if( rc==SQLITE_OK ){
+ pMem->z[amt] = 0;
+ pMem->z[amt+1] = 0;
+ pMem->flags = MEM_Blob|MEM_Term;
+ pMem->n = (int)amt;
+ }else{
sqlite3VdbeMemRelease(pMem);
}
}
- pMem->n = (int)amt;
return rc;
}
@@ -60614,7 +60955,6 @@ SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){
Mem *p = sqlite3DbMallocZero(db, sizeof(*p));
if( p ){
p->flags = MEM_Null;
- p->type = SQLITE_NULL;
p->db = db;
}
return p;
@@ -60660,11 +61000,9 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
if( pRec->pKeyInfo ){
assert( pRec->pKeyInfo->nField+pRec->pKeyInfo->nXField==nCol );
assert( pRec->pKeyInfo->enc==ENC(db) );
- pRec->flags = UNPACKED_PREFIX_MATCH;
pRec->aMem = (Mem *)((u8*)pRec + ROUND8(sizeof(UnpackedRecord)));
for(i=0; i<nCol; i++){
pRec->aMem[i].flags = MEM_Null;
- pRec->aMem[i].type = SQLITE_NULL;
pRec->aMem[i].db = db;
}
}else{
@@ -60737,7 +61075,6 @@ static int valueFromExpr(
zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken);
if( zVal==0 ) goto no_mem;
sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC);
- if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT;
}
if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){
sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8);
@@ -60755,9 +61092,9 @@ static int valueFromExpr(
){
sqlite3VdbeMemNumerify(pVal);
if( pVal->u.i==SMALLEST_INT64 ){
- pVal->flags &= MEM_Int;
+ pVal->flags &= ~MEM_Int;
pVal->flags |= MEM_Real;
- pVal->r = (double)LARGEST_INT64;
+ pVal->r = (double)SMALLEST_INT64;
}else{
pVal->u.i = -pVal->u.i;
}
@@ -60783,9 +61120,6 @@ static int valueFromExpr(
}
#endif
- if( pVal ){
- sqlite3VdbeMemStoreType(pVal);
- }
*ppVal = pVal;
return rc;
@@ -60856,7 +61190,7 @@ static void recordFunc(
}else{
aRet[0] = nSerial+1;
sqlite3PutVarint(&aRet[1], iSerial);
- sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format);
+ sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
sqlite3DbFree(db, aRet);
}
@@ -60949,7 +61283,6 @@ SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
}
pVal->db = pParse->db;
- sqlite3VdbeMemStoreType((Mem*)pVal);
}
}
}else{
@@ -61041,7 +61374,8 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
/*
** Create a new virtual database engine.
*/
-SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
+SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){
+ sqlite3 *db = pParse->db;
Vdbe *p;
p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
if( p==0 ) return 0;
@@ -61053,6 +61387,10 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
p->pPrev = 0;
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
+ p->pParse = pParse;
+ assert( pParse->aLabel==0 );
+ assert( pParse->nLabel==0 );
+ assert( pParse->nOpAlloc==0 );
return p;
}
@@ -61108,13 +61446,14 @@ SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
** unchanged (this is so that any opcodes already allocated can be
** correctly deallocated along with the rest of the Vdbe).
*/
-static int growOpArray(Vdbe *p){
+static int growOpArray(Vdbe *v){
VdbeOp *pNew;
+ Parse *p = v->pParse;
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
- pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
+ pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
if( pNew ){
p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
- p->aOp = pNew;
+ v->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
@@ -61153,7 +61492,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
i = p->nOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( op>0 && op<0xff );
- if( p->nOpAlloc<=i ){
+ if( p->pParse->nOpAlloc<=i ){
if( growOpArray(p) ){
return 1;
}
@@ -61172,6 +61511,15 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
#endif
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
+ int jj, kk;
+ Parse *pParse = p->pParse;
+ for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
+ struct yColCache *x = pParse->aColCache + jj;
+ if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
+ printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
+ kk++;
+ }
+ if( kk ) printf("\n");
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
test_addop_breakpoint();
}
@@ -61180,6 +61528,9 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
pOp->cycles = 0;
pOp->cnt = 0;
#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ pOp->iSrcLine = 0;
+#endif
return i;
}
SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){
@@ -61255,9 +61606,10 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(
**
** Zero is returned if a malloc() fails.
*/
-SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
+SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *v){
+ Parse *p = v->pParse;
int i = p->nLabel++;
- assert( p->magic==VDBE_MAGIC_INIT );
+ assert( v->magic==VDBE_MAGIC_INIT );
if( (i & (i-1))==0 ){
p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
(i*2+1)*sizeof(p->aLabel[0]));
@@ -61273,13 +61625,15 @@ SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe *p){
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
-SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
+SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){
+ Parse *p = v->pParse;
int j = -1-x;
- assert( p->magic==VDBE_MAGIC_INIT );
+ assert( v->magic==VDBE_MAGIC_INIT );
assert( j<p->nLabel );
if( j>=0 && p->aLabel ){
- p->aLabel[j] = p->nOp;
+ p->aLabel[j] = v->nOp;
}
+ p->iFixedOp = v->nOp - 1;
}
/*
@@ -61427,7 +61781,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
- int *aLabel = p->aLabel;
+ Parse *pParse = p->pParse;
+ int *aLabel = pParse->aLabel;
p->readOnly = 1;
p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
@@ -61490,12 +61845,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
- assert( -1-pOp->p2<p->nLabel );
+ assert( -1-pOp->p2<pParse->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
}
}
- sqlite3DbFree(p->db, p->aLabel);
- p->aLabel = 0;
+ sqlite3DbFree(p->db, pParse->aLabel);
+ pParse->aLabel = 0;
+ pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || p->btreeMask==0 );
}
@@ -61536,10 +61892,10 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg)
** Add a whole list of operations to the operation stack. Return the
** address of the first operation added.
*/
-SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
+SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp, int iLineno){
int addr;
assert( p->magic==VDBE_MAGIC_INIT );
- if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){
+ if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){
return 0;
}
addr = p->nOp;
@@ -61564,6 +61920,11 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp)
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
pOut->zComment = 0;
#endif
+#ifdef SQLITE_VDBE_COVERAGE
+ pOut->iSrcLine = iLineno+i;
+#else
+ (void)iLineno;
+#endif
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
@@ -61626,7 +61987,8 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
** the address of the next instruction to be coded.
*/
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
- if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
+ sqlite3VdbeChangeP2(p, addr, p->nOp);
+ p->pParse->iFixedOp = p->nOp - 1;
}
@@ -61729,6 +62091,18 @@ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
}
/*
+** Remove the last opcode inserted
+*/
+SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
+ if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
+ sqlite3VdbeChangeToNoop(p, p->nOp-1);
+ return 1;
+ }else{
+ return 0;
+ }
+}
+
+/*
** Change the value of the P4 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
** static array using sqlite3VdbeAddOpList but we want to make a
@@ -61839,6 +62213,15 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
}
#endif /* NDEBUG */
+#ifdef SQLITE_VDBE_COVERAGE
+/*
+** Set the value if the iSrcLine field for the previously coded instruction.
+*/
+SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){
+ sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine;
+}
+#endif /* SQLITE_VDBE_COVERAGE */
+
/*
** Return the opcode for a given address. If the address is -1, then
** return the most recently inserted opcode.
@@ -61851,14 +62234,6 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
** this routine is a valid pointer. But because the dummy.opcode is 0,
** dummy will never be written to. This is verified by code inspection and
** by running with Valgrind.
-**
-** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called
-** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE,
-** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as
-** a new VDBE is created. So we are free to set addr to p->nOp-1 without
-** having to double-check to make sure that the result is non-negative. But
-** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to
-** check the value of p->nOp-1 before continuing.
*/
SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
/* C89 specifies that the constant "dummy" will be initialized to all
@@ -61866,9 +62241,6 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */
assert( p->magic==VDBE_MAGIC_INIT );
if( addr<0 ){
-#ifdef SQLITE_OMIT_TRACE
- if( p->nOp==0 ) return (VdbeOp*)&dummy;
-#endif
addr = p->nOp - 1;
}
assert( (addr>=0 && addr<p->nOp) || p->db->mallocFailed );
@@ -61893,7 +62265,17 @@ static int translateP(char c, const Op *pOp){
}
/*
-** Compute a string for the "comment" field of a VDBE opcode listing
+** Compute a string for the "comment" field of a VDBE opcode listing.
+**
+** The Synopsis: field in comments in the vdbe.c source file gets converted
+** to an extra string that is appended to the sqlite3OpcodeName(). In the
+** absence of other comments, this synopsis becomes the comment on the opcode.
+** Some translation occurs:
+**
+** "PX" -> "r[X]"
+** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
+** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
+** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
*/
static int displayComment(
const Op *pOp, /* The opcode to be commented */
@@ -61927,7 +62309,13 @@ static int displayComment(
ii += 3;
jj += sqlite3Strlen30(zTemp+jj);
v2 = translateP(zSynopsis[ii], pOp);
- if( v2>1 ) sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){
+ ii += 2;
+ v2++;
+ }
+ if( v2>1 ){
+ sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
+ }
}else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
ii += 4;
}
@@ -62157,8 +62545,11 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
displayComment(pOp, zP4, zCom, sizeof(zCom));
#else
- zCom[0] = 0
+ zCom[0] = 0;
#endif
+ /* NB: The sqlite3OpcodeName() function is implemented by code created
+ ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
+ ** information from the vdbe.c source text */
fprintf(pOut, zFormat1, pc,
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
zCom
@@ -62183,6 +62574,7 @@ static void releaseMemArray(Mem *p, int N){
}
for(pEnd=&p[N]; p<pEnd; p++){
assert( (&p[1])==pEnd || p[0].db==p[1].db );
+ assert( sqlite3VdbeCheckMemInvariants(p) );
/* This block is really an inlined version of sqlite3VdbeMemRelease()
** that takes advantage of the fact that the memory cell value is
@@ -62196,6 +62588,10 @@ static void releaseMemArray(Mem *p, int N){
** with no indexes using a single prepared INSERT statement, bind()
** and reset(). Inserts are grouped into a transaction.
*/
+ testcase( p->flags & MEM_Agg );
+ testcase( p->flags & MEM_Dyn );
+ testcase( p->flags & MEM_Frame );
+ testcase( p->flags & MEM_RowSet );
if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
sqlite3VdbeMemRelease(p);
}else if( p->zMalloc ){
@@ -62203,7 +62599,7 @@ static void releaseMemArray(Mem *p, int N){
p->zMalloc = 0;
}
- p->flags = MEM_Invalid;
+ p->flags = MEM_Undefined;
}
db->mallocFailed = malloc_failed;
}
@@ -62325,7 +62721,6 @@ SQLITE_PRIVATE int sqlite3VdbeList(
}
if( p->explain==1 ){
pMem->flags = MEM_Int;
- pMem->type = SQLITE_INTEGER;
pMem->u.i = i; /* Program counter */
pMem++;
@@ -62333,7 +62728,6 @@ SQLITE_PRIVATE int sqlite3VdbeList(
pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */
assert( pMem->z!=0 );
pMem->n = sqlite3Strlen30(pMem->z);
- pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
pMem++;
@@ -62359,24 +62753,21 @@ SQLITE_PRIVATE int sqlite3VdbeList(
pMem->flags = MEM_Int;
pMem->u.i = pOp->p1; /* P1 */
- pMem->type = SQLITE_INTEGER;
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p2; /* P2 */
- pMem->type = SQLITE_INTEGER;
pMem++;
pMem->flags = MEM_Int;
pMem->u.i = pOp->p3; /* P3 */
- pMem->type = SQLITE_INTEGER;
pMem++;
if( sqlite3VdbeMemGrow(pMem, 32, 0) ){ /* P4 */
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
+ pMem->flags = MEM_Str|MEM_Term;
zP4 = displayP4(pOp, pMem->z, 32);
if( zP4!=pMem->z ){
sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0);
@@ -62385,7 +62776,6 @@ SQLITE_PRIVATE int sqlite3VdbeList(
pMem->n = sqlite3Strlen30(pMem->z);
pMem->enc = SQLITE_UTF8;
}
- pMem->type = SQLITE_TEXT;
pMem++;
if( p->explain==1 ){
@@ -62393,10 +62783,9 @@ SQLITE_PRIVATE int sqlite3VdbeList(
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
+ pMem->flags = MEM_Str|MEM_Term;
pMem->n = 2;
sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */
- pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
pMem++;
@@ -62405,13 +62794,11 @@ SQLITE_PRIVATE int sqlite3VdbeList(
assert( p->db->mallocFailed );
return SQLITE_ERROR;
}
- pMem->flags = MEM_Dyn|MEM_Str|MEM_Term;
+ pMem->flags = MEM_Str|MEM_Term;
pMem->n = displayComment(pOp, zP4, pMem->z, 500);
- pMem->type = SQLITE_TEXT;
pMem->enc = SQLITE_UTF8;
#else
pMem->flags = MEM_Null; /* Comment */
- pMem->type = SQLITE_NULL;
#endif
}
@@ -62434,7 +62821,7 @@ SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){
z = p->zSql;
}else if( p->nOp>=1 ){
const VdbeOp *pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
+ if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){
z = pOp->p4.z;
while( sqlite3Isspace(*z) ) z++;
}
@@ -62453,7 +62840,7 @@ SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){
if( sqlite3IoTrace==0 ) return;
if( nOp<1 ) return;
pOp = &p->aOp[0];
- if( pOp->opcode==OP_Trace && pOp->p4.z!=0 ){
+ if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){
int i, j;
char z[1000];
sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z);
@@ -62590,6 +62977,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
assert( p->nOp>0 );
assert( pParse!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
+ assert( pParse==p->pParse );
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
@@ -62613,8 +63001,8 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
/* Allocate space for memory registers, SQL variables, VDBE cursors and
** an array to marshal SQL function arguments in.
*/
- zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
- zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */
+ zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
+ zEnd = (u8*)&p->aOp[pParse->nOpAlloc]; /* First byte past end of zCsr[] */
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
@@ -62670,7 +63058,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
p->aMem--; /* aMem[] goes from 1..nMem */
p->nMem = nMem; /* not from 0..nMem-1 */
for(n=1; n<=nMem; n++){
- p->aMem[n].flags = MEM_Invalid;
+ p->aMem[n].flags = MEM_Undefined;
p->aMem[n].db = db;
}
}
@@ -62782,7 +63170,7 @@ static void Cleanup(Vdbe *p){
int i;
if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
if( p->aMem ){
- for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid );
+ for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined );
}
#endif
@@ -63441,6 +63829,7 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){
if( p->zErrMsg ){
u8 mallocFailed = db->mallocFailed;
sqlite3BeginBenignMalloc();
+ if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db);
sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
sqlite3EndBenignMalloc();
db->mallocFailed = mallocFailed;
@@ -63509,8 +63898,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
** to sqlite3_step(). For consistency (since sqlite3_step() was
** called), set the database error in this case as well.
*/
- sqlite3Error(db, p->rc, 0);
- sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT);
+ sqlite3Error(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
sqlite3DbFree(db, p->zErrMsg);
p->zErrMsg = 0;
}
@@ -63531,12 +63919,24 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
fprintf(out, "%02x", p->aOp[i].opcode);
}
fprintf(out, "\n");
+ if( p->zSql ){
+ char c, pc = 0;
+ fprintf(out, "-- ");
+ for(i=0; (c = p->zSql[i])!=0; i++){
+ if( pc=='\n' ) fprintf(out, "-- ");
+ putc(c, out);
+ pc = c;
+ }
+ if( pc!='\n' ) fprintf(out, "\n");
+ }
for(i=0; i<p->nOp; i++){
- fprintf(out, "%6d %10lld %8lld ",
+ char zHdr[100];
+ sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ",
p->aOp[i].cnt,
p->aOp[i].cycles,
p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
);
+ fprintf(out, "%s", zHdr);
sqlite3VdbePrintOp(out, i, &p->aOp[i]);
}
fclose(out);
@@ -63583,8 +63983,9 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
while( *pp ){
AuxData *pAux = *pp;
if( (iOp<0)
- || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
+ || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & MASKBIT32(pAux->iArg))))
){
+ testcase( pAux->iArg==31 );
if( pAux->xDelete ){
pAux->xDelete(pAux->pAux);
}
@@ -63617,7 +64018,6 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
}
for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
vdbeFreeOpArray(db, p->aOp, p->nOp);
- sqlite3DbFree(db, p->aLabel);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
sqlite3DbFree(db, p->pFree);
@@ -63848,21 +64248,15 @@ static u64 floatSwap(u64 in){
** buf. It is assumed that the caller has allocated sufficient space.
** Return the number of bytes written.
**
-** nBuf is the amount of space left in buf[]. nBuf must always be
-** large enough to hold the entire field. Except, if the field is
-** a blob with a zero-filled tail, then buf[] might be just the right
-** size to hold everything except for the zero-filled tail. If buf[]
-** is only big enough to hold the non-zero prefix, then only write that
-** prefix into buf[]. But if buf[] is large enough to hold both the
-** prefix and the tail then write the prefix and set the tail to all
-** zeros.
+** nBuf is the amount of space left in buf[]. The caller is responsible
+** for allocating enough space to buf[] to hold the entire field, exclusive
+** of the pMem->u.nZero bytes for a MEM_Zero value.
**
** Return the number of bytes actually written into buf[]. The number
** of bytes in the zero-filled tail is included in the return value only
** if those bytes were zeroed in buf[].
*/
-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
- u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
+SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
u32 len;
/* Integer and Real */
@@ -63877,7 +64271,6 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
v = pMem->u.i;
}
len = i = sqlite3VdbeSerialTypeLen(serial_type);
- assert( len<=(u32)nBuf );
while( i-- ){
buf[i] = (u8)(v&0xFF);
v >>= 8;
@@ -63889,17 +64282,8 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
if( serial_type>=12 ){
assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
== (int)sqlite3VdbeSerialTypeLen(serial_type) );
- assert( pMem->n<=nBuf );
len = pMem->n;
memcpy(buf, pMem->z, len);
- if( pMem->flags & MEM_Zero ){
- len += pMem->u.nZero;
- assert( nBuf>=0 );
- if( len > (u32)nBuf ){
- len = (u32)nBuf;
- }
- memset(&buf[pMem->n], 0, len-pMem->n);
- }
return len;
}
@@ -63907,6 +64291,14 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_f
return 0;
}
+/* Input "x" is a sequence of unsigned characters that represent a
+** big-endian integer. Return the equivalent native integer
+*/
+#define ONE_BYTE_INT(x) ((i8)(x)[0])
+#define TWO_BYTE_INT(x) (256*(i8)((x)[0])|(x)[1])
+#define THREE_BYTE_INT(x) (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
+#define FOUR_BYTE_UINT(x) (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
+
/*
** Deserialize the data blob pointed to by buf as serial type serial_type
** and store the result in pMem. Return the number of bytes read.
@@ -63916,6 +64308,8 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
u32 serial_type, /* Serial type to deserialize */
Mem *pMem /* Memory cell to write value into */
){
+ u64 x;
+ u32 y;
switch( serial_type ){
case 10: /* Reserved for future use */
case 11: /* Reserved for future use */
@@ -63924,37 +64318,38 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
break;
}
case 1: { /* 1-byte signed integer */
- pMem->u.i = (signed char)buf[0];
+ pMem->u.i = ONE_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 1;
}
case 2: { /* 2-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<8) | buf[1];
+ pMem->u.i = TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 2;
}
case 3: { /* 3-byte signed integer */
- pMem->u.i = (((signed char)buf[0])<<16) | (buf[1]<<8) | buf[2];
+ pMem->u.i = THREE_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 3;
}
case 4: { /* 4-byte signed integer */
- pMem->u.i = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
+ y = FOUR_BYTE_UINT(buf);
+ pMem->u.i = (i64)*(int*)&y;
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 4;
}
case 5: { /* 6-byte signed integer */
- u64 x = (((signed char)buf[0])<<8) | buf[1];
- u32 y = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5];
- x = (x<<32) | y;
- pMem->u.i = *(i64*)&x;
+ pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
return 6;
}
case 6: /* 8-byte signed integer */
case 7: { /* IEEE floating point */
- u64 x;
- u32 y;
#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
/* Verify that integers and floating point values use the same
** byte order. Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
@@ -63967,13 +64362,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
swapMixedEndianFloat(t2);
assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
#endif
-
- x = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3];
- y = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7];
+ x = FOUR_BYTE_UINT(buf);
+ y = FOUR_BYTE_UINT(buf+4);
x = (x<<32) | y;
if( serial_type==6 ){
pMem->u.i = *(i64*)&x;
pMem->flags = MEM_Int;
+ testcase( pMem->u.i<0 );
}else{
assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
swapMixedEndianFloat(x);
@@ -64065,7 +64460,7 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
u32 szHdr;
Mem *pMem = p->aMem;
- p->flags = 0;
+ p->default_rc = 0;
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
idx = getVarint32(aKey, szHdr);
d = szHdr;
@@ -64086,26 +64481,18 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
p->nField = u;
}
+#if SQLITE_DEBUG
/*
-** This function compares the two table rows or index records
-** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
-** or positive integer if key1 is less than, equal to or
-** greater than key2. The {nKey1, pKey1} key must be a blob
-** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
-** key must be a parsed key such as obtained from
-** sqlite3VdbeParseRecord.
-**
-** Key1 and Key2 do not have to contain the same number of fields.
-** The key with fewer fields is usually compares less than the
-** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set
-** and the common prefixes are equal, then key1 is less than key2.
-** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are
-** equal, then the keys are considered to be equal and
-** the parts beyond the common prefix are ignored.
+** This function compares two index or table record keys in the same way
+** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(),
+** this function deserializes and compares values using the
+** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
+** in assert() statements to ensure that the optimized code in
+** sqlite3VdbeRecordCompare() returns results with these two primitives.
*/
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
+static int vdbeRecordCompareDebug(
int nKey1, const void *pKey1, /* Left key */
- UnpackedRecord *pPKey2 /* Right key */
+ const UnpackedRecord *pPKey2 /* Right key */
){
u32 d1; /* Offset into aKey[] of next data element */
u32 idx1; /* Offset into aKey[] of next header element */
@@ -64179,24 +64566,576 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
assert( mem1.zMalloc==0 );
/* rc==0 here means that one of the keys ran out of fields and
- ** all the fields up to that point were equal. If the UNPACKED_INCRKEY
- ** flag is set, then break the tie by treating key2 as larger.
- ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes
- ** are considered to be equal. Otherwise, the longer key is the
- ** larger. As it happens, the pPKey2 will always be the longer
- ** if there is a difference.
- */
- assert( rc==0 );
- if( pPKey2->flags & UNPACKED_INCRKEY ){
- rc = -1;
- }else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){
- /* Leave rc==0 */
- }else if( idx1<szHdr1 ){
- rc = 1;
+ ** all the fields up to that point were equal. Return the the default_rc
+ ** value. */
+ return pPKey2->default_rc;
+}
+#endif
+
+/*
+** Both *pMem1 and *pMem2 contain string values. Compare the two values
+** using the collation sequence pColl. As usual, return a negative , zero
+** or positive value if *pMem1 is less than, equal to or greater than
+** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);".
+*/
+static int vdbeCompareMemString(
+ const Mem *pMem1,
+ const Mem *pMem2,
+ const CollSeq *pColl
+){
+ if( pMem1->enc==pColl->enc ){
+ /* The strings are already in the correct encoding. Call the
+ ** comparison function directly */
+ return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
+ }else{
+ int rc;
+ const void *v1, *v2;
+ int n1, n2;
+ Mem c1;
+ Mem c2;
+ memset(&c1, 0, sizeof(c1));
+ memset(&c2, 0, sizeof(c2));
+ sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
+ sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
+ v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
+ n1 = v1==0 ? 0 : c1.n;
+ v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc);
+ n2 = v2==0 ? 0 : c2.n;
+ rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
+ sqlite3VdbeMemRelease(&c1);
+ sqlite3VdbeMemRelease(&c2);
+ return rc;
}
- return rc;
}
+
+/*
+** Compare the values contained by the two memory cells, returning
+** negative, zero or positive if pMem1 is less than, equal to, or greater
+** than pMem2. Sorting order is NULL's first, followed by numbers (integers
+** and reals) sorted numerically, followed by text ordered by the collating
+** sequence pColl and finally blob's ordered by memcmp().
+**
+** Two NULL values are considered equal by this function.
+*/
+SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
+ int rc;
+ int f1, f2;
+ int combined_flags;
+
+ f1 = pMem1->flags;
+ f2 = pMem2->flags;
+ combined_flags = f1|f2;
+ assert( (combined_flags & MEM_RowSet)==0 );
+ /* If one value is NULL, it is less than the other. If both values
+ ** are NULL, return 0.
+ */
+ if( combined_flags&MEM_Null ){
+ return (f2&MEM_Null) - (f1&MEM_Null);
+ }
+
+ /* If one value is a number and the other is not, the number is less.
+ ** If both are numbers, compare as reals if one is a real, or as integers
+ ** if both values are integers.
+ */
+ if( combined_flags&(MEM_Int|MEM_Real) ){
+ double r1, r2;
+ if( (f1 & f2 & MEM_Int)!=0 ){
+ if( pMem1->u.i < pMem2->u.i ) return -1;
+ if( pMem1->u.i > pMem2->u.i ) return 1;
+ return 0;
+ }
+ if( (f1&MEM_Real)!=0 ){
+ r1 = pMem1->r;
+ }else if( (f1&MEM_Int)!=0 ){
+ r1 = (double)pMem1->u.i;
+ }else{
+ return 1;
+ }
+ if( (f2&MEM_Real)!=0 ){
+ r2 = pMem2->r;
+ }else if( (f2&MEM_Int)!=0 ){
+ r2 = (double)pMem2->u.i;
+ }else{
+ return -1;
+ }
+ if( r1<r2 ) return -1;
+ if( r1>r2 ) return 1;
+ return 0;
+ }
+
+ /* If one value is a string and the other is a blob, the string is less.
+ ** If both are strings, compare using the collating functions.
+ */
+ if( combined_flags&MEM_Str ){
+ if( (f1 & MEM_Str)==0 ){
+ return 1;
+ }
+ if( (f2 & MEM_Str)==0 ){
+ return -1;
+ }
+
+ assert( pMem1->enc==pMem2->enc );
+ assert( pMem1->enc==SQLITE_UTF8 ||
+ pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE );
+
+ /* The collation sequence must be defined at this point, even if
+ ** the user deletes the collation sequence after the vdbe program is
+ ** compiled (this was not always the case).
+ */
+ assert( !pColl || pColl->xCmp );
+
+ if( pColl ){
+ return vdbeCompareMemString(pMem1, pMem2, pColl);
+ }
+ /* If a NULL pointer was passed as the collate function, fall through
+ ** to the blob case and use memcmp(). */
+ }
+
+ /* Both values must be blobs. Compare using memcmp(). */
+ rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
+ if( rc==0 ){
+ rc = pMem1->n - pMem2->n;
+ }
+ return rc;
+}
+
+
+/*
+** The first argument passed to this function is a serial-type that
+** corresponds to an integer - all values between 1 and 9 inclusive
+** except 7. The second points to a buffer containing an integer value
+** serialized according to serial_type. This function deserializes
+** and returns the value.
+*/
+static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
+ u32 y;
+ assert( CORRUPT_DB || (serial_type>=1 && serial_type<=9 && serial_type!=7) );
+ switch( serial_type ){
+ case 0:
+ case 1:
+ testcase( aKey[0]&0x80 );
+ return ONE_BYTE_INT(aKey);
+ case 2:
+ testcase( aKey[0]&0x80 );
+ return TWO_BYTE_INT(aKey);
+ case 3:
+ testcase( aKey[0]&0x80 );
+ return THREE_BYTE_INT(aKey);
+ case 4: {
+ testcase( aKey[0]&0x80 );
+ y = FOUR_BYTE_UINT(aKey);
+ return (i64)*(int*)&y;
+ }
+ case 5: {
+ testcase( aKey[0]&0x80 );
+ return FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
+ }
+ case 6: {
+ u64 x = FOUR_BYTE_UINT(aKey);
+ testcase( aKey[0]&0x80 );
+ x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
+ return (i64)*(i64*)&x;
+ }
+ }
+
+ return (serial_type - 8);
+}
+
+/*
+** This function compares the two table rows or index records
+** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero
+** or positive integer if key1 is less than, equal to or
+** greater than key2. The {nKey1, pKey1} key must be a blob
+** created by th OP_MakeRecord opcode of the VDBE. The pPKey2
+** key must be a parsed key such as obtained from
+** sqlite3VdbeParseRecord.
+**
+** If argument bSkip is non-zero, it is assumed that the caller has already
+** determined that the first fields of the keys are equal.
+**
+** Key1 and Key2 do not have to contain the same number of fields. If all
+** fields that appear in both keys are equal, then pPKey2->default_rc is
+** returned.
+*/
+SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
+ int nKey1, const void *pKey1, /* Left key */
+ const UnpackedRecord *pPKey2, /* Right key */
+ int bSkip /* If true, skip the first field */
+){
+ u32 d1; /* Offset into aKey[] of next data element */
+ int i; /* Index of next field to compare */
+ u32 szHdr1; /* Size of record header in bytes */
+ u32 idx1; /* Offset of first type in header */
+ int rc = 0; /* Return value */
+ Mem *pRhs = pPKey2->aMem; /* Next field of pPKey2 to compare */
+ KeyInfo *pKeyInfo = pPKey2->pKeyInfo;
+ const unsigned char *aKey1 = (const unsigned char *)pKey1;
+ Mem mem1;
+
+ /* If bSkip is true, then the caller has already determined that the first
+ ** two elements in the keys are equal. Fix the various stack variables so
+ ** that this routine begins comparing at the second field. */
+ if( bSkip ){
+ u32 s1;
+ idx1 = 1 + getVarint32(&aKey1[1], s1);
+ szHdr1 = aKey1[0];
+ d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1);
+ i = 1;
+ pRhs++;
+ }else{
+ idx1 = getVarint32(aKey1, szHdr1);
+ d1 = szHdr1;
+ i = 0;
+ }
+
+ VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
+ assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField
+ || CORRUPT_DB );
+ assert( pPKey2->pKeyInfo->aSortOrder!=0 );
+ assert( pPKey2->pKeyInfo->nField>0 );
+ assert( idx1<=szHdr1 || CORRUPT_DB );
+ do{
+ u32 serial_type;
+
+ /* RHS is an integer */
+ if( pRhs->flags & MEM_Int ){
+ serial_type = aKey1[idx1];
+ testcase( serial_type==12 );
+ if( serial_type>=12 ){
+ rc = +1;
+ }else if( serial_type==0 ){
+ rc = -1;
+ }else if( serial_type==7 ){
+ double rhs = (double)pRhs->u.i;
+ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
+ if( mem1.r<rhs ){
+ rc = -1;
+ }else if( mem1.r>rhs ){
+ rc = +1;
+ }
+ }else{
+ i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]);
+ i64 rhs = pRhs->u.i;
+ if( lhs<rhs ){
+ rc = -1;
+ }else if( lhs>rhs ){
+ rc = +1;
+ }
+ }
+ }
+
+ /* RHS is real */
+ else if( pRhs->flags & MEM_Real ){
+ serial_type = aKey1[idx1];
+ if( serial_type>=12 ){
+ rc = +1;
+ }else if( serial_type==0 ){
+ rc = -1;
+ }else{
+ double rhs = pRhs->r;
+ double lhs;
+ sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
+ if( serial_type==7 ){
+ lhs = mem1.r;
+ }else{
+ lhs = (double)mem1.u.i;
+ }
+ if( lhs<rhs ){
+ rc = -1;
+ }else if( lhs>rhs ){
+ rc = +1;
+ }
+ }
+ }
+
+ /* RHS is a string */
+ else if( pRhs->flags & MEM_Str ){
+ getVarint32(&aKey1[idx1], serial_type);
+ testcase( serial_type==12 );
+ if( serial_type<12 ){
+ rc = -1;
+ }else if( !(serial_type & 0x01) ){
+ rc = +1;
+ }else{
+ mem1.n = (serial_type - 12) / 2;
+ testcase( (d1+mem1.n)==(unsigned)nKey1 );
+ testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
+ if( (d1+mem1.n) > (unsigned)nKey1 ){
+ rc = 1; /* Corruption */
+ }else if( pKeyInfo->aColl[i] ){
+ mem1.enc = pKeyInfo->enc;
+ mem1.db = pKeyInfo->db;
+ mem1.flags = MEM_Str;
+ mem1.z = (char*)&aKey1[d1];
+ rc = vdbeCompareMemString(&mem1, pRhs, pKeyInfo->aColl[i]);
+ }else{
+ int nCmp = MIN(mem1.n, pRhs->n);
+ rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
+ if( rc==0 ) rc = mem1.n - pRhs->n;
+ }
+ }
+ }
+
+ /* RHS is a blob */
+ else if( pRhs->flags & MEM_Blob ){
+ getVarint32(&aKey1[idx1], serial_type);
+ testcase( serial_type==12 );
+ if( serial_type<12 || (serial_type & 0x01) ){
+ rc = -1;
+ }else{
+ int nStr = (serial_type - 12) / 2;
+ testcase( (d1+nStr)==(unsigned)nKey1 );
+ testcase( (d1+nStr+1)==(unsigned)nKey1 );
+ if( (d1+nStr) > (unsigned)nKey1 ){
+ rc = 1; /* Corruption */
+ }else{
+ int nCmp = MIN(nStr, pRhs->n);
+ rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
+ if( rc==0 ) rc = nStr - pRhs->n;
+ }
+ }
+ }
+
+ /* RHS is null */
+ else{
+ serial_type = aKey1[idx1];
+ rc = (serial_type!=0);
+ }
+
+ if( rc!=0 ){
+ if( pKeyInfo->aSortOrder[i] ){
+ rc = -rc;
+ }
+ assert( CORRUPT_DB
+ || (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
+ || (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
+ || pKeyInfo->db->mallocFailed
+ );
+ assert( mem1.zMalloc==0 ); /* See comment below */
+ return rc;
+ }
+
+ i++;
+ pRhs++;
+ d1 += sqlite3VdbeSerialTypeLen(serial_type);
+ idx1 += sqlite3VarintLen(serial_type);
+ }while( idx1<(unsigned)szHdr1 && i<pPKey2->nField && d1<=(unsigned)nKey1 );
+
+ /* No memory allocation is ever used on mem1. Prove this using
+ ** the following assert(). If the assert() fails, it indicates a
+ ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */
+ assert( mem1.zMalloc==0 );
+
+ /* rc==0 here means that one or both of the keys ran out of fields and
+ ** all the fields up to that point were equal. Return the the default_rc
+ ** value. */
+ assert( CORRUPT_DB
+ || pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)
+ );
+ return pPKey2->default_rc;
+}
+
+/*
+** This function is an optimized version of sqlite3VdbeRecordCompare()
+** that (a) the first field of pPKey2 is an integer, and (b) the
+** size-of-header varint at the start of (pKey1/nKey1) fits in a single
+** byte (i.e. is less than 128).
+*/
+static int vdbeRecordCompareInt(
+ int nKey1, const void *pKey1, /* Left key */
+ const UnpackedRecord *pPKey2, /* Right key */
+ int bSkip /* Ignored */
+){
+ const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
+ int serial_type = ((const u8*)pKey1)[1];
+ int res;
+ u32 y;
+ u64 x;
+ i64 v = pPKey2->aMem[0].u.i;
+ i64 lhs;
+ UNUSED_PARAMETER(bSkip);
+
+ assert( bSkip==0 );
+ switch( serial_type ){
+ case 1: { /* 1-byte signed integer */
+ lhs = ONE_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 2: { /* 2-byte signed integer */
+ lhs = TWO_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 3: { /* 3-byte signed integer */
+ lhs = THREE_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 4: { /* 4-byte signed integer */
+ y = FOUR_BYTE_UINT(aKey);
+ lhs = (i64)*(int*)&y;
+ testcase( lhs<0 );
+ break;
+ }
+ case 5: { /* 6-byte signed integer */
+ lhs = FOUR_BYTE_UINT(aKey+2) + (((i64)1)<<32)*TWO_BYTE_INT(aKey);
+ testcase( lhs<0 );
+ break;
+ }
+ case 6: { /* 8-byte signed integer */
+ x = FOUR_BYTE_UINT(aKey);
+ x = (x<<32) | FOUR_BYTE_UINT(aKey+4);
+ lhs = *(i64*)&x;
+ testcase( lhs<0 );
+ break;
+ }
+ case 8:
+ lhs = 0;
+ break;
+ case 9:
+ lhs = 1;
+ break;
+
+ /* This case could be removed without changing the results of running
+ ** this code. Including it causes gcc to generate a faster switch
+ ** statement (since the range of switch targets now starts at zero and
+ ** is contiguous) but does not cause any duplicate code to be generated
+ ** (as gcc is clever enough to combine the two like cases). Other
+ ** compilers might be similar. */
+ case 0: case 7:
+ return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
+
+ default:
+ return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
+ }
+
+ if( v>lhs ){
+ res = pPKey2->r1;
+ }else if( v<lhs ){
+ res = pPKey2->r2;
+ }else if( pPKey2->nField>1 ){
+ /* The first fields of the two keys are equal. Compare the trailing
+ ** fields. */
+ res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
+ }else{
+ /* The first fields of the two keys are equal and there are no trailing
+ ** fields. Return pPKey2->default_rc in this case. */
+ res = pPKey2->default_rc;
+ }
+
+ assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
+ || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
+ || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
+ || CORRUPT_DB
+ );
+ return res;
+}
+
+/*
+** This function is an optimized version of sqlite3VdbeRecordCompare()
+** that (a) the first field of pPKey2 is a string, that (b) the first field
+** uses the collation sequence BINARY and (c) that the size-of-header varint
+** at the start of (pKey1/nKey1) fits in a single byte.
+*/
+static int vdbeRecordCompareString(
+ int nKey1, const void *pKey1, /* Left key */
+ const UnpackedRecord *pPKey2, /* Right key */
+ int bSkip
+){
+ const u8 *aKey1 = (const u8*)pKey1;
+ int serial_type;
+ int res;
+ UNUSED_PARAMETER(bSkip);
+
+ assert( bSkip==0 );
+ getVarint32(&aKey1[1], serial_type);
+
+ if( serial_type<12 ){
+ res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */
+ }else if( !(serial_type & 0x01) ){
+ res = pPKey2->r2; /* (pKey1/nKey1) is a blob */
+ }else{
+ int nCmp;
+ int nStr;
+ int szHdr = aKey1[0];
+
+ nStr = (serial_type-12) / 2;
+ if( (szHdr + nStr) > nKey1 ) return 0; /* Corruption */
+ nCmp = MIN( pPKey2->aMem[0].n, nStr );
+ res = memcmp(&aKey1[szHdr], pPKey2->aMem[0].z, nCmp);
+
+ if( res==0 ){
+ res = nStr - pPKey2->aMem[0].n;
+ if( res==0 ){
+ if( pPKey2->nField>1 ){
+ res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
+ }else{
+ res = pPKey2->default_rc;
+ }
+ }else if( res>0 ){
+ res = pPKey2->r2;
+ }else{
+ res = pPKey2->r1;
+ }
+ }else if( res>0 ){
+ res = pPKey2->r2;
+ }else{
+ res = pPKey2->r1;
+ }
+ }
+
+ assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
+ || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
+ || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
+ || CORRUPT_DB
+ );
+ return res;
+}
+
+/*
+** Return a pointer to an sqlite3VdbeRecordCompare() compatible function
+** suitable for comparing serialized records to the unpacked record passed
+** as the only argument.
+*/
+SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){
+ /* varintRecordCompareInt() and varintRecordCompareString() both assume
+ ** that the size-of-header varint that occurs at the start of each record
+ ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt()
+ ** also assumes that it is safe to overread a buffer by at least the
+ ** maximum possible legal header size plus 8 bytes. Because there is
+ ** guaranteed to be at least 74 (but not 136) bytes of padding following each
+ ** buffer passed to varintRecordCompareInt() this makes it convenient to
+ ** limit the size of the header to 64 bytes in cases where the first field
+ ** is an integer.
+ **
+ ** The easiest way to enforce this limit is to consider only records with
+ ** 13 fields or less. If the first field is an integer, the maximum legal
+ ** header size is (12*5 + 1 + 1) bytes. */
+ if( (p->pKeyInfo->nField + p->pKeyInfo->nXField)<=13 ){
+ int flags = p->aMem[0].flags;
+ if( p->pKeyInfo->aSortOrder[0] ){
+ p->r1 = 1;
+ p->r2 = -1;
+ }else{
+ p->r1 = -1;
+ p->r2 = 1;
+ }
+ if( (flags & MEM_Int) ){
+ return vdbeRecordCompareInt;
+ }
+ testcase( flags & MEM_Real );
+ testcase( flags & MEM_Null );
+ testcase( flags & MEM_Blob );
+ if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){
+ assert( flags & MEM_Str );
+ return vdbeRecordCompareString;
+ }
+ }
+
+ return sqlite3VdbeRecordCompare;
+}
/*
** pCur points at an index entry created using the OP_MakeRecord opcode.
@@ -64287,9 +65226,9 @@ idx_rowid_corruption:
** of the keys prior to the final rowid, not the entire key.
*/
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
- VdbeCursor *pC, /* The cursor to compare against */
- UnpackedRecord *pUnpacked, /* Unpacked version of key to compare against */
- int *res /* Write the comparison result here */
+ VdbeCursor *pC, /* The cursor to compare against */
+ const UnpackedRecord *pUnpacked, /* Unpacked version of key */
+ int *res /* Write the comparison result here */
){
i64 nCellKey = 0;
int rc;
@@ -64299,7 +65238,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
assert( sqlite3BtreeCursorIsValid(pCur) );
VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
- /* nCellKey will always be between 0 and 0xffffffff because of the say
+ /* nCellKey will always be between 0 and 0xffffffff because of the way
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
if( nCellKey<=0 || nCellKey>0x7fffffff ){
*res = 0;
@@ -64310,8 +65249,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
if( rc ){
return rc;
}
- assert( pUnpacked->flags & UNPACKED_PREFIX_MATCH );
- *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
+ *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked, 0);
sqlite3VdbeMemRelease(&m);
return SQLITE_OK;
}
@@ -64375,7 +65313,6 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff
if( pRet ){
sqlite3VdbeMemCopy((Mem *)pRet, pMem);
sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8);
- sqlite3VdbeMemStoreType((Mem *)pRet);
}
return pRet;
}
@@ -64549,7 +65486,6 @@ SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
Mem *p = (Mem*)pVal;
if( p->flags & (MEM_Blob|MEM_Str) ){
sqlite3VdbeMemExpandBlob(p);
- p->flags &= ~MEM_Str;
p->flags |= MEM_Blob;
return p->n ? p->z : 0;
}else{
@@ -64586,7 +65522,41 @@ SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
}
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
- return pVal->type;
+ static const u8 aType[] = {
+ SQLITE_BLOB, /* 0x00 */
+ SQLITE_NULL, /* 0x01 */
+ SQLITE_TEXT, /* 0x02 */
+ SQLITE_NULL, /* 0x03 */
+ SQLITE_INTEGER, /* 0x04 */
+ SQLITE_NULL, /* 0x05 */
+ SQLITE_INTEGER, /* 0x06 */
+ SQLITE_NULL, /* 0x07 */
+ SQLITE_FLOAT, /* 0x08 */
+ SQLITE_NULL, /* 0x09 */
+ SQLITE_FLOAT, /* 0x0a */
+ SQLITE_NULL, /* 0x0b */
+ SQLITE_INTEGER, /* 0x0c */
+ SQLITE_NULL, /* 0x0d */
+ SQLITE_INTEGER, /* 0x0e */
+ SQLITE_NULL, /* 0x0f */
+ SQLITE_BLOB, /* 0x10 */
+ SQLITE_NULL, /* 0x11 */
+ SQLITE_TEXT, /* 0x12 */
+ SQLITE_NULL, /* 0x13 */
+ SQLITE_INTEGER, /* 0x14 */
+ SQLITE_NULL, /* 0x15 */
+ SQLITE_INTEGER, /* 0x16 */
+ SQLITE_NULL, /* 0x17 */
+ SQLITE_FLOAT, /* 0x18 */
+ SQLITE_NULL, /* 0x19 */
+ SQLITE_FLOAT, /* 0x1a */
+ SQLITE_NULL, /* 0x1b */
+ SQLITE_INTEGER, /* 0x1c */
+ SQLITE_NULL, /* 0x1d */
+ SQLITE_INTEGER, /* 0x1e */
+ SQLITE_NULL, /* 0x1f */
+ };
+ return aType[pVal->flags&MEM_AffMask];
}
/**************************** sqlite3_result_ *******************************
@@ -64900,7 +65870,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
v->doingRerun = 1;
assert( v->expired==0 );
}
- if( rc2!=SQLITE_OK && ALWAYS(v->isPrepareV2) && ALWAYS(db->pErr) ){
+ if( rc2!=SQLITE_OK ){
/* This case occurs after failing to recompile an sql statement.
** The error message from the SQL compiler has already been loaded
** into the database handle. This block copies the error message
@@ -64910,6 +65880,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
** sqlite3_errmsg() and sqlite3_errcode().
*/
const char *zErr = (const char *)sqlite3_value_text(db->pErr);
+ assert( zErr!=0 || db->mallocFailed );
sqlite3DbFree(db, v->zErrMsg);
if( !db->mallocFailed ){
v->zErrMsg = sqlite3DbStrDup(db, zErr);
@@ -65106,6 +66077,30 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
return pVm->nResColumn;
}
+/*
+** Return a pointer to static memory containing an SQL NULL value.
+*/
+static const Mem *columnNullValue(void){
+ /* Even though the Mem structure contains an element
+ ** of type i64, on certain architectures (x86) with certain compiler
+ ** switches (-Os), gcc may align this Mem object on a 4-byte boundary
+ ** instead of an 8-byte one. This all works fine, except that when
+ ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
+ ** that a Mem structure is located on an 8-byte boundary. To prevent
+ ** these assert()s from failing, when building with SQLITE_DEBUG defined
+ ** using gcc, we force nullMem to be 8-byte aligned using the magical
+ ** __attribute__((aligned(8))) macro. */
+ static const Mem nullMem
+#if defined(SQLITE_DEBUG) && defined(__GNUC__)
+ __attribute__((aligned(8)))
+#endif
+ = {0, "", (double)0, {0}, 0, MEM_Null, 0,
+#ifdef SQLITE_DEBUG
+ 0, 0, /* pScopyFrom, pFiller */
+#endif
+ 0, 0 };
+ return &nullMem;
+}
/*
** Check to see if column iCol of the given statement is valid. If
@@ -65122,32 +66117,11 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
sqlite3_mutex_enter(pVm->db->mutex);
pOut = &pVm->pResultSet[i];
}else{
- /* If the value passed as the second argument is out of range, return
- ** a pointer to the following static Mem object which contains the
- ** value SQL NULL. Even though the Mem structure contains an element
- ** of type i64, on certain architectures (x86) with certain compiler
- ** switches (-Os), gcc may align this Mem object on a 4-byte boundary
- ** instead of an 8-byte one. This all works fine, except that when
- ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
- ** that a Mem structure is located on an 8-byte boundary. To prevent
- ** these assert()s from failing, when building with SQLITE_DEBUG defined
- ** using gcc, we force nullMem to be 8-byte aligned using the magical
- ** __attribute__((aligned(8))) macro. */
- static const Mem nullMem
-#if defined(SQLITE_DEBUG) && defined(__GNUC__)
- __attribute__((aligned(8)))
-#endif
- = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0,
-#ifdef SQLITE_DEBUG
- 0, 0, /* pScopyFrom, pFiller */
-#endif
- 0, 0 };
-
if( pVm && ALWAYS(pVm->db) ){
sqlite3_mutex_enter(pVm->db->mutex);
sqlite3Error(pVm->db, SQLITE_RANGE, 0);
}
- pOut = (Mem*)&nullMem;
+ pOut = (Mem*)columnNullValue();
}
return pOut;
}
@@ -65544,7 +66518,7 @@ SQLITE_API int sqlite3_bind_text16(
#endif /* SQLITE_OMIT_UTF16 */
SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
int rc;
- switch( pValue->type ){
+ switch( sqlite3_value_type((sqlite3_value*)pValue) ){
case SQLITE_INTEGER: {
rc = sqlite3_bind_int64(pStmt, i, pValue->u.i);
break;
@@ -65825,6 +66799,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
const char *zStart = zRawSql;
while( *(zRawSql++)!='\n' && *zRawSql );
sqlite3StrAccumAppend(&out, "-- ", 3);
+ assert( (zRawSql - zStart) > 0 );
sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
}
}else{
@@ -65857,9 +66832,9 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
if( pVar->flags & MEM_Null ){
sqlite3StrAccumAppend(&out, "NULL", 4);
}else if( pVar->flags & MEM_Int ){
- sqlite3XPrintf(&out, "%lld", pVar->u.i);
+ sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
}else if( pVar->flags & MEM_Real ){
- sqlite3XPrintf(&out, "%!.15g", pVar->r);
+ sqlite3XPrintf(&out, 0, "%!.15g", pVar->r);
}else if( pVar->flags & MEM_Str ){
int nOut; /* Number of bytes of the string text to include in output */
#ifndef SQLITE_OMIT_UTF16
@@ -65880,15 +66855,17 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
}
#endif
- sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
+ sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z);
#ifdef SQLITE_TRACE_SIZE_LIMIT
- if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+ if( nOut<pVar->n ){
+ sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
+ }
#endif
#ifndef SQLITE_OMIT_UTF16
if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
#endif
}else if( pVar->flags & MEM_Zero ){
- sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
+ sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero);
}else{
int nOut; /* Number of bytes of the blob to include in output */
assert( pVar->flags & MEM_Blob );
@@ -65898,11 +66875,13 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
#endif
for(i=0; i<nOut; i++){
- sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
+ sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff);
}
sqlite3StrAccumAppend(&out, "'", 1);
#ifdef SQLITE_TRACE_SIZE_LIMIT
- if( nOut<pVar->n ) sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
+ if( nOut<pVar->n ){
+ sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
+ }
#endif
}
}
@@ -65961,7 +66940,7 @@ SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
}
va_start(ap, zFormat);
- sqlite3VXPrintf(&p->str, 1, zFormat, ap);
+ sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap);
va_end(ap);
}
}
@@ -66040,33 +67019,8 @@ SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
** May you share freely, never taking more than you give.
**
*************************************************************************
-** The code in this file implements execution method of the
-** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c")
-** handles housekeeping details such as creating and deleting
-** VDBE instances. This file is solely interested in executing
-** the VDBE program.
-**
-** In the external interface, an "sqlite3_stmt*" is an opaque pointer
-** to a VDBE.
-**
-** The SQL parser generates a program which is then executed by
-** the VDBE to do the work of the SQL statement. VDBE programs are
-** similar in form to assembly language. The program consists of
-** a linear sequence of operations. Each operation has an opcode
-** and 5 operands. Operands P1, P2, and P3 are integers. Operand P4
-** is a null-terminated string. Operand P5 is an unsigned character.
-** Few opcodes use all 5 operands.
-**
-** Computation results are stored on a set of registers numbered beginning
-** with 1 and going up to Vdbe.nMem. Each register can store
-** either an integer, a null-terminated string, a floating point
-** number, or the SQL "NULL" value. An implicit conversion from one
-** type to the other occurs as necessary.
-**
-** Most of the code in this file is taken up by the sqlite3VdbeExec()
-** function which does the work of interpreting a VDBE program.
-** But other routines are also provided to help in building up
-** a program instruction by instruction.
+** The code in this file implements the function that runs the
+** bytecode of a prepared statement.
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files. The formatting
@@ -66078,7 +67032,11 @@ SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
/*
** Invoke this macro on memory cells just prior to changing the
** value of the cell. This macro verifies that shallow copies are
-** not misused.
+** not misused. A shallow copy of a string or blob just copies a
+** pointer to the string or blob, not the content. If the original
+** is changed while the copy is still in use, the string or blob might
+** be changed out from under the copy. This macro verifies that nothing
+** like that ever happens.
*/
#ifdef SQLITE_DEBUG
# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M)
@@ -66137,7 +67095,7 @@ static void updateMaxBlobsize(Mem *p){
#endif
/*
-** The next global variable is incremented each type the OP_Found opcode
+** The next global variable is incremented each time the OP_Found opcode
** is executed. This is used to test whether or not the foreign key
** operation implemented using OP_FkIsZero is working. This variable
** has no function other than to help verify the correct operation of the
@@ -66158,6 +67116,34 @@ SQLITE_API int sqlite3_found_count = 0;
#endif
/*
+** Invoke the VDBE coverage callback, if that callback is defined. This
+** feature is used for test suite validation only and does not appear an
+** production builds.
+**
+** M is an integer, 2 or 3, that indices how many different ways the
+** branch can go. It is usually 2. "I" is the direction the branch
+** goes. 0 means falls through. 1 means branch is taken. 2 means the
+** second alternative branch is taken.
+*/
+#if !defined(SQLITE_VDBE_COVERAGE)
+# define VdbeBranchTaken(I,M)
+#else
+# define VdbeBranchTaken(I,M) vdbeTakeBranch(pOp->iSrcLine,I,M)
+ static void vdbeTakeBranch(int iSrcLine, u8 I, u8 M){
+ if( iSrcLine<=2 && ALWAYS(iSrcLine>0) ){
+ M = iSrcLine;
+ /* Assert the truth of VdbeCoverageAlwaysTaken() and
+ ** VdbeCoverageNeverTaken() */
+ assert( (M & I)==I );
+ }else{
+ if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/
+ sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
+ iSrcLine,I,M);
+ }
+ }
+#endif
+
+/*
** Convert the given register into a string if it isn't one
** already. Return non-zero if a malloc() fails.
*/
@@ -66174,38 +67160,14 @@ SQLITE_API int sqlite3_found_count = 0;
**
** This routine converts an ephemeral string into a dynamically allocated
** string that the register itself controls. In other words, it
-** converts an MEM_Ephem string into an MEM_Dyn string.
+** converts an MEM_Ephem string into a string with P.z==P.zMalloc.
*/
#define Deephemeralize(P) \
if( ((P)->flags&MEM_Ephem)!=0 \
&& sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;}
/* Return true if the cursor was opened using the OP_OpenSorter opcode. */
-# define isSorter(x) ((x)->pSorter!=0)
-
-/*
-** Argument pMem points at a register that will be passed to a
-** user-defined function or returned to the user as the result of a query.
-** This routine sets the pMem->type variable used by the sqlite3_value_*()
-** routines.
-*/
-SQLITE_PRIVATE void sqlite3VdbeMemStoreType(Mem *pMem){
- int flags = pMem->flags;
- if( flags & MEM_Null ){
- pMem->type = SQLITE_NULL;
- }
- else if( flags & MEM_Int ){
- pMem->type = SQLITE_INTEGER;
- }
- else if( flags & MEM_Real ){
- pMem->type = SQLITE_FLOAT;
- }
- else if( flags & MEM_Str ){
- pMem->type = SQLITE_TEXT;
- }else{
- pMem->type = SQLITE_BLOB;
- }
-}
+#define isSorter(x) ((x)->pSorter!=0)
/*
** Allocate VdbeCursor number iCur. Return a pointer to it. Return NULL
@@ -66335,12 +67297,13 @@ static void applyAffinity(
** loss of information and return the revised type of the argument.
*/
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
- Mem *pMem = (Mem*)pVal;
- if( pMem->type==SQLITE_TEXT ){
+ int eType = sqlite3_value_type(pVal);
+ if( eType==SQLITE_TEXT ){
+ Mem *pMem = (Mem*)pVal;
applyNumericAffinity(pMem);
- sqlite3VdbeMemStoreType(pMem);
+ eType = sqlite3_value_type(pVal);
}
- return pMem->type;
+ return eType;
}
/*
@@ -66443,7 +67406,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){
** Print the value of a register for tracing purposes:
*/
static void memTracePrint(Mem *p){
- if( p->flags & MEM_Invalid ){
+ if( p->flags & MEM_Undefined ){
printf(" undefined");
}else if( p->flags & MEM_Null ){
printf(" NULL");
@@ -66576,20 +67539,6 @@ SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
#endif
-/*
-** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
-** sqlite3_interrupt() routine has been called. If it has been, then
-** processing of the VDBE program is interrupted.
-**
-** This macro added to every instruction that does a jump in order to
-** implement a loop. This test used to be on every single instruction,
-** but that meant we more testing than we needed. By only testing the
-** flag on jump instructions, we get a (small) speed improvement.
-*/
-#define CHECK_FOR_INTERRUPT \
- if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
-
-
#ifndef NDEBUG
/*
** This function is only called from within an assert() expression. It
@@ -66612,35 +67561,8 @@ static int checkSavepointCount(sqlite3 *db){
/*
-** Execute as much of a VDBE program as we can then return.
-**
-** sqlite3VdbeMakeReady() must be called before this routine in order to
-** close the program with a final OP_Halt and to set up the callbacks
-** and the error message pointer.
-**
-** Whenever a row or result data is available, this routine will either
-** invoke the result callback (if there is one) or return with
-** SQLITE_ROW.
-**
-** If an attempt is made to open a locked database, then this routine
-** will either invoke the busy callback (if there is one) or it will
-** return SQLITE_BUSY.
-**
-** If an error occurs, an error message is written to memory obtained
-** from sqlite3_malloc() and p->zErrMsg is made to point to that memory.
-** The error code is stored in p->rc and this routine returns SQLITE_ERROR.
-**
-** If the callback ever returns non-zero, then the program exits
-** immediately. There will be no error message but the p->rc field is
-** set to SQLITE_ABORT and this routine will return SQLITE_ERROR.
-**
-** A memory allocation error causes p->rc to be set to SQLITE_NOMEM and this
-** routine to return SQLITE_ERROR.
-**
-** Other fatal errors return SQLITE_ERROR.
-**
-** After this routine has finished, sqlite3VdbeFinalize() should be
-** used to clean up the mess that was left behind.
+** Execute as much of a VDBE program as we can.
+** This is the core of sqlite3_step().
*/
SQLITE_PRIVATE int sqlite3VdbeExec(
Vdbe *p /* The VDBE */
@@ -66666,431 +67588,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
i64 lastRowid = db->lastRowid; /* Saved value of the last insert ROWID */
#ifdef VDBE_PROFILE
u64 start; /* CPU clock count at start of opcode */
- int origPc; /* Program counter at start of opcode */
-#endif
- /********************************************************************
- ** Automatically generated code
- **
- ** The following union is automatically generated by the
- ** vdbe-compress.tcl script. The purpose of this union is to
- ** reduce the amount of stack space required by this function.
- ** See comments in the vdbe-compress.tcl script for details.
- */
- union vdbeExecUnion {
- struct OP_Yield_stack_vars {
- int pcDest;
- } aa;
- struct OP_Halt_stack_vars {
- const char *zType;
- const char *zLogFmt;
- } ab;
- struct OP_Null_stack_vars {
- int cnt;
- u16 nullFlag;
- } ac;
- struct OP_Variable_stack_vars {
- Mem *pVar; /* Value being transferred */
- } ad;
- struct OP_Move_stack_vars {
- char *zMalloc; /* Holding variable for allocated memory */
- int n; /* Number of registers left to copy */
- int p1; /* Register to copy from */
- int p2; /* Register to copy to */
- } ae;
- struct OP_Copy_stack_vars {
- int n;
- } af;
- struct OP_ResultRow_stack_vars {
- Mem *pMem;
- int i;
- } ag;
- struct OP_Concat_stack_vars {
- i64 nByte;
- } ah;
- struct OP_Remainder_stack_vars {
- char bIntint; /* Started out as two integer operands */
- int flags; /* Combined MEM_* flags from both inputs */
- i64 iA; /* Integer value of left operand */
- i64 iB; /* Integer value of right operand */
- double rA; /* Real value of left operand */
- double rB; /* Real value of right operand */
- } ai;
- struct OP_Function_stack_vars {
- int i;
- Mem *pArg;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- int n;
- } aj;
- struct OP_ShiftRight_stack_vars {
- i64 iA;
- u64 uA;
- i64 iB;
- u8 op;
- } ak;
- struct OP_Ge_stack_vars {
- int res; /* Result of the comparison of pIn1 against pIn3 */
- char affinity; /* Affinity to use for comparison */
- u16 flags1; /* Copy of initial value of pIn1->flags */
- u16 flags3; /* Copy of initial value of pIn3->flags */
- } al;
- struct OP_Compare_stack_vars {
- int n;
- int i;
- int p1;
- int p2;
- const KeyInfo *pKeyInfo;
- int idx;
- CollSeq *pColl; /* Collating sequence to use on this term */
- int bRev; /* True for DESCENDING sort order */
- } am;
- struct OP_Or_stack_vars {
- int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
- } an;
- struct OP_IfNot_stack_vars {
- int c;
- } ao;
- struct OP_Column_stack_vars {
- i64 payloadSize64; /* Number of bytes in the record */
- int p2; /* column number to retrieve */
- VdbeCursor *pC; /* The VDBE cursor */
- BtCursor *pCrsr; /* The BTree cursor */
- u32 *aType; /* aType[i] holds the numeric type of the i-th column */
- u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */
- int len; /* The length of the serialized data for the column */
- int i; /* Loop counter */
- Mem *pDest; /* Where to write the extracted value */
- Mem sMem; /* For storing the record being decoded */
- const u8 *zData; /* Part of the record being decoded */
- const u8 *zHdr; /* Next unparsed byte of the header */
- const u8 *zEndHdr; /* Pointer to first byte after the header */
- u32 offset; /* Offset into the data */
- u32 szField; /* Number of bytes in the content of a field */
- u32 avail; /* Number of bytes of available data */
- u32 t; /* A type code from the record header */
- Mem *pReg; /* PseudoTable input register */
- } ap;
- struct OP_Affinity_stack_vars {
- const char *zAffinity; /* The affinity to be applied */
- char cAff; /* A single character of affinity */
- } aq;
- struct OP_MakeRecord_stack_vars {
- u8 *zNewRecord; /* A buffer to hold the data for the new record */
- Mem *pRec; /* The new record */
- u64 nData; /* Number of bytes of data space */
- int nHdr; /* Number of bytes of header space */
- i64 nByte; /* Data space required for this record */
- int nZero; /* Number of zero bytes at the end of the record */
- int nVarint; /* Number of bytes in a varint */
- u32 serial_type; /* Type field */
- Mem *pData0; /* First field to be combined into the record */
- Mem *pLast; /* Last field of the record */
- int nField; /* Number of fields in the record */
- char *zAffinity; /* The affinity string for the record */
- int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
- int len; /* Length of a field */
- } ar;
- struct OP_Count_stack_vars {
- i64 nEntry;
- BtCursor *pCrsr;
- } as;
- struct OP_Savepoint_stack_vars {
- int p1; /* Value of P1 operand */
- char *zName; /* Name of savepoint */
- int nName;
- Savepoint *pNew;
- Savepoint *pSavepoint;
- Savepoint *pTmp;
- int iSavepoint;
- int ii;
- } at;
- struct OP_AutoCommit_stack_vars {
- int desiredAutoCommit;
- int iRollback;
- int turnOnAC;
- } au;
- struct OP_Transaction_stack_vars {
- Btree *pBt;
- } av;
- struct OP_ReadCookie_stack_vars {
- int iMeta;
- int iDb;
- int iCookie;
- } aw;
- struct OP_SetCookie_stack_vars {
- Db *pDb;
- } ax;
- struct OP_VerifyCookie_stack_vars {
- int iMeta;
- int iGen;
- Btree *pBt;
- } ay;
- struct OP_OpenWrite_stack_vars {
- int nField;
- KeyInfo *pKeyInfo;
- int p2;
- int iDb;
- int wrFlag;
- Btree *pX;
- VdbeCursor *pCur;
- Db *pDb;
- } az;
- struct OP_OpenEphemeral_stack_vars {
- VdbeCursor *pCx;
- KeyInfo *pKeyInfo;
- } ba;
- struct OP_SorterOpen_stack_vars {
- VdbeCursor *pCx;
- } bb;
- struct OP_OpenPseudo_stack_vars {
- VdbeCursor *pCx;
- } bc;
- struct OP_SeekGt_stack_vars {
- int res;
- int oc;
- VdbeCursor *pC;
- UnpackedRecord r;
- int nField;
- i64 iKey; /* The rowid we are to seek to */
- } bd;
- struct OP_Seek_stack_vars {
- VdbeCursor *pC;
- } be;
- struct OP_Found_stack_vars {
- int alreadyExists;
- int ii;
- VdbeCursor *pC;
- int res;
- char *pFree;
- UnpackedRecord *pIdxKey;
- UnpackedRecord r;
- char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
- } bf;
- struct OP_NotExists_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- u64 iKey;
- } bg;
- struct OP_NewRowid_stack_vars {
- i64 v; /* The new rowid */
- VdbeCursor *pC; /* Cursor of table to get the new rowid */
- int res; /* Result of an sqlite3BtreeLast() */
- int cnt; /* Counter to limit the number of searches */
- Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
- VdbeFrame *pFrame; /* Root frame of VDBE */
- } bh;
- struct OP_InsertInt_stack_vars {
- Mem *pData; /* MEM cell holding data for the record to be inserted */
- Mem *pKey; /* MEM cell holding key for the record */
- i64 iKey; /* The integer ROWID or key for the record to be inserted */
- VdbeCursor *pC; /* Cursor to table into which insert is written */
- int nZero; /* Number of zero-bytes to append */
- int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */
- const char *zDb; /* database name - used by the update hook */
- const char *zTbl; /* Table name - used by the opdate hook */
- int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
- } bi;
- struct OP_Delete_stack_vars {
- i64 iKey;
- VdbeCursor *pC;
- } bj;
- struct OP_SorterCompare_stack_vars {
- VdbeCursor *pC;
- int res;
- int nIgnore;
- } bk;
- struct OP_SorterData_stack_vars {
- VdbeCursor *pC;
- } bl;
- struct OP_RowData_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- u32 n;
- i64 n64;
- } bm;
- struct OP_Rowid_stack_vars {
- VdbeCursor *pC;
- i64 v;
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- } bn;
- struct OP_NullRow_stack_vars {
- VdbeCursor *pC;
- } bo;
- struct OP_Last_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- } bp;
- struct OP_Rewind_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- } bq;
- struct OP_SorterNext_stack_vars {
- VdbeCursor *pC;
- int res;
- } br;
- struct OP_IdxInsert_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int nKey;
- const char *zKey;
- } bs;
- struct OP_IdxDelete_stack_vars {
- VdbeCursor *pC;
- BtCursor *pCrsr;
- int res;
- UnpackedRecord r;
- } bt;
- struct OP_IdxRowid_stack_vars {
- BtCursor *pCrsr;
- VdbeCursor *pC;
- i64 rowid;
- } bu;
- struct OP_IdxGE_stack_vars {
- VdbeCursor *pC;
- int res;
- UnpackedRecord r;
- } bv;
- struct OP_Destroy_stack_vars {
- int iMoved;
- int iCnt;
- Vdbe *pVdbe;
- int iDb;
- } bw;
- struct OP_Clear_stack_vars {
- int nChange;
- } bx;
- struct OP_CreateTable_stack_vars {
- int pgno;
- int flags;
- Db *pDb;
- } by;
- struct OP_ParseSchema_stack_vars {
- int iDb;
- const char *zMaster;
- char *zSql;
- InitData initData;
- } bz;
- struct OP_IntegrityCk_stack_vars {
- int nRoot; /* Number of tables to check. (Number of root pages.) */
- int *aRoot; /* Array of rootpage numbers for tables to be checked */
- int j; /* Loop counter */
- int nErr; /* Number of errors reported */
- char *z; /* Text of the error report */
- Mem *pnErr; /* Register keeping track of errors remaining */
- } ca;
- struct OP_RowSetRead_stack_vars {
- i64 val;
- } cb;
- struct OP_RowSetTest_stack_vars {
- int iSet;
- int exists;
- } cc;
- struct OP_Program_stack_vars {
- int nMem; /* Number of memory registers for sub-program */
- int nByte; /* Bytes of runtime space required for sub-program */
- Mem *pRt; /* Register to allocate runtime space */
- Mem *pMem; /* Used to iterate through memory cells */
- Mem *pEnd; /* Last memory cell in new array */
- VdbeFrame *pFrame; /* New vdbe frame to execute in */
- SubProgram *pProgram; /* Sub-program to execute */
- void *t; /* Token identifying trigger */
- } cd;
- struct OP_Param_stack_vars {
- VdbeFrame *pFrame;
- Mem *pIn;
- } ce;
- struct OP_MemMax_stack_vars {
- Mem *pIn1;
- VdbeFrame *pFrame;
- } cf;
- struct OP_AggStep_stack_vars {
- int n;
- int i;
- Mem *pMem;
- Mem *pRec;
- sqlite3_context ctx;
- sqlite3_value **apVal;
- } cg;
- struct OP_AggFinal_stack_vars {
- Mem *pMem;
- } ch;
- struct OP_Checkpoint_stack_vars {
- int i; /* Loop counter */
- int aRes[3]; /* Results */
- Mem *pMem; /* Write results here */
- } ci;
- struct OP_JournalMode_stack_vars {
- Btree *pBt; /* Btree to change journal mode of */
- Pager *pPager; /* Pager associated with pBt */
- int eNew; /* New journal mode */
- int eOld; /* The old journal mode */
-#ifndef SQLITE_OMIT_WAL
- const char *zFilename; /* Name of database file for pPager */
#endif
- } cj;
- struct OP_IncrVacuum_stack_vars {
- Btree *pBt;
- } ck;
- struct OP_VBegin_stack_vars {
- VTable *pVTab;
- } cl;
- struct OP_VOpen_stack_vars {
- VdbeCursor *pCur;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- } cm;
- struct OP_VFilter_stack_vars {
- int nArg;
- int iQuery;
- const sqlite3_module *pModule;
- Mem *pQuery;
- Mem *pArgc;
- sqlite3_vtab_cursor *pVtabCursor;
- sqlite3_vtab *pVtab;
- VdbeCursor *pCur;
- int res;
- int i;
- Mem **apArg;
- } cn;
- struct OP_VColumn_stack_vars {
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- Mem *pDest;
- sqlite3_context sContext;
- } co;
- struct OP_VNext_stack_vars {
- sqlite3_vtab *pVtab;
- const sqlite3_module *pModule;
- int res;
- VdbeCursor *pCur;
- } cp;
- struct OP_VRename_stack_vars {
- sqlite3_vtab *pVtab;
- Mem *pName;
- } cq;
- struct OP_VUpdate_stack_vars {
- sqlite3_vtab *pVtab;
- sqlite3_module *pModule;
- int nArg;
- int i;
- sqlite_int64 rowid;
- Mem **apArg;
- Mem *pX;
- } cr;
- struct OP_Trace_stack_vars {
- char *zTrace;
- char *z;
- } cs;
- } u;
- /* End automatically generated code
- ********************************************************************/
+ /*** INSERT STACK UNION HERE ***/
assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */
sqlite3VdbeEnter(p);
@@ -67106,7 +67605,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
assert( p->explain==0 );
p->pResultSet = 0;
db->busyHandler.nBusy = 0;
- CHECK_FOR_INTERRUPT;
+ if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
sqlite3VdbeIOTraceSql(p);
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
if( db->xProgress ){
@@ -67150,7 +67649,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
assert( pc>=0 && pc<p->nOp );
if( db->mallocFailed ) goto no_mem;
#ifdef VDBE_PROFILE
- origPc = pc;
start = sqlite3Hwtime();
#endif
nVmStep++;
@@ -67198,18 +67696,21 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
assert( pOp->p1>0 );
assert( pOp->p1<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p1]) );
+ assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) );
REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]);
}
if( (pOp->opflags & OPFLG_IN2)!=0 ){
assert( pOp->p2>0 );
assert( pOp->p2<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p2]) );
+ assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) );
REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]);
}
if( (pOp->opflags & OPFLG_IN3)!=0 ){
assert( pOp->p3>0 );
assert( pOp->p3<=(p->nMem-p->nCursor) );
assert( memIsValid(&aMem[pOp->p3]) );
+ assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) );
REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]);
}
if( (pOp->opflags & OPFLG_OUT2)!=0 ){
@@ -67267,6 +67768,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
** The next instruction executed will be
** the one at index P2 from the beginning of
** the program.
+**
+** The P1 parameter is not actually used by this opcode. However, it
+** is sometimes set to 1 instead of 0 as a hint to the command-line shell
+** that this Goto is the bottom of a loop and that the lines from P2 down
+** to the current line should be indented for EXPLAIN output.
*/
case OP_Goto: { /* jump */
pc = pOp->p2 - 1;
@@ -67282,7 +67788,7 @@ case OP_Goto: { /* jump */
** checks on every opcode. This helps sqlite3_step() to run about 1.5%
** faster according to "valgrind --tool=cachegrind" */
check_for_interrupt:
- CHECK_FOR_INTERRUPT;
+ if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
/* Call the progress callback if it is configured and the required number
** of VDBE ops have been executed (either since this invocation of
@@ -67311,7 +67817,7 @@ check_for_interrupt:
case OP_Gosub: { /* jump */
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
pIn1 = &aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Dyn)==0 );
+ assert( VdbeMemDynamic(pIn1)==0 );
memAboutToChange(p, pIn1);
pIn1->flags = MEM_Int;
pIn1->u.i = pc;
@@ -67322,35 +67828,79 @@ case OP_Gosub: { /* jump */
/* Opcode: Return P1 * * * *
**
-** Jump to the next instruction after the address in register P1.
+** Jump to the next instruction after the address in register P1. After
+** the jump, register P1 becomes undefined.
*/
case OP_Return: { /* in1 */
pIn1 = &aMem[pOp->p1];
- assert( pIn1->flags & MEM_Int );
+ assert( pIn1->flags==MEM_Int );
pc = (int)pIn1->u.i;
+ pIn1->flags = MEM_Undefined;
+ break;
+}
+
+/* Opcode: InitCoroutine P1 P2 P3 * *
+**
+** Set up register P1 so that it will OP_Yield to the co-routine
+** located at address P3.
+**
+** If P2!=0 then the co-routine implementation immediately follows
+** this opcode. So jump over the co-routine implementation to
+** address P2.
+*/
+case OP_InitCoroutine: { /* jump */
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+ assert( pOp->p2>=0 && pOp->p2<p->nOp );
+ assert( pOp->p3>=0 && pOp->p3<p->nOp );
+ pOut = &aMem[pOp->p1];
+ assert( !VdbeMemDynamic(pOut) );
+ pOut->u.i = pOp->p3 - 1;
+ pOut->flags = MEM_Int;
+ if( pOp->p2 ) pc = pOp->p2 - 1;
break;
}
-/* Opcode: Yield P1 * * * *
+/* Opcode: EndCoroutine P1 * * * *
+**
+** The instruction at the address in register P1 is an OP_Yield.
+** Jump to the P2 parameter of that OP_Yield.
+** After the jump, register P1 becomes undefined.
+*/
+case OP_EndCoroutine: { /* in1 */
+ VdbeOp *pCaller;
+ pIn1 = &aMem[pOp->p1];
+ assert( pIn1->flags==MEM_Int );
+ assert( pIn1->u.i>=0 && pIn1->u.i<p->nOp );
+ pCaller = &aOp[pIn1->u.i];
+ assert( pCaller->opcode==OP_Yield );
+ assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
+ pc = pCaller->p2 - 1;
+ pIn1->flags = MEM_Undefined;
+ break;
+}
+
+/* Opcode: Yield P1 P2 * * *
**
** Swap the program counter with the value in register P1.
+**
+** If the co-routine ends with OP_Yield or OP_Return then continue
+** to the next instruction. But if the co-routine ends with
+** OP_EndCoroutine, jump immediately to P2.
*/
-case OP_Yield: { /* in1 */
-#if 0 /* local variables moved into u.aa */
+case OP_Yield: { /* in1, jump */
int pcDest;
-#endif /* local variables moved into u.aa */
pIn1 = &aMem[pOp->p1];
- assert( (pIn1->flags & MEM_Dyn)==0 );
+ assert( VdbeMemDynamic(pIn1)==0 );
pIn1->flags = MEM_Int;
- u.aa.pcDest = (int)pIn1->u.i;
+ pcDest = (int)pIn1->u.i;
pIn1->u.i = pc;
REGISTER_TRACE(pOp->p1, pIn1);
- pc = u.aa.pcDest;
+ pc = pcDest;
break;
}
/* Opcode: HaltIfNull P1 P2 P3 P4 P5
-** Synopsis: if r[P3] null then halt
+** Synopsis: if r[P3]=null halt
**
** Check the value in register P3. If it is NULL then Halt using
** parameter P1, P2, and P4 as if this were a Halt instruction. If the
@@ -67394,10 +67944,8 @@ case OP_HaltIfNull: { /* in3 */
** is the same as executing Halt.
*/
case OP_Halt: {
-#if 0 /* local variables moved into u.ab */
const char *zType;
const char *zLogFmt;
-#endif /* local variables moved into u.ab */
if( pOp->p1==SQLITE_OK && p->pFrame ){
/* Halt the sub-program. Return control to the parent frame. */
@@ -67408,7 +67956,7 @@ case OP_Halt: {
pc = sqlite3VdbeFrameRestore(pFrame);
lastRowid = db->lastRowid;
if( pOp->p2==OE_Ignore ){
- /* Instruction pc is the OP_Program that invoked the sub-program
+ /* Instruction pc is the OP_Program that invoked the sub-program
** currently being halted. If the p2 instruction of this OP_Halt
** instruction is set to OE_Ignore, then the sub-program is throwing
** an IGNORE exception. In this case jump to the address specified
@@ -67431,21 +67979,21 @@ case OP_Halt: {
testcase( pOp->p5==2 );
testcase( pOp->p5==3 );
testcase( pOp->p5==4 );
- u.ab.zType = azType[pOp->p5-1];
+ zType = azType[pOp->p5-1];
}else{
- u.ab.zType = 0;
+ zType = 0;
}
- assert( u.ab.zType!=0 || pOp->p4.z!=0 );
- u.ab.zLogFmt = "abort at %d in [%s]: %s";
- if( u.ab.zType && pOp->p4.z ){
- sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
- u.ab.zType, pOp->p4.z);
+ assert( zType!=0 || pOp->p4.z!=0 );
+ zLogFmt = "abort at %d in [%s]: %s";
+ if( zType && pOp->p4.z ){
+ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
+ zType, pOp->p4.z);
}else if( pOp->p4.z ){
sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
}else{
- sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", u.ab.zType);
+ sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
}
- sqlite3_log(pOp->p1, u.ab.zLogFmt, pc, p->zSql, p->zErrMsg);
+ sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg);
}
rc = sqlite3VdbeHalt(p);
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -67500,7 +68048,9 @@ case OP_Real: { /* same as TK_FLOAT, out2-prerelease */
** Synopsis: r[P2]='P4'
**
** P4 points to a nul terminated UTF-8 string. This opcode is transformed
-** into an OP_String before it is executed for the first time.
+** into an OP_String before it is executed for the first time. During
+** this transformation, the length of string P4 is computed and stored
+** as the P1 parameter.
*/
case OP_String8: { /* same as TK_STRING, out2-prerelease */
assert( pOp->p4.z!=0 );
@@ -67513,10 +68063,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
if( rc==SQLITE_TOOBIG ) goto too_big;
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->zMalloc==pOut->z );
- assert( pOut->flags & MEM_Dyn );
+ assert( VdbeMemDynamic(pOut)==0 );
pOut->zMalloc = 0;
pOut->flags |= MEM_Static;
- pOut->flags &= ~MEM_Dyn;
if( pOp->p4type==P4_DYNAMIC ){
sqlite3DbFree(db, pOp->p4.z);
}
@@ -67559,25 +68108,37 @@ case OP_String: { /* out2-prerelease */
** OP_Ne or OP_Eq.
*/
case OP_Null: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ac */
int cnt;
u16 nullFlag;
-#endif /* local variables moved into u.ac */
- u.ac.cnt = pOp->p3-pOp->p2;
+ cnt = pOp->p3-pOp->p2;
assert( pOp->p3<=(p->nMem-p->nCursor) );
- pOut->flags = u.ac.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
- while( u.ac.cnt>0 ){
+ pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
+ while( cnt>0 ){
pOut++;
memAboutToChange(p, pOut);
VdbeMemRelease(pOut);
- pOut->flags = u.ac.nullFlag;
- u.ac.cnt--;
+ pOut->flags = nullFlag;
+ cnt--;
}
break;
}
+/* Opcode: SoftNull P1 * * * *
+** Synopsis: r[P1]=NULL
+**
+** Set register P1 to have the value NULL as seen by the OP_MakeRecord
+** instruction, but do not free any string or blob memory associated with
+** the register, so that if the value was a string or blob that was
+** previously copied using OP_SCopy, the copies will continue to be valid.
+*/
+case OP_SoftNull: {
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
+ pOut = &aMem[pOp->p1];
+ pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined;
+ break;
+}
-/* Opcode: Blob P1 P2 * P4
+/* Opcode: Blob P1 P2 * P4 *
** Synopsis: r[P2]=P4 (len=P1)
**
** P4 points to a blob of data P1 bytes long. Store this
@@ -67596,21 +68157,19 @@ case OP_Blob: { /* out2-prerelease */
**
** Transfer the values of bound parameter P1 into register P2
**
-** If the parameter is named, then its name appears in P4 and P3==1.
+** If the parameter is named, then its name appears in P4.
** The P4 value is used by sqlite3_bind_parameter_name().
*/
case OP_Variable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ad */
Mem *pVar; /* Value being transferred */
-#endif /* local variables moved into u.ad */
assert( pOp->p1>0 && pOp->p1<=p->nVar );
assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] );
- u.ad.pVar = &p->aVar[pOp->p1 - 1];
- if( sqlite3VdbeMemTooBig(u.ad.pVar) ){
+ pVar = &p->aVar[pOp->p1 - 1];
+ if( sqlite3VdbeMemTooBig(pVar) ){
goto too_big;
}
- sqlite3VdbeMemShallowCopy(pOut, u.ad.pVar, MEM_Static);
+ sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
UPDATE_MAX_BLOBSIZE(pOut);
break;
}
@@ -67624,44 +68183,44 @@ case OP_Variable: { /* out2-prerelease */
** P1..P1+P3 and P2..P2+P3 to overlap.
*/
case OP_Move: {
-#if 0 /* local variables moved into u.ae */
char *zMalloc; /* Holding variable for allocated memory */
int n; /* Number of registers left to copy */
int p1; /* Register to copy from */
int p2; /* Register to copy to */
-#endif /* local variables moved into u.ae */
- u.ae.n = pOp->p3;
- u.ae.p1 = pOp->p1;
- u.ae.p2 = pOp->p2;
- assert( u.ae.n>=0 && u.ae.p1>0 && u.ae.p2>0 );
- assert( u.ae.p1+u.ae.n<=u.ae.p2 || u.ae.p2+u.ae.n<=u.ae.p1 );
+ n = pOp->p3;
+ p1 = pOp->p1;
+ p2 = pOp->p2;
+ assert( n>=0 && p1>0 && p2>0 );
+ assert( p1+n<=p2 || p2+n<=p1 );
- pIn1 = &aMem[u.ae.p1];
- pOut = &aMem[u.ae.p2];
+ pIn1 = &aMem[p1];
+ pOut = &aMem[p2];
do{
assert( pOut<=&aMem[(p->nMem-p->nCursor)] );
assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
memAboutToChange(p, pOut);
- u.ae.zMalloc = pOut->zMalloc;
- pOut->zMalloc = 0;
- sqlite3VdbeMemMove(pOut, pIn1);
+ VdbeMemRelease(pOut);
+ zMalloc = pOut->zMalloc;
+ memcpy(pOut, pIn1, sizeof(Mem));
#ifdef SQLITE_DEBUG
- if( pOut->pScopyFrom>=&aMem[u.ae.p1] && pOut->pScopyFrom<&aMem[u.ae.p1+pOp->p3] ){
- pOut->pScopyFrom += u.ae.p1 - pOp->p2;
+ if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
+ pOut->pScopyFrom += p1 - pOp->p2;
}
#endif
- pIn1->zMalloc = u.ae.zMalloc;
- REGISTER_TRACE(u.ae.p2++, pOut);
+ pIn1->flags = MEM_Undefined;
+ pIn1->xDel = 0;
+ pIn1->zMalloc = zMalloc;
+ REGISTER_TRACE(p2++, pOut);
pIn1++;
pOut++;
- }while( u.ae.n-- );
+ }while( n-- );
break;
}
/* Opcode: Copy P1 P2 P3 * *
-** Synopsis: r[P2@P3]=r[P1@P3]
+** Synopsis: r[P2@P3+1]=r[P1@P3+1]
**
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
@@ -67669,11 +68228,9 @@ case OP_Move: {
** is made of any string or blob constant. See also OP_SCopy.
*/
case OP_Copy: {
-#if 0 /* local variables moved into u.af */
int n;
-#endif /* local variables moved into u.af */
- u.af.n = pOp->p3;
+ n = pOp->p3;
pIn1 = &aMem[pOp->p1];
pOut = &aMem[pOp->p2];
assert( pOut!=pIn1 );
@@ -67683,8 +68240,8 @@ case OP_Copy: {
#ifdef SQLITE_DEBUG
pOut->pScopyFrom = 0;
#endif
- REGISTER_TRACE(pOp->p2+pOp->p3-u.af.n, pOut);
- if( (u.af.n--)==0 ) break;
+ REGISTER_TRACE(pOp->p2+pOp->p3-n, pOut);
+ if( (n--)==0 ) break;
pOut++;
pIn1++;
}
@@ -67721,14 +68278,12 @@ case OP_SCopy: { /* out2 */
** The registers P1 through P1+P2-1 contain a single row of
** results. This opcode causes the sqlite3_step() call to terminate
** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
-** structure to provide access to the top P1 values as the result
-** row.
+** structure to provide access to the r(P1)..r(P1+P2-1) values as
+** the result row.
*/
case OP_ResultRow: {
-#if 0 /* local variables moved into u.ag */
Mem *pMem;
int i;
-#endif /* local variables moved into u.ag */
assert( p->nResColumn==pOp->p2 );
assert( pOp->p1>0 );
assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 );
@@ -67754,8 +68309,8 @@ case OP_ResultRow: {
break;
}
- /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
- ** DML statements invoke this opcode to return the number of rows
+ /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
+ ** DML statements invoke this opcode to return the number of rows
** modified to the user. This is the only way that a VM that
** opens a statement transaction may invoke this opcode.
**
@@ -67782,15 +68337,14 @@ case OP_ResultRow: {
** and have an assigned type. The results are de-ephemeralized as
** a side effect.
*/
- u.ag.pMem = p->pResultSet = &aMem[pOp->p1];
- for(u.ag.i=0; u.ag.i<pOp->p2; u.ag.i++){
- assert( memIsValid(&u.ag.pMem[u.ag.i]) );
- Deephemeralize(&u.ag.pMem[u.ag.i]);
- assert( (u.ag.pMem[u.ag.i].flags & MEM_Ephem)==0
- || (u.ag.pMem[u.ag.i].flags & (MEM_Str|MEM_Blob))==0 );
- sqlite3VdbeMemNulTerminate(&u.ag.pMem[u.ag.i]);
- sqlite3VdbeMemStoreType(&u.ag.pMem[u.ag.i]);
- REGISTER_TRACE(pOp->p1+u.ag.i, &u.ag.pMem[u.ag.i]);
+ pMem = p->pResultSet = &aMem[pOp->p1];
+ for(i=0; i<pOp->p2; i++){
+ assert( memIsValid(&pMem[i]) );
+ Deephemeralize(&pMem[i]);
+ assert( (pMem[i].flags & MEM_Ephem)==0
+ || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
+ sqlite3VdbeMemNulTerminate(&pMem[i]);
+ REGISTER_TRACE(pOp->p1+i, &pMem[i]);
}
if( db->mallocFailed ) goto no_mem;
@@ -67815,9 +68369,7 @@ case OP_ResultRow: {
** to avoid a memcpy().
*/
case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
-#if 0 /* local variables moved into u.ah */
i64 nByte;
-#endif /* local variables moved into u.ah */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
@@ -67830,22 +68382,22 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */
if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem;
Stringify(pIn1, encoding);
Stringify(pIn2, encoding);
- u.ah.nByte = pIn1->n + pIn2->n;
- if( u.ah.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ nByte = pIn1->n + pIn2->n;
+ if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- MemSetTypeFlag(pOut, MEM_Str);
- if( sqlite3VdbeMemGrow(pOut, (int)u.ah.nByte+2, pOut==pIn2) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
goto no_mem;
}
+ MemSetTypeFlag(pOut, MEM_Str);
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
}
memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n);
- pOut->z[u.ah.nByte]=0;
- pOut->z[u.ah.nByte+1] = 0;
+ pOut->z[nByte]=0;
+ pOut->z[nByte+1] = 0;
pOut->flags |= MEM_Term;
- pOut->n = (int)u.ah.nByte;
+ pOut->n = (int)nByte;
pOut->enc = encoding;
UPDATE_MAX_BLOBSIZE(pOut);
break;
@@ -67894,79 +68446,77 @@ case OP_Subtract: /* same as TK_MINUS, in1, in2, out3 */
case OP_Multiply: /* same as TK_STAR, in1, in2, out3 */
case OP_Divide: /* same as TK_SLASH, in1, in2, out3 */
case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
-#if 0 /* local variables moved into u.ai */
char bIntint; /* Started out as two integer operands */
int flags; /* Combined MEM_* flags from both inputs */
i64 iA; /* Integer value of left operand */
i64 iB; /* Integer value of right operand */
double rA; /* Real value of left operand */
double rB; /* Real value of right operand */
-#endif /* local variables moved into u.ai */
pIn1 = &aMem[pOp->p1];
applyNumericAffinity(pIn1);
pIn2 = &aMem[pOp->p2];
applyNumericAffinity(pIn2);
pOut = &aMem[pOp->p3];
- u.ai.flags = pIn1->flags | pIn2->flags;
- if( (u.ai.flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
+ flags = pIn1->flags | pIn2->flags;
+ if( (flags & MEM_Null)!=0 ) goto arithmetic_result_is_null;
if( (pIn1->flags & pIn2->flags & MEM_Int)==MEM_Int ){
- u.ai.iA = pIn1->u.i;
- u.ai.iB = pIn2->u.i;
- u.ai.bIntint = 1;
+ iA = pIn1->u.i;
+ iB = pIn2->u.i;
+ bIntint = 1;
switch( pOp->opcode ){
- case OP_Add: if( sqlite3AddInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
- case OP_Subtract: if( sqlite3SubInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
- case OP_Multiply: if( sqlite3MulInt64(&u.ai.iB,u.ai.iA) ) goto fp_math; break;
+ case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break;
+ case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break;
+ case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break;
case OP_Divide: {
- if( u.ai.iA==0 ) goto arithmetic_result_is_null;
- if( u.ai.iA==-1 && u.ai.iB==SMALLEST_INT64 ) goto fp_math;
- u.ai.iB /= u.ai.iA;
+ if( iA==0 ) goto arithmetic_result_is_null;
+ if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
+ iB /= iA;
break;
}
default: {
- if( u.ai.iA==0 ) goto arithmetic_result_is_null;
- if( u.ai.iA==-1 ) u.ai.iA = 1;
- u.ai.iB %= u.ai.iA;
+ if( iA==0 ) goto arithmetic_result_is_null;
+ if( iA==-1 ) iA = 1;
+ iB %= iA;
break;
}
}
- pOut->u.i = u.ai.iB;
+ pOut->u.i = iB;
MemSetTypeFlag(pOut, MEM_Int);
}else{
- u.ai.bIntint = 0;
+ bIntint = 0;
fp_math:
- u.ai.rA = sqlite3VdbeRealValue(pIn1);
- u.ai.rB = sqlite3VdbeRealValue(pIn2);
+ rA = sqlite3VdbeRealValue(pIn1);
+ rB = sqlite3VdbeRealValue(pIn2);
switch( pOp->opcode ){
- case OP_Add: u.ai.rB += u.ai.rA; break;
- case OP_Subtract: u.ai.rB -= u.ai.rA; break;
- case OP_Multiply: u.ai.rB *= u.ai.rA; break;
+ case OP_Add: rB += rA; break;
+ case OP_Subtract: rB -= rA; break;
+ case OP_Multiply: rB *= rA; break;
case OP_Divide: {
/* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */
- if( u.ai.rA==(double)0 ) goto arithmetic_result_is_null;
- u.ai.rB /= u.ai.rA;
+ if( rA==(double)0 ) goto arithmetic_result_is_null;
+ rB /= rA;
break;
}
default: {
- u.ai.iA = (i64)u.ai.rA;
- u.ai.iB = (i64)u.ai.rB;
- if( u.ai.iA==0 ) goto arithmetic_result_is_null;
- if( u.ai.iA==-1 ) u.ai.iA = 1;
- u.ai.rB = (double)(u.ai.iB % u.ai.iA);
+ iA = (i64)rA;
+ iB = (i64)rB;
+ if( iA==0 ) goto arithmetic_result_is_null;
+ if( iA==-1 ) iA = 1;
+ rB = (double)(iB % iA);
break;
}
}
#ifdef SQLITE_OMIT_FLOATING_POINT
- pOut->u.i = u.ai.rB;
+ pOut->u.i = rB;
MemSetTypeFlag(pOut, MEM_Int);
#else
- if( sqlite3IsNaN(u.ai.rB) ){
+ if( sqlite3IsNaN(rB) ){
goto arithmetic_result_is_null;
}
- pOut->r = u.ai.rB;
+ pOut->r = rB;
MemSetTypeFlag(pOut, MEM_Real);
- if( (u.ai.flags & MEM_Real)==0 && !u.ai.bIntint ){
+ if( (flags & MEM_Real)==0 && !bIntint ){
sqlite3VdbeIntegerAffinity(pOut);
}
#endif
@@ -68019,56 +68569,53 @@ case OP_CollSeq: {
** See also: AggStep and AggFinal
*/
case OP_Function: {
-#if 0 /* local variables moved into u.aj */
int i;
Mem *pArg;
sqlite3_context ctx;
sqlite3_value **apVal;
int n;
-#endif /* local variables moved into u.aj */
- u.aj.n = pOp->p5;
- u.aj.apVal = p->apArg;
- assert( u.aj.apVal || u.aj.n==0 );
+ n = pOp->p5;
+ apVal = p->apArg;
+ assert( apVal || n==0 );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
pOut = &aMem[pOp->p3];
memAboutToChange(p, pOut);
- assert( u.aj.n==0 || (pOp->p2>0 && pOp->p2+u.aj.n<=(p->nMem-p->nCursor)+1) );
- assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.aj.n );
- u.aj.pArg = &aMem[pOp->p2];
- for(u.aj.i=0; u.aj.i<u.aj.n; u.aj.i++, u.aj.pArg++){
- assert( memIsValid(u.aj.pArg) );
- u.aj.apVal[u.aj.i] = u.aj.pArg;
- Deephemeralize(u.aj.pArg);
- sqlite3VdbeMemStoreType(u.aj.pArg);
- REGISTER_TRACE(pOp->p2+u.aj.i, u.aj.pArg);
+ assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
+ assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
+ pArg = &aMem[pOp->p2];
+ for(i=0; i<n; i++, pArg++){
+ assert( memIsValid(pArg) );
+ apVal[i] = pArg;
+ Deephemeralize(pArg);
+ REGISTER_TRACE(pOp->p2+i, pArg);
}
assert( pOp->p4type==P4_FUNCDEF );
- u.aj.ctx.pFunc = pOp->p4.pFunc;
- u.aj.ctx.iOp = pc;
- u.aj.ctx.pVdbe = p;
+ ctx.pFunc = pOp->p4.pFunc;
+ ctx.iOp = pc;
+ ctx.pVdbe = p;
/* The output cell may already have a buffer allocated. Move
- ** the pointer to u.aj.ctx.s so in case the user-function can use
+ ** the pointer to ctx.s so in case the user-function can use
** the already allocated buffer instead of allocating a new one.
*/
- memcpy(&u.aj.ctx.s, pOut, sizeof(Mem));
+ memcpy(&ctx.s, pOut, sizeof(Mem));
pOut->flags = MEM_Null;
pOut->xDel = 0;
pOut->zMalloc = 0;
- MemSetTypeFlag(&u.aj.ctx.s, MEM_Null);
+ MemSetTypeFlag(&ctx.s, MEM_Null);
- u.aj.ctx.fErrorOrAux = 0;
- if( u.aj.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+ ctx.fErrorOrAux = 0;
+ if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- u.aj.ctx.pColl = pOp[-1].p4.pColl;
+ ctx.pColl = pOp[-1].p4.pColl;
}
db->lastRowid = lastRowid;
- (*u.aj.ctx.pFunc->xFunc)(&u.aj.ctx, u.aj.n, u.aj.apVal); /* IMP: R-24505-23230 */
+ (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
lastRowid = db->lastRowid;
if( db->mallocFailed ){
@@ -68077,23 +68624,23 @@ case OP_Function: {
** to return a value. The following call releases any resources
** associated with such a value.
*/
- sqlite3VdbeMemRelease(&u.aj.ctx.s);
+ sqlite3VdbeMemRelease(&ctx.s);
goto no_mem;
}
/* If the function returned an error, throw an exception */
- if( u.aj.ctx.fErrorOrAux ){
- if( u.aj.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.aj.ctx.s));
- rc = u.aj.ctx.isError;
+ if( ctx.fErrorOrAux ){
+ if( ctx.isError ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
+ rc = ctx.isError;
}
sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
}
/* Copy the result of the function into register P3 */
- sqlite3VdbeChangeEncoding(&u.aj.ctx.s, encoding);
+ sqlite3VdbeChangeEncoding(&ctx.s, encoding);
assert( pOut->flags==MEM_Null );
- memcpy(pOut, &u.aj.ctx.s, sizeof(Mem));
+ memcpy(pOut, &ctx.s, sizeof(Mem));
if( sqlite3VdbeMemTooBig(pOut) ){
goto too_big;
}
@@ -68145,12 +68692,10 @@ case OP_BitAnd: /* same as TK_BITAND, in1, in2, out3 */
case OP_BitOr: /* same as TK_BITOR, in1, in2, out3 */
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
-#if 0 /* local variables moved into u.ak */
i64 iA;
u64 uA;
i64 iB;
u8 op;
-#endif /* local variables moved into u.ak */
pIn1 = &aMem[pOp->p1];
pIn2 = &aMem[pOp->p2];
@@ -68159,38 +68704,38 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
sqlite3VdbeMemSetNull(pOut);
break;
}
- u.ak.iA = sqlite3VdbeIntValue(pIn2);
- u.ak.iB = sqlite3VdbeIntValue(pIn1);
- u.ak.op = pOp->opcode;
- if( u.ak.op==OP_BitAnd ){
- u.ak.iA &= u.ak.iB;
- }else if( u.ak.op==OP_BitOr ){
- u.ak.iA |= u.ak.iB;
- }else if( u.ak.iB!=0 ){
- assert( u.ak.op==OP_ShiftRight || u.ak.op==OP_ShiftLeft );
+ iA = sqlite3VdbeIntValue(pIn2);
+ iB = sqlite3VdbeIntValue(pIn1);
+ op = pOp->opcode;
+ if( op==OP_BitAnd ){
+ iA &= iB;
+ }else if( op==OP_BitOr ){
+ iA |= iB;
+ }else if( iB!=0 ){
+ assert( op==OP_ShiftRight || op==OP_ShiftLeft );
/* If shifting by a negative amount, shift in the other direction */
- if( u.ak.iB<0 ){
+ if( iB<0 ){
assert( OP_ShiftRight==OP_ShiftLeft+1 );
- u.ak.op = 2*OP_ShiftLeft + 1 - u.ak.op;
- u.ak.iB = u.ak.iB>(-64) ? -u.ak.iB : 64;
+ op = 2*OP_ShiftLeft + 1 - op;
+ iB = iB>(-64) ? -iB : 64;
}
- if( u.ak.iB>=64 ){
- u.ak.iA = (u.ak.iA>=0 || u.ak.op==OP_ShiftLeft) ? 0 : -1;
+ if( iB>=64 ){
+ iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1;
}else{
- memcpy(&u.ak.uA, &u.ak.iA, sizeof(u.ak.uA));
- if( u.ak.op==OP_ShiftLeft ){
- u.ak.uA <<= u.ak.iB;
+ memcpy(&uA, &iA, sizeof(uA));
+ if( op==OP_ShiftLeft ){
+ uA <<= iB;
}else{
- u.ak.uA >>= u.ak.iB;
+ uA >>= iB;
/* Sign-extend on a right shift of a negative number */
- if( u.ak.iA<0 ) u.ak.uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-u.ak.iB);
+ if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB);
}
- memcpy(&u.ak.iA, &u.ak.uA, sizeof(u.ak.iA));
+ memcpy(&iA, &uA, sizeof(iA));
}
}
- pOut->u.i = u.ak.iA;
+ pOut->u.i = iA;
MemSetTypeFlag(pOut, MEM_Int);
break;
}
@@ -68222,6 +68767,7 @@ case OP_MustBeInt: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
if( (pIn1->flags & MEM_Int)==0 ){
applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
+ VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
if( (pIn1->flags & MEM_Int)==0 ){
if( pOp->p2==0 ){
rc = SQLITE_MISMATCH;
@@ -68260,7 +68806,7 @@ case OP_RealAffinity: { /* in1 */
**
** Force the value in register P1 to be text.
** If the value is numeric, convert it to a string using the
-** equivalent of printf(). Blob values are unchanged and
+** equivalent of sprintf(). Blob values are unchanged and
** are afterwards simply interpreted as text.
**
** A NULL value is not changed by this routine. It remains NULL.
@@ -68444,18 +68990,16 @@ case OP_Lt: /* same as TK_LT, jump, in1, in3 */
case OP_Le: /* same as TK_LE, jump, in1, in3 */
case OP_Gt: /* same as TK_GT, jump, in1, in3 */
case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
-#if 0 /* local variables moved into u.al */
int res; /* Result of the comparison of pIn1 against pIn3 */
char affinity; /* Affinity to use for comparison */
u16 flags1; /* Copy of initial value of pIn1->flags */
u16 flags3; /* Copy of initial value of pIn3->flags */
-#endif /* local variables moved into u.al */
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
- u.al.flags1 = pIn1->flags;
- u.al.flags3 = pIn3->flags;
- if( (u.al.flags1 | u.al.flags3)&MEM_Null ){
+ flags1 = pIn1->flags;
+ flags3 = pIn3->flags;
+ if( (flags1 | flags3)&MEM_Null ){
/* One or both operands are NULL */
if( pOp->p5 & SQLITE_NULLEQ ){
/* If SQLITE_NULLEQ is set (which will only happen if the operator is
@@ -68463,65 +69007,71 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
** or not both operands are null.
*/
assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
- assert( (u.al.flags1 & MEM_Cleared)==0 );
- if( (u.al.flags1&MEM_Null)!=0
- && (u.al.flags3&MEM_Null)!=0
- && (u.al.flags3&MEM_Cleared)==0
+ assert( (flags1 & MEM_Cleared)==0 );
+ assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
+ if( (flags1&MEM_Null)!=0
+ && (flags3&MEM_Null)!=0
+ && (flags3&MEM_Cleared)==0
){
- u.al.res = 0; /* Results are equal */
+ res = 0; /* Results are equal */
}else{
- u.al.res = 1; /* Results are not equal */
+ res = 1; /* Results are not equal */
}
}else{
/* SQLITE_NULLEQ is clear and at least one operand is NULL,
** then the result is always NULL.
** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
*/
- if( pOp->p5 & SQLITE_JUMPIFNULL ){
- pc = pOp->p2-1;
- }else if( pOp->p5 & SQLITE_STOREP2 ){
+ if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
MemSetTypeFlag(pOut, MEM_Null);
REGISTER_TRACE(pOp->p2, pOut);
+ }else{
+ VdbeBranchTaken(2,3);
+ if( pOp->p5 & SQLITE_JUMPIFNULL ){
+ pc = pOp->p2-1;
+ }
}
break;
}
}else{
/* Neither operand is NULL. Do a comparison. */
- u.al.affinity = pOp->p5 & SQLITE_AFF_MASK;
- if( u.al.affinity ){
- applyAffinity(pIn1, u.al.affinity, encoding);
- applyAffinity(pIn3, u.al.affinity, encoding);
+ affinity = pOp->p5 & SQLITE_AFF_MASK;
+ if( affinity ){
+ applyAffinity(pIn1, affinity, encoding);
+ applyAffinity(pIn3, affinity, encoding);
if( db->mallocFailed ) goto no_mem;
}
assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
ExpandBlob(pIn1);
ExpandBlob(pIn3);
- u.al.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
+ res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
}
switch( pOp->opcode ){
- case OP_Eq: u.al.res = u.al.res==0; break;
- case OP_Ne: u.al.res = u.al.res!=0; break;
- case OP_Lt: u.al.res = u.al.res<0; break;
- case OP_Le: u.al.res = u.al.res<=0; break;
- case OP_Gt: u.al.res = u.al.res>0; break;
- default: u.al.res = u.al.res>=0; break;
+ case OP_Eq: res = res==0; break;
+ case OP_Ne: res = res!=0; break;
+ case OP_Lt: res = res<0; break;
+ case OP_Le: res = res<=0; break;
+ case OP_Gt: res = res>0; break;
+ default: res = res>=0; break;
}
if( pOp->p5 & SQLITE_STOREP2 ){
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
MemSetTypeFlag(pOut, MEM_Int);
- pOut->u.i = u.al.res;
+ pOut->u.i = res;
REGISTER_TRACE(pOp->p2, pOut);
- }else if( u.al.res ){
- pc = pOp->p2-1;
+ }else{
+ VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
+ if( res ){
+ pc = pOp->p2-1;
+ }
}
-
/* Undo any changes made by applyAffinity() to the input registers. */
- pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (u.al.flags1&MEM_TypeMask);
- pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (u.al.flags3&MEM_TypeMask);
+ pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
+ pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
break;
}
@@ -68561,7 +69111,6 @@ case OP_Permutation: {
** and strings are less than blobs.
*/
case OP_Compare: {
-#if 0 /* local variables moved into u.am */
int n;
int i;
int p1;
@@ -68570,38 +69119,37 @@ case OP_Compare: {
int idx;
CollSeq *pColl; /* Collating sequence to use on this term */
int bRev; /* True for DESCENDING sort order */
-#endif /* local variables moved into u.am */
if( (pOp->p5 & OPFLAG_PERMUTE)==0 ) aPermute = 0;
- u.am.n = pOp->p3;
- u.am.pKeyInfo = pOp->p4.pKeyInfo;
- assert( u.am.n>0 );
- assert( u.am.pKeyInfo!=0 );
- u.am.p1 = pOp->p1;
- u.am.p2 = pOp->p2;
+ n = pOp->p3;
+ pKeyInfo = pOp->p4.pKeyInfo;
+ assert( n>0 );
+ assert( pKeyInfo!=0 );
+ p1 = pOp->p1;
+ p2 = pOp->p2;
#if SQLITE_DEBUG
if( aPermute ){
int k, mx = 0;
- for(k=0; k<u.am.n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
- assert( u.am.p1>0 && u.am.p1+mx<=(p->nMem-p->nCursor)+1 );
- assert( u.am.p2>0 && u.am.p2+mx<=(p->nMem-p->nCursor)+1 );
+ for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k];
+ assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 );
+ assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 );
}else{
- assert( u.am.p1>0 && u.am.p1+u.am.n<=(p->nMem-p->nCursor)+1 );
- assert( u.am.p2>0 && u.am.p2+u.am.n<=(p->nMem-p->nCursor)+1 );
+ assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 );
+ assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 );
}
#endif /* SQLITE_DEBUG */
- for(u.am.i=0; u.am.i<u.am.n; u.am.i++){
- u.am.idx = aPermute ? aPermute[u.am.i] : u.am.i;
- assert( memIsValid(&aMem[u.am.p1+u.am.idx]) );
- assert( memIsValid(&aMem[u.am.p2+u.am.idx]) );
- REGISTER_TRACE(u.am.p1+u.am.idx, &aMem[u.am.p1+u.am.idx]);
- REGISTER_TRACE(u.am.p2+u.am.idx, &aMem[u.am.p2+u.am.idx]);
- assert( u.am.i<u.am.pKeyInfo->nField );
- u.am.pColl = u.am.pKeyInfo->aColl[u.am.i];
- u.am.bRev = u.am.pKeyInfo->aSortOrder[u.am.i];
- iCompare = sqlite3MemCompare(&aMem[u.am.p1+u.am.idx], &aMem[u.am.p2+u.am.idx], u.am.pColl);
+ for(i=0; i<n; i++){
+ idx = aPermute ? aPermute[i] : i;
+ assert( memIsValid(&aMem[p1+idx]) );
+ assert( memIsValid(&aMem[p2+idx]) );
+ REGISTER_TRACE(p1+idx, &aMem[p1+idx]);
+ REGISTER_TRACE(p2+idx, &aMem[p2+idx]);
+ assert( i<pKeyInfo->nField );
+ pColl = pKeyInfo->aColl[i];
+ bRev = pKeyInfo->aSortOrder[i];
+ iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl);
if( iCompare ){
- if( u.am.bRev ) iCompare = -iCompare;
+ if( bRev ) iCompare = -iCompare;
break;
}
}
@@ -68617,11 +69165,11 @@ case OP_Compare: {
*/
case OP_Jump: { /* jump */
if( iCompare<0 ){
- pc = pOp->p1 - 1;
+ pc = pOp->p1 - 1; VdbeBranchTaken(0,3);
}else if( iCompare==0 ){
- pc = pOp->p2 - 1;
+ pc = pOp->p2 - 1; VdbeBranchTaken(1,3);
}else{
- pc = pOp->p3 - 1;
+ pc = pOp->p3 - 1; VdbeBranchTaken(2,3);
}
break;
}
@@ -68648,35 +69196,33 @@ case OP_Jump: { /* jump */
*/
case OP_And: /* same as TK_AND, in1, in2, out3 */
case OP_Or: { /* same as TK_OR, in1, in2, out3 */
-#if 0 /* local variables moved into u.an */
int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */
-#endif /* local variables moved into u.an */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
- u.an.v1 = 2;
+ v1 = 2;
}else{
- u.an.v1 = sqlite3VdbeIntValue(pIn1)!=0;
+ v1 = sqlite3VdbeIntValue(pIn1)!=0;
}
pIn2 = &aMem[pOp->p2];
if( pIn2->flags & MEM_Null ){
- u.an.v2 = 2;
+ v2 = 2;
}else{
- u.an.v2 = sqlite3VdbeIntValue(pIn2)!=0;
+ v2 = sqlite3VdbeIntValue(pIn2)!=0;
}
if( pOp->opcode==OP_And ){
static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
- u.an.v1 = and_logic[u.an.v1*3+u.an.v2];
+ v1 = and_logic[v1*3+v2];
}else{
static const unsigned char or_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
- u.an.v1 = or_logic[u.an.v1*3+u.an.v2];
+ v1 = or_logic[v1*3+v2];
}
pOut = &aMem[pOp->p3];
- if( u.an.v1==2 ){
+ if( v1==2 ){
MemSetTypeFlag(pOut, MEM_Null);
}else{
- pOut->u.i = u.an.v1;
+ pOut->u.i = v1;
MemSetTypeFlag(pOut, MEM_Int);
}
break;
@@ -68721,10 +69267,13 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */
/* Opcode: Once P1 P2 * * *
**
** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise,
-** set the flag and fall through to the next instruction.
+** set the flag and fall through to the next instruction. In other words,
+** this opcode causes all following opcodes up through P2 (but not including
+** P2) to run just once and to be skipped on subsequent times through the loop.
*/
case OP_Once: { /* jump */
assert( pOp->p1<p->nOnceFlag );
+ VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
if( p->aOnceFlag[pOp->p1] ){
pc = pOp->p2-1;
}else{
@@ -68747,21 +69296,20 @@ case OP_Once: { /* jump */
*/
case OP_If: /* jump, in1 */
case OP_IfNot: { /* jump, in1 */
-#if 0 /* local variables moved into u.ao */
int c;
-#endif /* local variables moved into u.ao */
pIn1 = &aMem[pOp->p1];
if( pIn1->flags & MEM_Null ){
- u.ao.c = pOp->p3;
+ c = pOp->p3;
}else{
#ifdef SQLITE_OMIT_FLOATING_POINT
- u.ao.c = sqlite3VdbeIntValue(pIn1)!=0;
+ c = sqlite3VdbeIntValue(pIn1)!=0;
#else
- u.ao.c = sqlite3VdbeRealValue(pIn1)!=0.0;
+ c = sqlite3VdbeRealValue(pIn1)!=0.0;
#endif
- if( pOp->opcode==OP_IfNot ) u.ao.c = !u.ao.c;
+ if( pOp->opcode==OP_IfNot ) c = !c;
}
- if( u.ao.c ){
+ VdbeBranchTaken(c!=0, 2);
+ if( c ){
pc = pOp->p2-1;
}
break;
@@ -68774,6 +69322,7 @@ case OP_IfNot: { /* jump, in1 */
*/
case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
+ VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
if( (pIn1->flags & MEM_Null)!=0 ){
pc = pOp->p2 - 1;
}
@@ -68787,6 +69336,7 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */
*/
case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
pIn1 = &aMem[pOp->p1];
+ VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
if( (pIn1->flags & MEM_Null)==0 ){
pc = pOp->p2 - 1;
}
@@ -68819,7 +69369,6 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */
** skipped for length() and all content loading can be skipped for typeof().
*/
case OP_Column: {
-#if 0 /* local variables moved into u.ap */
i64 payloadSize64; /* Number of bytes in the record */
int p2; /* column number to retrieve */
VdbeCursor *pC; /* The VDBE cursor */
@@ -68838,85 +69387,79 @@ case OP_Column: {
u32 avail; /* Number of bytes of available data */
u32 t; /* A type code from the record header */
Mem *pReg; /* PseudoTable input register */
-#endif /* local variables moved into u.ap */
- u.ap.p2 = pOp->p2;
+ p2 = pOp->p2;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- u.ap.pDest = &aMem[pOp->p3];
- memAboutToChange(p, u.ap.pDest);
+ pDest = &aMem[pOp->p3];
+ memAboutToChange(p, pDest);
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.ap.pC = p->apCsr[pOp->p1];
- assert( u.ap.pC!=0 );
- assert( u.ap.p2<u.ap.pC->nField );
- u.ap.aType = u.ap.pC->aType;
- u.ap.aOffset = u.ap.aType + u.ap.pC->nField;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( p2<pC->nField );
+ aType = pC->aType;
+ aOffset = aType + pC->nField;
#ifndef SQLITE_OMIT_VIRTUALTABLE
- assert( u.ap.pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
+ assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
#endif
- u.ap.pCrsr = u.ap.pC->pCursor;
- assert( u.ap.pCrsr!=0 || u.ap.pC->pseudoTableReg>0 ); /* u.ap.pCrsr NULL on PseudoTables */
- assert( u.ap.pCrsr!=0 || u.ap.pC->nullRow ); /* u.ap.pC->nullRow on PseudoTables */
+ pCrsr = pC->pCursor;
+ assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */
+ assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */
/* If the cursor cache is stale, bring it up-to-date */
- rc = sqlite3VdbeCursorMoveto(u.ap.pC);
+ rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
- if( u.ap.pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
- if( u.ap.pC->nullRow ){
- if( u.ap.pCrsr==0 ){
- assert( u.ap.pC->pseudoTableReg>0 );
- u.ap.pReg = &aMem[u.ap.pC->pseudoTableReg];
- if( u.ap.pC->multiPseudo ){
- sqlite3VdbeMemShallowCopy(u.ap.pDest, u.ap.pReg+u.ap.p2, MEM_Ephem);
- Deephemeralize(u.ap.pDest);
- goto op_column_out;
- }
- assert( u.ap.pReg->flags & MEM_Blob );
- assert( memIsValid(u.ap.pReg) );
- u.ap.pC->payloadSize = u.ap.pC->szRow = u.ap.avail = u.ap.pReg->n;
- u.ap.pC->aRow = (u8*)u.ap.pReg->z;
+ if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
+ if( pC->nullRow ){
+ if( pCrsr==0 ){
+ assert( pC->pseudoTableReg>0 );
+ pReg = &aMem[pC->pseudoTableReg];
+ assert( pReg->flags & MEM_Blob );
+ assert( memIsValid(pReg) );
+ pC->payloadSize = pC->szRow = avail = pReg->n;
+ pC->aRow = (u8*)pReg->z;
}else{
- MemSetTypeFlag(u.ap.pDest, MEM_Null);
+ MemSetTypeFlag(pDest, MEM_Null);
goto op_column_out;
}
}else{
- assert( u.ap.pCrsr );
- if( u.ap.pC->isTable==0 ){
- assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(u.ap.pCrsr, &u.ap.payloadSize64);
+ assert( pCrsr );
+ if( pC->isTable==0 ){
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
/* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
- ** payload size, so it is impossible for u.ap.payloadSize64 to be
+ ** payload size, so it is impossible for payloadSize64 to be
** larger than 32 bits. */
- assert( (u.ap.payloadSize64 & SQLITE_MAX_U32)==(u64)u.ap.payloadSize64 );
- u.ap.pC->aRow = sqlite3BtreeKeyFetch(u.ap.pCrsr, &u.ap.avail);
- u.ap.pC->payloadSize = (u32)u.ap.payloadSize64;
+ assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 );
+ pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail);
+ pC->payloadSize = (u32)payloadSize64;
}else{
- assert( sqlite3BtreeCursorIsValid(u.ap.pCrsr) );
- VVA_ONLY(rc =) sqlite3BtreeDataSize(u.ap.pCrsr, &u.ap.pC->payloadSize);
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize);
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- u.ap.pC->aRow = sqlite3BtreeDataFetch(u.ap.pCrsr, &u.ap.avail);
+ pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail);
}
- assert( u.ap.avail<=65536 ); /* Maximum page size is 64KiB */
- if( u.ap.pC->payloadSize <= (u32)u.ap.avail ){
- u.ap.pC->szRow = u.ap.pC->payloadSize;
+ assert( avail<=65536 ); /* Maximum page size is 64KiB */
+ if( pC->payloadSize <= (u32)avail ){
+ pC->szRow = pC->payloadSize;
}else{
- u.ap.pC->szRow = u.ap.avail;
+ pC->szRow = avail;
}
- if( u.ap.pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
}
- u.ap.pC->cacheStatus = p->cacheCtr;
- u.ap.pC->iHdrOffset = getVarint32(u.ap.pC->aRow, u.ap.offset);
- u.ap.pC->nHdrParsed = 0;
- u.ap.aOffset[0] = u.ap.offset;
- if( u.ap.avail<u.ap.offset ){
- /* u.ap.pC->aRow does not have to hold the entire row, but it does at least
- ** need to cover the header of the record. If u.ap.pC->aRow does not contain
+ pC->cacheStatus = p->cacheCtr;
+ pC->iHdrOffset = getVarint32(pC->aRow, offset);
+ pC->nHdrParsed = 0;
+ aOffset[0] = offset;
+ if( avail<offset ){
+ /* pC->aRow does not have to hold the entire row, but it does at least
+ ** need to cover the header of the record. If pC->aRow does not contain
** the complete header, then set it to zero, forcing the header to be
** dynamically allocated. */
- u.ap.pC->aRow = 0;
- u.ap.pC->szRow = 0;
+ pC->aRow = 0;
+ pC->szRow = 0;
}
/* Make sure a corrupt database has not given us an oversize header.
@@ -68928,72 +69471,72 @@ case OP_Column: {
** 3-byte type for each of the maximum of 32768 columns plus three
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
*/
- if( u.ap.offset > 98307 || u.ap.offset > u.ap.pC->payloadSize ){
+ if( offset > 98307 || offset > pC->payloadSize ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
}
}
- /* Make sure at least the first u.ap.p2+1 entries of the header have been
- ** parsed and valid information is in u.ap.aOffset[] and u.ap.aType[].
+ /* Make sure at least the first p2+1 entries of the header have been
+ ** parsed and valid information is in aOffset[] and aType[].
*/
- if( u.ap.pC->nHdrParsed<=u.ap.p2 ){
+ if( pC->nHdrParsed<=p2 ){
/* If there is more header available for parsing in the record, try
- ** to extract additional fields up through the u.ap.p2+1-th field
+ ** to extract additional fields up through the p2+1-th field
*/
- if( u.ap.pC->iHdrOffset<u.ap.aOffset[0] ){
- /* Make sure u.ap.zData points to enough of the record to cover the header. */
- if( u.ap.pC->aRow==0 ){
- memset(&u.ap.sMem, 0, sizeof(u.ap.sMem));
- rc = sqlite3VdbeMemFromBtree(u.ap.pCrsr, 0, u.ap.aOffset[0],
- !u.ap.pC->isTable, &u.ap.sMem);
+ if( pC->iHdrOffset<aOffset[0] ){
+ /* Make sure zData points to enough of the record to cover the header. */
+ if( pC->aRow==0 ){
+ memset(&sMem, 0, sizeof(sMem));
+ rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0],
+ !pC->isTable, &sMem);
if( rc!=SQLITE_OK ){
goto op_column_error;
}
- u.ap.zData = (u8*)u.ap.sMem.z;
+ zData = (u8*)sMem.z;
}else{
- u.ap.zData = u.ap.pC->aRow;
+ zData = pC->aRow;
}
-
- /* Fill in u.ap.aType[u.ap.i] and u.ap.aOffset[u.ap.i] values through the u.ap.p2-th field. */
- u.ap.i = u.ap.pC->nHdrParsed;
- u.ap.offset = u.ap.aOffset[u.ap.i];
- u.ap.zHdr = u.ap.zData + u.ap.pC->iHdrOffset;
- u.ap.zEndHdr = u.ap.zData + u.ap.aOffset[0];
- assert( u.ap.i<=u.ap.p2 && u.ap.zHdr<u.ap.zEndHdr );
+
+ /* Fill in aType[i] and aOffset[i] values through the p2-th field. */
+ i = pC->nHdrParsed;
+ offset = aOffset[i];
+ zHdr = zData + pC->iHdrOffset;
+ zEndHdr = zData + aOffset[0];
+ assert( i<=p2 && zHdr<zEndHdr );
do{
- if( u.ap.zHdr[0]<0x80 ){
- u.ap.t = u.ap.zHdr[0];
- u.ap.zHdr++;
+ if( zHdr[0]<0x80 ){
+ t = zHdr[0];
+ zHdr++;
}else{
- u.ap.zHdr += sqlite3GetVarint32(u.ap.zHdr, &u.ap.t);
+ zHdr += sqlite3GetVarint32(zHdr, &t);
}
- u.ap.aType[u.ap.i] = u.ap.t;
- u.ap.szField = sqlite3VdbeSerialTypeLen(u.ap.t);
- u.ap.offset += u.ap.szField;
- if( u.ap.offset<u.ap.szField ){ /* True if u.ap.offset overflows */
- u.ap.zHdr = &u.ap.zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */
+ aType[i] = t;
+ szField = sqlite3VdbeSerialTypeLen(t);
+ offset += szField;
+ if( offset<szField ){ /* True if offset overflows */
+ zHdr = &zEndHdr[1]; /* Forces SQLITE_CORRUPT return below */
break;
}
- u.ap.i++;
- u.ap.aOffset[u.ap.i] = u.ap.offset;
- }while( u.ap.i<=u.ap.p2 && u.ap.zHdr<u.ap.zEndHdr );
- u.ap.pC->nHdrParsed = u.ap.i;
- u.ap.pC->iHdrOffset = (u32)(u.ap.zHdr - u.ap.zData);
- if( u.ap.pC->aRow==0 ){
- sqlite3VdbeMemRelease(&u.ap.sMem);
- u.ap.sMem.flags = MEM_Null;
+ i++;
+ aOffset[i] = offset;
+ }while( i<=p2 && zHdr<zEndHdr );
+ pC->nHdrParsed = i;
+ pC->iHdrOffset = (u32)(zHdr - zData);
+ if( pC->aRow==0 ){
+ sqlite3VdbeMemRelease(&sMem);
+ sMem.flags = MEM_Null;
}
-
+
/* If we have read more header data than was contained in the header,
** or if the end of the last field appears to be past the end of the
** record, or if the end of the last field appears to be before the end
- ** of the record (when all fields present), then we must be dealing
+ ** of the record (when all fields present), then we must be dealing
** with a corrupt database.
*/
- if( (u.ap.zHdr > u.ap.zEndHdr)
- || (u.ap.offset > u.ap.pC->payloadSize)
- || (u.ap.zHdr==u.ap.zEndHdr && u.ap.offset!=u.ap.pC->payloadSize)
+ if( (zHdr > zEndHdr)
+ || (offset > pC->payloadSize)
+ || (zHdr==zEndHdr && offset!=pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
@@ -69001,77 +69544,78 @@ case OP_Column: {
}
/* If after trying to extra new entries from the header, nHdrParsed is
- ** still not up to u.ap.p2, that means that the record has fewer than u.ap.p2
+ ** still not up to p2, that means that the record has fewer than p2
** columns. So the result will be either the default value or a NULL.
*/
- if( u.ap.pC->nHdrParsed<=u.ap.p2 ){
+ if( pC->nHdrParsed<=p2 ){
if( pOp->p4type==P4_MEM ){
- sqlite3VdbeMemShallowCopy(u.ap.pDest, pOp->p4.pMem, MEM_Static);
+ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
}else{
- MemSetTypeFlag(u.ap.pDest, MEM_Null);
+ MemSetTypeFlag(pDest, MEM_Null);
}
goto op_column_out;
}
}
- /* Extract the content for the u.ap.p2+1-th column. Control can only
- ** reach this point if u.ap.aOffset[u.ap.p2], u.ap.aOffset[u.ap.p2+1], and u.ap.aType[u.ap.p2] are
+ /* Extract the content for the p2+1-th column. Control can only
+ ** reach this point if aOffset[p2], aOffset[p2+1], and aType[p2] are
** all valid.
*/
- assert( u.ap.p2<u.ap.pC->nHdrParsed );
+ assert( p2<pC->nHdrParsed );
assert( rc==SQLITE_OK );
- if( u.ap.pC->szRow>=u.ap.aOffset[u.ap.p2+1] ){
+ assert( sqlite3VdbeCheckMemInvariants(pDest) );
+ if( pC->szRow>=aOffset[p2+1] ){
/* This is the common case where the desired content fits on the original
** page - where the content is not on an overflow page */
- VdbeMemRelease(u.ap.pDest);
- sqlite3VdbeSerialGet(u.ap.pC->aRow+u.ap.aOffset[u.ap.p2], u.ap.aType[u.ap.p2], u.ap.pDest);
+ VdbeMemRelease(pDest);
+ sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
}else{
/* This branch happens only when content is on overflow pages */
- u.ap.t = u.ap.aType[u.ap.p2];
+ t = aType[p2];
if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
- && ((u.ap.t>=12 && (u.ap.t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
- || (u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.t))==0
+ && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
+ || (len = sqlite3VdbeSerialTypeLen(t))==0
){
/* Content is irrelevant for the typeof() function and for
** the length(X) function if X is a blob. So we might as well use
** bogus content rather than reading content from disk. NULL works
- ** for text and blob and whatever is in the u.ap.payloadSize64 variable
+ ** for text and blob and whatever is in the payloadSize64 variable
** will work for everything else. Content is also irrelevant if
** the content length is 0. */
- u.ap.zData = u.ap.t<=13 ? (u8*)&u.ap.payloadSize64 : 0;
- u.ap.sMem.zMalloc = 0;
+ zData = t<=13 ? (u8*)&payloadSize64 : 0;
+ sMem.zMalloc = 0;
}else{
- memset(&u.ap.sMem, 0, sizeof(u.ap.sMem));
- sqlite3VdbeMemMove(&u.ap.sMem, u.ap.pDest);
- rc = sqlite3VdbeMemFromBtree(u.ap.pCrsr, u.ap.aOffset[u.ap.p2], u.ap.len, !u.ap.pC->isTable,
- &u.ap.sMem);
+ memset(&sMem, 0, sizeof(sMem));
+ sqlite3VdbeMemMove(&sMem, pDest);
+ rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
+ &sMem);
if( rc!=SQLITE_OK ){
goto op_column_error;
}
- u.ap.zData = (u8*)u.ap.sMem.z;
+ zData = (u8*)sMem.z;
}
- sqlite3VdbeSerialGet(u.ap.zData, u.ap.t, u.ap.pDest);
+ sqlite3VdbeSerialGet(zData, t, pDest);
/* If we dynamically allocated space to hold the data (in the
** sqlite3VdbeMemFromBtree() call above) then transfer control of that
- ** dynamically allocated space over to the u.ap.pDest structure.
+ ** dynamically allocated space over to the pDest structure.
** This prevents a memory copy. */
- if( u.ap.sMem.zMalloc ){
- assert( u.ap.sMem.z==u.ap.sMem.zMalloc );
- assert( !(u.ap.pDest->flags & MEM_Dyn) );
- assert( !(u.ap.pDest->flags & (MEM_Blob|MEM_Str)) || u.ap.pDest->z==u.ap.sMem.z );
- u.ap.pDest->flags &= ~(MEM_Ephem|MEM_Static);
- u.ap.pDest->flags |= MEM_Term;
- u.ap.pDest->z = u.ap.sMem.z;
- u.ap.pDest->zMalloc = u.ap.sMem.zMalloc;
+ if( sMem.zMalloc ){
+ assert( sMem.z==sMem.zMalloc );
+ assert( VdbeMemDynamic(pDest)==0 );
+ assert( (pDest->flags & (MEM_Blob|MEM_Str))==0 || pDest->z==sMem.z );
+ pDest->flags &= ~(MEM_Ephem|MEM_Static);
+ pDest->flags |= MEM_Term;
+ pDest->z = sMem.z;
+ pDest->zMalloc = sMem.zMalloc;
}
}
- u.ap.pDest->enc = encoding;
+ pDest->enc = encoding;
op_column_out:
- rc = sqlite3VdbeMemMakeWriteable(u.ap.pDest);
+ Deephemeralize(pDest);
op_column_error:
- UPDATE_MAX_BLOBSIZE(u.ap.pDest);
- REGISTER_TRACE(pOp->p3, u.ap.pDest);
+ UPDATE_MAX_BLOBSIZE(pDest);
+ REGISTER_TRACE(pOp->p3, pDest);
break;
}
@@ -69085,20 +69629,17 @@ op_column_error:
** memory cell in the range.
*/
case OP_Affinity: {
-#if 0 /* local variables moved into u.aq */
const char *zAffinity; /* The affinity to be applied */
char cAff; /* A single character of affinity */
-#endif /* local variables moved into u.aq */
- u.aq.zAffinity = pOp->p4.z;
- assert( u.aq.zAffinity!=0 );
- assert( u.aq.zAffinity[pOp->p2]==0 );
+ zAffinity = pOp->p4.z;
+ assert( zAffinity!=0 );
+ assert( zAffinity[pOp->p2]==0 );
pIn1 = &aMem[pOp->p1];
- while( (u.aq.cAff = *(u.aq.zAffinity++))!=0 ){
+ while( (cAff = *(zAffinity++))!=0 ){
assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] );
assert( memIsValid(pIn1) );
- ExpandBlob(pIn1);
- applyAffinity(pIn1, u.aq.cAff, encoding);
+ applyAffinity(pIn1, cAff, encoding);
pIn1++;
}
break;
@@ -69121,7 +69662,6 @@ case OP_Affinity: {
** If P4 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
-#if 0 /* local variables moved into u.ar */
u8 *zNewRecord; /* A buffer to hold the data for the new record */
Mem *pRec; /* The new record */
u64 nData; /* Number of bytes of data space */
@@ -69135,102 +69675,120 @@ case OP_MakeRecord: {
int nField; /* Number of fields in the record */
char *zAffinity; /* The affinity string for the record */
int file_format; /* File format to use for encoding */
- int i; /* Space used in zNewRecord[] */
+ int i; /* Space used in zNewRecord[] header */
+ int j; /* Space used in zNewRecord[] content */
int len; /* Length of a field */
-#endif /* local variables moved into u.ar */
/* Assuming the record contains N fields, the record format looks
** like this:
**
** ------------------------------------------------------------------------
- ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
+ ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 |
** ------------------------------------------------------------------------
**
** Data(0) is taken from register P1. Data(1) comes from register P1+1
** and so froth.
**
- ** Each type field is a varint representing the serial type of the
+ ** Each type field is a varint representing the serial type of the
** corresponding data element (see sqlite3VdbeSerialType()). The
** hdr-size field is also a varint which is the offset from the beginning
** of the record to data0.
*/
- u.ar.nData = 0; /* Number of bytes of data space */
- u.ar.nHdr = 0; /* Number of bytes of header space */
- u.ar.nZero = 0; /* Number of zero bytes at the end of the record */
- u.ar.nField = pOp->p1;
- u.ar.zAffinity = pOp->p4.z;
- assert( u.ar.nField>0 && pOp->p2>0 && pOp->p2+u.ar.nField<=(p->nMem-p->nCursor)+1 );
- u.ar.pData0 = &aMem[u.ar.nField];
- u.ar.nField = pOp->p2;
- u.ar.pLast = &u.ar.pData0[u.ar.nField-1];
- u.ar.file_format = p->minWriteFileFormat;
+ nData = 0; /* Number of bytes of data space */
+ nHdr = 0; /* Number of bytes of header space */
+ nZero = 0; /* Number of zero bytes at the end of the record */
+ nField = pOp->p1;
+ zAffinity = pOp->p4.z;
+ assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 );
+ pData0 = &aMem[nField];
+ nField = pOp->p2;
+ pLast = &pData0[nField-1];
+ file_format = p->minWriteFileFormat;
/* Identify the output register */
assert( pOp->p3<pOp->p1 || pOp->p3>=pOp->p1+pOp->p2 );
pOut = &aMem[pOp->p3];
memAboutToChange(p, pOut);
+ /* Apply the requested affinity to all inputs
+ */
+ assert( pData0<=pLast );
+ if( zAffinity ){
+ pRec = pData0;
+ do{
+ applyAffinity(pRec++, *(zAffinity++), encoding);
+ assert( zAffinity[0]==0 || pRec<=pLast );
+ }while( zAffinity[0] );
+ }
+
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
*/
- for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){
- assert( memIsValid(u.ar.pRec) );
- if( u.ar.zAffinity ){
- applyAffinity(u.ar.pRec, u.ar.zAffinity[u.ar.pRec-u.ar.pData0], encoding);
- }
- if( u.ar.pRec->flags&MEM_Zero && u.ar.pRec->n>0 ){
- sqlite3VdbeMemExpandBlob(u.ar.pRec);
- }
- u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format);
- u.ar.len = sqlite3VdbeSerialTypeLen(u.ar.serial_type);
- u.ar.nData += u.ar.len;
- u.ar.nHdr += sqlite3VarintLen(u.ar.serial_type);
- if( u.ar.pRec->flags & MEM_Zero ){
- /* Only pure zero-filled BLOBs can be input to this Opcode.
- ** We do not allow blobs with a prefix and a zero-filled tail. */
- u.ar.nZero += u.ar.pRec->u.nZero;
- }else if( u.ar.len ){
- u.ar.nZero = 0;
+ pRec = pLast;
+ do{
+ assert( memIsValid(pRec) );
+ serial_type = sqlite3VdbeSerialType(pRec, file_format);
+ len = sqlite3VdbeSerialTypeLen(serial_type);
+ if( pRec->flags & MEM_Zero ){
+ if( nData ){
+ sqlite3VdbeMemExpandBlob(pRec);
+ }else{
+ nZero += pRec->u.nZero;
+ len -= pRec->u.nZero;
+ }
}
- }
+ nData += len;
+ testcase( serial_type==127 );
+ testcase( serial_type==128 );
+ nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
+ }while( (--pRec)>=pData0 );
/* Add the initial header varint and total the size */
- u.ar.nHdr += u.ar.nVarint = sqlite3VarintLen(u.ar.nHdr);
- if( u.ar.nVarint<sqlite3VarintLen(u.ar.nHdr) ){
- u.ar.nHdr++;
- }
- u.ar.nByte = u.ar.nHdr+u.ar.nData-u.ar.nZero;
- if( u.ar.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ testcase( nHdr==126 );
+ testcase( nHdr==127 );
+ if( nHdr<=126 ){
+ /* The common case */
+ nHdr += 1;
+ }else{
+ /* Rare case of a really large header */
+ nVarint = sqlite3VarintLen(nHdr);
+ nHdr += nVarint;
+ if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
+ }
+ nByte = nHdr+nData;
+ if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- /* Make sure the output register has a buffer large enough to store
+ /* Make sure the output register has a buffer large enough to store
** the new record. The output register (pOp->p3) is not allowed to
** be one of the input registers (because the following call to
** sqlite3VdbeMemGrow() could clobber the value before it is used).
*/
- if( sqlite3VdbeMemGrow(pOut, (int)u.ar.nByte, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){
goto no_mem;
}
- u.ar.zNewRecord = (u8 *)pOut->z;
+ zNewRecord = (u8 *)pOut->z;
/* Write the record */
- u.ar.i = putVarint32(u.ar.zNewRecord, u.ar.nHdr);
- for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){
- u.ar.serial_type = sqlite3VdbeSerialType(u.ar.pRec, u.ar.file_format);
- u.ar.i += putVarint32(&u.ar.zNewRecord[u.ar.i], u.ar.serial_type); /* serial type */
- }
- for(u.ar.pRec=u.ar.pData0; u.ar.pRec<=u.ar.pLast; u.ar.pRec++){ /* serial data */
- u.ar.i += sqlite3VdbeSerialPut(&u.ar.zNewRecord[u.ar.i], (int)(u.ar.nByte-u.ar.i), u.ar.pRec,u.ar.file_format);
- }
- assert( u.ar.i==u.ar.nByte );
+ i = putVarint32(zNewRecord, nHdr);
+ j = nHdr;
+ assert( pData0<=pLast );
+ pRec = pData0;
+ do{
+ serial_type = sqlite3VdbeSerialType(pRec, file_format);
+ i += putVarint32(&zNewRecord[i], serial_type); /* serial type */
+ j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
+ }while( (++pRec)<=pLast );
+ assert( i==nHdr );
+ assert( j==nByte );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- pOut->n = (int)u.ar.nByte;
- pOut->flags = MEM_Blob | MEM_Dyn;
+ pOut->n = (int)nByte;
+ pOut->flags = MEM_Blob;
pOut->xDel = 0;
- if( u.ar.nZero ){
- pOut->u.nZero = u.ar.nZero;
+ if( nZero ){
+ pOut->u.nZero = nZero;
pOut->flags |= MEM_Zero;
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */
@@ -69247,15 +69805,14 @@ case OP_MakeRecord: {
*/
#ifndef SQLITE_OMIT_BTREECOUNT
case OP_Count: { /* out2-prerelease */
-#if 0 /* local variables moved into u.as */
i64 nEntry;
BtCursor *pCrsr;
-#endif /* local variables moved into u.as */
- u.as.pCrsr = p->apCsr[pOp->p1]->pCursor;
- assert( u.as.pCrsr );
- rc = sqlite3BtreeCount(u.as.pCrsr, &u.as.nEntry);
- pOut->u.i = u.as.nEntry;
+ pCrsr = p->apCsr[pOp->p1]->pCursor;
+ assert( pCrsr );
+ nEntry = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3BtreeCount(pCrsr, &nEntry);
+ pOut->u.i = nEntry;
break;
}
#endif
@@ -69267,7 +69824,6 @@ case OP_Count: { /* out2-prerelease */
** existing savepoint, P1==1, or to rollback an existing savepoint P1==2.
*/
case OP_Savepoint: {
-#if 0 /* local variables moved into u.at */
int p1; /* Value of P1 operand */
char *zName; /* Name of savepoint */
int nName;
@@ -69276,30 +69832,29 @@ case OP_Savepoint: {
Savepoint *pTmp;
int iSavepoint;
int ii;
-#endif /* local variables moved into u.at */
- u.at.p1 = pOp->p1;
- u.at.zName = pOp->p4.z;
+ p1 = pOp->p1;
+ zName = pOp->p4.z;
- /* Assert that the u.at.p1 parameter is valid. Also that if there is no open
- ** transaction, then there cannot be any savepoints.
+ /* Assert that the p1 parameter is valid. Also that if there is no open
+ ** transaction, then there cannot be any savepoints.
*/
assert( db->pSavepoint==0 || db->autoCommit==0 );
- assert( u.at.p1==SAVEPOINT_BEGIN||u.at.p1==SAVEPOINT_RELEASE||u.at.p1==SAVEPOINT_ROLLBACK );
+ assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK );
assert( db->pSavepoint || db->isTransactionSavepoint==0 );
assert( checkSavepointCount(db) );
assert( p->bIsReader );
- if( u.at.p1==SAVEPOINT_BEGIN ){
+ if( p1==SAVEPOINT_BEGIN ){
if( db->nVdbeWrite>0 ){
- /* A new savepoint cannot be created if there are active write
+ /* A new savepoint cannot be created if there are active write
** statements (i.e. open read/write incremental blob handles).
*/
sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else{
- u.at.nName = sqlite3Strlen30(u.at.zName);
+ nName = sqlite3Strlen30(zName);
#ifndef SQLITE_OMIT_VIRTUALTABLE
/* This call is Ok even if this savepoint is actually a transaction
@@ -69313,11 +69868,11 @@ case OP_Savepoint: {
#endif
/* Create a new savepoint structure. */
- u.at.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.at.nName+1);
- if( u.at.pNew ){
- u.at.pNew->zName = (char *)&u.at.pNew[1];
- memcpy(u.at.pNew->zName, u.at.zName, u.at.nName+1);
-
+ pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1);
+ if( pNew ){
+ pNew->zName = (char *)&pNew[1];
+ memcpy(pNew->zName, zName, nName+1);
+
/* If there is no open transaction, then mark this as a special
** "transaction savepoint". */
if( db->autoCommit ){
@@ -69326,45 +69881,45 @@ case OP_Savepoint: {
}else{
db->nSavepoint++;
}
-
+
/* Link the new savepoint into the database handle's list. */
- u.at.pNew->pNext = db->pSavepoint;
- db->pSavepoint = u.at.pNew;
- u.at.pNew->nDeferredCons = db->nDeferredCons;
- u.at.pNew->nDeferredImmCons = db->nDeferredImmCons;
+ pNew->pNext = db->pSavepoint;
+ db->pSavepoint = pNew;
+ pNew->nDeferredCons = db->nDeferredCons;
+ pNew->nDeferredImmCons = db->nDeferredImmCons;
}
}
}else{
- u.at.iSavepoint = 0;
+ iSavepoint = 0;
/* Find the named savepoint. If there is no such savepoint, then an
** an error is returned to the user. */
for(
- u.at.pSavepoint = db->pSavepoint;
- u.at.pSavepoint && sqlite3StrICmp(u.at.pSavepoint->zName, u.at.zName);
- u.at.pSavepoint = u.at.pSavepoint->pNext
+ pSavepoint = db->pSavepoint;
+ pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName);
+ pSavepoint = pSavepoint->pNext
){
- u.at.iSavepoint++;
+ iSavepoint++;
}
- if( !u.at.pSavepoint ){
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.at.zName);
+ if( !pSavepoint ){
+ sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
rc = SQLITE_ERROR;
- }else if( db->nVdbeWrite>0 && u.at.p1==SAVEPOINT_RELEASE ){
- /* It is not possible to release (commit) a savepoint if there are
+ }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
+ /* It is not possible to release (commit) a savepoint if there are
** active write statements.
*/
- sqlite3SetString(&p->zErrMsg, db,
+ sqlite3SetString(&p->zErrMsg, db,
"cannot release savepoint - SQL statements in progress"
);
rc = SQLITE_BUSY;
}else{
/* Determine whether or not this is a transaction savepoint. If so,
- ** and this is a RELEASE command, then the current transaction
- ** is committed.
+ ** and this is a RELEASE command, then the current transaction
+ ** is committed.
*/
- int isTransaction = u.at.pSavepoint->pNext==0 && db->isTransactionSavepoint;
- if( isTransaction && u.at.p1==SAVEPOINT_RELEASE ){
+ int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint;
+ if( isTransaction && p1==SAVEPOINT_RELEASE ){
if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}
@@ -69378,52 +69933,52 @@ case OP_Savepoint: {
db->isTransactionSavepoint = 0;
rc = p->rc;
}else{
- u.at.iSavepoint = db->nSavepoint - u.at.iSavepoint - 1;
- if( u.at.p1==SAVEPOINT_ROLLBACK ){
- for(u.at.ii=0; u.at.ii<db->nDb; u.at.ii++){
- sqlite3BtreeTripAllCursors(db->aDb[u.at.ii].pBt, SQLITE_ABORT);
+ iSavepoint = db->nSavepoint - iSavepoint - 1;
+ if( p1==SAVEPOINT_ROLLBACK ){
+ for(ii=0; ii<db->nDb; ii++){
+ sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
}
}
- for(u.at.ii=0; u.at.ii<db->nDb; u.at.ii++){
- rc = sqlite3BtreeSavepoint(db->aDb[u.at.ii].pBt, u.at.p1, u.at.iSavepoint);
+ for(ii=0; ii<db->nDb; ii++){
+ rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
}
- if( u.at.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+ if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
sqlite3ExpirePreparedStatements(db);
sqlite3ResetAllSchemasOfConnection(db);
db->flags = (db->flags | SQLITE_InternChanges);
}
}
-
- /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
+
+ /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all
** savepoints nested inside of the savepoint being operated on. */
- while( db->pSavepoint!=u.at.pSavepoint ){
- u.at.pTmp = db->pSavepoint;
- db->pSavepoint = u.at.pTmp->pNext;
- sqlite3DbFree(db, u.at.pTmp);
+ while( db->pSavepoint!=pSavepoint ){
+ pTmp = db->pSavepoint;
+ db->pSavepoint = pTmp->pNext;
+ sqlite3DbFree(db, pTmp);
db->nSavepoint--;
}
- /* If it is a RELEASE, then destroy the savepoint being operated on
- ** too. If it is a ROLLBACK TO, then set the number of deferred
+ /* If it is a RELEASE, then destroy the savepoint being operated on
+ ** too. If it is a ROLLBACK TO, then set the number of deferred
** constraint violations present in the database to the value stored
** when the savepoint was created. */
- if( u.at.p1==SAVEPOINT_RELEASE ){
- assert( u.at.pSavepoint==db->pSavepoint );
- db->pSavepoint = u.at.pSavepoint->pNext;
- sqlite3DbFree(db, u.at.pSavepoint);
+ if( p1==SAVEPOINT_RELEASE ){
+ assert( pSavepoint==db->pSavepoint );
+ db->pSavepoint = pSavepoint->pNext;
+ sqlite3DbFree(db, pSavepoint);
if( !isTransaction ){
db->nSavepoint--;
}
}else{
- db->nDeferredCons = u.at.pSavepoint->nDeferredCons;
- db->nDeferredImmCons = u.at.pSavepoint->nDeferredImmCons;
+ db->nDeferredCons = pSavepoint->nDeferredCons;
+ db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
}
if( !isTransaction ){
- rc = sqlite3VtabSavepoint(db, u.at.p1, u.at.iSavepoint);
+ rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
}
}
@@ -69442,50 +69997,48 @@ case OP_Savepoint: {
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
-#if 0 /* local variables moved into u.au */
int desiredAutoCommit;
int iRollback;
int turnOnAC;
-#endif /* local variables moved into u.au */
- u.au.desiredAutoCommit = pOp->p1;
- u.au.iRollback = pOp->p2;
- u.au.turnOnAC = u.au.desiredAutoCommit && !db->autoCommit;
- assert( u.au.desiredAutoCommit==1 || u.au.desiredAutoCommit==0 );
- assert( u.au.desiredAutoCommit==1 || u.au.iRollback==0 );
+ desiredAutoCommit = pOp->p1;
+ iRollback = pOp->p2;
+ turnOnAC = desiredAutoCommit && !db->autoCommit;
+ assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
+ assert( desiredAutoCommit==1 || iRollback==0 );
assert( db->nVdbeActive>0 ); /* At least this one VM is active */
assert( p->bIsReader );
#if 0
- if( u.au.turnOnAC && u.au.iRollback && db->nVdbeActive>1 ){
+ if( turnOnAC && iRollback && db->nVdbeActive>1 ){
/* If this instruction implements a ROLLBACK and other VMs are
** still running, and a transaction is active, return an error indicating
- ** that the other VMs must complete first.
+ ** that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
}else
#endif
- if( u.au.turnOnAC && !u.au.iRollback && db->nVdbeWrite>0 ){
+ if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
/* If this instruction implements a COMMIT and other VMs are writing
- ** return an error indicating that the other VMs must complete first.
+ ** return an error indicating that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
- }else if( u.au.desiredAutoCommit!=db->autoCommit ){
- if( u.au.iRollback ){
- assert( u.au.desiredAutoCommit==1 );
+ }else if( desiredAutoCommit!=db->autoCommit ){
+ if( iRollback ){
+ assert( desiredAutoCommit==1 );
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
db->autoCommit = 1;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
- db->autoCommit = (u8)u.au.desiredAutoCommit;
+ db->autoCommit = (u8)desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
- db->autoCommit = (u8)(1-u.au.desiredAutoCommit);
+ db->autoCommit = (u8)(1-desiredAutoCommit);
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
@@ -69500,34 +70053,28 @@ case OP_AutoCommit: {
goto vdbe_return;
}else{
sqlite3SetString(&p->zErrMsg, db,
- (!u.au.desiredAutoCommit)?"cannot start a transaction within a transaction":(
- (u.au.iRollback)?"cannot rollback - no transaction is active":
+ (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
+ (iRollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
-
+
rc = SQLITE_ERROR;
}
break;
}
-/* Opcode: Transaction P1 P2 * * *
+/* Opcode: Transaction P1 P2 P3 P4 P5
**
-** Begin a transaction. The transaction ends when a Commit or Rollback
-** opcode is encountered. Depending on the ON CONFLICT setting, the
-** transaction might also be rolled back if an error is encountered.
+** Begin a transaction on database P1 if a transaction is not already
+** active.
+** If P2 is non-zero, then a write-transaction is started, or if a
+** read-transaction is already active, it is upgraded to a write-transaction.
+** If P2 is zero, then a read-transaction is started.
**
** P1 is the index of the database file on which the transaction is
** started. Index 0 is the main database file and index 1 is the
** file used for temporary tables. Indices of 2 or more are used for
** attached databases.
**
-** If P2 is non-zero, then a write-transaction is started. A RESERVED lock is
-** obtained on the database file when a write-transaction is started. No
-** other process can start another write transaction while this transaction is
-** underway. Starting a write transaction also creates a rollback journal. A
-** write transaction must be started before any changes can be made to the
-** database. If P2 is greater than or equal to 2 then an EXCLUSIVE lock is
-** also obtained on the file.
-**
** If a write-transaction is started and the Vdbe.usesStmtJournal flag is
** true (this flag is set if the Vdbe may modify more than one row and may
** throw an ABORT exception), a statement transaction may also be opened.
@@ -69538,12 +70085,21 @@ case OP_AutoCommit: {
** entire transaction. If no error is encountered, the statement transaction
** will automatically commit when the VDBE halts.
**
-** If P2 is zero, then a read-lock is obtained on the database file.
+** If P5!=0 then this opcode also checks the schema cookie against P3
+** and the schema generation counter against P4.
+** The cookie changes its value whenever the database schema changes.
+** This operation is used to detect when that the cookie has changed
+** and that the current process needs to reread the schema. If the schema
+** cookie in P3 differs from the schema cookie in the database header or
+** if the schema generation counter in P4 differs from the current
+** generation counter, then an SQLITE_SCHEMA error is raised and execution
+** halts. The sqlite3_step() wrapper function might then reprepare the
+** statement and rerun it from the beginning.
*/
case OP_Transaction: {
-#if 0 /* local variables moved into u.av */
Btree *pBt;
-#endif /* local variables moved into u.av */
+ int iMeta;
+ int iGen;
assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 );
@@ -69553,10 +70109,10 @@ case OP_Transaction: {
rc = SQLITE_READONLY;
goto abort_due_to_error;
}
- u.av.pBt = db->aDb[pOp->p1].pBt;
+ pBt = db->aDb[pOp->p1].pBt;
- if( u.av.pBt ){
- rc = sqlite3BtreeBeginTrans(u.av.pBt, pOp->p2);
+ if( pBt ){
+ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
if( rc==SQLITE_BUSY ){
p->pc = pc;
p->rc = rc = SQLITE_BUSY;
@@ -69566,19 +70122,19 @@ case OP_Transaction: {
goto abort_due_to_error;
}
- if( pOp->p2 && p->usesStmtJournal
- && (db->autoCommit==0 || db->nVdbeRead>1)
+ if( pOp->p2 && p->usesStmtJournal
+ && (db->autoCommit==0 || db->nVdbeRead>1)
){
- assert( sqlite3BtreeIsInTrans(u.av.pBt) );
+ assert( sqlite3BtreeIsInTrans(pBt) );
if( p->iStatement==0 ){
assert( db->nStatement>=0 && db->nSavepoint>=0 );
- db->nStatement++;
+ db->nStatement++;
p->iStatement = db->nSavepoint + db->nStatement;
}
rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginStmt(u.av.pBt, p->iStatement);
+ rc = sqlite3BtreeBeginStmt(pBt, p->iStatement);
}
/* Store the current value of the database handles deferred constraint
@@ -69587,6 +70143,35 @@ case OP_Transaction: {
p->nStmtDefCons = db->nDeferredCons;
p->nStmtDefImmCons = db->nDeferredImmCons;
}
+
+ /* Gather the schema version number for checking */
+ sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
+ iGen = db->aDb[pOp->p1].pSchema->iGeneration;
+ }else{
+ iGen = iMeta = 0;
+ }
+ assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
+ if( pOp->p5 && (iMeta!=pOp->p3 || iGen!=pOp->p4.i) ){
+ sqlite3DbFree(db, p->zErrMsg);
+ p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
+ /* If the schema-cookie from the database file matches the cookie
+ ** stored with the in-memory representation of the schema, do
+ ** not reload the schema from the database file.
+ **
+ ** If virtual-tables are in use, this is not just an optimization.
+ ** Often, v-tables store their data in other SQLite tables, which
+ ** are queried from within xNext() and other v-table methods using
+ ** prepared queries. If such a query is out-of-date, we do not want to
+ ** discard the database schema, as the user code implementing the
+ ** v-table would have to be ready for the sqlite3_vtab structure itself
+ ** to be invalidated whenever sqlite3_step() is called from within
+ ** a v-table method.
+ */
+ if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
+ sqlite3ResetOneSchema(db, pOp->p1);
+ }
+ p->expired = 1;
+ rc = SQLITE_SCHEMA;
}
break;
}
@@ -69604,22 +70189,20 @@ case OP_Transaction: {
** executing this instruction.
*/
case OP_ReadCookie: { /* out2-prerelease */
-#if 0 /* local variables moved into u.aw */
int iMeta;
int iDb;
int iCookie;
-#endif /* local variables moved into u.aw */
assert( p->bIsReader );
- u.aw.iDb = pOp->p1;
- u.aw.iCookie = pOp->p3;
+ iDb = pOp->p1;
+ iCookie = pOp->p3;
assert( pOp->p3<SQLITE_N_BTREE_META );
- assert( u.aw.iDb>=0 && u.aw.iDb<db->nDb );
- assert( db->aDb[u.aw.iDb].pBt!=0 );
- assert( (p->btreeMask & (((yDbMask)1)<<u.aw.iDb))!=0 );
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( db->aDb[iDb].pBt!=0 );
+ assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 );
- sqlite3BtreeGetMeta(db->aDb[u.aw.iDb].pBt, u.aw.iCookie, (u32 *)&u.aw.iMeta);
- pOut->u.i = u.aw.iMeta;
+ sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
+ pOut->u.i = iMeta;
break;
}
@@ -69634,27 +70217,25 @@ case OP_ReadCookie: { /* out2-prerelease */
** A transaction must be started before executing this opcode.
*/
case OP_SetCookie: { /* in3 */
-#if 0 /* local variables moved into u.ax */
Db *pDb;
-#endif /* local variables moved into u.ax */
assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( p->readOnly==0 );
- u.ax.pDb = &db->aDb[pOp->p1];
- assert( u.ax.pDb->pBt!=0 );
+ pDb = &db->aDb[pOp->p1];
+ assert( pDb->pBt!=0 );
assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
pIn3 = &aMem[pOp->p3];
sqlite3VdbeMemIntegerify(pIn3);
/* See note about index shifting on OP_ReadCookie */
- rc = sqlite3BtreeUpdateMeta(u.ax.pDb->pBt, pOp->p2, (int)pIn3->u.i);
+ rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i);
if( pOp->p2==BTREE_SCHEMA_VERSION ){
/* When the schema cookie changes, record the new cookie internally */
- u.ax.pDb->pSchema->schema_cookie = (int)pIn3->u.i;
+ pDb->pSchema->schema_cookie = (int)pIn3->u.i;
db->flags |= SQLITE_InternChanges;
}else if( pOp->p2==BTREE_FILE_FORMAT ){
/* Record changes in the file format */
- u.ax.pDb->pSchema->file_format = (u8)pIn3->u.i;
+ pDb->pSchema->file_format = (u8)pIn3->u.i;
}
if( pOp->p1==1 ){
/* Invalidate all prepared statements whenever the TEMP database
@@ -69665,68 +70246,6 @@ case OP_SetCookie: { /* in3 */
break;
}
-/* Opcode: VerifyCookie P1 P2 P3 * *
-**
-** Check the value of global database parameter number 0 (the
-** schema version) and make sure it is equal to P2 and that the
-** generation counter on the local schema parse equals P3.
-**
-** P1 is the database number which is 0 for the main database file
-** and 1 for the file holding temporary tables and some higher number
-** for auxiliary databases.
-**
-** The cookie changes its value whenever the database schema changes.
-** This operation is used to detect when that the cookie has changed
-** and that the current process needs to reread the schema.
-**
-** Either a transaction needs to have been started or an OP_Open needs
-** to be executed (to establish a read lock) before this opcode is
-** invoked.
-*/
-case OP_VerifyCookie: {
-#if 0 /* local variables moved into u.ay */
- int iMeta;
- int iGen;
- Btree *pBt;
-#endif /* local variables moved into u.ay */
-
- assert( pOp->p1>=0 && pOp->p1<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
- assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
- assert( p->bIsReader );
- u.ay.pBt = db->aDb[pOp->p1].pBt;
- if( u.ay.pBt ){
- sqlite3BtreeGetMeta(u.ay.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ay.iMeta);
- u.ay.iGen = db->aDb[pOp->p1].pSchema->iGeneration;
- }else{
- u.ay.iGen = u.ay.iMeta = 0;
- }
- if( u.ay.iMeta!=pOp->p2 || u.ay.iGen!=pOp->p3 ){
- sqlite3DbFree(db, p->zErrMsg);
- p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed");
- /* If the schema-cookie from the database file matches the cookie
- ** stored with the in-memory representation of the schema, do
- ** not reload the schema from the database file.
- **
- ** If virtual-tables are in use, this is not just an optimization.
- ** Often, v-tables store their data in other SQLite tables, which
- ** are queried from within xNext() and other v-table methods using
- ** prepared queries. If such a query is out-of-date, we do not want to
- ** discard the database schema, as the user code implementing the
- ** v-table would have to be ready for the sqlite3_vtab structure itself
- ** to be invalidated whenever sqlite3_step() is called from within
- ** a v-table method.
- */
- if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ay.iMeta ){
- sqlite3ResetOneSchema(db, pOp->p1);
- }
-
- p->expired = 1;
- rc = SQLITE_SCHEMA;
- }
- break;
-}
-
/* Opcode: OpenRead P1 P2 P3 P4 P5
** Synopsis: root=P2 iDb=P3
**
@@ -69780,7 +70299,6 @@ case OP_VerifyCookie: {
*/
case OP_OpenRead:
case OP_OpenWrite: {
-#if 0 /* local variables moved into u.az */
int nField;
KeyInfo *pKeyInfo;
int p2;
@@ -69789,7 +70307,6 @@ case OP_OpenWrite: {
Btree *pX;
VdbeCursor *pCur;
Db *pDb;
-#endif /* local variables moved into u.az */
assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
@@ -69801,60 +70318,60 @@ case OP_OpenWrite: {
break;
}
- u.az.nField = 0;
- u.az.pKeyInfo = 0;
- u.az.p2 = pOp->p2;
- u.az.iDb = pOp->p3;
- assert( u.az.iDb>=0 && u.az.iDb<db->nDb );
- assert( (p->btreeMask & (((yDbMask)1)<<u.az.iDb))!=0 );
- u.az.pDb = &db->aDb[u.az.iDb];
- u.az.pX = u.az.pDb->pBt;
- assert( u.az.pX!=0 );
+ nField = 0;
+ pKeyInfo = 0;
+ p2 = pOp->p2;
+ iDb = pOp->p3;
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 );
+ pDb = &db->aDb[iDb];
+ pX = pDb->pBt;
+ assert( pX!=0 );
if( pOp->opcode==OP_OpenWrite ){
- u.az.wrFlag = 1;
- assert( sqlite3SchemaMutexHeld(db, u.az.iDb, 0) );
- if( u.az.pDb->pSchema->file_format < p->minWriteFileFormat ){
- p->minWriteFileFormat = u.az.pDb->pSchema->file_format;
+ wrFlag = 1;
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ if( pDb->pSchema->file_format < p->minWriteFileFormat ){
+ p->minWriteFileFormat = pDb->pSchema->file_format;
}
}else{
- u.az.wrFlag = 0;
+ wrFlag = 0;
}
if( pOp->p5 & OPFLAG_P2ISREG ){
- assert( u.az.p2>0 );
- assert( u.az.p2<=(p->nMem-p->nCursor) );
- pIn2 = &aMem[u.az.p2];
+ assert( p2>0 );
+ assert( p2<=(p->nMem-p->nCursor) );
+ pIn2 = &aMem[p2];
assert( memIsValid(pIn2) );
assert( (pIn2->flags & MEM_Int)!=0 );
sqlite3VdbeMemIntegerify(pIn2);
- u.az.p2 = (int)pIn2->u.i;
- /* The u.az.p2 value always comes from a prior OP_CreateTable opcode and
- ** that opcode will always set the u.az.p2 value to 2 or more or else fail.
+ p2 = (int)pIn2->u.i;
+ /* The p2 value always comes from a prior OP_CreateTable opcode and
+ ** that opcode will always set the p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
- if( NEVER(u.az.p2<2) ) {
+ if( NEVER(p2<2) ) {
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
if( pOp->p4type==P4_KEYINFO ){
- u.az.pKeyInfo = pOp->p4.pKeyInfo;
- assert( u.az.pKeyInfo->enc==ENC(db) );
- assert( u.az.pKeyInfo->db==db );
- u.az.nField = u.az.pKeyInfo->nField+u.az.pKeyInfo->nXField;
+ pKeyInfo = pOp->p4.pKeyInfo;
+ assert( pKeyInfo->enc==ENC(db) );
+ assert( pKeyInfo->db==db );
+ nField = pKeyInfo->nField+pKeyInfo->nXField;
}else if( pOp->p4type==P4_INT32 ){
- u.az.nField = pOp->p4.i;
+ nField = pOp->p4.i;
}
assert( pOp->p1>=0 );
- assert( u.az.nField>=0 );
- testcase( u.az.nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */
- u.az.pCur = allocateCursor(p, pOp->p1, u.az.nField, u.az.iDb, 1);
- if( u.az.pCur==0 ) goto no_mem;
- u.az.pCur->nullRow = 1;
- u.az.pCur->isOrdered = 1;
- rc = sqlite3BtreeCursor(u.az.pX, u.az.p2, u.az.wrFlag, u.az.pKeyInfo, u.az.pCur->pCursor);
- u.az.pCur->pKeyInfo = u.az.pKeyInfo;
+ assert( nField>=0 );
+ testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */
+ pCur = allocateCursor(p, pOp->p1, nField, iDb, 1);
+ if( pCur==0 ) goto no_mem;
+ pCur->nullRow = 1;
+ pCur->isOrdered = 1;
+ rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
+ pCur->pKeyInfo = pKeyInfo;
assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
- sqlite3BtreeCursorHints(u.az.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
+ sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
/* Since it performs no memory allocation or IO, the only value that
** sqlite3BtreeCursor() may return is SQLITE_OK. */
@@ -69863,8 +70380,8 @@ case OP_OpenWrite: {
/* Set the VdbeCursor.isTable variable. Previous versions of
** SQLite used to check if the root-page flags were sane at this point
** and report database corruption if they were not, but this check has
- ** since moved into the btree layer. */
- u.az.pCur->isTable = pOp->p4type!=P4_KEYINFO;
+ ** since moved into the btree layer. */
+ pCur->isTable = pOp->p4type!=P4_KEYINFO;
break;
}
@@ -69896,12 +70413,10 @@ case OP_OpenWrite: {
*/
case OP_OpenAutoindex:
case OP_OpenEphemeral: {
-#if 0 /* local variables moved into u.ba */
VdbeCursor *pCx;
KeyInfo *pKeyInfo;
-#endif /* local variables moved into u.ba */
- static const int vfsFlags =
+ static const int vfsFlags =
SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_EXCLUSIVE |
@@ -69909,13 +70424,13 @@ case OP_OpenEphemeral: {
SQLITE_OPEN_TRANSIENT_DB;
assert( pOp->p1>=0 );
assert( pOp->p2>=0 );
- u.ba.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.ba.pCx==0 ) goto no_mem;
- u.ba.pCx->nullRow = 1;
- rc = sqlite3BtreeOpen(db->pVfs, 0, db, &u.ba.pCx->pBt,
+ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBt,
BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeBeginTrans(u.ba.pCx->pBt, 1);
+ rc = sqlite3BtreeBeginTrans(pCx->pBt, 1);
}
if( rc==SQLITE_OK ){
/* If a transient index is required, create it by calling
@@ -69923,57 +70438,54 @@ case OP_OpenEphemeral: {
** opening it. If a transient table is required, just use the
** automatically created table with root-page 1 (an BLOB_INTKEY table).
*/
- if( (u.ba.pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
+ if( (pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
int pgno;
assert( pOp->p4type==P4_KEYINFO );
- rc = sqlite3BtreeCreateTable(u.ba.pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
+ rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_BLOBKEY | pOp->p5);
if( rc==SQLITE_OK ){
assert( pgno==MASTER_ROOT+1 );
- assert( u.ba.pKeyInfo->db==db );
- assert( u.ba.pKeyInfo->enc==ENC(db) );
- u.ba.pCx->pKeyInfo = u.ba.pKeyInfo;
- rc = sqlite3BtreeCursor(u.ba.pCx->pBt, pgno, 1, u.ba.pKeyInfo, u.ba.pCx->pCursor);
+ assert( pKeyInfo->db==db );
+ assert( pKeyInfo->enc==ENC(db) );
+ pCx->pKeyInfo = pKeyInfo;
+ rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor);
}
- u.ba.pCx->isTable = 0;
+ pCx->isTable = 0;
}else{
- rc = sqlite3BtreeCursor(u.ba.pCx->pBt, MASTER_ROOT, 1, 0, u.ba.pCx->pCursor);
- u.ba.pCx->isTable = 1;
+ rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor);
+ pCx->isTable = 1;
}
}
- u.ba.pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
+ pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
-/* Opcode: SorterOpen P1 * * P4 *
+/* Opcode: SorterOpen P1 P2 * P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
** tables using an external merge-sort algorithm.
*/
case OP_SorterOpen: {
-#if 0 /* local variables moved into u.bb */
VdbeCursor *pCx;
-#endif /* local variables moved into u.bb */
assert( pOp->p1>=0 );
assert( pOp->p2>=0 );
- u.bb.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
- if( u.bb.pCx==0 ) goto no_mem;
- u.bb.pCx->pKeyInfo = pOp->p4.pKeyInfo;
- assert( u.bb.pCx->pKeyInfo->db==db );
- assert( u.bb.pCx->pKeyInfo->enc==ENC(db) );
- rc = sqlite3VdbeSorterInit(db, u.bb.pCx);
+ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1);
+ if( pCx==0 ) goto no_mem;
+ pCx->pKeyInfo = pOp->p4.pKeyInfo;
+ assert( pCx->pKeyInfo->db==db );
+ assert( pCx->pKeyInfo->enc==ENC(db) );
+ rc = sqlite3VdbeSorterInit(db, pCx);
break;
}
-/* Opcode: OpenPseudo P1 P2 P3 * P5
-** Synopsis: content in r[P2@P3]
+/* Opcode: OpenPseudo P1 P2 P3 * *
+** Synopsis: P3 columns in r[P2]
**
** Open a new cursor that points to a fake table that contains a single
-** row of data. The content of that one row in the content of memory
-** register P2 when P5==0. In other words, cursor P1 becomes an alias for the
-** MEM_Blob content contained in register P2. When P5==1, then the
-** row is represented by P3 consecutive registers beginning with P2.
+** row of data. The content of that one row is the content of memory
+** register P2. In other words, cursor P1 becomes an alias for the
+** MEM_Blob content contained in register P2.
**
** A pseudo-table created by this opcode is used to hold a single
** row output from the sorter so that the row can be decomposed into
@@ -69984,18 +70496,16 @@ case OP_SorterOpen: {
** the pseudo-table.
*/
case OP_OpenPseudo: {
-#if 0 /* local variables moved into u.bc */
VdbeCursor *pCx;
-#endif /* local variables moved into u.bc */
assert( pOp->p1>=0 );
assert( pOp->p3>=0 );
- u.bc.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
- if( u.bc.pCx==0 ) goto no_mem;
- u.bc.pCx->nullRow = 1;
- u.bc.pCx->pseudoTableReg = pOp->p2;
- u.bc.pCx->isTable = 1;
- u.bc.pCx->multiPseudo = pOp->p5;
+ pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0);
+ if( pCx==0 ) goto no_mem;
+ pCx->nullRow = 1;
+ pCx->pseudoTableReg = pOp->p2;
+ pCx->isTable = 1;
+ assert( pOp->p5==0 );
break;
}
@@ -70067,39 +70577,37 @@ case OP_Close: {
**
** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt
*/
-case OP_SeekLt: /* jump, in3 */
-case OP_SeekLe: /* jump, in3 */
-case OP_SeekGe: /* jump, in3 */
-case OP_SeekGt: { /* jump, in3 */
-#if 0 /* local variables moved into u.bd */
+case OP_SeekLT: /* jump, in3 */
+case OP_SeekLE: /* jump, in3 */
+case OP_SeekGE: /* jump, in3 */
+case OP_SeekGT: { /* jump, in3 */
int res;
int oc;
VdbeCursor *pC;
UnpackedRecord r;
int nField;
i64 iKey; /* The rowid we are to seek to */
-#endif /* local variables moved into u.bd */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p2!=0 );
- u.bd.pC = p->apCsr[pOp->p1];
- assert( u.bd.pC!=0 );
- assert( u.bd.pC->pseudoTableReg==0 );
- assert( OP_SeekLe == OP_SeekLt+1 );
- assert( OP_SeekGe == OP_SeekLt+2 );
- assert( OP_SeekGt == OP_SeekLt+3 );
- assert( u.bd.pC->isOrdered );
- assert( u.bd.pC->pCursor!=0 );
- u.bd.oc = pOp->opcode;
- u.bd.pC->nullRow = 0;
- if( u.bd.pC->isTable ){
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->pseudoTableReg==0 );
+ assert( OP_SeekLE == OP_SeekLT+1 );
+ assert( OP_SeekGE == OP_SeekLT+2 );
+ assert( OP_SeekGT == OP_SeekLT+3 );
+ assert( pC->isOrdered );
+ assert( pC->pCursor!=0 );
+ oc = pOp->opcode;
+ pC->nullRow = 0;
+ if( pC->isTable ){
/* The input value in P3 might be of any type: integer, real, string,
** blob, or NULL. But it needs to be an integer before we can do
** the seek, so covert it. */
pIn3 = &aMem[pOp->p3];
applyNumericAffinity(pIn3);
- u.bd.iKey = sqlite3VdbeIntValue(pIn3);
- u.bd.pC->rowidIsValid = 0;
+ iKey = sqlite3VdbeIntValue(pIn3);
+ pC->rowidIsValid = 0;
/* If the P3 value could not be converted into an integer without
** loss of information, then special processing is required... */
@@ -70107,100 +70615,103 @@ case OP_SeekGt: { /* jump, in3 */
if( (pIn3->flags & MEM_Real)==0 ){
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
- pc = pOp->p2 - 1;
+ pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
break;
}
- /* If the approximation u.bd.iKey is larger than the actual real search
+ /* If the approximation iKey is larger than the actual real search
** term, substitute >= for > and < for <=. e.g. if the search term
** is 4.9 and the integer approximation 5:
**
** (x > 4.9) -> (x >= 5)
** (x <= 4.9) -> (x < 5)
*/
- if( pIn3->r<(double)u.bd.iKey ){
- assert( OP_SeekGe==(OP_SeekGt-1) );
- assert( OP_SeekLt==(OP_SeekLe-1) );
- assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) );
- if( (u.bd.oc & 0x0001)==(OP_SeekGt & 0x0001) ) u.bd.oc--;
+ if( pIn3->r<(double)iKey ){
+ assert( OP_SeekGE==(OP_SeekGT-1) );
+ assert( OP_SeekLT==(OP_SeekLE-1) );
+ assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) );
+ if( (oc & 0x0001)==(OP_SeekGT & 0x0001) ) oc--;
}
- /* If the approximation u.bd.iKey is smaller than the actual real search
+ /* If the approximation iKey is smaller than the actual real search
** term, substitute <= for < and > for >=. */
- else if( pIn3->r>(double)u.bd.iKey ){
- assert( OP_SeekLe==(OP_SeekLt+1) );
- assert( OP_SeekGt==(OP_SeekGe+1) );
- assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) );
- if( (u.bd.oc & 0x0001)==(OP_SeekLt & 0x0001) ) u.bd.oc++;
+ else if( pIn3->r>(double)iKey ){
+ assert( OP_SeekLE==(OP_SeekLT+1) );
+ assert( OP_SeekGT==(OP_SeekGE+1) );
+ assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
+ if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++;
}
- }
- rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res);
+ }
+ rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- if( u.bd.res==0 ){
- u.bd.pC->rowidIsValid = 1;
- u.bd.pC->lastRowid = u.bd.iKey;
+ if( res==0 ){
+ pC->rowidIsValid = 1;
+ pC->lastRowid = iKey;
}
}else{
- u.bd.nField = pOp->p4.i;
+ nField = pOp->p4.i;
assert( pOp->p4type==P4_INT32 );
- assert( u.bd.nField>0 );
- u.bd.r.pKeyInfo = u.bd.pC->pKeyInfo;
- u.bd.r.nField = (u16)u.bd.nField;
+ assert( nField>0 );
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)nField;
/* The next line of code computes as follows, only faster:
- ** if( u.bd.oc==OP_SeekGt || u.bd.oc==OP_SeekLe ){
- ** u.bd.r.flags = UNPACKED_INCRKEY;
+ ** if( oc==OP_SeekGT || oc==OP_SeekLE ){
+ ** r.default_rc = -1;
** }else{
- ** u.bd.r.flags = 0;
+ ** r.default_rc = +1;
** }
*/
- u.bd.r.flags = (u8)(UNPACKED_INCRKEY * (1 & (u.bd.oc - OP_SeekLt)));
- assert( u.bd.oc!=OP_SeekGt || u.bd.r.flags==UNPACKED_INCRKEY );
- assert( u.bd.oc!=OP_SeekLe || u.bd.r.flags==UNPACKED_INCRKEY );
- assert( u.bd.oc!=OP_SeekGe || u.bd.r.flags==0 );
- assert( u.bd.oc!=OP_SeekLt || u.bd.r.flags==0 );
+ r.default_rc = ((1 & (oc - OP_SeekLT)) ? -1 : +1);
+ assert( oc!=OP_SeekGT || r.default_rc==-1 );
+ assert( oc!=OP_SeekLE || r.default_rc==-1 );
+ assert( oc!=OP_SeekGE || r.default_rc==+1 );
+ assert( oc!=OP_SeekLT || r.default_rc==+1 );
- u.bd.r.aMem = &aMem[pOp->p3];
+ r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bd.r.nField; i++) assert( memIsValid(&u.bd.r.aMem[i]) ); }
+ { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
- ExpandBlob(u.bd.r.aMem);
- rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, &u.bd.r, 0, 0, &u.bd.res);
+ ExpandBlob(r.aMem);
+ rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- u.bd.pC->rowidIsValid = 0;
+ pC->rowidIsValid = 0;
}
- u.bd.pC->deferredMoveto = 0;
- u.bd.pC->cacheStatus = CACHE_STALE;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
- if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
- if( u.bd.res<0 || (u.bd.res==0 && u.bd.oc==OP_SeekGt) ){
- rc = sqlite3BtreeNext(u.bd.pC->pCursor, &u.bd.res);
+ if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT );
+ if( res<0 || (res==0 && oc==OP_SeekGT) ){
+ res = 0;
+ rc = sqlite3BtreeNext(pC->pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bd.pC->rowidIsValid = 0;
+ pC->rowidIsValid = 0;
}else{
- u.bd.res = 0;
+ res = 0;
}
}else{
- assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
- if( u.bd.res>0 || (u.bd.res==0 && u.bd.oc==OP_SeekLt) ){
- rc = sqlite3BtreePrevious(u.bd.pC->pCursor, &u.bd.res);
+ assert( oc==OP_SeekLT || oc==OP_SeekLE );
+ if( res>0 || (res==0 && oc==OP_SeekLT) ){
+ res = 0;
+ rc = sqlite3BtreePrevious(pC->pCursor, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
- u.bd.pC->rowidIsValid = 0;
+ pC->rowidIsValid = 0;
}else{
- /* u.bd.res might be negative because the table is empty. Check to
+ /* res might be negative because the table is empty. Check to
** see if this is the case.
*/
- u.bd.res = sqlite3BtreeEof(u.bd.pC->pCursor);
+ res = sqlite3BtreeEof(pC->pCursor);
}
}
assert( pOp->p2>0 );
- if( u.bd.res ){
+ VdbeBranchTaken(res!=0,2);
+ if( res ){
pc = pOp->p2 - 1;
}
break;
@@ -70217,20 +70728,18 @@ case OP_SeekGt: { /* jump, in3 */
** occur, no unnecessary I/O happens.
*/
case OP_Seek: { /* in2 */
-#if 0 /* local variables moved into u.be */
VdbeCursor *pC;
-#endif /* local variables moved into u.be */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.be.pC = p->apCsr[pOp->p1];
- assert( u.be.pC!=0 );
- assert( u.be.pC->pCursor!=0 );
- assert( u.be.pC->isTable );
- u.be.pC->nullRow = 0;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->pCursor!=0 );
+ assert( pC->isTable );
+ pC->nullRow = 0;
pIn2 = &aMem[pOp->p2];
- u.be.pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
- u.be.pC->rowidIsValid = 0;
- u.be.pC->deferredMoveto = 1;
+ pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
+ pC->rowidIsValid = 0;
+ pC->deferredMoveto = 1;
break;
}
@@ -70285,7 +70794,6 @@ case OP_Seek: { /* in2 */
case OP_NoConflict: /* jump, in3 */
case OP_NotFound: /* jump, in3 */
case OP_Found: { /* jump, in3 */
-#if 0 /* local variables moved into u.bf */
int alreadyExists;
int ii;
VdbeCursor *pC;
@@ -70294,72 +70802,70 @@ case OP_Found: { /* jump, in3 */
UnpackedRecord *pIdxKey;
UnpackedRecord r;
char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*4 + 7];
-#endif /* local variables moved into u.bf */
#ifdef SQLITE_TEST
if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++;
#endif
- u.bf.alreadyExists = 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p4type==P4_INT32 );
- u.bf.pC = p->apCsr[pOp->p1];
- assert( u.bf.pC!=0 );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
pIn3 = &aMem[pOp->p3];
- assert( u.bf.pC->pCursor!=0 );
- assert( u.bf.pC->isTable==0 );
+ assert( pC->pCursor!=0 );
+ assert( pC->isTable==0 );
+ pFree = 0; /* Not needed. Only used to suppress a compiler warning. */
if( pOp->p4.i>0 ){
- u.bf.r.pKeyInfo = u.bf.pC->pKeyInfo;
- u.bf.r.nField = (u16)pOp->p4.i;
- u.bf.r.aMem = pIn3;
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)pOp->p4.i;
+ r.aMem = pIn3;
+ for(ii=0; ii<r.nField; ii++){
+ assert( memIsValid(&r.aMem[ii]) );
+ ExpandBlob(&r.aMem[ii]);
#ifdef SQLITE_DEBUG
- {
- int i;
- for(i=0; i<u.bf.r.nField; i++){
- assert( memIsValid(&u.bf.r.aMem[i]) );
- if( i ) REGISTER_TRACE(pOp->p3+i, &u.bf.r.aMem[i]);
- }
- }
+ if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]);
#endif
- u.bf.r.flags = UNPACKED_PREFIX_MATCH;
- u.bf.pIdxKey = &u.bf.r;
+ }
+ pIdxKey = &r;
}else{
- u.bf.pIdxKey = sqlite3VdbeAllocUnpackedRecord(
- u.bf.pC->pKeyInfo, u.bf.aTempRec, sizeof(u.bf.aTempRec), &u.bf.pFree
- );
- if( u.bf.pIdxKey==0 ) goto no_mem;
+ pIdxKey = sqlite3VdbeAllocUnpackedRecord(
+ pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
+ );
+ if( pIdxKey==0 ) goto no_mem;
assert( pIn3->flags & MEM_Blob );
assert( (pIn3->flags & MEM_Zero)==0 ); /* zeroblobs already expanded */
- sqlite3VdbeRecordUnpack(u.bf.pC->pKeyInfo, pIn3->n, pIn3->z, u.bf.pIdxKey);
- u.bf.pIdxKey->flags |= UNPACKED_PREFIX_MATCH;
+ sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
}
+ pIdxKey->default_rc = 0;
if( pOp->opcode==OP_NoConflict ){
/* For the OP_NoConflict opcode, take the jump if any of the
** input fields are NULL, since any key with a NULL will not
** conflict */
- for(u.bf.ii=0; u.bf.ii<u.bf.r.nField; u.bf.ii++){
- if( u.bf.r.aMem[u.bf.ii].flags & MEM_Null ){
- pc = pOp->p2 - 1;
+ for(ii=0; ii<r.nField; ii++){
+ if( r.aMem[ii].flags & MEM_Null ){
+ pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
break;
}
}
}
- rc = sqlite3BtreeMovetoUnpacked(u.bf.pC->pCursor, u.bf.pIdxKey, 0, 0, &u.bf.res);
+ rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
if( pOp->p4.i==0 ){
- sqlite3DbFree(db, u.bf.pFree);
+ sqlite3DbFree(db, pFree);
}
if( rc!=SQLITE_OK ){
break;
}
- u.bf.pC->seekResult = u.bf.res;
- u.bf.alreadyExists = (u.bf.res==0);
- u.bf.pC->nullRow = 1-u.bf.alreadyExists;
- u.bf.pC->deferredMoveto = 0;
- u.bf.pC->cacheStatus = CACHE_STALE;
+ pC->seekResult = res;
+ alreadyExists = (res==0);
+ pC->nullRow = 1-alreadyExists;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
if( pOp->opcode==OP_Found ){
- if( u.bf.alreadyExists ) pc = pOp->p2 - 1;
+ VdbeBranchTaken(alreadyExists!=0,2);
+ if( alreadyExists ) pc = pOp->p2 - 1;
}else{
- if( !u.bf.alreadyExists ) pc = pOp->p2 - 1;
+ VdbeBranchTaken(alreadyExists==0,2);
+ if( !alreadyExists ) pc = pOp->p2 - 1;
}
break;
}
@@ -70379,35 +70885,34 @@ case OP_Found: { /* jump, in3 */
** See also: Found, NotFound, NoConflict
*/
case OP_NotExists: { /* jump, in3 */
-#if 0 /* local variables moved into u.bg */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
u64 iKey;
-#endif /* local variables moved into u.bg */
pIn3 = &aMem[pOp->p3];
assert( pIn3->flags & MEM_Int );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bg.pC = p->apCsr[pOp->p1];
- assert( u.bg.pC!=0 );
- assert( u.bg.pC->isTable );
- assert( u.bg.pC->pseudoTableReg==0 );
- u.bg.pCrsr = u.bg.pC->pCursor;
- assert( u.bg.pCrsr!=0 );
- u.bg.res = 0;
- u.bg.iKey = pIn3->u.i;
- rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res);
- u.bg.pC->lastRowid = pIn3->u.i;
- u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0;
- u.bg.pC->nullRow = 0;
- u.bg.pC->cacheStatus = CACHE_STALE;
- u.bg.pC->deferredMoveto = 0;
- if( u.bg.res!=0 ){
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->isTable );
+ assert( pC->pseudoTableReg==0 );
+ pCrsr = pC->pCursor;
+ assert( pCrsr!=0 );
+ res = 0;
+ iKey = pIn3->u.i;
+ rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
+ pC->lastRowid = pIn3->u.i;
+ pC->rowidIsValid = res==0 ?1:0;
+ pC->nullRow = 0;
+ pC->cacheStatus = CACHE_STALE;
+ pC->deferredMoveto = 0;
+ VdbeBranchTaken(res!=0,2);
+ if( res!=0 ){
pc = pOp->p2 - 1;
- assert( u.bg.pC->rowidIsValid==0 );
+ assert( pC->rowidIsValid==0 );
}
- u.bg.pC->seekResult = u.bg.res;
+ pC->seekResult = res;
break;
}
@@ -70443,21 +70948,19 @@ case OP_Sequence: { /* out2-prerelease */
** AUTOINCREMENT feature.
*/
case OP_NewRowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bh */
i64 v; /* The new rowid */
VdbeCursor *pC; /* Cursor of table to get the new rowid */
int res; /* Result of an sqlite3BtreeLast() */
int cnt; /* Counter to limit the number of searches */
Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */
VdbeFrame *pFrame; /* Root frame of VDBE */
-#endif /* local variables moved into u.bh */
- u.bh.v = 0;
- u.bh.res = 0;
+ v = 0;
+ res = 0;
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bh.pC = p->apCsr[pOp->p1];
- assert( u.bh.pC!=0 );
- if( NEVER(u.bh.pC->pCursor==0) ){
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ if( NEVER(pC->pCursor==0) ){
/* The zero initialization above is all that is needed */
}else{
/* The next rowid or record number (different terms for the same
@@ -70473,7 +70976,7 @@ case OP_NewRowid: { /* out2-prerelease */
** succeeded. If the random rowid does exist, we select a new one
** and try again, up to 100 times.
*/
- assert( u.bh.pC->isTable );
+ assert( pC->isTable );
#ifdef SQLITE_32BIT_ROWID
# define MAX_ROWID 0x7fffffff
@@ -70485,61 +70988,56 @@ case OP_NewRowid: { /* out2-prerelease */
# define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff )
#endif
- if( !u.bh.pC->useRandomRowid ){
- u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor);
- if( u.bh.v==0 ){
- rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res);
- if( rc!=SQLITE_OK ){
- goto abort_due_to_error;
- }
- if( u.bh.res ){
- u.bh.v = 1; /* IMP: R-61914-48074 */
+ if( !pC->useRandomRowid ){
+ rc = sqlite3BtreeLast(pC->pCursor, &res);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ if( res ){
+ v = 1; /* IMP: R-61914-48074 */
+ }else{
+ assert( sqlite3BtreeCursorIsValid(pC->pCursor) );
+ rc = sqlite3BtreeKeySize(pC->pCursor, &v);
+ assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */
+ if( v>=MAX_ROWID ){
+ pC->useRandomRowid = 1;
}else{
- assert( sqlite3BtreeCursorIsValid(u.bh.pC->pCursor) );
- rc = sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v);
- assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */
- if( u.bh.v>=MAX_ROWID ){
- u.bh.pC->useRandomRowid = 1;
- }else{
- u.bh.v++; /* IMP: R-29538-34987 */
- }
+ v++; /* IMP: R-29538-34987 */
}
}
+ }
#ifndef SQLITE_OMIT_AUTOINCREMENT
- if( pOp->p3 ){
+ if( pOp->p3 ){
+ /* Assert that P3 is a valid memory cell. */
+ assert( pOp->p3>0 );
+ if( p->pFrame ){
+ for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
/* Assert that P3 is a valid memory cell. */
- assert( pOp->p3>0 );
- if( p->pFrame ){
- for(u.bh.pFrame=p->pFrame; u.bh.pFrame->pParent; u.bh.pFrame=u.bh.pFrame->pParent);
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=u.bh.pFrame->nMem );
- u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3];
- }else{
- /* Assert that P3 is a valid memory cell. */
- assert( pOp->p3<=(p->nMem-p->nCursor) );
- u.bh.pMem = &aMem[pOp->p3];
- memAboutToChange(p, u.bh.pMem);
- }
- assert( memIsValid(u.bh.pMem) );
-
- REGISTER_TRACE(pOp->p3, u.bh.pMem);
- sqlite3VdbeMemIntegerify(u.bh.pMem);
- assert( (u.bh.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
- if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){
- rc = SQLITE_FULL; /* IMP: R-12275-61338 */
- goto abort_due_to_error;
- }
- if( u.bh.v<u.bh.pMem->u.i+1 ){
- u.bh.v = u.bh.pMem->u.i + 1;
- }
- u.bh.pMem->u.i = u.bh.v;
+ assert( pOp->p3<=pFrame->nMem );
+ pMem = &pFrame->aMem[pOp->p3];
+ }else{
+ /* Assert that P3 is a valid memory cell. */
+ assert( pOp->p3<=(p->nMem-p->nCursor) );
+ pMem = &aMem[pOp->p3];
+ memAboutToChange(p, pMem);
}
-#endif
+ assert( memIsValid(pMem) );
- sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.v<MAX_ROWID ? u.bh.v+1 : 0);
+ REGISTER_TRACE(pOp->p3, pMem);
+ sqlite3VdbeMemIntegerify(pMem);
+ assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */
+ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){
+ rc = SQLITE_FULL; /* IMP: R-12275-61338 */
+ goto abort_due_to_error;
+ }
+ if( v<pMem->u.i+1 ){
+ v = pMem->u.i + 1;
+ }
+ pMem->u.i = v;
}
- if( u.bh.pC->useRandomRowid ){
+#endif
+ if( pC->useRandomRowid ){
/* IMPLEMENTATION-OF: R-07677-41881 If the largest ROWID is equal to the
** largest possible integer (9223372036854775807) then the database
** engine starts picking positive candidate ROWIDs at random until
@@ -70547,35 +71045,35 @@ case OP_NewRowid: { /* out2-prerelease */
assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is
** an AUTOINCREMENT table. */
/* on the first attempt, simply do one more than previous */
- u.bh.v = lastRowid;
- u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
- u.bh.v++; /* ensure non-zero */
- u.bh.cnt = 0;
- while( ((rc = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.v,
- 0, &u.bh.res))==SQLITE_OK)
- && (u.bh.res==0)
- && (++u.bh.cnt<100)){
+ v = lastRowid;
+ v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
+ v++; /* ensure non-zero */
+ cnt = 0;
+ while( ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
+ 0, &res))==SQLITE_OK)
+ && (res==0)
+ && (++cnt<100)){
/* collision - try another random rowid */
- sqlite3_randomness(sizeof(u.bh.v), &u.bh.v);
- if( u.bh.cnt<5 ){
+ sqlite3_randomness(sizeof(v), &v);
+ if( cnt<5 ){
/* try "small" random rowids for the initial attempts */
- u.bh.v &= 0xffffff;
+ v &= 0xffffff;
}else{
- u.bh.v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
+ v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
}
- u.bh.v++; /* ensure non-zero */
+ v++; /* ensure non-zero */
}
- if( rc==SQLITE_OK && u.bh.res==0 ){
+ if( rc==SQLITE_OK && res==0 ){
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
goto abort_due_to_error;
}
- assert( u.bh.v>0 ); /* EV: R-40812-03570 */
+ assert( v>0 ); /* EV: R-40812-03570 */
}
- u.bh.pC->rowidIsValid = 0;
- u.bh.pC->deferredMoveto = 0;
- u.bh.pC->cacheStatus = CACHE_STALE;
+ pC->rowidIsValid = 0;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
}
- pOut->u.i = u.bh.v;
+ pOut->u.i = v;
break;
}
@@ -70627,7 +71125,6 @@ case OP_NewRowid: { /* out2-prerelease */
*/
case OP_Insert:
case OP_InsertInt: {
-#if 0 /* local variables moved into u.bi */
Mem *pData; /* MEM cell holding data for the record to be inserted */
Mem *pKey; /* MEM cell holding key for the record */
i64 iKey; /* The integer ROWID or key for the record to be inserted */
@@ -70637,60 +71134,58 @@ case OP_InsertInt: {
const char *zDb; /* database name - used by the update hook */
const char *zTbl; /* Table name - used by the opdate hook */
int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
-#endif /* local variables moved into u.bi */
- u.bi.pData = &aMem[pOp->p2];
+ pData = &aMem[pOp->p2];
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- assert( memIsValid(u.bi.pData) );
- u.bi.pC = p->apCsr[pOp->p1];
- assert( u.bi.pC!=0 );
- assert( u.bi.pC->pCursor!=0 );
- assert( u.bi.pC->pseudoTableReg==0 );
- assert( u.bi.pC->isTable );
- REGISTER_TRACE(pOp->p2, u.bi.pData);
+ assert( memIsValid(pData) );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->pCursor!=0 );
+ assert( pC->pseudoTableReg==0 );
+ assert( pC->isTable );
+ REGISTER_TRACE(pOp->p2, pData);
if( pOp->opcode==OP_Insert ){
- u.bi.pKey = &aMem[pOp->p3];
- assert( u.bi.pKey->flags & MEM_Int );
- assert( memIsValid(u.bi.pKey) );
- REGISTER_TRACE(pOp->p3, u.bi.pKey);
- u.bi.iKey = u.bi.pKey->u.i;
+ pKey = &aMem[pOp->p3];
+ assert( pKey->flags & MEM_Int );
+ assert( memIsValid(pKey) );
+ REGISTER_TRACE(pOp->p3, pKey);
+ iKey = pKey->u.i;
}else{
assert( pOp->opcode==OP_InsertInt );
- u.bi.iKey = pOp->p3;
+ iKey = pOp->p3;
}
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = u.bi.iKey;
- if( u.bi.pData->flags & MEM_Null ){
- u.bi.pData->z = 0;
- u.bi.pData->n = 0;
+ if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = lastRowid = iKey;
+ if( pData->flags & MEM_Null ){
+ pData->z = 0;
+ pData->n = 0;
}else{
- assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) );
+ assert( pData->flags & (MEM_Blob|MEM_Str) );
}
- u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0);
- if( u.bi.pData->flags & MEM_Zero ){
- u.bi.nZero = u.bi.pData->u.nZero;
+ seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0);
+ if( pData->flags & MEM_Zero ){
+ nZero = pData->u.nZero;
}else{
- u.bi.nZero = 0;
+ nZero = 0;
}
- sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
- rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey,
- u.bi.pData->z, u.bi.pData->n, u.bi.nZero,
- (pOp->p5 & OPFLAG_APPEND)!=0, u.bi.seekResult
+ rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
+ pData->z, pData->n, nZero,
+ (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
);
- u.bi.pC->rowidIsValid = 0;
- u.bi.pC->deferredMoveto = 0;
- u.bi.pC->cacheStatus = CACHE_STALE;
+ pC->rowidIsValid = 0;
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
- u.bi.zDb = db->aDb[u.bi.pC->iDb].zName;
- u.bi.zTbl = pOp->p4.z;
- u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
- assert( u.bi.pC->isTable );
- db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey);
- assert( u.bi.pC->iDb>=0 );
+ zDb = db->aDb[pC->iDb].zName;
+ zTbl = pOp->p4.z;
+ op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
+ assert( pC->isTable );
+ db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
+ assert( pC->iDb>=0 );
}
break;
}
@@ -70716,37 +71211,34 @@ case OP_InsertInt: {
** using OP_NotFound prior to invoking this opcode.
*/
case OP_Delete: {
-#if 0 /* local variables moved into u.bj */
i64 iKey;
VdbeCursor *pC;
-#endif /* local variables moved into u.bj */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bj.pC = p->apCsr[pOp->p1];
- assert( u.bj.pC!=0 );
- assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
- u.bj.iKey = u.bj.pC->lastRowid; /* Only used for the update hook */
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
+ iKey = pC->lastRowid; /* Only used for the update hook */
/* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
** OP_Column on the same table without any intervening operations that
- ** might move or invalidate the cursor. Hence cursor u.bj.pC is always pointing
+ ** might move or invalidate the cursor. Hence cursor pC is always pointing
** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
** below is always a no-op and cannot fail. We will run it anyhow, though,
** to guard against future changes to the code generator.
**/
- assert( u.bj.pC->deferredMoveto==0 );
- rc = sqlite3VdbeCursorMoveto(u.bj.pC);
+ assert( pC->deferredMoveto==0 );
+ rc = sqlite3VdbeCursorMoveto(pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
- sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0);
- rc = sqlite3BtreeDelete(u.bj.pC->pCursor);
- u.bj.pC->cacheStatus = CACHE_STALE;
+ rc = sqlite3BtreeDelete(pC->pCursor);
+ pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && u.bj.pC->isTable ){
+ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
- db->aDb[u.bj.pC->iDb].zName, pOp->p4.z, u.bj.iKey);
- assert( u.bj.pC->iDb>=0 );
+ db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
+ assert( pC->iDb>=0 );
}
if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
break;
@@ -70780,19 +71272,18 @@ case OP_ResetCount: {
** each other. Jump to P2 if they are different.
*/
case OP_SorterCompare: {
-#if 0 /* local variables moved into u.bk */
VdbeCursor *pC;
int res;
int nIgnore;
-#endif /* local variables moved into u.bk */
- u.bk.pC = p->apCsr[pOp->p1];
- assert( isSorter(u.bk.pC) );
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC) );
assert( pOp->p4type==P4_INT32 );
pIn3 = &aMem[pOp->p3];
- u.bk.nIgnore = pOp->p4.i;
- rc = sqlite3VdbeSorterCompare(u.bk.pC, pIn3, u.bk.nIgnore, &u.bk.res);
- if( u.bk.res ){
+ nIgnore = pOp->p4.i;
+ rc = sqlite3VdbeSorterCompare(pC, pIn3, nIgnore, &res);
+ VdbeBranchTaken(res!=0,2);
+ if( res ){
pc = pOp->p2-1;
}
break;
@@ -70804,14 +71295,12 @@ case OP_SorterCompare: {
** Write into register P2 the current sorter data for sorter cursor P1.
*/
case OP_SorterData: {
-#if 0 /* local variables moved into u.bl */
VdbeCursor *pC;
-#endif /* local variables moved into u.bl */
pOut = &aMem[pOp->p2];
- u.bl.pC = p->apCsr[pOp->p1];
- assert( isSorter(u.bl.pC) );
- rc = sqlite3VdbeSorterRowkey(u.bl.pC, pOut);
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC) );
+ rc = sqlite3VdbeSorterRowkey(pC, pOut);
break;
}
@@ -70831,7 +71320,7 @@ case OP_SorterData: {
**
** Write into register P2 the complete row key for cursor P1.
** There is no interpretation of the data.
-** The key is copied onto the P3 register exactly as
+** The key is copied onto the P2 register exactly as
** it is found in the database file.
**
** If the P1 cursor must be pointing to a valid row (not a NULL row)
@@ -70839,62 +71328,60 @@ case OP_SorterData: {
*/
case OP_RowKey:
case OP_RowData: {
-#if 0 /* local variables moved into u.bm */
VdbeCursor *pC;
BtCursor *pCrsr;
u32 n;
i64 n64;
-#endif /* local variables moved into u.bm */
pOut = &aMem[pOp->p2];
memAboutToChange(p, pOut);
/* Note that RowKey and RowData are really exactly the same instruction */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bm.pC = p->apCsr[pOp->p1];
- assert( isSorter(u.bm.pC)==0 );
- assert( u.bm.pC->isTable || pOp->opcode!=OP_RowData );
- assert( u.bm.pC->isTable==0 || pOp->opcode==OP_RowData );
- assert( u.bm.pC!=0 );
- assert( u.bm.pC->nullRow==0 );
- assert( u.bm.pC->pseudoTableReg==0 );
- assert( u.bm.pC->pCursor!=0 );
- u.bm.pCrsr = u.bm.pC->pCursor;
- assert( sqlite3BtreeCursorIsValid(u.bm.pCrsr) );
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC)==0 );
+ assert( pC->isTable || pOp->opcode!=OP_RowData );
+ assert( pC->isTable==0 || pOp->opcode==OP_RowData );
+ assert( pC!=0 );
+ assert( pC->nullRow==0 );
+ assert( pC->pseudoTableReg==0 );
+ assert( pC->pCursor!=0 );
+ pCrsr = pC->pCursor;
+ assert( sqlite3BtreeCursorIsValid(pCrsr) );
/* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
** OP_Rewind/Op_Next with no intervening instructions that might invalidate
** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always
** a no-op and can never fail. But we leave it in place as a safety.
*/
- assert( u.bm.pC->deferredMoveto==0 );
- rc = sqlite3VdbeCursorMoveto(u.bm.pC);
+ assert( pC->deferredMoveto==0 );
+ rc = sqlite3VdbeCursorMoveto(pC);
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
- if( u.bm.pC->isTable==0 ){
- assert( !u.bm.pC->isTable );
- VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bm.pCrsr, &u.bm.n64);
+ if( pC->isTable==0 ){
+ assert( !pC->isTable );
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64);
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
- if( u.bm.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
- u.bm.n = (u32)u.bm.n64;
+ n = (u32)n64;
}else{
- VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bm.pCrsr, &u.bm.n);
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &n);
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
- if( u.bm.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+ if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
}
- if( sqlite3VdbeMemGrow(pOut, u.bm.n, 0) ){
+ if( sqlite3VdbeMemGrow(pOut, n, 0) ){
goto no_mem;
}
- pOut->n = u.bm.n;
+ pOut->n = n;
MemSetTypeFlag(pOut, MEM_Blob);
- if( u.bm.pC->isTable==0 ){
- rc = sqlite3BtreeKey(u.bm.pCrsr, 0, u.bm.n, pOut->z);
+ if( pC->isTable==0 ){
+ rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z);
}else{
- rc = sqlite3BtreeData(u.bm.pCrsr, 0, u.bm.n, pOut->z);
+ rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
}
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
@@ -70913,42 +71400,40 @@ case OP_RowData: {
** one opcode now works for both table types.
*/
case OP_Rowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bn */
VdbeCursor *pC;
i64 v;
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
-#endif /* local variables moved into u.bn */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bn.pC = p->apCsr[pOp->p1];
- assert( u.bn.pC!=0 );
- assert( u.bn.pC->pseudoTableReg==0 || u.bn.pC->nullRow );
- if( u.bn.pC->nullRow ){
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->pseudoTableReg==0 || pC->nullRow );
+ if( pC->nullRow ){
pOut->flags = MEM_Null;
break;
- }else if( u.bn.pC->deferredMoveto ){
- u.bn.v = u.bn.pC->movetoTarget;
+ }else if( pC->deferredMoveto ){
+ v = pC->movetoTarget;
#ifndef SQLITE_OMIT_VIRTUALTABLE
- }else if( u.bn.pC->pVtabCursor ){
- u.bn.pVtab = u.bn.pC->pVtabCursor->pVtab;
- u.bn.pModule = u.bn.pVtab->pModule;
- assert( u.bn.pModule->xRowid );
- rc = u.bn.pModule->xRowid(u.bn.pC->pVtabCursor, &u.bn.v);
- sqlite3VtabImportErrmsg(p, u.bn.pVtab);
+ }else if( pC->pVtabCursor ){
+ pVtab = pC->pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
+ assert( pModule->xRowid );
+ rc = pModule->xRowid(pC->pVtabCursor, &v);
+ sqlite3VtabImportErrmsg(p, pVtab);
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
- assert( u.bn.pC->pCursor!=0 );
- rc = sqlite3VdbeCursorMoveto(u.bn.pC);
+ assert( pC->pCursor!=0 );
+ rc = sqlite3VdbeCursorMoveto(pC);
if( rc ) goto abort_due_to_error;
- if( u.bn.pC->rowidIsValid ){
- u.bn.v = u.bn.pC->lastRowid;
+ if( pC->rowidIsValid ){
+ v = pC->lastRowid;
}else{
- rc = sqlite3BtreeKeySize(u.bn.pC->pCursor, &u.bn.v);
+ rc = sqlite3BtreeKeySize(pC->pCursor, &v);
assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */
}
}
- pOut->u.i = u.bn.v;
+ pOut->u.i = v;
break;
}
@@ -70959,19 +71444,16 @@ case OP_Rowid: { /* out2-prerelease */
** write a NULL.
*/
case OP_NullRow: {
-#if 0 /* local variables moved into u.bo */
VdbeCursor *pC;
-#endif /* local variables moved into u.bo */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bo.pC = p->apCsr[pOp->p1];
- assert( u.bo.pC!=0 );
- u.bo.pC->nullRow = 1;
- u.bo.pC->rowidIsValid = 0;
- u.bo.pC->cacheStatus = CACHE_STALE;
- assert( u.bo.pC->pCursor || u.bo.pC->pVtabCursor );
- if( u.bo.pC->pCursor ){
- sqlite3BtreeClearCursor(u.bo.pC->pCursor);
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pC->nullRow = 1;
+ pC->rowidIsValid = 0;
+ pC->cacheStatus = CACHE_STALE;
+ if( pC->pCursor ){
+ sqlite3BtreeClearCursor(pC->pCursor);
}
break;
}
@@ -70985,25 +71467,24 @@ case OP_NullRow: {
** to the following instruction.
*/
case OP_Last: { /* jump */
-#if 0 /* local variables moved into u.bp */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
-#endif /* local variables moved into u.bp */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bp.pC = p->apCsr[pOp->p1];
- assert( u.bp.pC!=0 );
- u.bp.pCrsr = u.bp.pC->pCursor;
- u.bp.res = 0;
- assert( u.bp.pCrsr!=0 );
- rc = sqlite3BtreeLast(u.bp.pCrsr, &u.bp.res);
- u.bp.pC->nullRow = (u8)u.bp.res;
- u.bp.pC->deferredMoveto = 0;
- u.bp.pC->rowidIsValid = 0;
- u.bp.pC->cacheStatus = CACHE_STALE;
- if( pOp->p2>0 && u.bp.res ){
- pc = pOp->p2 - 1;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pCrsr = pC->pCursor;
+ res = 0;
+ assert( pCrsr!=0 );
+ rc = sqlite3BtreeLast(pCrsr, &res);
+ pC->nullRow = (u8)res;
+ pC->deferredMoveto = 0;
+ pC->rowidIsValid = 0;
+ pC->cacheStatus = CACHE_STALE;
+ if( pOp->p2>0 ){
+ VdbeBranchTaken(res!=0,2);
+ if( res ) pc = pOp->p2 - 1;
}
break;
}
@@ -71039,36 +71520,35 @@ case OP_Sort: { /* jump */
** to the following instruction.
*/
case OP_Rewind: { /* jump */
-#if 0 /* local variables moved into u.bq */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
-#endif /* local variables moved into u.bq */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bq.pC = p->apCsr[pOp->p1];
- assert( u.bq.pC!=0 );
- assert( isSorter(u.bq.pC)==(pOp->opcode==OP_SorterSort) );
- u.bq.res = 1;
- if( isSorter(u.bq.pC) ){
- rc = sqlite3VdbeSorterRewind(db, u.bq.pC, &u.bq.res);
- }else{
- u.bq.pCrsr = u.bq.pC->pCursor;
- assert( u.bq.pCrsr );
- rc = sqlite3BtreeFirst(u.bq.pCrsr, &u.bq.res);
- u.bq.pC->deferredMoveto = 0;
- u.bq.pC->cacheStatus = CACHE_STALE;
- u.bq.pC->rowidIsValid = 0;
- }
- u.bq.pC->nullRow = (u8)u.bq.res;
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
+ res = 1;
+ if( isSorter(pC) ){
+ rc = sqlite3VdbeSorterRewind(db, pC, &res);
+ }else{
+ pCrsr = pC->pCursor;
+ assert( pCrsr );
+ rc = sqlite3BtreeFirst(pCrsr, &res);
+ pC->deferredMoveto = 0;
+ pC->cacheStatus = CACHE_STALE;
+ pC->rowidIsValid = 0;
+ }
+ pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
- if( u.bq.res ){
+ VdbeBranchTaken(res!=0,2);
+ if( res ){
pc = pOp->p2 - 1;
}
break;
}
-/* Opcode: Next P1 P2 * * P5
+/* Opcode: Next P1 P2 P3 P4 P5
**
** Advance cursor P1 so that it points to the next key/data pair in its
** table or index. If there are no more key/value pairs then fall through
@@ -71078,6 +71558,11 @@ case OP_Rewind: { /* jump */
** The P1 cursor must be for a real table, not a pseudo-table. P1 must have
** been opened prior to this opcode or the program will segfault.
**
+** The P3 value is a hint to the btree implementation. If P3==1, that
+** means P1 is an SQL index and that this instruction could have been
+** omitted if that index had been unique. P3 is usually 0. P3 is
+** always either 0 or 1.
+**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite3BtreeNext().
**
@@ -71086,12 +71571,12 @@ case OP_Rewind: { /* jump */
**
** See also: Prev, NextIfOpen
*/
-/* Opcode: NextIfOpen P1 P2 * * P5
+/* Opcode: NextIfOpen P1 P2 P3 P4 P5
**
** This opcode works just like OP_Next except that if cursor P1 is not
** open it behaves a no-op.
*/
-/* Opcode: Prev P1 P2 * * P5
+/* Opcode: Prev P1 P2 P3 P4 P5
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index. If there is no previous key/value pairs then fall through
@@ -71101,26 +71586,29 @@ case OP_Rewind: { /* jump */
** The P1 cursor must be for a real table, not a pseudo-table. If P1 is
** not open then the behavior is undefined.
**
+** The P3 value is a hint to the btree implementation. If P3==1, that
+** means P1 is an SQL index and that this instruction could have been
+** omitted if that index had been unique. P3 is usually 0. P3 is
+** always either 0 or 1.
+**
** P4 is always of type P4_ADVANCE. The function pointer points to
** sqlite3BtreePrevious().
**
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
*/
-/* Opcode: PrevIfOpen P1 P2 * * P5
+/* Opcode: PrevIfOpen P1 P2 P3 P4 P5
**
** This opcode works just like OP_Prev except that if cursor P1 is not
** open it behaves a no-op.
*/
case OP_SorterNext: { /* jump */
-#if 0 /* local variables moved into u.br */
VdbeCursor *pC;
int res;
-#endif /* local variables moved into u.br */
- u.br.pC = p->apCsr[pOp->p1];
- assert( isSorter(u.br.pC) );
- rc = sqlite3VdbeSorterNext(db, u.br.pC, &u.br.res);
+ pC = p->apCsr[pOp->p1];
+ assert( isSorter(pC) );
+ rc = sqlite3VdbeSorterNext(db, pC, &res);
goto next_tail;
case OP_PrevIfOpen: /* jump */
case OP_NextIfOpen: /* jump */
@@ -71130,28 +71618,32 @@ case OP_Prev: /* jump */
case OP_Next: /* jump */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
assert( pOp->p5<ArraySize(p->aCounter) );
- u.br.pC = p->apCsr[pOp->p1];
- assert( u.br.pC!=0 );
- assert( u.br.pC->deferredMoveto==0 );
- assert( u.br.pC->pCursor );
+ pC = p->apCsr[pOp->p1];
+ res = pOp->p3;
+ assert( pC!=0 );
+ assert( pC->deferredMoveto==0 );
+ assert( pC->pCursor );
+ assert( res==0 || (res==1 && pC->isTable==0) );
+ testcase( res==1 );
assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext );
assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext );
assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious);
- rc = pOp->p4.xAdvance(u.br.pC->pCursor, &u.br.res);
+ rc = pOp->p4.xAdvance(pC->pCursor, &res);
next_tail:
- u.br.pC->cacheStatus = CACHE_STALE;
- if( u.br.res==0 ){
- u.br.pC->nullRow = 0;
+ pC->cacheStatus = CACHE_STALE;
+ VdbeBranchTaken(res==0,2);
+ if( res==0 ){
+ pC->nullRow = 0;
pc = pOp->p2 - 1;
p->aCounter[pOp->p5]++;
#ifdef SQLITE_TEST
sqlite3_search_count++;
#endif
}else{
- u.br.pC->nullRow = 1;
+ pC->nullRow = 1;
}
- u.br.pC->rowidIsValid = 0;
+ pC->rowidIsValid = 0;
goto check_for_interrupt;
}
@@ -71165,40 +71657,46 @@ next_tail:
** P3 is a flag that provides a hint to the b-tree layer that this
** insert is likely to be an append.
**
+** If P5 has the OPFLAG_NCHANGE bit set, then the change counter is
+** incremented by this instruction. If the OPFLAG_NCHANGE bit is clear,
+** then the change counter is unchanged.
+**
+** If P5 has the OPFLAG_USESEEKRESULT bit set, then the cursor must have
+** just done a seek to the spot where the new entry is to be inserted.
+** This flag avoids doing an extra seek.
+**
** This instruction only works for indices. The equivalent instruction
** for tables is OP_Insert.
*/
case OP_SorterInsert: /* in2 */
case OP_IdxInsert: { /* in2 */
-#if 0 /* local variables moved into u.bs */
VdbeCursor *pC;
BtCursor *pCrsr;
int nKey;
const char *zKey;
-#endif /* local variables moved into u.bs */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bs.pC = p->apCsr[pOp->p1];
- assert( u.bs.pC!=0 );
- assert( isSorter(u.bs.pC)==(pOp->opcode==OP_SorterInsert) );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) );
pIn2 = &aMem[pOp->p2];
assert( pIn2->flags & MEM_Blob );
- u.bs.pCrsr = u.bs.pC->pCursor;
+ pCrsr = pC->pCursor;
if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
- assert( u.bs.pCrsr!=0 );
- assert( u.bs.pC->isTable==0 );
+ assert( pCrsr!=0 );
+ assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
- if( isSorter(u.bs.pC) ){
- rc = sqlite3VdbeSorterWrite(db, u.bs.pC, pIn2);
+ if( isSorter(pC) ){
+ rc = sqlite3VdbeSorterWrite(db, pC, pIn2);
}else{
- u.bs.nKey = pIn2->n;
- u.bs.zKey = pIn2->z;
- rc = sqlite3BtreeInsert(u.bs.pCrsr, u.bs.zKey, u.bs.nKey, "", 0, 0, pOp->p3,
- ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bs.pC->seekResult : 0)
+ nKey = pIn2->n;
+ zKey = pIn2->z;
+ rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3,
+ ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
);
- assert( u.bs.pC->deferredMoveto==0 );
- u.bs.pC->cacheStatus = CACHE_STALE;
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
}
}
break;
@@ -71212,34 +71710,32 @@ case OP_IdxInsert: { /* in2 */
** index opened by cursor P1.
*/
case OP_IdxDelete: {
-#if 0 /* local variables moved into u.bt */
VdbeCursor *pC;
BtCursor *pCrsr;
int res;
UnpackedRecord r;
-#endif /* local variables moved into u.bt */
assert( pOp->p3>0 );
assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bt.pC = p->apCsr[pOp->p1];
- assert( u.bt.pC!=0 );
- u.bt.pCrsr = u.bt.pC->pCursor;
- assert( u.bt.pCrsr!=0 );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pCrsr = pC->pCursor;
+ assert( pCrsr!=0 );
assert( pOp->p5==0 );
- u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo;
- u.bt.r.nField = (u16)pOp->p3;
- u.bt.r.flags = UNPACKED_PREFIX_MATCH;
- u.bt.r.aMem = &aMem[pOp->p2];
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)pOp->p3;
+ r.default_rc = 0;
+ r.aMem = &aMem[pOp->p2];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bt.r.nField; i++) assert( memIsValid(&u.bt.r.aMem[i]) ); }
+ { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
- rc = sqlite3BtreeMovetoUnpacked(u.bt.pCrsr, &u.bt.r, 0, 0, &u.bt.res);
- if( rc==SQLITE_OK && u.bt.res==0 ){
- rc = sqlite3BtreeDelete(u.bt.pCrsr);
+ rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
+ if( rc==SQLITE_OK && res==0 ){
+ rc = sqlite3BtreeDelete(pCrsr);
}
- assert( u.bt.pC->deferredMoveto==0 );
- u.bt.pC->cacheStatus = CACHE_STALE;
+ assert( pC->deferredMoveto==0 );
+ pC->cacheStatus = CACHE_STALE;
break;
}
@@ -71253,28 +71749,27 @@ case OP_IdxDelete: {
** See also: Rowid, MakeRecord.
*/
case OP_IdxRowid: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bu */
BtCursor *pCrsr;
VdbeCursor *pC;
i64 rowid;
-#endif /* local variables moved into u.bu */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bu.pC = p->apCsr[pOp->p1];
- assert( u.bu.pC!=0 );
- u.bu.pCrsr = u.bu.pC->pCursor;
- assert( u.bu.pCrsr!=0 );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ pCrsr = pC->pCursor;
+ assert( pCrsr!=0 );
pOut->flags = MEM_Null;
- rc = sqlite3VdbeCursorMoveto(u.bu.pC);
+ rc = sqlite3VdbeCursorMoveto(pC);
if( NEVER(rc) ) goto abort_due_to_error;
- assert( u.bu.pC->deferredMoveto==0 );
- assert( u.bu.pC->isTable==0 );
- if( !u.bu.pC->nullRow ){
- rc = sqlite3VdbeIdxRowid(db, u.bu.pCrsr, &u.bu.rowid);
+ assert( pC->deferredMoveto==0 );
+ assert( pC->isTable==0 );
+ if( !pC->nullRow ){
+ rowid = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
}
- pOut->u.i = u.bu.rowid;
+ pOut->u.i = rowid;
pOut->flags = MEM_Int;
}
break;
@@ -71284,65 +71779,87 @@ case OP_IdxRowid: { /* out2-prerelease */
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
-** key that omits the ROWID. Compare this key value against the index
-** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
+** key that omits the PRIMARY KEY. Compare this key value against the index
+** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID
+** fields at the end.
**
** If the P1 index entry is greater than or equal to the key value
** then jump to P2. Otherwise fall through to the next instruction.
+*/
+/* Opcode: IdxGT P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
**
-** If P5 is non-zero then the key value is increased by an epsilon
-** prior to the comparison. This make the opcode work like IdxGT except
-** that if the key from register P3 is a prefix of the key in the cursor,
-** the result is false whereas it would be true with IdxGT.
+** The P4 register values beginning with P3 form an unpacked index
+** key that omits the PRIMARY KEY. Compare this key value against the index
+** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID
+** fields at the end.
+**
+** If the P1 index entry is greater than the key value
+** then jump to P2. Otherwise fall through to the next instruction.
*/
/* Opcode: IdxLT P1 P2 P3 P4 P5
** Synopsis: key=r[P3@P4]
**
** The P4 register values beginning with P3 form an unpacked index
-** key that omits the ROWID. Compare this key value against the index
-** that P1 is currently pointing to, ignoring the ROWID on the P1 index.
+** key that omits the PRIMARY KEY or ROWID. Compare this key value against
+** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
+** ROWID on the P1 index.
**
** If the P1 index entry is less than the key value then jump to P2.
** Otherwise fall through to the next instruction.
+*/
+/* Opcode: IdxLE P1 P2 P3 P4 P5
+** Synopsis: key=r[P3@P4]
+**
+** The P4 register values beginning with P3 form an unpacked index
+** key that omits the PRIMARY KEY or ROWID. Compare this key value against
+** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or
+** ROWID on the P1 index.
**
-** If P5 is non-zero then the key value is increased by an epsilon prior
-** to the comparison. This makes the opcode work like IdxLE.
+** If the P1 index entry is less than or equal to the key value then jump
+** to P2. Otherwise fall through to the next instruction.
*/
+case OP_IdxLE: /* jump */
+case OP_IdxGT: /* jump */
case OP_IdxLT: /* jump */
-case OP_IdxGE: { /* jump */
-#if 0 /* local variables moved into u.bv */
+case OP_IdxGE: { /* jump */
VdbeCursor *pC;
int res;
UnpackedRecord r;
-#endif /* local variables moved into u.bv */
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
- u.bv.pC = p->apCsr[pOp->p1];
- assert( u.bv.pC!=0 );
- assert( u.bv.pC->isOrdered );
- assert( u.bv.pC->pCursor!=0);
- assert( u.bv.pC->deferredMoveto==0 );
+ pC = p->apCsr[pOp->p1];
+ assert( pC!=0 );
+ assert( pC->isOrdered );
+ assert( pC->pCursor!=0);
+ assert( pC->deferredMoveto==0 );
assert( pOp->p5==0 || pOp->p5==1 );
assert( pOp->p4type==P4_INT32 );
- u.bv.r.pKeyInfo = u.bv.pC->pKeyInfo;
- u.bv.r.nField = (u16)pOp->p4.i;
- if( pOp->p5 ){
- u.bv.r.flags = UNPACKED_INCRKEY | UNPACKED_PREFIX_MATCH;
+ r.pKeyInfo = pC->pKeyInfo;
+ r.nField = (u16)pOp->p4.i;
+ if( pOp->opcode<OP_IdxLT ){
+ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxGT );
+ r.default_rc = -1;
}else{
- u.bv.r.flags = UNPACKED_PREFIX_MATCH;
+ assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxLT );
+ r.default_rc = 0;
}
- u.bv.r.aMem = &aMem[pOp->p3];
+ r.aMem = &aMem[pOp->p3];
#ifdef SQLITE_DEBUG
- { int i; for(i=0; i<u.bv.r.nField; i++) assert( memIsValid(&u.bv.r.aMem[i]) ); }
+ { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
#endif
- rc = sqlite3VdbeIdxKeyCompare(u.bv.pC, &u.bv.r, &u.bv.res);
- if( pOp->opcode==OP_IdxLT ){
- u.bv.res = -u.bv.res;
+ res = 0; /* Not needed. Only used to silence a warning. */
+ rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res);
+ assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
+ if( (pOp->opcode&1)==(OP_IdxLT&1) ){
+ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
+ res = -res;
}else{
- assert( pOp->opcode==OP_IdxGE );
- u.bv.res++;
+ assert( pOp->opcode==OP_IdxGE || pOp->opcode==OP_IdxGT );
+ res++;
}
- if( u.bv.res>0 ){
+ VdbeBranchTaken(res>0,2);
+ if( res>0 ){
pc = pOp->p2 - 1 ;
}
break;
@@ -71369,43 +71886,42 @@ case OP_IdxGE: { /* jump */
** See also: Clear
*/
case OP_Destroy: { /* out2-prerelease */
-#if 0 /* local variables moved into u.bw */
int iMoved;
int iCnt;
Vdbe *pVdbe;
int iDb;
-#endif /* local variables moved into u.bw */
assert( p->readOnly==0 );
#ifndef SQLITE_OMIT_VIRTUALTABLE
- u.bw.iCnt = 0;
- for(u.bw.pVdbe=db->pVdbe; u.bw.pVdbe; u.bw.pVdbe = u.bw.pVdbe->pNext){
- if( u.bw.pVdbe->magic==VDBE_MAGIC_RUN && u.bw.pVdbe->bIsReader
- && u.bw.pVdbe->inVtabMethod<2 && u.bw.pVdbe->pc>=0
+ iCnt = 0;
+ for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
+ if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader
+ && pVdbe->inVtabMethod<2 && pVdbe->pc>=0
){
- u.bw.iCnt++;
+ iCnt++;
}
}
#else
- u.bw.iCnt = db->nVdbeRead;
+ iCnt = db->nVdbeRead;
#endif
pOut->flags = MEM_Null;
- if( u.bw.iCnt>1 ){
+ if( iCnt>1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
}else{
- u.bw.iDb = pOp->p3;
- assert( u.bw.iCnt==1 );
- assert( (p->btreeMask & (((yDbMask)1)<<u.bw.iDb))!=0 );
- rc = sqlite3BtreeDropTable(db->aDb[u.bw.iDb].pBt, pOp->p1, &u.bw.iMoved);
+ iDb = pOp->p3;
+ assert( iCnt==1 );
+ assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 );
+ iMoved = 0; /* Not needed. Only to silence a warning. */
+ rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int;
- pOut->u.i = u.bw.iMoved;
+ pOut->u.i = iMoved;
#ifndef SQLITE_OMIT_AUTOVACUUM
- if( rc==SQLITE_OK && u.bw.iMoved!=0 ){
- sqlite3RootPageMoved(db, u.bw.iDb, u.bw.iMoved, pOp->p1);
+ if( rc==SQLITE_OK && iMoved!=0 ){
+ sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
/* All OP_Destroy operations occur on the same btree */
- assert( resetSchemaOnFault==0 || resetSchemaOnFault==u.bw.iDb+1 );
- resetSchemaOnFault = u.bw.iDb+1;
+ assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
+ resetSchemaOnFault = iDb+1;
}
#endif
}
@@ -71431,23 +71947,20 @@ case OP_Destroy: { /* out2-prerelease */
** See also: Destroy
*/
case OP_Clear: {
-#if 0 /* local variables moved into u.bx */
int nChange;
-#endif /* local variables moved into u.bx */
-
- u.bx.nChange = 0;
+
+ nChange = 0;
assert( p->readOnly==0 );
- assert( pOp->p1!=1 );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 );
rc = sqlite3BtreeClearTable(
- db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0)
+ db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
);
if( pOp->p3 ){
- p->nChange += u.bx.nChange;
+ p->nChange += nChange;
if( pOp->p3>0 ){
assert( memIsValid(&aMem[pOp->p3]) );
memAboutToChange(p, &aMem[pOp->p3]);
- aMem[pOp->p3].u.i += u.bx.nChange;
+ aMem[pOp->p3].u.i += nChange;
}
}
break;
@@ -71479,26 +71992,24 @@ case OP_Clear: {
*/
case OP_CreateIndex: /* out2-prerelease */
case OP_CreateTable: { /* out2-prerelease */
-#if 0 /* local variables moved into u.by */
int pgno;
int flags;
Db *pDb;
-#endif /* local variables moved into u.by */
- u.by.pgno = 0;
+ pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( p->readOnly==0 );
- u.by.pDb = &db->aDb[pOp->p1];
- assert( u.by.pDb->pBt!=0 );
+ pDb = &db->aDb[pOp->p1];
+ assert( pDb->pBt!=0 );
if( pOp->opcode==OP_CreateTable ){
- /* u.by.flags = BTREE_INTKEY; */
- u.by.flags = BTREE_INTKEY;
+ /* flags = BTREE_INTKEY; */
+ flags = BTREE_INTKEY;
}else{
- u.by.flags = BTREE_BLOBKEY;
+ flags = BTREE_BLOBKEY;
}
- rc = sqlite3BtreeCreateTable(u.by.pDb->pBt, &u.by.pgno, u.by.flags);
- pOut->u.i = u.by.pgno;
+ rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
+ pOut->u.i = pgno;
break;
}
@@ -71511,44 +72022,42 @@ case OP_CreateTable: { /* out2-prerelease */
** then runs the new virtual machine. It is thus a re-entrant opcode.
*/
case OP_ParseSchema: {
-#if 0 /* local variables moved into u.bz */
int iDb;
const char *zMaster;
char *zSql;
InitData initData;
-#endif /* local variables moved into u.bz */
/* Any prepared statement that invokes this opcode will hold mutexes
- ** on every btree. This is a prerequisite for invoking
+ ** on every btree. This is a prerequisite for invoking
** sqlite3InitCallback().
*/
#ifdef SQLITE_DEBUG
- for(u.bz.iDb=0; u.bz.iDb<db->nDb; u.bz.iDb++){
- assert( u.bz.iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[u.bz.iDb].pBt) );
+ for(iDb=0; iDb<db->nDb; iDb++){
+ assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
}
#endif
- u.bz.iDb = pOp->p1;
- assert( u.bz.iDb>=0 && u.bz.iDb<db->nDb );
- assert( DbHasProperty(db, u.bz.iDb, DB_SchemaLoaded) );
+ iDb = pOp->p1;
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( DbHasProperty(db, iDb, DB_SchemaLoaded) );
/* Used to be a conditional */ {
- u.bz.zMaster = SCHEMA_TABLE(u.bz.iDb);
- u.bz.initData.db = db;
- u.bz.initData.iDb = pOp->p1;
- u.bz.initData.pzErrMsg = &p->zErrMsg;
- u.bz.zSql = sqlite3MPrintf(db,
+ zMaster = SCHEMA_TABLE(iDb);
+ initData.db = db;
+ initData.iDb = pOp->p1;
+ initData.pzErrMsg = &p->zErrMsg;
+ zSql = sqlite3MPrintf(db,
"SELECT name, rootpage, sql FROM '%q'.%s WHERE %s ORDER BY rowid",
- db->aDb[u.bz.iDb].zName, u.bz.zMaster, pOp->p4.z);
- if( u.bz.zSql==0 ){
+ db->aDb[iDb].zName, zMaster, pOp->p4.z);
+ if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
assert( db->init.busy==0 );
db->init.busy = 1;
- u.bz.initData.rc = SQLITE_OK;
+ initData.rc = SQLITE_OK;
assert( !db->mallocFailed );
- rc = sqlite3_exec(db, u.bz.zSql, sqlite3InitCallback, &u.bz.initData, 0);
- if( rc==SQLITE_OK ) rc = u.bz.initData.rc;
- sqlite3DbFree(db, u.bz.zSql);
+ rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
+ if( rc==SQLITE_OK ) rc = initData.rc;
+ sqlite3DbFree(db, zSql);
db->init.busy = 0;
}
}
@@ -71556,7 +72065,7 @@ case OP_ParseSchema: {
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
- break;
+ break;
}
#if !defined(SQLITE_OMIT_ANALYZE)
@@ -71632,42 +72141,40 @@ case OP_DropTrigger: {
** This opcode is used to implement the integrity_check pragma.
*/
case OP_IntegrityCk: {
-#if 0 /* local variables moved into u.ca */
int nRoot; /* Number of tables to check. (Number of root pages.) */
int *aRoot; /* Array of rootpage numbers for tables to be checked */
int j; /* Loop counter */
int nErr; /* Number of errors reported */
char *z; /* Text of the error report */
Mem *pnErr; /* Register keeping track of errors remaining */
-#endif /* local variables moved into u.ca */
assert( p->bIsReader );
- u.ca.nRoot = pOp->p2;
- assert( u.ca.nRoot>0 );
- u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) );
- if( u.ca.aRoot==0 ) goto no_mem;
+ nRoot = pOp->p2;
+ assert( nRoot>0 );
+ aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) );
+ if( aRoot==0 ) goto no_mem;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- u.ca.pnErr = &aMem[pOp->p3];
- assert( (u.ca.pnErr->flags & MEM_Int)!=0 );
- assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 );
+ pnErr = &aMem[pOp->p3];
+ assert( (pnErr->flags & MEM_Int)!=0 );
+ assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 );
pIn1 = &aMem[pOp->p1];
- for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){
- u.ca.aRoot[u.ca.j] = (int)sqlite3VdbeIntValue(&pIn1[u.ca.j]);
+ for(j=0; j<nRoot; j++){
+ aRoot[j] = (int)sqlite3VdbeIntValue(&pIn1[j]);
}
- u.ca.aRoot[u.ca.j] = 0;
+ aRoot[j] = 0;
assert( pOp->p5<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 );
- u.ca.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.ca.aRoot, u.ca.nRoot,
- (int)u.ca.pnErr->u.i, &u.ca.nErr);
- sqlite3DbFree(db, u.ca.aRoot);
- u.ca.pnErr->u.i -= u.ca.nErr;
+ z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
+ (int)pnErr->u.i, &nErr);
+ sqlite3DbFree(db, aRoot);
+ pnErr->u.i -= nErr;
sqlite3VdbeMemSetNull(pIn1);
- if( u.ca.nErr==0 ){
- assert( u.ca.z==0 );
- }else if( u.ca.z==0 ){
+ if( nErr==0 ){
+ assert( z==0 );
+ }else if( z==0 ){
goto no_mem;
}else{
- sqlite3VdbeMemSetStr(pIn1, u.ca.z, -1, SQLITE_UTF8, sqlite3_free);
+ sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free);
}
UPDATE_MAX_BLOBSIZE(pIn1);
sqlite3VdbeChangeEncoding(pIn1, encoding);
@@ -71703,20 +72210,20 @@ case OP_RowSetAdd: { /* in1, in2 */
** unchanged and jump to instruction P2.
*/
case OP_RowSetRead: { /* jump, in1, out3 */
-#if 0 /* local variables moved into u.cb */
i64 val;
-#endif /* local variables moved into u.cb */
pIn1 = &aMem[pOp->p1];
- if( (pIn1->flags & MEM_RowSet)==0
- || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
+ if( (pIn1->flags & MEM_RowSet)==0
+ || sqlite3RowSetNext(pIn1->u.pRowSet, &val)==0
){
/* The boolean index is empty */
sqlite3VdbeMemSetNull(pIn1);
pc = pOp->p2 - 1;
+ VdbeBranchTaken(1,2);
}else{
/* A value was pulled from the index */
- sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
+ sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
+ VdbeBranchTaken(0,2);
}
goto check_for_interrupt;
}
@@ -71746,14 +72253,12 @@ case OP_RowSetRead: { /* jump, in1, out3 */
** inserted as part of some other set).
*/
case OP_RowSetTest: { /* jump, in1, in3 */
-#if 0 /* local variables moved into u.cc */
int iSet;
int exists;
-#endif /* local variables moved into u.cc */
pIn1 = &aMem[pOp->p1];
pIn3 = &aMem[pOp->p3];
- u.cc.iSet = pOp->p4.i;
+ iSet = pOp->p4.i;
assert( pIn3->flags&MEM_Int );
/* If there is anything other than a rowset object in memory cell P1,
@@ -71765,17 +72270,18 @@ case OP_RowSetTest: { /* jump, in1, in3 */
}
assert( pOp->p4type==P4_INT32 );
- assert( u.cc.iSet==-1 || u.cc.iSet>=0 );
- if( u.cc.iSet ){
- u.cc.exists = sqlite3RowSetTest(pIn1->u.pRowSet,
- (u8)(u.cc.iSet>=0 ? u.cc.iSet & 0xf : 0xff),
+ assert( iSet==-1 || iSet>=0 );
+ if( iSet ){
+ exists = sqlite3RowSetTest(pIn1->u.pRowSet,
+ (u8)(iSet>=0 ? iSet & 0xf : 0xff),
pIn3->u.i);
- if( u.cc.exists ){
+ VdbeBranchTaken(exists!=0,2);
+ if( exists ){
pc = pOp->p2 - 1;
break;
}
}
- if( u.cc.iSet>=0 ){
+ if( iSet>=0 ){
sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
}
break;
@@ -71784,7 +72290,7 @@ case OP_RowSetTest: { /* jump, in1, in3 */
#ifndef SQLITE_OMIT_TRIGGER
-/* Opcode: Program P1 P2 P3 P4 *
+/* Opcode: Program P1 P2 P3 P4 P5
**
** Execute the trigger program passed as P4 (type P4_SUBPROGRAM).
**
@@ -71796,9 +72302,10 @@ case OP_RowSetTest: { /* jump, in1, in3 */
** memory required by the sub-vdbe at runtime.
**
** P4 is a pointer to the VM containing the trigger program.
+**
+** If P5 is non-zero, then recursive program invocation is enabled.
*/
case OP_Program: { /* jump */
-#if 0 /* local variables moved into u.cd */
int nMem; /* Number of memory registers for sub-program */
int nByte; /* Bytes of runtime space required for sub-program */
Mem *pRt; /* Register to allocate runtime space */
@@ -71807,27 +72314,26 @@ case OP_Program: { /* jump */
VdbeFrame *pFrame; /* New vdbe frame to execute in */
SubProgram *pProgram; /* Sub-program to execute */
void *t; /* Token identifying trigger */
-#endif /* local variables moved into u.cd */
-
- u.cd.pProgram = pOp->p4.pProgram;
- u.cd.pRt = &aMem[pOp->p3];
- assert( u.cd.pProgram->nOp>0 );
- /* If the p5 flag is clear, then recursive invocation of triggers is
+ pProgram = pOp->p4.pProgram;
+ pRt = &aMem[pOp->p3];
+ assert( pProgram->nOp>0 );
+
+ /* If the p5 flag is clear, then recursive invocation of triggers is
** disabled for backwards compatibility (p5 is set if this sub-program
** is really a trigger, not a foreign key action, and the flag set
** and cleared by the "PRAGMA recursive_triggers" command is clear).
- **
- ** It is recursive invocation of triggers, at the SQL level, that is
- ** disabled. In some cases a single trigger may generate more than one
- ** SubProgram (if the trigger may be executed with more than one different
+ **
+ ** It is recursive invocation of triggers, at the SQL level, that is
+ ** disabled. In some cases a single trigger may generate more than one
+ ** SubProgram (if the trigger may be executed with more than one different
** ON CONFLICT algorithm). SubProgram structures associated with a
- ** single trigger all have the same value for the SubProgram.token
+ ** single trigger all have the same value for the SubProgram.token
** variable. */
if( pOp->p5 ){
- u.cd.t = u.cd.pProgram->token;
- for(u.cd.pFrame=p->pFrame; u.cd.pFrame && u.cd.pFrame->token!=u.cd.t; u.cd.pFrame=u.cd.pFrame->pParent);
- if( u.cd.pFrame ) break;
+ t = pProgram->token;
+ for(pFrame=p->pFrame; pFrame && pFrame->token!=t; pFrame=pFrame->pParent);
+ if( pFrame ) break;
}
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
@@ -71836,69 +72342,69 @@ case OP_Program: { /* jump */
break;
}
- /* Register u.cd.pRt is used to store the memory required to save the state
+ /* Register pRt is used to store the memory required to save the state
** of the current program, and the memory required at runtime to execute
- ** the trigger program. If this trigger has been fired before, then u.cd.pRt
+ ** the trigger program. If this trigger has been fired before, then pRt
** is already allocated. Otherwise, it must be initialized. */
- if( (u.cd.pRt->flags&MEM_Frame)==0 ){
- /* SubProgram.nMem is set to the number of memory cells used by the
+ if( (pRt->flags&MEM_Frame)==0 ){
+ /* SubProgram.nMem is set to the number of memory cells used by the
** program stored in SubProgram.aOp. As well as these, one memory
** cell is required for each cursor used by the program. Set local
- ** variable u.cd.nMem (and later, VdbeFrame.nChildMem) to this value.
+ ** variable nMem (and later, VdbeFrame.nChildMem) to this value.
*/
- u.cd.nMem = u.cd.pProgram->nMem + u.cd.pProgram->nCsr;
- u.cd.nByte = ROUND8(sizeof(VdbeFrame))
- + u.cd.nMem * sizeof(Mem)
- + u.cd.pProgram->nCsr * sizeof(VdbeCursor *)
- + u.cd.pProgram->nOnce * sizeof(u8);
- u.cd.pFrame = sqlite3DbMallocZero(db, u.cd.nByte);
- if( !u.cd.pFrame ){
+ nMem = pProgram->nMem + pProgram->nCsr;
+ nByte = ROUND8(sizeof(VdbeFrame))
+ + nMem * sizeof(Mem)
+ + pProgram->nCsr * sizeof(VdbeCursor *)
+ + pProgram->nOnce * sizeof(u8);
+ pFrame = sqlite3DbMallocZero(db, nByte);
+ if( !pFrame ){
goto no_mem;
}
- sqlite3VdbeMemRelease(u.cd.pRt);
- u.cd.pRt->flags = MEM_Frame;
- u.cd.pRt->u.pFrame = u.cd.pFrame;
+ sqlite3VdbeMemRelease(pRt);
+ pRt->flags = MEM_Frame;
+ pRt->u.pFrame = pFrame;
- u.cd.pFrame->v = p;
- u.cd.pFrame->nChildMem = u.cd.nMem;
- u.cd.pFrame->nChildCsr = u.cd.pProgram->nCsr;
- u.cd.pFrame->pc = pc;
- u.cd.pFrame->aMem = p->aMem;
- u.cd.pFrame->nMem = p->nMem;
- u.cd.pFrame->apCsr = p->apCsr;
- u.cd.pFrame->nCursor = p->nCursor;
- u.cd.pFrame->aOp = p->aOp;
- u.cd.pFrame->nOp = p->nOp;
- u.cd.pFrame->token = u.cd.pProgram->token;
- u.cd.pFrame->aOnceFlag = p->aOnceFlag;
- u.cd.pFrame->nOnceFlag = p->nOnceFlag;
+ pFrame->v = p;
+ pFrame->nChildMem = nMem;
+ pFrame->nChildCsr = pProgram->nCsr;
+ pFrame->pc = pc;
+ pFrame->aMem = p->aMem;
+ pFrame->nMem = p->nMem;
+ pFrame->apCsr = p->apCsr;
+ pFrame->nCursor = p->nCursor;
+ pFrame->aOp = p->aOp;
+ pFrame->nOp = p->nOp;
+ pFrame->token = pProgram->token;
+ pFrame->aOnceFlag = p->aOnceFlag;
+ pFrame->nOnceFlag = p->nOnceFlag;
- u.cd.pEnd = &VdbeFrameMem(u.cd.pFrame)[u.cd.pFrame->nChildMem];
- for(u.cd.pMem=VdbeFrameMem(u.cd.pFrame); u.cd.pMem!=u.cd.pEnd; u.cd.pMem++){
- u.cd.pMem->flags = MEM_Invalid;
- u.cd.pMem->db = db;
+ pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
+ for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
+ pMem->flags = MEM_Undefined;
+ pMem->db = db;
}
}else{
- u.cd.pFrame = u.cd.pRt->u.pFrame;
- assert( u.cd.pProgram->nMem+u.cd.pProgram->nCsr==u.cd.pFrame->nChildMem );
- assert( u.cd.pProgram->nCsr==u.cd.pFrame->nChildCsr );
- assert( pc==u.cd.pFrame->pc );
+ pFrame = pRt->u.pFrame;
+ assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
+ assert( pProgram->nCsr==pFrame->nChildCsr );
+ assert( pc==pFrame->pc );
}
p->nFrame++;
- u.cd.pFrame->pParent = p->pFrame;
- u.cd.pFrame->lastRowid = lastRowid;
- u.cd.pFrame->nChange = p->nChange;
+ pFrame->pParent = p->pFrame;
+ pFrame->lastRowid = lastRowid;
+ pFrame->nChange = p->nChange;
p->nChange = 0;
- p->pFrame = u.cd.pFrame;
- p->aMem = aMem = &VdbeFrameMem(u.cd.pFrame)[-1];
- p->nMem = u.cd.pFrame->nChildMem;
- p->nCursor = (u16)u.cd.pFrame->nChildCsr;
+ p->pFrame = pFrame;
+ p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
+ p->nMem = pFrame->nChildMem;
+ p->nCursor = (u16)pFrame->nChildCsr;
p->apCsr = (VdbeCursor **)&aMem[p->nMem+1];
- p->aOp = aOp = u.cd.pProgram->aOp;
- p->nOp = u.cd.pProgram->nOp;
+ p->aOp = aOp = pProgram->aOp;
+ p->nOp = pProgram->nOp;
p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
- p->nOnceFlag = u.cd.pProgram->nOnce;
+ p->nOnceFlag = pProgram->nOnce;
pc = -1;
memset(p->aOnceFlag, 0, p->nOnceFlag);
@@ -71918,13 +72424,11 @@ case OP_Program: { /* jump */
** calling OP_Program instruction.
*/
case OP_Param: { /* out2-prerelease */
-#if 0 /* local variables moved into u.ce */
VdbeFrame *pFrame;
Mem *pIn;
-#endif /* local variables moved into u.ce */
- u.ce.pFrame = p->pFrame;
- u.ce.pIn = &u.ce.pFrame->aMem[pOp->p1 + u.ce.pFrame->aOp[u.ce.pFrame->pc].p1];
- sqlite3VdbeMemShallowCopy(pOut, u.ce.pIn, MEM_Ephem);
+ pFrame = p->pFrame;
+ pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];
+ sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
break;
}
@@ -71964,8 +72468,10 @@ case OP_FkCounter: {
*/
case OP_FkIfZero: { /* jump */
if( pOp->p1 ){
+ VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}else{
+ VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
}
break;
@@ -71985,22 +72491,19 @@ case OP_FkIfZero: { /* jump */
** an integer.
*/
case OP_MemMax: { /* in2 */
-#if 0 /* local variables moved into u.cf */
- Mem *pIn1;
VdbeFrame *pFrame;
-#endif /* local variables moved into u.cf */
if( p->pFrame ){
- for(u.cf.pFrame=p->pFrame; u.cf.pFrame->pParent; u.cf.pFrame=u.cf.pFrame->pParent);
- u.cf.pIn1 = &u.cf.pFrame->aMem[pOp->p1];
+ for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
+ pIn1 = &pFrame->aMem[pOp->p1];
}else{
- u.cf.pIn1 = &aMem[pOp->p1];
+ pIn1 = &aMem[pOp->p1];
}
- assert( memIsValid(u.cf.pIn1) );
- sqlite3VdbeMemIntegerify(u.cf.pIn1);
+ assert( memIsValid(pIn1) );
+ sqlite3VdbeMemIntegerify(pIn1);
pIn2 = &aMem[pOp->p2];
sqlite3VdbeMemIntegerify(pIn2);
- if( u.cf.pIn1->u.i<pIn2->u.i){
- u.cf.pIn1->u.i = pIn2->u.i;
+ if( pIn1->u.i<pIn2->u.i){
+ pIn1->u.i = pIn2->u.i;
}
break;
}
@@ -72017,6 +72520,7 @@ case OP_MemMax: { /* in2 */
case OP_IfPos: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
+ VdbeBranchTaken( pIn1->u.i>0, 2);
if( pIn1->u.i>0 ){
pc = pOp->p2 - 1;
}
@@ -72034,6 +72538,7 @@ case OP_IfPos: { /* jump, in1 */
case OP_IfNeg: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
+ VdbeBranchTaken(pIn1->u.i<0, 2);
if( pIn1->u.i<0 ){
pc = pOp->p2 - 1;
}
@@ -72053,6 +72558,7 @@ case OP_IfZero: { /* jump, in1 */
pIn1 = &aMem[pOp->p1];
assert( pIn1->flags&MEM_Int );
pIn1->u.i += pOp->p3;
+ VdbeBranchTaken(pIn1->u.i==0, 2);
if( pIn1->u.i==0 ){
pc = pOp->p2 - 1;
}
@@ -72071,56 +72577,53 @@ case OP_IfZero: { /* jump, in1 */
** successors.
*/
case OP_AggStep: {
-#if 0 /* local variables moved into u.cg */
int n;
int i;
Mem *pMem;
Mem *pRec;
sqlite3_context ctx;
sqlite3_value **apVal;
-#endif /* local variables moved into u.cg */
-
- u.cg.n = pOp->p5;
- assert( u.cg.n>=0 );
- u.cg.pRec = &aMem[pOp->p2];
- u.cg.apVal = p->apArg;
- assert( u.cg.apVal || u.cg.n==0 );
- for(u.cg.i=0; u.cg.i<u.cg.n; u.cg.i++, u.cg.pRec++){
- assert( memIsValid(u.cg.pRec) );
- u.cg.apVal[u.cg.i] = u.cg.pRec;
- memAboutToChange(p, u.cg.pRec);
- sqlite3VdbeMemStoreType(u.cg.pRec);
- }
- u.cg.ctx.pFunc = pOp->p4.pFunc;
+
+ n = pOp->p5;
+ assert( n>=0 );
+ pRec = &aMem[pOp->p2];
+ apVal = p->apArg;
+ assert( apVal || n==0 );
+ for(i=0; i<n; i++, pRec++){
+ assert( memIsValid(pRec) );
+ apVal[i] = pRec;
+ memAboutToChange(p, pRec);
+ }
+ ctx.pFunc = pOp->p4.pFunc;
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3];
- u.cg.pMem->n++;
- u.cg.ctx.s.flags = MEM_Null;
- u.cg.ctx.s.z = 0;
- u.cg.ctx.s.zMalloc = 0;
- u.cg.ctx.s.xDel = 0;
- u.cg.ctx.s.db = db;
- u.cg.ctx.isError = 0;
- u.cg.ctx.pColl = 0;
- u.cg.ctx.skipFlag = 0;
- if( u.cg.ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
+ ctx.pMem = pMem = &aMem[pOp->p3];
+ pMem->n++;
+ ctx.s.flags = MEM_Null;
+ ctx.s.z = 0;
+ ctx.s.zMalloc = 0;
+ ctx.s.xDel = 0;
+ ctx.s.db = db;
+ ctx.isError = 0;
+ ctx.pColl = 0;
+ ctx.skipFlag = 0;
+ if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
assert( pOp>p->aOp );
assert( pOp[-1].p4type==P4_COLLSEQ );
assert( pOp[-1].opcode==OP_CollSeq );
- u.cg.ctx.pColl = pOp[-1].p4.pColl;
+ ctx.pColl = pOp[-1].p4.pColl;
}
- (u.cg.ctx.pFunc->xStep)(&u.cg.ctx, u.cg.n, u.cg.apVal); /* IMP: R-24505-23230 */
- if( u.cg.ctx.isError ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cg.ctx.s));
- rc = u.cg.ctx.isError;
+ (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
+ if( ctx.isError ){
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
+ rc = ctx.isError;
}
- if( u.cg.ctx.skipFlag ){
+ if( ctx.skipFlag ){
assert( pOp[-1].opcode==OP_CollSeq );
- u.cg.i = pOp[-1].p1;
- if( u.cg.i ) sqlite3VdbeMemSetInt64(&aMem[u.cg.i], 1);
+ i = pOp[-1].p1;
+ if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
}
- sqlite3VdbeMemRelease(&u.cg.ctx.s);
+ sqlite3VdbeMemRelease(&ctx.s);
break;
}
@@ -72139,19 +72642,17 @@ case OP_AggStep: {
** the step function was not previously called.
*/
case OP_AggFinal: {
-#if 0 /* local variables moved into u.ch */
Mem *pMem;
-#endif /* local variables moved into u.ch */
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
- u.ch.pMem = &aMem[pOp->p1];
- assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
- rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc);
+ pMem = &aMem[pOp->p1];
+ assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
+ rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
if( rc ){
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem));
+ sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
}
- sqlite3VdbeChangeEncoding(u.ch.pMem, encoding);
- UPDATE_MAX_BLOBSIZE(u.ch.pMem);
- if( sqlite3VdbeMemTooBig(u.ch.pMem) ){
+ sqlite3VdbeChangeEncoding(pMem, encoding);
+ UPDATE_MAX_BLOBSIZE(pMem);
+ if( sqlite3VdbeMemTooBig(pMem) ){
goto too_big;
}
break;
@@ -72170,33 +72671,31 @@ case OP_AggFinal: {
** mem[P3+2] are initialized to -1.
*/
case OP_Checkpoint: {
-#if 0 /* local variables moved into u.ci */
int i; /* Loop counter */
int aRes[3]; /* Results */
Mem *pMem; /* Write results here */
-#endif /* local variables moved into u.ci */
assert( p->readOnly==0 );
- u.ci.aRes[0] = 0;
- u.ci.aRes[1] = u.ci.aRes[2] = -1;
+ aRes[0] = 0;
+ aRes[1] = aRes[2] = -1;
assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
|| pOp->p2==SQLITE_CHECKPOINT_FULL
|| pOp->p2==SQLITE_CHECKPOINT_RESTART
);
- rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &u.ci.aRes[1], &u.ci.aRes[2]);
+ rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
if( rc==SQLITE_BUSY ){
rc = SQLITE_OK;
- u.ci.aRes[0] = 1;
- }
- for(u.ci.i=0, u.ci.pMem = &aMem[pOp->p3]; u.ci.i<3; u.ci.i++, u.ci.pMem++){
- sqlite3VdbeMemSetInt64(u.ci.pMem, (i64)u.ci.aRes[u.ci.i]);
+ aRes[0] = 1;
}
+ for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){
+ sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]);
+ }
break;
};
#endif
#ifndef SQLITE_OMIT_PRAGMA
-/* Opcode: JournalMode P1 P2 P3 * P5
+/* Opcode: JournalMode P1 P2 P3 * *
**
** Change the journal mode of database P1 to P3. P3 must be one of the
** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
@@ -72208,7 +72707,6 @@ case OP_Checkpoint: {
** Write a string containing the final journal-mode to register P2.
*/
case OP_JournalMode: { /* out2-prerelease */
-#if 0 /* local variables moved into u.cj */
Btree *pBt; /* Btree to change journal mode of */
Pager *pPager; /* Pager associated with pBt */
int eNew; /* New journal mode */
@@ -72216,86 +72714,85 @@ case OP_JournalMode: { /* out2-prerelease */
#ifndef SQLITE_OMIT_WAL
const char *zFilename; /* Name of database file for pPager */
#endif
-#endif /* local variables moved into u.cj */
- u.cj.eNew = pOp->p3;
- assert( u.cj.eNew==PAGER_JOURNALMODE_DELETE
- || u.cj.eNew==PAGER_JOURNALMODE_TRUNCATE
- || u.cj.eNew==PAGER_JOURNALMODE_PERSIST
- || u.cj.eNew==PAGER_JOURNALMODE_OFF
- || u.cj.eNew==PAGER_JOURNALMODE_MEMORY
- || u.cj.eNew==PAGER_JOURNALMODE_WAL
- || u.cj.eNew==PAGER_JOURNALMODE_QUERY
+ eNew = pOp->p3;
+ assert( eNew==PAGER_JOURNALMODE_DELETE
+ || eNew==PAGER_JOURNALMODE_TRUNCATE
+ || eNew==PAGER_JOURNALMODE_PERSIST
+ || eNew==PAGER_JOURNALMODE_OFF
+ || eNew==PAGER_JOURNALMODE_MEMORY
+ || eNew==PAGER_JOURNALMODE_WAL
+ || eNew==PAGER_JOURNALMODE_QUERY
);
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( p->readOnly==0 );
- u.cj.pBt = db->aDb[pOp->p1].pBt;
- u.cj.pPager = sqlite3BtreePager(u.cj.pBt);
- u.cj.eOld = sqlite3PagerGetJournalMode(u.cj.pPager);
- if( u.cj.eNew==PAGER_JOURNALMODE_QUERY ) u.cj.eNew = u.cj.eOld;
- if( !sqlite3PagerOkToChangeJournalMode(u.cj.pPager) ) u.cj.eNew = u.cj.eOld;
+ pBt = db->aDb[pOp->p1].pBt;
+ pPager = sqlite3BtreePager(pBt);
+ eOld = sqlite3PagerGetJournalMode(pPager);
+ if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld;
+ if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld;
#ifndef SQLITE_OMIT_WAL
- u.cj.zFilename = sqlite3PagerFilename(u.cj.pPager, 1);
+ zFilename = sqlite3PagerFilename(pPager, 1);
/* Do not allow a transition to journal_mode=WAL for a database
- ** in temporary storage or if the VFS does not support shared memory
+ ** in temporary storage or if the VFS does not support shared memory
*/
- if( u.cj.eNew==PAGER_JOURNALMODE_WAL
- && (sqlite3Strlen30(u.cj.zFilename)==0 /* Temp file */
- || !sqlite3PagerWalSupported(u.cj.pPager)) /* No shared-memory support */
+ if( eNew==PAGER_JOURNALMODE_WAL
+ && (sqlite3Strlen30(zFilename)==0 /* Temp file */
+ || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */
){
- u.cj.eNew = u.cj.eOld;
+ eNew = eOld;
}
- if( (u.cj.eNew!=u.cj.eOld)
- && (u.cj.eOld==PAGER_JOURNALMODE_WAL || u.cj.eNew==PAGER_JOURNALMODE_WAL)
+ if( (eNew!=eOld)
+ && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
){
if( !db->autoCommit || db->nVdbeRead>1 ){
rc = SQLITE_ERROR;
- sqlite3SetString(&p->zErrMsg, db,
+ sqlite3SetString(&p->zErrMsg, db,
"cannot change %s wal mode from within a transaction",
- (u.cj.eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
+ (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
break;
}else{
-
- if( u.cj.eOld==PAGER_JOURNALMODE_WAL ){
+
+ if( eOld==PAGER_JOURNALMODE_WAL ){
/* If leaving WAL mode, close the log file. If successful, the call
- ** to PagerCloseWal() checkpoints and deletes the write-ahead-log
- ** file. An EXCLUSIVE lock may still be held on the database file
- ** after a successful return.
+ ** to PagerCloseWal() checkpoints and deletes the write-ahead-log
+ ** file. An EXCLUSIVE lock may still be held on the database file
+ ** after a successful return.
*/
- rc = sqlite3PagerCloseWal(u.cj.pPager);
+ rc = sqlite3PagerCloseWal(pPager);
if( rc==SQLITE_OK ){
- sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
+ sqlite3PagerSetJournalMode(pPager, eNew);
}
- }else if( u.cj.eOld==PAGER_JOURNALMODE_MEMORY ){
+ }else if( eOld==PAGER_JOURNALMODE_MEMORY ){
/* Cannot transition directly from MEMORY to WAL. Use mode OFF
** as an intermediate */
- sqlite3PagerSetJournalMode(u.cj.pPager, PAGER_JOURNALMODE_OFF);
+ sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF);
}
-
+
/* Open a transaction on the database file. Regardless of the journal
** mode, this transaction always uses a rollback journal.
*/
- assert( sqlite3BtreeIsInTrans(u.cj.pBt)==0 );
+ assert( sqlite3BtreeIsInTrans(pBt)==0 );
if( rc==SQLITE_OK ){
- rc = sqlite3BtreeSetVersion(u.cj.pBt, (u.cj.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
+ rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
}
}
}
#endif /* ifndef SQLITE_OMIT_WAL */
if( rc ){
- u.cj.eNew = u.cj.eOld;
+ eNew = eOld;
}
- u.cj.eNew = sqlite3PagerSetJournalMode(u.cj.pPager, u.cj.eNew);
+ eNew = sqlite3PagerSetJournalMode(pPager, eNew);
pOut = &aMem[pOp->p2];
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
- pOut->z = (char *)sqlite3JournalModename(u.cj.eNew);
+ pOut->z = (char *)sqlite3JournalModename(eNew);
pOut->n = sqlite3Strlen30(pOut->z);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
@@ -72325,15 +72822,14 @@ case OP_Vacuum: {
** P2. Otherwise, fall through to the next instruction.
*/
case OP_IncrVacuum: { /* jump */
-#if 0 /* local variables moved into u.ck */
Btree *pBt;
-#endif /* local variables moved into u.ck */
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
assert( p->readOnly==0 );
- u.ck.pBt = db->aDb[pOp->p1].pBt;
- rc = sqlite3BtreeIncrVacuum(u.ck.pBt);
+ pBt = db->aDb[pOp->p1].pBt;
+ rc = sqlite3BtreeIncrVacuum(pBt);
+ VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
pc = pOp->p2 - 1;
rc = SQLITE_OK;
@@ -72404,12 +72900,10 @@ case OP_TableLock: {
** code will be set to SQLITE_LOCKED.
*/
case OP_VBegin: {
-#if 0 /* local variables moved into u.cl */
VTable *pVTab;
-#endif /* local variables moved into u.cl */
- u.cl.pVTab = pOp->p4.pVtab;
- rc = sqlite3VtabBegin(db, u.cl.pVTab);
- if( u.cl.pVTab ) sqlite3VtabImportErrmsg(p, u.cl.pVTab->pVtab);
+ pVTab = pOp->p4.pVtab;
+ rc = sqlite3VtabBegin(db, pVTab);
+ if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -72448,32 +72942,30 @@ case OP_VDestroy: {
** table and stores that cursor in P1.
*/
case OP_VOpen: {
-#if 0 /* local variables moved into u.cm */
VdbeCursor *pCur;
sqlite3_vtab_cursor *pVtabCursor;
sqlite3_vtab *pVtab;
sqlite3_module *pModule;
-#endif /* local variables moved into u.cm */
assert( p->bIsReader );
- u.cm.pCur = 0;
- u.cm.pVtabCursor = 0;
- u.cm.pVtab = pOp->p4.pVtab->pVtab;
- u.cm.pModule = (sqlite3_module *)u.cm.pVtab->pModule;
- assert(u.cm.pVtab && u.cm.pModule);
- rc = u.cm.pModule->xOpen(u.cm.pVtab, &u.cm.pVtabCursor);
- sqlite3VtabImportErrmsg(p, u.cm.pVtab);
+ pCur = 0;
+ pVtabCursor = 0;
+ pVtab = pOp->p4.pVtab->pVtab;
+ pModule = (sqlite3_module *)pVtab->pModule;
+ assert(pVtab && pModule);
+ rc = pModule->xOpen(pVtab, &pVtabCursor);
+ sqlite3VtabImportErrmsg(p, pVtab);
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
- u.cm.pVtabCursor->pVtab = u.cm.pVtab;
+ pVtabCursor->pVtab = pVtab;
/* Initialize vdbe cursor object */
- u.cm.pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
- if( u.cm.pCur ){
- u.cm.pCur->pVtabCursor = u.cm.pVtabCursor;
+ pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
+ if( pCur ){
+ pCur->pVtabCursor = pVtabCursor;
}else{
db->mallocFailed = 1;
- u.cm.pModule->xClose(u.cm.pVtabCursor);
+ pModule->xClose(pVtabCursor);
}
}
break;
@@ -72501,7 +72993,6 @@ case OP_VOpen: {
** A jump is made to P2 if the result set after filtering would be empty.
*/
case OP_VFilter: { /* jump */
-#if 0 /* local variables moved into u.cn */
int nArg;
int iQuery;
const sqlite3_module *pModule;
@@ -72513,45 +73004,43 @@ case OP_VFilter: { /* jump */
int res;
int i;
Mem **apArg;
-#endif /* local variables moved into u.cn */
-
- u.cn.pQuery = &aMem[pOp->p3];
- u.cn.pArgc = &u.cn.pQuery[1];
- u.cn.pCur = p->apCsr[pOp->p1];
- assert( memIsValid(u.cn.pQuery) );
- REGISTER_TRACE(pOp->p3, u.cn.pQuery);
- assert( u.cn.pCur->pVtabCursor );
- u.cn.pVtabCursor = u.cn.pCur->pVtabCursor;
- u.cn.pVtab = u.cn.pVtabCursor->pVtab;
- u.cn.pModule = u.cn.pVtab->pModule;
+
+ pQuery = &aMem[pOp->p3];
+ pArgc = &pQuery[1];
+ pCur = p->apCsr[pOp->p1];
+ assert( memIsValid(pQuery) );
+ REGISTER_TRACE(pOp->p3, pQuery);
+ assert( pCur->pVtabCursor );
+ pVtabCursor = pCur->pVtabCursor;
+ pVtab = pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
/* Grab the index number and argc parameters */
- assert( (u.cn.pQuery->flags&MEM_Int)!=0 && u.cn.pArgc->flags==MEM_Int );
- u.cn.nArg = (int)u.cn.pArgc->u.i;
- u.cn.iQuery = (int)u.cn.pQuery->u.i;
+ assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
+ nArg = (int)pArgc->u.i;
+ iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */
{
- u.cn.res = 0;
- u.cn.apArg = p->apArg;
- for(u.cn.i = 0; u.cn.i<u.cn.nArg; u.cn.i++){
- u.cn.apArg[u.cn.i] = &u.cn.pArgc[u.cn.i+1];
- sqlite3VdbeMemStoreType(u.cn.apArg[u.cn.i]);
+ res = 0;
+ apArg = p->apArg;
+ for(i = 0; i<nArg; i++){
+ apArg[i] = &pArgc[i+1];
}
p->inVtabMethod = 1;
- rc = u.cn.pModule->xFilter(u.cn.pVtabCursor, u.cn.iQuery, pOp->p4.z, u.cn.nArg, u.cn.apArg);
+ rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
p->inVtabMethod = 0;
- sqlite3VtabImportErrmsg(p, u.cn.pVtab);
+ sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
- u.cn.res = u.cn.pModule->xEof(u.cn.pVtabCursor);
+ res = pModule->xEof(pVtabCursor);
}
-
- if( u.cn.res ){
+ VdbeBranchTaken(res!=0,2);
+ if( res ){
pc = pOp->p2 - 1;
}
}
- u.cn.pCur->nullRow = 0;
+ pCur->nullRow = 0;
break;
}
@@ -72566,51 +73055,49 @@ case OP_VFilter: { /* jump */
** P1 cursor is pointing to into register P3.
*/
case OP_VColumn: {
-#if 0 /* local variables moved into u.co */
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
Mem *pDest;
sqlite3_context sContext;
-#endif /* local variables moved into u.co */
VdbeCursor *pCur = p->apCsr[pOp->p1];
assert( pCur->pVtabCursor );
assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
- u.co.pDest = &aMem[pOp->p3];
- memAboutToChange(p, u.co.pDest);
+ pDest = &aMem[pOp->p3];
+ memAboutToChange(p, pDest);
if( pCur->nullRow ){
- sqlite3VdbeMemSetNull(u.co.pDest);
+ sqlite3VdbeMemSetNull(pDest);
break;
}
- u.co.pVtab = pCur->pVtabCursor->pVtab;
- u.co.pModule = u.co.pVtab->pModule;
- assert( u.co.pModule->xColumn );
- memset(&u.co.sContext, 0, sizeof(u.co.sContext));
+ pVtab = pCur->pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
+ assert( pModule->xColumn );
+ memset(&sContext, 0, sizeof(sContext));
/* The output cell may already have a buffer allocated. Move
- ** the current contents to u.co.sContext.s so in case the user-function
- ** can use the already allocated buffer instead of allocating a
+ ** the current contents to sContext.s so in case the user-function
+ ** can use the already allocated buffer instead of allocating a
** new one.
*/
- sqlite3VdbeMemMove(&u.co.sContext.s, u.co.pDest);
- MemSetTypeFlag(&u.co.sContext.s, MEM_Null);
+ sqlite3VdbeMemMove(&sContext.s, pDest);
+ MemSetTypeFlag(&sContext.s, MEM_Null);
- rc = u.co.pModule->xColumn(pCur->pVtabCursor, &u.co.sContext, pOp->p2);
- sqlite3VtabImportErrmsg(p, u.co.pVtab);
- if( u.co.sContext.isError ){
- rc = u.co.sContext.isError;
+ rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
+ sqlite3VtabImportErrmsg(p, pVtab);
+ if( sContext.isError ){
+ rc = sContext.isError;
}
/* Copy the result of the function to the P3 register. We
** do this regardless of whether or not an error occurred to ensure any
- ** dynamic allocation in u.co.sContext.s (a Mem struct) is released.
+ ** dynamic allocation in sContext.s (a Mem struct) is released.
*/
- sqlite3VdbeChangeEncoding(&u.co.sContext.s, encoding);
- sqlite3VdbeMemMove(u.co.pDest, &u.co.sContext.s);
- REGISTER_TRACE(pOp->p3, u.co.pDest);
- UPDATE_MAX_BLOBSIZE(u.co.pDest);
+ sqlite3VdbeChangeEncoding(&sContext.s, encoding);
+ sqlite3VdbeMemMove(pDest, &sContext.s);
+ REGISTER_TRACE(pOp->p3, pDest);
+ UPDATE_MAX_BLOBSIZE(pDest);
- if( sqlite3VdbeMemTooBig(u.co.pDest) ){
+ if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
break;
@@ -72625,38 +73112,36 @@ case OP_VColumn: {
** the end of its result set, then fall through to the next instruction.
*/
case OP_VNext: { /* jump */
-#if 0 /* local variables moved into u.cp */
sqlite3_vtab *pVtab;
const sqlite3_module *pModule;
int res;
VdbeCursor *pCur;
-#endif /* local variables moved into u.cp */
- u.cp.res = 0;
- u.cp.pCur = p->apCsr[pOp->p1];
- assert( u.cp.pCur->pVtabCursor );
- if( u.cp.pCur->nullRow ){
+ res = 0;
+ pCur = p->apCsr[pOp->p1];
+ assert( pCur->pVtabCursor );
+ if( pCur->nullRow ){
break;
}
- u.cp.pVtab = u.cp.pCur->pVtabCursor->pVtab;
- u.cp.pModule = u.cp.pVtab->pModule;
- assert( u.cp.pModule->xNext );
+ pVtab = pCur->pVtabCursor->pVtab;
+ pModule = pVtab->pModule;
+ assert( pModule->xNext );
/* Invoke the xNext() method of the module. There is no way for the
** underlying implementation to return an error if one occurs during
- ** xNext(). Instead, if an error occurs, true is returned (indicating that
+ ** xNext(). Instead, if an error occurs, true is returned (indicating that
** data is available) and the error code returned when xColumn or
** some other method is next invoked on the save virtual table cursor.
*/
p->inVtabMethod = 1;
- rc = u.cp.pModule->xNext(u.cp.pCur->pVtabCursor);
+ rc = pModule->xNext(pCur->pVtabCursor);
p->inVtabMethod = 0;
- sqlite3VtabImportErrmsg(p, u.cp.pVtab);
+ sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
- u.cp.res = u.cp.pModule->xEof(u.cp.pCur->pVtabCursor);
+ res = pModule->xEof(pCur->pVtabCursor);
}
-
- if( !u.cp.res ){
+ VdbeBranchTaken(!res,2);
+ if( !res ){
/* If there is data, jump to P2 */
pc = pOp->p2 - 1;
}
@@ -72672,25 +73157,23 @@ case OP_VNext: { /* jump */
** in register P1 is passed as the zName argument to the xRename method.
*/
case OP_VRename: {
-#if 0 /* local variables moved into u.cq */
sqlite3_vtab *pVtab;
Mem *pName;
-#endif /* local variables moved into u.cq */
- u.cq.pVtab = pOp->p4.pVtab->pVtab;
- u.cq.pName = &aMem[pOp->p1];
- assert( u.cq.pVtab->pModule->xRename );
- assert( memIsValid(u.cq.pName) );
+ pVtab = pOp->p4.pVtab->pVtab;
+ pName = &aMem[pOp->p1];
+ assert( pVtab->pModule->xRename );
+ assert( memIsValid(pName) );
assert( p->readOnly==0 );
- REGISTER_TRACE(pOp->p1, u.cq.pName);
- assert( u.cq.pName->flags & MEM_Str );
- testcase( u.cq.pName->enc==SQLITE_UTF8 );
- testcase( u.cq.pName->enc==SQLITE_UTF16BE );
- testcase( u.cq.pName->enc==SQLITE_UTF16LE );
- rc = sqlite3VdbeChangeEncoding(u.cq.pName, SQLITE_UTF8);
+ REGISTER_TRACE(pOp->p1, pName);
+ assert( pName->flags & MEM_Str );
+ testcase( pName->enc==SQLITE_UTF8 );
+ testcase( pName->enc==SQLITE_UTF16BE );
+ testcase( pName->enc==SQLITE_UTF16LE );
+ rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
if( rc==SQLITE_OK ){
- rc = u.cq.pVtab->pModule->xRename(u.cq.pVtab, u.cq.pName->z);
- sqlite3VtabImportErrmsg(p, u.cq.pVtab);
+ rc = pVtab->pModule->xRename(pVtab, pName->z);
+ sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
}
break;
@@ -72698,7 +73181,7 @@ case OP_VRename: {
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VUpdate P1 P2 P3 P4 *
+/* Opcode: VUpdate P1 P2 P3 P4 P5
** Synopsis: data=r[P3@P2]
**
** P4 is a pointer to a virtual table object, an sqlite3_vtab structure.
@@ -72721,9 +73204,11 @@ case OP_VRename: {
** P1 is a boolean flag. If it is set to true and the xUpdate call
** is successful, then the value returned by sqlite3_last_insert_rowid()
** is set to the value of the rowid for the row just inserted.
+**
+** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to
+** apply in the case of a constraint failure on an insert or update.
*/
case OP_VUpdate: {
-#if 0 /* local variables moved into u.cr */
sqlite3_vtab *pVtab;
sqlite3_module *pModule;
int nArg;
@@ -72731,34 +73216,32 @@ case OP_VUpdate: {
sqlite_int64 rowid;
Mem **apArg;
Mem *pX;
-#endif /* local variables moved into u.cr */
- assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
+ assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
);
assert( p->readOnly==0 );
- u.cr.pVtab = pOp->p4.pVtab->pVtab;
- u.cr.pModule = (sqlite3_module *)u.cr.pVtab->pModule;
- u.cr.nArg = pOp->p2;
+ pVtab = pOp->p4.pVtab->pVtab;
+ pModule = (sqlite3_module *)pVtab->pModule;
+ nArg = pOp->p2;
assert( pOp->p4type==P4_VTAB );
- if( ALWAYS(u.cr.pModule->xUpdate) ){
+ if( ALWAYS(pModule->xUpdate) ){
u8 vtabOnConflict = db->vtabOnConflict;
- u.cr.apArg = p->apArg;
- u.cr.pX = &aMem[pOp->p3];
- for(u.cr.i=0; u.cr.i<u.cr.nArg; u.cr.i++){
- assert( memIsValid(u.cr.pX) );
- memAboutToChange(p, u.cr.pX);
- sqlite3VdbeMemStoreType(u.cr.pX);
- u.cr.apArg[u.cr.i] = u.cr.pX;
- u.cr.pX++;
+ apArg = p->apArg;
+ pX = &aMem[pOp->p3];
+ for(i=0; i<nArg; i++){
+ assert( memIsValid(pX) );
+ memAboutToChange(p, pX);
+ apArg[i] = pX;
+ pX++;
}
db->vtabOnConflict = pOp->p5;
- rc = u.cr.pModule->xUpdate(u.cr.pVtab, u.cr.nArg, u.cr.apArg, &u.cr.rowid);
+ rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid);
db->vtabOnConflict = vtabOnConflict;
- sqlite3VtabImportErrmsg(p, u.cr.pVtab);
+ sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK && pOp->p1 ){
- assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
- db->lastRowid = lastRowid = u.cr.rowid;
+ assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) );
+ db->lastRowid = lastRowid = rowid;
}
if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
if( pOp->p5==OE_Ignore ){
@@ -72811,46 +73294,54 @@ case OP_MaxPgcnt: { /* out2-prerelease */
#endif
-#ifndef SQLITE_OMIT_TRACE
-/* Opcode: Trace * * * P4 *
+/* Opcode: Init * P2 * P4 *
+** Synopsis: Start at P2
+**
+** Programs contain a single instance of this opcode as the very first
+** opcode.
**
** If tracing is enabled (by the sqlite3_trace()) interface, then
** the UTF-8 string contained in P4 is emitted on the trace callback.
+** Or if P4 is blank, use the string returned by sqlite3_sql().
+**
+** If P2 is not zero, jump to instruction P2.
*/
-case OP_Trace: {
-#if 0 /* local variables moved into u.cs */
+case OP_Init: { /* jump */
char *zTrace;
char *z;
-#endif /* local variables moved into u.cs */
+ if( pOp->p2 ){
+ pc = pOp->p2 - 1;
+ }
+#ifndef SQLITE_OMIT_TRACE
if( db->xTrace
&& !p->doingRerun
- && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
+ && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
- u.cs.z = sqlite3VdbeExpandSql(p, u.cs.zTrace);
- db->xTrace(db->pTraceArg, u.cs.z);
- sqlite3DbFree(db, u.cs.z);
+ z = sqlite3VdbeExpandSql(p, zTrace);
+ db->xTrace(db->pTraceArg, z);
+ sqlite3DbFree(db, z);
}
#ifdef SQLITE_USE_FCNTL_TRACE
- u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
- if( u.cs.zTrace ){
+ zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql);
+ if( zTrace ){
int i;
for(i=0; i<db->nDb; i++){
- if( ((1<<i) & p->btreeMask)==0 ) continue;
- sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, u.cs.zTrace);
+ if( MASKBIT(i) & p->btreeMask)==0 ) continue;
+ sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
}
}
#endif /* SQLITE_USE_FCNTL_TRACE */
#ifdef SQLITE_DEBUG
if( (db->flags & SQLITE_SqlTrace)!=0
- && (u.cs.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
+ && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0
){
- sqlite3DebugPrintf("SQL-trace: %s\n", u.cs.zTrace);
+ sqlite3DebugPrintf("SQL-trace: %s\n", zTrace);
}
#endif /* SQLITE_DEBUG */
+#endif /* SQLITE_OMIT_TRACE */
break;
}
-#endif
/* Opcode: Noop * * * * *
@@ -72882,10 +73373,6 @@ default: { /* This is really OP_Noop and OP_Explain */
u64 elapsed = sqlite3Hwtime() - start;
pOp->cycles += elapsed;
pOp->cnt++;
-#if 0
- fprintf(stdout, "%10llu ", elapsed);
- sqlite3VdbePrintOp(stdout, origPc, &aOp[origPc]);
-#endif
}
#endif
@@ -72975,6 +73462,7 @@ abort_due_to_interrupt:
goto vdbe_error_halt;
}
+
/************** End of vdbe.c ************************************************/
/************** Begin file vdbeblob.c ****************************************/
/*
@@ -73110,22 +73598,20 @@ SQLITE_API int sqlite3_blob_open(
** which closes the b-tree cursor and (possibly) commits the
** transaction.
*/
+ static const int iLn = VDBE_OFFSET_LINENO(4);
static const VdbeOpList openBlob[] = {
- {OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */
- {OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */
- {OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */
-
+ /* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */
+ {OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */
/* One of the following two instructions is replaced by an OP_Noop. */
- {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
- {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */
-
- {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */
- {OP_NotExists, 0, 10, 1}, /* 6: Seek the cursor */
- {OP_Column, 0, 0, 1}, /* 7 */
- {OP_ResultRow, 1, 0, 0}, /* 8 */
- {OP_Goto, 0, 5, 0}, /* 9 */
- {OP_Close, 0, 0, 0}, /* 10 */
- {OP_Halt, 0, 0, 0}, /* 11 */
+ {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */
+ {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */
+ {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */
+ {OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */
+ {OP_Column, 0, 0, 1}, /* 6 */
+ {OP_ResultRow, 1, 0, 0}, /* 7 */
+ {OP_Goto, 0, 4, 0}, /* 8 */
+ {OP_Close, 0, 0, 0}, /* 9 */
+ {OP_Halt, 0, 0, 0}, /* 10 */
};
int rc = SQLITE_OK;
@@ -73232,42 +73718,37 @@ SQLITE_API int sqlite3_blob_open(
}
}
- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db);
+ pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse);
assert( pBlob->pStmt || db->mallocFailed );
if( pBlob->pStmt ){
Vdbe *v = (Vdbe *)pBlob->pStmt;
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
- sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
-
- /* Configure the OP_Transaction */
- sqlite3VdbeChangeP1(v, 0, iDb);
- sqlite3VdbeChangeP2(v, 0, flags);
-
- /* Configure the OP_VerifyCookie */
- sqlite3VdbeChangeP1(v, 1, iDb);
- sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie);
- sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration);
+ sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags,
+ pTab->pSchema->schema_cookie,
+ pTab->pSchema->iGeneration);
+ sqlite3VdbeChangeP5(v, 1);
+ sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn);
/* Make sure a mutex is held on the table to be accessed */
sqlite3VdbeUsesBtree(v, iDb);
/* Configure the OP_TableLock instruction */
#ifdef SQLITE_OMIT_SHARED_CACHE
- sqlite3VdbeChangeToNoop(v, 2);
+ sqlite3VdbeChangeToNoop(v, 1);
#else
- sqlite3VdbeChangeP1(v, 2, iDb);
- sqlite3VdbeChangeP2(v, 2, pTab->tnum);
- sqlite3VdbeChangeP3(v, 2, flags);
- sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
+ sqlite3VdbeChangeP1(v, 1, iDb);
+ sqlite3VdbeChangeP2(v, 1, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 1, flags);
+ sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT);
#endif
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
** parameter of the other to pTab->tnum. */
- sqlite3VdbeChangeToNoop(v, 4 - flags);
- sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum);
- sqlite3VdbeChangeP3(v, 3 + flags, iDb);
+ sqlite3VdbeChangeToNoop(v, 3 - flags);
+ sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 2 + flags, iDb);
/* Configure the number of columns. Configure the cursor to
** think that the table has one more column than it really
@@ -73276,8 +73757,8 @@ SQLITE_API int sqlite3_blob_open(
** we can invoke OP_Column to fill in the vdbe cursors type
** and offset cache without causing any IO.
*/
- sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
- sqlite3VdbeChangeP2(v, 7, pTab->nCol);
+ sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
+ sqlite3VdbeChangeP2(v, 6, pTab->nCol);
if( !db->mallocFailed ){
pParse->nVar = 1;
pParse->nMem = 1;
@@ -73862,10 +74343,10 @@ static void vdbeSorterCompare(
return;
}
}
- r2->flags |= UNPACKED_PREFIX_MATCH;
+ assert( r2->default_rc==0 );
}
- *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
+ *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0);
}
/*
@@ -75122,9 +75603,12 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
/*
** Call sqlite3WalkExpr() for every expression in Select statement p.
** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and
-** on the compound select chain, p->pPrior. Invoke the xSelectCallback()
-** either before or after the walk of expressions and FROM clause, depending
-** on whether pWalker->bSelectDepthFirst is false or true, respectively.
+** on the compound select chain, p->pPrior.
+**
+** If it is not NULL, the xSelectCallback() callback is invoked before
+** the walk of the expressions and FROM clause. The xSelectCallback2()
+** method, if it is not NULL, is invoked following the walk of the
+** expressions and FROM clause.
**
** Return WRC_Continue under normal conditions. Return WRC_Abort if
** there is an abort request.
@@ -75134,11 +75618,13 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){
*/
SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
int rc;
- if( p==0 || pWalker->xSelectCallback==0 ) return WRC_Continue;
+ if( p==0 || (pWalker->xSelectCallback==0 && pWalker->xSelectCallback2==0) ){
+ return WRC_Continue;
+ }
rc = WRC_Continue;
pWalker->walkerDepth++;
while( p ){
- if( !pWalker->bSelectDepthFirst ){
+ if( pWalker->xSelectCallback ){
rc = pWalker->xSelectCallback(pWalker, p);
if( rc ) break;
}
@@ -75148,12 +75634,8 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
pWalker->walkerDepth--;
return WRC_Abort;
}
- if( pWalker->bSelectDepthFirst ){
- rc = pWalker->xSelectCallback(pWalker, p);
- /* Depth-first search is currently only used for
- ** selectAddSubqueryTypeInfo() and that routine always returns
- ** WRC_Continue (0). So the following branch is never taken. */
- if( NEVER(rc) ) break;
+ if( pWalker->xSelectCallback2 ){
+ pWalker->xSelectCallback2(pWalker, p);
}
p = p->pPrior;
}
@@ -75501,6 +75983,8 @@ static int lookupName(
}else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
pExpr->iTable = 0;
pTab = pParse->pTriggerTab;
+ }else{
+ pTab = 0;
}
if( pTab ){
@@ -75544,8 +76028,8 @@ static int lookupName(
/*
** Perhaps the name is a reference to the ROWID
*/
- assert( pTab!=0 || cntTab==0 );
- if( cnt==0 && cntTab==1 && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
+ if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
+ && HasRowid(pMatch->pTab) ){
cnt = 1;
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
pExpr->affinity = SQLITE_AFF_INTEGER;
@@ -77139,16 +77623,25 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
}
/*
-** Return 1 if an expression must be FALSE in all cases and 0 if the
-** expression might be true. This is an optimization. If is OK to
-** return 0 here even if the expression really is always false (a
-** false negative). But it is a bug to return 1 if the expression
-** might be true in some rare circumstances (a false positive.)
+** If the expression is always either TRUE or FALSE (respectively),
+** then return 1. If one cannot determine the truth value of the
+** expression at compile-time return 0.
+**
+** This is an optimization. If is OK to return 0 here even if
+** the expression really is always false or false (a false negative).
+** But it is a bug to return 1 if the expression might have different
+** boolean values in different circumstances (a false positive.)
**
** Note that if the expression is part of conditional for a
** LEFT JOIN, then we cannot determine at compile-time whether or not
** is it true or false, so always return 0.
*/
+static int exprAlwaysTrue(Expr *p){
+ int v = 0;
+ if( ExprHasProperty(p, EP_FromJoin) ) return 0;
+ if( !sqlite3ExprIsInteger(p, &v) ) return 0;
+ return v!=0;
+}
static int exprAlwaysFalse(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
@@ -77503,6 +77996,33 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
}
/*
+** Create and return a deep copy of the object passed as the second
+** argument. If an OOM condition is encountered, NULL is returned
+** and the db->mallocFailed flag set.
+*/
+#ifndef SQLITE_OMIT_CTE
+static With *withDup(sqlite3 *db, With *p){
+ With *pRet = 0;
+ if( p ){
+ int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
+ pRet = sqlite3DbMallocZero(db, nByte);
+ if( pRet ){
+ int i;
+ pRet->nCte = p->nCte;
+ for(i=0; i<p->nCte; i++){
+ pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0);
+ pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0);
+ pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName);
+ }
+ }
+ }
+ return pRet;
+}
+#else
+# define withDup(x,y) 0
+#endif
+
+/*
** The following group of routines make deep copies of expressions,
** expression lists, ID lists, and select statements. The copies can
** be deleted (by being passed to their respective ...Delete() routines)
@@ -77582,6 +78102,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
pNewItem->regReturn = pOldItem->regReturn;
pNewItem->isCorrelated = pOldItem->isCorrelated;
pNewItem->viaCoroutine = pOldItem->viaCoroutine;
+ pNewItem->isRecursive = pOldItem->isRecursive;
pNewItem->zIndex = sqlite3DbStrDup(db, pOldItem->zIndex);
pNewItem->notIndexed = pOldItem->notIndexed;
pNewItem->pIndex = pOldItem->pIndex;
@@ -77639,10 +78160,11 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
pNew->iLimit = 0;
pNew->iOffset = 0;
pNew->selFlags = p->selFlags & ~SF_UsesEphemeral;
- pNew->pRightmost = 0;
pNew->addrOpenEphm[0] = -1;
pNew->addrOpenEphm[1] = -1;
pNew->addrOpenEphm[2] = -1;
+ pNew->nSelectRow = p->nSelectRow;
+ pNew->pWith = withDup(db, p->pWith);
return pNew;
}
#else
@@ -77948,24 +78470,6 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
}
/*
-** Generate an OP_IsNull instruction that tests register iReg and jumps
-** to location iDest if the value in iReg is NULL. The value in iReg
-** was computed by pExpr. If we can look at pExpr at compile-time and
-** determine that it can never generate a NULL, then the OP_IsNull operation
-** can be omitted.
-*/
-SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(
- Vdbe *v, /* The VDBE under construction */
- const Expr *pExpr, /* Only generate OP_IsNull if this expr can be NULL */
- int iReg, /* Test the value in this register for NULL */
- int iDest /* Jump here if the value is null */
-){
- if( sqlite3ExprCanBeNull(pExpr) ){
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iDest);
- }
-}
-
-/*
** Return TRUE if the given expression is a constant which would be
** unchanged by OP_Affinity with the affinity given in the second
** argument.
@@ -78161,7 +78665,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
pExpr = p->pEList->a[0].pExpr;
iCol = (i16)pExpr->iColumn;
- /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
+ /* Code an OP_Transaction and OP_TableLock for <table>. */
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3CodeVerifySchema(pParse, iDb);
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
@@ -78172,9 +78676,8 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
*/
assert(v);
if( iCol<0 ){
- int iAddr;
-
- iAddr = sqlite3CodeOnce(pParse);
+ int iAddr = sqlite3CodeOnce(pParse);
+ VdbeCoverage(v);
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
eType = IN_INDEX_ROWID;
@@ -78199,18 +78702,18 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
&& sqlite3FindCollSeq(db, ENC(db), pIdx->azColl[0], 0)==pReq
&& (!mustBeUnique || (pIdx->nKeyCol==1 && pIdx->onError!=OE_None))
){
- int iAddr = sqlite3CodeOnce(pParse);
+ int iAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
VdbeComment((v, "%s", pIdx->zName));
assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 );
eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0];
- sqlite3VdbeJumpHere(v, iAddr);
if( prNotFound && !pTab->aCol[iCol].notNull ){
*prNotFound = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Null, 0, *prNotFound);
}
+ sqlite3VdbeJumpHere(v, iAddr);
}
}
}
@@ -78299,7 +78802,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
** save the results, and reuse the same result on subsequent invocations.
*/
if( !ExprHasProperty(pExpr, EP_VarSelect) ){
- testAddr = sqlite3CodeOnce(pParse);
+ testAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
}
#ifndef SQLITE_OMIT_EXPLAIN
@@ -78340,7 +78843,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
*/
pExpr->iTable = pParse->nTab++;
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
- if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1, 1);
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
@@ -78416,6 +78918,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
if( isRowid ){
sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
@@ -78539,10 +79042,11 @@ static void sqlite3ExprCodeIN(
if( destIfNull==destIfFalse ){
/* Shortcut for the common case where the false and NULL outcomes are
** the same. */
- sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull);
+ sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
}else{
- int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1);
+ int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
+ VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
sqlite3VdbeJumpHere(v, addr1);
}
@@ -78550,8 +79054,9 @@ static void sqlite3ExprCodeIN(
if( eType==IN_INDEX_ROWID ){
/* In this case, the RHS is the ROWID of table b-tree
*/
- sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse);
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
+ VdbeCoverage(v);
}else{
/* In this case, the RHS is an index b-tree.
*/
@@ -78572,19 +79077,20 @@ static void sqlite3ExprCodeIN(
** for this particular IN operator.
*/
sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
-
+ VdbeCoverage(v);
}else{
/* In this branch, the RHS of the IN might contain a NULL and
** the presence of a NULL on the RHS makes a difference in the
** outcome.
*/
- int j1, j2, j3;
+ int j1, j2;
/* First check to see if the LHS is contained in the RHS. If so,
** then the presence of NULLs in the RHS does not matter, so jump
** over all of the code that follows.
*/
j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
+ VdbeCoverage(v);
/* Here we begin generating code that runs if the LHS is not
** contained within the RHS. Generate additional code that
@@ -78592,18 +79098,15 @@ static void sqlite3ExprCodeIN(
** jump to destIfNull. If there are no NULLs in the RHS then
** jump to destIfFalse.
*/
- j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull);
- j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
- sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
- sqlite3VdbeJumpHere(v, j3);
- sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
- sqlite3VdbeJumpHere(v, j2);
-
- /* Jump to the appropriate target depending on whether or not
- ** the RHS contains a NULL
- */
- sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull);
+ sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_IfNot, rRhsHasNull, destIfFalse); VdbeCoverage(v);
+ j2 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
+ VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, rRhsHasNull);
sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
+ sqlite3VdbeJumpHere(v, j2);
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, rRhsHasNull);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
/* The OP_Found at the top of this branch jumps here when true,
** causing the overall IN expression evaluation to fall through.
@@ -78786,6 +79289,11 @@ SQLITE_PRIVATE void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
*/
SQLITE_PRIVATE void sqlite3ExprCachePush(Parse *pParse){
pParse->iCacheLevel++;
+#ifdef SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("PUSH to %d\n", pParse->iCacheLevel);
+ }
+#endif
}
/*
@@ -78799,6 +79307,11 @@ SQLITE_PRIVATE void sqlite3ExprCachePop(Parse *pParse, int N){
assert( N>0 );
assert( pParse->iCacheLevel>=N );
pParse->iCacheLevel -= N;
+#ifdef SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("POP to %d\n", pParse->iCacheLevel);
+ }
+#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iLevel>pParse->iCacheLevel ){
cacheEntryClear(pParse, p);
@@ -78893,6 +79406,11 @@ SQLITE_PRIVATE void sqlite3ExprCacheClear(Parse *pParse){
int i;
struct yColCache *p;
+#if SQLITE_DEBUG
+ if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
+ printf("CLEAR\n");
+ }
+#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg ){
cacheEntryClear(pParse, p);
@@ -79109,22 +79627,16 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
case TK_GE:
case TK_NE:
case TK_EQ: {
- assert( TK_LT==OP_Lt );
- assert( TK_LE==OP_Le );
- assert( TK_GT==OP_Gt );
- assert( TK_GE==OP_Ge );
- assert( TK_EQ==OP_Eq );
- assert( TK_NE==OP_Ne );
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, inReg, SQLITE_STOREP2);
+ assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -79138,6 +79650,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==TK_EQ);
+ VdbeCoverageIf(v, op==TK_NE);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -79154,28 +79668,17 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
case TK_LSHIFT:
case TK_RSHIFT:
case TK_CONCAT: {
- assert( TK_AND==OP_And );
- assert( TK_OR==OP_Or );
- assert( TK_PLUS==OP_Add );
- assert( TK_MINUS==OP_Subtract );
- assert( TK_REM==OP_Remainder );
- assert( TK_BITAND==OP_BitAnd );
- assert( TK_BITOR==OP_BitOr );
- assert( TK_SLASH==OP_Divide );
- assert( TK_LSHIFT==OP_ShiftLeft );
- assert( TK_RSHIFT==OP_ShiftRight );
- assert( TK_CONCAT==OP_Concat );
- testcase( op==TK_AND );
- testcase( op==TK_OR );
- testcase( op==TK_PLUS );
- testcase( op==TK_MINUS );
- testcase( op==TK_REM );
- testcase( op==TK_BITAND );
- testcase( op==TK_BITOR );
- testcase( op==TK_SLASH );
- testcase( op==TK_LSHIFT );
- testcase( op==TK_RSHIFT );
- testcase( op==TK_CONCAT );
+ assert( TK_AND==OP_And ); testcase( op==TK_AND );
+ assert( TK_OR==OP_Or ); testcase( op==TK_OR );
+ assert( TK_PLUS==OP_Add ); testcase( op==TK_PLUS );
+ assert( TK_MINUS==OP_Subtract ); testcase( op==TK_MINUS );
+ assert( TK_REM==OP_Remainder ); testcase( op==TK_REM );
+ assert( TK_BITAND==OP_BitAnd ); testcase( op==TK_BITAND );
+ assert( TK_BITOR==OP_BitOr ); testcase( op==TK_BITOR );
+ assert( TK_SLASH==OP_Divide ); testcase( op==TK_SLASH );
+ assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT );
+ assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT );
+ assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
sqlite3VdbeAddOp3(v, op, r2, r1, target);
@@ -79207,10 +79710,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
}
case TK_BITNOT:
case TK_NOT: {
- assert( TK_BITNOT==OP_BitNot );
- assert( TK_NOT==OP_Not );
- testcase( op==TK_BITNOT );
- testcase( op==TK_NOT );
+ assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT );
+ assert( TK_NOT==OP_Not ); testcase( op==TK_NOT );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
testcase( regFree1==0 );
inReg = target;
@@ -79220,14 +79721,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
case TK_ISNULL:
case TK_NOTNULL: {
int addr;
- assert( TK_ISNULL==OP_IsNull );
- assert( TK_NOTNULL==OP_NotNull );
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
+ assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
+ assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
testcase( regFree1==0 );
addr = sqlite3VdbeAddOp1(v, op, r1);
+ VdbeCoverageIf(v, op==TK_ISNULL);
+ VdbeCoverageIf(v, op==TK_NOTNULL);
sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
sqlite3VdbeJumpHere(v, addr);
break;
@@ -79248,7 +79749,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
FuncDef *pDef; /* The function definition object */
int nId; /* Length of the function name in bytes */
const char *zId; /* The function name */
- int constMask = 0; /* Mask of function arguments that are constant */
+ u32 constMask = 0; /* Mask of function arguments that are constant */
int i; /* Loop counter */
u8 enc = ENC(db); /* The text encoding used by this database */
CollSeq *pColl = 0; /* A collating sequence */
@@ -79279,6 +79780,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
for(i=1; i<nFarg; i++){
sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
+ VdbeCoverage(v);
sqlite3ExprCacheRemove(pParse, target, 1);
sqlite3ExprCachePush(pParse);
sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
@@ -79299,7 +79801,8 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
for(i=0; i<nFarg; i++){
if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
- constMask |= (1<<i);
+ testcase( i==31 );
+ constMask |= MASKBIT32(i);
}
if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
@@ -79415,13 +79918,14 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
r3 = sqlite3GetTempReg(pParse);
r4 = sqlite3GetTempReg(pParse);
codeCompare(pParse, pLeft, pRight, OP_Ge,
- r1, r2, r3, SQLITE_STOREP2);
+ r1, r2, r3, SQLITE_STOREP2); VdbeCoverage(v);
pLItem++;
pRight = pLItem->pExpr;
sqlite3ReleaseTempReg(pParse, regFree2);
r2 = sqlite3ExprCodeTemp(pParse, pRight, &regFree2);
testcase( regFree2==0 );
codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
+ VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
sqlite3ReleaseTempReg(pParse, r3);
sqlite3ReleaseTempReg(pParse, r4);
@@ -79588,6 +80092,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
if( pExpr->affinity==OE_Ignore ){
sqlite3VdbeAddOp4(
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
+ VdbeCoverage(v);
}else{
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
pExpr->affinity, pExpr->u.zToken, 0, 0);
@@ -79675,7 +80180,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
** results in register target. The results are guaranteed to appear
** in register target.
*/
-SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
+SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
int inReg;
assert( target>0 && target<=pParse->nMem );
@@ -79688,7 +80193,20 @@ SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
sqlite3VdbeAddOp2(pParse->pVdbe, OP_SCopy, inReg, target);
}
}
- return target;
+}
+
+/*
+** Generate code that will evaluate expression pExpr and store the
+** results in register target. The results are guaranteed to appear
+** in register target. If the expression is constant, then this routine
+** might choose to code the expression at initialization time.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
+ if( pParse->okConstFactor && sqlite3ExprIsConstant(pExpr) ){
+ sqlite3ExprCodeAtInit(pParse, pExpr, target, 0);
+ }else{
+ sqlite3ExprCode(pParse, pExpr, target);
+ }
}
/*
@@ -79703,25 +80221,16 @@ SQLITE_PRIVATE int sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){
** times. They are evaluated once and the results of the expression
** are reused.
*/
-SQLITE_PRIVATE int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
+SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){
Vdbe *v = pParse->pVdbe;
- int inReg;
- inReg = sqlite3ExprCode(pParse, pExpr, target);
+ int iMem;
+
assert( target>0 );
- /* The only place, other than this routine, where expressions can be
- ** converted to TK_REGISTER is internal subexpressions in BETWEEN and
- ** CASE operators. Neither ever calls this routine. And this routine
- ** is never called twice on the same expression. Hence it is impossible
- ** for the input to this routine to already be a register. Nevertheless,
- ** it seems prudent to keep the ALWAYS() in case the conditions above
- ** change with future modifications or enhancements. */
- if( ALWAYS(pExpr->op!=TK_REGISTER) ){
- int iMem;
- iMem = ++pParse->nMem;
- sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
- exprToRegister(pExpr, iMem);
- }
- return inReg;
+ assert( pExpr->op!=TK_REGISTER );
+ sqlite3ExprCode(pParse, pExpr, target);
+ iMem = ++pParse->nMem;
+ sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
+ exprToRegister(pExpr, iMem);
}
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
@@ -80029,7 +80538,17 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
- sqlite3VdbeAddOp2(pParse->pVdbe, copyOp, inReg, target+i);
+ VdbeOp *pOp;
+ Vdbe *v = pParse->pVdbe;
+ if( copyOp==OP_Copy
+ && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
+ && pOp->p1+pOp->p3+1==inReg
+ && pOp->p2+pOp->p3+1==target+i
+ ){
+ pOp->p3++;
+ }else{
+ sqlite3VdbeAddOp2(v, copyOp, inReg, target+i);
+ }
}
}
}
@@ -80120,8 +80639,8 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
case TK_AND: {
int d2 = sqlite3VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
sqlite3ExprCachePop(pParse, 1);
@@ -80130,7 +80649,9 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
case TK_OR: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3ExprCachePop(pParse, 1);
break;
}
case TK_NOT: {
@@ -80144,23 +80665,17 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
case TK_GE:
case TK_NE:
case TK_EQ: {
- assert( TK_LT==OP_Lt );
- assert( TK_LE==OP_Le );
- assert( TK_GT==OP_Gt );
- assert( TK_GE==OP_Ge );
- assert( TK_EQ==OP_Eq );
- assert( TK_NE==OP_Ne );
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull);
+ assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -80174,18 +80689,20 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
op = (op==TK_IS) ? TK_EQ : TK_NE;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==TK_EQ);
+ VdbeCoverageIf(v, op==TK_NE);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
- assert( TK_ISNULL==OP_IsNull );
- assert( TK_NOTNULL==OP_NotNull );
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
+ assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL );
+ assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
sqlite3VdbeAddOp2(v, op, r1, dest);
+ VdbeCoverageIf(v, op==TK_ISNULL);
+ VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
@@ -80205,10 +80722,17 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int
}
#endif
default: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
- sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
- testcase( regFree1==0 );
- testcase( jumpIfNull==0 );
+ if( exprAlwaysTrue(pExpr) ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
+ }else if( exprAlwaysFalse(pExpr) ){
+ /* No-op */
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
+ sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
+ VdbeCoverage(v);
+ testcase( regFree1==0 );
+ testcase( jumpIfNull==0 );
+ }
break;
}
}
@@ -80271,14 +80795,16 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
case TK_AND: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqlite3ExprCachePop(pParse, 1);
break;
}
case TK_OR: {
int d2 = sqlite3VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
- sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
+ sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
sqlite3ExprCachePop(pParse, 1);
@@ -80295,17 +80821,17 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
case TK_GE:
case TK_NE:
case TK_EQ: {
- testcase( op==TK_LT );
- testcase( op==TK_LE );
- testcase( op==TK_GT );
- testcase( op==TK_GE );
- testcase( op==TK_EQ );
- testcase( op==TK_NE );
testcase( jumpIfNull==0 );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, &regFree2);
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, jumpIfNull);
+ assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt);
+ assert(TK_LE==OP_Le); testcase(op==OP_Le); VdbeCoverageIf(v,op==OP_Le);
+ assert(TK_GT==OP_Gt); testcase(op==OP_Gt); VdbeCoverageIf(v,op==OP_Gt);
+ assert(TK_GE==OP_Ge); testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge);
+ assert(TK_EQ==OP_Eq); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq);
+ assert(TK_NE==OP_Ne); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
@@ -80319,16 +80845,18 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ;
codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op,
r1, r2, dest, SQLITE_NULLEQ);
+ VdbeCoverageIf(v, op==TK_EQ);
+ VdbeCoverageIf(v, op==TK_NE);
testcase( regFree1==0 );
testcase( regFree2==0 );
break;
}
case TK_ISNULL:
case TK_NOTNULL: {
- testcase( op==TK_ISNULL );
- testcase( op==TK_NOTNULL );
r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
sqlite3VdbeAddOp2(v, op, r1, dest);
+ testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL);
+ testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL);
testcase( regFree1==0 );
break;
}
@@ -80350,10 +80878,17 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int
}
#endif
default: {
- r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
- sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
- testcase( regFree1==0 );
- testcase( jumpIfNull==0 );
+ if( exprAlwaysFalse(pExpr) ){
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
+ }else if( exprAlwaysTrue(pExpr) ){
+ /* no-op */
+ }else{
+ r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
+ sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
+ VdbeCoverage(v);
+ testcase( regFree1==0 );
+ testcase( jumpIfNull==0 );
+ }
break;
}
}
@@ -80897,8 +81432,8 @@ static void renameTableFunc(
assert( len>0 );
} while( token!=TK_LP && token!=TK_USING );
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
- zTableName, tname.z+tname.n);
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+ zSql, zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -80950,7 +81485,7 @@ static void renameParentFunc(
sqlite3Dequote(zParent);
if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){
char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"",
- (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
+ (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew
);
sqlite3DbFree(db, zOutput);
zOutput = zOut;
@@ -81036,8 +81571,8 @@ static void renameTriggerFunc(
/* Variable tname now contains the token that is the old table-name
** in the CREATE TRIGGER statement.
*/
- zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql,
- zTableName, tname.z+tname.n);
+ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql),
+ zSql, zTableName, tname.z+tname.n);
sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC);
}
}
@@ -81289,7 +81824,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable(
}
#endif
- /* Begin a transaction and code the VerifyCookie for database iDb.
+ /* Begin a transaction for database iDb.
** Then modify the schema cookie (since the ALTER TABLE modifies the
** schema). Open a statement transaction if the table is a virtual
** table.
@@ -81425,6 +81960,7 @@ SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minForm
sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
sqlite3VdbeJumpHere(v, j1);
sqlite3ReleaseTempReg(pParse, r1);
@@ -82725,6 +83261,7 @@ static void analyzeOneTable(
**
*/
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
+ VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto);
@@ -82746,6 +83283,7 @@ static void analyzeOneTable(
aGotoChng[i] =
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
+ VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng);
aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto);
@@ -82792,7 +83330,7 @@ static void analyzeOneTable(
sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp);
sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, 2+IsStat34);
- sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow);
+ sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
/* Add the entry to the stat1 table. */
callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
@@ -82819,10 +83357,15 @@ static void analyzeOneTable(
addrNext = sqlite3VdbeCurrentAddr(v);
callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
+ VdbeCoverage(v);
callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
callStatGet(v, regStat4, STAT_GET_NLT, regLt);
callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
+ /* We know that the regSampleRowid row exists because it was read by
+ ** the previous loop. Thus the not-found jump of seekOp will never
+ ** be taken */
+ VdbeCoverageNeverTaken(v);
#ifdef SQLITE_ENABLE_STAT3
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
pIdx->aiColumn[0], regSample);
@@ -82833,10 +83376,10 @@ static void analyzeOneTable(
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
#endif
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
+ sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
sqlite3VdbeJumpHere(v, addrIsNull);
}
#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
@@ -82853,7 +83396,7 @@ static void analyzeOneTable(
if( pOnlyIdx==0 && needTableCnt ){
VdbeComment((v, "%s", pTab->zName));
sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
- jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
+ jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
@@ -83453,10 +83996,6 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
if( pExpr ){
if( pExpr->op!=TK_ID ){
rc = sqlite3ResolveExprNames(pName, pExpr);
- if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
- sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
- return SQLITE_ERROR;
- }
}else{
pExpr->op = TK_STRING;
}
@@ -84386,6 +84925,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
assert( !pParse->isMultiWrite
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
+ while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
sqlite3VdbeAddOp0(v, OP_Halt);
/* The cookie mask contains one bit for each database file open.
@@ -84394,20 +84934,22 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
** transaction on each used database and to verify the schema cookie
** on each used database.
*/
- if( pParse->cookieGoto>0 ){
+ if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){
yDbMask mask;
- int iDb, i, addr;
- sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
+ int iDb, i;
+ assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
+ sqlite3VdbeJumpHere(v, 0);
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
if( (mask & pParse->cookieMask)==0 ) continue;
sqlite3VdbeUsesBtree(v, iDb);
- sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
- if( db->init.busy==0 ){
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- sqlite3VdbeAddOp3(v, OP_VerifyCookie,
- iDb, pParse->cookieValue[iDb],
- db->aDb[iDb].pSchema->iGeneration);
- }
+ sqlite3VdbeAddOp4Int(v,
+ OP_Transaction, /* Opcode */
+ iDb, /* P1 */
+ (mask & pParse->writeMask)!=0, /* P2 */
+ pParse->cookieValue[iDb], /* P3 */
+ db->aDb[iDb].pSchema->iGeneration /* P4 */
+ );
+ if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
for(i=0; i<pParse->nVtabLock; i++){
@@ -84428,17 +84970,16 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
sqlite3AutoincrementBegin(pParse);
/* Code constant expressions that where factored out of inner loops */
- addr = pParse->cookieGoto;
if( pParse->pConstExpr ){
ExprList *pEL = pParse->pConstExpr;
- pParse->cookieGoto = 0;
+ pParse->okConstFactor = 0;
for(i=0; i<pEL->nExpr; i++){
sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
}
}
/* Finally, jump back to the beginning of the executable code. */
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, 1);
}
}
@@ -84461,7 +85002,6 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
pParse->nSet = 0;
pParse->nVar = 0;
pParse->cookieMask = 0;
- pParse->cookieGoto = 0;
}
/*
@@ -85193,7 +85733,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
reg3 = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
- j1 = sqlite3VdbeAddOp1(v, OP_If, reg3);
+ j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
1 : SQLITE_MAX_FILE_FORMAT;
sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
@@ -85697,10 +86237,10 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){
for(j=0; zIdent[j]; j++){
if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
}
- needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
- if( !needQuote ){
- needQuote = zIdent[j];
- }
+ needQuote = sqlite3Isdigit(zIdent[0])
+ || sqlite3KeywordCode(zIdent, j)!=TK_ID
+ || zIdent[j]!=0
+ || j==0;
if( needQuote ) z[i++] = '"';
for(j=0; zIdent[j]; j++){
@@ -86920,27 +87460,27 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
/* Open the table. Loop through all rows of the table, inserting index
** records into the sorter. */
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v);
regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 0, &iPartIdxLabel);
+ sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
+ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb);
sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb,
(char *)pKey, P4_KEYINFO);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0));
- addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
+ addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v);
assert( pKey!=0 || db->mallocFailed || pParse->nErr );
if( pIndex->onError!=OE_None && pKey!=0 ){
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
addr2 = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
- pKey->nField - pIndex->nKeyCol);
+ pKey->nField - pIndex->nKeyCol); VdbeCoverage(v);
sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
}else{
addr2 = sqlite3VdbeCurrentAddr(v);
@@ -86949,7 +87489,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3ReleaseTempReg(pParse, regRecord);
- sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2);
+ sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp1(v, OP_Close, iTab);
@@ -87718,7 +88258,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
assert( iStart<=pSrc->nSrc );
/* Allocate additional space if needed */
- if( pSrc->nSrc+nExtra>pSrc->nAlloc ){
+ if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
SrcList *pNew;
int nAlloc = pSrc->nSrc+nExtra;
int nGot;
@@ -87730,7 +88270,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
}
pSrc = pNew;
nGot = (sqlite3DbMallocSize(db, pNew) - sizeof(*pSrc))/sizeof(pSrc->a[0])+1;
- pSrc->nAlloc = (u8)nGot;
+ pSrc->nAlloc = nGot;
}
/* Move existing slots that come after the newly inserted slots
@@ -87738,7 +88278,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(
for(i=pSrc->nSrc-1; i>=iStart; i--){
pSrc->a[i+nExtra] = pSrc->a[i];
}
- pSrc->nSrc += (i8)nExtra;
+ pSrc->nSrc += nExtra;
/* Zero the newly allocated slots */
memset(&pSrc->a[iStart], 0, sizeof(pSrc->a[0])*nExtra);
@@ -88070,59 +88610,26 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){
}
/*
-** Generate VDBE code that will verify the schema cookie and start
-** a read-transaction for all named database files.
-**
-** It is important that all schema cookies be verified and all
-** read transactions be started before anything else happens in
-** the VDBE program. But this routine can be called after much other
-** code has been generated. So here is what we do:
-**
-** The first time this routine is called, we code an OP_Goto that
-** will jump to a subroutine at the end of the program. Then we
-** record every database that needs its schema verified in the
-** pParse->cookieMask field. Later, after all other code has been
-** generated, the subroutine that does the cookie verifications and
-** starts the transactions will be coded and the OP_Goto P2 value
-** will be made to point to that subroutine. The generation of the
-** cookie verification subroutine code happens in sqlite3FinishCoding().
-**
-** If iDb<0 then code the OP_Goto only - don't set flag to verify the
-** schema on any databases. This can be used to position the OP_Goto
-** early in the code, before we know if any database tables will be used.
+** Record the fact that the schema cookie will need to be verified
+** for database iDb. The code to actually verify the schema cookie
+** will occur at the end of the top-level VDBE and will be generated
+** later, by sqlite3FinishCoding().
*/
SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse);
+ sqlite3 *db = pToplevel->db;
+ yDbMask mask;
-#ifndef SQLITE_OMIT_TRIGGER
- if( pToplevel!=pParse ){
- /* This branch is taken if a trigger is currently being coded. In this
- ** case, set cookieGoto to a non-zero value to show that this function
- ** has been called. This is used by the sqlite3ExprCodeConstants()
- ** function. */
- pParse->cookieGoto = -1;
- }
-#endif
- if( pToplevel->cookieGoto==0 ){
- Vdbe *v = sqlite3GetVdbe(pToplevel);
- if( v==0 ) return; /* This only happens if there was a prior error */
- pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1;
- }
- if( iDb>=0 ){
- sqlite3 *db = pToplevel->db;
- yDbMask mask;
-
- assert( iDb<db->nDb );
- assert( db->aDb[iDb].pBt!=0 || iDb==1 );
- assert( iDb<SQLITE_MAX_ATTACHED+2 );
- assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
- mask = ((yDbMask)1)<<iDb;
- if( (pToplevel->cookieMask & mask)==0 ){
- pToplevel->cookieMask |= mask;
- pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
- if( !OMIT_TEMPDB && iDb==1 ){
- sqlite3OpenTempDatabase(pToplevel);
- }
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( db->aDb[iDb].pBt!=0 || iDb==1 );
+ assert( iDb<SQLITE_MAX_ATTACHED+2 );
+ assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
+ mask = ((yDbMask)1)<<iDb;
+ if( (pToplevel->cookieMask & mask)==0 ){
+ pToplevel->cookieMask |= mask;
+ pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
+ if( !OMIT_TEMPDB && iDb==1 ){
+ sqlite3OpenTempDatabase(pToplevel);
}
}
}
@@ -88235,9 +88742,9 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint(
for(j=0; j<pIdx->nKeyCol; j++){
char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
- sqlite3StrAccumAppend(&errMsg, pTab->zName, -1);
+ sqlite3StrAccumAppendAll(&errMsg, pTab->zName);
sqlite3StrAccumAppend(&errMsg, ".", 1);
- sqlite3StrAccumAppend(&errMsg, zCol, -1);
+ sqlite3StrAccumAppendAll(&errMsg, zCol);
}
zErr = sqlite3StrAccumFinish(&errMsg);
sqlite3HaltConstraint(pParse,
@@ -88429,8 +88936,9 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
assert( sqlite3KeyInfoIsWriteable(pKey) );
for(i=0; i<nCol; i++){
char *zColl = pIdx->azColl[i];
- if( NEVER(zColl==0) ) zColl = "BINARY";
- pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
+ assert( zColl!=0 );
+ pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
+ sqlite3LocateCollSeq(pParse, zColl);
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
}
if( pParse->nErr ){
@@ -88443,6 +88951,76 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
return sqlite3KeyInfoRef(pIdx->pKeyInfo);
}
+#ifndef SQLITE_OMIT_CTE
+/*
+** This routine is invoked once per CTE by the parser while parsing a
+** WITH clause.
+*/
+SQLITE_PRIVATE With *sqlite3WithAdd(
+ Parse *pParse, /* Parsing context */
+ With *pWith, /* Existing WITH clause, or NULL */
+ Token *pName, /* Name of the common-table */
+ ExprList *pArglist, /* Optional column name list for the table */
+ Select *pQuery /* Query used to initialize the table */
+){
+ sqlite3 *db = pParse->db;
+ With *pNew;
+ char *zName;
+
+ /* Check that the CTE name is unique within this WITH clause. If
+ ** not, store an error in the Parse structure. */
+ zName = sqlite3NameFromToken(pParse->db, pName);
+ if( zName && pWith ){
+ int i;
+ for(i=0; i<pWith->nCte; i++){
+ if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){
+ sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName);
+ }
+ }
+ }
+
+ if( pWith ){
+ int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
+ pNew = sqlite3DbRealloc(db, pWith, nByte);
+ }else{
+ pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
+ }
+ assert( zName!=0 || pNew==0 );
+ assert( db->mallocFailed==0 || pNew==0 );
+
+ if( pNew==0 ){
+ sqlite3ExprListDelete(db, pArglist);
+ sqlite3SelectDelete(db, pQuery);
+ sqlite3DbFree(db, zName);
+ pNew = pWith;
+ }else{
+ pNew->a[pNew->nCte].pSelect = pQuery;
+ pNew->a[pNew->nCte].pCols = pArglist;
+ pNew->a[pNew->nCte].zName = zName;
+ pNew->a[pNew->nCte].zErr = 0;
+ pNew->nCte++;
+ }
+
+ return pNew;
+}
+
+/*
+** Free the contents of the With object passed as the second argument.
+*/
+SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){
+ if( pWith ){
+ int i;
+ for(i=0; i<pWith->nCte; i++){
+ struct Cte *pCte = &pWith->a[i];
+ sqlite3ExprListDelete(db, pCte->pCols);
+ sqlite3SelectDelete(db, pCte->pSelect);
+ sqlite3DbFree(db, pCte->zName);
+ }
+ sqlite3DbFree(db, pWith);
+ }
+}
+#endif /* !defined(SQLITE_OMIT_CTE) */
+
/************** End of build.c ***********************************************/
/************** Begin file callback.c ****************************************/
/*
@@ -88803,7 +89381,6 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction(
assert( nArg>=(-2) );
assert( nArg>=(-1) || createFlag==0 );
- assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE );
h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a);
/* First search for a match amongst the application-defined functions.
@@ -89023,10 +89600,8 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
SrcList *pFrom;
sqlite3 *db = pParse->db;
int iDb = sqlite3SchemaToIndex(db, pView->pSchema);
-
pWhere = sqlite3ExprDup(db, pWhere, 0);
pFrom = sqlite3SrcListAppend(db, 0, 0, 0);
-
if( pFrom ){
assert( pFrom->nSrc==1 );
pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName);
@@ -89034,10 +89609,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
assert( pFrom->a[0].pOn==0 );
assert( pFrom->a[0].pUsing==0 );
}
-
pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
- if( pSel ) pSel->selFlags |= SF_Materialize;
-
sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
sqlite3Select(pParse, pSel, &dest);
sqlite3SelectDelete(db, pSel);
@@ -89374,7 +89946,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
iKey = ++pParse->nMem;
nKey = 0; /* Zero tells OP_Found to use a composite key */
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey,
- sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+ sqlite3IndexAffinityStr(v, pPk), nPk);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey);
}else{
/* Get the rowid of the row to be deleted and remember it in the RowSet */
@@ -89412,13 +89984,15 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
if( aToOpen[iDataCur-iTabCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
+ VdbeCoverage(v);
}
}else if( pPk ){
- addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur);
+ addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
assert( nKey==0 ); /* OP_Found will use a composite key */
}else{
addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey);
+ VdbeCoverage(v);
assert( nKey==1 );
}
@@ -89442,7 +90016,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
if( okOnePass ){
sqlite3VdbeResolveLabel(v, addrBypass);
}else if( pPk ){
- sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1);
+ sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrLoop);
}else{
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop);
@@ -89540,7 +90114,11 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
** not attempt to delete it or fire any DELETE triggers. */
iLabel = sqlite3VdbeMakeLabel(v);
opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
- if( !bNoSeek ) sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ if( !bNoSeek ){
+ sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ VdbeCoverageIf(v, opSeek==OP_NotExists);
+ VdbeCoverageIf(v, opSeek==OP_NotFound);
+ }
/* If there are any triggers to fire, allocate a range of registers to
** use for the old.* references in the triggers. */
@@ -89562,7 +90140,9 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
** used by any BEFORE and AFTER triggers that exist. */
sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld);
for(iCol=0; iCol<pTab->nCol; iCol++){
- if( mask==0xffffffff || mask&(1<<iCol) ){
+ testcase( mask!=0xffffffff && iCol==31 );
+ testcase( mask!=0xffffffff && iCol==32 );
+ if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+iCol+1);
}
}
@@ -89580,6 +90160,8 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete(
*/
if( addrStart<sqlite3VdbeCurrentAddr(v) ){
sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
+ VdbeCoverageIf(v, opSeek==OP_NotExists);
+ VdbeCoverageIf(v, opSeek==OP_NotFound);
}
/* Do FK processing. This call checks that any FK constraints that
@@ -89642,9 +90224,10 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
int i; /* Index loop counter */
- int r1; /* Register holding an index key */
+ int r1 = -1; /* Register holding an index key */
int iPartIdxLabel; /* Jump destination for skipping partial index entries */
Index *pIdx; /* Current index */
+ Index *pPrior = 0; /* Prior index */
Vdbe *v; /* The prepared statement under construction */
Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */
@@ -89655,10 +90238,12 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
if( pIdx==pPk ) continue;
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel);
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
+ &iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
+ pPrior = pIdx;
}
}
@@ -89680,6 +90265,17 @@ SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(
** to false or null. If pIdx is not a partial index, *piPartIdxLabel
** will be set to zero which is an empty label that is ignored by
** sqlite3VdbeResolveLabel().
+**
+** The pPrior and regPrior parameters are used to implement a cache to
+** avoid unnecessary register loads. If pPrior is not NULL, then it is
+** a pointer to a different index for which an index key has just been
+** computed into register regPrior. If the current pIdx index is generating
+** its key into the same sequence of registers and if pPrior and pIdx share
+** a column in common, then the register corresponding to that column already
+** holds the correct value and the loading of that register is skipped.
+** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK
+** on a table with multiple indices, and especially with the ROWID or
+** PRIMARY KEY columns of the index.
*/
SQLITE_PRIVATE int sqlite3GenerateIndexKey(
Parse *pParse, /* Parsing context */
@@ -89687,14 +90283,15 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
int iDataCur, /* Cursor number from which to take column data */
int regOut, /* Put the new key into this register if not 0 */
int prefixOnly, /* Compute only a unique prefix of the key */
- int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
+ int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */
+ Index *pPrior, /* Previously generated index key */
+ int regPrior /* Register holding previous generated key */
){
Vdbe *v = pParse->pVdbe;
int j;
Table *pTab = pIdx->pTable;
int regBase;
int nCol;
- Index *pPk;
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
@@ -89708,28 +90305,21 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey(
}
nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
regBase = sqlite3GetTempRange(pParse, nCol);
- pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
+ if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
for(j=0; j<nCol; j++){
- i16 idx = pIdx->aiColumn[j];
- if( pPk ) idx = sqlite3ColumnOfIndex(pPk, idx);
- if( idx<0 || idx==pTab->iPKey ){
- sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regBase+j);
- }else{
- sqlite3VdbeAddOp3(v, OP_Column, iDataCur, idx, regBase+j);
- sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[j], -1);
- }
+ if( pPrior && pPrior->aiColumn[j]==pIdx->aiColumn[j] ) continue;
+ sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j],
+ regBase+j);
+ /* If the column affinity is REAL but the number is an integer, then it
+ ** might be stored in the table as an integer (using a compact
+ ** representation) then converted to REAL by an OP_RealAffinity opcode.
+ ** But we are getting ready to store this value back into an index, where
+ ** it should be converted by to INTEGER again. So omit the OP_RealAffinity
+ ** opcode if it is present */
+ sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);
}
if( regOut ){
- const char *zAff;
- if( pTab->pSelect
- || OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
- ){
- zAff = 0;
- }else{
- zAff = sqlite3IndexAffinityStr(v, pIdx);
- }
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
- sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
}
sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
@@ -89874,7 +90464,7 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
case SQLITE_INTEGER: {
i64 iVal = sqlite3_value_int64(argv[0]);
if( iVal<0 ){
- if( (iVal<<1)==0 ){
+ if( iVal==SMALLEST_INT64 ){
/* IMP: R-31676-45509 If X is the integer -9223372036854775808
** then abs(X) throws an integer overflow error since there is no
** equivalent positive 64-bit two complement value. */
@@ -89956,6 +90546,32 @@ static void instrFunc(
}
/*
+** Implementation of the printf() function.
+*/
+static void printfFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ PrintfArguments x;
+ StrAccum str;
+ const char *zFormat;
+ int n;
+
+ if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
+ x.nArg = argc-1;
+ x.nUsed = 0;
+ x.apArg = argv+1;
+ sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH);
+ str.db = sqlite3_context_db_handle(context);
+ sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
+ n = str.nChar;
+ sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
+ SQLITE_DYNAMIC);
+ }
+}
+
+/*
** Implementation of the substr() function.
**
** substr(x,p1,p2) returns p2 characters of x[] beginning with p1.
@@ -90728,7 +91344,7 @@ static void charFunc(
){
unsigned char *z, *zOut;
int i;
- zOut = z = sqlite3_malloc( argc*4 );
+ zOut = z = sqlite3_malloc( argc*4+1 );
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
@@ -91248,11 +91864,11 @@ static void groupConcatStep(
zSep = ",";
nSep = 1;
}
- sqlite3StrAccumAppend(pAccum, zSep, nSep);
+ if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
}
zVal = (char*)sqlite3_value_text(argv[0]);
nVal = sqlite3_value_bytes(argv[0]);
- sqlite3StrAccumAppend(pAccum, zVal, nVal);
+ if( nVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
}
}
static void groupConcatFinalize(sqlite3_context *context){
@@ -91385,6 +92001,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
FUNCTION(instr, 2, 0, 0, instrFunc ),
FUNCTION(substr, 2, 0, 0, substrFunc ),
FUNCTION(substr, 3, 0, 0, substrFunc ),
+ FUNCTION(printf, -1, 0, 0, printfFunc ),
FUNCTION(unicode, 1, 0, 0, unicodeFunc ),
FUNCTION(char, -1, 0, 0, charFunc ),
FUNCTION(abs, 1, 0, 0, absFunc ),
@@ -91802,10 +92419,11 @@ static void fkLookupParent(
** search for a matching row in the parent table. */
if( nIncr<0 ){
sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk);
+ VdbeCoverage(v);
}
for(i=0; i<pFKey->nCol; i++){
int iReg = aiCol[i] + regData + 1;
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk);
+ sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v);
}
if( isIgnore==0 ){
@@ -91822,17 +92440,19 @@ static void fkLookupParent(
** will have INTEGER affinity applied to it, which may not be correct. */
sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp);
iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0);
+ VdbeCoverage(v);
/* If the parent table is the same as the child table, and we are about
** to increment the constraint-counter (i.e. this is an INSERT operation),
** then check if the row being inserted matches itself. If so, do not
** increment the constraint-counter. */
if( pTab==pFKey->pFrom && nIncr==1 ){
- sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp);
+ sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
}
sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead);
- sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp);
+ sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
sqlite3VdbeJumpHere(v, iMustBeInt);
@@ -91868,15 +92488,15 @@ static void fkLookupParent(
/* The parent key is a composite key that includes the IPK column */
iParent = regData;
}
- sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
+ sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
}
sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
}
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
- sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec,
+ sqlite3IndexAffinityStr(v,pIdx), nCol);
+ sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
@@ -92014,6 +92634,7 @@ static void fkScanChildren(
if( nIncr<0 ){
iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0);
+ VdbeCoverage(v);
}
/* Create an Expr object representing an SQL expression like:
@@ -92176,7 +92797,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
}
if( !p ) return;
iSkip = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip);
+ sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
}
pParse->disableTriggers = 1;
@@ -92194,6 +92815,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa
*/
if( (db->flags & SQLITE_DeferFKs)==0 ){
sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
}
@@ -92353,7 +92975,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
for(i=0; i<pFKey->nCol; i++){
int iReg = pFKey->aCol[i].iFrom + regOld + 1;
- sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump);
+ sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
}
@@ -92920,10 +93542,16 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
}
/*
-** Set P4 of the most recently inserted opcode to a column affinity
-** string for table pTab. A column affinity string has one character
-** for each column indexed by the index, according to the affinity of the
-** column:
+** Compute the affinity string for table pTab, if it has not already been
+** computed. As an optimization, omit trailing SQLITE_AFF_NONE affinities.
+**
+** If the affinity exists (if it is no entirely SQLITE_AFF_NONE values) and
+** if iReg>0 then code an OP_Affinity opcode that will set the affinities
+** for register iReg and following. Or if affinities exists and iReg==0,
+** then just set the P4 operand of the previous opcode (which should be
+** an OP_MakeRecord) to the affinity string.
+**
+** A column affinity string has one character per column:
**
** Character Column affinity
** ------------------------------
@@ -92933,19 +93561,11 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
** 'd' INTEGER
** 'e' REAL
*/
-SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
- /* The first time a column affinity string for a particular table
- ** is required, it is allocated and populated here. It is then
- ** stored as a member of the Table structure for subsequent use.
- **
- ** The column affinity string will eventually be deleted by
- ** sqlite3DeleteTable() when the Table structure itself is cleaned up.
- */
- if( !pTab->zColAff ){
- char *zColAff;
- int i;
+SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
+ int i;
+ char *zColAff = pTab->zColAff;
+ if( zColAff==0 ){
sqlite3 *db = sqlite3VdbeDb(v);
-
zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
if( !zColAff ){
db->mallocFailed = 1;
@@ -92955,22 +93575,28 @@ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){
for(i=0; i<pTab->nCol; i++){
zColAff[i] = pTab->aCol[i].affinity;
}
- zColAff[pTab->nCol] = '\0';
-
+ do{
+ zColAff[i--] = 0;
+ }while( i>=0 && zColAff[i]==SQLITE_AFF_NONE );
pTab->zColAff = zColAff;
}
-
- sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT);
+ i = sqlite3Strlen30(zColAff);
+ if( i ){
+ if( iReg ){
+ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
+ }else{
+ sqlite3VdbeChangeP4(v, -1, zColAff, i);
+ }
+ }
}
/*
** Return non-zero if the table pTab in database iDb or any of its indices
-** have been opened at any point in the VDBE program beginning at location
-** iStartAddr throught the end of the program. This is used to see if
+** have been opened at any point in the VDBE program. This is used to see if
** a statement of the form "INSERT INTO <iDb, pTab> SELECT ..." can
-** run without using temporary table for the results of the SELECT.
+** run without using a temporary table for the results of the SELECT.
*/
-static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
+static int readsTable(Parse *p, int iDb, Table *pTab){
Vdbe *v = sqlite3GetVdbe(p);
int i;
int iEnd = sqlite3VdbeCurrentAddr(v);
@@ -92978,7 +93604,7 @@ static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){
VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0;
#endif
- for(i=iStartAddr; i<iEnd; i++){
+ for(i=1; i<iEnd; i++){
VdbeOp *pOp = sqlite3VdbeGetOp(v, i);
assert( pOp!=0 );
if( pOp->opcode==OP_OpenRead && pOp->p3==iDb ){
@@ -93079,14 +93705,14 @@ SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){
sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1);
addr = sqlite3VdbeCurrentAddr(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
+ sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
- sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
+ sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
- sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2);
+ sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
sqlite3VdbeAddOp0(v, OP_Close);
}
@@ -93121,25 +93747,16 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
assert( v );
for(p = pParse->pAinc; p; p = p->pNext){
Db *pDb = &db->aDb[p->iDb];
- int j1, j2, j3, j4, j5;
+ int j1;
int iRec;
int memId = p->regCtr;
iRec = sqlite3GetTempReg(pParse);
assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
- j2 = sqlite3VdbeAddOp0(v, OP_Rewind);
- j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
- j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec);
- sqlite3VdbeAddOp2(v, OP_Next, 0, j3);
- sqlite3VdbeJumpHere(v, j2);
+ j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
- j5 = sqlite3VdbeAddOp0(v, OP_Goto);
- sqlite3VdbeJumpHere(v, j4);
- sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1);
sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeJumpHere(v, j5);
sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -93157,97 +93774,6 @@ SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){
#endif /* SQLITE_OMIT_AUTOINCREMENT */
-/*
-** Generate code for a co-routine that will evaluate a subquery one
-** row at a time.
-**
-** The pSelect parameter is the subquery that the co-routine will evaluation.
-** Information about the location of co-routine and the registers it will use
-** is returned by filling in the pDest object.
-**
-** Registers are allocated as follows:
-**
-** pDest->iSDParm The register holding the next entry-point of the
-** co-routine. Run the co-routine to its next breakpoint
-** by calling "OP_Yield $X" where $X is pDest->iSDParm.
-**
-** pDest->iSDParm+1 The register holding the "completed" flag for the
-** co-routine. This register is 0 if the previous Yield
-** generated a new result row, or 1 if the subquery
-** has completed. If the Yield is called again
-** after this register becomes 1, then the VDBE will
-** halt with an SQLITE_INTERNAL error.
-**
-** pDest->iSdst First result register.
-**
-** pDest->nSdst Number of result registers.
-**
-** This routine handles all of the register allocation and fills in the
-** pDest structure appropriately.
-**
-** Here is a schematic of the generated code assuming that X is the
-** co-routine entry-point register reg[pDest->iSDParm], that EOF is the
-** completed flag reg[pDest->iSDParm+1], and R and S are the range of
-** registers that hold the result set, reg[pDest->iSdst] through
-** reg[pDest->iSdst+pDest->nSdst-1]:
-**
-** X <- A
-** EOF <- 0
-** goto B
-** A: setup for the SELECT
-** loop rows in the SELECT
-** load results into registers R..S
-** yield X
-** end loop
-** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** halt-error
-** B:
-**
-** To use this subroutine, the caller generates code as follows:
-**
-** [ Co-routine generated by this subroutine, shown above ]
-** S: yield X
-** if EOF goto E
-** if skip this row, goto C
-** if terminate loop, goto E
-** deal with this row
-** C: goto S
-** E:
-*/
-SQLITE_PRIVATE int sqlite3CodeCoroutine(Parse *pParse, Select *pSelect, SelectDest *pDest){
- int regYield; /* Register holding co-routine entry-point */
- int regEof; /* Register holding co-routine completion flag */
- int addrTop; /* Top of the co-routine */
- int j1; /* Jump instruction */
- int rc; /* Result code */
- Vdbe *v; /* VDBE under construction */
-
- regYield = ++pParse->nMem;
- regEof = ++pParse->nMem;
- v = sqlite3GetVdbe(pParse);
- addrTop = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_Integer, addrTop+2, regYield); /* X <- A */
- VdbeComment((v, "Co-routine entry point"));
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */
- VdbeComment((v, "Co-routine completion flag"));
- sqlite3SelectDestInit(pDest, SRT_Coroutine, regYield);
- j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
- rc = sqlite3Select(pParse, pSelect, pDest);
- assert( pParse->nErr==0 || rc );
- if( pParse->db->mallocFailed && rc==SQLITE_OK ) rc = SQLITE_NOMEM;
- if( rc ) return rc;
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */
- sqlite3VdbeAddOp1(v, OP_Yield, regYield); /* yield X */
- sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
- VdbeComment((v, "End of coroutine"));
- sqlite3VdbeJumpHere(v, j1); /* label B: */
- return rc;
-}
-
-
-
/* Forward declaration */
static int xferOptimization(
Parse *pParse, /* Parser context */
@@ -93310,7 +93836,6 @@ static int xferOptimization(
** and the SELECT clause does not read from <table> at any time.
** The generated code follows this template:
**
-** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
@@ -93319,12 +93844,9 @@ static int xferOptimization(
** yield X
** end loop
** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** goto A
+** end-coroutine X
** B: open write cursor to <table> and its indices
-** C: yield X
-** if EOF goto D
+** C: yield X, at EOF goto D
** insert the select result into <table> from R..R+n
** goto C
** D: cleanup
@@ -93335,7 +93857,6 @@ static int xferOptimization(
** we have to use a intermediate table to store the results of
** the select. The template is like this:
**
-** EOF <- 0
** X <- A
** goto B
** A: setup for the SELECT
@@ -93344,12 +93865,9 @@ static int xferOptimization(
** yield X
** end loop
** cleanup after the SELECT
-** EOF <- 1
-** yield X
-** halt-error
+** end co-routine R
** B: open temp table
-** L: yield X
-** if EOF goto M
+** L: yield X, at EOF goto M
** insert row from R..R+n into temp table
** goto L
** M: open write cursor to <table> and its indices
@@ -93362,7 +93880,6 @@ static int xferOptimization(
SQLITE_PRIVATE void sqlite3Insert(
Parse *pParse, /* Parser context */
SrcList *pTabList, /* Name of table into which we are inserting */
- ExprList *pList, /* List of values to be inserted */
Select *pSelect, /* A SELECT statement to use as the data source */
IdList *pColumn, /* Column names corresponding to IDLIST. */
int onError /* How to handle constraint errors */
@@ -93380,16 +93897,17 @@ SQLITE_PRIVATE void sqlite3Insert(
int iIdxCur = 0; /* First index cursor */
int ipkColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
int endOfLoop; /* Label for the end of the insertion loop */
- int useTempTable = 0; /* Store SELECT results in intermediate table */
int srcTab = 0; /* Data comes from this temporary cursor if >=0 */
int addrInsTop = 0; /* Jump to label "D" */
int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */
- int addrSelect = 0; /* Address of coroutine that implements the SELECT */
SelectDest dest; /* Destination for SELECT on rhs of INSERT */
int iDb; /* Index of database holding TABLE */
Db *pDb; /* The database containing table being inserted into */
- int appendFlag = 0; /* True if the insert is likely to be an append */
- int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
+ u8 useTempTable = 0; /* Store SELECT results in intermediate table */
+ u8 appendFlag = 0; /* True if the insert is likely to be an append */
+ u8 withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
+ u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
+ ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
@@ -93398,7 +93916,6 @@ SQLITE_PRIVATE void sqlite3Insert(
int regIns; /* Block of regs holding rowid+data being inserted */
int regRowid; /* registers holding insert rowid */
int regData; /* register holding first column to insert */
- int regEof = 0; /* Register recording end of SELECT data */
int *aRegIdx = 0; /* One register allocated to each index */
#ifndef SQLITE_OMIT_TRIGGER
@@ -93413,6 +93930,17 @@ SQLITE_PRIVATE void sqlite3Insert(
goto insert_cleanup;
}
+ /* If the Select object is really just a simple VALUES() list with a
+ ** single row values (the common case) then keep that one row of values
+ ** and go ahead and discard the Select object
+ */
+ if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
+ pList = pSelect->pEList;
+ pSelect->pEList = 0;
+ sqlite3SelectDelete(db, pSelect);
+ pSelect = 0;
+ }
+
/* Locate the table into which we will be inserting new information.
*/
assert( pTabList->nSrc==1 );
@@ -93490,6 +94018,56 @@ SQLITE_PRIVATE void sqlite3Insert(
*/
regAutoinc = autoIncBegin(pParse, iDb, pTab);
+ /* Allocate registers for holding the rowid of the new row,
+ ** the content of the new row, and the assemblied row record.
+ */
+ regRowid = regIns = pParse->nMem+1;
+ pParse->nMem += pTab->nCol + 1;
+ if( IsVirtual(pTab) ){
+ regRowid++;
+ pParse->nMem++;
+ }
+ regData = regRowid+1;
+
+ /* If the INSERT statement included an IDLIST term, then make sure
+ ** all elements of the IDLIST really are columns of the table and
+ ** remember the column indices.
+ **
+ ** If the table has an INTEGER PRIMARY KEY column and that column
+ ** is named in the IDLIST, then record in the ipkColumn variable
+ ** the index into IDLIST of the primary key column. ipkColumn is
+ ** the index of the primary key as it appears in IDLIST, not as
+ ** is appears in the original table. (The index of the INTEGER
+ ** PRIMARY KEY in the original table is pTab->iPKey.)
+ */
+ if( pColumn ){
+ for(i=0; i<pColumn->nId; i++){
+ pColumn->a[i].idx = -1;
+ }
+ for(i=0; i<pColumn->nId; i++){
+ for(j=0; j<pTab->nCol; j++){
+ if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
+ pColumn->a[i].idx = j;
+ if( i!=j ) bIdListInOrder = 0;
+ if( j==pTab->iPKey ){
+ ipkColumn = i; assert( !withoutRowid );
+ }
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
+ ipkColumn = i;
+ }else{
+ sqlite3ErrorMsg(pParse, "table %S has no column named %s",
+ pTabList, 0, pColumn->a[i].zName);
+ pParse->checkSchema = 1;
+ goto insert_cleanup;
+ }
+ }
+ }
+ }
+
/* Figure out how many columns of data are supplied. If the data
** is coming from a SELECT statement, then generate a co-routine that
** produces a single row of the SELECT on each invocation. The
@@ -93497,14 +94075,24 @@ SQLITE_PRIVATE void sqlite3Insert(
*/
if( pSelect ){
/* Data is coming from a SELECT. Generate a co-routine to run the SELECT */
- int rc = sqlite3CodeCoroutine(pParse, pSelect, &dest);
- if( rc ) goto insert_cleanup;
-
- regEof = dest.iSDParm + 1;
+ int regYield; /* Register holding co-routine entry-point */
+ int addrTop; /* Top of the co-routine */
+ int rc; /* Result code */
+
+ regYield = ++pParse->nMem;
+ addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ dest.iSdst = bIdListInOrder ? regData : 0;
+ dest.nSdst = pTab->nCol;
+ rc = sqlite3Select(pParse, pSelect, &dest);
regFromSelect = dest.iSdst;
+ assert( pParse->nErr==0 || rc );
+ if( rc || db->mallocFailed ) goto insert_cleanup;
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
assert( pSelect->pEList );
nColumn = pSelect->pEList->nExpr;
- assert( dest.nSdst==nColumn );
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
@@ -93515,7 +94103,7 @@ SQLITE_PRIVATE void sqlite3Insert(
** of the tables being read by the SELECT statement. Also use a
** temp table in the case of row triggers.
*/
- if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){
+ if( pTrigger || readsTable(pParse, iDb, pTab) ){
useTempTable = 1;
}
@@ -93525,28 +94113,25 @@ SQLITE_PRIVATE void sqlite3Insert(
** here is from the 4th template:
**
** B: open temp table
- ** L: yield X
- ** if EOF goto M
+ ** L: yield X, goto M at EOF
** insert row from R..R+n into temp table
** goto L
** M: ...
*/
int regRec; /* Register to hold packed record */
int regTempRowid; /* Register to hold temp table ROWID */
- int addrTop; /* Label "L" */
- int addrIf; /* Address of jump to M */
+ int addrL; /* Label "L" */
srcTab = pParse->nTab++;
regRec = sqlite3GetTempReg(pParse);
regTempRowid = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
- addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
- addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
+ addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid);
sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid);
- sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
- sqlite3VdbeJumpHere(v, addrIf);
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrL);
+ sqlite3VdbeJumpHere(v, addrL);
sqlite3ReleaseTempReg(pParse, regRec);
sqlite3ReleaseTempReg(pParse, regTempRowid);
}
@@ -93567,6 +94152,14 @@ SQLITE_PRIVATE void sqlite3Insert(
}
}
+ /* If there is no IDLIST term but the table has an integer primary
+ ** key, the set the ipkColumn variable to the integer primary key
+ ** column index in the original table definition.
+ */
+ if( pColumn==0 && nColumn>0 ){
+ ipkColumn = pTab->iPKey;
+ }
+
/* Make sure the number of columns in the source data matches the number
** of columns to be inserted into the table.
*/
@@ -93585,52 +94178,6 @@ SQLITE_PRIVATE void sqlite3Insert(
sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
goto insert_cleanup;
}
-
- /* If the INSERT statement included an IDLIST term, then make sure
- ** all elements of the IDLIST really are columns of the table and
- ** remember the column indices.
- **
- ** If the table has an INTEGER PRIMARY KEY column and that column
- ** is named in the IDLIST, then record in the ipkColumn variable
- ** the index into IDLIST of the primary key column. ipkColumn is
- ** the index of the primary key as it appears in IDLIST, not as
- ** is appears in the original table. (The index of the INTEGER
- ** PRIMARY KEY in the original table is pTab->iPKey.)
- */
- if( pColumn ){
- for(i=0; i<pColumn->nId; i++){
- pColumn->a[i].idx = -1;
- }
- for(i=0; i<pColumn->nId; i++){
- for(j=0; j<pTab->nCol; j++){
- if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
- pColumn->a[i].idx = j;
- if( j==pTab->iPKey ){
- ipkColumn = i; assert( !withoutRowid );
- }
- break;
- }
- }
- if( j>=pTab->nCol ){
- if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
- ipkColumn = i;
- }else{
- sqlite3ErrorMsg(pParse, "table %S has no column named %s",
- pTabList, 0, pColumn->a[i].zName);
- pParse->checkSchema = 1;
- goto insert_cleanup;
- }
- }
- }
- }
-
- /* If there is no IDLIST term but the table has an integer primary
- ** key, the set the ipkColumn variable to the integer primary key
- ** column index in the original table definition.
- */
- if( pColumn==0 && nColumn>0 ){
- ipkColumn = pTab->iPKey;
- }
/* Initialize the count of rows to be inserted
*/
@@ -93658,39 +94205,27 @@ SQLITE_PRIVATE void sqlite3Insert(
/* This block codes the top of loop only. The complete loop is the
** following pseudocode (template 4):
**
- ** rewind temp table
+ ** rewind temp table, if empty goto D
** C: loop over rows of intermediate table
** transfer values form intermediate table into <table>
** end loop
** D: ...
*/
- addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab);
+ addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v);
addrCont = sqlite3VdbeCurrentAddr(v);
}else if( pSelect ){
/* This block codes the top of loop only. The complete loop is the
** following pseudocode (template 3):
**
- ** C: yield X
- ** if EOF goto D
+ ** C: yield X, at EOF goto D
** insert the select result into <table> from R..R+n
** goto C
** D: ...
*/
- addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
- addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
+ addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
+ VdbeCoverage(v);
}
- /* Allocate registers for holding the rowid of the new row,
- ** the content of the new row, and the assemblied row record.
- */
- regRowid = regIns = pParse->nMem+1;
- pParse->nMem += pTab->nCol + 1;
- if( IsVirtual(pTab) ){
- regRowid++;
- pParse->nMem++;
- }
- regData = regRowid+1;
-
/* Run the BEFORE and INSTEAD OF triggers, if there are any
*/
endOfLoop = sqlite3VdbeMakeLabel(v);
@@ -93714,10 +94249,10 @@ SQLITE_PRIVATE void sqlite3Insert(
assert( pSelect==0 ); /* Otherwise useTempTable is true */
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
}
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols);
+ j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
}
/* Cannot have triggers on a virtual table. If it were possible,
@@ -93751,8 +94286,7 @@ SQLITE_PRIVATE void sqlite3Insert(
** table column affinities.
*/
if( !isView ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
+ sqlite3TableAffinity(v, pTab, regCols+1);
}
/* Fire BEFORE or INSTEAD OF triggers */
@@ -93774,7 +94308,7 @@ SQLITE_PRIVATE void sqlite3Insert(
if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+ipkColumn, regRowid);
+ sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid);
}else{
VdbeOp *pOp;
sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid);
@@ -93793,14 +94327,14 @@ SQLITE_PRIVATE void sqlite3Insert(
if( !appendFlag ){
int j1;
if( !IsVirtual(pTab) ){
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
+ j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
sqlite3VdbeJumpHere(v, j1);
}else{
j1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v);
}
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
}
}else if( IsVirtual(pTab) || withoutRowid ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
@@ -93820,8 +94354,9 @@ SQLITE_PRIVATE void sqlite3Insert(
/* The value of the INTEGER PRIMARY KEY column is always a NULL.
** Whenever this column is read, the rowid will be substituted
** in its place. Hence, fill this column with a NULL to avoid
- ** taking up data space with information that will never be used. */
- sqlite3VdbeAddOp2(v, OP_Null, 0, iRegStore);
+ ** taking up data space with information that will never be used.
+ ** As there may be shallow copies of this value, make it a soft-NULL */
+ sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
continue;
}
if( pColumn==0 ){
@@ -93838,11 +94373,13 @@ SQLITE_PRIVATE void sqlite3Insert(
}
}
if( j<0 || nColumn==0 || (pColumn && j>=pColumn->nId) ){
- sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, iRegStore);
+ sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore);
}else if( useTempTable ){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, iRegStore);
}else if( pSelect ){
- sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
+ if( regFromSelect!=regData ){
+ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+j, iRegStore);
+ }
}else{
sqlite3ExprCode(pParse, pList->a[j].pExpr, iRegStore);
}
@@ -93888,7 +94425,7 @@ SQLITE_PRIVATE void sqlite3Insert(
*/
sqlite3VdbeResolveLabel(v, endOfLoop);
if( useTempTable ){
- sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont);
+ sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrInsTop);
sqlite3VdbeAddOp1(v, OP_Close, srcTab);
}else if( pSelect ){
@@ -94055,6 +94592,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
int ipkTop = 0; /* Top of the rowid change constraint check */
int ipkBottom = 0; /* Bottom of the rowid change constraint check */
u8 isUpdate; /* True if this is an UPDATE operation */
+ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */
+ int regRowid = -1; /* Register holding ROWID value */
isUpdate = regOldData!=0;
db = pParse->db;
@@ -94108,15 +94647,17 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
sqlite3VdbeAddOp4(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
regNewData+1+i, zMsg, P4_DYNAMIC);
sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
+ VdbeCoverage(v);
break;
}
case OE_Ignore: {
sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
+ VdbeCoverage(v);
break;
}
default: {
assert( onError==OE_Replace );
- j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
+ j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v);
sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
sqlite3VdbeJumpHere(v, j1);
break;
@@ -94168,6 +94709,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
** it might have changed. Skip the conflict logic below if the rowid
** is unchanged. */
sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverage(v);
}
/* If the response to a rowid conflict is REPLACE but the response
@@ -94187,6 +94730,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* Check to see if the new rowid already exists in the table. Skip
** the following conflict logic if it does not. */
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData);
+ VdbeCoverage(v);
/* Generate code that deals with a rowid collision */
switch( onError ){
@@ -94265,6 +94809,10 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */
if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */
+ if( bAffinityDone==0 ){
+ sqlite3TableAffinity(v, pTab, regNewData+1);
+ bAffinityDone = 1;
+ }
iThisCur = iIdxCur+ix;
addrUniqueOk = sqlite3VdbeMakeLabel(v);
@@ -94285,7 +94833,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
int iField = pIdx->aiColumn[i];
int x;
if( iField<0 || iField==pTab->iPKey ){
+ if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
x = regNewData;
+ regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
}else{
x = iField + regNewData + 1;
}
@@ -94293,7 +94843,6 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
VdbeComment((v, "%s", iField<0 ? "rowid" : pTab->aCol[iField].zName));
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]);
- sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
VdbeComment((v, "for %s", pIdx->zName));
sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn);
@@ -94321,51 +94870,58 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
/* Check to see if the new index entry will be unique */
sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk,
- regIdx, pIdx->nKeyCol);
+ regIdx, pIdx->nKeyCol); VdbeCoverage(v);
/* Generate code to handle collisions */
regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
- if( HasRowid(pTab) ){
- sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
- /* Conflict only if the rowid of the existing index entry
- ** is different from old-rowid */
- if( isUpdate ){
- sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
- }
- }else{
- int x;
- /* Extract the PRIMARY KEY from the end of the index entry and
- ** store it in registers regR..regR+nPk-1 */
- if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){
- for(i=0; i<pPk->nKeyCol; i++){
- x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
- sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
- VdbeComment((v, "%s.%s", pTab->zName,
- pTab->aCol[pPk->aiColumn[i]].zName));
- }
- }
- if( isUpdate ){
- /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
- ** table, only conflict if the new PRIMARY KEY values are actually
- ** different from the old.
- **
- ** For a UNIQUE index, only conflict if the PRIMARY KEY values
- ** of the matched index row are different from the original PRIMARY
- ** KEY values of this row before the update. */
- int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
- int op = OP_Ne;
- int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
-
- for(i=0; i<pPk->nKeyCol; i++){
- char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
- x = pPk->aiColumn[i];
- if( i==(pPk->nKeyCol-1) ){
- addrJump = addrUniqueOk;
- op = OP_Eq;
+ if( isUpdate || onError==OE_Replace ){
+ if( HasRowid(pTab) ){
+ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
+ /* Conflict only if the rowid of the existing index entry
+ ** is different from old-rowid */
+ if( isUpdate ){
+ sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverage(v);
+ }
+ }else{
+ int x;
+ /* Extract the PRIMARY KEY from the end of the index entry and
+ ** store it in registers regR..regR+nPk-1 */
+ if( pIdx!=pPk ){
+ for(i=0; i<pPk->nKeyCol; i++){
+ x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
+ sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
+ VdbeComment((v, "%s.%s", pTab->zName,
+ pTab->aCol[pPk->aiColumn[i]].zName));
+ }
+ }
+ if( isUpdate ){
+ /* If currently processing the PRIMARY KEY of a WITHOUT ROWID
+ ** table, only conflict if the new PRIMARY KEY values are actually
+ ** different from the old.
+ **
+ ** For a UNIQUE index, only conflict if the PRIMARY KEY values
+ ** of the matched index row are different from the original PRIMARY
+ ** KEY values of this row before the update. */
+ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
+ int op = OP_Ne;
+ int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
+
+ for(i=0; i<pPk->nKeyCol; i++){
+ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
+ x = pPk->aiColumn[i];
+ if( i==(pPk->nKeyCol-1) ){
+ addrJump = addrUniqueOk;
+ op = OP_Eq;
+ }
+ sqlite3VdbeAddOp4(v, op,
+ regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
+ );
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
+ VdbeCoverageIf(v, op==OP_Eq);
+ VdbeCoverageIf(v, op==OP_Ne);
}
- sqlite3VdbeAddOp4(v, op,
- regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
- );
}
}
}
@@ -94436,14 +94992,17 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
int regData; /* Content registers (after the rowid) */
int regRec; /* Register holding assemblied record for the table */
int i; /* Loop counter */
+ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
v = sqlite3GetVdbe(pParse);
assert( v!=0 );
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( aRegIdx[i]==0 ) continue;
+ bAffinityDone = 1;
if( pIdx->pPartIdxWhere ){
sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
+ VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]);
pik_flags = 0;
@@ -94458,7 +95017,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
regData = regNewData + 1;
regRec = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec);
- sqlite3TableAffinityStr(v, pTab);
+ if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0);
sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol);
if( pParse->nested ){
pik_flags = 0;
@@ -94664,6 +95223,12 @@ static int xferOptimization(
if( pSelect==0 ){
return 0; /* Must be of the form INSERT INTO ... SELECT ... */
}
+ if( pParse->pWith || pSelect->pWith ){
+ /* Do not attempt to process this query if there are an WITH clauses
+ ** attached to it. Proceeding may generate a false "no such table: xxx"
+ ** error if pSelect reads from a CTE named "xxx". */
+ return 0;
+ }
if( sqlite3TriggerList(pParse, pDest) ){
return 0; /* tab1 must not have triggers */
}
@@ -94821,16 +95386,17 @@ static int xferOptimization(
**
** (3) onError is something other than OE_Abort and OE_Rollback.
*/
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0);
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v);
emptyDestTest = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
sqlite3VdbeJumpHere(v, addr1);
}
if( HasRowid(pSrc) ){
sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead);
- emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
+ emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
if( pDest->iPKey>=0 ){
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
+ VdbeCoverage(v);
sqlite3RowidConstraint(pParse, onError, pDest);
sqlite3VdbeJumpHere(v, addr2);
autoIncStep(pParse, regAutoinc, regRowid);
@@ -94844,7 +95410,7 @@ static int xferOptimization(
sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid);
sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
+ sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}else{
@@ -94863,15 +95429,15 @@ static int xferOptimization(
sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx);
sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR);
VdbeComment((v, "%s", pDestIdx->zName));
- addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0);
+ addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
- sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1);
+ sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
sqlite3VdbeAddOp2(v, OP_Close, iDest, 0);
}
- sqlite3VdbeJumpHere(v, emptySrcTest);
+ if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest);
sqlite3ReleaseTempReg(pParse, regRowid);
sqlite3ReleaseTempReg(pParse, regData);
if( emptyDestTest ){
@@ -97105,6 +97671,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** size of historical compatibility.
*/
case PragTyp_DEFAULT_CACHE_SIZE: {
+ static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList getCacheSize[] = {
{ OP_Transaction, 0, 0, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */
@@ -97122,7 +97689,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeSetNumCols(v, 1);
sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "cache_size", SQLITE_STATIC);
pParse->nMem += 2;
- addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
+ addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize,iLn);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, iDb);
sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
@@ -97367,6 +97934,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** file. Before writing to meta[6], check that meta[3] indicates
** that this really is an auto-vacuum capable database.
*/
+ static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList setMeta6[] = {
{ OP_Transaction, 0, 1, 0}, /* 0 */
{ OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE},
@@ -97376,7 +97944,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */
};
int iAddr;
- iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6);
+ iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
sqlite3VdbeChangeP1(v, iAddr, iDb);
sqlite3VdbeChangeP1(v, iAddr+1, iDb);
sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4);
@@ -97402,10 +97970,10 @@ SQLITE_PRIVATE void sqlite3Pragma(
}
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1);
- addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb);
+ addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v);
sqlite3VdbeAddOp1(v, OP_ResultRow, 1);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
- sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr);
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr);
break;
}
@@ -97976,7 +98544,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
assert( pParse->nErr>0 || pFK==0 );
if( pFK ) break;
if( pParse->nTab<i ) pParse->nTab = i;
- addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0);
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
pIdx = 0;
@@ -97992,26 +98560,26 @@ SQLITE_PRIVATE void sqlite3Pragma(
if( iKey!=pTab->iPKey ){
sqlite3VdbeAddOp3(v, OP_Column, 0, iKey, regRow);
sqlite3ColumnDefault(v, pTab, iKey, regRow);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk);
- sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
- sqlite3VdbeCurrentAddr(v)+3);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow, addrOk); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, regRow,
+ sqlite3VdbeCurrentAddr(v)+3); VdbeCoverage(v);
}else{
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regRow);
}
- sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow);
+ sqlite3VdbeAddOp3(v, OP_NotExists, i, 0, regRow); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrOk);
sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
}else{
for(j=0; j<pFK->nCol; j++){
sqlite3ExprCodeGetColumnOfTable(v, pTab, 0,
aiCols ? aiCols[j] : pFK->aCol[j].iFrom, regRow+j);
- sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk);
+ sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v);
}
if( pParent ){
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regRow, pFK->nCol, regKey);
- sqlite3VdbeChangeP4(v, -1,
- sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey,
+ sqlite3IndexAffinityStr(v,pIdx), pFK->nCol);
sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0);
+ VdbeCoverage(v);
}
}
sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1);
@@ -98022,7 +98590,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeResolveLabel(v, addrOk);
sqlite3DbFree(db, aiCols);
}
- sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1);
+ sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addrTop);
}
}
@@ -98069,6 +98637,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
** messages have been generated, output OK. Otherwise output the
** error message
*/
+ static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList endCode[] = {
{ OP_AddImm, 1, 0, 0}, /* 0 */
{ OP_IfNeg, 1, 0, 0}, /* 1 */
@@ -98117,6 +98686,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3CodeVerifySchema(pParse, i);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */
+ VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
@@ -98148,7 +98718,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
sqlite3VdbeChangeP5(v, (u8)i);
- addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
+ addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
P4_DYNAMIC);
@@ -98162,12 +98732,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx, *pPk;
+ Index *pPrior = 0;
int loopTop;
int iDataCur, iIdxCur;
+ int r1 = -1;
if( pTab->pIndex==0 ) continue;
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
+ VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeJumpHere(v, addr);
sqlite3ExprCacheClear(pParse);
@@ -98178,16 +98751,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */
}
pParse->nMem = MAX(pParse->nMem, 8+j);
- sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4;
- int r1;
if( pPk==pIdx ) continue;
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3);
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
+ pPrior, r1);
+ pPrior = pIdx;
sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1,
- pIdx->nColumn);
+ pIdx->nColumn); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); /* Decrement error limit */
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, "row ", P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
@@ -98197,13 +98771,13 @@ SQLITE_PRIVATE void sqlite3Pragma(
sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1);
- jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
+ jmp4 = sqlite3VdbeAddOp1(v, OP_IfPos, 1); VdbeCoverage(v);
sqlite3VdbeAddOp0(v, OP_Halt);
sqlite3VdbeJumpHere(v, jmp4);
sqlite3VdbeJumpHere(v, jmp2);
sqlite3VdbeResolveLabel(v, jmp3);
}
- sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop);
+ sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, loopTop-1);
#ifndef SQLITE_OMIT_BTREECOUNT
sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
@@ -98211,10 +98785,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
if( pPk==pIdx ) continue;
addr = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3);
- sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3);
+ sqlite3VdbeAddOp3(v, OP_Eq, 8+j, addr+8, 3); VdbeCoverage(v);
+ sqlite3VdbeChangeP5(v, SQLITE_NOTNULL);
sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
@@ -98223,7 +98798,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
#endif /* SQLITE_OMIT_BTREECOUNT */
}
}
- addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
+ addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
sqlite3VdbeChangeP2(v, addr, -mxErr);
sqlite3VdbeJumpHere(v, addr+1);
sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
@@ -98361,7 +98936,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_Integer, 0, 1, 0}, /* 1 */
{ OP_SetCookie, 0, 0, 1}, /* 2 */
};
- int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie);
+ int addr = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, sqlite3Atoi(zRight));
sqlite3VdbeChangeP1(v, addr+2, iDb);
@@ -98373,7 +98948,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
{ OP_ReadCookie, 0, 1, 0}, /* 1 */
{ OP_ResultRow, 1, 1, 0}
};
- int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie);
+ int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie, 0);
sqlite3VdbeChangeP1(v, addr, iDb);
sqlite3VdbeChangeP1(v, addr+1, iDb);
sqlite3VdbeChangeP3(v, addr+1, iCookie);
@@ -99112,7 +99687,11 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
** Free all memory allocations in the pParse object
*/
SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){
- if( pParse ) sqlite3ExprListDelete(pParse->db, pParse->pConstExpr);
+ if( pParse ){
+ sqlite3 *db = pParse->db;
+ sqlite3DbFree(db, pParse->aLabel);
+ sqlite3ExprListDelete(db, pParse->pConstExpr);
+ }
}
/*
@@ -99496,6 +100075,7 @@ static void clearSelect(sqlite3 *db, Select *p){
sqlite3SelectDelete(db, p->pPrior);
sqlite3ExprDelete(db, p->pLimit);
sqlite3ExprDelete(db, p->pOffset);
+ sqlite3WithDelete(db, p->pWith);
}
/*
@@ -99576,6 +100156,14 @@ SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
}
/*
+** Return a pointer to the right-most SELECT statement in a compound.
+*/
+static Select *findRightmost(Select *p){
+ while( p->pNext ) p = p->pNext;
+ return p;
+}
+
+/*
** Given 1 to 3 identifiers preceding the JOIN keyword, determine the
** type of join. Return an integer constant that expresses that type
** in terms of the following bit values:
@@ -99913,7 +100501,7 @@ static void pushOntoSorter(
}else{
iLimit = pSelect->iLimit;
}
- addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit);
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
sqlite3VdbeJumpHere(v, addr1);
@@ -99928,13 +100516,13 @@ static void pushOntoSorter(
*/
static void codeOffset(
Vdbe *v, /* Generate code into this VM */
- Select *p, /* The SELECT statement being coded */
+ int iOffset, /* Register holding the offset counter */
int iContinue /* Jump here to skip the current record */
){
- if( p->iOffset && iContinue!=0 ){
+ if( iOffset>0 && iContinue!=0 ){
int addr;
- sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
- addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset);
+ sqlite3VdbeAddOp2(v, OP_AddImm, iOffset, -1);
+ addr = sqlite3VdbeAddOp1(v, OP_IfNeg, iOffset); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, iContinue);
VdbeComment((v, "skip OFFSET records"));
sqlite3VdbeJumpHere(v, addr);
@@ -99962,7 +100550,7 @@ static void codeDistinct(
v = pParse->pVdbe;
r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N);
+ sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iTab, r1);
sqlite3ReleaseTempReg(pParse, r1);
@@ -100009,17 +100597,16 @@ struct DistinctCtx {
** This routine generates the code for the inside of the inner loop
** of a SELECT.
**
-** If srcTab and nColumn are both zero, then the pEList expressions
-** are evaluated in order to get the data for this row. If nColumn>0
-** then data is pulled from srcTab and pEList is used only to get the
-** datatypes for each column.
+** If srcTab is negative, then the pEList expressions
+** are evaluated in order to get the data for this row. If srcTab is
+** zero or more, then data is pulled from srcTab and pEList is used only
+** to get number columns and the datatype for each column.
*/
static void selectInnerLoop(
Parse *pParse, /* The parser context */
Select *p, /* The complete select statement being coded */
ExprList *pEList, /* List of values being extracted */
int srcTab, /* Pull data from this table */
- int nColumn, /* Number of columns in the source table */
ExprList *pOrderBy, /* If not NULL, sort results using this key */
DistinctCtx *pDistinct, /* If not NULL, info on how to process DISTINCT */
SelectDest *pDest, /* How to dispose of the results */
@@ -100035,49 +100622,47 @@ static void selectInnerLoop(
int nResultCol; /* Number of result columns */
assert( v );
- if( NEVER(v==0) ) return;
assert( pEList!=0 );
hasDistinct = pDistinct ? pDistinct->eTnctType : WHERE_DISTINCT_NOOP;
if( pOrderBy==0 && !hasDistinct ){
- codeOffset(v, p, iContinue);
+ codeOffset(v, p->iOffset, iContinue);
}
/* Pull the requested columns.
*/
- if( nColumn>0 ){
- nResultCol = nColumn;
- }else{
- nResultCol = pEList->nExpr;
- }
+ nResultCol = pEList->nExpr;
+
if( pDest->iSdst==0 ){
pDest->iSdst = pParse->nMem+1;
- pDest->nSdst = nResultCol;
pParse->nMem += nResultCol;
- }else{
- assert( pDest->nSdst==nResultCol );
+ }else if( pDest->iSdst+nResultCol > pParse->nMem ){
+ /* This is an error condition that can result, for example, when a SELECT
+ ** on the right-hand side of an INSERT contains more result columns than
+ ** there are columns in the table on the left. The error will be caught
+ ** and reported later. But we need to make sure enough memory is allocated
+ ** to avoid other spurious errors in the meantime. */
+ pParse->nMem += nResultCol;
}
+ pDest->nSdst = nResultCol;
regResult = pDest->iSdst;
- if( nColumn>0 ){
- for(i=0; i<nColumn; i++){
+ if( srcTab>=0 ){
+ for(i=0; i<nResultCol; i++){
sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i);
+ VdbeComment((v, "%s", pEList->a[i].zName));
}
}else if( eDest!=SRT_Exists ){
/* If the destination is an EXISTS(...) expression, the actual
** values returned by the SELECT are not required.
*/
- sqlite3ExprCacheClear(pParse);
sqlite3ExprCodeExprList(pParse, pEList, regResult,
- (eDest==SRT_Output)?SQLITE_ECEL_DUP:0);
+ (eDest==SRT_Output||eDest==SRT_Coroutine)?SQLITE_ECEL_DUP:0);
}
- nColumn = nResultCol;
/* If the DISTINCT keyword was present on the SELECT statement
** and this row has been seen before, then do not make this row
** part of the result.
*/
if( hasDistinct ){
- assert( pEList!=0 );
- assert( pEList->nExpr==nColumn );
switch( pDistinct->eTnctType ){
case WHERE_DISTINCT_ORDERED: {
VdbeOp *pOp; /* No longer required OpenEphemeral instr. */
@@ -100086,7 +100671,7 @@ static void selectInnerLoop(
/* Allocate space for the previous row */
regPrev = pParse->nMem+1;
- pParse->nMem += nColumn;
+ pParse->nMem += nResultCol;
/* Change the OP_OpenEphemeral coded earlier to an OP_Null
** sets the MEM_Cleared bit on the first register of the
@@ -100100,19 +100685,21 @@ static void selectInnerLoop(
pOp->p1 = 1;
pOp->p2 = regPrev;
- iJump = sqlite3VdbeCurrentAddr(v) + nColumn;
- for(i=0; i<nColumn; i++){
+ iJump = sqlite3VdbeCurrentAddr(v) + nResultCol;
+ for(i=0; i<nResultCol; i++){
CollSeq *pColl = sqlite3ExprCollSeq(pParse, pEList->a[i].pExpr);
- if( i<nColumn-1 ){
+ if( i<nResultCol-1 ){
sqlite3VdbeAddOp3(v, OP_Ne, regResult+i, iJump, regPrev+i);
+ VdbeCoverage(v);
}else{
sqlite3VdbeAddOp3(v, OP_Eq, regResult+i, iContinue, regPrev+i);
- }
+ VdbeCoverage(v);
+ }
sqlite3VdbeChangeP4(v, -1, (const char *)pColl, P4_COLLSEQ);
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
}
assert( sqlite3VdbeCurrentAddr(v)==iJump );
- sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nColumn-1);
+ sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1);
break;
}
@@ -100123,12 +100710,12 @@ static void selectInnerLoop(
default: {
assert( pDistinct->eTnctType==WHERE_DISTINCT_UNORDERED );
- codeDistinct(pParse, pDistinct->tabTnct, iContinue, nColumn, regResult);
+ codeDistinct(pParse, pDistinct->tabTnct, iContinue, nResultCol, regResult);
break;
}
}
if( pOrderBy==0 ){
- codeOffset(v, p, iContinue);
+ codeOffset(v, p->iOffset, iContinue);
}
}
@@ -100140,7 +100727,7 @@ static void selectInnerLoop(
case SRT_Union: {
int r1;
r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
sqlite3ReleaseTempReg(pParse, r1);
break;
@@ -100151,19 +100738,33 @@ static void selectInnerLoop(
** the temporary table iParm.
*/
case SRT_Except: {
- sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nColumn);
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol);
break;
}
-#endif
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
/* Store the result as data using a unique key.
*/
+ case SRT_DistTable:
case SRT_Table:
case SRT_EphemTab: {
int r1 = sqlite3GetTempReg(pParse);
testcase( eDest==SRT_Table );
testcase( eDest==SRT_EphemTab );
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
+#ifndef SQLITE_OMIT_CTE
+ if( eDest==SRT_DistTable ){
+ /* If the destination is DistTable, then cursor (iParm+1) is open
+ ** on an ephemeral index. If the current row is already present
+ ** in the index, do not write it to the output. If not, add the
+ ** current row to the index and proceed with writing it to the
+ ** output table as well. */
+ int addr = sqlite3VdbeCurrentAddr(v) + 4;
+ sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r1);
+ assert( pOrderBy==0 );
+ }
+#endif
if( pOrderBy ){
pushOntoSorter(pParse, pOrderBy, p, r1);
}else{
@@ -100183,7 +100784,7 @@ static void selectInnerLoop(
** item into the set table with bogus data.
*/
case SRT_Set: {
- assert( nColumn==1 );
+ assert( nResultCol==1 );
pDest->affSdst =
sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst);
if( pOrderBy ){
@@ -100215,7 +100816,7 @@ static void selectInnerLoop(
** of the scan loop.
*/
case SRT_Mem: {
- assert( nColumn==1 );
+ assert( nResultCol==1 );
if( pOrderBy ){
pushOntoSorter(pParse, pOrderBy, p, regResult);
}else{
@@ -100226,28 +100827,73 @@ static void selectInnerLoop(
}
#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
- /* Send the data to the callback function or to a subroutine. In the
- ** case of a subroutine, the subroutine itself is responsible for
- ** popping the data from the stack.
- */
- case SRT_Coroutine:
- case SRT_Output: {
+ case SRT_Coroutine: /* Send data to a co-routine */
+ case SRT_Output: { /* Return the results */
testcase( eDest==SRT_Coroutine );
testcase( eDest==SRT_Output );
if( pOrderBy ){
int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
pushOntoSorter(pParse, pOrderBy, p, r1);
sqlite3ReleaseTempReg(pParse, r1);
}else if( eDest==SRT_Coroutine ){
sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
}else{
- sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
- sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol);
+ sqlite3ExprCacheAffinityChange(pParse, regResult, nResultCol);
}
break;
}
+#ifndef SQLITE_OMIT_CTE
+ /* Write the results into a priority queue that is order according to
+ ** pDest->pOrderBy (in pSO). pDest->iSDParm (in iParm) is the cursor for an
+ ** index with pSO->nExpr+2 columns. Build a key using pSO for the first
+ ** pSO->nExpr columns, then make sure all keys are unique by adding a
+ ** final OP_Sequence column. The last column is the record as a blob.
+ */
+ case SRT_DistQueue:
+ case SRT_Queue: {
+ int nKey;
+ int r1, r2, r3;
+ int addrTest = 0;
+ ExprList *pSO;
+ pSO = pDest->pOrderBy;
+ assert( pSO );
+ nKey = pSO->nExpr;
+ r1 = sqlite3GetTempReg(pParse);
+ r2 = sqlite3GetTempRange(pParse, nKey+2);
+ r3 = r2+nKey+1;
+ if( eDest==SRT_DistQueue ){
+ /* If the destination is DistQueue, then cursor (iParm+1) is open
+ ** on a second ephemeral index that holds all values every previously
+ ** added to the queue. */
+ addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0,
+ regResult, nResultCol);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3);
+ if( eDest==SRT_DistQueue ){
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3);
+ sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+ }
+ for(i=0; i<nKey; i++){
+ sqlite3VdbeAddOp2(v, OP_SCopy,
+ regResult + pSO->a[i].u.x.iOrderByCol - 1,
+ r2+i);
+ }
+ sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey);
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1);
+ sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
+ if( addrTest ) sqlite3VdbeJumpHere(v, addrTest);
+ sqlite3ReleaseTempReg(pParse, r1);
+ sqlite3ReleaseTempRange(pParse, r2, nKey+2);
+ break;
+ }
+#endif /* SQLITE_OMIT_CTE */
+
+
+
#if !defined(SQLITE_OMIT_TRIGGER)
/* Discard the results. This is used for SELECT statements inside
** the body of a TRIGGER. The purpose of such selects is to call
@@ -100266,7 +100912,7 @@ static void selectInnerLoop(
** the output for us.
*/
if( pOrderBy==0 && p->iLimit ){
- sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
+ sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
}
}
@@ -100336,7 +100982,7 @@ SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
** function is responsible for seeing that this structure is eventually
** freed.
*/
-static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
+static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList, int nExtra){
int nExpr;
KeyInfo *pInfo;
struct ExprList_item *pItem;
@@ -100344,7 +100990,7 @@ static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
int i;
nExpr = pList->nExpr;
- pInfo = sqlite3KeyInfoAlloc(db, nExpr, 1);
+ pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra, 1);
if( pInfo ){
assert( sqlite3KeyInfoIsWriteable(pInfo) );
for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
@@ -100485,13 +101131,14 @@ static void generateSortTail(
int ptab2 = pParse->nTab++;
sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, pOrderBy->nExpr+2);
addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
- codeOffset(v, p, addrContinue);
+ VdbeCoverage(v);
+ codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
sqlite3VdbeAddOp3(v, OP_Column, ptab2, pOrderBy->nExpr+1, regRow);
sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
}else{
- addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak);
- codeOffset(v, p, addrContinue);
+ addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
+ codeOffset(v, p->iOffset, addrContinue);
sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr+1, regRow);
}
switch( eDest ){
@@ -100548,9 +101195,9 @@ static void generateSortTail(
*/
sqlite3VdbeResolveLabel(v, addrContinue);
if( p->selFlags & SF_UseSorter ){
- sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr);
+ sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v);
}else{
- sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
+ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v);
}
sqlite3VdbeResolveLabel(v, addrBreak);
if( eDest==SRT_Output || eDest==SRT_Coroutine ){
@@ -100670,7 +101317,7 @@ static const char *columnTypeImpl(
sNC.pParse = pNC->pParse;
zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol, &estWidth);
}
- }else if( ALWAYS(pTab->pSchema) ){
+ }else if( pTab->pSchema ){
/* A real table */
assert( !pS );
if( iCol<0 ) iCol = pTab->iPKey;
@@ -100831,8 +101478,9 @@ static void generateColumnNames(
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT);
}
}else{
- sqlite3VdbeSetColName(v, i, COLNAME_NAME,
- sqlite3DbStrDup(db, pEList->a[i].zSpan), SQLITE_DYNAMIC);
+ const char *z = pEList->a[i].zSpan;
+ z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z);
+ sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC);
}
}
generateColumnTypes(pParse, pTabList, pEList);
@@ -100920,7 +101568,7 @@ static int selectColumnsFromExprList(
char *zNewName;
int k;
for(k=nName-1; k>1 && sqlite3Isdigit(zName[k]); k--){}
- if( zName[k]==':' ) nName = k;
+ if( k>=0 && zName[k]==':' ) nName = k;
zName[nName] = 0;
zNewName = sqlite3MPrintf(db, "%s:%d", zName, ++cnt);
sqlite3DbFree(db, zName);
@@ -101032,12 +101680,14 @@ SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe;
if( v==0 ){
- v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
-#ifndef SQLITE_OMIT_TRACE
- if( v ){
- sqlite3VdbeAddOp0(v, OP_Trace);
+ v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
+ if( v ) sqlite3VdbeAddOp0(v, OP_Init);
+ if( pParse->pToplevel==0
+ && OptimizationEnabled(pParse->db,SQLITE_FactorOutConst)
+ ){
+ pParse->okConstFactor = 1;
}
-#endif
+
}
return v;
}
@@ -101054,8 +101704,13 @@ SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){
**
** This routine changes the values of iLimit and iOffset only if
** a limit or offset is defined by pLimit and pOffset. iLimit and
-** iOffset should have been preset to appropriate default values
-** (usually but not always -1) prior to calling this routine.
+** iOffset should have been preset to appropriate default values (zero)
+** prior to calling this routine.
+**
+** The iOffset register (if it exists) is initialized to the value
+** of the OFFSET. The iLimit register is initialized to LIMIT. Register
+** iOffset+1 is initialized to LIMIT+OFFSET.
+**
** Only if pLimit!=0 or pOffset!=0 do the limit registers get
** redefined. The UNION ALL operator uses this property to force
** the reuse of the same limit and offset registers across multiple
@@ -101079,7 +101734,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
if( p->pLimit ){
p->iLimit = iLimit = ++pParse->nMem;
v = sqlite3GetVdbe(pParse);
- if( NEVER(v==0) ) return; /* VDBE should have already been allocated */
+ assert( v!=0 );
if( sqlite3ExprIsInteger(p->pLimit, &n) ){
sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit);
VdbeComment((v, "LIMIT counter"));
@@ -101090,22 +101745,22 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
}
}else{
sqlite3ExprCode(pParse, p->pLimit, iLimit);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
VdbeComment((v, "LIMIT counter"));
- sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak);
+ sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v);
}
if( p->pOffset ){
p->iOffset = iOffset = ++pParse->nMem;
pParse->nMem++; /* Allocate an extra register for limit+offset */
sqlite3ExprCode(pParse, p->pOffset, iOffset);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
VdbeComment((v, "OFFSET counter"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset);
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
sqlite3VdbeJumpHere(v, addr1);
sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
VdbeComment((v, "LIMIT+OFFSET"));
- addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit);
+ addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
sqlite3VdbeJumpHere(v, addr1);
}
@@ -101134,9 +101789,209 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){
}
return pRet;
}
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
-/* Forward reference */
+/*
+** The select statement passed as the second parameter is a compound SELECT
+** with an ORDER BY clause. This function allocates and returns a KeyInfo
+** structure suitable for implementing the ORDER BY.
+**
+** Space to hold the KeyInfo structure is obtained from malloc. The calling
+** function is responsible for ensuring that this structure is eventually
+** freed.
+*/
+static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
+ ExprList *pOrderBy = p->pOrderBy;
+ int nOrderBy = p->pOrderBy->nExpr;
+ sqlite3 *db = pParse->db;
+ KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
+ if( pRet ){
+ int i;
+ for(i=0; i<nOrderBy; i++){
+ struct ExprList_item *pItem = &pOrderBy->a[i];
+ Expr *pTerm = pItem->pExpr;
+ CollSeq *pColl;
+
+ if( pTerm->flags & EP_Collate ){
+ pColl = sqlite3ExprCollSeq(pParse, pTerm);
+ }else{
+ pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1);
+ if( pColl==0 ) pColl = db->pDfltColl;
+ pOrderBy->a[i].pExpr =
+ sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
+ }
+ assert( sqlite3KeyInfoIsWriteable(pRet) );
+ pRet->aColl[i] = pColl;
+ pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder;
+ }
+ }
+
+ return pRet;
+}
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** This routine generates VDBE code to compute the content of a WITH RECURSIVE
+** query of the form:
+**
+** <recursive-table> AS (<setup-query> UNION [ALL] <recursive-query>)
+** \___________/ \_______________/
+** p->pPrior p
+**
+**
+** There is exactly one reference to the recursive-table in the FROM clause
+** of recursive-query, marked with the SrcList->a[].isRecursive flag.
+**
+** The setup-query runs once to generate an initial set of rows that go
+** into a Queue table. Rows are extracted from the Queue table one by
+** one. Each row extracted from Queue is output to pDest. Then the single
+** extracted row (now in the iCurrent table) becomes the content of the
+** recursive-table for a recursive-query run. The output of the recursive-query
+** is added back into the Queue table. Then another row is extracted from Queue
+** and the iteration continues until the Queue table is empty.
+**
+** If the compound query operator is UNION then no duplicate rows are ever
+** inserted into the Queue table. The iDistinct table keeps a copy of all rows
+** that have ever been inserted into Queue and causes duplicates to be
+** discarded. If the operator is UNION ALL, then duplicates are allowed.
+**
+** If the query has an ORDER BY, then entries in the Queue table are kept in
+** ORDER BY order and the first entry is extracted for each cycle. Without
+** an ORDER BY, the Queue table is just a FIFO.
+**
+** If a LIMIT clause is provided, then the iteration stops after LIMIT rows
+** have been output to pDest. A LIMIT of zero means to output no rows and a
+** negative LIMIT means to output all rows. If there is also an OFFSET clause
+** with a positive value, then the first OFFSET outputs are discarded rather
+** than being sent to pDest. The LIMIT count does not begin until after OFFSET
+** rows have been skipped.
+*/
+static void generateWithRecursiveQuery(
+ Parse *pParse, /* Parsing context */
+ Select *p, /* The recursive SELECT to be coded */
+ SelectDest *pDest /* What to do with query results */
+){
+ SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */
+ int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */
+ Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */
+ Select *pSetup = p->pPrior; /* The setup query */
+ int addrTop; /* Top of the loop */
+ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */
+ int iCurrent = 0; /* The Current table */
+ int regCurrent; /* Register holding Current table */
+ int iQueue; /* The Queue table */
+ int iDistinct = 0; /* To ensure unique results if UNION */
+ int eDest = SRT_Table; /* How to write to Queue */
+ SelectDest destQueue; /* SelectDest targetting the Queue table */
+ int i; /* Loop counter */
+ int rc; /* Result code */
+ ExprList *pOrderBy; /* The ORDER BY clause */
+ Expr *pLimit, *pOffset; /* Saved LIMIT and OFFSET */
+ int regLimit, regOffset; /* Registers used by LIMIT and OFFSET */
+
+ /* Obtain authorization to do a recursive query */
+ if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;
+
+ /* Process the LIMIT and OFFSET clauses, if they exist */
+ addrBreak = sqlite3VdbeMakeLabel(v);
+ computeLimitRegisters(pParse, p, addrBreak);
+ pLimit = p->pLimit;
+ pOffset = p->pOffset;
+ regLimit = p->iLimit;
+ regOffset = p->iOffset;
+ p->pLimit = p->pOffset = 0;
+ p->iLimit = p->iOffset = 0;
+ pOrderBy = p->pOrderBy;
+
+ /* Locate the cursor number of the Current table */
+ for(i=0; ALWAYS(i<pSrc->nSrc); i++){
+ if( pSrc->a[i].isRecursive ){
+ iCurrent = pSrc->a[i].iCursor;
+ break;
+ }
+ }
+
+ /* Allocate cursors numbers for Queue and Distinct. The cursor number for
+ ** the Distinct table must be exactly one greater than Queue in order
+ ** for the SRT_DistTable and SRT_DistQueue destinations to work. */
+ iQueue = pParse->nTab++;
+ if( p->op==TK_UNION ){
+ eDest = pOrderBy ? SRT_DistQueue : SRT_DistTable;
+ iDistinct = pParse->nTab++;
+ }else{
+ eDest = pOrderBy ? SRT_Queue : SRT_Table;
+ }
+ sqlite3SelectDestInit(&destQueue, eDest, iQueue);
+
+ /* Allocate cursors for Current, Queue, and Distinct. */
+ regCurrent = ++pParse->nMem;
+ sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol);
+ if( pOrderBy ){
+ KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1);
+ sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0,
+ (char*)pKeyInfo, P4_KEYINFO);
+ destQueue.pOrderBy = pOrderBy;
+ }else{
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol);
+ }
+ VdbeComment((v, "Queue table"));
+ if( iDistinct ){
+ p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0);
+ p->selFlags |= SF_UsesEphemeral;
+ }
+
+ /* Detach the ORDER BY clause from the compound SELECT */
+ p->pOrderBy = 0;
+
+ /* Store the results of the setup-query in Queue. */
+ pSetup->pNext = 0;
+ rc = sqlite3Select(pParse, pSetup, &destQueue);
+ pSetup->pNext = p;
+ if( rc ) goto end_of_recursive_query;
+
+ /* Find the next row in the Queue and output that row */
+ addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v);
+
+ /* Transfer the next row in Queue over to Current */
+ sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */
+ if( pOrderBy ){
+ sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent);
+ }
+ sqlite3VdbeAddOp1(v, OP_Delete, iQueue);
+
+ /* Output the single row in Current */
+ addrCont = sqlite3VdbeMakeLabel(v);
+ codeOffset(v, regOffset, addrCont);
+ selectInnerLoop(pParse, p, p->pEList, iCurrent,
+ 0, 0, pDest, addrCont, addrBreak);
+ if( regLimit ){
+ sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
+ VdbeCoverage(v);
+ }
+ sqlite3VdbeResolveLabel(v, addrCont);
+
+ /* Execute the recursive SELECT taking the single row in Current as
+ ** the value for the recursive-table. Store the results in the Queue.
+ */
+ p->pPrior = 0;
+ sqlite3Select(pParse, p, &destQueue);
+ assert( p->pPrior==0 );
+ p->pPrior = pSetup;
+
+ /* Keep running the loop until the Queue is empty */
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
+ sqlite3VdbeResolveLabel(v, addrBreak);
+
+end_of_recursive_query:
+ p->pOrderBy = pOrderBy;
+ p->pLimit = pLimit;
+ p->pOffset = pOffset;
+ return;
+}
+#endif /* SQLITE_OMIT_CTE */
+
+/* Forward references */
static int multiSelectOrderBy(
Parse *pParse, /* Parsing context */
Select *p, /* The right-most of SELECTs to be coded */
@@ -101144,7 +101999,6 @@ static int multiSelectOrderBy(
);
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
/*
** This routine is called to process a compound query form from
** two or more separate queries using UNION, UNION ALL, EXCEPT, or
@@ -101188,18 +102042,17 @@ static int multiSelect(
Select *pDelete = 0; /* Chain of simple selects to delete */
sqlite3 *db; /* Database connection */
#ifndef SQLITE_OMIT_EXPLAIN
- int iSub1; /* EQP id of left-hand query */
- int iSub2; /* EQP id of right-hand query */
+ int iSub1 = 0; /* EQP id of left-hand query */
+ int iSub2 = 0; /* EQP id of right-hand query */
#endif
/* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
*/
assert( p && p->pPrior ); /* Calling function guarantees this much */
+ assert( (p->selFlags & SF_Recursive)==0 || p->op==TK_ALL || p->op==TK_UNION );
db = pParse->db;
pPrior = p->pPrior;
- assert( pPrior->pRightmost!=pPrior );
- assert( pPrior->pRightmost==p->pRightmost );
dest = *pDest;
if( pPrior->pOrderBy ){
sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before",
@@ -101241,11 +102094,17 @@ static int multiSelect(
goto multi_select_end;
}
+#ifndef SQLITE_OMIT_CTE
+ if( p->selFlags & SF_Recursive ){
+ generateWithRecursiveQuery(pParse, p, &dest);
+ }else
+#endif
+
/* Compound SELECTs that have an ORDER BY clause are handled separately.
*/
if( p->pOrderBy ){
return multiSelectOrderBy(pParse, p, pDest);
- }
+ }else
/* Generate code for the left and right SELECT statements.
*/
@@ -101269,7 +102128,7 @@ static int multiSelect(
p->iLimit = pPrior->iLimit;
p->iOffset = pPrior->iOffset;
if( p->iLimit ){
- addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
+ addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v);
VdbeComment((v, "Jump ahead if LIMIT reached"));
}
explainSetInteger(iSub2, pParse->iNextSelectId);
@@ -101301,12 +102160,10 @@ static int multiSelect(
testcase( p->op==TK_EXCEPT );
testcase( p->op==TK_UNION );
priorOp = SRT_Union;
- if( dest.eDest==priorOp && ALWAYS(!p->pLimit &&!p->pOffset) ){
+ if( dest.eDest==priorOp ){
/* We can reuse a temporary table generated by a SELECT to our
** right.
*/
- assert( p->pRightmost!=p ); /* Can only happen for leftward elements
- ** of a 3-way or more compound */
assert( p->pLimit==0 ); /* Not allowed on leftward elements */
assert( p->pOffset==0 ); /* Not allowed on leftward elements */
unionTab = dest.iSDParm;
@@ -101319,7 +102176,7 @@ static int multiSelect(
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
assert( p->addrOpenEphm[0] == -1 );
p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
+ findRightmost(p)->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
}
@@ -101378,12 +102235,12 @@ static int multiSelect(
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
iStart = sqlite3VdbeCurrentAddr(v);
- selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
+ selectInnerLoop(pParse, p, p->pEList, unionTab,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
+ sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak);
sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0);
}
@@ -101408,7 +102265,7 @@ static int multiSelect(
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
assert( p->addrOpenEphm[0] == -1 );
p->addrOpenEphm[0] = addr;
- p->pRightmost->selFlags |= SF_UsesEphemeral;
+ findRightmost(p)->selFlags |= SF_UsesEphemeral;
assert( p->pEList );
/* Code the SELECTs to our left into temporary table "tab1".
@@ -101453,15 +102310,15 @@ static int multiSelect(
iBreak = sqlite3VdbeMakeLabel(v);
iCont = sqlite3VdbeMakeLabel(v);
computeLimitRegisters(pParse, p, iBreak);
- sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
r1 = sqlite3GetTempReg(pParse);
iStart = sqlite3VdbeAddOp2(v, OP_RowKey, tab1, r1);
- sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
+ sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, r1);
- selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
+ selectInnerLoop(pParse, p, p->pEList, tab1,
0, 0, &dest, iCont, iBreak);
sqlite3VdbeResolveLabel(v, iCont);
- sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
+ sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v);
sqlite3VdbeResolveLabel(v, iBreak);
sqlite3VdbeAddOp2(v, OP_Close, tab2, 0);
sqlite3VdbeAddOp2(v, OP_Close, tab1, 0);
@@ -101487,7 +102344,7 @@ static int multiSelect(
CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
int nCol; /* Number of columns in result set */
- assert( p->pRightmost==p );
+ assert( p->pNext==0 );
nCol = p->pEList->nExpr;
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
if( !pKeyInfo ){
@@ -101568,10 +102425,10 @@ static int generateOutputSubroutine(
*/
if( regPrev ){
int j1, j2;
- j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
+ j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
- sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
+ sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, j1);
sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
@@ -101580,7 +102437,7 @@ static int generateOutputSubroutine(
/* Suppress the first OFFSET entries if there is an OFFSET clause
*/
- codeOffset(v, p, iContinue);
+ codeOffset(v, p->iOffset, iContinue);
switch( pDest->eDest ){
/* Store the result as data using a unique key.
@@ -101672,7 +102529,7 @@ static int generateOutputSubroutine(
/* Jump to the end of the loop if the LIMIT is reached.
*/
if( p->iLimit ){
- sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
+ sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
}
/* Generate the subroutine return
@@ -101780,9 +102637,7 @@ static int multiSelectOrderBy(
SelectDest destA; /* Destination for coroutine A */
SelectDest destB; /* Destination for coroutine B */
int regAddrA; /* Address register for select-A coroutine */
- int regEofA; /* Flag to indicate when select-A is complete */
int regAddrB; /* Address register for select-B coroutine */
- int regEofB; /* Flag to indicate when select-B is complete */
int addrSelectA; /* Address of the select-A coroutine */
int addrSelectB; /* Address of the select-B coroutine */
int regOutA; /* Address register for the output-A subroutine */
@@ -101790,6 +102645,7 @@ static int multiSelectOrderBy(
int addrOutA; /* Address of the output-A subroutine */
int addrOutB = 0; /* Address of the output-B subroutine */
int addrEofA; /* Address of the select-A-exhausted subroutine */
+ int addrEofA_noB; /* Alternate addrEofA if B is uninitialized */
int addrEofB; /* Address of the select-B-exhausted subroutine */
int addrAltB; /* Address of the A<B subroutine */
int addrAeqB; /* Address of the A==B subroutine */
@@ -101869,24 +102725,7 @@ static int multiSelectOrderBy(
&& pItem->u.x.iOrderByCol<=p->pEList->nExpr );
aPermute[i] = pItem->u.x.iOrderByCol - 1;
}
- pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1);
- if( pKeyMerge ){
- for(i=0; i<nOrderBy; i++){
- CollSeq *pColl;
- Expr *pTerm = pOrderBy->a[i].pExpr;
- if( pTerm->flags & EP_Collate ){
- pColl = sqlite3ExprCollSeq(pParse, pTerm);
- }else{
- pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
- if( pColl==0 ) pColl = db->pDfltColl;
- pOrderBy->a[i].pExpr =
- sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName);
- }
- assert( sqlite3KeyInfoIsWriteable(pKeyMerge) );
- pKeyMerge->aColl[i] = pColl;
- pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
- }
- }
+ pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
}else{
pKeyMerge = 0;
}
@@ -101921,6 +102760,7 @@ static int multiSelectOrderBy(
/* Separate the left and the right query from one another
*/
p->pPrior = 0;
+ pPrior->pNext = 0;
sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER");
if( pPrior->pPrior==0 ){
sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER");
@@ -101943,37 +102783,30 @@ static int multiSelectOrderBy(
p->pOffset = 0;
regAddrA = ++pParse->nMem;
- regEofA = ++pParse->nMem;
regAddrB = ++pParse->nMem;
- regEofB = ++pParse->nMem;
regOutA = ++pParse->nMem;
regOutB = ++pParse->nMem;
sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
- /* Jump past the various subroutines and coroutines to the main
- ** merge loop
- */
- j1 = sqlite3VdbeAddOp0(v, OP_Goto);
- addrSelectA = sqlite3VdbeCurrentAddr(v);
-
-
/* Generate a coroutine to evaluate the SELECT statement to the
** left of the compound operator - the "A" select.
*/
- VdbeNoopComment((v, "Begin coroutine for left SELECT"));
+ addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
+ j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
+ VdbeComment((v, "left SELECT"));
pPrior->iLimit = regLimitA;
explainSetInteger(iSub1, pParse->iNextSelectId);
sqlite3Select(pParse, pPrior, &destA);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- VdbeNoopComment((v, "End coroutine for left SELECT"));
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA);
+ sqlite3VdbeJumpHere(v, j1);
/* Generate a coroutine to evaluate the SELECT statement on
** the right - the "B" select
*/
- addrSelectB = sqlite3VdbeCurrentAddr(v);
- VdbeNoopComment((v, "Begin coroutine for right SELECT"));
+ addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
+ j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
+ VdbeComment((v, "right SELECT"));
savedLimit = p->iLimit;
savedOffset = p->iOffset;
p->iLimit = regLimitB;
@@ -101982,9 +102815,7 @@ static int multiSelectOrderBy(
sqlite3Select(pParse, p, &destB);
p->iLimit = savedLimit;
p->iOffset = savedOffset;
- sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- VdbeNoopComment((v, "End coroutine for right SELECT"));
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB);
/* Generate a subroutine that outputs the current row of the A
** select as the next output row of the compound select.
@@ -102008,13 +102839,13 @@ static int multiSelectOrderBy(
/* Generate a subroutine to run when the results from select A
** are exhausted and only data in select B remains.
*/
- VdbeNoopComment((v, "eof-A subroutine"));
if( op==TK_EXCEPT || op==TK_INTERSECT ){
- addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd);
+ addrEofA_noB = addrEofA = labelEnd;
}else{
- addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
+ VdbeNoopComment((v, "eof-A subroutine"));
+ addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+ addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd);
+ VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
p->nSelectRow += pPrior->nSelectRow;
}
@@ -102027,9 +102858,8 @@ static int multiSelectOrderBy(
if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow;
}else{
VdbeNoopComment((v, "eof-B subroutine"));
- addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
- sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
+ addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
}
@@ -102037,8 +102867,7 @@ static int multiSelectOrderBy(
*/
VdbeNoopComment((v, "A-lt-B subroutine"));
addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
/* Generate code to handle the case of A==B
@@ -102051,8 +102880,7 @@ static int multiSelectOrderBy(
}else{
VdbeNoopComment((v, "A-eq-B subroutine"));
addrAeqB =
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
}
@@ -102063,19 +102891,14 @@ static int multiSelectOrderBy(
if( op==TK_ALL || op==TK_UNION ){
sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
}
- sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
- sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
/* This code runs once to initialize everything.
*/
sqlite3VdbeJumpHere(v, j1);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA);
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB);
- sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA);
- sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
- sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
- sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
+ sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
/* Implement the main merge loop
*/
@@ -102084,7 +102907,7 @@ static int multiSelectOrderBy(
sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy,
(char*)pKeyMerge, P4_KEYINFO);
sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE);
- sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
+ sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v);
/* Jump to the this point in order to terminate the query.
*/
@@ -102104,6 +102927,7 @@ static int multiSelectOrderBy(
sqlite3SelectDelete(db, p->pPrior);
}
p->pPrior = pPrior;
+ pPrior->pNext = p;
/*** TBD: Insert subroutine calls to close cursors on incomplete
**** subqueries ****/
@@ -102309,6 +103133,14 @@ static void substSelect(
** (21) The subquery does not use LIMIT or the outer query is not
** DISTINCT. (See ticket [752e1646fc]).
**
+** (22) The subquery is not a recursive CTE.
+**
+** (23) The parent is not a recursive CTE, or the sub-query is not a
+** compound query. This restriction is because transforming the
+** parent to a compound query confuses the code that handles
+** recursive queries in multiSelect().
+**
+**
** In this routine, the "p" parameter is a pointer to the outer query.
** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
@@ -102361,7 +103193,7 @@ static int flattenSubquery(
** and (14). */
if( pSub->pLimit && p->pLimit ) return 0; /* Restriction (13) */
if( pSub->pOffset ) return 0; /* Restriction (14) */
- if( p->pRightmost && pSub->pLimit ){
+ if( (p->selFlags & SF_Compound)!=0 && pSub->pLimit ){
return 0; /* Restriction (15) */
}
if( pSubSrc->nSrc==0 ) return 0; /* Restriction (7) */
@@ -102380,6 +103212,8 @@ static int flattenSubquery(
if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
return 0; /* Restriction (21) */
}
+ if( pSub->selFlags & SF_Recursive ) return 0; /* Restriction (22) */
+ if( (p->selFlags & SF_Recursive) && pSub->pPrior ) return 0; /* (23) */
/* OBSOLETE COMMENT 1:
** Restriction 3: If the subquery is a join, make sure the subquery is
@@ -102510,14 +103344,14 @@ static int flattenSubquery(
p->pOrderBy = pOrderBy;
p->pSrc = pSrc;
p->op = TK_ALL;
- p->pRightmost = 0;
if( pNew==0 ){
- pNew = pPrior;
+ p->pPrior = pPrior;
}else{
pNew->pPrior = pPrior;
- pNew->pRightmost = 0;
+ if( pPrior ) pPrior->pNext = pNew;
+ pNew->pNext = p;
+ p->pPrior = pNew;
}
- p->pPrior = pNew;
if( db->mallocFailed ) return 1;
}
@@ -102856,11 +103690,207 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
pNew->pHaving = 0;
pNew->pOrderBy = 0;
p->pPrior = 0;
+ p->pNext = 0;
+ p->selFlags &= ~SF_Compound;
+ assert( pNew->pPrior!=0 );
+ pNew->pPrior->pNext = pNew;
pNew->pLimit = 0;
pNew->pOffset = 0;
return WRC_Continue;
}
+#ifndef SQLITE_OMIT_CTE
+/*
+** Argument pWith (which may be NULL) points to a linked list of nested
+** WITH contexts, from inner to outermost. If the table identified by
+** FROM clause element pItem is really a common-table-expression (CTE)
+** then return a pointer to the CTE definition for that table. Otherwise
+** return NULL.
+**
+** If a non-NULL value is returned, set *ppContext to point to the With
+** object that the returned CTE belongs to.
+*/
+static struct Cte *searchWith(
+ With *pWith, /* Current outermost WITH clause */
+ struct SrcList_item *pItem, /* FROM clause element to resolve */
+ With **ppContext /* OUT: WITH clause return value belongs to */
+){
+ const char *zName;
+ if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){
+ With *p;
+ for(p=pWith; p; p=p->pOuter){
+ int i;
+ for(i=0; i<p->nCte; i++){
+ if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){
+ *ppContext = p;
+ return &p->a[i];
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/* The code generator maintains a stack of active WITH clauses
+** with the inner-most WITH clause being at the top of the stack.
+**
+** This routine pushes the WITH clause passed as the second argument
+** onto the top of the stack. If argument bFree is true, then this
+** WITH clause will never be popped from the stack. In this case it
+** should be freed along with the Parse object. In other cases, when
+** bFree==0, the With object will be freed along with the SELECT
+** statement with which it is associated.
+*/
+SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){
+ assert( bFree==0 || pParse->pWith==0 );
+ if( pWith ){
+ pWith->pOuter = pParse->pWith;
+ pParse->pWith = pWith;
+ pParse->bFreeWith = bFree;
+ }
+}
+
+/*
+** This function checks if argument pFrom refers to a CTE declared by
+** a WITH clause on the stack currently maintained by the parser. And,
+** if currently processing a CTE expression, if it is a recursive
+** reference to the current CTE.
+**
+** If pFrom falls into either of the two categories above, pFrom->pTab
+** and other fields are populated accordingly. The caller should check
+** (pFrom->pTab!=0) to determine whether or not a successful match
+** was found.
+**
+** Whether or not a match is found, SQLITE_OK is returned if no error
+** occurs. If an error does occur, an error message is stored in the
+** parser and some error code other than SQLITE_OK returned.
+*/
+static int withExpand(
+ Walker *pWalker,
+ struct SrcList_item *pFrom
+){
+ Parse *pParse = pWalker->pParse;
+ sqlite3 *db = pParse->db;
+ struct Cte *pCte; /* Matched CTE (or NULL if no match) */
+ With *pWith; /* WITH clause that pCte belongs to */
+
+ assert( pFrom->pTab==0 );
+
+ pCte = searchWith(pParse->pWith, pFrom, &pWith);
+ if( pCte ){
+ Table *pTab;
+ ExprList *pEList;
+ Select *pSel;
+ Select *pLeft; /* Left-most SELECT statement */
+ int bMayRecursive; /* True if compound joined by UNION [ALL] */
+ With *pSavedWith; /* Initial value of pParse->pWith */
+
+ /* If pCte->zErr is non-NULL at this point, then this is an illegal
+ ** recursive reference to CTE pCte. Leave an error in pParse and return
+ ** early. If pCte->zErr is NULL, then this is not a recursive reference.
+ ** In this case, proceed. */
+ if( pCte->zErr ){
+ sqlite3ErrorMsg(pParse, pCte->zErr, pCte->zName);
+ return SQLITE_ERROR;
+ }
+
+ assert( pFrom->pTab==0 );
+ pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
+ if( pTab==0 ) return WRC_Abort;
+ pTab->nRef = 1;
+ pTab->zName = sqlite3DbStrDup(db, pCte->zName);
+ pTab->iPKey = -1;
+ pTab->nRowEst = 1048576;
+ pTab->tabFlags |= TF_Ephemeral;
+ pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
+ if( db->mallocFailed ) return SQLITE_NOMEM;
+ assert( pFrom->pSelect );
+
+ /* Check if this is a recursive CTE. */
+ pSel = pFrom->pSelect;
+ bMayRecursive = ( pSel->op==TK_ALL || pSel->op==TK_UNION );
+ if( bMayRecursive ){
+ int i;
+ SrcList *pSrc = pFrom->pSelect->pSrc;
+ for(i=0; i<pSrc->nSrc; i++){
+ struct SrcList_item *pItem = &pSrc->a[i];
+ if( pItem->zDatabase==0
+ && pItem->zName!=0
+ && 0==sqlite3StrICmp(pItem->zName, pCte->zName)
+ ){
+ pItem->pTab = pTab;
+ pItem->isRecursive = 1;
+ pTab->nRef++;
+ pSel->selFlags |= SF_Recursive;
+ }
+ }
+ }
+
+ /* Only one recursive reference is permitted. */
+ if( pTab->nRef>2 ){
+ sqlite3ErrorMsg(
+ pParse, "multiple references to recursive table: %s", pCte->zName
+ );
+ return SQLITE_ERROR;
+ }
+ assert( pTab->nRef==1 || ((pSel->selFlags&SF_Recursive) && pTab->nRef==2 ));
+
+ pCte->zErr = "circular reference: %s";
+ pSavedWith = pParse->pWith;
+ pParse->pWith = pWith;
+ sqlite3WalkSelect(pWalker, bMayRecursive ? pSel->pPrior : pSel);
+
+ for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
+ pEList = pLeft->pEList;
+ if( pCte->pCols ){
+ if( pEList->nExpr!=pCte->pCols->nExpr ){
+ sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
+ pCte->zName, pEList->nExpr, pCte->pCols->nExpr
+ );
+ pParse->pWith = pSavedWith;
+ return SQLITE_ERROR;
+ }
+ pEList = pCte->pCols;
+ }
+
+ selectColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol);
+ if( bMayRecursive ){
+ if( pSel->selFlags & SF_Recursive ){
+ pCte->zErr = "multiple recursive references: %s";
+ }else{
+ pCte->zErr = "recursive reference in a subquery: %s";
+ }
+ sqlite3WalkSelect(pWalker, pSel);
+ }
+ pCte->zErr = 0;
+ pParse->pWith = pSavedWith;
+ }
+
+ return SQLITE_OK;
+}
+#endif
+
+#ifndef SQLITE_OMIT_CTE
+/*
+** If the SELECT passed as the second argument has an associated WITH
+** clause, pop it from the stack stored as part of the Parse object.
+**
+** This function is used as the xSelectCallback2() callback by
+** sqlite3SelectExpand() when walking a SELECT tree to resolve table
+** names and other FROM clause elements.
+*/
+static void selectPopWith(Walker *pWalker, Select *p){
+ Parse *pParse = pWalker->pParse;
+ With *pWith = findRightmost(p)->pWith;
+ if( pWith!=0 ){
+ assert( pParse->pWith==pWith );
+ pParse->pWith = pWith->pOuter;
+ }
+}
+#else
+#define selectPopWith 0
+#endif
+
/*
** This routine is a Walker callback for "expanding" a SELECT statement.
** "Expanding" means to do the following:
@@ -102904,6 +103934,7 @@ static int selectExpander(Walker *pWalker, Select *p){
}
pTabList = p->pSrc;
pEList = p->pEList;
+ sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
/* Make sure cursor numbers have been assigned to all entries in
** the FROM clause of the SELECT statement.
@@ -102916,12 +103947,21 @@ static int selectExpander(Walker *pWalker, Select *p){
*/
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab;
+ assert( pFrom->isRecursive==0 || pFrom->pTab );
+ if( pFrom->isRecursive ) continue;
if( pFrom->pTab!=0 ){
/* This statement has already been prepared. There is no need
** to go further. */
assert( i==0 );
+#ifndef SQLITE_OMIT_CTE
+ selectPopWith(pWalker, p);
+#endif
return WRC_Prune;
}
+#ifndef SQLITE_OMIT_CTE
+ if( withExpand(pWalker, pFrom) ) return WRC_Abort;
+ if( pFrom->pTab ) {} else
+#endif
if( pFrom->zName==0 ){
#ifndef SQLITE_OMIT_SUBQUERY
Select *pSel = pFrom->pSelect;
@@ -103184,6 +104224,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
sqlite3WalkSelect(&w, pSelect);
}
w.xSelectCallback = selectExpander;
+ w.xSelectCallback2 = selectPopWith;
sqlite3WalkSelect(&w, pSelect);
}
@@ -103202,7 +104243,7 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
** at that point because identifiers had not yet been resolved. This
** routine is called after identifier resolution.
*/
-static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
+static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
Parse *pParse;
int i;
SrcList *pTabList;
@@ -103218,13 +104259,13 @@ static int selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
/* A sub-query in the FROM clause of a SELECT */
Select *pSel = pFrom->pSelect;
- assert( pSel );
- while( pSel->pPrior ) pSel = pSel->pPrior;
- selectAddColumnTypeAndCollation(pParse, pTab, pSel);
+ if( pSel ){
+ while( pSel->pPrior ) pSel = pSel->pPrior;
+ selectAddColumnTypeAndCollation(pParse, pTab, pSel);
+ }
}
}
}
- return WRC_Continue;
}
#endif
@@ -103240,10 +104281,9 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){
#ifndef SQLITE_OMIT_SUBQUERY
Walker w;
memset(&w, 0, sizeof(w));
- w.xSelectCallback = selectAddSubqueryTypeInfo;
+ w.xSelectCallback2 = selectAddSubqueryTypeInfo;
w.xExprCallback = exprWalkNoop;
w.pParse = pParse;
- w.bSelectDepthFirst = 1;
sqlite3WalkSelect(&w, pSelect);
#endif
}
@@ -103290,14 +104330,23 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pFunc;
- if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
- return;
- }
+ int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
+ if( nReg==0 ) return;
+#ifdef SQLITE_DEBUG
+ /* Verify that all AggInfo registers are within the range specified by
+ ** AggInfo.mnReg..AggInfo.mxReg */
+ assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
for(i=0; i<pAggInfo->nColumn; i++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
+ assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aCol[i].iMem<=pAggInfo->mxReg );
+ }
+ for(i=0; i<pAggInfo->nFunc; i++){
+ assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg
+ && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg );
}
+#endif
+ sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
- sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
if( pFunc->iDistinct>=0 ){
Expr *pE = pFunc->pExpr;
assert( !ExprHasProperty(pE, EP_xIsSelect) );
@@ -103306,7 +104355,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
"argument");
pFunc->iDistinct = -1;
}else{
- KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList);
+ KeyInfo *pKeyInfo = keyInfoFromExprList(pParse, pE->x.pList, 0);
sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0,
(char*)pKeyInfo, P4_KEYINFO);
}
@@ -103343,7 +104392,6 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
struct AggInfo_col *pC;
pAggInfo->directMode = 1;
- sqlite3ExprCacheClear(pParse);
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
int nArg;
int addrNext = 0;
@@ -103399,7 +104447,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
** values to an OP_Copy.
*/
if( regHit ){
- addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit);
+ addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v);
}
sqlite3ExprCacheClear(pParse);
for(i=0, pC=pAggInfo->aCol; i<pAggInfo->nAccumulator; i++, pC++){
@@ -103440,50 +104488,8 @@ static void explainSimpleCount(
/*
** Generate code for the SELECT statement given in the p argument.
**
-** The results are distributed in various ways depending on the
-** contents of the SelectDest structure pointed to by argument pDest
-** as follows:
-**
-** pDest->eDest Result
-** ------------ -------------------------------------------
-** SRT_Output Generate a row of output (using the OP_ResultRow
-** opcode) for each row in the result set.
-**
-** SRT_Mem Only valid if the result is a single column.
-** Store the first column of the first result row
-** in register pDest->iSDParm then abandon the rest
-** of the query. This destination implies "LIMIT 1".
-**
-** SRT_Set The result must be a single column. Store each
-** row of result as the key in table pDest->iSDParm.
-** Apply the affinity pDest->affSdst before storing
-** results. Used to implement "IN (SELECT ...)".
-**
-** SRT_Union Store results as a key in a temporary table
-** identified by pDest->iSDParm.
-**
-** SRT_Except Remove results from the temporary table pDest->iSDParm.
-**
-** SRT_Table Store results in temporary table pDest->iSDParm.
-** This is like SRT_EphemTab except that the table
-** is assumed to already be open.
-**
-** SRT_EphemTab Create an temporary table pDest->iSDParm and store
-** the result there. The cursor is left open after
-** returning. This is like SRT_Table except that
-** this destination uses OP_OpenEphemeral to create
-** the table first.
-**
-** SRT_Coroutine Generate a co-routine that returns a new row of
-** results each time it is invoked. The entry point
-** of the co-routine is stored in register pDest->iSDParm.
-**
-** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result
-** set is not empty.
-**
-** SRT_Discard Throw the results away. This is used by SELECT
-** statements within triggers whose only purpose is
-** the side-effects of functions.
+** The results are returned according to the SelectDest structure.
+** See comments in sqliteInt.h for further information.
**
** This routine returns the number of errors. If any errors are
** encountered, then an appropriate error message is left in
@@ -103600,42 +104606,24 @@ SQLITE_PRIVATE int sqlite3Select(
p->selFlags |= SF_Aggregate;
}
i = -1;
- }else if( pTabList->nSrc==1 && (p->selFlags & SF_Materialize)==0
- && OptimizationEnabled(db, SQLITE_SubqCoroutine)
+ }else if( pTabList->nSrc==1
+ && OptimizationEnabled(db, SQLITE_SubqCoroutine)
){
/* Implement a co-routine that will return a single row of the result
** set on each invocation.
*/
- int addrTop;
- int addrEof;
+ int addrTop = sqlite3VdbeCurrentAddr(v)+1;
pItem->regReturn = ++pParse->nMem;
- addrEof = ++pParse->nMem;
- /* Before coding the OP_Goto to jump to the start of the main routine,
- ** ensure that the jump to the verify-schema routine has already
- ** been coded. Otherwise, the verify-schema would likely be coded as
- ** part of the co-routine. If the main routine then accessed the
- ** database before invoking the co-routine for the first time (for
- ** example to initialize a LIMIT register from a sub-select), it would
- ** be doing so without having verified the schema version and obtained
- ** the required db locks. See ticket d6b36be38. */
- sqlite3CodeVerifySchema(pParse, -1);
- sqlite3VdbeAddOp0(v, OP_Goto);
- addrTop = sqlite3VdbeAddOp1(v, OP_OpenPseudo, pItem->iCursor);
- sqlite3VdbeChangeP5(v, 1);
- VdbeComment((v, "coroutine for %s", pItem->pTab->zName));
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop);
+ VdbeComment((v, "%s", pItem->pTab->zName));
pItem->addrFillSub = addrTop;
- sqlite3VdbeAddOp2(v, OP_Integer, 0, addrEof);
- sqlite3VdbeChangeP5(v, 1);
sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
sqlite3Select(pParse, pSub, &dest);
pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
pItem->viaCoroutine = 1;
- sqlite3VdbeChangeP2(v, addrTop, dest.iSdst);
- sqlite3VdbeChangeP3(v, addrTop, dest.nSdst);
- sqlite3VdbeAddOp2(v, OP_Integer, 1, addrEof);
- sqlite3VdbeAddOp1(v, OP_Yield, pItem->regReturn);
- VdbeComment((v, "end %s", pItem->pTab->zName));
+ pItem->regResult = dest.iSdst;
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn);
sqlite3VdbeJumpHere(v, addrTop-1);
sqlite3ClearTempRegCache(pParse);
}else{
@@ -103651,12 +104639,14 @@ SQLITE_PRIVATE int sqlite3Select(
pItem->regReturn = ++pParse->nMem;
topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
pItem->addrFillSub = topAddr+1;
- VdbeNoopComment((v, "materialize %s", pItem->pTab->zName));
if( pItem->isCorrelated==0 ){
/* If the subquery is not correlated and if we are not inside of
** a trigger, then we only need to compute the value of the subquery
** once. */
- onceAddr = sqlite3CodeOnce(pParse);
+ onceAddr = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+ VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName));
+ }else{
+ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName));
}
sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
@@ -103688,21 +104678,6 @@ SQLITE_PRIVATE int sqlite3Select(
/* If there is are a sequence of queries, do the earlier ones first.
*/
if( p->pPrior ){
- if( p->pRightmost==0 ){
- Select *pLoop, *pRight = 0;
- int cnt = 0;
- int mxSelect;
- for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
- pLoop->pRightmost = p;
- pLoop->pNext = pRight;
- pRight = pLoop;
- }
- mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
- if( mxSelect && cnt>mxSelect ){
- sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
- goto select_end;
- }
- }
rc = multiSelect(pParse, p, pDest);
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
return rc;
@@ -103758,7 +104733,7 @@ SQLITE_PRIVATE int sqlite3Select(
*/
if( pOrderBy ){
KeyInfo *pKeyInfo;
- pKeyInfo = keyInfoFromExprList(pParse, pOrderBy);
+ pKeyInfo = keyInfoFromExprList(pParse, pOrderBy, 0);
pOrderBy->iECursor = pParse->nTab++;
p->addrOpenEphm[2] = addrSortIndex =
sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
@@ -103790,7 +104765,7 @@ SQLITE_PRIVATE int sqlite3Select(
sDistinct.tabTnct = pParse->nTab++;
sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
sDistinct.tabTnct, 0, 0,
- (char*)keyInfoFromExprList(pParse, p->pEList),
+ (char*)keyInfoFromExprList(pParse, p->pEList, 0),
P4_KEYINFO);
sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED;
@@ -103824,7 +104799,7 @@ SQLITE_PRIVATE int sqlite3Select(
}
/* Use the standard inner loop. */
- selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, &sDistinct, pDest,
+ selectInnerLoop(pParse, p, pEList, -1, pOrderBy, &sDistinct, pDest,
sqlite3WhereContinueLabel(pWInfo),
sqlite3WhereBreakLabel(pWInfo));
@@ -103876,6 +104851,7 @@ SQLITE_PRIVATE int sqlite3Select(
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
+ sAggInfo.mnReg = pParse->nMem+1;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
@@ -103890,6 +104866,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
}
+ sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
@@ -103912,7 +104889,7 @@ SQLITE_PRIVATE int sqlite3Select(
** will be converted into a Noop.
*/
sAggInfo.sortingIdx = pParse->nTab++;
- pKeyInfo = keyInfoFromExprList(pParse, pGroupBy);
+ pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0);
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
0, (char*)pKeyInfo, P4_KEYINFO);
@@ -104004,7 +104981,7 @@ SQLITE_PRIVATE int sqlite3Select(
sortOut = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
- VdbeComment((v, "GROUP BY sort"));
+ VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
sAggInfo.useSortingIdx = 1;
sqlite3ExprCacheClear(pParse);
}
@@ -104031,7 +105008,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
j1 = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
+ sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); VdbeCoverage(v);
/* Generate code that runs whenever the GROUP BY changes.
** Changes in the GROUP BY are detected by the previous code
@@ -104045,7 +105022,7 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
VdbeComment((v, "output one row"));
- sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
+ sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
VdbeComment((v, "check abort flag"));
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
VdbeComment((v, "reset accumulator"));
@@ -104062,6 +105039,7 @@ SQLITE_PRIVATE int sqlite3Select(
*/
if( groupBySort ){
sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
+ VdbeCoverage(v);
}else{
sqlite3WhereEnd(pWInfo);
sqlite3VdbeChangeToNoop(v, addrSortingIdx);
@@ -104089,12 +105067,12 @@ SQLITE_PRIVATE int sqlite3Select(
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
sqlite3VdbeResolveLabel(v, addrOutputRow);
addrOutputRow = sqlite3VdbeCurrentAddr(v);
- sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
+ sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v);
VdbeComment((v, "Groupby result generator entry point"));
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, &sAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
+ selectInnerLoop(pParse, p, p->pEList, -1, pOrderBy,
&sDistinct, pDest,
addrOutputRow+1, addrSetAbort);
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
@@ -104237,7 +105215,7 @@ SQLITE_PRIVATE int sqlite3Select(
pOrderBy = 0;
sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
- selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, 0,
+ selectInnerLoop(pParse, p, p->pEList, -1, 0, 0,
pDest, addrEnd, addrEnd);
sqlite3ExprListDelete(db, pDel);
}
@@ -104362,10 +105340,6 @@ SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
sqlite3ExplainPrintf(pVdbe, "(null-select)");
return;
}
- while( p->pPrior ){
- p->pPrior->pNext = p;
- p = p->pPrior;
- }
sqlite3ExplainPush(pVdbe);
while( p ){
explainOneSelect(pVdbe, p);
@@ -104981,25 +105955,21 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(
sqlite3 *db, /* The database connection */
Token *pTableName, /* Name of the table into which we insert */
IdList *pColumn, /* List of columns in pTableName to insert into */
- ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
Select *pSelect, /* A SELECT statement that supplies values */
u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
TriggerStep *pTriggerStep;
- assert(pEList == 0 || pSelect == 0);
- assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
+ assert(pSelect != 0 || db->mallocFailed);
pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
if( pTriggerStep ){
pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
pTriggerStep->pIdList = pColumn;
- pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
pTriggerStep->orconf = orconf;
}else{
sqlite3IdListDelete(db, pColumn);
}
- sqlite3ExprListDelete(db, pEList);
sqlite3SelectDelete(db, pSelect);
return pTriggerStep;
@@ -105154,6 +106124,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
assert( pTable!=0 );
if( (v = sqlite3GetVdbe(pParse))!=0 ){
int base;
+ static const int iLn = VDBE_OFFSET_LINENO(2);
static const VdbeOpList dropTrigger[] = {
{ OP_Rewind, 0, ADDR(9), 0},
{ OP_String8, 0, 1, 0}, /* 1 */
@@ -105168,7 +106139,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){
sqlite3BeginWriteOperation(pParse, 0, iDb);
sqlite3OpenMasterTable(pParse, iDb);
- base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
+ base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger, iLn);
sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
sqlite3ChangeCookie(pParse, iDb);
@@ -105314,15 +106285,7 @@ static int codeTriggerProgram(
** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy
*/
pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf;
-
- /* Clear the cookieGoto flag. When coding triggers, the cookieGoto
- ** variable is used as a flag to indicate to sqlite3ExprCodeConstants()
- ** that it is not safe to refactor constants (this happens after the
- ** start of the first loop in the SQL statement is coded - at that
- ** point code may be conditionally executed, so it is no longer safe to
- ** initialize constant register values). */
- assert( pParse->cookieGoto==0 || pParse->cookieGoto==-1 );
- pParse->cookieGoto = 0;
+ assert( pParse->okConstFactor==0 );
switch( pStep->op ){
case TK_UPDATE: {
@@ -105337,7 +106300,6 @@ static int codeTriggerProgram(
case TK_INSERT: {
sqlite3Insert(pParse,
targetSrcList(pParse, pStep),
- sqlite3ExprListDup(db, pStep->pExprList, 0),
sqlite3SelectDup(db, pStep->pSelect, 0),
sqlite3IdListDup(db, pStep->pIdList),
pParse->eOrconf
@@ -105794,7 +106756,7 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
}
#ifndef SQLITE_OMIT_FLOATING_POINT
- if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
+ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
@@ -106112,7 +107074,7 @@ SQLITE_PRIVATE void sqlite3Update(
regKey = iPk;
}else{
sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey,
- sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT);
+ sqlite3IndexAffinityStr(v, pPk), nPk);
sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, regKey);
}
sqlite3WhereEnd(pWInfo);
@@ -106156,18 +107118,23 @@ SQLITE_PRIVATE void sqlite3Update(
if( aToOpen[iDataCur-iBaseCur] ){
assert( pPk!=0 );
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
+ VdbeCoverageNeverTaken(v);
}
labelContinue = labelBreak;
sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
+ VdbeCoverage(v);
}else if( pPk ){
labelContinue = sqlite3VdbeMakeLabel(v);
- sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak);
+ sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
addrTop = sqlite3VdbeAddOp2(v, OP_RowKey, iEph, regKey);
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
+ VdbeCoverage(v);
}else{
labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, labelBreak,
regOldRowid);
+ VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ VdbeCoverage(v);
}
/* If the record number will change, set register regNewRowid to
@@ -106177,7 +107144,7 @@ SQLITE_PRIVATE void sqlite3Update(
assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
if( chngRowid ){
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
- sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid);
+ sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v);
}
/* Compute the old pre-UPDATE content of the row being changed, if that
@@ -106189,9 +107156,10 @@ SQLITE_PRIVATE void sqlite3Update(
);
for(i=0; i<pTab->nCol; i++){
if( oldmask==0xffffffff
- || (i<32 && (oldmask & (1<<i)))
+ || (i<32 && (oldmask & MASKBIT32(i))!=0)
|| (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
){
+ testcase( oldmask!=0xffffffff && i==31 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regOld+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regOld+i);
@@ -106218,15 +107186,15 @@ SQLITE_PRIVATE void sqlite3Update(
newmask = sqlite3TriggerColmask(
pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
);
- sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
+ /*sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);*/
for(i=0; i<pTab->nCol; i++){
if( i==pTab->iPKey ){
- /*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}else{
j = aXRef[i];
if( j>=0 ){
sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
- }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask&(1<<i)) ){
+ }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){
/* This branch loads the value of a column that will not be changed
** into a register. This is done if there are no BEFORE triggers, or
** if there are one or more BEFORE triggers that use this value via
@@ -106235,6 +107203,8 @@ SQLITE_PRIVATE void sqlite3Update(
testcase( i==31 );
testcase( i==32 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
+ }else{
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}
}
}
@@ -106243,8 +107213,7 @@ SQLITE_PRIVATE void sqlite3Update(
** verified. One could argue that this is wrong.
*/
if( tmask&TRIGGER_BEFORE ){
- sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol);
- sqlite3TableAffinityStr(v, pTab);
+ sqlite3TableAffinity(v, pTab, regNew);
sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges,
TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue);
@@ -106256,8 +107225,10 @@ SQLITE_PRIVATE void sqlite3Update(
*/
if( pPk ){
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey);
+ VdbeCoverage(v);
}else{
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid);
+ VdbeCoverage(v);
}
/* If it did not delete it, the row-trigger may still have modified
@@ -106293,6 +107264,7 @@ SQLITE_PRIVATE void sqlite3Update(
}else{
j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
}
+ VdbeCoverageNeverTaken(v);
}
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx);
@@ -106336,7 +107308,7 @@ SQLITE_PRIVATE void sqlite3Update(
/* Nothing to do at end-of-loop for a single-pass */
}else if( pPk ){
sqlite3VdbeResolveLabel(v, labelContinue);
- sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop);
+ sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v);
}else{
sqlite3VdbeAddOp2(v, OP_Goto, 0, labelContinue);
}
@@ -106465,7 +107437,7 @@ static void updateVirtualTable(
/* Generate code to scan the ephemeral table and call VUpdate. */
iReg = ++pParse->nMem;
pParse->nMem += pTab->nCol+1;
- addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0);
+ addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg);
sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
for(i=0; i<pTab->nCol; i++){
@@ -106475,7 +107447,7 @@ static void updateVirtualTable(
sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
sqlite3MayAbort(pParse);
- sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1);
+ sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, addr);
sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
@@ -108047,7 +109019,7 @@ struct WhereLevel {
int addrFirst; /* First instruction of interior of the loop */
int addrBody; /* Beginning of the body of this loop */
u8 iFrom; /* Which entry in the FROM clause */
- u8 op, p5; /* Opcode and P5 of the opcode that ends the loop */
+ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
int p1, p2; /* Operands of the opcode used to ends the loop */
union { /* Information that depends on pWLoop->wsFlags */
struct {
@@ -108434,6 +109406,7 @@ struct WhereInfo {
#define WHERE_MULTI_OR 0x00002000 /* OR using multiple indices */
#define WHERE_AUTO_INDEX 0x00004000 /* Uses an ephemeral index */
#define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */
+#define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/
/************** End of whereInt.h ********************************************/
/************** Continuing where we left off in where.c **********************/
@@ -109086,7 +110059,7 @@ static int isLikeOrGlob(
}
assert( pLeft->iColumn!=(-1) ); /* Because IPK never has AFF_TEXT */
- pRight = pList->a[0].pExpr;
+ pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
op = pRight->op;
if( op==TK_VARIABLE ){
Vdbe *pReprepare = pParse->pReprepare;
@@ -110020,7 +110993,7 @@ static void constructAutomaticIndex(
** transient index on 2nd and subsequent iterations of the loop. */
v = pParse->pVdbe;
assert( v!=0 );
- addrInit = sqlite3CodeOnce(pParse);
+ addrInit = sqlite3CodeOnce(pParse); VdbeCoverage(v);
/* Count the number of columns that will be added to the index
** and used to match WHERE clause constraints */
@@ -110127,12 +111100,12 @@ static void constructAutomaticIndex(
VdbeComment((v, "for %s", pTable->zName));
/* Fill the automatic index with content */
- addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
regRecord = sqlite3GetTempReg(pParse);
- sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0);
+ sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
- sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
+ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
sqlite3VdbeJumpHere(v, addrTop);
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -110170,7 +111143,8 @@ static sqlite3_index_info *allocateIndexInfo(
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
testcase( pTerm->eOperator & WO_IN );
testcase( pTerm->eOperator & WO_ISNULL );
- if( pTerm->eOperator & (WO_ISNULL) ) continue;
+ testcase( pTerm->eOperator & WO_ALL );
+ if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
nTerm++;
}
@@ -110222,7 +111196,8 @@ static sqlite3_index_info *allocateIndexInfo(
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
testcase( pTerm->eOperator & WO_IN );
testcase( pTerm->eOperator & WO_ISNULL );
- if( pTerm->eOperator & (WO_ISNULL) ) continue;
+ testcase( pTerm->eOperator & WO_ALL );
+ if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
if( pTerm->wtFlags & TERM_VNULL ) continue;
pIdxCons[j].iColumn = pTerm->u.leftColumn;
pIdxCons[j].iTermOffset = i;
@@ -110330,7 +111305,7 @@ static void whereKeyStats(
assert( pRec->nField>0 && iCol<pIdx->nSampleCol );
do{
iTest = (iMin+i)/2;
- res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec);
+ res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec, 0);
if( res<0 ){
iMin = iTest+1;
}else{
@@ -110345,16 +111320,16 @@ static void whereKeyStats(
if( res==0 ){
/* If (res==0) is true, then sample $i must be equal to pRec */
assert( i<pIdx->nSample );
- assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)
+ assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)
|| pParse->db->mallocFailed );
}else{
/* Otherwise, pRec must be smaller than sample $i and larger than
** sample ($i-1). */
assert( i==pIdx->nSample
- || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
+ || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)>0
|| pParse->db->mallocFailed );
assert( i==0
- || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
+ || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec, 0)<0
|| pParse->db->mallocFailed );
}
#endif /* ifdef SQLITE_DEBUG */
@@ -110806,6 +111781,8 @@ static int codeEqualityTerm(
}
iTab = pX->iTable;
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
+ VdbeCoverageIf(v, bRev);
+ VdbeCoverageIf(v, !bRev);
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
pLoop->wsFlags |= WHERE_IN_ABLE;
if( pLevel->u.in.nIn==0 ){
@@ -110825,7 +111802,7 @@ static int codeEqualityTerm(
pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
}
pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen;
- sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
+ sqlite3VdbeAddOp1(v, OP_IsNull, iReg); VdbeCoverage(v);
}else{
pLevel->u.in.nIn = 0;
}
@@ -110920,10 +111897,14 @@ static int codeAllEqualityTerms(
if( nSkip ){
int iIdxCur = pLevel->iIdxCur;
sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
VdbeComment((v, "begin skip-scan on %s", pIdx->zName));
j = sqlite3VdbeAddOp0(v, OP_Goto);
- pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLt:OP_SeekGt),
+ pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
iIdxCur, 0, regBase, nSkip);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
sqlite3VdbeJumpHere(v, j);
for(j=0; j<nSkip; j++){
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
@@ -110956,7 +111937,10 @@ static int codeAllEqualityTerms(
testcase( pTerm->eOperator & WO_IN );
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
Expr *pRight = pTerm->pExpr->pRight;
- sqlite3ExprCodeIsNullJump(v, pRight, regBase+j, pLevel->addrBrk);
+ if( sqlite3ExprCanBeNull(pRight) ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
+ VdbeCoverage(v);
+ }
if( zAff ){
if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
zAff[j] = SQLITE_AFF_NONE;
@@ -110987,7 +111971,7 @@ static void explainAppendTerm(
const char *zOp /* Name of the operator */
){
if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5);
- sqlite3StrAccumAppend(pStr, zColumn, -1);
+ sqlite3StrAccumAppendAll(pStr, zColumn);
sqlite3StrAccumAppend(pStr, zOp, 1);
sqlite3StrAccumAppend(pStr, "?", 1);
}
@@ -111033,7 +112017,7 @@ static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
}else{
if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
sqlite3StrAccumAppend(&txt, "ANY(", 4);
- sqlite3StrAccumAppend(&txt, z, -1);
+ sqlite3StrAccumAppendAll(&txt, z);
sqlite3StrAccumAppend(&txt, ")", 1);
}
}
@@ -111202,10 +112186,10 @@ static Bitmask codeOneLoopStart(
/* Special case of a FROM clause subquery implemented as a co-routine */
if( pTabItem->viaCoroutine ){
int regYield = pTabItem->regReturn;
- sqlite3VdbeAddOp2(v, OP_Integer, pTabItem->addrFillSub-1, regYield);
- pLevel->p2 = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
- VdbeComment((v, "next row of co-routine %s", pTabItem->pTab->zName));
- sqlite3VdbeAddOp2(v, OP_If, regYield+1, addrBrk);
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
+ pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk);
+ VdbeCoverage(v);
+ VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
pLevel->op = OP_Goto;
}else
@@ -111237,6 +112221,7 @@ static Bitmask codeOneLoopStart(
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
pLoop->u.vtab.idxStr,
pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
+ VdbeCoverage(v);
pLoop->u.vtab.needFree = 0;
for(j=0; j<nConstraint && j<16; j++){
if( (pLoop->u.vtab.omitMask>>j)&1 ){
@@ -111260,16 +112245,18 @@ static Bitmask codeOneLoopStart(
** construct.
*/
assert( pLoop->u.btree.nEq==1 );
- iReleaseReg = sqlite3GetTempReg(pParse);
pTerm = pLoop->aLTerm[0];
assert( pTerm!=0 );
assert( pTerm->pExpr!=0 );
assert( omitTable==0 );
testcase( pTerm->wtFlags & TERM_VIRTUAL );
+ iReleaseReg = ++pParse->nMem;
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
+ if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
addrNxt = pLevel->addrNxt;
- sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
+ sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt); VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
+ VdbeCoverage(v);
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
VdbeComment((v, "pk"));
@@ -111303,10 +112290,10 @@ static Bitmask codeOneLoopStart(
** seek opcodes. It depends on a particular ordering of TK_xx
*/
const u8 aMoveOp[] = {
- /* TK_GT */ OP_SeekGt,
- /* TK_LE */ OP_SeekLe,
- /* TK_LT */ OP_SeekLt,
- /* TK_GE */ OP_SeekGe
+ /* TK_GT */ OP_SeekGT,
+ /* TK_LE */ OP_SeekLE,
+ /* TK_LT */ OP_SeekLT,
+ /* TK_GE */ OP_SeekGE
};
assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
@@ -111320,11 +112307,17 @@ static Bitmask codeOneLoopStart(
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
VdbeComment((v, "pk"));
+ VdbeCoverageIf(v, pX->op==TK_GT);
+ VdbeCoverageIf(v, pX->op==TK_LE);
+ VdbeCoverageIf(v, pX->op==TK_LT);
+ VdbeCoverageIf(v, pX->op==TK_GE);
sqlite3ExprCacheAffinityChange(pParse, r1, 1);
sqlite3ReleaseTempReg(pParse, rTemp);
disableTerm(pLevel, pStart);
}else{
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrBrk);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
}
if( pEnd ){
Expr *pX;
@@ -111348,10 +112341,14 @@ static Bitmask codeOneLoopStart(
pLevel->p2 = start;
assert( pLevel->p5==0 );
if( testOp!=OP_Noop ){
- iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
+ iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg);
+ VdbeCoverageIf(v, testOp==OP_Le);
+ VdbeCoverageIf(v, testOp==OP_Lt);
+ VdbeCoverageIf(v, testOp==OP_Ge);
+ VdbeCoverageIf(v, testOp==OP_Gt);
sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL);
}
}else if( pLoop->wsFlags & WHERE_INDEXED ){
@@ -111391,20 +112388,19 @@ static Bitmask codeOneLoopStart(
0,
OP_Rewind, /* 2: (!start_constraints && startEq && !bRev) */
OP_Last, /* 3: (!start_constraints && startEq && bRev) */
- OP_SeekGt, /* 4: (start_constraints && !startEq && !bRev) */
- OP_SeekLt, /* 5: (start_constraints && !startEq && bRev) */
- OP_SeekGe, /* 6: (start_constraints && startEq && !bRev) */
- OP_SeekLe /* 7: (start_constraints && startEq && bRev) */
+ OP_SeekGT, /* 4: (start_constraints && !startEq && !bRev) */
+ OP_SeekLT, /* 5: (start_constraints && !startEq && bRev) */
+ OP_SeekGE, /* 6: (start_constraints && startEq && !bRev) */
+ OP_SeekLE /* 7: (start_constraints && startEq && bRev) */
};
static const u8 aEndOp[] = {
- OP_Noop, /* 0: (!end_constraints) */
- OP_IdxGE, /* 1: (end_constraints && !bRev) */
- OP_IdxLT /* 2: (end_constraints && bRev) */
+ OP_IdxGE, /* 0: (end_constraints && !bRev && !endEq) */
+ OP_IdxGT, /* 1: (end_constraints && !bRev && endEq) */
+ OP_IdxLE, /* 2: (end_constraints && bRev && !endEq) */
+ OP_IdxLT, /* 3: (end_constraints && bRev && endEq) */
};
u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */
- int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */
int regBase; /* Base register holding constraint values */
- int r1; /* Temp register */
WhereTerm *pRangeStart = 0; /* Inequality constraint at range start */
WhereTerm *pRangeEnd = 0; /* Inequality constraint at range end */
int startEq; /* True if range start uses ==, >= or <= */
@@ -111417,6 +112413,8 @@ static Bitmask codeOneLoopStart(
int op; /* Instruction opcode */
char *zStartAff; /* Affinity for start of range constraint */
char cEndAff = 0; /* Affinity for end of range constraint */
+ u8 bSeekPastNull = 0; /* True to seek past initial nulls */
+ u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */
pIdx = pLoop->u.btree.pIndex;
iIdxCur = pLevel->iIdxCur;
@@ -111435,7 +112433,7 @@ static Bitmask codeOneLoopStart(
&& (pIdx->nKeyCol>nEq)
){
assert( pLoop->u.btree.nSkip==0 );
- isMinQuery = 1;
+ bSeekPastNull = 1;
nExtraReg = 1;
}
@@ -111450,7 +112448,14 @@ static Bitmask codeOneLoopStart(
if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
pRangeEnd = pLoop->aLTerm[j++];
nExtraReg = 1;
+ if( pRangeStart==0
+ && (j = pIdx->aiColumn[nEq])>=0
+ && pIdx->pTable->aCol[j].notNull==0
+ ){
+ bSeekPastNull = 1;
+ }
}
+ assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 );
/* Generate code to evaluate all constraint terms using == or IN
** and store the values of those terms in an array of registers
@@ -111469,6 +112474,7 @@ static Bitmask codeOneLoopStart(
|| (bRev && pIdx->nKeyCol==nEq)
){
SWAP(WhereTerm *, pRangeEnd, pRangeStart);
+ SWAP(u8, bSeekPastNull, bStopAtNull);
}
testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 );
@@ -111484,8 +112490,11 @@ static Bitmask codeOneLoopStart(
if( pRangeStart ){
Expr *pRight = pRangeStart->pExpr->pRight;
sqlite3ExprCode(pParse, pRight, regBase+nEq);
- if( (pRangeStart->wtFlags & TERM_VNULL)==0 ){
- sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
+ if( (pRangeStart->wtFlags & TERM_VNULL)==0
+ && sqlite3ExprCanBeNull(pRight)
+ ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
+ VdbeCoverage(v);
}
if( zStartAff ){
if( sqlite3CompareAffinity(pRight, zStartAff[nEq])==SQLITE_AFF_NONE){
@@ -111500,22 +112509,23 @@ static Bitmask codeOneLoopStart(
}
nConstraint++;
testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
- }else if( isMinQuery ){
+ }else if( bSeekPastNull ){
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
nConstraint++;
startEq = 0;
start_constraints = 1;
}
- codeApplyAffinity(pParse, regBase, nConstraint, zStartAff);
+ codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff);
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
assert( op!=0 );
- testcase( op==OP_Rewind );
- testcase( op==OP_Last );
- testcase( op==OP_SeekGt );
- testcase( op==OP_SeekGe );
- testcase( op==OP_SeekLe );
- testcase( op==OP_SeekLt );
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind );
+ VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last );
+ VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT );
+ VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE );
+ VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE );
+ VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT );
/* Load the value for the inequality constraint at the end of the
** range (if any).
@@ -111525,8 +112535,11 @@ static Bitmask codeOneLoopStart(
Expr *pRight = pRangeEnd->pExpr->pRight;
sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
sqlite3ExprCode(pParse, pRight, regBase+nEq);
- if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){
- sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt);
+ if( (pRangeEnd->wtFlags & TERM_VNULL)==0
+ && sqlite3ExprCanBeNull(pRight)
+ ){
+ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
+ VdbeCoverage(v);
}
if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE
&& !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff)
@@ -111535,6 +112548,10 @@ static Bitmask codeOneLoopStart(
}
nConstraint++;
testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
+ }else if( bStopAtNull ){
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
+ endEq = 0;
+ nConstraint++;
}
sqlite3DbFree(db, zStartAff);
@@ -111542,32 +112559,14 @@ static Bitmask codeOneLoopStart(
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
/* Check if the index cursor is past the end of the range. */
- op = aEndOp[(pRangeEnd || nEq) * (1 + bRev)];
- testcase( op==OP_Noop );
- testcase( op==OP_IdxGE );
- testcase( op==OP_IdxLT );
- if( op!=OP_Noop ){
+ if( nConstraint ){
+ op = aEndOp[bRev*2 + endEq];
sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint);
- sqlite3VdbeChangeP5(v, endEq!=bRev ?1:0);
- }
-
- /* If there are inequality constraints, check that the value
- ** of the table column that the inequality contrains is not NULL.
- ** If it is, jump to the next iteration of the loop.
- */
- r1 = sqlite3GetTempReg(pParse);
- testcase( pLoop->wsFlags & WHERE_BTM_LIMIT );
- testcase( pLoop->wsFlags & WHERE_TOP_LIMIT );
- if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
- && (j = pIdx->aiColumn[nEq])>=0
- && pIdx->pTable->aCol[j].notNull==0
- && (nEq || (pLoop->wsFlags & WHERE_BTM_LIMIT)==0)
- ){
- sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1);
- VdbeComment((v, "%s", pIdx->pTable->aCol[j].zName));
- sqlite3VdbeAddOp2(v, OP_IsNull, r1, addrCont);
+ testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT );
+ testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE );
+ testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT );
+ testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE );
}
- sqlite3ReleaseTempReg(pParse, r1);
/* Seek the table cursor, if required */
disableTerm(pLevel, pRangeStart);
@@ -111575,7 +112574,7 @@ static Bitmask codeOneLoopStart(
if( omitTable ){
/* pIdx is a covering index. No need to access the main table. */
}else if( HasRowid(pIdx->pTable) ){
- iRowidReg = iReleaseReg = sqlite3GetTempReg(pParse);
+ iRowidReg = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */
@@ -111587,7 +112586,7 @@ static Bitmask codeOneLoopStart(
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
}
sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont,
- iRowidReg, pPk->nKeyCol);
+ iRowidReg, pPk->nKeyCol); VdbeCoverage(v);
}
/* Record the instruction used to terminate the loop. Disable
@@ -111601,6 +112600,8 @@ static Bitmask codeOneLoopStart(
pLevel->op = OP_Next;
}
pLevel->p1 = iIdxCur;
+ assert( (WHERE_UNQ_WANTED>>16)==1 );
+ pLevel->p3 = (pLoop->wsFlags>>16)&1;
if( (pLoop->wsFlags & WHERE_CONSTRAINT)==0 ){
pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
}else{
@@ -111731,7 +112732,9 @@ static Bitmask codeOneLoopStart(
Expr *pExpr = pWC->a[iTerm].pExpr;
if( &pWC->a[iTerm] == pTerm ) continue;
if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
- if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
+ testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
+ testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
+ if( pWC->a[iTerm].wtFlags & (TERM_ORINFO|TERM_VIRTUAL) ) continue;
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
pExpr = sqlite3ExprDup(db, pExpr, 0);
pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
@@ -111767,6 +112770,7 @@ static Bitmask codeOneLoopStart(
regRowid, 0);
sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset,
sqlite3VdbeCurrentAddr(v)+2, r, iSet);
+ VdbeCoverage(v);
}
sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
@@ -111827,10 +112831,18 @@ static Bitmask codeOneLoopStart(
static const u8 aStep[] = { OP_Next, OP_Prev };
static const u8 aStart[] = { OP_Rewind, OP_Last };
assert( bRev==0 || bRev==1 );
- pLevel->op = aStep[bRev];
- pLevel->p1 = iCur;
- pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
- pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+ if( pTabItem->isRecursive ){
+ /* Tables marked isRecursive have only a single row that is stored in
+ ** a pseudo-cursor. No need to Rewind or Next such cursors. */
+ pLevel->op = OP_Noop;
+ }else{
+ pLevel->op = aStep[bRev];
+ pLevel->p1 = iCur;
+ pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk);
+ VdbeCoverageIf(v, bRev==0);
+ VdbeCoverageIf(v, bRev!=0);
+ pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP;
+ }
}
/* Insert code to test every subexpression that can be completely
@@ -111910,7 +112922,6 @@ static Bitmask codeOneLoopStart(
pTerm->wtFlags |= TERM_CODED;
}
}
- sqlite3ReleaseTempReg(pParse, iReleaseReg);
return pLevel->notReady;
}
@@ -112347,6 +113358,7 @@ static int whereLoopAddBtreeIndex(
&& saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */
+ && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
pNew->u.btree.nEq++;
@@ -112354,7 +113366,10 @@ static int whereLoopAddBtreeIndex(
pNew->aLTerm[pNew->nLTerm++] = 0;
pNew->wsFlags |= WHERE_SKIPSCAN;
nIter = sqlite3LogEst(pProbe->aiRowEst[0]/pProbe->aiRowEst[saved_nEq+1]);
+ pNew->rRun = rLogSize + nIter;
+ pNew->nOut += nIter;
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter);
+ pNew->nOut = saved_nOut;
}
for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
int nIn = 0;
@@ -112396,12 +113411,13 @@ static int whereLoopAddBtreeIndex(
|| nInMul==0
);
pNew->wsFlags |= WHERE_COLUMN_EQ;
- if( iCol<0
- || (pProbe->onError!=OE_None && nInMul==0
- && pNew->u.btree.nEq==pProbe->nKeyCol-1)
- ){
+ if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1)){
assert( (pNew->wsFlags & WHERE_COLUMN_IN)==0 || iCol<0 );
- pNew->wsFlags |= WHERE_ONEROW;
+ if( iCol>=0 && pProbe->onError==OE_None ){
+ pNew->wsFlags |= WHERE_UNQ_WANTED;
+ }else{
+ pNew->wsFlags |= WHERE_ONEROW;
+ }
}
pNew->u.btree.nEq++;
pNew->nOut = nRowEst + nInMul;
@@ -112614,6 +113630,7 @@ static int whereLoopAddBtree(
&& !pSrc->notIndexed
&& HasRowid(pTab)
&& !pSrc->isCorrelated
+ && !pSrc->isRecursive
){
/* Generate auto-index WhereLoops */
WhereTerm *pTerm;
@@ -113279,9 +114296,12 @@ static int wherePathSatisfiesOrderBy(
orderDistinctMask |= pLoop->maskSelf;
for(i=0; i<nOrderBy; i++){
Expr *p;
+ Bitmask mTerm;
if( MASKBIT(i) & obSat ) continue;
p = pOrderBy->a[i].pExpr;
- if( (exprTableUsage(&pWInfo->sMaskSet, p)&~orderDistinctMask)==0 ){
+ mTerm = exprTableUsage(&pWInfo->sMaskSet,p);
+ if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
+ if( (mTerm&~orderDistinctMask)==0 ){
obSat |= MASKBIT(i);
}
}
@@ -113843,14 +114863,16 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
initMaskSet(pMaskSet);
whereClauseInit(&pWInfo->sWC, pWInfo);
whereSplit(&pWInfo->sWC, pWhere, TK_AND);
- sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
/* Special case: a WHERE clause that is constant. Evaluate the
** expression and either jump over all of the code or fall thru.
*/
- if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
- sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
- pWhere = 0;
+ for(ii=0; ii<sWLB.pWC->nTerm; ii++){
+ if( nTabList==0 || sqlite3ExprIsConstantNotJoin(sWLB.pWC->a[ii].pExpr) ){
+ sqlite3ExprIfFalse(pParse, sWLB.pWC->a[ii].pExpr, pWInfo->iBreak,
+ SQLITE_JUMPIFNULL);
+ sWLB.pWC->a[ii].wtFlags |= TERM_CODED;
+ }
}
/* Special case: No FROM clause
@@ -113902,22 +114924,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
goto whereBeginError;
}
- /* If the ORDER BY (or GROUP BY) clause contains references to general
- ** expressions, then we won't be able to satisfy it using indices, so
- ** go ahead and disable it now.
- */
- if( pOrderBy && (wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){
- for(ii=0; ii<pOrderBy->nExpr; ii++){
- Expr *pExpr = sqlite3ExprSkipCollate(pOrderBy->a[ii].pExpr);
- if( pExpr->op!=TK_COLUMN ){
- pWInfo->pOrderBy = pOrderBy = 0;
- break;
- }else if( pExpr->iColumn<0 ){
- break;
- }
- }
- }
-
if( wctrlFlags & WHERE_WANT_DISTINCT ){
if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
/* The DISTINCT marking is pointless. Ignore it. */
@@ -114129,7 +115135,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
VdbeComment((v, "%s", pIx->zName));
}
- sqlite3CodeVerifySchema(pParse, iDb);
+ if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb);
notReady &= ~getMask(&pWInfo->sMaskSet, pTabItem->iCursor);
}
pWInfo->iTop = sqlite3VdbeCurrentAddr(v);
@@ -114191,8 +115197,12 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
pLoop = pLevel->pWLoop;
sqlite3VdbeResolveLabel(v, pLevel->addrCont);
if( pLevel->op!=OP_Noop ){
- sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2);
+ sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, pLevel->op==OP_Next);
+ VdbeCoverageIf(v, pLevel->op==OP_Prev);
+ VdbeCoverageIf(v, pLevel->op==OP_VNext);
}
if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
struct InLoop *pIn;
@@ -114201,6 +115211,9 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
+ VdbeCoverage(v);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_PrevIfOpen);
+ VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
}
sqlite3DbFree(db, pLevel->u.in.aInLoop);
@@ -114213,7 +115226,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
}
if( pLevel->iLeftJoin ){
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin);
+ addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
|| (pLoop->wsFlags & WHERE_INDEXED)!=0 );
if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ){
@@ -114240,12 +115253,38 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
assert( pWInfo->nLevel<=pTabList->nSrc );
for(i=0, pLevel=pWInfo->a; i<pWInfo->nLevel; i++, pLevel++){
+ int k, last;
+ VdbeOp *pOp;
Index *pIdx = 0;
struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
Table *pTab = pTabItem->pTab;
assert( pTab!=0 );
pLoop = pLevel->pWLoop;
+ /* For a co-routine, change all OP_Column references to the table of
+ ** the co-routine into OP_SCopy of result contained in a register.
+ ** OP_Rowid becomes OP_Null.
+ */
+ if( pTabItem->viaCoroutine && !db->mallocFailed ){
+ last = sqlite3VdbeCurrentAddr(v);
+ k = pLevel->addrBody;
+ pOp = sqlite3VdbeGetOp(v, k);
+ for(; k<last; k++, pOp++){
+ if( pOp->p1!=pLevel->iTabCur ) continue;
+ if( pOp->opcode==OP_Column ){
+ pOp->opcode = OP_SCopy;
+ pOp->p1 = pOp->p2 + pTabItem->regResult;
+ pOp->p2 = pOp->p3;
+ pOp->p3 = 0;
+ }else if( pOp->opcode==OP_Rowid ){
+ pOp->opcode = OP_Null;
+ pOp->p1 = 0;
+ pOp->p3 = 0;
+ }
+ }
+ continue;
+ }
+
/* Close all of the cursors that were opened by sqlite3WhereBegin.
** Except, do not close cursors that will be reused by the OR optimization
** (WHERE_OMIT_OPEN_CLOSE). And do not close the OP_OpenWrite cursors
@@ -114284,9 +115323,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
pIdx = pLevel->u.pCovidx;
}
if( pIdx && !db->mallocFailed ){
- int k, last;
- VdbeOp *pOp;
-
last = sqlite3VdbeCurrentAddr(v);
k = pLevel->addrBody;
pOp = sqlite3VdbeGetOp(v, k);
@@ -114381,14 +115417,6 @@ struct TrigEvent { int a; IdList * b; };
*/
struct AttachKey { int type; Token key; };
-/*
-** One or more VALUES claues
-*/
-struct ValueList {
- ExprList *pList;
- Select *pSelect;
-};
-
/* This is a utility routine used to set the ExprSpan.zStart and
** ExprSpan.zEnd values of pOut so that the span covers the complete
@@ -114512,28 +115540,28 @@ struct ValueList {
** defined, then do no error processing.
*/
#define YYCODETYPE unsigned char
-#define YYNOCODE 253
+#define YYNOCODE 254
#define YYACTIONTYPE unsigned short int
-#define YYWILDCARD 68
+#define YYWILDCARD 70
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
- int yy4;
- struct TrigEvent yy90;
- ExprSpan yy118;
- u16 yy177;
- TriggerStep* yy203;
- u8 yy210;
- struct {int value; int mask;} yy215;
- SrcList* yy259;
- struct ValueList yy260;
- struct LimitVal yy292;
- Expr* yy314;
- ExprList* yy322;
- struct LikeOp yy342;
- IdList* yy384;
- Select* yy387;
+ Select* yy3;
+ ExprList* yy14;
+ With* yy59;
+ SrcList* yy65;
+ struct LikeOp yy96;
+ Expr* yy132;
+ u8 yy186;
+ int yy328;
+ ExprSpan yy346;
+ struct TrigEvent yy378;
+ u16 yy381;
+ IdList* yy408;
+ struct {int value; int mask;} yy429;
+ TriggerStep* yy473;
+ struct LimitVal yy476;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
@@ -114542,8 +115570,8 @@ typedef union {
#define sqlite3ParserARG_PDECL ,Parse *pParse
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
-#define YYNSTATE 631
-#define YYNRULE 329
+#define YYNSTATE 642
+#define YYNRULE 327
#define YYFALLBACK 1
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
@@ -114613,480 +115641,463 @@ static const YYMINORTYPE yyzerominor = { 0 };
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
*/
-#define YY_ACTTAB_COUNT (1582)
+#define YY_ACTTAB_COUNT (1497)
static const YYACTIONTYPE yy_action[] = {
- /* 0 */ 312, 961, 185, 420, 2, 171, 516, 515, 597, 56,
- /* 10 */ 56, 56, 56, 49, 54, 54, 54, 54, 53, 53,
- /* 20 */ 52, 52, 52, 51, 234, 197, 196, 195, 624, 623,
- /* 30 */ 301, 590, 584, 56, 56, 56, 56, 156, 54, 54,
- /* 40 */ 54, 54, 53, 53, 52, 52, 52, 51, 234, 628,
- /* 50 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 60 */ 56, 56, 56, 466, 54, 54, 54, 54, 53, 53,
- /* 70 */ 52, 52, 52, 51, 234, 312, 597, 52, 52, 52,
- /* 80 */ 51, 234, 33, 54, 54, 54, 54, 53, 53, 52,
- /* 90 */ 52, 52, 51, 234, 624, 623, 621, 620, 165, 624,
- /* 100 */ 623, 383, 380, 379, 214, 328, 590, 584, 624, 623,
- /* 110 */ 467, 59, 378, 619, 618, 617, 53, 53, 52, 52,
- /* 120 */ 52, 51, 234, 506, 507, 57, 58, 48, 582, 581,
- /* 130 */ 583, 583, 55, 55, 56, 56, 56, 56, 30, 54,
- /* 140 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 150 */ 312, 50, 47, 146, 233, 232, 207, 474, 256, 349,
- /* 160 */ 255, 475, 621, 620, 554, 438, 298, 621, 620, 236,
- /* 170 */ 674, 435, 440, 553, 439, 366, 621, 620, 540, 224,
- /* 180 */ 551, 590, 584, 176, 138, 282, 386, 277, 385, 168,
- /* 190 */ 600, 422, 951, 548, 622, 951, 273, 572, 572, 566,
- /* 200 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 210 */ 56, 56, 56, 354, 54, 54, 54, 54, 53, 53,
- /* 220 */ 52, 52, 52, 51, 234, 312, 561, 526, 62, 675,
- /* 230 */ 132, 595, 410, 348, 579, 579, 492, 426, 577, 419,
- /* 240 */ 627, 65, 329, 560, 441, 237, 676, 123, 607, 67,
- /* 250 */ 542, 532, 622, 170, 205, 500, 590, 584, 166, 559,
- /* 260 */ 622, 403, 593, 593, 593, 442, 443, 271, 422, 950,
- /* 270 */ 166, 223, 950, 483, 190, 57, 58, 48, 582, 581,
- /* 280 */ 583, 583, 55, 55, 56, 56, 56, 56, 600, 54,
- /* 290 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 300 */ 312, 441, 412, 376, 175, 165, 166, 391, 383, 380,
- /* 310 */ 379, 342, 412, 203, 426, 66, 392, 622, 415, 378,
- /* 320 */ 597, 166, 442, 338, 444, 571, 601, 74, 415, 624,
- /* 330 */ 623, 590, 584, 624, 623, 174, 601, 92, 333, 171,
- /* 340 */ 1, 410, 597, 579, 579, 624, 623, 600, 306, 425,
- /* 350 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 360 */ 56, 56, 56, 580, 54, 54, 54, 54, 53, 53,
- /* 370 */ 52, 52, 52, 51, 234, 312, 472, 262, 399, 68,
- /* 380 */ 412, 339, 571, 389, 624, 623, 578, 602, 597, 589,
- /* 390 */ 588, 603, 412, 622, 423, 533, 415, 621, 620, 513,
- /* 400 */ 257, 621, 620, 166, 601, 91, 590, 584, 415, 45,
- /* 410 */ 597, 586, 585, 621, 620, 250, 601, 92, 39, 347,
- /* 420 */ 576, 336, 597, 547, 567, 57, 58, 48, 582, 581,
- /* 430 */ 583, 583, 55, 55, 56, 56, 56, 56, 587, 54,
- /* 440 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 450 */ 312, 561, 621, 620, 531, 291, 470, 188, 399, 375,
- /* 460 */ 247, 492, 249, 350, 412, 476, 476, 368, 560, 299,
- /* 470 */ 334, 412, 281, 482, 67, 565, 410, 622, 579, 579,
- /* 480 */ 415, 590, 584, 280, 559, 467, 520, 415, 601, 92,
- /* 490 */ 597, 167, 544, 36, 877, 601, 16, 519, 564, 6,
- /* 500 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 510 */ 56, 56, 56, 200, 54, 54, 54, 54, 53, 53,
- /* 520 */ 52, 52, 52, 51, 234, 312, 183, 412, 236, 528,
- /* 530 */ 395, 535, 358, 256, 349, 255, 397, 412, 248, 182,
- /* 540 */ 353, 359, 549, 415, 236, 317, 563, 50, 47, 146,
- /* 550 */ 273, 601, 73, 415, 7, 311, 590, 584, 568, 493,
- /* 560 */ 213, 601, 92, 233, 232, 410, 173, 579, 579, 330,
- /* 570 */ 575, 574, 631, 629, 332, 57, 58, 48, 582, 581,
- /* 580 */ 583, 583, 55, 55, 56, 56, 56, 56, 199, 54,
- /* 590 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 600 */ 312, 492, 340, 320, 511, 505, 572, 572, 460, 562,
- /* 610 */ 549, 170, 145, 430, 67, 558, 410, 622, 579, 579,
- /* 620 */ 384, 236, 600, 412, 408, 575, 574, 504, 572, 572,
- /* 630 */ 571, 590, 584, 353, 198, 143, 268, 549, 316, 415,
- /* 640 */ 306, 424, 207, 50, 47, 146, 167, 601, 69, 546,
- /* 650 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 660 */ 56, 56, 56, 555, 54, 54, 54, 54, 53, 53,
- /* 670 */ 52, 52, 52, 51, 234, 312, 600, 326, 412, 270,
- /* 680 */ 145, 264, 274, 266, 459, 571, 423, 35, 412, 568,
- /* 690 */ 407, 213, 428, 388, 415, 308, 212, 143, 622, 354,
- /* 700 */ 317, 12, 601, 94, 415, 549, 590, 584, 50, 47,
- /* 710 */ 146, 365, 601, 97, 552, 362, 318, 147, 602, 361,
- /* 720 */ 325, 15, 603, 187, 206, 57, 58, 48, 582, 581,
- /* 730 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
- /* 740 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 750 */ 312, 412, 35, 412, 415, 22, 630, 2, 600, 50,
- /* 760 */ 47, 146, 601, 95, 412, 485, 510, 415, 412, 415,
- /* 770 */ 412, 11, 235, 486, 412, 601, 104, 601, 103, 19,
- /* 780 */ 415, 590, 584, 352, 415, 40, 415, 38, 601, 105,
- /* 790 */ 415, 32, 601, 106, 601, 133, 544, 169, 601, 134,
- /* 800 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 810 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
- /* 820 */ 52, 52, 52, 51, 234, 312, 412, 274, 412, 415,
- /* 830 */ 412, 274, 274, 274, 201, 230, 721, 601, 98, 484,
- /* 840 */ 427, 307, 415, 622, 415, 540, 415, 622, 622, 622,
- /* 850 */ 601, 102, 601, 101, 601, 93, 590, 584, 262, 21,
- /* 860 */ 129, 622, 522, 521, 554, 222, 469, 521, 600, 324,
- /* 870 */ 323, 322, 211, 553, 622, 57, 58, 48, 582, 581,
- /* 880 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
- /* 890 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 900 */ 312, 412, 261, 412, 415, 412, 600, 210, 625, 367,
- /* 910 */ 51, 234, 601, 100, 538, 606, 142, 415, 355, 415,
- /* 920 */ 412, 415, 412, 496, 622, 601, 77, 601, 96, 601,
- /* 930 */ 137, 590, 584, 530, 622, 529, 415, 141, 415, 28,
- /* 940 */ 524, 600, 229, 544, 601, 136, 601, 135, 604, 204,
- /* 950 */ 57, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 960 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
- /* 970 */ 52, 52, 52, 51, 234, 312, 412, 360, 412, 415,
- /* 980 */ 412, 360, 286, 600, 503, 220, 127, 601, 76, 629,
- /* 990 */ 332, 382, 415, 622, 415, 540, 415, 622, 412, 613,
- /* 1000 */ 601, 90, 601, 89, 601, 75, 590, 584, 341, 272,
- /* 1010 */ 377, 622, 126, 27, 415, 622, 164, 544, 125, 280,
- /* 1020 */ 373, 122, 601, 88, 480, 57, 46, 48, 582, 581,
- /* 1030 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
- /* 1040 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 1050 */ 312, 412, 360, 412, 415, 412, 284, 186, 369, 321,
- /* 1060 */ 477, 170, 601, 87, 121, 473, 221, 415, 622, 415,
- /* 1070 */ 254, 415, 412, 355, 412, 601, 99, 601, 86, 601,
- /* 1080 */ 17, 590, 584, 259, 612, 120, 159, 158, 415, 622,
- /* 1090 */ 415, 14, 465, 157, 462, 25, 601, 85, 601, 84,
- /* 1100 */ 622, 58, 48, 582, 581, 583, 583, 55, 55, 56,
- /* 1110 */ 56, 56, 56, 412, 54, 54, 54, 54, 53, 53,
- /* 1120 */ 52, 52, 52, 51, 234, 312, 412, 262, 412, 415,
- /* 1130 */ 412, 262, 118, 611, 117, 24, 10, 601, 83, 351,
- /* 1140 */ 216, 219, 415, 622, 415, 608, 415, 622, 412, 622,
- /* 1150 */ 601, 72, 601, 71, 601, 82, 590, 584, 262, 4,
- /* 1160 */ 605, 622, 458, 115, 415, 456, 252, 154, 452, 110,
- /* 1170 */ 108, 453, 601, 81, 622, 451, 622, 48, 582, 581,
- /* 1180 */ 583, 583, 55, 55, 56, 56, 56, 56, 412, 54,
- /* 1190 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 234,
- /* 1200 */ 44, 406, 450, 3, 415, 412, 262, 107, 416, 623,
- /* 1210 */ 446, 437, 601, 80, 436, 335, 238, 189, 411, 409,
- /* 1220 */ 594, 415, 622, 44, 406, 401, 3, 412, 557, 601,
- /* 1230 */ 70, 416, 623, 412, 622, 149, 622, 421, 404, 64,
- /* 1240 */ 412, 622, 409, 415, 622, 331, 139, 148, 566, 415,
- /* 1250 */ 449, 601, 18, 228, 124, 626, 415, 601, 79, 315,
- /* 1260 */ 181, 404, 412, 545, 601, 78, 262, 541, 41, 42,
- /* 1270 */ 534, 566, 390, 202, 262, 43, 414, 413, 415, 622,
- /* 1280 */ 595, 314, 622, 622, 180, 539, 601, 92, 415, 276,
- /* 1290 */ 622, 41, 42, 509, 616, 615, 601, 9, 43, 414,
- /* 1300 */ 413, 622, 418, 595, 262, 622, 275, 600, 614, 622,
- /* 1310 */ 218, 593, 593, 593, 592, 591, 13, 178, 217, 417,
- /* 1320 */ 622, 236, 622, 44, 406, 490, 3, 269, 399, 267,
- /* 1330 */ 609, 416, 623, 400, 593, 593, 593, 592, 591, 13,
- /* 1340 */ 265, 622, 409, 622, 263, 622, 34, 406, 244, 3,
- /* 1350 */ 258, 363, 464, 463, 416, 623, 622, 356, 251, 8,
- /* 1360 */ 622, 404, 177, 599, 455, 409, 622, 622, 622, 622,
- /* 1370 */ 445, 566, 243, 622, 622, 236, 295, 240, 31, 239,
- /* 1380 */ 622, 431, 30, 396, 404, 290, 622, 294, 622, 293,
- /* 1390 */ 144, 41, 42, 622, 566, 622, 394, 622, 43, 414,
- /* 1400 */ 413, 622, 289, 595, 398, 60, 622, 292, 37, 231,
- /* 1410 */ 598, 172, 622, 29, 41, 42, 393, 523, 622, 556,
- /* 1420 */ 184, 43, 414, 413, 287, 387, 595, 543, 285, 518,
- /* 1430 */ 537, 536, 517, 327, 593, 593, 593, 592, 591, 13,
- /* 1440 */ 215, 283, 278, 514, 513, 304, 303, 302, 179, 300,
- /* 1450 */ 512, 310, 454, 128, 227, 226, 309, 593, 593, 593,
- /* 1460 */ 592, 591, 13, 494, 489, 225, 488, 150, 487, 242,
- /* 1470 */ 163, 61, 374, 481, 162, 161, 624, 623, 241, 372,
- /* 1480 */ 209, 479, 370, 260, 26, 160, 478, 364, 468, 471,
- /* 1490 */ 140, 152, 119, 467, 131, 116, 155, 153, 345, 457,
- /* 1500 */ 151, 346, 130, 114, 113, 112, 111, 448, 319, 23,
- /* 1510 */ 109, 434, 20, 433, 432, 429, 566, 610, 573, 596,
- /* 1520 */ 63, 405, 191, 279, 510, 296, 498, 288, 570, 495,
- /* 1530 */ 499, 497, 461, 194, 5, 305, 193, 192, 381, 569,
- /* 1540 */ 357, 256, 344, 245, 526, 246, 253, 313, 595, 343,
- /* 1550 */ 447, 297, 236, 402, 550, 491, 508, 502, 501, 527,
- /* 1560 */ 234, 208, 525, 962, 962, 962, 371, 962, 962, 962,
- /* 1570 */ 962, 962, 962, 962, 962, 337, 962, 962, 962, 593,
- /* 1580 */ 593, 593,
+ /* 0 */ 306, 212, 432, 955, 639, 191, 955, 295, 559, 88,
+ /* 10 */ 88, 88, 88, 81, 86, 86, 86, 86, 85, 85,
+ /* 20 */ 84, 84, 84, 83, 330, 185, 184, 183, 635, 635,
+ /* 30 */ 292, 606, 606, 88, 88, 88, 88, 683, 86, 86,
+ /* 40 */ 86, 86, 85, 85, 84, 84, 84, 83, 330, 16,
+ /* 50 */ 436, 597, 89, 90, 80, 600, 599, 601, 601, 87,
+ /* 60 */ 87, 88, 88, 88, 88, 684, 86, 86, 86, 86,
+ /* 70 */ 85, 85, 84, 84, 84, 83, 330, 306, 559, 84,
+ /* 80 */ 84, 84, 83, 330, 65, 86, 86, 86, 86, 85,
+ /* 90 */ 85, 84, 84, 84, 83, 330, 635, 635, 634, 633,
+ /* 100 */ 182, 682, 550, 379, 376, 375, 17, 322, 606, 606,
+ /* 110 */ 371, 198, 479, 91, 374, 82, 79, 165, 85, 85,
+ /* 120 */ 84, 84, 84, 83, 330, 598, 635, 635, 107, 89,
+ /* 130 */ 90, 80, 600, 599, 601, 601, 87, 87, 88, 88,
+ /* 140 */ 88, 88, 186, 86, 86, 86, 86, 85, 85, 84,
+ /* 150 */ 84, 84, 83, 330, 306, 594, 594, 142, 328, 327,
+ /* 160 */ 484, 249, 344, 238, 635, 635, 634, 633, 585, 448,
+ /* 170 */ 526, 525, 229, 388, 1, 394, 450, 584, 449, 635,
+ /* 180 */ 635, 635, 635, 319, 395, 606, 606, 199, 157, 273,
+ /* 190 */ 382, 268, 381, 187, 635, 635, 634, 633, 311, 555,
+ /* 200 */ 266, 593, 593, 266, 347, 588, 89, 90, 80, 600,
+ /* 210 */ 599, 601, 601, 87, 87, 88, 88, 88, 88, 478,
+ /* 220 */ 86, 86, 86, 86, 85, 85, 84, 84, 84, 83,
+ /* 230 */ 330, 306, 272, 536, 634, 633, 146, 610, 197, 310,
+ /* 240 */ 575, 182, 482, 271, 379, 376, 375, 506, 21, 634,
+ /* 250 */ 633, 634, 633, 635, 635, 374, 611, 574, 548, 440,
+ /* 260 */ 111, 563, 606, 606, 634, 633, 324, 479, 608, 608,
+ /* 270 */ 608, 300, 435, 573, 119, 407, 210, 162, 562, 883,
+ /* 280 */ 592, 592, 306, 89, 90, 80, 600, 599, 601, 601,
+ /* 290 */ 87, 87, 88, 88, 88, 88, 506, 86, 86, 86,
+ /* 300 */ 86, 85, 85, 84, 84, 84, 83, 330, 620, 111,
+ /* 310 */ 635, 635, 361, 606, 606, 358, 249, 349, 248, 433,
+ /* 320 */ 243, 479, 586, 634, 633, 195, 611, 93, 119, 221,
+ /* 330 */ 575, 497, 534, 534, 89, 90, 80, 600, 599, 601,
+ /* 340 */ 601, 87, 87, 88, 88, 88, 88, 574, 86, 86,
+ /* 350 */ 86, 86, 85, 85, 84, 84, 84, 83, 330, 306,
+ /* 360 */ 77, 429, 638, 573, 589, 530, 240, 230, 242, 105,
+ /* 370 */ 249, 349, 248, 515, 588, 208, 460, 529, 564, 173,
+ /* 380 */ 634, 633, 970, 144, 430, 2, 424, 228, 380, 557,
+ /* 390 */ 606, 606, 190, 153, 159, 158, 514, 51, 632, 631,
+ /* 400 */ 630, 71, 536, 432, 954, 196, 610, 954, 614, 45,
+ /* 410 */ 18, 89, 90, 80, 600, 599, 601, 601, 87, 87,
+ /* 420 */ 88, 88, 88, 88, 261, 86, 86, 86, 86, 85,
+ /* 430 */ 85, 84, 84, 84, 83, 330, 306, 608, 608, 608,
+ /* 440 */ 542, 424, 402, 385, 241, 506, 451, 320, 211, 543,
+ /* 450 */ 164, 436, 386, 293, 451, 587, 108, 496, 111, 334,
+ /* 460 */ 391, 591, 424, 614, 27, 452, 453, 606, 606, 72,
+ /* 470 */ 257, 70, 259, 452, 339, 342, 564, 582, 68, 415,
+ /* 480 */ 469, 328, 327, 62, 614, 45, 110, 393, 89, 90,
+ /* 490 */ 80, 600, 599, 601, 601, 87, 87, 88, 88, 88,
+ /* 500 */ 88, 152, 86, 86, 86, 86, 85, 85, 84, 84,
+ /* 510 */ 84, 83, 330, 306, 110, 499, 520, 538, 402, 389,
+ /* 520 */ 424, 110, 566, 500, 593, 593, 454, 82, 79, 165,
+ /* 530 */ 424, 591, 384, 564, 340, 615, 188, 162, 424, 350,
+ /* 540 */ 616, 424, 614, 44, 606, 606, 445, 582, 300, 434,
+ /* 550 */ 151, 19, 614, 9, 568, 580, 348, 615, 469, 567,
+ /* 560 */ 614, 26, 616, 614, 45, 89, 90, 80, 600, 599,
+ /* 570 */ 601, 601, 87, 87, 88, 88, 88, 88, 411, 86,
+ /* 580 */ 86, 86, 86, 85, 85, 84, 84, 84, 83, 330,
+ /* 590 */ 306, 579, 110, 578, 521, 282, 433, 398, 400, 255,
+ /* 600 */ 486, 82, 79, 165, 487, 164, 82, 79, 165, 488,
+ /* 610 */ 488, 364, 387, 424, 544, 544, 509, 350, 362, 155,
+ /* 620 */ 191, 606, 606, 559, 642, 640, 333, 82, 79, 165,
+ /* 630 */ 305, 564, 507, 312, 357, 614, 45, 329, 596, 595,
+ /* 640 */ 194, 337, 89, 90, 80, 600, 599, 601, 601, 87,
+ /* 650 */ 87, 88, 88, 88, 88, 424, 86, 86, 86, 86,
+ /* 660 */ 85, 85, 84, 84, 84, 83, 330, 306, 20, 323,
+ /* 670 */ 150, 263, 211, 543, 421, 596, 595, 614, 22, 424,
+ /* 680 */ 193, 424, 284, 424, 391, 424, 509, 424, 577, 424,
+ /* 690 */ 186, 335, 424, 559, 424, 313, 120, 546, 606, 606,
+ /* 700 */ 67, 614, 47, 614, 50, 614, 48, 614, 100, 614,
+ /* 710 */ 99, 614, 101, 576, 614, 102, 614, 109, 326, 89,
+ /* 720 */ 90, 80, 600, 599, 601, 601, 87, 87, 88, 88,
+ /* 730 */ 88, 88, 424, 86, 86, 86, 86, 85, 85, 84,
+ /* 740 */ 84, 84, 83, 330, 306, 424, 311, 424, 585, 54,
+ /* 750 */ 424, 516, 517, 590, 614, 112, 424, 584, 424, 572,
+ /* 760 */ 424, 195, 424, 571, 424, 67, 424, 614, 94, 614,
+ /* 770 */ 98, 424, 614, 97, 264, 606, 606, 195, 614, 46,
+ /* 780 */ 614, 96, 614, 30, 614, 49, 614, 115, 614, 114,
+ /* 790 */ 418, 229, 388, 614, 113, 306, 89, 90, 80, 600,
+ /* 800 */ 599, 601, 601, 87, 87, 88, 88, 88, 88, 424,
+ /* 810 */ 86, 86, 86, 86, 85, 85, 84, 84, 84, 83,
+ /* 820 */ 330, 119, 424, 590, 110, 372, 606, 606, 195, 53,
+ /* 830 */ 250, 614, 29, 195, 472, 438, 729, 190, 302, 498,
+ /* 840 */ 14, 523, 641, 2, 614, 43, 306, 89, 90, 80,
+ /* 850 */ 600, 599, 601, 601, 87, 87, 88, 88, 88, 88,
+ /* 860 */ 424, 86, 86, 86, 86, 85, 85, 84, 84, 84,
+ /* 870 */ 83, 330, 424, 613, 964, 964, 354, 606, 606, 420,
+ /* 880 */ 312, 64, 614, 42, 391, 355, 283, 437, 301, 255,
+ /* 890 */ 414, 410, 495, 492, 614, 28, 471, 306, 89, 90,
+ /* 900 */ 80, 600, 599, 601, 601, 87, 87, 88, 88, 88,
+ /* 910 */ 88, 424, 86, 86, 86, 86, 85, 85, 84, 84,
+ /* 920 */ 84, 83, 330, 424, 110, 110, 110, 110, 606, 606,
+ /* 930 */ 110, 254, 13, 614, 41, 532, 531, 283, 481, 531,
+ /* 940 */ 457, 284, 119, 561, 356, 614, 40, 284, 306, 89,
+ /* 950 */ 78, 80, 600, 599, 601, 601, 87, 87, 88, 88,
+ /* 960 */ 88, 88, 424, 86, 86, 86, 86, 85, 85, 84,
+ /* 970 */ 84, 84, 83, 330, 110, 424, 341, 220, 555, 606,
+ /* 980 */ 606, 351, 555, 318, 614, 95, 413, 255, 83, 330,
+ /* 990 */ 284, 284, 255, 640, 333, 356, 255, 614, 39, 306,
+ /* 1000 */ 356, 90, 80, 600, 599, 601, 601, 87, 87, 88,
+ /* 1010 */ 88, 88, 88, 424, 86, 86, 86, 86, 85, 85,
+ /* 1020 */ 84, 84, 84, 83, 330, 424, 317, 316, 141, 465,
+ /* 1030 */ 606, 606, 219, 619, 463, 614, 10, 417, 462, 255,
+ /* 1040 */ 189, 510, 553, 351, 207, 363, 161, 614, 38, 315,
+ /* 1050 */ 218, 255, 255, 80, 600, 599, 601, 601, 87, 87,
+ /* 1060 */ 88, 88, 88, 88, 424, 86, 86, 86, 86, 85,
+ /* 1070 */ 85, 84, 84, 84, 83, 330, 76, 419, 255, 3,
+ /* 1080 */ 878, 461, 424, 247, 331, 331, 614, 37, 217, 76,
+ /* 1090 */ 419, 390, 3, 216, 215, 422, 4, 331, 331, 424,
+ /* 1100 */ 547, 12, 424, 545, 614, 36, 424, 541, 422, 424,
+ /* 1110 */ 540, 424, 214, 424, 408, 424, 539, 403, 605, 605,
+ /* 1120 */ 237, 614, 25, 119, 614, 24, 588, 408, 614, 45,
+ /* 1130 */ 118, 614, 35, 614, 34, 614, 33, 614, 23, 588,
+ /* 1140 */ 60, 223, 603, 602, 513, 378, 73, 74, 140, 139,
+ /* 1150 */ 424, 110, 265, 75, 426, 425, 59, 424, 610, 73,
+ /* 1160 */ 74, 549, 402, 404, 424, 373, 75, 426, 425, 604,
+ /* 1170 */ 138, 610, 614, 11, 392, 76, 419, 181, 3, 614,
+ /* 1180 */ 32, 271, 369, 331, 331, 493, 614, 31, 149, 608,
+ /* 1190 */ 608, 608, 607, 15, 422, 365, 614, 8, 137, 489,
+ /* 1200 */ 136, 190, 608, 608, 608, 607, 15, 485, 176, 135,
+ /* 1210 */ 7, 252, 477, 408, 174, 133, 175, 474, 57, 56,
+ /* 1220 */ 132, 130, 119, 76, 419, 588, 3, 468, 245, 464,
+ /* 1230 */ 171, 331, 331, 125, 123, 456, 447, 122, 446, 104,
+ /* 1240 */ 336, 231, 422, 166, 154, 73, 74, 332, 116, 431,
+ /* 1250 */ 121, 309, 75, 426, 425, 222, 106, 610, 308, 637,
+ /* 1260 */ 204, 408, 629, 627, 628, 6, 200, 428, 427, 290,
+ /* 1270 */ 203, 622, 201, 588, 62, 63, 289, 66, 419, 399,
+ /* 1280 */ 3, 401, 288, 92, 143, 331, 331, 287, 608, 608,
+ /* 1290 */ 608, 607, 15, 73, 74, 227, 422, 325, 69, 416,
+ /* 1300 */ 75, 426, 425, 612, 412, 610, 192, 61, 569, 209,
+ /* 1310 */ 396, 226, 278, 225, 383, 408, 527, 558, 276, 533,
+ /* 1320 */ 552, 528, 321, 523, 370, 508, 180, 588, 494, 179,
+ /* 1330 */ 366, 117, 253, 269, 522, 503, 608, 608, 608, 607,
+ /* 1340 */ 15, 551, 502, 58, 274, 524, 178, 73, 74, 304,
+ /* 1350 */ 501, 368, 303, 206, 75, 426, 425, 491, 360, 610,
+ /* 1360 */ 213, 177, 483, 131, 345, 298, 297, 296, 202, 294,
+ /* 1370 */ 480, 490, 466, 134, 172, 129, 444, 346, 470, 128,
+ /* 1380 */ 314, 459, 103, 127, 126, 148, 124, 167, 443, 235,
+ /* 1390 */ 608, 608, 608, 607, 15, 442, 439, 623, 234, 299,
+ /* 1400 */ 145, 583, 291, 377, 581, 160, 119, 156, 270, 636,
+ /* 1410 */ 971, 169, 279, 626, 520, 625, 473, 624, 170, 621,
+ /* 1420 */ 618, 119, 168, 55, 409, 423, 537, 609, 286, 285,
+ /* 1430 */ 405, 570, 560, 556, 5, 52, 458, 554, 147, 267,
+ /* 1440 */ 519, 504, 518, 406, 262, 239, 260, 512, 343, 511,
+ /* 1450 */ 258, 353, 565, 256, 224, 251, 359, 277, 275, 476,
+ /* 1460 */ 475, 246, 352, 244, 467, 455, 236, 233, 232, 307,
+ /* 1470 */ 441, 281, 205, 163, 397, 280, 535, 505, 330, 617,
+ /* 1480 */ 971, 971, 971, 971, 367, 971, 971, 971, 971, 971,
+ /* 1490 */ 971, 971, 971, 971, 971, 971, 338,
};
static const YYCODETYPE yy_lookahead[] = {
- /* 0 */ 19, 143, 144, 145, 146, 24, 7, 8, 27, 78,
- /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- /* 20 */ 89, 90, 91, 92, 93, 106, 107, 108, 27, 28,
- /* 30 */ 15, 50, 51, 78, 79, 80, 81, 26, 83, 84,
- /* 40 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 1,
- /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 60 */ 79, 80, 81, 11, 83, 84, 85, 86, 87, 88,
- /* 70 */ 89, 90, 91, 92, 93, 19, 95, 89, 90, 91,
- /* 80 */ 92, 93, 26, 83, 84, 85, 86, 87, 88, 89,
- /* 90 */ 90, 91, 92, 93, 27, 28, 95, 96, 97, 27,
- /* 100 */ 28, 100, 101, 102, 22, 19, 50, 51, 27, 28,
- /* 110 */ 58, 55, 111, 7, 8, 9, 87, 88, 89, 90,
- /* 120 */ 91, 92, 93, 98, 99, 69, 70, 71, 72, 73,
- /* 130 */ 74, 75, 76, 77, 78, 79, 80, 81, 127, 83,
- /* 140 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 150 */ 19, 223, 224, 225, 87, 88, 162, 31, 106, 107,
- /* 160 */ 108, 35, 95, 96, 33, 98, 23, 95, 96, 117,
- /* 170 */ 119, 243, 105, 42, 107, 49, 95, 96, 151, 93,
- /* 180 */ 26, 50, 51, 97, 98, 99, 100, 101, 102, 103,
- /* 190 */ 196, 22, 23, 121, 167, 26, 110, 130, 131, 67,
- /* 200 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 210 */ 79, 80, 81, 219, 83, 84, 85, 86, 87, 88,
- /* 220 */ 89, 90, 91, 92, 93, 19, 12, 95, 234, 119,
- /* 230 */ 24, 99, 113, 239, 115, 116, 151, 68, 23, 147,
- /* 240 */ 148, 26, 215, 29, 151, 153, 119, 155, 163, 164,
- /* 250 */ 23, 23, 167, 26, 162, 23, 50, 51, 26, 45,
- /* 260 */ 167, 47, 130, 131, 132, 172, 173, 23, 22, 23,
- /* 270 */ 26, 186, 26, 188, 120, 69, 70, 71, 72, 73,
- /* 280 */ 74, 75, 76, 77, 78, 79, 80, 81, 196, 83,
- /* 290 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 300 */ 19, 151, 151, 23, 119, 97, 26, 19, 100, 101,
- /* 310 */ 102, 219, 151, 162, 68, 22, 28, 167, 167, 111,
- /* 320 */ 27, 26, 172, 173, 231, 232, 175, 176, 167, 27,
- /* 330 */ 28, 50, 51, 27, 28, 119, 175, 176, 246, 24,
- /* 340 */ 22, 113, 27, 115, 116, 27, 28, 196, 22, 23,
- /* 350 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 360 */ 79, 80, 81, 114, 83, 84, 85, 86, 87, 88,
- /* 370 */ 89, 90, 91, 92, 93, 19, 21, 151, 217, 22,
- /* 380 */ 151, 231, 232, 222, 27, 28, 23, 114, 95, 50,
- /* 390 */ 51, 118, 151, 167, 68, 89, 167, 95, 96, 104,
- /* 400 */ 23, 95, 96, 26, 175, 176, 50, 51, 167, 22,
- /* 410 */ 95, 72, 73, 95, 96, 16, 175, 176, 137, 64,
- /* 420 */ 23, 195, 27, 121, 23, 69, 70, 71, 72, 73,
- /* 430 */ 74, 75, 76, 77, 78, 79, 80, 81, 99, 83,
- /* 440 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 450 */ 19, 12, 95, 96, 23, 226, 101, 22, 217, 19,
- /* 460 */ 61, 151, 63, 222, 151, 106, 107, 108, 29, 159,
- /* 470 */ 244, 151, 99, 163, 164, 23, 113, 167, 115, 116,
- /* 480 */ 167, 50, 51, 110, 45, 58, 47, 167, 175, 176,
- /* 490 */ 95, 51, 168, 137, 139, 175, 176, 58, 11, 22,
- /* 500 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 510 */ 79, 80, 81, 22, 83, 84, 85, 86, 87, 88,
- /* 520 */ 89, 90, 91, 92, 93, 19, 23, 151, 117, 23,
- /* 530 */ 217, 207, 19, 106, 107, 108, 216, 151, 139, 23,
- /* 540 */ 129, 28, 26, 167, 117, 105, 23, 223, 224, 225,
- /* 550 */ 110, 175, 176, 167, 77, 165, 50, 51, 168, 169,
- /* 560 */ 170, 175, 176, 87, 88, 113, 26, 115, 116, 171,
- /* 570 */ 172, 173, 0, 1, 2, 69, 70, 71, 72, 73,
- /* 580 */ 74, 75, 76, 77, 78, 79, 80, 81, 162, 83,
- /* 590 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 600 */ 19, 151, 98, 217, 23, 37, 130, 131, 23, 23,
- /* 610 */ 26, 26, 96, 163, 164, 23, 113, 167, 115, 116,
- /* 620 */ 52, 117, 196, 151, 171, 172, 173, 59, 130, 131,
- /* 630 */ 232, 50, 51, 129, 208, 209, 16, 121, 156, 167,
- /* 640 */ 22, 23, 162, 223, 224, 225, 51, 175, 176, 121,
- /* 650 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 660 */ 79, 80, 81, 178, 83, 84, 85, 86, 87, 88,
- /* 670 */ 89, 90, 91, 92, 93, 19, 196, 109, 151, 23,
- /* 680 */ 96, 61, 151, 63, 23, 232, 68, 26, 151, 168,
- /* 690 */ 169, 170, 23, 89, 167, 26, 208, 209, 167, 219,
- /* 700 */ 105, 36, 175, 176, 167, 121, 50, 51, 223, 224,
- /* 710 */ 225, 229, 175, 176, 178, 233, 247, 248, 114, 239,
- /* 720 */ 189, 22, 118, 24, 162, 69, 70, 71, 72, 73,
- /* 730 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
- /* 740 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 750 */ 19, 151, 26, 151, 167, 24, 145, 146, 196, 223,
- /* 760 */ 224, 225, 175, 176, 151, 182, 183, 167, 151, 167,
- /* 770 */ 151, 36, 199, 190, 151, 175, 176, 175, 176, 206,
- /* 780 */ 167, 50, 51, 221, 167, 136, 167, 138, 175, 176,
- /* 790 */ 167, 26, 175, 176, 175, 176, 168, 36, 175, 176,
- /* 800 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 810 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
- /* 820 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
- /* 830 */ 151, 151, 151, 151, 162, 207, 23, 175, 176, 26,
- /* 840 */ 249, 250, 167, 167, 167, 151, 167, 167, 167, 167,
- /* 850 */ 175, 176, 175, 176, 175, 176, 50, 51, 151, 53,
- /* 860 */ 22, 167, 192, 193, 33, 189, 192, 193, 196, 189,
- /* 870 */ 189, 189, 162, 42, 167, 69, 70, 71, 72, 73,
- /* 880 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
- /* 890 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 900 */ 19, 151, 195, 151, 167, 151, 196, 162, 151, 215,
- /* 910 */ 92, 93, 175, 176, 28, 174, 119, 167, 151, 167,
- /* 920 */ 151, 167, 151, 182, 167, 175, 176, 175, 176, 175,
- /* 930 */ 176, 50, 51, 23, 167, 23, 167, 40, 167, 22,
- /* 940 */ 167, 196, 53, 168, 175, 176, 175, 176, 175, 162,
- /* 950 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 960 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
- /* 970 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
- /* 980 */ 151, 151, 207, 196, 30, 218, 22, 175, 176, 1,
- /* 990 */ 2, 53, 167, 167, 167, 151, 167, 167, 151, 151,
- /* 1000 */ 175, 176, 175, 176, 175, 176, 50, 51, 221, 23,
- /* 1010 */ 53, 167, 22, 22, 167, 167, 103, 168, 22, 110,
- /* 1020 */ 19, 105, 175, 176, 20, 69, 70, 71, 72, 73,
- /* 1030 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
- /* 1040 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 1050 */ 19, 151, 151, 151, 167, 151, 207, 24, 44, 215,
- /* 1060 */ 60, 26, 175, 176, 54, 54, 240, 167, 167, 167,
- /* 1070 */ 240, 167, 151, 151, 151, 175, 176, 175, 176, 175,
- /* 1080 */ 176, 50, 51, 139, 151, 22, 105, 119, 167, 167,
- /* 1090 */ 167, 5, 1, 36, 28, 77, 175, 176, 175, 176,
- /* 1100 */ 167, 70, 71, 72, 73, 74, 75, 76, 77, 78,
- /* 1110 */ 79, 80, 81, 151, 83, 84, 85, 86, 87, 88,
- /* 1120 */ 89, 90, 91, 92, 93, 19, 151, 151, 151, 167,
- /* 1130 */ 151, 151, 109, 151, 128, 77, 22, 175, 176, 26,
- /* 1140 */ 218, 240, 167, 167, 167, 151, 167, 167, 151, 167,
- /* 1150 */ 175, 176, 175, 176, 175, 176, 50, 51, 151, 22,
- /* 1160 */ 151, 167, 23, 120, 167, 1, 16, 122, 20, 120,
- /* 1170 */ 109, 195, 175, 176, 167, 195, 167, 71, 72, 73,
- /* 1180 */ 74, 75, 76, 77, 78, 79, 80, 81, 151, 83,
- /* 1190 */ 84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
- /* 1200 */ 19, 20, 195, 22, 167, 151, 151, 128, 27, 28,
- /* 1210 */ 129, 23, 175, 176, 23, 66, 141, 22, 151, 38,
- /* 1220 */ 151, 167, 167, 19, 20, 151, 22, 151, 151, 175,
- /* 1230 */ 176, 27, 28, 151, 167, 15, 167, 4, 57, 16,
- /* 1240 */ 151, 167, 38, 167, 167, 3, 166, 248, 67, 167,
- /* 1250 */ 195, 175, 176, 181, 181, 150, 167, 175, 176, 251,
- /* 1260 */ 6, 57, 151, 151, 175, 176, 151, 151, 87, 88,
- /* 1270 */ 89, 67, 151, 162, 151, 94, 95, 96, 167, 167,
- /* 1280 */ 99, 251, 167, 167, 152, 151, 175, 176, 167, 151,
- /* 1290 */ 167, 87, 88, 151, 150, 150, 175, 176, 94, 95,
- /* 1300 */ 96, 167, 150, 99, 151, 167, 151, 196, 13, 167,
- /* 1310 */ 195, 130, 131, 132, 133, 134, 135, 152, 195, 160,
- /* 1320 */ 167, 117, 167, 19, 20, 151, 22, 151, 217, 151,
- /* 1330 */ 161, 27, 28, 222, 130, 131, 132, 133, 134, 135,
- /* 1340 */ 151, 167, 38, 167, 151, 167, 19, 20, 195, 22,
- /* 1350 */ 151, 151, 151, 151, 27, 28, 167, 151, 151, 26,
- /* 1360 */ 167, 57, 25, 196, 151, 38, 167, 167, 167, 167,
- /* 1370 */ 151, 67, 151, 167, 167, 117, 201, 151, 125, 151,
- /* 1380 */ 167, 151, 127, 124, 57, 151, 167, 202, 167, 203,
- /* 1390 */ 151, 87, 88, 167, 67, 167, 151, 167, 94, 95,
- /* 1400 */ 96, 167, 151, 99, 123, 126, 167, 204, 136, 227,
- /* 1410 */ 205, 119, 167, 105, 87, 88, 122, 177, 167, 158,
- /* 1420 */ 158, 94, 95, 96, 212, 105, 99, 213, 212, 177,
- /* 1430 */ 213, 213, 185, 48, 130, 131, 132, 133, 134, 135,
- /* 1440 */ 5, 212, 177, 179, 104, 10, 11, 12, 13, 14,
- /* 1450 */ 177, 180, 17, 22, 230, 93, 180, 130, 131, 132,
- /* 1460 */ 133, 134, 135, 185, 177, 230, 177, 32, 177, 34,
- /* 1470 */ 157, 22, 18, 158, 157, 157, 27, 28, 43, 158,
- /* 1480 */ 158, 158, 46, 237, 136, 157, 238, 158, 191, 201,
- /* 1490 */ 69, 56, 191, 58, 220, 22, 157, 62, 18, 201,
- /* 1500 */ 65, 158, 220, 194, 194, 194, 194, 201, 158, 242,
- /* 1510 */ 191, 41, 242, 158, 158, 39, 67, 154, 232, 168,
- /* 1520 */ 245, 228, 198, 178, 183, 200, 168, 211, 232, 168,
- /* 1530 */ 178, 178, 201, 187, 198, 149, 87, 88, 179, 168,
- /* 1540 */ 241, 106, 107, 108, 95, 211, 241, 112, 99, 211,
- /* 1550 */ 201, 197, 117, 193, 210, 188, 184, 184, 184, 175,
- /* 1560 */ 93, 235, 175, 252, 252, 252, 236, 252, 252, 252,
- /* 1570 */ 252, 252, 252, 252, 252, 140, 252, 252, 252, 130,
- /* 1580 */ 131, 132,
+ /* 0 */ 19, 22, 22, 23, 1, 24, 26, 15, 27, 80,
+ /* 10 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
+ /* 20 */ 91, 92, 93, 94, 95, 108, 109, 110, 27, 28,
+ /* 30 */ 23, 50, 51, 80, 81, 82, 83, 122, 85, 86,
+ /* 40 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 22,
+ /* 50 */ 70, 23, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 60 */ 79, 80, 81, 82, 83, 122, 85, 86, 87, 88,
+ /* 70 */ 89, 90, 91, 92, 93, 94, 95, 19, 97, 91,
+ /* 80 */ 92, 93, 94, 95, 26, 85, 86, 87, 88, 89,
+ /* 90 */ 90, 91, 92, 93, 94, 95, 27, 28, 97, 98,
+ /* 100 */ 99, 122, 211, 102, 103, 104, 79, 19, 50, 51,
+ /* 110 */ 19, 122, 59, 55, 113, 224, 225, 226, 89, 90,
+ /* 120 */ 91, 92, 93, 94, 95, 23, 27, 28, 26, 71,
+ /* 130 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ /* 140 */ 82, 83, 51, 85, 86, 87, 88, 89, 90, 91,
+ /* 150 */ 92, 93, 94, 95, 19, 132, 133, 58, 89, 90,
+ /* 160 */ 21, 108, 109, 110, 27, 28, 97, 98, 33, 100,
+ /* 170 */ 7, 8, 119, 120, 22, 19, 107, 42, 109, 27,
+ /* 180 */ 28, 27, 28, 95, 28, 50, 51, 99, 100, 101,
+ /* 190 */ 102, 103, 104, 105, 27, 28, 97, 98, 107, 152,
+ /* 200 */ 112, 132, 133, 112, 65, 69, 71, 72, 73, 74,
+ /* 210 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 11,
+ /* 220 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ /* 230 */ 95, 19, 101, 97, 97, 98, 24, 101, 122, 157,
+ /* 240 */ 12, 99, 103, 112, 102, 103, 104, 152, 22, 97,
+ /* 250 */ 98, 97, 98, 27, 28, 113, 27, 29, 91, 164,
+ /* 260 */ 165, 124, 50, 51, 97, 98, 219, 59, 132, 133,
+ /* 270 */ 134, 22, 23, 45, 66, 47, 212, 213, 124, 140,
+ /* 280 */ 132, 133, 19, 71, 72, 73, 74, 75, 76, 77,
+ /* 290 */ 78, 79, 80, 81, 82, 83, 152, 85, 86, 87,
+ /* 300 */ 88, 89, 90, 91, 92, 93, 94, 95, 164, 165,
+ /* 310 */ 27, 28, 230, 50, 51, 233, 108, 109, 110, 70,
+ /* 320 */ 16, 59, 23, 97, 98, 26, 97, 22, 66, 185,
+ /* 330 */ 12, 187, 27, 28, 71, 72, 73, 74, 75, 76,
+ /* 340 */ 77, 78, 79, 80, 81, 82, 83, 29, 85, 86,
+ /* 350 */ 87, 88, 89, 90, 91, 92, 93, 94, 95, 19,
+ /* 360 */ 22, 148, 149, 45, 23, 47, 62, 154, 64, 156,
+ /* 370 */ 108, 109, 110, 37, 69, 23, 163, 59, 26, 26,
+ /* 380 */ 97, 98, 144, 145, 146, 147, 152, 200, 52, 23,
+ /* 390 */ 50, 51, 26, 22, 89, 90, 60, 210, 7, 8,
+ /* 400 */ 9, 138, 97, 22, 23, 26, 101, 26, 174, 175,
+ /* 410 */ 197, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ /* 420 */ 80, 81, 82, 83, 16, 85, 86, 87, 88, 89,
+ /* 430 */ 90, 91, 92, 93, 94, 95, 19, 132, 133, 134,
+ /* 440 */ 23, 152, 208, 209, 140, 152, 152, 111, 195, 196,
+ /* 450 */ 98, 70, 163, 160, 152, 23, 22, 164, 165, 246,
+ /* 460 */ 207, 27, 152, 174, 175, 171, 172, 50, 51, 137,
+ /* 470 */ 62, 139, 64, 171, 172, 222, 124, 27, 138, 24,
+ /* 480 */ 163, 89, 90, 130, 174, 175, 197, 163, 71, 72,
+ /* 490 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ /* 500 */ 83, 22, 85, 86, 87, 88, 89, 90, 91, 92,
+ /* 510 */ 93, 94, 95, 19, 197, 181, 182, 23, 208, 209,
+ /* 520 */ 152, 197, 26, 189, 132, 133, 232, 224, 225, 226,
+ /* 530 */ 152, 97, 91, 26, 232, 116, 212, 213, 152, 222,
+ /* 540 */ 121, 152, 174, 175, 50, 51, 243, 97, 22, 23,
+ /* 550 */ 22, 234, 174, 175, 177, 23, 239, 116, 163, 177,
+ /* 560 */ 174, 175, 121, 174, 175, 71, 72, 73, 74, 75,
+ /* 570 */ 76, 77, 78, 79, 80, 81, 82, 83, 24, 85,
+ /* 580 */ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ /* 590 */ 19, 23, 197, 11, 23, 227, 70, 208, 220, 152,
+ /* 600 */ 31, 224, 225, 226, 35, 98, 224, 225, 226, 108,
+ /* 610 */ 109, 110, 115, 152, 117, 118, 27, 222, 49, 123,
+ /* 620 */ 24, 50, 51, 27, 0, 1, 2, 224, 225, 226,
+ /* 630 */ 166, 124, 168, 169, 239, 174, 175, 170, 171, 172,
+ /* 640 */ 22, 194, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 650 */ 79, 80, 81, 82, 83, 152, 85, 86, 87, 88,
+ /* 660 */ 89, 90, 91, 92, 93, 94, 95, 19, 22, 208,
+ /* 670 */ 24, 23, 195, 196, 170, 171, 172, 174, 175, 152,
+ /* 680 */ 26, 152, 152, 152, 207, 152, 97, 152, 23, 152,
+ /* 690 */ 51, 244, 152, 97, 152, 247, 248, 23, 50, 51,
+ /* 700 */ 26, 174, 175, 174, 175, 174, 175, 174, 175, 174,
+ /* 710 */ 175, 174, 175, 23, 174, 175, 174, 175, 188, 71,
+ /* 720 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ /* 730 */ 82, 83, 152, 85, 86, 87, 88, 89, 90, 91,
+ /* 740 */ 92, 93, 94, 95, 19, 152, 107, 152, 33, 24,
+ /* 750 */ 152, 100, 101, 27, 174, 175, 152, 42, 152, 23,
+ /* 760 */ 152, 26, 152, 23, 152, 26, 152, 174, 175, 174,
+ /* 770 */ 175, 152, 174, 175, 23, 50, 51, 26, 174, 175,
+ /* 780 */ 174, 175, 174, 175, 174, 175, 174, 175, 174, 175,
+ /* 790 */ 163, 119, 120, 174, 175, 19, 71, 72, 73, 74,
+ /* 800 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 152,
+ /* 810 */ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ /* 820 */ 95, 66, 152, 97, 197, 23, 50, 51, 26, 53,
+ /* 830 */ 23, 174, 175, 26, 23, 23, 23, 26, 26, 26,
+ /* 840 */ 36, 106, 146, 147, 174, 175, 19, 71, 72, 73,
+ /* 850 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ /* 860 */ 152, 85, 86, 87, 88, 89, 90, 91, 92, 93,
+ /* 870 */ 94, 95, 152, 196, 119, 120, 19, 50, 51, 168,
+ /* 880 */ 169, 26, 174, 175, 207, 28, 152, 249, 250, 152,
+ /* 890 */ 163, 163, 163, 163, 174, 175, 163, 19, 71, 72,
+ /* 900 */ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
+ /* 910 */ 83, 152, 85, 86, 87, 88, 89, 90, 91, 92,
+ /* 920 */ 93, 94, 95, 152, 197, 197, 197, 197, 50, 51,
+ /* 930 */ 197, 194, 36, 174, 175, 191, 192, 152, 191, 192,
+ /* 940 */ 163, 152, 66, 124, 152, 174, 175, 152, 19, 71,
+ /* 950 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ /* 960 */ 82, 83, 152, 85, 86, 87, 88, 89, 90, 91,
+ /* 970 */ 92, 93, 94, 95, 197, 152, 100, 188, 152, 50,
+ /* 980 */ 51, 152, 152, 188, 174, 175, 252, 152, 94, 95,
+ /* 990 */ 152, 152, 152, 1, 2, 152, 152, 174, 175, 19,
+ /* 1000 */ 152, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 1010 */ 81, 82, 83, 152, 85, 86, 87, 88, 89, 90,
+ /* 1020 */ 91, 92, 93, 94, 95, 152, 188, 188, 22, 194,
+ /* 1030 */ 50, 51, 240, 173, 194, 174, 175, 252, 194, 152,
+ /* 1040 */ 36, 181, 28, 152, 23, 219, 122, 174, 175, 219,
+ /* 1050 */ 221, 152, 152, 73, 74, 75, 76, 77, 78, 79,
+ /* 1060 */ 80, 81, 82, 83, 152, 85, 86, 87, 88, 89,
+ /* 1070 */ 90, 91, 92, 93, 94, 95, 19, 20, 152, 22,
+ /* 1080 */ 23, 194, 152, 240, 27, 28, 174, 175, 240, 19,
+ /* 1090 */ 20, 26, 22, 194, 194, 38, 22, 27, 28, 152,
+ /* 1100 */ 23, 22, 152, 116, 174, 175, 152, 23, 38, 152,
+ /* 1110 */ 23, 152, 221, 152, 57, 152, 23, 163, 50, 51,
+ /* 1120 */ 194, 174, 175, 66, 174, 175, 69, 57, 174, 175,
+ /* 1130 */ 40, 174, 175, 174, 175, 174, 175, 174, 175, 69,
+ /* 1140 */ 22, 53, 74, 75, 30, 53, 89, 90, 22, 22,
+ /* 1150 */ 152, 197, 23, 96, 97, 98, 22, 152, 101, 89,
+ /* 1160 */ 90, 91, 208, 209, 152, 53, 96, 97, 98, 101,
+ /* 1170 */ 22, 101, 174, 175, 152, 19, 20, 105, 22, 174,
+ /* 1180 */ 175, 112, 19, 27, 28, 20, 174, 175, 24, 132,
+ /* 1190 */ 133, 134, 135, 136, 38, 44, 174, 175, 107, 61,
+ /* 1200 */ 54, 26, 132, 133, 134, 135, 136, 54, 107, 22,
+ /* 1210 */ 5, 140, 1, 57, 36, 111, 122, 28, 79, 79,
+ /* 1220 */ 131, 123, 66, 19, 20, 69, 22, 1, 16, 20,
+ /* 1230 */ 125, 27, 28, 123, 111, 120, 23, 131, 23, 16,
+ /* 1240 */ 68, 142, 38, 15, 22, 89, 90, 3, 167, 4,
+ /* 1250 */ 248, 251, 96, 97, 98, 180, 180, 101, 251, 151,
+ /* 1260 */ 6, 57, 151, 13, 151, 26, 25, 151, 161, 202,
+ /* 1270 */ 153, 162, 153, 69, 130, 128, 203, 19, 20, 127,
+ /* 1280 */ 22, 126, 204, 129, 22, 27, 28, 205, 132, 133,
+ /* 1290 */ 134, 135, 136, 89, 90, 231, 38, 95, 137, 179,
+ /* 1300 */ 96, 97, 98, 206, 179, 101, 122, 107, 159, 159,
+ /* 1310 */ 125, 231, 216, 228, 107, 57, 184, 217, 216, 176,
+ /* 1320 */ 217, 176, 48, 106, 18, 184, 158, 69, 159, 158,
+ /* 1330 */ 46, 71, 237, 176, 176, 176, 132, 133, 134, 135,
+ /* 1340 */ 136, 217, 176, 137, 216, 178, 158, 89, 90, 179,
+ /* 1350 */ 176, 159, 179, 159, 96, 97, 98, 159, 159, 101,
+ /* 1360 */ 5, 158, 202, 22, 18, 10, 11, 12, 13, 14,
+ /* 1370 */ 190, 238, 17, 190, 158, 193, 41, 159, 202, 193,
+ /* 1380 */ 159, 202, 245, 193, 193, 223, 190, 32, 159, 34,
+ /* 1390 */ 132, 133, 134, 135, 136, 159, 39, 155, 43, 150,
+ /* 1400 */ 223, 177, 201, 178, 177, 186, 66, 199, 177, 152,
+ /* 1410 */ 253, 56, 215, 152, 182, 152, 202, 152, 63, 152,
+ /* 1420 */ 152, 66, 67, 242, 229, 152, 174, 152, 152, 152,
+ /* 1430 */ 152, 152, 152, 152, 199, 242, 202, 152, 198, 152,
+ /* 1440 */ 152, 152, 183, 192, 152, 215, 152, 183, 215, 183,
+ /* 1450 */ 152, 241, 214, 152, 211, 152, 152, 211, 211, 152,
+ /* 1460 */ 152, 241, 152, 152, 152, 152, 152, 152, 152, 114,
+ /* 1470 */ 152, 152, 235, 152, 152, 152, 174, 187, 95, 174,
+ /* 1480 */ 253, 253, 253, 253, 236, 253, 253, 253, 253, 253,
+ /* 1490 */ 253, 253, 253, 253, 253, 253, 141,
};
-#define YY_SHIFT_USE_DFLT (-82)
-#define YY_SHIFT_COUNT (419)
-#define YY_SHIFT_MIN (-81)
-#define YY_SHIFT_MAX (1480)
+#define YY_SHIFT_USE_DFLT (-86)
+#define YY_SHIFT_COUNT (429)
+#define YY_SHIFT_MIN (-85)
+#define YY_SHIFT_MAX (1383)
static const short yy_shift_ofst[] = {
- /* 0 */ 988, 1204, 1435, 1204, 1304, 1304, 67, 67, 1, -19,
- /* 10 */ 1304, 1304, 1304, 1304, 427, 81, 131, 131, 806, 1181,
- /* 20 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
- /* 30 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
- /* 40 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1327, 1304,
- /* 50 */ 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304, 1304,
- /* 60 */ 1304, 1304, 52, 81, 81, 476, 476, 395, 1258, 56,
- /* 70 */ 731, 656, 581, 506, 431, 356, 281, 206, 881, 881,
- /* 80 */ 881, 881, 881, 881, 881, 881, 881, 881, 881, 881,
- /* 90 */ 881, 881, 881, 956, 881, 1031, 1106, 1106, -69, -45,
- /* 100 */ -45, -45, -45, -45, 0, 29, -12, 81, 81, 81,
- /* 110 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- /* 120 */ 81, 81, 81, 355, 440, 81, 81, 81, 81, 81,
- /* 130 */ 504, 411, 395, 818, 1467, -82, -82, -82, 1449, 86,
- /* 140 */ 439, 439, 306, 357, 302, 72, 318, 246, 169, 81,
- /* 150 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- /* 160 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- /* 170 */ 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- /* 180 */ 81, 81, 315, 315, 315, 572, 1258, 1258, 1258, -82,
- /* 190 */ -82, -82, 132, 132, 208, 568, 568, 568, 516, 503,
- /* 200 */ 214, 452, 363, 228, 119, 119, 119, 119, 359, 126,
- /* 210 */ 119, 119, 584, 293, 604, 106, 11, 288, 288, 513,
- /* 220 */ 11, 513, 295, 813, 395, 831, 395, 831, 595, 831,
- /* 230 */ 288, 649, 498, 498, 395, 154, 273, 699, 1476, 1292,
- /* 240 */ 1292, 1470, 1470, 1292, 1473, 1421, 1255, 1480, 1480, 1480,
- /* 250 */ 1480, 1292, 1454, 1255, 1473, 1421, 1421, 1255, 1292, 1454,
- /* 260 */ 1348, 1436, 1292, 1292, 1454, 1292, 1454, 1292, 1454, 1431,
- /* 270 */ 1320, 1320, 1320, 1385, 1362, 1362, 1431, 1320, 1340, 1320,
- /* 280 */ 1385, 1320, 1320, 1294, 1308, 1294, 1308, 1294, 1308, 1292,
- /* 290 */ 1292, 1272, 1279, 1281, 1253, 1259, 1255, 1258, 1337, 1333,
- /* 300 */ 1295, 1295, 1254, 1254, 1254, 1254, -82, -82, -82, -82,
- /* 310 */ -82, -82, 339, 399, 618, 326, 620, -81, 669, 477,
- /* 320 */ 661, 585, 377, 280, 244, 232, 25, -1, 373, 227,
- /* 330 */ 215, 1233, 1242, 1195, 1075, 1220, 1149, 1223, 1191, 1188,
- /* 340 */ 1081, 1113, 1079, 1061, 1049, 1148, 1045, 1150, 1164, 1043,
- /* 350 */ 1139, 1137, 1113, 1114, 1006, 1058, 1018, 1023, 1066, 1057,
- /* 360 */ 968, 1091, 1086, 1063, 981, 944, 1011, 1035, 1010, 1000,
- /* 370 */ 1014, 916, 1033, 1004, 1001, 909, 913, 996, 957, 991,
- /* 380 */ 990, 986, 964, 938, 954, 917, 889, 897, 912, 910,
- /* 390 */ 797, 886, 761, 838, 528, 726, 735, 765, 665, 726,
- /* 400 */ 592, 586, 540, 523, 491, 487, 435, 401, 397, 387,
- /* 410 */ 249, 216, 185, 127, 110, 51, 82, 143, 15, 48,
+ /* 0 */ 992, 1057, 1355, 1156, 1204, 1204, 1, 262, -19, 135,
+ /* 10 */ 135, 776, 1204, 1204, 1204, 1204, 69, 69, 53, 208,
+ /* 20 */ 283, 755, 58, 725, 648, 571, 494, 417, 340, 263,
+ /* 30 */ 212, 827, 827, 827, 827, 827, 827, 827, 827, 827,
+ /* 40 */ 827, 827, 827, 827, 827, 827, 878, 827, 929, 980,
+ /* 50 */ 980, 1070, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 60 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 70 */ 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 80 */ 1258, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204, 1204,
+ /* 90 */ 1204, 1204, 1204, 1204, -71, -47, -47, -47, -47, -47,
+ /* 100 */ 0, 29, -12, 283, 283, 139, 91, 392, 392, 894,
+ /* 110 */ 672, 726, 1383, -86, -86, -86, 88, 318, 318, 99,
+ /* 120 */ 381, -20, 283, 283, 283, 283, 283, 283, 283, 283,
+ /* 130 */ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+ /* 140 */ 283, 283, 283, 283, 624, 876, 726, 672, 1340, 1340,
+ /* 150 */ 1340, 1340, 1340, 1340, -86, -86, -86, 305, 136, 136,
+ /* 160 */ 142, 167, 226, 154, 137, 152, 283, 283, 283, 283,
+ /* 170 */ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+ /* 180 */ 283, 283, 283, 336, 336, 336, 283, 283, 352, 283,
+ /* 190 */ 283, 283, 283, 283, 228, 283, 283, 283, 283, 283,
+ /* 200 */ 283, 283, 283, 283, 283, 501, 569, 596, 596, 596,
+ /* 210 */ 507, 497, 441, 391, 353, 156, 156, 857, 353, 857,
+ /* 220 */ 735, 813, 639, 715, 156, 332, 715, 715, 496, 419,
+ /* 230 */ 646, 1357, 1184, 1184, 1335, 1335, 1184, 1341, 1260, 1144,
+ /* 240 */ 1346, 1346, 1346, 1346, 1184, 1306, 1144, 1341, 1260, 1260,
+ /* 250 */ 1144, 1184, 1306, 1206, 1284, 1184, 1184, 1306, 1184, 1306,
+ /* 260 */ 1184, 1306, 1262, 1207, 1207, 1207, 1274, 1262, 1207, 1217,
+ /* 270 */ 1207, 1274, 1207, 1207, 1185, 1200, 1185, 1200, 1185, 1200,
+ /* 280 */ 1184, 1184, 1161, 1262, 1202, 1202, 1262, 1154, 1155, 1147,
+ /* 290 */ 1152, 1144, 1241, 1239, 1250, 1250, 1254, 1254, 1254, 1254,
+ /* 300 */ -86, -86, -86, -86, -86, -86, 1068, 304, 526, 249,
+ /* 310 */ 408, -83, 434, 812, 27, 811, 807, 802, 751, 589,
+ /* 320 */ 651, 163, 131, 674, 366, 450, 299, 148, 23, 102,
+ /* 330 */ 229, -21, 1245, 1244, 1222, 1099, 1228, 1172, 1223, 1215,
+ /* 340 */ 1213, 1115, 1106, 1123, 1110, 1209, 1105, 1212, 1226, 1098,
+ /* 350 */ 1089, 1140, 1139, 1104, 1189, 1178, 1094, 1211, 1205, 1187,
+ /* 360 */ 1101, 1071, 1153, 1175, 1146, 1138, 1151, 1091, 1164, 1165,
+ /* 370 */ 1163, 1069, 1072, 1148, 1112, 1134, 1127, 1129, 1126, 1092,
+ /* 380 */ 1114, 1118, 1088, 1090, 1093, 1087, 1084, 987, 1079, 1077,
+ /* 390 */ 1074, 1065, 924, 1021, 1014, 1004, 1006, 819, 739, 896,
+ /* 400 */ 855, 804, 739, 740, 736, 690, 654, 665, 618, 582,
+ /* 410 */ 568, 528, 554, 379, 532, 479, 455, 379, 432, 371,
+ /* 420 */ 341, 28, 338, 116, -11, -57, -85, 7, -8, 3,
};
-#define YY_REDUCE_USE_DFLT (-143)
-#define YY_REDUCE_COUNT (311)
-#define YY_REDUCE_MIN (-142)
-#define YY_REDUCE_MAX (1387)
+#define YY_REDUCE_USE_DFLT (-110)
+#define YY_REDUCE_COUNT (305)
+#define YY_REDUCE_MIN (-109)
+#define YY_REDUCE_MAX (1323)
static const short yy_reduce_ofst[] = {
- /* 0 */ -142, 1111, 92, 151, 241, 161, 150, 93, 85, 324,
- /* 10 */ 386, 313, 320, 229, -6, 310, 536, 485, -72, 1121,
- /* 20 */ 1089, 1082, 1076, 1054, 1037, 997, 979, 977, 975, 962,
- /* 30 */ 923, 921, 904, 902, 900, 887, 847, 829, 827, 825,
- /* 40 */ 812, 771, 769, 754, 752, 750, 737, 679, 677, 675,
- /* 50 */ 662, 623, 619, 617, 613, 602, 600, 587, 537, 527,
- /* 60 */ 472, 376, 480, 450, 226, 453, 398, 390, 426, 420,
- /* 70 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
- /* 80 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
- /* 90 */ 420, 420, 420, 420, 420, 420, 420, 420, 420, 420,
- /* 100 */ 420, 420, 420, 420, 420, 420, 420, 1153, 922, 1123,
- /* 110 */ 1115, 1055, 1007, 980, 976, 901, 844, 830, 767, 826,
- /* 120 */ 682, 694, 707, 482, 583, 681, 680, 676, 531, 27,
- /* 130 */ 787, 562, 521, 420, 420, 420, 420, 420, 773, 741,
- /* 140 */ 674, 670, 1067, 1251, 1245, 1239, 1234, 591, 591, 1230,
- /* 150 */ 1228, 1226, 1221, 1219, 1213, 1207, 1206, 1202, 1201, 1200,
- /* 160 */ 1199, 1193, 1189, 1178, 1176, 1174, 1155, 1142, 1138, 1134,
- /* 170 */ 1116, 1112, 1077, 1074, 1069, 1067, 1009, 994, 982, 933,
- /* 180 */ 848, 757, 849, 775, 628, 611, 745, 710, 672, 469,
- /* 190 */ 488, 573, 1387, 1384, 1367, 1374, 1373, 1372, 1344, 1354,
- /* 200 */ 1360, 1354, 1354, 1354, 1354, 1354, 1354, 1354, 1330, 1326,
- /* 210 */ 1354, 1354, 1344, 1371, 1336, 1386, 1349, 1338, 1334, 1305,
- /* 220 */ 1331, 1299, 1359, 1346, 1361, 1353, 1358, 1352, 1341, 1345,
- /* 230 */ 1316, 1293, 1296, 1286, 1351, 1325, 1324, 1363, 1275, 1356,
- /* 240 */ 1355, 1270, 1267, 1350, 1282, 1319, 1306, 1312, 1311, 1310,
- /* 250 */ 1309, 1343, 1339, 1298, 1274, 1301, 1297, 1288, 1329, 1328,
- /* 260 */ 1248, 1246, 1323, 1322, 1318, 1321, 1317, 1315, 1313, 1276,
- /* 270 */ 1291, 1289, 1287, 1278, 1235, 1224, 1271, 1273, 1264, 1265,
- /* 280 */ 1247, 1252, 1240, 1218, 1229, 1217, 1216, 1214, 1212, 1262,
- /* 290 */ 1261, 1182, 1205, 1203, 1186, 1185, 1175, 1167, 1169, 1159,
- /* 300 */ 1165, 1132, 1152, 1145, 1144, 1105, 1030, 1008, 999, 1073,
- /* 310 */ 1072, 1080,
+ /* 0 */ 238, 954, 213, 289, 310, 234, 144, 317, -109, 382,
+ /* 10 */ 377, 303, 461, 389, 378, 368, 302, 294, 253, 395,
+ /* 20 */ 293, 324, 403, 403, 403, 403, 403, 403, 403, 403,
+ /* 30 */ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
+ /* 40 */ 403, 403, 403, 403, 403, 403, 403, 403, 403, 403,
+ /* 50 */ 403, 1022, 1012, 1005, 998, 963, 961, 959, 957, 950,
+ /* 60 */ 947, 930, 912, 873, 861, 823, 810, 771, 759, 720,
+ /* 70 */ 708, 670, 657, 619, 614, 612, 610, 608, 606, 604,
+ /* 80 */ 598, 595, 593, 580, 542, 540, 537, 535, 533, 531,
+ /* 90 */ 529, 527, 503, 386, 403, 403, 403, 403, 403, 403,
+ /* 100 */ 403, 403, 403, 95, 447, 82, 334, 504, 467, 403,
+ /* 110 */ 477, 464, 403, 403, 403, 403, 860, 747, 744, 785,
+ /* 120 */ 638, 638, 926, 891, 900, 899, 887, 844, 840, 835,
+ /* 130 */ 848, 830, 843, 829, 792, 839, 826, 737, 838, 795,
+ /* 140 */ 789, 47, 734, 530, 696, 777, 711, 677, 733, 730,
+ /* 150 */ 729, 728, 727, 627, 448, 64, 187, 1305, 1302, 1252,
+ /* 160 */ 1290, 1273, 1323, 1322, 1321, 1319, 1318, 1316, 1315, 1314,
+ /* 170 */ 1313, 1312, 1311, 1310, 1308, 1307, 1304, 1303, 1301, 1298,
+ /* 180 */ 1294, 1292, 1289, 1266, 1264, 1259, 1288, 1287, 1238, 1285,
+ /* 190 */ 1281, 1280, 1279, 1278, 1251, 1277, 1276, 1275, 1273, 1268,
+ /* 200 */ 1267, 1265, 1263, 1261, 1257, 1248, 1237, 1247, 1246, 1243,
+ /* 210 */ 1238, 1240, 1235, 1249, 1234, 1233, 1230, 1220, 1214, 1210,
+ /* 220 */ 1225, 1219, 1232, 1231, 1197, 1195, 1227, 1224, 1201, 1208,
+ /* 230 */ 1242, 1137, 1236, 1229, 1193, 1181, 1221, 1177, 1196, 1179,
+ /* 240 */ 1191, 1190, 1186, 1182, 1218, 1216, 1176, 1162, 1183, 1180,
+ /* 250 */ 1160, 1199, 1203, 1133, 1095, 1198, 1194, 1188, 1192, 1171,
+ /* 260 */ 1169, 1168, 1173, 1174, 1166, 1159, 1141, 1170, 1158, 1167,
+ /* 270 */ 1157, 1132, 1145, 1143, 1124, 1128, 1103, 1102, 1100, 1096,
+ /* 280 */ 1150, 1149, 1085, 1125, 1080, 1064, 1120, 1097, 1082, 1078,
+ /* 290 */ 1073, 1067, 1109, 1107, 1119, 1117, 1116, 1113, 1111, 1108,
+ /* 300 */ 1007, 1000, 1002, 1076, 1075, 1081,
};
static const YYACTIONTYPE yy_default[] = {
- /* 0 */ 636, 872, 960, 960, 872, 872, 960, 960, 960, 762,
- /* 10 */ 960, 960, 960, 870, 960, 960, 790, 790, 934, 960,
- /* 20 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 30 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 40 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 50 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 60 */ 960, 960, 960, 960, 960, 960, 960, 677, 766, 796,
- /* 70 */ 960, 960, 960, 960, 960, 960, 960, 960, 933, 935,
- /* 80 */ 804, 803, 913, 777, 801, 794, 798, 873, 866, 867,
- /* 90 */ 865, 869, 874, 960, 797, 833, 850, 832, 844, 849,
- /* 100 */ 856, 848, 845, 835, 834, 836, 837, 960, 960, 960,
- /* 110 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 120 */ 960, 960, 960, 662, 731, 960, 960, 960, 960, 960,
- /* 130 */ 960, 960, 960, 838, 839, 853, 852, 851, 960, 669,
- /* 140 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 150 */ 940, 938, 960, 885, 960, 960, 960, 960, 960, 960,
- /* 160 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 170 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 180 */ 960, 642, 762, 762, 762, 636, 960, 960, 960, 952,
- /* 190 */ 766, 756, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 200 */ 960, 960, 960, 960, 806, 745, 923, 925, 960, 906,
- /* 210 */ 743, 664, 764, 679, 754, 644, 800, 779, 779, 918,
- /* 220 */ 800, 918, 702, 725, 960, 790, 960, 790, 699, 790,
- /* 230 */ 779, 868, 960, 960, 960, 763, 754, 960, 945, 770,
- /* 240 */ 770, 937, 937, 770, 812, 735, 800, 742, 742, 742,
- /* 250 */ 742, 770, 659, 800, 812, 735, 735, 800, 770, 659,
- /* 260 */ 912, 910, 770, 770, 659, 770, 659, 770, 659, 878,
- /* 270 */ 733, 733, 733, 717, 882, 882, 878, 733, 702, 733,
- /* 280 */ 717, 733, 733, 783, 778, 783, 778, 783, 778, 770,
- /* 290 */ 770, 960, 795, 784, 793, 791, 800, 960, 665, 720,
- /* 300 */ 652, 652, 641, 641, 641, 641, 957, 957, 952, 704,
- /* 310 */ 704, 687, 960, 960, 960, 960, 960, 960, 960, 887,
- /* 320 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 330 */ 960, 960, 637, 947, 960, 960, 944, 960, 960, 960,
- /* 340 */ 960, 805, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 350 */ 960, 960, 922, 960, 960, 960, 960, 960, 960, 960,
- /* 360 */ 916, 960, 960, 960, 960, 960, 960, 909, 908, 960,
- /* 370 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 380 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 390 */ 960, 960, 960, 960, 960, 792, 960, 785, 960, 871,
- /* 400 */ 960, 960, 960, 960, 960, 960, 960, 960, 960, 960,
- /* 410 */ 748, 821, 960, 820, 824, 819, 671, 960, 650, 960,
- /* 420 */ 633, 638, 956, 959, 958, 955, 954, 953, 948, 946,
- /* 430 */ 943, 942, 941, 939, 936, 932, 891, 889, 896, 895,
- /* 440 */ 894, 893, 892, 890, 888, 886, 807, 802, 799, 931,
- /* 450 */ 884, 744, 741, 740, 658, 949, 915, 924, 811, 810,
- /* 460 */ 813, 921, 920, 919, 917, 914, 901, 809, 808, 736,
- /* 470 */ 876, 875, 661, 905, 904, 903, 907, 911, 902, 772,
- /* 480 */ 660, 657, 668, 723, 724, 732, 730, 729, 728, 727,
- /* 490 */ 726, 722, 670, 678, 716, 701, 700, 881, 883, 880,
- /* 500 */ 879, 709, 708, 714, 713, 712, 711, 710, 707, 706,
- /* 510 */ 705, 698, 697, 703, 696, 719, 718, 715, 695, 739,
- /* 520 */ 738, 737, 734, 694, 693, 692, 824, 691, 690, 830,
- /* 530 */ 829, 817, 860, 759, 758, 757, 769, 768, 781, 780,
- /* 540 */ 815, 814, 782, 767, 761, 760, 776, 775, 774, 773,
- /* 550 */ 765, 755, 787, 789, 788, 786, 862, 771, 859, 930,
- /* 560 */ 929, 928, 927, 926, 864, 863, 831, 828, 682, 683,
- /* 570 */ 899, 898, 900, 897, 685, 684, 681, 680, 861, 750,
- /* 580 */ 749, 857, 854, 846, 842, 858, 855, 847, 843, 841,
- /* 590 */ 840, 826, 825, 823, 822, 818, 827, 673, 751, 747,
- /* 600 */ 746, 816, 753, 752, 689, 688, 686, 667, 666, 663,
- /* 610 */ 656, 654, 653, 655, 651, 649, 648, 647, 646, 645,
- /* 620 */ 676, 675, 674, 672, 671, 643, 640, 639, 635, 634,
- /* 630 */ 632,
+ /* 0 */ 647, 964, 964, 964, 878, 878, 969, 964, 774, 802,
+ /* 10 */ 802, 938, 969, 969, 969, 876, 969, 969, 969, 964,
+ /* 20 */ 969, 778, 808, 969, 969, 969, 969, 969, 969, 969,
+ /* 30 */ 969, 937, 939, 816, 815, 918, 789, 813, 806, 810,
+ /* 40 */ 879, 872, 873, 871, 875, 880, 969, 809, 841, 856,
+ /* 50 */ 840, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 60 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 70 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 80 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 90 */ 969, 969, 969, 969, 850, 855, 862, 854, 851, 843,
+ /* 100 */ 842, 844, 845, 969, 969, 673, 739, 969, 969, 846,
+ /* 110 */ 969, 685, 847, 859, 858, 857, 680, 969, 969, 969,
+ /* 120 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 130 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 140 */ 969, 969, 969, 969, 647, 964, 969, 969, 964, 964,
+ /* 150 */ 964, 964, 964, 964, 956, 778, 768, 969, 969, 969,
+ /* 160 */ 969, 969, 969, 969, 969, 969, 969, 944, 942, 969,
+ /* 170 */ 891, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 180 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 190 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 200 */ 969, 969, 969, 969, 653, 969, 911, 774, 774, 774,
+ /* 210 */ 776, 754, 766, 655, 812, 791, 791, 923, 812, 923,
+ /* 220 */ 710, 733, 707, 802, 791, 874, 802, 802, 775, 766,
+ /* 230 */ 969, 949, 782, 782, 941, 941, 782, 821, 743, 812,
+ /* 240 */ 750, 750, 750, 750, 782, 670, 812, 821, 743, 743,
+ /* 250 */ 812, 782, 670, 917, 915, 782, 782, 670, 782, 670,
+ /* 260 */ 782, 670, 884, 741, 741, 741, 725, 884, 741, 710,
+ /* 270 */ 741, 725, 741, 741, 795, 790, 795, 790, 795, 790,
+ /* 280 */ 782, 782, 969, 884, 888, 888, 884, 807, 796, 805,
+ /* 290 */ 803, 812, 676, 728, 663, 663, 652, 652, 652, 652,
+ /* 300 */ 961, 961, 956, 712, 712, 695, 969, 969, 969, 969,
+ /* 310 */ 969, 969, 687, 969, 893, 969, 969, 969, 969, 969,
+ /* 320 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 330 */ 969, 828, 969, 648, 951, 969, 969, 948, 969, 969,
+ /* 340 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 350 */ 969, 969, 969, 969, 969, 969, 921, 969, 969, 969,
+ /* 360 */ 969, 969, 969, 914, 913, 969, 969, 969, 969, 969,
+ /* 370 */ 969, 969, 969, 969, 969, 969, 969, 969, 969, 969,
+ /* 380 */ 969, 969, 969, 969, 969, 969, 969, 757, 969, 969,
+ /* 390 */ 969, 761, 969, 969, 969, 969, 969, 969, 804, 969,
+ /* 400 */ 797, 969, 877, 969, 969, 969, 969, 969, 969, 969,
+ /* 410 */ 969, 969, 969, 966, 969, 969, 969, 965, 969, 969,
+ /* 420 */ 969, 969, 969, 830, 969, 829, 833, 969, 661, 969,
+ /* 430 */ 644, 649, 960, 963, 962, 959, 958, 957, 952, 950,
+ /* 440 */ 947, 946, 945, 943, 940, 936, 897, 895, 902, 901,
+ /* 450 */ 900, 899, 898, 896, 894, 892, 818, 817, 814, 811,
+ /* 460 */ 753, 935, 890, 752, 749, 748, 669, 953, 920, 929,
+ /* 470 */ 928, 927, 822, 926, 925, 924, 922, 919, 906, 820,
+ /* 480 */ 819, 744, 882, 881, 672, 910, 909, 908, 912, 916,
+ /* 490 */ 907, 784, 751, 671, 668, 675, 679, 731, 732, 740,
+ /* 500 */ 738, 737, 736, 735, 734, 730, 681, 686, 724, 709,
+ /* 510 */ 708, 717, 716, 722, 721, 720, 719, 718, 715, 714,
+ /* 520 */ 713, 706, 705, 711, 704, 727, 726, 723, 703, 747,
+ /* 530 */ 746, 745, 742, 702, 701, 700, 833, 699, 698, 838,
+ /* 540 */ 837, 866, 826, 755, 759, 758, 762, 763, 771, 770,
+ /* 550 */ 769, 780, 781, 793, 792, 824, 823, 794, 779, 773,
+ /* 560 */ 772, 788, 787, 786, 785, 777, 767, 799, 798, 868,
+ /* 570 */ 783, 867, 865, 934, 933, 932, 931, 930, 870, 967,
+ /* 580 */ 968, 887, 889, 886, 801, 800, 885, 869, 839, 836,
+ /* 590 */ 690, 691, 905, 904, 903, 693, 692, 689, 688, 863,
+ /* 600 */ 860, 852, 864, 861, 853, 849, 848, 834, 832, 831,
+ /* 610 */ 827, 835, 760, 756, 825, 765, 764, 697, 696, 694,
+ /* 620 */ 678, 677, 674, 667, 665, 664, 666, 662, 660, 659,
+ /* 630 */ 658, 657, 656, 684, 683, 682, 654, 651, 650, 646,
+ /* 640 */ 645, 643,
};
/* The next table maps tokens into fallback tokens. If a construct
@@ -115159,6 +116170,7 @@ static const YYCODETYPE yyFallback[] = {
27, /* OFFSET => ID */
27, /* PRAGMA => ID */
27, /* RAISE => ID */
+ 27, /* RECURSIVE => ID */
27, /* REPLACE => ID */
27, /* RESTRICT => ID */
27, /* ROW => ID */
@@ -115166,6 +116178,7 @@ static const YYCODETYPE yyFallback[] = {
27, /* VACUUM => ID */
27, /* VIEW => ID */
27, /* VIRTUAL => ID */
+ 27, /* WITH => ID */
27, /* REINDEX => ID */
27, /* RENAME => ID */
27, /* CTIME_KW => ID */
@@ -115261,55 +116274,56 @@ static const char *const yyTokenName[] = {
"EACH", "FAIL", "FOR", "IGNORE",
"INITIALLY", "INSTEAD", "LIKE_KW", "MATCH",
"NO", "KEY", "OF", "OFFSET",
- "PRAGMA", "RAISE", "REPLACE", "RESTRICT",
- "ROW", "TRIGGER", "VACUUM", "VIEW",
- "VIRTUAL", "REINDEX", "RENAME", "CTIME_KW",
- "ANY", "OR", "AND", "IS",
- "BETWEEN", "IN", "ISNULL", "NOTNULL",
- "NE", "EQ", "GT", "LE",
- "LT", "GE", "ESCAPE", "BITAND",
- "BITOR", "LSHIFT", "RSHIFT", "PLUS",
- "MINUS", "STAR", "SLASH", "REM",
- "CONCAT", "COLLATE", "BITNOT", "STRING",
- "JOIN_KW", "CONSTRAINT", "DEFAULT", "NULL",
- "PRIMARY", "UNIQUE", "CHECK", "REFERENCES",
- "AUTOINCR", "ON", "INSERT", "DELETE",
- "UPDATE", "SET", "DEFERRABLE", "FOREIGN",
- "DROP", "UNION", "ALL", "EXCEPT",
- "INTERSECT", "SELECT", "DISTINCT", "DOT",
- "FROM", "JOIN", "USING", "ORDER",
- "GROUP", "HAVING", "LIMIT", "WHERE",
- "INTO", "VALUES", "INTEGER", "FLOAT",
- "BLOB", "REGISTER", "VARIABLE", "CASE",
- "WHEN", "THEN", "ELSE", "INDEX",
- "ALTER", "ADD", "error", "input",
- "cmdlist", "ecmd", "explain", "cmdx",
- "cmd", "transtype", "trans_opt", "nm",
- "savepoint_opt", "create_table", "create_table_args", "createkw",
- "temp", "ifnotexists", "dbnm", "columnlist",
- "conslist_opt", "table_options", "select", "column",
- "columnid", "type", "carglist", "id",
- "ids", "typetoken", "typename", "signed",
- "plus_num", "minus_num", "ccons", "term",
- "expr", "onconf", "sortorder", "autoinc",
- "idxlist_opt", "refargs", "defer_subclause", "refarg",
- "refact", "init_deferred_pred_opt", "conslist", "tconscomma",
- "tcons", "idxlist", "defer_subclause_opt", "orconf",
- "resolvetype", "raisetype", "ifexists", "fullname",
- "oneselect", "multiselect_op", "distinct", "selcollist",
- "from", "where_opt", "groupby_opt", "having_opt",
- "orderby_opt", "limit_opt", "sclp", "as",
+ "PRAGMA", "RAISE", "RECURSIVE", "REPLACE",
+ "RESTRICT", "ROW", "TRIGGER", "VACUUM",
+ "VIEW", "VIRTUAL", "WITH", "REINDEX",
+ "RENAME", "CTIME_KW", "ANY", "OR",
+ "AND", "IS", "BETWEEN", "IN",
+ "ISNULL", "NOTNULL", "NE", "EQ",
+ "GT", "LE", "LT", "GE",
+ "ESCAPE", "BITAND", "BITOR", "LSHIFT",
+ "RSHIFT", "PLUS", "MINUS", "STAR",
+ "SLASH", "REM", "CONCAT", "COLLATE",
+ "BITNOT", "STRING", "JOIN_KW", "CONSTRAINT",
+ "DEFAULT", "NULL", "PRIMARY", "UNIQUE",
+ "CHECK", "REFERENCES", "AUTOINCR", "ON",
+ "INSERT", "DELETE", "UPDATE", "SET",
+ "DEFERRABLE", "FOREIGN", "DROP", "UNION",
+ "ALL", "EXCEPT", "INTERSECT", "SELECT",
+ "VALUES", "DISTINCT", "DOT", "FROM",
+ "JOIN", "USING", "ORDER", "GROUP",
+ "HAVING", "LIMIT", "WHERE", "INTO",
+ "INTEGER", "FLOAT", "BLOB", "VARIABLE",
+ "CASE", "WHEN", "THEN", "ELSE",
+ "INDEX", "ALTER", "ADD", "error",
+ "input", "cmdlist", "ecmd", "explain",
+ "cmdx", "cmd", "transtype", "trans_opt",
+ "nm", "savepoint_opt", "create_table", "create_table_args",
+ "createkw", "temp", "ifnotexists", "dbnm",
+ "columnlist", "conslist_opt", "table_options", "select",
+ "column", "columnid", "type", "carglist",
+ "typetoken", "typename", "signed", "plus_num",
+ "minus_num", "ccons", "term", "expr",
+ "onconf", "sortorder", "autoinc", "idxlist_opt",
+ "refargs", "defer_subclause", "refarg", "refact",
+ "init_deferred_pred_opt", "conslist", "tconscomma", "tcons",
+ "idxlist", "defer_subclause_opt", "orconf", "resolvetype",
+ "raisetype", "ifexists", "fullname", "selectnowith",
+ "oneselect", "with", "multiselect_op", "distinct",
+ "selcollist", "from", "where_opt", "groupby_opt",
+ "having_opt", "orderby_opt", "limit_opt", "values",
+ "nexprlist", "exprlist", "sclp", "as",
"seltablist", "stl_prefix", "joinop", "indexed_opt",
"on_opt", "using_opt", "joinop2", "idlist",
- "sortlist", "nexprlist", "setlist", "insert_cmd",
- "inscollist_opt", "valuelist", "exprlist", "likeop",
- "between_op", "in_op", "case_operand", "case_exprlist",
- "case_else", "uniqueflag", "collate", "nmnum",
- "number", "trigger_decl", "trigger_cmd_list", "trigger_time",
+ "sortlist", "setlist", "insert_cmd", "inscollist_opt",
+ "likeop", "between_op", "in_op", "case_operand",
+ "case_exprlist", "case_else", "uniqueflag", "collate",
+ "nmnum", "trigger_decl", "trigger_cmd_list", "trigger_time",
"trigger_event", "foreach_clause", "when_clause", "trigger_cmd",
"trnm", "tridxby", "database_kw_opt", "key_opt",
"add_column_fullname", "kwcolumn_opt", "create_vtab", "vtabarglist",
"vtabarg", "vtabargtoken", "lp", "anylist",
+ "wqlist",
};
#endif /* NDEBUG */
@@ -115357,295 +116371,293 @@ static const char *const yyRuleName[] = {
/* 37 */ "columnlist ::= column",
/* 38 */ "column ::= columnid type carglist",
/* 39 */ "columnid ::= nm",
- /* 40 */ "id ::= ID",
- /* 41 */ "id ::= INDEXED",
- /* 42 */ "ids ::= ID|STRING",
- /* 43 */ "nm ::= id",
- /* 44 */ "nm ::= STRING",
- /* 45 */ "nm ::= JOIN_KW",
- /* 46 */ "type ::=",
- /* 47 */ "type ::= typetoken",
- /* 48 */ "typetoken ::= typename",
- /* 49 */ "typetoken ::= typename LP signed RP",
- /* 50 */ "typetoken ::= typename LP signed COMMA signed RP",
- /* 51 */ "typename ::= ids",
- /* 52 */ "typename ::= typename ids",
- /* 53 */ "signed ::= plus_num",
- /* 54 */ "signed ::= minus_num",
- /* 55 */ "carglist ::= carglist ccons",
- /* 56 */ "carglist ::=",
- /* 57 */ "ccons ::= CONSTRAINT nm",
- /* 58 */ "ccons ::= DEFAULT term",
- /* 59 */ "ccons ::= DEFAULT LP expr RP",
- /* 60 */ "ccons ::= DEFAULT PLUS term",
- /* 61 */ "ccons ::= DEFAULT MINUS term",
- /* 62 */ "ccons ::= DEFAULT id",
- /* 63 */ "ccons ::= NULL onconf",
- /* 64 */ "ccons ::= NOT NULL onconf",
- /* 65 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
- /* 66 */ "ccons ::= UNIQUE onconf",
- /* 67 */ "ccons ::= CHECK LP expr RP",
- /* 68 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
- /* 69 */ "ccons ::= defer_subclause",
- /* 70 */ "ccons ::= COLLATE ids",
- /* 71 */ "autoinc ::=",
- /* 72 */ "autoinc ::= AUTOINCR",
- /* 73 */ "refargs ::=",
- /* 74 */ "refargs ::= refargs refarg",
- /* 75 */ "refarg ::= MATCH nm",
- /* 76 */ "refarg ::= ON INSERT refact",
- /* 77 */ "refarg ::= ON DELETE refact",
- /* 78 */ "refarg ::= ON UPDATE refact",
- /* 79 */ "refact ::= SET NULL",
- /* 80 */ "refact ::= SET DEFAULT",
- /* 81 */ "refact ::= CASCADE",
- /* 82 */ "refact ::= RESTRICT",
- /* 83 */ "refact ::= NO ACTION",
- /* 84 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
- /* 85 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
- /* 86 */ "init_deferred_pred_opt ::=",
- /* 87 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
- /* 88 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
- /* 89 */ "conslist_opt ::=",
- /* 90 */ "conslist_opt ::= COMMA conslist",
- /* 91 */ "conslist ::= conslist tconscomma tcons",
- /* 92 */ "conslist ::= tcons",
- /* 93 */ "tconscomma ::= COMMA",
- /* 94 */ "tconscomma ::=",
- /* 95 */ "tcons ::= CONSTRAINT nm",
- /* 96 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
- /* 97 */ "tcons ::= UNIQUE LP idxlist RP onconf",
- /* 98 */ "tcons ::= CHECK LP expr RP onconf",
- /* 99 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
- /* 100 */ "defer_subclause_opt ::=",
- /* 101 */ "defer_subclause_opt ::= defer_subclause",
- /* 102 */ "onconf ::=",
- /* 103 */ "onconf ::= ON CONFLICT resolvetype",
- /* 104 */ "orconf ::=",
- /* 105 */ "orconf ::= OR resolvetype",
- /* 106 */ "resolvetype ::= raisetype",
- /* 107 */ "resolvetype ::= IGNORE",
- /* 108 */ "resolvetype ::= REPLACE",
- /* 109 */ "cmd ::= DROP TABLE ifexists fullname",
- /* 110 */ "ifexists ::= IF EXISTS",
- /* 111 */ "ifexists ::=",
- /* 112 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
- /* 113 */ "cmd ::= DROP VIEW ifexists fullname",
- /* 114 */ "cmd ::= select",
- /* 115 */ "select ::= oneselect",
- /* 116 */ "select ::= select multiselect_op oneselect",
- /* 117 */ "multiselect_op ::= UNION",
- /* 118 */ "multiselect_op ::= UNION ALL",
- /* 119 */ "multiselect_op ::= EXCEPT|INTERSECT",
- /* 120 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
- /* 121 */ "distinct ::= DISTINCT",
- /* 122 */ "distinct ::= ALL",
- /* 123 */ "distinct ::=",
- /* 124 */ "sclp ::= selcollist COMMA",
- /* 125 */ "sclp ::=",
- /* 126 */ "selcollist ::= sclp expr as",
- /* 127 */ "selcollist ::= sclp STAR",
- /* 128 */ "selcollist ::= sclp nm DOT STAR",
- /* 129 */ "as ::= AS nm",
- /* 130 */ "as ::= ids",
- /* 131 */ "as ::=",
- /* 132 */ "from ::=",
- /* 133 */ "from ::= FROM seltablist",
- /* 134 */ "stl_prefix ::= seltablist joinop",
- /* 135 */ "stl_prefix ::=",
- /* 136 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
- /* 137 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
- /* 138 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
- /* 139 */ "dbnm ::=",
- /* 140 */ "dbnm ::= DOT nm",
- /* 141 */ "fullname ::= nm dbnm",
- /* 142 */ "joinop ::= COMMA|JOIN",
- /* 143 */ "joinop ::= JOIN_KW JOIN",
- /* 144 */ "joinop ::= JOIN_KW nm JOIN",
- /* 145 */ "joinop ::= JOIN_KW nm nm JOIN",
- /* 146 */ "on_opt ::= ON expr",
- /* 147 */ "on_opt ::=",
- /* 148 */ "indexed_opt ::=",
- /* 149 */ "indexed_opt ::= INDEXED BY nm",
- /* 150 */ "indexed_opt ::= NOT INDEXED",
- /* 151 */ "using_opt ::= USING LP idlist RP",
- /* 152 */ "using_opt ::=",
- /* 153 */ "orderby_opt ::=",
- /* 154 */ "orderby_opt ::= ORDER BY sortlist",
- /* 155 */ "sortlist ::= sortlist COMMA expr sortorder",
- /* 156 */ "sortlist ::= expr sortorder",
- /* 157 */ "sortorder ::= ASC",
- /* 158 */ "sortorder ::= DESC",
- /* 159 */ "sortorder ::=",
- /* 160 */ "groupby_opt ::=",
- /* 161 */ "groupby_opt ::= GROUP BY nexprlist",
- /* 162 */ "having_opt ::=",
- /* 163 */ "having_opt ::= HAVING expr",
- /* 164 */ "limit_opt ::=",
- /* 165 */ "limit_opt ::= LIMIT expr",
- /* 166 */ "limit_opt ::= LIMIT expr OFFSET expr",
- /* 167 */ "limit_opt ::= LIMIT expr COMMA expr",
- /* 168 */ "cmd ::= DELETE FROM fullname indexed_opt where_opt",
- /* 169 */ "where_opt ::=",
- /* 170 */ "where_opt ::= WHERE expr",
- /* 171 */ "cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt",
- /* 172 */ "setlist ::= setlist COMMA nm EQ expr",
- /* 173 */ "setlist ::= nm EQ expr",
- /* 174 */ "cmd ::= insert_cmd INTO fullname inscollist_opt valuelist",
- /* 175 */ "cmd ::= insert_cmd INTO fullname inscollist_opt select",
- /* 176 */ "cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
+ /* 40 */ "nm ::= ID|INDEXED",
+ /* 41 */ "nm ::= STRING",
+ /* 42 */ "nm ::= JOIN_KW",
+ /* 43 */ "type ::=",
+ /* 44 */ "type ::= typetoken",
+ /* 45 */ "typetoken ::= typename",
+ /* 46 */ "typetoken ::= typename LP signed RP",
+ /* 47 */ "typetoken ::= typename LP signed COMMA signed RP",
+ /* 48 */ "typename ::= ID|STRING",
+ /* 49 */ "typename ::= typename ID|STRING",
+ /* 50 */ "signed ::= plus_num",
+ /* 51 */ "signed ::= minus_num",
+ /* 52 */ "carglist ::= carglist ccons",
+ /* 53 */ "carglist ::=",
+ /* 54 */ "ccons ::= CONSTRAINT nm",
+ /* 55 */ "ccons ::= DEFAULT term",
+ /* 56 */ "ccons ::= DEFAULT LP expr RP",
+ /* 57 */ "ccons ::= DEFAULT PLUS term",
+ /* 58 */ "ccons ::= DEFAULT MINUS term",
+ /* 59 */ "ccons ::= DEFAULT ID|INDEXED",
+ /* 60 */ "ccons ::= NULL onconf",
+ /* 61 */ "ccons ::= NOT NULL onconf",
+ /* 62 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc",
+ /* 63 */ "ccons ::= UNIQUE onconf",
+ /* 64 */ "ccons ::= CHECK LP expr RP",
+ /* 65 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+ /* 66 */ "ccons ::= defer_subclause",
+ /* 67 */ "ccons ::= COLLATE ID|STRING",
+ /* 68 */ "autoinc ::=",
+ /* 69 */ "autoinc ::= AUTOINCR",
+ /* 70 */ "refargs ::=",
+ /* 71 */ "refargs ::= refargs refarg",
+ /* 72 */ "refarg ::= MATCH nm",
+ /* 73 */ "refarg ::= ON INSERT refact",
+ /* 74 */ "refarg ::= ON DELETE refact",
+ /* 75 */ "refarg ::= ON UPDATE refact",
+ /* 76 */ "refact ::= SET NULL",
+ /* 77 */ "refact ::= SET DEFAULT",
+ /* 78 */ "refact ::= CASCADE",
+ /* 79 */ "refact ::= RESTRICT",
+ /* 80 */ "refact ::= NO ACTION",
+ /* 81 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 82 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 83 */ "init_deferred_pred_opt ::=",
+ /* 84 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 85 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 86 */ "conslist_opt ::=",
+ /* 87 */ "conslist_opt ::= COMMA conslist",
+ /* 88 */ "conslist ::= conslist tconscomma tcons",
+ /* 89 */ "conslist ::= tcons",
+ /* 90 */ "tconscomma ::= COMMA",
+ /* 91 */ "tconscomma ::=",
+ /* 92 */ "tcons ::= CONSTRAINT nm",
+ /* 93 */ "tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf",
+ /* 94 */ "tcons ::= UNIQUE LP idxlist RP onconf",
+ /* 95 */ "tcons ::= CHECK LP expr RP onconf",
+ /* 96 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+ /* 97 */ "defer_subclause_opt ::=",
+ /* 98 */ "defer_subclause_opt ::= defer_subclause",
+ /* 99 */ "onconf ::=",
+ /* 100 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 101 */ "orconf ::=",
+ /* 102 */ "orconf ::= OR resolvetype",
+ /* 103 */ "resolvetype ::= raisetype",
+ /* 104 */ "resolvetype ::= IGNORE",
+ /* 105 */ "resolvetype ::= REPLACE",
+ /* 106 */ "cmd ::= DROP TABLE ifexists fullname",
+ /* 107 */ "ifexists ::= IF EXISTS",
+ /* 108 */ "ifexists ::=",
+ /* 109 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select",
+ /* 110 */ "cmd ::= DROP VIEW ifexists fullname",
+ /* 111 */ "cmd ::= select",
+ /* 112 */ "select ::= with selectnowith",
+ /* 113 */ "selectnowith ::= oneselect",
+ /* 114 */ "selectnowith ::= selectnowith multiselect_op oneselect",
+ /* 115 */ "multiselect_op ::= UNION",
+ /* 116 */ "multiselect_op ::= UNION ALL",
+ /* 117 */ "multiselect_op ::= EXCEPT|INTERSECT",
+ /* 118 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 119 */ "oneselect ::= values",
+ /* 120 */ "values ::= VALUES LP nexprlist RP",
+ /* 121 */ "values ::= values COMMA LP exprlist RP",
+ /* 122 */ "distinct ::= DISTINCT",
+ /* 123 */ "distinct ::= ALL",
+ /* 124 */ "distinct ::=",
+ /* 125 */ "sclp ::= selcollist COMMA",
+ /* 126 */ "sclp ::=",
+ /* 127 */ "selcollist ::= sclp expr as",
+ /* 128 */ "selcollist ::= sclp STAR",
+ /* 129 */ "selcollist ::= sclp nm DOT STAR",
+ /* 130 */ "as ::= AS nm",
+ /* 131 */ "as ::= ID|STRING",
+ /* 132 */ "as ::=",
+ /* 133 */ "from ::=",
+ /* 134 */ "from ::= FROM seltablist",
+ /* 135 */ "stl_prefix ::= seltablist joinop",
+ /* 136 */ "stl_prefix ::=",
+ /* 137 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt",
+ /* 138 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt",
+ /* 139 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt",
+ /* 140 */ "dbnm ::=",
+ /* 141 */ "dbnm ::= DOT nm",
+ /* 142 */ "fullname ::= nm dbnm",
+ /* 143 */ "joinop ::= COMMA|JOIN",
+ /* 144 */ "joinop ::= JOIN_KW JOIN",
+ /* 145 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 146 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 147 */ "on_opt ::= ON expr",
+ /* 148 */ "on_opt ::=",
+ /* 149 */ "indexed_opt ::=",
+ /* 150 */ "indexed_opt ::= INDEXED BY nm",
+ /* 151 */ "indexed_opt ::= NOT INDEXED",
+ /* 152 */ "using_opt ::= USING LP idlist RP",
+ /* 153 */ "using_opt ::=",
+ /* 154 */ "orderby_opt ::=",
+ /* 155 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 156 */ "sortlist ::= sortlist COMMA expr sortorder",
+ /* 157 */ "sortlist ::= expr sortorder",
+ /* 158 */ "sortorder ::= ASC",
+ /* 159 */ "sortorder ::= DESC",
+ /* 160 */ "sortorder ::=",
+ /* 161 */ "groupby_opt ::=",
+ /* 162 */ "groupby_opt ::= GROUP BY nexprlist",
+ /* 163 */ "having_opt ::=",
+ /* 164 */ "having_opt ::= HAVING expr",
+ /* 165 */ "limit_opt ::=",
+ /* 166 */ "limit_opt ::= LIMIT expr",
+ /* 167 */ "limit_opt ::= LIMIT expr OFFSET expr",
+ /* 168 */ "limit_opt ::= LIMIT expr COMMA expr",
+ /* 169 */ "cmd ::= with DELETE FROM fullname indexed_opt where_opt",
+ /* 170 */ "where_opt ::=",
+ /* 171 */ "where_opt ::= WHERE expr",
+ /* 172 */ "cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt",
+ /* 173 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 174 */ "setlist ::= nm EQ expr",
+ /* 175 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt select",
+ /* 176 */ "cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES",
/* 177 */ "insert_cmd ::= INSERT orconf",
/* 178 */ "insert_cmd ::= REPLACE",
- /* 179 */ "valuelist ::= VALUES LP nexprlist RP",
- /* 180 */ "valuelist ::= valuelist COMMA LP exprlist RP",
- /* 181 */ "inscollist_opt ::=",
- /* 182 */ "inscollist_opt ::= LP idlist RP",
- /* 183 */ "idlist ::= idlist COMMA nm",
- /* 184 */ "idlist ::= nm",
- /* 185 */ "expr ::= term",
- /* 186 */ "expr ::= LP expr RP",
- /* 187 */ "term ::= NULL",
- /* 188 */ "expr ::= id",
- /* 189 */ "expr ::= JOIN_KW",
- /* 190 */ "expr ::= nm DOT nm",
- /* 191 */ "expr ::= nm DOT nm DOT nm",
- /* 192 */ "term ::= INTEGER|FLOAT|BLOB",
- /* 193 */ "term ::= STRING",
- /* 194 */ "expr ::= REGISTER",
- /* 195 */ "expr ::= VARIABLE",
- /* 196 */ "expr ::= expr COLLATE ids",
- /* 197 */ "expr ::= CAST LP expr AS typetoken RP",
- /* 198 */ "expr ::= ID LP distinct exprlist RP",
- /* 199 */ "expr ::= ID LP STAR RP",
- /* 200 */ "term ::= CTIME_KW",
- /* 201 */ "expr ::= expr AND expr",
- /* 202 */ "expr ::= expr OR expr",
- /* 203 */ "expr ::= expr LT|GT|GE|LE expr",
- /* 204 */ "expr ::= expr EQ|NE expr",
- /* 205 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
- /* 206 */ "expr ::= expr PLUS|MINUS expr",
- /* 207 */ "expr ::= expr STAR|SLASH|REM expr",
- /* 208 */ "expr ::= expr CONCAT expr",
- /* 209 */ "likeop ::= LIKE_KW",
- /* 210 */ "likeop ::= NOT LIKE_KW",
- /* 211 */ "likeop ::= MATCH",
- /* 212 */ "likeop ::= NOT MATCH",
- /* 213 */ "expr ::= expr likeop expr",
- /* 214 */ "expr ::= expr likeop expr ESCAPE expr",
- /* 215 */ "expr ::= expr ISNULL|NOTNULL",
- /* 216 */ "expr ::= expr NOT NULL",
- /* 217 */ "expr ::= expr IS expr",
- /* 218 */ "expr ::= expr IS NOT expr",
- /* 219 */ "expr ::= NOT expr",
- /* 220 */ "expr ::= BITNOT expr",
- /* 221 */ "expr ::= MINUS expr",
- /* 222 */ "expr ::= PLUS expr",
- /* 223 */ "between_op ::= BETWEEN",
- /* 224 */ "between_op ::= NOT BETWEEN",
- /* 225 */ "expr ::= expr between_op expr AND expr",
- /* 226 */ "in_op ::= IN",
- /* 227 */ "in_op ::= NOT IN",
- /* 228 */ "expr ::= expr in_op LP exprlist RP",
- /* 229 */ "expr ::= LP select RP",
- /* 230 */ "expr ::= expr in_op LP select RP",
- /* 231 */ "expr ::= expr in_op nm dbnm",
- /* 232 */ "expr ::= EXISTS LP select RP",
- /* 233 */ "expr ::= CASE case_operand case_exprlist case_else END",
- /* 234 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
- /* 235 */ "case_exprlist ::= WHEN expr THEN expr",
- /* 236 */ "case_else ::= ELSE expr",
- /* 237 */ "case_else ::=",
- /* 238 */ "case_operand ::= expr",
- /* 239 */ "case_operand ::=",
- /* 240 */ "exprlist ::= nexprlist",
- /* 241 */ "exprlist ::=",
- /* 242 */ "nexprlist ::= nexprlist COMMA expr",
- /* 243 */ "nexprlist ::= expr",
- /* 244 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
- /* 245 */ "uniqueflag ::= UNIQUE",
- /* 246 */ "uniqueflag ::=",
- /* 247 */ "idxlist_opt ::=",
- /* 248 */ "idxlist_opt ::= LP idxlist RP",
- /* 249 */ "idxlist ::= idxlist COMMA nm collate sortorder",
- /* 250 */ "idxlist ::= nm collate sortorder",
- /* 251 */ "collate ::=",
- /* 252 */ "collate ::= COLLATE ids",
- /* 253 */ "cmd ::= DROP INDEX ifexists fullname",
- /* 254 */ "cmd ::= VACUUM",
- /* 255 */ "cmd ::= VACUUM nm",
- /* 256 */ "cmd ::= PRAGMA nm dbnm",
- /* 257 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
- /* 258 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
- /* 259 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
- /* 260 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
- /* 261 */ "nmnum ::= plus_num",
- /* 262 */ "nmnum ::= nm",
- /* 263 */ "nmnum ::= ON",
- /* 264 */ "nmnum ::= DELETE",
- /* 265 */ "nmnum ::= DEFAULT",
- /* 266 */ "plus_num ::= PLUS number",
- /* 267 */ "plus_num ::= number",
- /* 268 */ "minus_num ::= MINUS number",
- /* 269 */ "number ::= INTEGER|FLOAT",
- /* 270 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
- /* 271 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
- /* 272 */ "trigger_time ::= BEFORE",
- /* 273 */ "trigger_time ::= AFTER",
- /* 274 */ "trigger_time ::= INSTEAD OF",
- /* 275 */ "trigger_time ::=",
- /* 276 */ "trigger_event ::= DELETE|INSERT",
- /* 277 */ "trigger_event ::= UPDATE",
- /* 278 */ "trigger_event ::= UPDATE OF idlist",
- /* 279 */ "foreach_clause ::=",
- /* 280 */ "foreach_clause ::= FOR EACH ROW",
- /* 281 */ "when_clause ::=",
- /* 282 */ "when_clause ::= WHEN expr",
- /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
- /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI",
- /* 285 */ "trnm ::= nm",
- /* 286 */ "trnm ::= nm DOT nm",
- /* 287 */ "tridxby ::=",
- /* 288 */ "tridxby ::= INDEXED BY nm",
- /* 289 */ "tridxby ::= NOT INDEXED",
- /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
- /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist",
- /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
- /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
- /* 294 */ "trigger_cmd ::= select",
- /* 295 */ "expr ::= RAISE LP IGNORE RP",
- /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP",
- /* 297 */ "raisetype ::= ROLLBACK",
- /* 298 */ "raisetype ::= ABORT",
- /* 299 */ "raisetype ::= FAIL",
- /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname",
- /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
- /* 302 */ "cmd ::= DETACH database_kw_opt expr",
- /* 303 */ "key_opt ::=",
- /* 304 */ "key_opt ::= KEY expr",
- /* 305 */ "database_kw_opt ::= DATABASE",
- /* 306 */ "database_kw_opt ::=",
- /* 307 */ "cmd ::= REINDEX",
- /* 308 */ "cmd ::= REINDEX nm dbnm",
- /* 309 */ "cmd ::= ANALYZE",
- /* 310 */ "cmd ::= ANALYZE nm dbnm",
- /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
- /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
- /* 313 */ "add_column_fullname ::= fullname",
- /* 314 */ "kwcolumn_opt ::=",
- /* 315 */ "kwcolumn_opt ::= COLUMNKW",
- /* 316 */ "cmd ::= create_vtab",
- /* 317 */ "cmd ::= create_vtab LP vtabarglist RP",
- /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
- /* 319 */ "vtabarglist ::= vtabarg",
- /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
- /* 321 */ "vtabarg ::=",
- /* 322 */ "vtabarg ::= vtabarg vtabargtoken",
- /* 323 */ "vtabargtoken ::= ANY",
- /* 324 */ "vtabargtoken ::= lp anylist RP",
- /* 325 */ "lp ::= LP",
- /* 326 */ "anylist ::=",
- /* 327 */ "anylist ::= anylist LP anylist RP",
- /* 328 */ "anylist ::= anylist ANY",
+ /* 179 */ "inscollist_opt ::=",
+ /* 180 */ "inscollist_opt ::= LP idlist RP",
+ /* 181 */ "idlist ::= idlist COMMA nm",
+ /* 182 */ "idlist ::= nm",
+ /* 183 */ "expr ::= term",
+ /* 184 */ "expr ::= LP expr RP",
+ /* 185 */ "term ::= NULL",
+ /* 186 */ "expr ::= ID|INDEXED",
+ /* 187 */ "expr ::= JOIN_KW",
+ /* 188 */ "expr ::= nm DOT nm",
+ /* 189 */ "expr ::= nm DOT nm DOT nm",
+ /* 190 */ "term ::= INTEGER|FLOAT|BLOB",
+ /* 191 */ "term ::= STRING",
+ /* 192 */ "expr ::= VARIABLE",
+ /* 193 */ "expr ::= expr COLLATE ID|STRING",
+ /* 194 */ "expr ::= CAST LP expr AS typetoken RP",
+ /* 195 */ "expr ::= ID|INDEXED LP distinct exprlist RP",
+ /* 196 */ "expr ::= ID|INDEXED LP STAR RP",
+ /* 197 */ "term ::= CTIME_KW",
+ /* 198 */ "expr ::= expr AND expr",
+ /* 199 */ "expr ::= expr OR expr",
+ /* 200 */ "expr ::= expr LT|GT|GE|LE expr",
+ /* 201 */ "expr ::= expr EQ|NE expr",
+ /* 202 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr",
+ /* 203 */ "expr ::= expr PLUS|MINUS expr",
+ /* 204 */ "expr ::= expr STAR|SLASH|REM expr",
+ /* 205 */ "expr ::= expr CONCAT expr",
+ /* 206 */ "likeop ::= LIKE_KW|MATCH",
+ /* 207 */ "likeop ::= NOT LIKE_KW|MATCH",
+ /* 208 */ "expr ::= expr likeop expr",
+ /* 209 */ "expr ::= expr likeop expr ESCAPE expr",
+ /* 210 */ "expr ::= expr ISNULL|NOTNULL",
+ /* 211 */ "expr ::= expr NOT NULL",
+ /* 212 */ "expr ::= expr IS expr",
+ /* 213 */ "expr ::= expr IS NOT expr",
+ /* 214 */ "expr ::= NOT expr",
+ /* 215 */ "expr ::= BITNOT expr",
+ /* 216 */ "expr ::= MINUS expr",
+ /* 217 */ "expr ::= PLUS expr",
+ /* 218 */ "between_op ::= BETWEEN",
+ /* 219 */ "between_op ::= NOT BETWEEN",
+ /* 220 */ "expr ::= expr between_op expr AND expr",
+ /* 221 */ "in_op ::= IN",
+ /* 222 */ "in_op ::= NOT IN",
+ /* 223 */ "expr ::= expr in_op LP exprlist RP",
+ /* 224 */ "expr ::= LP select RP",
+ /* 225 */ "expr ::= expr in_op LP select RP",
+ /* 226 */ "expr ::= expr in_op nm dbnm",
+ /* 227 */ "expr ::= EXISTS LP select RP",
+ /* 228 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 229 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 230 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 231 */ "case_else ::= ELSE expr",
+ /* 232 */ "case_else ::=",
+ /* 233 */ "case_operand ::= expr",
+ /* 234 */ "case_operand ::=",
+ /* 235 */ "exprlist ::= nexprlist",
+ /* 236 */ "exprlist ::=",
+ /* 237 */ "nexprlist ::= nexprlist COMMA expr",
+ /* 238 */ "nexprlist ::= expr",
+ /* 239 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
+ /* 240 */ "uniqueflag ::= UNIQUE",
+ /* 241 */ "uniqueflag ::=",
+ /* 242 */ "idxlist_opt ::=",
+ /* 243 */ "idxlist_opt ::= LP idxlist RP",
+ /* 244 */ "idxlist ::= idxlist COMMA nm collate sortorder",
+ /* 245 */ "idxlist ::= nm collate sortorder",
+ /* 246 */ "collate ::=",
+ /* 247 */ "collate ::= COLLATE ID|STRING",
+ /* 248 */ "cmd ::= DROP INDEX ifexists fullname",
+ /* 249 */ "cmd ::= VACUUM",
+ /* 250 */ "cmd ::= VACUUM nm",
+ /* 251 */ "cmd ::= PRAGMA nm dbnm",
+ /* 252 */ "cmd ::= PRAGMA nm dbnm EQ nmnum",
+ /* 253 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP",
+ /* 254 */ "cmd ::= PRAGMA nm dbnm EQ minus_num",
+ /* 255 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP",
+ /* 256 */ "nmnum ::= plus_num",
+ /* 257 */ "nmnum ::= nm",
+ /* 258 */ "nmnum ::= ON",
+ /* 259 */ "nmnum ::= DELETE",
+ /* 260 */ "nmnum ::= DEFAULT",
+ /* 261 */ "plus_num ::= PLUS INTEGER|FLOAT",
+ /* 262 */ "plus_num ::= INTEGER|FLOAT",
+ /* 263 */ "minus_num ::= MINUS INTEGER|FLOAT",
+ /* 264 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END",
+ /* 265 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause",
+ /* 266 */ "trigger_time ::= BEFORE",
+ /* 267 */ "trigger_time ::= AFTER",
+ /* 268 */ "trigger_time ::= INSTEAD OF",
+ /* 269 */ "trigger_time ::=",
+ /* 270 */ "trigger_event ::= DELETE|INSERT",
+ /* 271 */ "trigger_event ::= UPDATE",
+ /* 272 */ "trigger_event ::= UPDATE OF idlist",
+ /* 273 */ "foreach_clause ::=",
+ /* 274 */ "foreach_clause ::= FOR EACH ROW",
+ /* 275 */ "when_clause ::=",
+ /* 276 */ "when_clause ::= WHEN expr",
+ /* 277 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI",
+ /* 278 */ "trigger_cmd_list ::= trigger_cmd SEMI",
+ /* 279 */ "trnm ::= nm",
+ /* 280 */ "trnm ::= nm DOT nm",
+ /* 281 */ "tridxby ::=",
+ /* 282 */ "tridxby ::= INDEXED BY nm",
+ /* 283 */ "tridxby ::= NOT INDEXED",
+ /* 284 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt",
+ /* 285 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select",
+ /* 286 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt",
+ /* 287 */ "trigger_cmd ::= select",
+ /* 288 */ "expr ::= RAISE LP IGNORE RP",
+ /* 289 */ "expr ::= RAISE LP raisetype COMMA nm RP",
+ /* 290 */ "raisetype ::= ROLLBACK",
+ /* 291 */ "raisetype ::= ABORT",
+ /* 292 */ "raisetype ::= FAIL",
+ /* 293 */ "cmd ::= DROP TRIGGER ifexists fullname",
+ /* 294 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt",
+ /* 295 */ "cmd ::= DETACH database_kw_opt expr",
+ /* 296 */ "key_opt ::=",
+ /* 297 */ "key_opt ::= KEY expr",
+ /* 298 */ "database_kw_opt ::= DATABASE",
+ /* 299 */ "database_kw_opt ::=",
+ /* 300 */ "cmd ::= REINDEX",
+ /* 301 */ "cmd ::= REINDEX nm dbnm",
+ /* 302 */ "cmd ::= ANALYZE",
+ /* 303 */ "cmd ::= ANALYZE nm dbnm",
+ /* 304 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
+ /* 305 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column",
+ /* 306 */ "add_column_fullname ::= fullname",
+ /* 307 */ "kwcolumn_opt ::=",
+ /* 308 */ "kwcolumn_opt ::= COLUMNKW",
+ /* 309 */ "cmd ::= create_vtab",
+ /* 310 */ "cmd ::= create_vtab LP vtabarglist RP",
+ /* 311 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
+ /* 312 */ "vtabarglist ::= vtabarg",
+ /* 313 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
+ /* 314 */ "vtabarg ::=",
+ /* 315 */ "vtabarg ::= vtabarg vtabargtoken",
+ /* 316 */ "vtabargtoken ::= ANY",
+ /* 317 */ "vtabargtoken ::= lp anylist RP",
+ /* 318 */ "lp ::= LP",
+ /* 319 */ "anylist ::=",
+ /* 320 */ "anylist ::= anylist LP anylist RP",
+ /* 321 */ "anylist ::= anylist ANY",
+ /* 322 */ "with ::=",
+ /* 323 */ "with ::= WITH wqlist",
+ /* 324 */ "with ::= WITH RECURSIVE wqlist",
+ /* 325 */ "wqlist ::= nm idxlist_opt AS LP select RP",
+ /* 326 */ "wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP",
};
#endif /* NDEBUG */
@@ -115724,76 +116736,76 @@ static void yy_destructor(
** which appear on the RHS of the rule, but which are not used
** inside the C code.
*/
- case 162: /* select */
+ case 163: /* select */
+ case 195: /* selectnowith */
case 196: /* oneselect */
+ case 207: /* values */
{
-sqlite3SelectDelete(pParse->db, (yypminor->yy387));
+sqlite3SelectDelete(pParse->db, (yypminor->yy3));
}
break;
- case 175: /* term */
- case 176: /* expr */
+ case 174: /* term */
+ case 175: /* expr */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy118).pExpr);
+sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr);
}
break;
- case 180: /* idxlist_opt */
- case 189: /* idxlist */
- case 199: /* selcollist */
- case 202: /* groupby_opt */
- case 204: /* orderby_opt */
- case 206: /* sclp */
- case 216: /* sortlist */
- case 217: /* nexprlist */
- case 218: /* setlist */
- case 222: /* exprlist */
- case 227: /* case_exprlist */
+ case 179: /* idxlist_opt */
+ case 188: /* idxlist */
+ case 200: /* selcollist */
+ case 203: /* groupby_opt */
+ case 205: /* orderby_opt */
+ case 208: /* nexprlist */
+ case 209: /* exprlist */
+ case 210: /* sclp */
+ case 220: /* sortlist */
+ case 221: /* setlist */
+ case 228: /* case_exprlist */
{
-sqlite3ExprListDelete(pParse->db, (yypminor->yy322));
+sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
}
break;
- case 195: /* fullname */
- case 200: /* from */
- case 208: /* seltablist */
- case 209: /* stl_prefix */
+ case 194: /* fullname */
+ case 201: /* from */
+ case 212: /* seltablist */
+ case 213: /* stl_prefix */
{
-sqlite3SrcListDelete(pParse->db, (yypminor->yy259));
+sqlite3SrcListDelete(pParse->db, (yypminor->yy65));
}
break;
- case 201: /* where_opt */
- case 203: /* having_opt */
- case 212: /* on_opt */
- case 226: /* case_operand */
- case 228: /* case_else */
- case 238: /* when_clause */
- case 243: /* key_opt */
+ case 197: /* with */
+ case 252: /* wqlist */
{
-sqlite3ExprDelete(pParse->db, (yypminor->yy314));
+sqlite3WithDelete(pParse->db, (yypminor->yy59));
}
break;
- case 213: /* using_opt */
- case 215: /* idlist */
- case 220: /* inscollist_opt */
+ case 202: /* where_opt */
+ case 204: /* having_opt */
+ case 216: /* on_opt */
+ case 227: /* case_operand */
+ case 229: /* case_else */
+ case 238: /* when_clause */
+ case 243: /* key_opt */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy384));
+sqlite3ExprDelete(pParse->db, (yypminor->yy132));
}
break;
- case 221: /* valuelist */
+ case 217: /* using_opt */
+ case 219: /* idlist */
+ case 223: /* inscollist_opt */
{
-
- sqlite3ExprListDelete(pParse->db, (yypminor->yy260).pList);
- sqlite3SelectDelete(pParse->db, (yypminor->yy260).pSelect);
-
+sqlite3IdListDelete(pParse->db, (yypminor->yy408));
}
break;
case 234: /* trigger_cmd_list */
case 239: /* trigger_cmd */
{
-sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy203));
+sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy473));
}
break;
case 236: /* trigger_event */
{
-sqlite3IdListDelete(pParse->db, (yypminor->yy90).b);
+sqlite3IdListDelete(pParse->db, (yypminor->yy378).b);
}
break;
default: break; /* If no destructor action specified: do nothing */
@@ -116038,277 +117050,271 @@ static const struct {
YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
unsigned char nrhs; /* Number of right-hand side symbols in the rule */
} yyRuleInfo[] = {
- { 143, 1 },
- { 144, 2 },
{ 144, 1 },
+ { 145, 2 },
{ 145, 1 },
- { 145, 3 },
- { 146, 0 },
{ 146, 1 },
{ 146, 3 },
+ { 147, 0 },
{ 147, 1 },
- { 148, 3 },
+ { 147, 3 },
+ { 148, 1 },
+ { 149, 3 },
+ { 151, 0 },
+ { 151, 1 },
+ { 151, 2 },
{ 150, 0 },
{ 150, 1 },
- { 150, 2 },
- { 149, 0 },
- { 149, 1 },
- { 149, 1 },
- { 149, 1 },
- { 148, 2 },
- { 148, 2 },
- { 148, 2 },
- { 152, 1 },
- { 152, 0 },
- { 148, 2 },
- { 148, 3 },
- { 148, 5 },
- { 148, 2 },
- { 153, 6 },
- { 155, 1 },
- { 157, 0 },
- { 157, 3 },
+ { 150, 1 },
+ { 150, 1 },
+ { 149, 2 },
+ { 149, 2 },
+ { 149, 2 },
+ { 153, 1 },
+ { 153, 0 },
+ { 149, 2 },
+ { 149, 3 },
+ { 149, 5 },
+ { 149, 2 },
+ { 154, 6 },
{ 156, 1 },
- { 156, 0 },
- { 154, 5 },
- { 154, 2 },
- { 161, 0 },
- { 161, 2 },
- { 159, 3 },
- { 159, 1 },
- { 163, 3 },
- { 164, 1 },
- { 167, 1 },
- { 167, 1 },
- { 168, 1 },
- { 151, 1 },
- { 151, 1 },
- { 151, 1 },
- { 165, 0 },
+ { 158, 0 },
+ { 158, 3 },
+ { 157, 1 },
+ { 157, 0 },
+ { 155, 5 },
+ { 155, 2 },
+ { 162, 0 },
+ { 162, 2 },
+ { 160, 3 },
+ { 160, 1 },
+ { 164, 3 },
{ 165, 1 },
+ { 152, 1 },
+ { 152, 1 },
+ { 152, 1 },
+ { 166, 0 },
+ { 166, 1 },
+ { 168, 1 },
+ { 168, 4 },
+ { 168, 6 },
{ 169, 1 },
- { 169, 4 },
- { 169, 6 },
+ { 169, 2 },
{ 170, 1 },
- { 170, 2 },
- { 171, 1 },
- { 171, 1 },
- { 166, 2 },
- { 166, 0 },
- { 174, 2 },
- { 174, 2 },
- { 174, 4 },
- { 174, 3 },
- { 174, 3 },
- { 174, 2 },
- { 174, 2 },
- { 174, 3 },
- { 174, 5 },
- { 174, 2 },
- { 174, 4 },
- { 174, 4 },
- { 174, 1 },
- { 174, 2 },
- { 179, 0 },
- { 179, 1 },
- { 181, 0 },
- { 181, 2 },
+ { 170, 1 },
+ { 167, 2 },
+ { 167, 0 },
+ { 173, 2 },
+ { 173, 2 },
+ { 173, 4 },
+ { 173, 3 },
+ { 173, 3 },
+ { 173, 2 },
+ { 173, 2 },
+ { 173, 3 },
+ { 173, 5 },
+ { 173, 2 },
+ { 173, 4 },
+ { 173, 4 },
+ { 173, 1 },
+ { 173, 2 },
+ { 178, 0 },
+ { 178, 1 },
+ { 180, 0 },
+ { 180, 2 },
+ { 182, 2 },
+ { 182, 3 },
+ { 182, 3 },
+ { 182, 3 },
{ 183, 2 },
- { 183, 3 },
- { 183, 3 },
- { 183, 3 },
- { 184, 2 },
+ { 183, 2 },
+ { 183, 1 },
+ { 183, 1 },
+ { 183, 2 },
+ { 181, 3 },
+ { 181, 2 },
+ { 184, 0 },
{ 184, 2 },
- { 184, 1 },
- { 184, 1 },
{ 184, 2 },
- { 182, 3 },
- { 182, 2 },
- { 185, 0 },
- { 185, 2 },
- { 185, 2 },
- { 160, 0 },
- { 160, 2 },
- { 186, 3 },
+ { 161, 0 },
+ { 161, 2 },
+ { 185, 3 },
+ { 185, 1 },
{ 186, 1 },
- { 187, 1 },
- { 187, 0 },
- { 188, 2 },
- { 188, 7 },
- { 188, 5 },
- { 188, 5 },
- { 188, 10 },
+ { 186, 0 },
+ { 187, 2 },
+ { 187, 7 },
+ { 187, 5 },
+ { 187, 5 },
+ { 187, 10 },
+ { 189, 0 },
+ { 189, 1 },
+ { 176, 0 },
+ { 176, 3 },
{ 190, 0 },
- { 190, 1 },
- { 177, 0 },
- { 177, 3 },
- { 191, 0 },
- { 191, 2 },
- { 192, 1 },
- { 192, 1 },
- { 192, 1 },
- { 148, 4 },
- { 194, 2 },
- { 194, 0 },
- { 148, 8 },
- { 148, 4 },
- { 148, 1 },
- { 162, 1 },
- { 162, 3 },
- { 197, 1 },
- { 197, 2 },
- { 197, 1 },
- { 196, 9 },
+ { 190, 2 },
+ { 191, 1 },
+ { 191, 1 },
+ { 191, 1 },
+ { 149, 4 },
+ { 193, 2 },
+ { 193, 0 },
+ { 149, 8 },
+ { 149, 4 },
+ { 149, 1 },
+ { 163, 2 },
+ { 195, 1 },
+ { 195, 3 },
{ 198, 1 },
+ { 198, 2 },
{ 198, 1 },
- { 198, 0 },
- { 206, 2 },
- { 206, 0 },
- { 199, 3 },
- { 199, 2 },
- { 199, 4 },
- { 207, 2 },
- { 207, 1 },
- { 207, 0 },
- { 200, 0 },
- { 200, 2 },
- { 209, 2 },
- { 209, 0 },
- { 208, 7 },
- { 208, 7 },
- { 208, 7 },
- { 158, 0 },
- { 158, 2 },
- { 195, 2 },
- { 210, 1 },
+ { 196, 9 },
+ { 196, 1 },
+ { 207, 4 },
+ { 207, 5 },
+ { 199, 1 },
+ { 199, 1 },
+ { 199, 0 },
{ 210, 2 },
- { 210, 3 },
- { 210, 4 },
- { 212, 2 },
- { 212, 0 },
- { 211, 0 },
- { 211, 3 },
+ { 210, 0 },
+ { 200, 3 },
+ { 200, 2 },
+ { 200, 4 },
{ 211, 2 },
- { 213, 4 },
+ { 211, 1 },
+ { 211, 0 },
+ { 201, 0 },
+ { 201, 2 },
+ { 213, 2 },
{ 213, 0 },
- { 204, 0 },
- { 204, 3 },
- { 216, 4 },
+ { 212, 7 },
+ { 212, 7 },
+ { 212, 7 },
+ { 159, 0 },
+ { 159, 2 },
+ { 194, 2 },
+ { 214, 1 },
+ { 214, 2 },
+ { 214, 3 },
+ { 214, 4 },
{ 216, 2 },
- { 178, 1 },
- { 178, 1 },
- { 178, 0 },
- { 202, 0 },
- { 202, 3 },
- { 203, 0 },
- { 203, 2 },
+ { 216, 0 },
+ { 215, 0 },
+ { 215, 3 },
+ { 215, 2 },
+ { 217, 4 },
+ { 217, 0 },
{ 205, 0 },
- { 205, 2 },
- { 205, 4 },
- { 205, 4 },
- { 148, 5 },
- { 201, 0 },
- { 201, 2 },
- { 148, 7 },
- { 218, 5 },
- { 218, 3 },
- { 148, 5 },
- { 148, 5 },
- { 148, 6 },
- { 219, 2 },
- { 219, 1 },
- { 221, 4 },
+ { 205, 3 },
+ { 220, 4 },
+ { 220, 2 },
+ { 177, 1 },
+ { 177, 1 },
+ { 177, 0 },
+ { 203, 0 },
+ { 203, 3 },
+ { 204, 0 },
+ { 204, 2 },
+ { 206, 0 },
+ { 206, 2 },
+ { 206, 4 },
+ { 206, 4 },
+ { 149, 6 },
+ { 202, 0 },
+ { 202, 2 },
+ { 149, 8 },
{ 221, 5 },
- { 220, 0 },
- { 220, 3 },
- { 215, 3 },
- { 215, 1 },
- { 176, 1 },
- { 176, 3 },
+ { 221, 3 },
+ { 149, 6 },
+ { 149, 7 },
+ { 222, 2 },
+ { 222, 1 },
+ { 223, 0 },
+ { 223, 3 },
+ { 219, 3 },
+ { 219, 1 },
{ 175, 1 },
- { 176, 1 },
- { 176, 1 },
- { 176, 3 },
- { 176, 5 },
+ { 175, 3 },
+ { 174, 1 },
{ 175, 1 },
{ 175, 1 },
- { 176, 1 },
- { 176, 1 },
- { 176, 3 },
- { 176, 6 },
- { 176, 5 },
- { 176, 4 },
+ { 175, 3 },
+ { 175, 5 },
+ { 174, 1 },
+ { 174, 1 },
{ 175, 1 },
- { 176, 3 },
- { 176, 3 },
- { 176, 3 },
- { 176, 3 },
- { 176, 3 },
- { 176, 3 },
- { 176, 3 },
- { 176, 3 },
- { 223, 1 },
- { 223, 2 },
- { 223, 1 },
- { 223, 2 },
- { 176, 3 },
- { 176, 5 },
- { 176, 2 },
- { 176, 3 },
- { 176, 3 },
- { 176, 4 },
- { 176, 2 },
- { 176, 2 },
- { 176, 2 },
- { 176, 2 },
+ { 175, 3 },
+ { 175, 6 },
+ { 175, 5 },
+ { 175, 4 },
+ { 174, 1 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 3 },
{ 224, 1 },
{ 224, 2 },
- { 176, 5 },
+ { 175, 3 },
+ { 175, 5 },
+ { 175, 2 },
+ { 175, 3 },
+ { 175, 3 },
+ { 175, 4 },
+ { 175, 2 },
+ { 175, 2 },
+ { 175, 2 },
+ { 175, 2 },
{ 225, 1 },
{ 225, 2 },
- { 176, 5 },
- { 176, 3 },
- { 176, 5 },
- { 176, 4 },
- { 176, 4 },
- { 176, 5 },
- { 227, 5 },
- { 227, 4 },
- { 228, 2 },
- { 228, 0 },
+ { 175, 5 },
{ 226, 1 },
- { 226, 0 },
- { 222, 1 },
- { 222, 0 },
- { 217, 3 },
- { 217, 1 },
- { 148, 12 },
- { 229, 1 },
+ { 226, 2 },
+ { 175, 5 },
+ { 175, 3 },
+ { 175, 5 },
+ { 175, 4 },
+ { 175, 4 },
+ { 175, 5 },
+ { 228, 5 },
+ { 228, 4 },
+ { 229, 2 },
{ 229, 0 },
- { 180, 0 },
- { 180, 3 },
- { 189, 5 },
- { 189, 3 },
+ { 227, 1 },
+ { 227, 0 },
+ { 209, 1 },
+ { 209, 0 },
+ { 208, 3 },
+ { 208, 1 },
+ { 149, 12 },
+ { 230, 1 },
{ 230, 0 },
- { 230, 2 },
- { 148, 4 },
- { 148, 1 },
- { 148, 2 },
- { 148, 3 },
- { 148, 5 },
- { 148, 6 },
- { 148, 5 },
- { 148, 6 },
- { 231, 1 },
- { 231, 1 },
- { 231, 1 },
- { 231, 1 },
- { 231, 1 },
- { 172, 2 },
- { 172, 1 },
- { 173, 2 },
+ { 179, 0 },
+ { 179, 3 },
+ { 188, 5 },
+ { 188, 3 },
+ { 231, 0 },
+ { 231, 2 },
+ { 149, 4 },
+ { 149, 1 },
+ { 149, 2 },
+ { 149, 3 },
+ { 149, 5 },
+ { 149, 6 },
+ { 149, 5 },
+ { 149, 6 },
+ { 232, 1 },
+ { 232, 1 },
+ { 232, 1 },
{ 232, 1 },
- { 148, 5 },
+ { 232, 1 },
+ { 171, 2 },
+ { 171, 1 },
+ { 172, 2 },
+ { 149, 5 },
{ 233, 11 },
{ 235, 1 },
{ 235, 1 },
@@ -116331,31 +117337,30 @@ static const struct {
{ 239, 7 },
{ 239, 5 },
{ 239, 5 },
- { 239, 5 },
{ 239, 1 },
- { 176, 4 },
- { 176, 6 },
- { 193, 1 },
- { 193, 1 },
- { 193, 1 },
- { 148, 4 },
- { 148, 6 },
- { 148, 3 },
+ { 175, 4 },
+ { 175, 6 },
+ { 192, 1 },
+ { 192, 1 },
+ { 192, 1 },
+ { 149, 4 },
+ { 149, 6 },
+ { 149, 3 },
{ 243, 0 },
{ 243, 2 },
{ 242, 1 },
{ 242, 0 },
- { 148, 1 },
- { 148, 3 },
- { 148, 1 },
- { 148, 3 },
- { 148, 6 },
- { 148, 6 },
+ { 149, 1 },
+ { 149, 3 },
+ { 149, 1 },
+ { 149, 3 },
+ { 149, 6 },
+ { 149, 6 },
{ 244, 1 },
{ 245, 0 },
{ 245, 1 },
- { 148, 1 },
- { 148, 4 },
+ { 149, 1 },
+ { 149, 4 },
{ 246, 8 },
{ 247, 1 },
{ 247, 3 },
@@ -116367,6 +117372,11 @@ static const struct {
{ 251, 0 },
{ 251, 4 },
{ 251, 2 },
+ { 197, 0 },
+ { 197, 2 },
+ { 197, 3 },
+ { 252, 6 },
+ { 252, 8 },
};
static void yy_accept(yyParser*); /* Forward Declaration */
@@ -116434,17 +117444,17 @@ static void yy_reduce(
{ sqlite3FinishCoding(pParse); }
break;
case 9: /* cmd ::= BEGIN transtype trans_opt */
-{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy4);}
+{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);}
break;
case 13: /* transtype ::= */
-{yygotominor.yy4 = TK_DEFERRED;}
+{yygotominor.yy328 = TK_DEFERRED;}
break;
case 14: /* transtype ::= DEFERRED */
case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15);
case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16);
- case 117: /* multiselect_op ::= UNION */ yytestcase(yyruleno==117);
- case 119: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==119);
-{yygotominor.yy4 = yymsp[0].major;}
+ case 115: /* multiselect_op ::= UNION */ yytestcase(yyruleno==115);
+ case 117: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==117);
+{yygotominor.yy328 = yymsp[0].major;}
break;
case 17: /* cmd ::= COMMIT trans_opt */
case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18);
@@ -116470,7 +117480,7 @@ static void yy_reduce(
break;
case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
- sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy4,0,0,yymsp[-2].minor.yy4);
+ sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy328,0,0,yymsp[-2].minor.yy328);
}
break;
case 27: /* createkw ::= CREATE */
@@ -116481,45 +117491,45 @@ static void yy_reduce(
break;
case 28: /* ifnotexists ::= */
case 31: /* temp ::= */ yytestcase(yyruleno==31);
- case 71: /* autoinc ::= */ yytestcase(yyruleno==71);
- case 84: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==84);
- case 86: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==86);
- case 88: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==88);
- case 100: /* defer_subclause_opt ::= */ yytestcase(yyruleno==100);
- case 111: /* ifexists ::= */ yytestcase(yyruleno==111);
- case 223: /* between_op ::= BETWEEN */ yytestcase(yyruleno==223);
- case 226: /* in_op ::= IN */ yytestcase(yyruleno==226);
-{yygotominor.yy4 = 0;}
+ case 68: /* autoinc ::= */ yytestcase(yyruleno==68);
+ case 81: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==81);
+ case 83: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==83);
+ case 85: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==85);
+ case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97);
+ case 108: /* ifexists ::= */ yytestcase(yyruleno==108);
+ case 218: /* between_op ::= BETWEEN */ yytestcase(yyruleno==218);
+ case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
+{yygotominor.yy328 = 0;}
break;
case 29: /* ifnotexists ::= IF NOT EXISTS */
case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30);
- case 72: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==72);
- case 87: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==87);
- case 110: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==110);
- case 224: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==224);
- case 227: /* in_op ::= NOT IN */ yytestcase(yyruleno==227);
-{yygotominor.yy4 = 1;}
+ case 69: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==69);
+ case 84: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ yytestcase(yyruleno==84);
+ case 107: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==107);
+ case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
+ case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
+{yygotominor.yy328 = 1;}
break;
case 32: /* create_table_args ::= LP columnlist conslist_opt RP table_options */
{
- sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy210,0);
+ sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy186,0);
}
break;
case 33: /* create_table_args ::= AS select */
{
- sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy387);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
+ sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy3);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
}
break;
case 34: /* table_options ::= */
-{yygotominor.yy210 = 0;}
+{yygotominor.yy186 = 0;}
break;
case 35: /* table_options ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
- yygotominor.yy210 = TF_WithoutRowid;
+ yygotominor.yy186 = TF_WithoutRowid;
}else{
- yygotominor.yy210 = 0;
+ yygotominor.yy186 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
@@ -116537,650 +117547,669 @@ static void yy_reduce(
pParse->constraintName.n = 0;
}
break;
- case 40: /* id ::= ID */
- case 41: /* id ::= INDEXED */ yytestcase(yyruleno==41);
- case 42: /* ids ::= ID|STRING */ yytestcase(yyruleno==42);
- case 43: /* nm ::= id */ yytestcase(yyruleno==43);
- case 44: /* nm ::= STRING */ yytestcase(yyruleno==44);
- case 45: /* nm ::= JOIN_KW */ yytestcase(yyruleno==45);
- case 48: /* typetoken ::= typename */ yytestcase(yyruleno==48);
- case 51: /* typename ::= ids */ yytestcase(yyruleno==51);
- case 129: /* as ::= AS nm */ yytestcase(yyruleno==129);
- case 130: /* as ::= ids */ yytestcase(yyruleno==130);
- case 140: /* dbnm ::= DOT nm */ yytestcase(yyruleno==140);
- case 149: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==149);
- case 252: /* collate ::= COLLATE ids */ yytestcase(yyruleno==252);
- case 261: /* nmnum ::= plus_num */ yytestcase(yyruleno==261);
- case 262: /* nmnum ::= nm */ yytestcase(yyruleno==262);
- case 263: /* nmnum ::= ON */ yytestcase(yyruleno==263);
- case 264: /* nmnum ::= DELETE */ yytestcase(yyruleno==264);
- case 265: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==265);
- case 266: /* plus_num ::= PLUS number */ yytestcase(yyruleno==266);
- case 267: /* plus_num ::= number */ yytestcase(yyruleno==267);
- case 268: /* minus_num ::= MINUS number */ yytestcase(yyruleno==268);
- case 269: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==269);
- case 285: /* trnm ::= nm */ yytestcase(yyruleno==285);
+ case 40: /* nm ::= ID|INDEXED */
+ case 41: /* nm ::= STRING */ yytestcase(yyruleno==41);
+ case 42: /* nm ::= JOIN_KW */ yytestcase(yyruleno==42);
+ case 45: /* typetoken ::= typename */ yytestcase(yyruleno==45);
+ case 48: /* typename ::= ID|STRING */ yytestcase(yyruleno==48);
+ case 130: /* as ::= AS nm */ yytestcase(yyruleno==130);
+ case 131: /* as ::= ID|STRING */ yytestcase(yyruleno==131);
+ case 141: /* dbnm ::= DOT nm */ yytestcase(yyruleno==141);
+ case 150: /* indexed_opt ::= INDEXED BY nm */ yytestcase(yyruleno==150);
+ case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
+ case 256: /* nmnum ::= plus_num */ yytestcase(yyruleno==256);
+ case 257: /* nmnum ::= nm */ yytestcase(yyruleno==257);
+ case 258: /* nmnum ::= ON */ yytestcase(yyruleno==258);
+ case 259: /* nmnum ::= DELETE */ yytestcase(yyruleno==259);
+ case 260: /* nmnum ::= DEFAULT */ yytestcase(yyruleno==260);
+ case 261: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==261);
+ case 262: /* plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==262);
+ case 263: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==263);
+ case 279: /* trnm ::= nm */ yytestcase(yyruleno==279);
{yygotominor.yy0 = yymsp[0].minor.yy0;}
break;
- case 47: /* type ::= typetoken */
+ case 44: /* type ::= typetoken */
{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
break;
- case 49: /* typetoken ::= typename LP signed RP */
+ case 46: /* typetoken ::= typename LP signed RP */
{
yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z);
}
break;
- case 50: /* typetoken ::= typename LP signed COMMA signed RP */
+ case 47: /* typetoken ::= typename LP signed COMMA signed RP */
{
yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
yygotominor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z);
}
break;
- case 52: /* typename ::= typename ids */
+ case 49: /* typename ::= typename ID|STRING */
{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
- case 57: /* ccons ::= CONSTRAINT nm */
- case 95: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==95);
+ case 54: /* ccons ::= CONSTRAINT nm */
+ case 92: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==92);
{pParse->constraintName = yymsp[0].minor.yy0;}
break;
- case 58: /* ccons ::= DEFAULT term */
- case 60: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==60);
-{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy118);}
+ case 55: /* ccons ::= DEFAULT term */
+ case 57: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==57);
+{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy346);}
break;
- case 59: /* ccons ::= DEFAULT LP expr RP */
-{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy118);}
+ case 56: /* ccons ::= DEFAULT LP expr RP */
+{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy346);}
break;
- case 61: /* ccons ::= DEFAULT MINUS term */
+ case 58: /* ccons ::= DEFAULT MINUS term */
{
ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy118.pExpr, 0, 0);
+ v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy346.pExpr, 0, 0);
v.zStart = yymsp[-1].minor.yy0.z;
- v.zEnd = yymsp[0].minor.yy118.zEnd;
+ v.zEnd = yymsp[0].minor.yy346.zEnd;
sqlite3AddDefaultValue(pParse,&v);
}
break;
- case 62: /* ccons ::= DEFAULT id */
+ case 59: /* ccons ::= DEFAULT ID|INDEXED */
{
ExprSpan v;
spanExpr(&v, pParse, TK_STRING, &yymsp[0].minor.yy0);
sqlite3AddDefaultValue(pParse,&v);
}
break;
- case 64: /* ccons ::= NOT NULL onconf */
-{sqlite3AddNotNull(pParse, yymsp[0].minor.yy4);}
+ case 61: /* ccons ::= NOT NULL onconf */
+{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);}
break;
- case 65: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
-{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy4,yymsp[0].minor.yy4,yymsp[-2].minor.yy4);}
+ case 62: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
+{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);}
break;
- case 66: /* ccons ::= UNIQUE onconf */
-{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy4,0,0,0,0);}
+ case 63: /* ccons ::= UNIQUE onconf */
+{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0,0,0);}
break;
- case 67: /* ccons ::= CHECK LP expr RP */
-{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy118.pExpr);}
+ case 64: /* ccons ::= CHECK LP expr RP */
+{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy346.pExpr);}
break;
- case 68: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy4);}
+ case 65: /* ccons ::= REFERENCES nm idxlist_opt refargs */
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy328);}
break;
- case 69: /* ccons ::= defer_subclause */
-{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy4);}
+ case 66: /* ccons ::= defer_subclause */
+{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);}
break;
- case 70: /* ccons ::= COLLATE ids */
+ case 67: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
- case 73: /* refargs ::= */
-{ yygotominor.yy4 = OE_None*0x0101; /* EV: R-19803-45884 */}
+ case 70: /* refargs ::= */
+{ yygotominor.yy328 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
- case 74: /* refargs ::= refargs refarg */
-{ yygotominor.yy4 = (yymsp[-1].minor.yy4 & ~yymsp[0].minor.yy215.mask) | yymsp[0].minor.yy215.value; }
+ case 71: /* refargs ::= refargs refarg */
+{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & ~yymsp[0].minor.yy429.mask) | yymsp[0].minor.yy429.value; }
break;
- case 75: /* refarg ::= MATCH nm */
- case 76: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==76);
-{ yygotominor.yy215.value = 0; yygotominor.yy215.mask = 0x000000; }
+ case 72: /* refarg ::= MATCH nm */
+ case 73: /* refarg ::= ON INSERT refact */ yytestcase(yyruleno==73);
+{ yygotominor.yy429.value = 0; yygotominor.yy429.mask = 0x000000; }
break;
- case 77: /* refarg ::= ON DELETE refact */
-{ yygotominor.yy215.value = yymsp[0].minor.yy4; yygotominor.yy215.mask = 0x0000ff; }
+ case 74: /* refarg ::= ON DELETE refact */
+{ yygotominor.yy429.value = yymsp[0].minor.yy328; yygotominor.yy429.mask = 0x0000ff; }
break;
- case 78: /* refarg ::= ON UPDATE refact */
-{ yygotominor.yy215.value = yymsp[0].minor.yy4<<8; yygotominor.yy215.mask = 0x00ff00; }
+ case 75: /* refarg ::= ON UPDATE refact */
+{ yygotominor.yy429.value = yymsp[0].minor.yy328<<8; yygotominor.yy429.mask = 0x00ff00; }
break;
- case 79: /* refact ::= SET NULL */
-{ yygotominor.yy4 = OE_SetNull; /* EV: R-33326-45252 */}
+ case 76: /* refact ::= SET NULL */
+{ yygotominor.yy328 = OE_SetNull; /* EV: R-33326-45252 */}
break;
- case 80: /* refact ::= SET DEFAULT */
-{ yygotominor.yy4 = OE_SetDflt; /* EV: R-33326-45252 */}
+ case 77: /* refact ::= SET DEFAULT */
+{ yygotominor.yy328 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
- case 81: /* refact ::= CASCADE */
-{ yygotominor.yy4 = OE_Cascade; /* EV: R-33326-45252 */}
+ case 78: /* refact ::= CASCADE */
+{ yygotominor.yy328 = OE_Cascade; /* EV: R-33326-45252 */}
break;
- case 82: /* refact ::= RESTRICT */
-{ yygotominor.yy4 = OE_Restrict; /* EV: R-33326-45252 */}
+ case 79: /* refact ::= RESTRICT */
+{ yygotominor.yy328 = OE_Restrict; /* EV: R-33326-45252 */}
break;
- case 83: /* refact ::= NO ACTION */
-{ yygotominor.yy4 = OE_None; /* EV: R-33326-45252 */}
+ case 80: /* refact ::= NO ACTION */
+{ yygotominor.yy328 = OE_None; /* EV: R-33326-45252 */}
break;
- case 85: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
- case 101: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==101);
- case 103: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==103);
- case 106: /* resolvetype ::= raisetype */ yytestcase(yyruleno==106);
-{yygotominor.yy4 = yymsp[0].minor.yy4;}
+ case 82: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
+ case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98);
+ case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100);
+ case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103);
+{yygotominor.yy328 = yymsp[0].minor.yy328;}
break;
- case 89: /* conslist_opt ::= */
+ case 86: /* conslist_opt ::= */
{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
break;
- case 90: /* conslist_opt ::= COMMA conslist */
+ case 87: /* conslist_opt ::= COMMA conslist */
{yygotominor.yy0 = yymsp[-1].minor.yy0;}
break;
- case 93: /* tconscomma ::= COMMA */
+ case 90: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
break;
- case 96: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
-{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy4,yymsp[-2].minor.yy4,0);}
+ case 93: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
+{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy328,yymsp[-2].minor.yy328,0);}
break;
- case 97: /* tcons ::= UNIQUE LP idxlist RP onconf */
-{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy4,0,0,0,0);}
+ case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */
+{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy328,0,0,0,0);}
break;
- case 98: /* tcons ::= CHECK LP expr RP onconf */
-{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy118.pExpr);}
+ case 95: /* tcons ::= CHECK LP expr RP onconf */
+{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy346.pExpr);}
break;
- case 99: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
+ case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
{
- sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy4);
- sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy4);
+ sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy328);
+ sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328);
}
break;
- case 102: /* onconf ::= */
-{yygotominor.yy4 = OE_Default;}
+ case 99: /* onconf ::= */
+{yygotominor.yy328 = OE_Default;}
break;
- case 104: /* orconf ::= */
-{yygotominor.yy210 = OE_Default;}
+ case 101: /* orconf ::= */
+{yygotominor.yy186 = OE_Default;}
break;
- case 105: /* orconf ::= OR resolvetype */
-{yygotominor.yy210 = (u8)yymsp[0].minor.yy4;}
+ case 102: /* orconf ::= OR resolvetype */
+{yygotominor.yy186 = (u8)yymsp[0].minor.yy328;}
break;
- case 107: /* resolvetype ::= IGNORE */
-{yygotominor.yy4 = OE_Ignore;}
+ case 104: /* resolvetype ::= IGNORE */
+{yygotominor.yy328 = OE_Ignore;}
break;
- case 108: /* resolvetype ::= REPLACE */
-{yygotominor.yy4 = OE_Replace;}
+ case 105: /* resolvetype ::= REPLACE */
+{yygotominor.yy328 = OE_Replace;}
break;
- case 109: /* cmd ::= DROP TABLE ifexists fullname */
+ case 106: /* cmd ::= DROP TABLE ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy259, 0, yymsp[-1].minor.yy4);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy65, 0, yymsp[-1].minor.yy328);
}
break;
- case 112: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
+ case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */
{
- sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy387, yymsp[-6].minor.yy4, yymsp[-4].minor.yy4);
+ sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy3, yymsp[-6].minor.yy328, yymsp[-4].minor.yy328);
}
break;
- case 113: /* cmd ::= DROP VIEW ifexists fullname */
+ case 110: /* cmd ::= DROP VIEW ifexists fullname */
{
- sqlite3DropTable(pParse, yymsp[0].minor.yy259, 1, yymsp[-1].minor.yy4);
+ sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328);
}
break;
- case 114: /* cmd ::= select */
+ case 111: /* cmd ::= select */
{
- SelectDest dest = {SRT_Output, 0, 0, 0, 0};
- sqlite3Select(pParse, yymsp[0].minor.yy387, &dest);
+ SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
+ sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
sqlite3ExplainBegin(pParse->pVdbe);
- sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy387);
+ sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy3);
sqlite3ExplainFinish(pParse->pVdbe);
- sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
+}
+ break;
+ case 112: /* select ::= with selectnowith */
+{
+ Select *p = yymsp[0].minor.yy3, *pNext, *pLoop;
+ if( p ){
+ int cnt = 0, mxSelect;
+ p->pWith = yymsp[-1].minor.yy59;
+ if( p->pPrior ){
+ pNext = 0;
+ for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
+ pLoop->pNext = pNext;
+ pLoop->selFlags |= SF_Compound;
+ }
+ mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
+ if( mxSelect && cnt>mxSelect ){
+ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
+ }
+ }
+ }else{
+ sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
+ }
+ yygotominor.yy3 = p;
}
break;
- case 115: /* select ::= oneselect */
-{yygotominor.yy387 = yymsp[0].minor.yy387;}
+ case 113: /* selectnowith ::= oneselect */
+ case 119: /* oneselect ::= values */ yytestcase(yyruleno==119);
+{yygotominor.yy3 = yymsp[0].minor.yy3;}
break;
- case 116: /* select ::= select multiselect_op oneselect */
+ case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
- if( yymsp[0].minor.yy387 ){
- yymsp[0].minor.yy387->op = (u8)yymsp[-1].minor.yy4;
- yymsp[0].minor.yy387->pPrior = yymsp[-2].minor.yy387;
- if( yymsp[-1].minor.yy4!=TK_ALL ) pParse->hasCompound = 1;
+ Select *pRhs = yymsp[0].minor.yy3;
+ if( pRhs && pRhs->pPrior ){
+ SrcList *pFrom;
+ Token x;
+ x.n = 0;
+ pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
+ pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
+ }
+ if( pRhs ){
+ pRhs->op = (u8)yymsp[-1].minor.yy328;
+ pRhs->pPrior = yymsp[-2].minor.yy3;
+ if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
}
- yygotominor.yy387 = yymsp[0].minor.yy387;
+ yygotominor.yy3 = pRhs;
}
break;
- case 118: /* multiselect_op ::= UNION ALL */
-{yygotominor.yy4 = TK_ALL;}
+ case 116: /* multiselect_op ::= UNION ALL */
+{yygotominor.yy328 = TK_ALL;}
break;
- case 120: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
+ case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
- yygotominor.yy387 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy259,yymsp[-4].minor.yy314,yymsp[-3].minor.yy322,yymsp[-2].minor.yy314,yymsp[-1].minor.yy322,yymsp[-7].minor.yy177,yymsp[0].minor.yy292.pLimit,yymsp[0].minor.yy292.pOffset);
+ yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
}
break;
- case 121: /* distinct ::= DISTINCT */
-{yygotominor.yy177 = SF_Distinct;}
+ case 120: /* values ::= VALUES LP nexprlist RP */
+{
+ yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
+}
break;
- case 122: /* distinct ::= ALL */
- case 123: /* distinct ::= */ yytestcase(yyruleno==123);
-{yygotominor.yy177 = 0;}
+ case 121: /* values ::= values COMMA LP exprlist RP */
+{
+ Select *pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
+ if( pRight ){
+ pRight->op = TK_ALL;
+ pRight->pPrior = yymsp[-4].minor.yy3;
+ yygotominor.yy3 = pRight;
+ }else{
+ yygotominor.yy3 = yymsp[-4].minor.yy3;
+ }
+}
+ break;
+ case 122: /* distinct ::= DISTINCT */
+{yygotominor.yy381 = SF_Distinct;}
break;
- case 124: /* sclp ::= selcollist COMMA */
- case 248: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==248);
-{yygotominor.yy322 = yymsp[-1].minor.yy322;}
+ case 123: /* distinct ::= ALL */
+ case 124: /* distinct ::= */ yytestcase(yyruleno==124);
+{yygotominor.yy381 = 0;}
break;
- case 125: /* sclp ::= */
- case 153: /* orderby_opt ::= */ yytestcase(yyruleno==153);
- case 160: /* groupby_opt ::= */ yytestcase(yyruleno==160);
- case 241: /* exprlist ::= */ yytestcase(yyruleno==241);
- case 247: /* idxlist_opt ::= */ yytestcase(yyruleno==247);
-{yygotominor.yy322 = 0;}
+ case 125: /* sclp ::= selcollist COMMA */
+ case 243: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==243);
+{yygotominor.yy14 = yymsp[-1].minor.yy14;}
break;
- case 126: /* selcollist ::= sclp expr as */
+ case 126: /* sclp ::= */
+ case 154: /* orderby_opt ::= */ yytestcase(yyruleno==154);
+ case 161: /* groupby_opt ::= */ yytestcase(yyruleno==161);
+ case 236: /* exprlist ::= */ yytestcase(yyruleno==236);
+ case 242: /* idxlist_opt ::= */ yytestcase(yyruleno==242);
+{yygotominor.yy14 = 0;}
+ break;
+ case 127: /* selcollist ::= sclp expr as */
{
- yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, yymsp[-1].minor.yy118.pExpr);
- if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[0].minor.yy0, 1);
- sqlite3ExprListSetSpan(pParse,yygotominor.yy322,&yymsp[-1].minor.yy118);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, yymsp[-1].minor.yy346.pExpr);
+ if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[0].minor.yy0, 1);
+ sqlite3ExprListSetSpan(pParse,yygotominor.yy14,&yymsp[-1].minor.yy346);
}
break;
- case 127: /* selcollist ::= sclp STAR */
+ case 128: /* selcollist ::= sclp STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0);
- yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy322, p);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy14, p);
}
break;
- case 128: /* selcollist ::= sclp nm DOT STAR */
+ case 129: /* selcollist ::= sclp nm DOT STAR */
{
Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0);
Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, pDot);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, pDot);
}
break;
- case 131: /* as ::= */
+ case 132: /* as ::= */
{yygotominor.yy0.n = 0;}
break;
- case 132: /* from ::= */
-{yygotominor.yy259 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy259));}
+ case 133: /* from ::= */
+{yygotominor.yy65 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy65));}
break;
- case 133: /* from ::= FROM seltablist */
+ case 134: /* from ::= FROM seltablist */
{
- yygotominor.yy259 = yymsp[0].minor.yy259;
- sqlite3SrcListShiftJoinType(yygotominor.yy259);
+ yygotominor.yy65 = yymsp[0].minor.yy65;
+ sqlite3SrcListShiftJoinType(yygotominor.yy65);
}
break;
- case 134: /* stl_prefix ::= seltablist joinop */
+ case 135: /* stl_prefix ::= seltablist joinop */
{
- yygotominor.yy259 = yymsp[-1].minor.yy259;
- if( ALWAYS(yygotominor.yy259 && yygotominor.yy259->nSrc>0) ) yygotominor.yy259->a[yygotominor.yy259->nSrc-1].jointype = (u8)yymsp[0].minor.yy4;
+ yygotominor.yy65 = yymsp[-1].minor.yy65;
+ if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) yygotominor.yy65->a[yygotominor.yy65->nSrc-1].jointype = (u8)yymsp[0].minor.yy328;
}
break;
- case 135: /* stl_prefix ::= */
-{yygotominor.yy259 = 0;}
+ case 136: /* stl_prefix ::= */
+{yygotominor.yy65 = 0;}
break;
- case 136: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
+ case 137: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */
{
- yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
- sqlite3SrcListIndexedBy(pParse, yygotominor.yy259, &yymsp[-2].minor.yy0);
+ yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
+ sqlite3SrcListIndexedBy(pParse, yygotominor.yy65, &yymsp[-2].minor.yy0);
}
break;
- case 137: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
+ case 138: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */
{
- yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy387,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy3,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
}
break;
- case 138: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
+ case 139: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */
{
- if( yymsp[-6].minor.yy259==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy314==0 && yymsp[0].minor.yy384==0 ){
- yygotominor.yy259 = yymsp[-4].minor.yy259;
- }else if( yymsp[-4].minor.yy259->nSrc==1 ){
- yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
- if( yygotominor.yy259 ){
- struct SrcList_item *pNew = &yygotominor.yy259->a[yygotominor.yy259->nSrc-1];
- struct SrcList_item *pOld = yymsp[-4].minor.yy259->a;
+ if( yymsp[-6].minor.yy65==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy132==0 && yymsp[0].minor.yy408==0 ){
+ yygotominor.yy65 = yymsp[-4].minor.yy65;
+ }else if( yymsp[-4].minor.yy65->nSrc==1 ){
+ yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
+ if( yygotominor.yy65 ){
+ struct SrcList_item *pNew = &yygotominor.yy65->a[yygotominor.yy65->nSrc-1];
+ struct SrcList_item *pOld = yymsp[-4].minor.yy65->a;
pNew->zName = pOld->zName;
pNew->zDatabase = pOld->zDatabase;
pNew->pSelect = pOld->pSelect;
pOld->zName = pOld->zDatabase = 0;
pOld->pSelect = 0;
}
- sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy259);
+ sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy65);
}else{
Select *pSubquery;
- sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy259);
- pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy259,0,0,0,0,SF_NestedFrom,0,0);
- yygotominor.yy259 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy259,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy314,yymsp[0].minor.yy384);
+ sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy65);
+ pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy65,0,0,0,0,SF_NestedFrom,0,0);
+ yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy132,yymsp[0].minor.yy408);
}
}
break;
- case 139: /* dbnm ::= */
- case 148: /* indexed_opt ::= */ yytestcase(yyruleno==148);
+ case 140: /* dbnm ::= */
+ case 149: /* indexed_opt ::= */ yytestcase(yyruleno==149);
{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
break;
- case 141: /* fullname ::= nm dbnm */
-{yygotominor.yy259 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
+ case 142: /* fullname ::= nm dbnm */
+{yygotominor.yy65 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
break;
- case 142: /* joinop ::= COMMA|JOIN */
-{ yygotominor.yy4 = JT_INNER; }
+ case 143: /* joinop ::= COMMA|JOIN */
+{ yygotominor.yy328 = JT_INNER; }
break;
- case 143: /* joinop ::= JOIN_KW JOIN */
-{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+ case 144: /* joinop ::= JOIN_KW JOIN */
+{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
break;
- case 144: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
+ case 145: /* joinop ::= JOIN_KW nm JOIN */
+{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
break;
- case 145: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy4 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
+ case 146: /* joinop ::= JOIN_KW nm nm JOIN */
+{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
break;
- case 146: /* on_opt ::= ON expr */
- case 163: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==163);
- case 170: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==170);
- case 236: /* case_else ::= ELSE expr */ yytestcase(yyruleno==236);
- case 238: /* case_operand ::= expr */ yytestcase(yyruleno==238);
-{yygotominor.yy314 = yymsp[0].minor.yy118.pExpr;}
+ case 147: /* on_opt ::= ON expr */
+ case 164: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==164);
+ case 171: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==171);
+ case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
+ case 233: /* case_operand ::= expr */ yytestcase(yyruleno==233);
+{yygotominor.yy132 = yymsp[0].minor.yy346.pExpr;}
break;
- case 147: /* on_opt ::= */
- case 162: /* having_opt ::= */ yytestcase(yyruleno==162);
- case 169: /* where_opt ::= */ yytestcase(yyruleno==169);
- case 237: /* case_else ::= */ yytestcase(yyruleno==237);
- case 239: /* case_operand ::= */ yytestcase(yyruleno==239);
-{yygotominor.yy314 = 0;}
+ case 148: /* on_opt ::= */
+ case 163: /* having_opt ::= */ yytestcase(yyruleno==163);
+ case 170: /* where_opt ::= */ yytestcase(yyruleno==170);
+ case 232: /* case_else ::= */ yytestcase(yyruleno==232);
+ case 234: /* case_operand ::= */ yytestcase(yyruleno==234);
+{yygotominor.yy132 = 0;}
break;
- case 150: /* indexed_opt ::= NOT INDEXED */
+ case 151: /* indexed_opt ::= NOT INDEXED */
{yygotominor.yy0.z=0; yygotominor.yy0.n=1;}
break;
- case 151: /* using_opt ::= USING LP idlist RP */
- case 182: /* inscollist_opt ::= LP idlist RP */ yytestcase(yyruleno==182);
-{yygotominor.yy384 = yymsp[-1].minor.yy384;}
+ case 152: /* using_opt ::= USING LP idlist RP */
+ case 180: /* inscollist_opt ::= LP idlist RP */ yytestcase(yyruleno==180);
+{yygotominor.yy408 = yymsp[-1].minor.yy408;}
break;
- case 152: /* using_opt ::= */
- case 181: /* inscollist_opt ::= */ yytestcase(yyruleno==181);
-{yygotominor.yy384 = 0;}
+ case 153: /* using_opt ::= */
+ case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179);
+{yygotominor.yy408 = 0;}
break;
- case 154: /* orderby_opt ::= ORDER BY sortlist */
- case 161: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==161);
- case 240: /* exprlist ::= nexprlist */ yytestcase(yyruleno==240);
-{yygotominor.yy322 = yymsp[0].minor.yy322;}
+ case 155: /* orderby_opt ::= ORDER BY sortlist */
+ case 162: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==162);
+ case 235: /* exprlist ::= nexprlist */ yytestcase(yyruleno==235);
+{yygotominor.yy14 = yymsp[0].minor.yy14;}
break;
- case 155: /* sortlist ::= sortlist COMMA expr sortorder */
+ case 156: /* sortlist ::= sortlist COMMA expr sortorder */
{
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322,yymsp[-1].minor.yy118.pExpr);
- if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14,yymsp[-1].minor.yy346.pExpr);
+ if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
}
break;
- case 156: /* sortlist ::= expr sortorder */
+ case 157: /* sortlist ::= expr sortorder */
{
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy118.pExpr);
- if( yygotominor.yy322 && ALWAYS(yygotominor.yy322->a) ) yygotominor.yy322->a[0].sortOrder = (u8)yymsp[0].minor.yy4;
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy346.pExpr);
+ if( yygotominor.yy14 && ALWAYS(yygotominor.yy14->a) ) yygotominor.yy14->a[0].sortOrder = (u8)yymsp[0].minor.yy328;
}
break;
- case 157: /* sortorder ::= ASC */
- case 159: /* sortorder ::= */ yytestcase(yyruleno==159);
-{yygotominor.yy4 = SQLITE_SO_ASC;}
+ case 158: /* sortorder ::= ASC */
+ case 160: /* sortorder ::= */ yytestcase(yyruleno==160);
+{yygotominor.yy328 = SQLITE_SO_ASC;}
break;
- case 158: /* sortorder ::= DESC */
-{yygotominor.yy4 = SQLITE_SO_DESC;}
+ case 159: /* sortorder ::= DESC */
+{yygotominor.yy328 = SQLITE_SO_DESC;}
break;
- case 164: /* limit_opt ::= */
-{yygotominor.yy292.pLimit = 0; yygotominor.yy292.pOffset = 0;}
+ case 165: /* limit_opt ::= */
+{yygotominor.yy476.pLimit = 0; yygotominor.yy476.pOffset = 0;}
break;
- case 165: /* limit_opt ::= LIMIT expr */
-{yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr; yygotominor.yy292.pOffset = 0;}
+ case 166: /* limit_opt ::= LIMIT expr */
+{yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr; yygotominor.yy476.pOffset = 0;}
break;
- case 166: /* limit_opt ::= LIMIT expr OFFSET expr */
-{yygotominor.yy292.pLimit = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pOffset = yymsp[0].minor.yy118.pExpr;}
+ case 167: /* limit_opt ::= LIMIT expr OFFSET expr */
+{yygotominor.yy476.pLimit = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pOffset = yymsp[0].minor.yy346.pExpr;}
break;
- case 167: /* limit_opt ::= LIMIT expr COMMA expr */
-{yygotominor.yy292.pOffset = yymsp[-2].minor.yy118.pExpr; yygotominor.yy292.pLimit = yymsp[0].minor.yy118.pExpr;}
+ case 168: /* limit_opt ::= LIMIT expr COMMA expr */
+{yygotominor.yy476.pOffset = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr;}
break;
- case 168: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */
+ case 169: /* cmd ::= with DELETE FROM fullname indexed_opt where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy259, &yymsp[-1].minor.yy0);
- sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy259,yymsp[0].minor.yy314);
+ sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy65, &yymsp[-1].minor.yy0);
+ sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy65,yymsp[0].minor.yy132);
}
break;
- case 171: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */
+ case 172: /* cmd ::= with UPDATE orconf fullname indexed_opt SET setlist where_opt */
{
- sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy259, &yymsp[-3].minor.yy0);
- sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy322,"set list");
- sqlite3Update(pParse,yymsp[-4].minor.yy259,yymsp[-1].minor.yy322,yymsp[0].minor.yy314,yymsp[-5].minor.yy210);
+ sqlite3WithPush(pParse, yymsp[-7].minor.yy59, 1);
+ sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy65, &yymsp[-3].minor.yy0);
+ sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy14,"set list");
+ sqlite3Update(pParse,yymsp[-4].minor.yy65,yymsp[-1].minor.yy14,yymsp[0].minor.yy132,yymsp[-5].minor.yy186);
}
break;
- case 172: /* setlist ::= setlist COMMA nm EQ expr */
+ case 173: /* setlist ::= setlist COMMA nm EQ expr */
{
- yygotominor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy118.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy346.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
}
break;
- case 173: /* setlist ::= nm EQ expr */
+ case 174: /* setlist ::= nm EQ expr */
{
- yygotominor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy118.pExpr);
- sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy346.pExpr);
+ sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
}
break;
- case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt valuelist */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy259, yymsp[0].minor.yy260.pList, yymsp[0].minor.yy260.pSelect, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);}
- break;
- case 175: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */
-{sqlite3Insert(pParse, yymsp[-2].minor.yy259, 0, yymsp[0].minor.yy387, yymsp[-1].minor.yy384, yymsp[-4].minor.yy210);}
- break;
- case 176: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
-{sqlite3Insert(pParse, yymsp[-3].minor.yy259, 0, 0, yymsp[-2].minor.yy384, yymsp[-5].minor.yy210);}
- break;
- case 177: /* insert_cmd ::= INSERT orconf */
-{yygotominor.yy210 = yymsp[0].minor.yy210;}
- break;
- case 178: /* insert_cmd ::= REPLACE */
-{yygotominor.yy210 = OE_Replace;}
- break;
- case 179: /* valuelist ::= VALUES LP nexprlist RP */
+ case 175: /* cmd ::= with insert_cmd INTO fullname inscollist_opt select */
{
- yygotominor.yy260.pList = yymsp[-1].minor.yy322;
- yygotominor.yy260.pSelect = 0;
+ sqlite3WithPush(pParse, yymsp[-5].minor.yy59, 1);
+ sqlite3Insert(pParse, yymsp[-2].minor.yy65, yymsp[0].minor.yy3, yymsp[-1].minor.yy408, yymsp[-4].minor.yy186);
}
break;
- case 180: /* valuelist ::= valuelist COMMA LP exprlist RP */
+ case 176: /* cmd ::= with insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */
{
- Select *pRight = sqlite3SelectNew(pParse, yymsp[-1].minor.yy322, 0, 0, 0, 0, 0, 0, 0, 0);
- if( yymsp[-4].minor.yy260.pList ){
- yymsp[-4].minor.yy260.pSelect = sqlite3SelectNew(pParse, yymsp[-4].minor.yy260.pList, 0, 0, 0, 0, 0, 0, 0, 0);
- yymsp[-4].minor.yy260.pList = 0;
- }
- yygotominor.yy260.pList = 0;
- if( yymsp[-4].minor.yy260.pSelect==0 || pRight==0 ){
- sqlite3SelectDelete(pParse->db, pRight);
- sqlite3SelectDelete(pParse->db, yymsp[-4].minor.yy260.pSelect);
- yygotominor.yy260.pSelect = 0;
- }else{
- pRight->op = TK_ALL;
- pRight->pPrior = yymsp[-4].minor.yy260.pSelect;
- pRight->selFlags |= SF_Values;
- pRight->pPrior->selFlags |= SF_Values;
- yygotominor.yy260.pSelect = pRight;
- }
+ sqlite3WithPush(pParse, yymsp[-6].minor.yy59, 1);
+ sqlite3Insert(pParse, yymsp[-3].minor.yy65, 0, yymsp[-2].minor.yy408, yymsp[-5].minor.yy186);
}
break;
- case 183: /* idlist ::= idlist COMMA nm */
-{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy384,&yymsp[0].minor.yy0);}
+ case 177: /* insert_cmd ::= INSERT orconf */
+{yygotominor.yy186 = yymsp[0].minor.yy186;}
+ break;
+ case 178: /* insert_cmd ::= REPLACE */
+{yygotominor.yy186 = OE_Replace;}
+ break;
+ case 181: /* idlist ::= idlist COMMA nm */
+{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy408,&yymsp[0].minor.yy0);}
break;
- case 184: /* idlist ::= nm */
-{yygotominor.yy384 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
+ case 182: /* idlist ::= nm */
+{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
break;
- case 185: /* expr ::= term */
-{yygotominor.yy118 = yymsp[0].minor.yy118;}
+ case 183: /* expr ::= term */
+{yygotominor.yy346 = yymsp[0].minor.yy346;}
break;
- case 186: /* expr ::= LP expr RP */
-{yygotominor.yy118.pExpr = yymsp[-1].minor.yy118.pExpr; spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
+ case 184: /* expr ::= LP expr RP */
+{yygotominor.yy346.pExpr = yymsp[-1].minor.yy346.pExpr; spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);}
break;
- case 187: /* term ::= NULL */
- case 192: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==192);
- case 193: /* term ::= STRING */ yytestcase(yyruleno==193);
-{spanExpr(&yygotominor.yy118, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
+ case 185: /* term ::= NULL */
+ case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190);
+ case 191: /* term ::= STRING */ yytestcase(yyruleno==191);
+{spanExpr(&yygotominor.yy346, pParse, yymsp[0].major, &yymsp[0].minor.yy0);}
break;
- case 188: /* expr ::= id */
- case 189: /* expr ::= JOIN_KW */ yytestcase(yyruleno==189);
-{spanExpr(&yygotominor.yy118, pParse, TK_ID, &yymsp[0].minor.yy0);}
+ case 186: /* expr ::= ID|INDEXED */
+ case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187);
+{spanExpr(&yygotominor.yy346, pParse, TK_ID, &yymsp[0].minor.yy0);}
break;
- case 190: /* expr ::= nm DOT nm */
+ case 188: /* expr ::= nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
- spanSet(&yygotominor.yy118,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
+ spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 191: /* expr ::= nm DOT nm DOT nm */
+ case 189: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
- spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
+ spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 194: /* expr ::= REGISTER */
+ case 192: /* expr ::= VARIABLE */
{
- /* When doing a nested parse, one can include terms in an expression
- ** that look like this: #1 #2 ... These terms refer to registers
- ** in the virtual machine. #N is the N-th register. */
- if( pParse->nested==0 ){
- sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
- yygotominor.yy118.pExpr = 0;
+ if( yymsp[0].minor.yy0.n>=2 && yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1]) ){
+ /* When doing a nested parse, one can include terms in an expression
+ ** that look like this: #1 #2 ... These terms refer to registers
+ ** in the virtual machine. #N is the N-th register. */
+ if( pParse->nested==0 ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0);
+ yygotominor.yy346.pExpr = 0;
+ }else{
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
+ if( yygotominor.yy346.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy346.pExpr->iTable);
+ }
}else{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0);
- if( yygotominor.yy118.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy118.pExpr->iTable);
+ spanExpr(&yygotominor.yy346, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
+ sqlite3ExprAssignVarNumber(pParse, yygotominor.yy346.pExpr);
}
- spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 195: /* expr ::= VARIABLE */
+ case 193: /* expr ::= expr COLLATE ID|STRING */
{
- spanExpr(&yygotominor.yy118, pParse, TK_VARIABLE, &yymsp[0].minor.yy0);
- sqlite3ExprAssignVarNumber(pParse, yygotominor.yy118.pExpr);
- spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0);
+ yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 196: /* expr ::= expr COLLATE ids */
+ case 194: /* expr ::= CAST LP expr AS typetoken RP */
{
- yygotominor.yy118.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy118.pExpr, &yymsp[0].minor.yy0);
- yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy346.pExpr, 0, &yymsp[-1].minor.yy0);
+ spanSet(&yygotominor.yy346,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 197: /* expr ::= CAST LP expr AS typetoken RP */
+ case 195: /* expr ::= ID|INDEXED LP distinct exprlist RP */
{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy118.pExpr, 0, &yymsp[-1].minor.yy0);
- spanSet(&yygotominor.yy118,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
-}
- break;
- case 198: /* expr ::= ID LP distinct exprlist RP */
-{
- if( yymsp[-1].minor.yy322 && yymsp[-1].minor.yy322->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
+ if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
}
- yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0);
- spanSet(&yygotominor.yy118,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
- if( yymsp[-2].minor.yy177 && yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->flags |= EP_Distinct;
+ yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
+ spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
+ if( yymsp[-2].minor.yy381 && yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->flags |= EP_Distinct;
}
}
break;
- case 199: /* expr ::= ID LP STAR RP */
+ case 196: /* expr ::= ID|INDEXED LP STAR RP */
{
- yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
- spanSet(&yygotominor.yy118,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+ yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0);
+ spanSet(&yygotominor.yy346,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
}
break;
- case 200: /* term ::= CTIME_KW */
+ case 197: /* term ::= CTIME_KW */
{
- yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
- spanSet(&yygotominor.yy118, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
+ yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0);
+ spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0);
}
break;
- case 201: /* expr ::= expr AND expr */
- case 202: /* expr ::= expr OR expr */ yytestcase(yyruleno==202);
- case 203: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==203);
- case 204: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==204);
- case 205: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==205);
- case 206: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==206);
- case 207: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==207);
- case 208: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==208);
-{spanBinaryExpr(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);}
+ case 198: /* expr ::= expr AND expr */
+ case 199: /* expr ::= expr OR expr */ yytestcase(yyruleno==199);
+ case 200: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==200);
+ case 201: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==201);
+ case 202: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==202);
+ case 203: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==203);
+ case 204: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==204);
+ case 205: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==205);
+{spanBinaryExpr(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);}
break;
- case 209: /* likeop ::= LIKE_KW */
- case 211: /* likeop ::= MATCH */ yytestcase(yyruleno==211);
-{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 0;}
+ case 206: /* likeop ::= LIKE_KW|MATCH */
+{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 0;}
break;
- case 210: /* likeop ::= NOT LIKE_KW */
- case 212: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==212);
-{yygotominor.yy342.eOperator = yymsp[0].minor.yy0; yygotominor.yy342.bNot = 1;}
+ case 207: /* likeop ::= NOT LIKE_KW|MATCH */
+{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.bNot = 1;}
break;
- case 213: /* expr ::= expr likeop expr */
+ case 208: /* expr ::= expr likeop expr */
{
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy118.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy118.pExpr);
- yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy342.eOperator);
- if( yymsp[-1].minor.yy342.bNot ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
- yygotominor.yy118.zStart = yymsp[-2].minor.yy118.zStart;
- yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
- if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy346.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy346.pExpr);
+ yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy96.eOperator);
+ if( yymsp[-1].minor.yy96.bNot ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
+ yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
+ yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
+ if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc;
}
break;
- case 214: /* expr ::= expr likeop expr ESCAPE expr */
+ case 209: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
- pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy118.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
- yygotominor.yy118.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy342.eOperator);
- if( yymsp[-3].minor.yy342.bNot ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
- yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
- yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
- if( yygotominor.yy118.pExpr ) yygotominor.yy118.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy346.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
+ yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy96.eOperator);
+ if( yymsp[-3].minor.yy96.bNot ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
+ yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+ yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
+ if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc;
}
break;
- case 215: /* expr ::= expr ISNULL|NOTNULL */
-{spanUnaryPostfix(&yygotominor.yy118,pParse,yymsp[0].major,&yymsp[-1].minor.yy118,&yymsp[0].minor.yy0);}
+ case 210: /* expr ::= expr ISNULL|NOTNULL */
+{spanUnaryPostfix(&yygotominor.yy346,pParse,yymsp[0].major,&yymsp[-1].minor.yy346,&yymsp[0].minor.yy0);}
break;
- case 216: /* expr ::= expr NOT NULL */
-{spanUnaryPostfix(&yygotominor.yy118,pParse,TK_NOTNULL,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy0);}
+ case 211: /* expr ::= expr NOT NULL */
+{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);}
break;
- case 217: /* expr ::= expr IS expr */
+ case 212: /* expr ::= expr IS expr */
{
- spanBinaryExpr(&yygotominor.yy118,pParse,TK_IS,&yymsp[-2].minor.yy118,&yymsp[0].minor.yy118);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_ISNULL);
+ spanBinaryExpr(&yygotominor.yy346,pParse,TK_IS,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_ISNULL);
}
break;
- case 218: /* expr ::= expr IS NOT expr */
+ case 213: /* expr ::= expr IS NOT expr */
{
- spanBinaryExpr(&yygotominor.yy118,pParse,TK_ISNOT,&yymsp[-3].minor.yy118,&yymsp[0].minor.yy118);
- binaryToUnaryIfNull(pParse, yymsp[0].minor.yy118.pExpr, yygotominor.yy118.pExpr, TK_NOTNULL);
+ spanBinaryExpr(&yygotominor.yy346,pParse,TK_ISNOT,&yymsp[-3].minor.yy346,&yymsp[0].minor.yy346);
+ binaryToUnaryIfNull(pParse, yymsp[0].minor.yy346.pExpr, yygotominor.yy346.pExpr, TK_NOTNULL);
}
break;
- case 219: /* expr ::= NOT expr */
- case 220: /* expr ::= BITNOT expr */ yytestcase(yyruleno==220);
-{spanUnaryPrefix(&yygotominor.yy118,pParse,yymsp[-1].major,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+ case 214: /* expr ::= NOT expr */
+ case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
+{spanUnaryPrefix(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
break;
- case 221: /* expr ::= MINUS expr */
-{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UMINUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+ case 216: /* expr ::= MINUS expr */
+{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UMINUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
break;
- case 222: /* expr ::= PLUS expr */
-{spanUnaryPrefix(&yygotominor.yy118,pParse,TK_UPLUS,&yymsp[0].minor.yy118,&yymsp[-1].minor.yy0);}
+ case 217: /* expr ::= PLUS expr */
+{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UPLUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);}
break;
- case 225: /* expr ::= expr between_op expr AND expr */
+ case 220: /* expr ::= expr between_op expr AND expr */
{
- ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy118.pExpr);
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy118.pExpr, 0, 0);
- if( yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
+ pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy346.pExpr, 0, 0);
+ if( yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
- yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
- yygotominor.yy118.zEnd = yymsp[0].minor.yy118.zEnd;
+ if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
+ yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+ yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd;
}
break;
- case 228: /* expr ::= expr in_op LP exprlist RP */
+ case 223: /* expr ::= expr in_op LP exprlist RP */
{
- if( yymsp[-1].minor.yy322==0 ){
+ if( yymsp[-1].minor.yy14==0 ){
/* Expressions of the form
**
** expr1 IN ()
@@ -117189,225 +118218,225 @@ static void yy_reduce(
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy4]);
- sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy118.pExpr);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &sqlite3IntTokens[yymsp[-3].minor.yy328]);
+ sqlite3ExprDelete(pParse->db, yymsp[-4].minor.yy346.pExpr);
}else{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
- if( yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy322;
- sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
+ if( yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322);
+ sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
}
- if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
+ if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
}
- yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 229: /* expr ::= LP select RP */
+ case 224: /* expr ::= LP select RP */
{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
- if( yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
- ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
+ ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
}
- yygotominor.yy118.zStart = yymsp[-2].minor.yy0.z;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy346.zStart = yymsp[-2].minor.yy0.z;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 230: /* expr ::= expr in_op LP select RP */
+ case 225: /* expr ::= expr in_op LP select RP */
{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy118.pExpr, 0, 0);
- if( yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->x.pSelect = yymsp[-1].minor.yy387;
- ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
+ if( yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
+ ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
}
- if( yymsp[-3].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
- yygotominor.yy118.zStart = yymsp[-4].minor.yy118.zStart;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
+ yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 231: /* expr ::= expr in_op nm dbnm */
+ case 226: /* expr ::= expr in_op nm dbnm */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy118.pExpr, 0, 0);
- if( yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
- ExprSetProperty(yygotominor.yy118.pExpr, EP_xIsSelect);
- sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0);
+ if( yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
+ ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
sqlite3SrcListDelete(pParse->db, pSrc);
}
- if( yymsp[-2].minor.yy4 ) yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy118.pExpr, 0, 0);
- yygotominor.yy118.zStart = yymsp[-3].minor.yy118.zStart;
- yygotominor.yy118.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
+ if( yymsp[-2].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0);
+ yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart;
+ yygotominor.yy346.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n];
}
break;
- case 232: /* expr ::= EXISTS LP select RP */
+ case 227: /* expr ::= EXISTS LP select RP */
{
- Expr *p = yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
+ Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
if( p ){
- p->x.pSelect = yymsp[-1].minor.yy387;
+ p->x.pSelect = yymsp[-1].minor.yy3;
ExprSetProperty(p, EP_xIsSelect);
sqlite3ExprSetHeight(pParse, p);
}else{
- sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy387);
+ sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
}
- yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 233: /* expr ::= CASE case_operand case_exprlist case_else END */
+ case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy314, 0, 0);
- if( yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->x.pList = yymsp[-1].minor.yy314 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy314) : yymsp[-2].minor.yy322;
- sqlite3ExprSetHeight(pParse, yygotominor.yy118.pExpr);
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, 0, 0);
+ if( yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy132 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy132) : yymsp[-2].minor.yy14;
+ sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
}else{
- sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322);
- sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy314);
+ sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
+ sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy132);
}
- yygotominor.yy118.zStart = yymsp[-4].minor.yy0.z;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy346.zStart = yymsp[-4].minor.yy0.z;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 234: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
+ case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy118.pExpr);
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy346.pExpr);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
}
break;
- case 235: /* case_exprlist ::= WHEN expr THEN expr */
+ case 230: /* case_exprlist ::= WHEN expr THEN expr */
{
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy118.pExpr);
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,yygotominor.yy322, yymsp[0].minor.yy118.pExpr);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr);
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr);
}
break;
- case 242: /* nexprlist ::= nexprlist COMMA expr */
-{yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy118.pExpr);}
+ case 237: /* nexprlist ::= nexprlist COMMA expr */
+{yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy346.pExpr);}
break;
- case 243: /* nexprlist ::= expr */
-{yygotominor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy118.pExpr);}
+ case 238: /* nexprlist ::= expr */
+{yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy346.pExpr);}
break;
- case 244: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
+ case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy4,
- &yymsp[-11].minor.yy0, yymsp[0].minor.yy314, SQLITE_SO_ASC, yymsp[-8].minor.yy4);
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy14, yymsp[-10].minor.yy328,
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy132, SQLITE_SO_ASC, yymsp[-8].minor.yy328);
}
break;
- case 245: /* uniqueflag ::= UNIQUE */
- case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298);
-{yygotominor.yy4 = OE_Abort;}
+ case 240: /* uniqueflag ::= UNIQUE */
+ case 291: /* raisetype ::= ABORT */ yytestcase(yyruleno==291);
+{yygotominor.yy328 = OE_Abort;}
break;
- case 246: /* uniqueflag ::= */
-{yygotominor.yy4 = OE_None;}
+ case 241: /* uniqueflag ::= */
+{yygotominor.yy328 = OE_None;}
break;
- case 249: /* idxlist ::= idxlist COMMA nm collate sortorder */
+ case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */
{
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, p);
- sqlite3ExprListSetName(pParse,yygotominor.yy322,&yymsp[-2].minor.yy0,1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index");
- if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p);
+ sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
+ if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
}
break;
- case 250: /* idxlist ::= nm collate sortorder */
+ case 245: /* idxlist ::= nm collate sortorder */
{
Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
- yygotominor.yy322 = sqlite3ExprListAppend(pParse,0, p);
- sqlite3ExprListSetName(pParse, yygotominor.yy322, &yymsp[-2].minor.yy0, 1);
- sqlite3ExprListCheckLength(pParse, yygotominor.yy322, "index");
- if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy4;
+ yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p);
+ sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
+ sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
+ if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328;
}
break;
- case 251: /* collate ::= */
+ case 246: /* collate ::= */
{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
break;
- case 253: /* cmd ::= DROP INDEX ifexists fullname */
-{sqlite3DropIndex(pParse, yymsp[0].minor.yy259, yymsp[-1].minor.yy4);}
+ case 248: /* cmd ::= DROP INDEX ifexists fullname */
+{sqlite3DropIndex(pParse, yymsp[0].minor.yy65, yymsp[-1].minor.yy328);}
break;
- case 254: /* cmd ::= VACUUM */
- case 255: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==255);
+ case 249: /* cmd ::= VACUUM */
+ case 250: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==250);
{sqlite3Vacuum(pParse);}
break;
- case 256: /* cmd ::= PRAGMA nm dbnm */
+ case 251: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
- case 257: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
+ case 252: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
- case 258: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
+ case 253: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
break;
- case 259: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
+ case 254: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);}
break;
- case 260: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
+ case 255: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
- case 270: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
+ case 264: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
- sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy203, &all);
+ sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy473, &all);
}
break;
- case 271: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
+ case 265: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
- sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy4, yymsp[-4].minor.yy90.a, yymsp[-4].minor.yy90.b, yymsp[-2].minor.yy259, yymsp[0].minor.yy314, yymsp[-10].minor.yy4, yymsp[-8].minor.yy4);
+ sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy65, yymsp[0].minor.yy132, yymsp[-10].minor.yy328, yymsp[-8].minor.yy328);
yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
}
break;
- case 272: /* trigger_time ::= BEFORE */
- case 275: /* trigger_time ::= */ yytestcase(yyruleno==275);
-{ yygotominor.yy4 = TK_BEFORE; }
+ case 266: /* trigger_time ::= BEFORE */
+ case 269: /* trigger_time ::= */ yytestcase(yyruleno==269);
+{ yygotominor.yy328 = TK_BEFORE; }
break;
- case 273: /* trigger_time ::= AFTER */
-{ yygotominor.yy4 = TK_AFTER; }
+ case 267: /* trigger_time ::= AFTER */
+{ yygotominor.yy328 = TK_AFTER; }
break;
- case 274: /* trigger_time ::= INSTEAD OF */
-{ yygotominor.yy4 = TK_INSTEAD;}
+ case 268: /* trigger_time ::= INSTEAD OF */
+{ yygotominor.yy328 = TK_INSTEAD;}
break;
- case 276: /* trigger_event ::= DELETE|INSERT */
- case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277);
-{yygotominor.yy90.a = yymsp[0].major; yygotominor.yy90.b = 0;}
+ case 270: /* trigger_event ::= DELETE|INSERT */
+ case 271: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==271);
+{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;}
break;
- case 278: /* trigger_event ::= UPDATE OF idlist */
-{yygotominor.yy90.a = TK_UPDATE; yygotominor.yy90.b = yymsp[0].minor.yy384;}
+ case 272: /* trigger_event ::= UPDATE OF idlist */
+{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy408;}
break;
- case 281: /* when_clause ::= */
- case 303: /* key_opt ::= */ yytestcase(yyruleno==303);
-{ yygotominor.yy314 = 0; }
+ case 275: /* when_clause ::= */
+ case 296: /* key_opt ::= */ yytestcase(yyruleno==296);
+{ yygotominor.yy132 = 0; }
break;
- case 282: /* when_clause ::= WHEN expr */
- case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304);
-{ yygotominor.yy314 = yymsp[0].minor.yy118.pExpr; }
+ case 276: /* when_clause ::= WHEN expr */
+ case 297: /* key_opt ::= KEY expr */ yytestcase(yyruleno==297);
+{ yygotominor.yy132 = yymsp[0].minor.yy346.pExpr; }
break;
- case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
+ case 277: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
- assert( yymsp[-2].minor.yy203!=0 );
- yymsp[-2].minor.yy203->pLast->pNext = yymsp[-1].minor.yy203;
- yymsp[-2].minor.yy203->pLast = yymsp[-1].minor.yy203;
- yygotominor.yy203 = yymsp[-2].minor.yy203;
+ assert( yymsp[-2].minor.yy473!=0 );
+ yymsp[-2].minor.yy473->pLast->pNext = yymsp[-1].minor.yy473;
+ yymsp[-2].minor.yy473->pLast = yymsp[-1].minor.yy473;
+ yygotominor.yy473 = yymsp[-2].minor.yy473;
}
break;
- case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */
+ case 278: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
- assert( yymsp[-1].minor.yy203!=0 );
- yymsp[-1].minor.yy203->pLast = yymsp[-1].minor.yy203;
- yygotominor.yy203 = yymsp[-1].minor.yy203;
+ assert( yymsp[-1].minor.yy473!=0 );
+ yymsp[-1].minor.yy473->pLast = yymsp[-1].minor.yy473;
+ yygotominor.yy473 = yymsp[-1].minor.yy473;
}
break;
- case 286: /* trnm ::= nm DOT nm */
+ case 280: /* trnm ::= nm DOT nm */
{
yygotominor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
@@ -117415,123 +118444,137 @@ static void yy_reduce(
"statements within triggers");
}
break;
- case 288: /* tridxby ::= INDEXED BY nm */
+ case 282: /* tridxby ::= INDEXED BY nm */
{
sqlite3ErrorMsg(pParse,
"the INDEXED BY clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 289: /* tridxby ::= NOT INDEXED */
+ case 283: /* tridxby ::= NOT INDEXED */
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
- case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
-{ yygotominor.yy203 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy322, yymsp[0].minor.yy314, yymsp[-5].minor.yy210); }
- break;
- case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt valuelist */
-{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, yymsp[0].minor.yy260.pList, yymsp[0].minor.yy260.pSelect, yymsp[-4].minor.yy210);}
+ case 284: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */
+{ yygotominor.yy473 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy14, yymsp[0].minor.yy132, yymsp[-5].minor.yy186); }
break;
- case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
-{yygotominor.yy203 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy384, 0, yymsp[0].minor.yy387, yymsp[-4].minor.yy210);}
+ case 285: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */
+{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy408, yymsp[0].minor.yy3, yymsp[-4].minor.yy186);}
break;
- case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
-{yygotominor.yy203 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy314);}
+ case 286: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */
+{yygotominor.yy473 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy132);}
break;
- case 294: /* trigger_cmd ::= select */
-{yygotominor.yy203 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy387); }
+ case 287: /* trigger_cmd ::= select */
+{yygotominor.yy473 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy3); }
break;
- case 295: /* expr ::= RAISE LP IGNORE RP */
+ case 288: /* expr ::= RAISE LP IGNORE RP */
{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
- if( yygotominor.yy118.pExpr ){
- yygotominor.yy118.pExpr->affinity = OE_Ignore;
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0);
+ if( yygotominor.yy346.pExpr ){
+ yygotominor.yy346.pExpr->affinity = OE_Ignore;
}
- yygotominor.yy118.zStart = yymsp[-3].minor.yy0.z;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */
+ case 289: /* expr ::= RAISE LP raisetype COMMA nm RP */
{
- yygotominor.yy118.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
- if( yygotominor.yy118.pExpr ) {
- yygotominor.yy118.pExpr->affinity = (char)yymsp[-3].minor.yy4;
+ yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0);
+ if( yygotominor.yy346.pExpr ) {
+ yygotominor.yy346.pExpr->affinity = (char)yymsp[-3].minor.yy328;
}
- yygotominor.yy118.zStart = yymsp[-5].minor.yy0.z;
- yygotominor.yy118.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
+ yygotominor.yy346.zStart = yymsp[-5].minor.yy0.z;
+ yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
}
break;
- case 297: /* raisetype ::= ROLLBACK */
-{yygotominor.yy4 = OE_Rollback;}
+ case 290: /* raisetype ::= ROLLBACK */
+{yygotominor.yy328 = OE_Rollback;}
break;
- case 299: /* raisetype ::= FAIL */
-{yygotominor.yy4 = OE_Fail;}
+ case 292: /* raisetype ::= FAIL */
+{yygotominor.yy328 = OE_Fail;}
break;
- case 300: /* cmd ::= DROP TRIGGER ifexists fullname */
+ case 293: /* cmd ::= DROP TRIGGER ifexists fullname */
{
- sqlite3DropTrigger(pParse,yymsp[0].minor.yy259,yymsp[-1].minor.yy4);
+ sqlite3DropTrigger(pParse,yymsp[0].minor.yy65,yymsp[-1].minor.yy328);
}
break;
- case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
+ case 294: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
- sqlite3Attach(pParse, yymsp[-3].minor.yy118.pExpr, yymsp[-1].minor.yy118.pExpr, yymsp[0].minor.yy314);
+ sqlite3Attach(pParse, yymsp[-3].minor.yy346.pExpr, yymsp[-1].minor.yy346.pExpr, yymsp[0].minor.yy132);
}
break;
- case 302: /* cmd ::= DETACH database_kw_opt expr */
+ case 295: /* cmd ::= DETACH database_kw_opt expr */
{
- sqlite3Detach(pParse, yymsp[0].minor.yy118.pExpr);
+ sqlite3Detach(pParse, yymsp[0].minor.yy346.pExpr);
}
break;
- case 307: /* cmd ::= REINDEX */
+ case 300: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
- case 308: /* cmd ::= REINDEX nm dbnm */
+ case 301: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 309: /* cmd ::= ANALYZE */
+ case 302: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
- case 310: /* cmd ::= ANALYZE nm dbnm */
+ case 303: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
- case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
+ case 304: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
- sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy259,&yymsp[0].minor.yy0);
+ sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy65,&yymsp[0].minor.yy0);
}
break;
- case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
+ case 305: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
{
sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
}
break;
- case 313: /* add_column_fullname ::= fullname */
+ case 306: /* add_column_fullname ::= fullname */
{
pParse->db->lookaside.bEnabled = 0;
- sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy259);
+ sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy65);
}
break;
- case 316: /* cmd ::= create_vtab */
+ case 309: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
- case 317: /* cmd ::= create_vtab LP vtabarglist RP */
+ case 310: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
- case 318: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
+ case 311: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
- sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy4);
+ sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy328);
}
break;
- case 321: /* vtabarg ::= */
+ case 314: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
- case 323: /* vtabargtoken ::= ANY */
- case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324);
- case 325: /* lp ::= LP */ yytestcase(yyruleno==325);
+ case 316: /* vtabargtoken ::= ANY */
+ case 317: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==317);
+ case 318: /* lp ::= LP */ yytestcase(yyruleno==318);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
+ case 322: /* with ::= */
+{yygotominor.yy59 = 0;}
+ break;
+ case 323: /* with ::= WITH wqlist */
+ case 324: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==324);
+{ yygotominor.yy59 = yymsp[0].minor.yy59; }
+ break;
+ case 325: /* wqlist ::= nm idxlist_opt AS LP select RP */
+{
+ yygotominor.yy59 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3);
+}
+ break;
+ case 326: /* wqlist ::= wqlist COMMA nm idxlist_opt AS LP select RP */
+{
+ yygotominor.yy59 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy59, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy3);
+}
+ break;
default:
/* (0) input ::= cmdlist */ yytestcase(yyruleno==0);
/* (1) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==1);
@@ -117546,28 +118589,28 @@ static void yy_reduce(
/* (25) cmd ::= create_table create_table_args */ yytestcase(yyruleno==25);
/* (36) columnlist ::= columnlist COMMA column */ yytestcase(yyruleno==36);
/* (37) columnlist ::= column */ yytestcase(yyruleno==37);
- /* (46) type ::= */ yytestcase(yyruleno==46);
- /* (53) signed ::= plus_num */ yytestcase(yyruleno==53);
- /* (54) signed ::= minus_num */ yytestcase(yyruleno==54);
- /* (55) carglist ::= carglist ccons */ yytestcase(yyruleno==55);
- /* (56) carglist ::= */ yytestcase(yyruleno==56);
- /* (63) ccons ::= NULL onconf */ yytestcase(yyruleno==63);
- /* (91) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==91);
- /* (92) conslist ::= tcons */ yytestcase(yyruleno==92);
- /* (94) tconscomma ::= */ yytestcase(yyruleno==94);
- /* (279) foreach_clause ::= */ yytestcase(yyruleno==279);
- /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280);
- /* (287) tridxby ::= */ yytestcase(yyruleno==287);
- /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305);
- /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306);
- /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314);
- /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315);
- /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319);
- /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320);
- /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322);
- /* (326) anylist ::= */ yytestcase(yyruleno==326);
- /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327);
- /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328);
+ /* (43) type ::= */ yytestcase(yyruleno==43);
+ /* (50) signed ::= plus_num */ yytestcase(yyruleno==50);
+ /* (51) signed ::= minus_num */ yytestcase(yyruleno==51);
+ /* (52) carglist ::= carglist ccons */ yytestcase(yyruleno==52);
+ /* (53) carglist ::= */ yytestcase(yyruleno==53);
+ /* (60) ccons ::= NULL onconf */ yytestcase(yyruleno==60);
+ /* (88) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==88);
+ /* (89) conslist ::= tcons */ yytestcase(yyruleno==89);
+ /* (91) tconscomma ::= */ yytestcase(yyruleno==91);
+ /* (273) foreach_clause ::= */ yytestcase(yyruleno==273);
+ /* (274) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==274);
+ /* (281) tridxby ::= */ yytestcase(yyruleno==281);
+ /* (298) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==298);
+ /* (299) database_kw_opt ::= */ yytestcase(yyruleno==299);
+ /* (307) kwcolumn_opt ::= */ yytestcase(yyruleno==307);
+ /* (308) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==308);
+ /* (312) vtabarglist ::= vtabarg */ yytestcase(yyruleno==312);
+ /* (313) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==313);
+ /* (315) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==315);
+ /* (319) anylist ::= */ yytestcase(yyruleno==319);
+ /* (320) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==320);
+ /* (321) anylist ::= anylist ANY */ yytestcase(yyruleno==321);
break;
};
assert( yyruleno>=0 && yyruleno<sizeof(yyRuleInfo)/sizeof(yyRuleInfo[0]) );
@@ -117906,20 +118949,20 @@ const unsigned char ebcdicToAscii[] = {
** is substantially reduced. This is important for embedded applications
** on platforms with limited memory.
*/
-/* Hash score: 177 */
+/* Hash score: 182 */
static int keywordCode(const char *z, int n){
- /* zText[] encodes 819 bytes of keywords in 545 bytes */
+ /* zText[] encodes 834 bytes of keywords in 554 bytes */
/* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */
/* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */
/* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */
- /* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERENAMEBETWEEN */
- /* OTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */
+ /* UNIQUERYWITHOUTERELEASEATTACHAVINGROUPDATEBEGINNERECURSIVE */
+ /* BETWEENOTNULLIKECASCADELETECASECOLLATECREATECURRENT_DATEDETACH */
/* IMMEDIATEJOINSERTMATCHPLANALYZEPRAGMABORTVALUESVIRTUALIMITWHEN */
- /* WHEREPLACEAFTERESTRICTANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */
+ /* WHERENAMEAFTEREPLACEANDEFAULTAUTOINCREMENTCASTCOLUMNCOMMIT */
/* CONFLICTCROSSCURRENT_TIMESTAMPRIMARYDEFERREDISTINCTDROPFAIL */
- /* FROMFULLGLOBYIFISNULLORDERIGHTROLLBACKROWUNIONUSINGVACUUMVIEW */
- /* INITIALLY */
- static const char zText[544] = {
+ /* FROMFULLGLOBYIFISNULLORDERESTRICTRIGHTROLLBACKROWUNIONUSING */
+ /* VACUUMVIEWINITIALLY */
+ static const char zText[553] = {
'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H',
'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G',
'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A',
@@ -117932,75 +118975,75 @@ static int keywordCode(const char *z, int n){
'O','F','F','S','E','T','E','M','P','O','R','A','R','Y','U','N','I','Q',
'U','E','R','Y','W','I','T','H','O','U','T','E','R','E','L','E','A','S',
'E','A','T','T','A','C','H','A','V','I','N','G','R','O','U','P','D','A',
- 'T','E','B','E','G','I','N','N','E','R','E','N','A','M','E','B','E','T',
- 'W','E','E','N','O','T','N','U','L','L','I','K','E','C','A','S','C','A',
- 'D','E','L','E','T','E','C','A','S','E','C','O','L','L','A','T','E','C',
- 'R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E','D',
- 'E','T','A','C','H','I','M','M','E','D','I','A','T','E','J','O','I','N',
- 'S','E','R','T','M','A','T','C','H','P','L','A','N','A','L','Y','Z','E',
- 'P','R','A','G','M','A','B','O','R','T','V','A','L','U','E','S','V','I',
- 'R','T','U','A','L','I','M','I','T','W','H','E','N','W','H','E','R','E',
- 'P','L','A','C','E','A','F','T','E','R','E','S','T','R','I','C','T','A',
- 'N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E','M',
- 'E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M','I',
- 'T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R','R',
- 'E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A','R',
- 'Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D','R',
- 'O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O','B',
- 'Y','I','F','I','S','N','U','L','L','O','R','D','E','R','I','G','H','T',
- 'R','O','L','L','B','A','C','K','R','O','W','U','N','I','O','N','U','S',
- 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','I','T','I',
- 'A','L','L','Y',
+ 'T','E','B','E','G','I','N','N','E','R','E','C','U','R','S','I','V','E',
+ 'B','E','T','W','E','E','N','O','T','N','U','L','L','I','K','E','C','A',
+ 'S','C','A','D','E','L','E','T','E','C','A','S','E','C','O','L','L','A',
+ 'T','E','C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A',
+ 'T','E','D','E','T','A','C','H','I','M','M','E','D','I','A','T','E','J',
+ 'O','I','N','S','E','R','T','M','A','T','C','H','P','L','A','N','A','L',
+ 'Y','Z','E','P','R','A','G','M','A','B','O','R','T','V','A','L','U','E',
+ 'S','V','I','R','T','U','A','L','I','M','I','T','W','H','E','N','W','H',
+ 'E','R','E','N','A','M','E','A','F','T','E','R','E','P','L','A','C','E',
+ 'A','N','D','E','F','A','U','L','T','A','U','T','O','I','N','C','R','E',
+ 'M','E','N','T','C','A','S','T','C','O','L','U','M','N','C','O','M','M',
+ 'I','T','C','O','N','F','L','I','C','T','C','R','O','S','S','C','U','R',
+ 'R','E','N','T','_','T','I','M','E','S','T','A','M','P','R','I','M','A',
+ 'R','Y','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','D',
+ 'R','O','P','F','A','I','L','F','R','O','M','F','U','L','L','G','L','O',
+ 'B','Y','I','F','I','S','N','U','L','L','O','R','D','E','R','E','S','T',
+ 'R','I','C','T','R','I','G','H','T','R','O','L','L','B','A','C','K','R',
+ 'O','W','U','N','I','O','N','U','S','I','N','G','V','A','C','U','U','M',
+ 'V','I','E','W','I','N','I','T','I','A','L','L','Y',
};
static const unsigned char aHash[127] = {
- 75, 104, 115, 73, 0, 45, 0, 0, 81, 0, 76, 0, 0,
- 42, 12, 77, 15, 0, 114, 84, 53, 111, 0, 19, 0, 0,
- 119, 0, 117, 88, 0, 22, 92, 0, 9, 0, 0, 69, 70,
- 0, 68, 6, 0, 48, 89, 101, 0, 116, 100, 0, 0, 44,
- 0, 102, 24, 0, 17, 0, 120, 52, 23, 0, 5, 109, 25,
- 95, 0, 0, 122, 105, 59, 121, 56, 28, 54, 0, 90, 0,
- 99, 26, 0, 98, 0, 0, 0, 94, 91, 96, 87, 108, 14,
- 39, 107, 0, 80, 0, 18, 86, 110, 32, 0, 118, 79, 112,
- 61, 46, 83, 0, 0, 93, 40, 0, 113, 0, 36, 0, 0,
- 29, 0, 85, 62, 63, 0, 20, 60, 0, 55,
+ 76, 105, 117, 74, 0, 45, 0, 0, 82, 0, 77, 0, 0,
+ 42, 12, 78, 15, 0, 116, 85, 54, 112, 0, 19, 0, 0,
+ 121, 0, 119, 115, 0, 22, 93, 0, 9, 0, 0, 70, 71,
+ 0, 69, 6, 0, 48, 90, 102, 0, 118, 101, 0, 0, 44,
+ 0, 103, 24, 0, 17, 0, 122, 53, 23, 0, 5, 110, 25,
+ 96, 0, 0, 124, 106, 60, 123, 57, 28, 55, 0, 91, 0,
+ 100, 26, 0, 99, 0, 0, 0, 95, 92, 97, 88, 109, 14,
+ 39, 108, 0, 81, 0, 18, 89, 111, 32, 0, 120, 80, 113,
+ 62, 46, 84, 0, 0, 94, 40, 59, 114, 0, 36, 0, 0,
+ 29, 0, 86, 63, 64, 0, 20, 61, 0, 56,
};
- static const unsigned char aNext[122] = {
+ static const unsigned char aNext[124] = {
0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 0,
- 43, 3, 47, 0, 0, 0, 0, 30, 0, 57, 0, 38, 0,
- 0, 0, 1, 65, 0, 0, 66, 0, 41, 0, 0, 0, 0,
- 0, 0, 49, 64, 0, 0, 0, 51, 31, 0, 16, 34, 10,
- 0, 0, 0, 0, 0, 0, 0, 11, 71, 78, 0, 8, 0,
- 103, 97, 0, 106, 0, 58, 0, 74, 50, 27, 37, 72, 82,
- 0, 35, 67, 0, 0,
+ 0, 0, 0, 0, 33, 0, 21, 0, 0, 0, 0, 0, 50,
+ 0, 43, 3, 47, 0, 0, 0, 0, 30, 0, 58, 0, 38,
+ 0, 0, 0, 1, 66, 0, 0, 67, 0, 41, 0, 0, 0,
+ 0, 0, 0, 49, 65, 0, 0, 0, 0, 31, 52, 16, 34,
+ 10, 0, 0, 0, 0, 0, 0, 0, 11, 72, 79, 0, 8,
+ 0, 104, 98, 0, 107, 0, 87, 0, 75, 51, 0, 27, 37,
+ 73, 83, 0, 35, 68, 0, 0,
};
- static const unsigned char aLen[122] = {
+ static const unsigned char aLen[124] = {
7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6,
7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6,
11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10,
- 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 5, 7, 6,
- 6, 5, 6, 5, 5, 6, 7, 7, 3, 2, 4, 4, 7,
- 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 5, 4, 7,
- 6, 5, 6, 7, 5, 4, 5, 7, 5, 8, 3, 7, 13,
- 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8, 2,
- 4, 4, 4, 4, 4, 2, 2, 6, 5, 5, 8, 3, 5,
- 5, 6, 4, 9, 3,
+ 4, 6, 2, 3, 9, 4, 2, 6, 5, 7, 4, 5, 7,
+ 6, 6, 5, 6, 5, 5, 9, 7, 7, 3, 2, 4, 4,
+ 7, 3, 6, 4, 7, 6, 12, 6, 9, 4, 6, 5, 4,
+ 7, 6, 5, 6, 7, 5, 4, 5, 6, 5, 7, 3, 7,
+ 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 8, 8,
+ 2, 4, 4, 4, 4, 4, 2, 2, 6, 5, 8, 5, 8,
+ 3, 5, 5, 6, 4, 9, 3,
};
- static const unsigned short int aOffset[122] = {
+ static const unsigned short int aOffset[124] = {
0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33,
36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81,
86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152,
- 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 188, 192, 199,
- 204, 209, 212, 218, 221, 225, 231, 237, 237, 237, 240, 243, 247,
- 248, 252, 258, 262, 269, 275, 287, 293, 302, 304, 310, 315, 317,
- 324, 329, 334, 340, 346, 351, 355, 358, 365, 369, 377, 379, 386,
- 388, 390, 399, 403, 409, 415, 423, 428, 428, 444, 451, 458, 459,
- 466, 470, 474, 478, 482, 485, 487, 489, 495, 499, 504, 512, 515,
- 520, 525, 531, 535, 540,
+ 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 184, 188, 192,
+ 199, 204, 209, 212, 218, 221, 225, 234, 240, 240, 240, 243, 246,
+ 250, 251, 255, 261, 265, 272, 278, 290, 296, 305, 307, 313, 318,
+ 320, 327, 332, 337, 343, 349, 354, 358, 361, 367, 371, 378, 380,
+ 387, 389, 391, 400, 404, 410, 416, 424, 429, 429, 445, 452, 459,
+ 460, 467, 471, 475, 479, 483, 486, 488, 490, 496, 500, 508, 513,
+ 521, 524, 529, 534, 540, 544, 549,
};
- static const unsigned char aCode[122] = {
+ static const unsigned char aCode[124] = {
TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE,
TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN,
TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD,
@@ -118010,22 +119053,22 @@ static int keywordCode(const char *z, int n){
TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT,
TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO,
TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP,
- TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_JOIN_KW,
- TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP, TK_UPDATE,
- TK_BEGIN, TK_JOIN_KW, TK_RENAME, TK_BETWEEN, TK_NOTNULL,
- TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW, TK_CASCADE,
- TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE,
- TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT,
- TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT,
- TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_WHERE,
- TK_REPLACE, TK_AFTER, TK_RESTRICT, TK_AND, TK_DEFAULT,
- TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW,
- TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW,
- TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP,
- TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY,
- TK_IF, TK_ISNULL, TK_ORDER, TK_JOIN_KW, TK_ROLLBACK,
- TK_ROW, TK_UNION, TK_USING, TK_VACUUM, TK_VIEW,
- TK_INITIALLY, TK_ALL,
+ TK_OR, TK_UNIQUE, TK_QUERY, TK_WITHOUT, TK_WITH,
+ TK_JOIN_KW, TK_RELEASE, TK_ATTACH, TK_HAVING, TK_GROUP,
+ TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RECURSIVE, TK_BETWEEN,
+ TK_NOTNULL, TK_NOT, TK_NO, TK_NULL, TK_LIKE_KW,
+ TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE,
+ TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN,
+ TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA,
+ TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN,
+ TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, TK_AND,
+ TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, TK_CAST,
+ TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW,
+ TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS,
+ TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW,
+ TK_BY, TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT,
+ TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING,
+ TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL,
};
int h, i;
if( n<2 ) return TK_ID;
@@ -118083,79 +119126,81 @@ static int keywordCode(const char *z, int n){
testcase( i==46 ); /* UNIQUE */
testcase( i==47 ); /* QUERY */
testcase( i==48 ); /* WITHOUT */
- testcase( i==49 ); /* OUTER */
- testcase( i==50 ); /* RELEASE */
- testcase( i==51 ); /* ATTACH */
- testcase( i==52 ); /* HAVING */
- testcase( i==53 ); /* GROUP */
- testcase( i==54 ); /* UPDATE */
- testcase( i==55 ); /* BEGIN */
- testcase( i==56 ); /* INNER */
- testcase( i==57 ); /* RENAME */
- testcase( i==58 ); /* BETWEEN */
- testcase( i==59 ); /* NOTNULL */
- testcase( i==60 ); /* NOT */
- testcase( i==61 ); /* NO */
- testcase( i==62 ); /* NULL */
- testcase( i==63 ); /* LIKE */
- testcase( i==64 ); /* CASCADE */
- testcase( i==65 ); /* ASC */
- testcase( i==66 ); /* DELETE */
- testcase( i==67 ); /* CASE */
- testcase( i==68 ); /* COLLATE */
- testcase( i==69 ); /* CREATE */
- testcase( i==70 ); /* CURRENT_DATE */
- testcase( i==71 ); /* DETACH */
- testcase( i==72 ); /* IMMEDIATE */
- testcase( i==73 ); /* JOIN */
- testcase( i==74 ); /* INSERT */
- testcase( i==75 ); /* MATCH */
- testcase( i==76 ); /* PLAN */
- testcase( i==77 ); /* ANALYZE */
- testcase( i==78 ); /* PRAGMA */
- testcase( i==79 ); /* ABORT */
- testcase( i==80 ); /* VALUES */
- testcase( i==81 ); /* VIRTUAL */
- testcase( i==82 ); /* LIMIT */
- testcase( i==83 ); /* WHEN */
- testcase( i==84 ); /* WHERE */
- testcase( i==85 ); /* REPLACE */
- testcase( i==86 ); /* AFTER */
- testcase( i==87 ); /* RESTRICT */
- testcase( i==88 ); /* AND */
- testcase( i==89 ); /* DEFAULT */
- testcase( i==90 ); /* AUTOINCREMENT */
- testcase( i==91 ); /* TO */
- testcase( i==92 ); /* IN */
- testcase( i==93 ); /* CAST */
- testcase( i==94 ); /* COLUMN */
- testcase( i==95 ); /* COMMIT */
- testcase( i==96 ); /* CONFLICT */
- testcase( i==97 ); /* CROSS */
- testcase( i==98 ); /* CURRENT_TIMESTAMP */
- testcase( i==99 ); /* CURRENT_TIME */
- testcase( i==100 ); /* PRIMARY */
- testcase( i==101 ); /* DEFERRED */
- testcase( i==102 ); /* DISTINCT */
- testcase( i==103 ); /* IS */
- testcase( i==104 ); /* DROP */
- testcase( i==105 ); /* FAIL */
- testcase( i==106 ); /* FROM */
- testcase( i==107 ); /* FULL */
- testcase( i==108 ); /* GLOB */
- testcase( i==109 ); /* BY */
- testcase( i==110 ); /* IF */
- testcase( i==111 ); /* ISNULL */
- testcase( i==112 ); /* ORDER */
- testcase( i==113 ); /* RIGHT */
- testcase( i==114 ); /* ROLLBACK */
- testcase( i==115 ); /* ROW */
- testcase( i==116 ); /* UNION */
- testcase( i==117 ); /* USING */
- testcase( i==118 ); /* VACUUM */
- testcase( i==119 ); /* VIEW */
- testcase( i==120 ); /* INITIALLY */
- testcase( i==121 ); /* ALL */
+ testcase( i==49 ); /* WITH */
+ testcase( i==50 ); /* OUTER */
+ testcase( i==51 ); /* RELEASE */
+ testcase( i==52 ); /* ATTACH */
+ testcase( i==53 ); /* HAVING */
+ testcase( i==54 ); /* GROUP */
+ testcase( i==55 ); /* UPDATE */
+ testcase( i==56 ); /* BEGIN */
+ testcase( i==57 ); /* INNER */
+ testcase( i==58 ); /* RECURSIVE */
+ testcase( i==59 ); /* BETWEEN */
+ testcase( i==60 ); /* NOTNULL */
+ testcase( i==61 ); /* NOT */
+ testcase( i==62 ); /* NO */
+ testcase( i==63 ); /* NULL */
+ testcase( i==64 ); /* LIKE */
+ testcase( i==65 ); /* CASCADE */
+ testcase( i==66 ); /* ASC */
+ testcase( i==67 ); /* DELETE */
+ testcase( i==68 ); /* CASE */
+ testcase( i==69 ); /* COLLATE */
+ testcase( i==70 ); /* CREATE */
+ testcase( i==71 ); /* CURRENT_DATE */
+ testcase( i==72 ); /* DETACH */
+ testcase( i==73 ); /* IMMEDIATE */
+ testcase( i==74 ); /* JOIN */
+ testcase( i==75 ); /* INSERT */
+ testcase( i==76 ); /* MATCH */
+ testcase( i==77 ); /* PLAN */
+ testcase( i==78 ); /* ANALYZE */
+ testcase( i==79 ); /* PRAGMA */
+ testcase( i==80 ); /* ABORT */
+ testcase( i==81 ); /* VALUES */
+ testcase( i==82 ); /* VIRTUAL */
+ testcase( i==83 ); /* LIMIT */
+ testcase( i==84 ); /* WHEN */
+ testcase( i==85 ); /* WHERE */
+ testcase( i==86 ); /* RENAME */
+ testcase( i==87 ); /* AFTER */
+ testcase( i==88 ); /* REPLACE */
+ testcase( i==89 ); /* AND */
+ testcase( i==90 ); /* DEFAULT */
+ testcase( i==91 ); /* AUTOINCREMENT */
+ testcase( i==92 ); /* TO */
+ testcase( i==93 ); /* IN */
+ testcase( i==94 ); /* CAST */
+ testcase( i==95 ); /* COLUMN */
+ testcase( i==96 ); /* COMMIT */
+ testcase( i==97 ); /* CONFLICT */
+ testcase( i==98 ); /* CROSS */
+ testcase( i==99 ); /* CURRENT_TIMESTAMP */
+ testcase( i==100 ); /* CURRENT_TIME */
+ testcase( i==101 ); /* PRIMARY */
+ testcase( i==102 ); /* DEFERRED */
+ testcase( i==103 ); /* DISTINCT */
+ testcase( i==104 ); /* IS */
+ testcase( i==105 ); /* DROP */
+ testcase( i==106 ); /* FAIL */
+ testcase( i==107 ); /* FROM */
+ testcase( i==108 ); /* FULL */
+ testcase( i==109 ); /* GLOB */
+ testcase( i==110 ); /* BY */
+ testcase( i==111 ); /* IF */
+ testcase( i==112 ); /* ISNULL */
+ testcase( i==113 ); /* ORDER */
+ testcase( i==114 ); /* RESTRICT */
+ testcase( i==115 ); /* RIGHT */
+ testcase( i==116 ); /* ROLLBACK */
+ testcase( i==117 ); /* ROW */
+ testcase( i==118 ); /* UNION */
+ testcase( i==119 ); /* USING */
+ testcase( i==120 ); /* VACUUM */
+ testcase( i==121 ); /* VIEW */
+ testcase( i==122 ); /* INITIALLY */
+ testcase( i==123 ); /* ALL */
return aCode[i];
}
}
@@ -118164,7 +119209,7 @@ static int keywordCode(const char *z, int n){
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
return keywordCode((char*)z, n);
}
-#define SQLITE_N_KEYWORD 122
+#define SQLITE_N_KEYWORD 124
/************** End of keywordhash.h *****************************************/
/************** Continuing where we left off in tokenize.c *******************/
@@ -118408,24 +119453,15 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){
for(i=1; sqlite3Isdigit(z[i]); i++){}
return i;
}
- case '#': {
- for(i=1; sqlite3Isdigit(z[i]); i++){}
- if( i>1 ){
- /* Parameters of the form #NNN (where NNN is a number) are used
- ** internally by sqlite3NestedParse. */
- *tokenType = TK_REGISTER;
- return i;
- }
- /* Fall through into the next case if the '#' is not followed by
- ** a digit. Try to match #AAAA where AAAA is a parameter name. */
- }
#ifndef SQLITE_OMIT_TCL_VARIABLE
case '$':
#endif
case '@': /* For compatibility with MS SQL Server */
+ case '#':
case ':': {
int n = 0;
- testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' );
+ testcase( z[0]=='$' ); testcase( z[0]=='@' );
+ testcase( z[0]==':' ); testcase( z[0]=='#' );
*tokenType = TK_VARIABLE;
for(i=1; (c=z[i])!=0; i++){
if( IdChar(c) ){
@@ -118608,6 +119644,7 @@ abort_parse:
sqlite3DeleteTable(db, pParse->pNewTable);
}
+ if( pParse->bFreeWith ) sqlite3WithDelete(db, pParse->pWith);
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]);
sqlite3DbFree(db, pParse->azVar);
@@ -119138,13 +120175,6 @@ SQLITE_API int sqlite3_initialize(void){
*/
if( sqlite3GlobalConfig.isInit ) return SQLITE_OK;
-#ifdef SQLITE_ENABLE_SQLLOG
- {
- extern void sqlite3_init_sqllog(void);
- sqlite3_init_sqllog();
- }
-#endif
-
/* Make sure the mutex subsystem is initialized. If unable to
** initialize the mutex subsystem, return early with the error.
** If the system is so sick that we are unable to allocate a mutex,
@@ -119591,7 +120621,8 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
db->lookaside.bEnabled = 1;
db->lookaside.bMalloced = pBuf==0 ?1:0;
}else{
- db->lookaside.pEnd = 0;
+ db->lookaside.pStart = db;
+ db->lookaside.pEnd = db;
db->lookaside.bEnabled = 0;
db->lookaside.bMalloced = 0;
}
@@ -119989,9 +121020,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
#endif
sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
- if( db->pErr ){
- sqlite3ValueFree(db->pErr);
- }
+ sqlite3ValueFree(db->pErr);
sqlite3CloseExtensions(db);
db->magic = SQLITE_MAGIC_ERROR;
@@ -120066,8 +121095,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** Return a static string containing the name corresponding to the error code
** specified in the argument.
*/
-#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \
- defined(SQLITE_DEBUG_OS_TRACE)
+#if defined(SQLITE_TEST)
SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
@@ -120089,6 +121117,7 @@ SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break;
case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break;
case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break;
+ case SQLITE_READONLY_DBMOVED: zName = "SQLITE_READONLY_DBMOVED"; break;
case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break;
case SQLITE_IOERR: zName = "SQLITE_IOERR"; break;
case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break;
@@ -120373,6 +121402,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
){
FuncDef *p;
int nName;
+ int extraFlags;
assert( sqlite3_mutex_held(db->mutex) );
if( zFunctionName==0 ||
@@ -120383,6 +121413,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
(255<(nName = sqlite3Strlen30( zFunctionName))) ){
return SQLITE_MISUSE_BKPT;
}
+
+ assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
+ extraFlags = enc & SQLITE_DETERMINISTIC;
+ enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY);
#ifndef SQLITE_OMIT_UTF16
/* If SQLITE_UTF16 is specified as the encoding type, transform this
@@ -120396,10 +121430,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
enc = SQLITE_UTF16NATIVE;
}else if( enc==SQLITE_ANY ){
int rc;
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags,
pUserData, xFunc, xStep, xFinal, pDestructor);
if( rc==SQLITE_OK ){
- rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
+ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags,
pUserData, xFunc, xStep, xFinal, pDestructor);
}
if( rc!=SQLITE_OK ){
@@ -120442,7 +121476,8 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
pDestructor->nRef++;
}
p->pDestructor = pDestructor;
- p->funcFlags &= SQLITE_FUNC_ENCMASK;
+ p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags;
+ testcase( p->funcFlags & SQLITE_DETERMINISTIC );
p->xFunc = xFunc;
p->xStep = xStep;
p->xFinalize = xFinal;
@@ -120872,6 +121907,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
if( db->mallocFailed ){
z = sqlite3ErrStr(SQLITE_NOMEM);
}else{
+ testcase( db->pErr==0 );
z = (char*)sqlite3_value_text(db->pErr);
assert( !db->mallocFailed );
if( z==0 ){
@@ -120913,8 +121949,7 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
}else{
z = sqlite3_value_text16(db->pErr);
if( z==0 ){
- sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
- SQLITE_UTF8, SQLITE_STATIC);
+ sqlite3Error(db, db->errCode, sqlite3ErrStr(db->errCode));
z = sqlite3_value_text16(db->pErr);
}
/* A malloc() may have failed within the call to sqlite3_value_text16()
@@ -121628,8 +122663,6 @@ static int openDatabase(
}
#endif
- sqlite3Error(db, rc, 0);
-
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
** mode. Doing nothing at all also makes NORMAL the default.
@@ -121640,6 +122673,8 @@ static int openDatabase(
SQLITE_DEFAULT_LOCKING_MODE);
#endif
+ if( rc ) sqlite3Error(db, rc, 0);
+
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
@@ -122099,7 +123134,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){
** to the xRandomness method of the default VFS.
*/
case SQLITE_TESTCTRL_PRNG_RESET: {
- sqlite3PrngResetState();
+ sqlite3_randomness(0,0);
break;
}
@@ -122308,7 +123343,22 @@ SQLITE_API int sqlite3_test_control(int op, ...){
** that demonstrat invariants on well-formed database files.
*/
case SQLITE_TESTCTRL_NEVER_CORRUPT: {
- sqlite3Config.neverCorrupt = va_arg(ap, int);
+ sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int);
+ break;
+ }
+
+
+ /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr);
+ **
+ ** Set the VDBE coverage callback function to xCallback with context
+ ** pointer ptr.
+ */
+ case SQLITE_TESTCTRL_VDBE_COVERAGE: {
+#ifdef SQLITE_VDBE_COVERAGE
+ typedef void (*branch_callback)(void*,int,u8,u8);
+ sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback);
+ sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*);
+#endif
break;
}
@@ -125083,6 +126133,19 @@ static int fts3CreateMethod(
return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
}
+/*
+** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
+** extension is currently being used by a version of SQLite too old to
+** support estimatedRows. In that case this function is a no-op.
+*/
+static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
+#if SQLITE_VERSION_NUMBER>=3008002
+ if( sqlite3_libversion_number()>=3008002 ){
+ pIdxInfo->estimatedRows = nRow;
+ }
+#endif
+}
+
/*
** Implementation of the xBestIndex method for FTS3 tables. There
** are three possible strategies, in order of preference:
@@ -125110,7 +126173,20 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
for(i=0; i<pInfo->nConstraint; i++){
int bDocid; /* True if this constraint is on docid */
struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i];
- if( pCons->usable==0 ) continue;
+ if( pCons->usable==0 ){
+ if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
+ /* There exists an unusable MATCH constraint. This means that if
+ ** the planner does elect to use the results of this call as part
+ ** of the overall query plan the user will see an "unable to use
+ ** function MATCH in the requested context" error. To discourage
+ ** this, return a very high cost here. */
+ pInfo->idxNum = FTS3_FULLSCAN_SEARCH;
+ pInfo->estimatedCost = 1e50;
+ fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50);
+ return SQLITE_OK;
+ }
+ continue;
+ }
bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1);
@@ -131280,13 +132356,13 @@ SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){
*/
static int fts3StrHash(const void *pKey, int nKey){
const char *z = (const char *)pKey;
- int h = 0;
+ unsigned h = 0;
if( nKey<=0 ) nKey = (int) strlen(z);
while( nKey > 0 ){
h = (h<<3) ^ h ^ *z++;
nKey--;
}
- return h & 0x7fffffff;
+ return (int)(h & 0x7fffffff);
}
static int fts3StrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
if( n1!=n2 ) return 1;
@@ -131971,12 +133047,14 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
/* Step 2 */
switch( z[1] ){
case 'a':
- stem(&z, "lanoita", "ate", m_gt_0) ||
- stem(&z, "lanoit", "tion", m_gt_0);
+ if( !stem(&z, "lanoita", "ate", m_gt_0) ){
+ stem(&z, "lanoit", "tion", m_gt_0);
+ }
break;
case 'c':
- stem(&z, "icne", "ence", m_gt_0) ||
- stem(&z, "icna", "ance", m_gt_0);
+ if( !stem(&z, "icne", "ence", m_gt_0) ){
+ stem(&z, "icna", "ance", m_gt_0);
+ }
break;
case 'e':
stem(&z, "rezi", "ize", m_gt_0);
@@ -131985,43 +133063,54 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
stem(&z, "igol", "log", m_gt_0);
break;
case 'l':
- stem(&z, "ilb", "ble", m_gt_0) ||
- stem(&z, "illa", "al", m_gt_0) ||
- stem(&z, "iltne", "ent", m_gt_0) ||
- stem(&z, "ile", "e", m_gt_0) ||
- stem(&z, "ilsuo", "ous", m_gt_0);
+ if( !stem(&z, "ilb", "ble", m_gt_0)
+ && !stem(&z, "illa", "al", m_gt_0)
+ && !stem(&z, "iltne", "ent", m_gt_0)
+ && !stem(&z, "ile", "e", m_gt_0)
+ ){
+ stem(&z, "ilsuo", "ous", m_gt_0);
+ }
break;
case 'o':
- stem(&z, "noitazi", "ize", m_gt_0) ||
- stem(&z, "noita", "ate", m_gt_0) ||
- stem(&z, "rota", "ate", m_gt_0);
+ if( !stem(&z, "noitazi", "ize", m_gt_0)
+ && !stem(&z, "noita", "ate", m_gt_0)
+ ){
+ stem(&z, "rota", "ate", m_gt_0);
+ }
break;
case 's':
- stem(&z, "msila", "al", m_gt_0) ||
- stem(&z, "ssenevi", "ive", m_gt_0) ||
- stem(&z, "ssenluf", "ful", m_gt_0) ||
- stem(&z, "ssensuo", "ous", m_gt_0);
+ if( !stem(&z, "msila", "al", m_gt_0)
+ && !stem(&z, "ssenevi", "ive", m_gt_0)
+ && !stem(&z, "ssenluf", "ful", m_gt_0)
+ ){
+ stem(&z, "ssensuo", "ous", m_gt_0);
+ }
break;
case 't':
- stem(&z, "itila", "al", m_gt_0) ||
- stem(&z, "itivi", "ive", m_gt_0) ||
- stem(&z, "itilib", "ble", m_gt_0);
+ if( !stem(&z, "itila", "al", m_gt_0)
+ && !stem(&z, "itivi", "ive", m_gt_0)
+ ){
+ stem(&z, "itilib", "ble", m_gt_0);
+ }
break;
}
/* Step 3 */
switch( z[0] ){
case 'e':
- stem(&z, "etaci", "ic", m_gt_0) ||
- stem(&z, "evita", "", m_gt_0) ||
- stem(&z, "ezila", "al", m_gt_0);
+ if( !stem(&z, "etaci", "ic", m_gt_0)
+ && !stem(&z, "evita", "", m_gt_0)
+ ){
+ stem(&z, "ezila", "al", m_gt_0);
+ }
break;
case 'i':
stem(&z, "itici", "ic", m_gt_0);
break;
case 'l':
- stem(&z, "laci", "ic", m_gt_0) ||
- stem(&z, "luf", "", m_gt_0);
+ if( !stem(&z, "laci", "ic", m_gt_0) ){
+ stem(&z, "luf", "", m_gt_0);
+ }
break;
case 's':
stem(&z, "ssen", "", m_gt_0);
@@ -132062,9 +133151,11 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
z += 3;
}
}else if( z[2]=='e' ){
- stem(&z, "tneme", "", m_gt_1) ||
- stem(&z, "tnem", "", m_gt_1) ||
- stem(&z, "tne", "", m_gt_1);
+ if( !stem(&z, "tneme", "", m_gt_1)
+ && !stem(&z, "tnem", "", m_gt_1)
+ ){
+ stem(&z, "tne", "", m_gt_1);
+ }
}
}
break;
@@ -132083,8 +133174,9 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
}
break;
case 't':
- stem(&z, "eta", "", m_gt_1) ||
- stem(&z, "iti", "", m_gt_1);
+ if( !stem(&z, "eta", "", m_gt_1) ){
+ stem(&z, "iti", "", m_gt_1);
+ }
break;
case 'u':
if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index 59b9570b85..1f19ada4cb 100644
--- a/src/3rdparty/sqlite/sqlite3.h
+++ b/src/3rdparty/sqlite/sqlite3.h
@@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.2"
-#define SQLITE_VERSION_NUMBER 3008002
-#define SQLITE_SOURCE_ID "2013-12-06 14:53:30 27392118af4c38c5203a04b8013e1afdb1cebd0d"
+#define SQLITE_VERSION "3.8.4.1"
+#define SQLITE_VERSION_NUMBER 3008004
+#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -491,6 +491,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
+#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@@ -558,7 +559,8 @@ SQLITE_API int sqlite3_exec(
** after reboot following a crash or power loss, the only bytes in a
** file that were written at the application level might have changed
** and that adjacent bytes, even bytes within the same sector are
-** guaranteed to be unchanged.
+** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+** flag indicate that a file cannot be deleted when open.
*/
#define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002
@@ -789,15 +791,29 @@ struct sqlite3_io_methods {
** additional information.
**
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
-** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by
-** SQLite and sent to all VFSes in place of a call to the xSync method
-** when the database connection has [PRAGMA synchronous] set to OFF.)^
-** Some specialized VFSes need this signal in order to operate correctly
-** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most
-** VFSes do not need this signal and should silently ignore this opcode.
-** Applications should not call [sqlite3_file_control()] with this
-** opcode as doing so may disrupt the operation of the specialized VFSes
-** that do require it.
+** No longer in use.
+**
+** <li>[[SQLITE_FCNTL_SYNC]]
+** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
+** sent to the VFS immediately before the xSync method is invoked on a
+** database file descriptor. Or, if the xSync method is not invoked
+** because the user has configured SQLite with
+** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place
+** of the xSync method. In most cases, the pointer argument passed with
+** this file-control is NULL. However, if the database file is being synced
+** as part of a multi-database commit, the argument points to a nul-terminated
+** string containing the transactions master-journal file name. VFSes that
+** do not need this signal should silently ignore this opcode. Applications
+** should not call [sqlite3_file_control()] with this opcode as doing so may
+** disrupt the operation of the specialized VFSes that do require it.
+**
+** <li>[[SQLITE_FCNTL_COMMIT_PHASETWO]]
+** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite
+** and sent to the VFS after a transaction has been committed immediately
+** but before the database is unlocked. VFSes that do not need this signal
+** should silently ignore this opcode. Applications should not call
+** [sqlite3_file_control()] with this opcode as doing so may disrupt the
+** operation of the specialized VFSes that do require it.
**
** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
@@ -921,6 +937,12 @@ struct sqlite3_io_methods {
** SQLite stack may generate instances of this file control if
** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
**
+** <li>[[SQLITE_FCNTL_HAS_MOVED]]
+** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
+** pointer to an integer and it writes a boolean into that integer depending
+** on whether or not the file has been renamed, moved, or deleted since it
+** was first opened.
+**
** </ul>
*/
#define SQLITE_FCNTL_LOCKSTATE 1
@@ -941,6 +963,9 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_TEMPFILENAME 16
#define SQLITE_FCNTL_MMAP_SIZE 18
#define SQLITE_FCNTL_TRACE 19
+#define SQLITE_FCNTL_HAS_MOVED 20
+#define SQLITE_FCNTL_SYNC 21
+#define SQLITE_FCNTL_COMMIT_PHASETWO 22
/*
** CAPI3REF: Mutex Handle
@@ -2375,11 +2400,13 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
+** ^If N is less than one, then P can be a NULL pointer.
**
-** ^The first time this routine is invoked (either internally or by
-** the application) the PRNG is seeded using randomness obtained
-** from the xRandomness method of the default [sqlite3_vfs] object.
-** ^On all subsequent invocations, the pseudo-randomness is generated
+** ^If this routine has not been previously called or if the previous
+** call had N less than one, then the PRNG is seeded using randomness
+** obtained from the xRandomness method of the default [sqlite3_vfs] object.
+** ^If the previous call to this routine had an N of 1 or more then
+** the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
@@ -2539,6 +2566,7 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_FUNCTION 31 /* NULL Function Name */
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
#define SQLITE_COPY 0 /* No longer used */
+#define SQLITE_RECURSIVE 33 /* NULL NULL */
/*
** CAPI3REF: Tracing And Profiling Functions
@@ -3957,15 +3985,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
**
** ^The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for
-** its parameters. Every SQL function implementation must be able to work
-** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be
-** more efficient with one encoding than another. ^An application may
-** invoke sqlite3_create_function() or sqlite3_create_function16() multiple
-** times with the same function but with different values of eTextRep.
+** its parameters. The application should set this parameter to
+** [SQLITE_UTF16LE] if the function implementation invokes
+** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
+** implementation invokes [sqlite3_value_text16be()] on an input, or
+** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
+** otherwise. ^The same SQL function may be registered multiple times using
+** different preferred text encodings, with different implementations for
+** each encoding.
** ^When multiple implementations of the same function are available, SQLite
** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what text
-** encoding is used, then the fourth argument should be [SQLITE_ANY].
+**
+** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
+** to signal that the function will always return the same result given
+** the same inputs within a single SQL statement. Most SQL functions are
+** deterministic. The built-in [random()] SQL function is an example of a
+** function that is not deterministic. The SQLite query planner is able to
+** perform additional optimizations on deterministic functions, so use
+** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
**
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^
@@ -4051,10 +4088,20 @@ SQLITE_API int sqlite3_create_function_v2(
#define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3
#define SQLITE_UTF16 4 /* Use native byte order */
-#define SQLITE_ANY 5 /* sqlite3_create_function only */
+#define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
+** CAPI3REF: Function Flags
+**
+** These constants may be ORed together with the
+** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
+** to [sqlite3_create_function()], [sqlite3_create_function16()], or
+** [sqlite3_create_function_v2()].
+*/
+#define SQLITE_DETERMINISTIC 0x800
+
+/*
** CAPI3REF: Deprecated Functions
** DEPRECATED
**
@@ -6075,7 +6122,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
-#define SQLITE_TESTCTRL_LAST 20
+#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
+#define SQLITE_TESTCTRL_LAST 21
/*
** CAPI3REF: SQLite Runtime Status
diff --git a/src/3rdparty/xkbcommon.pri b/src/3rdparty/xkbcommon.pri
index 57470c0499..eb34403746 100644
--- a/src/3rdparty/xkbcommon.pri
+++ b/src/3rdparty/xkbcommon.pri
@@ -1,15 +1,20 @@
QMAKE_CFLAGS += -std=gnu99 -w
-INCLUDEPATH += $$PWD/xkbcommon $$PWD/xkbcommon/src $$PWD/xkbcommon/src/xkbcomp
+INCLUDEPATH += $$PWD/xkbcommon \
+ $$PWD/xkbcommon/xkbcommon \
+ $$PWD/xkbcommon/src \
+ $$PWD/xkbcommon/src/xkbcomp
DEFINES += DFLT_XKB_CONFIG_ROOT='\\"$$QMAKE_XKB_CONFIG_ROOT\\"'
-### RMLVO names can be overwritten with environmental variables (See libxkbcommon documentation)
+### RMLVO names can be overwritten with environmental variables (see libxkbcommon documentation)
DEFINES += DEFAULT_XKB_RULES='\\"evdev\\"'
DEFINES += DEFAULT_XKB_MODEL='\\"pc105\\"'
DEFINES += DEFAULT_XKB_LAYOUT='\\"us\\"'
+# Need to rename several files, qmake has problems processing a project when
+# sub-directories contain files with an equal names.
-# Need to rename 2 files, qmake has problems processing a project when
-# directories contain files with equal names.
+# libxkbcommon generates some of these files while executing "./autogen.sh"
+# and some while executing "make" (actually YACC)
SOURCES += \
$$PWD/xkbcommon/src/atom.c \
$$PWD/xkbcommon/src/xkb-compat.c \ # renamed: compat.c -> xkb-compat.c
@@ -18,7 +23,10 @@ SOURCES += \
$$PWD/xkbcommon/src/keysym.c \
$$PWD/xkbcommon/src/keysym-utf.c \
$$PWD/xkbcommon/src/state.c \
- $$PWD/xkbcommon/src/text.c
+ $$PWD/xkbcommon/src/text.c \
+ $$PWD/xkbcommon/src/context-priv.c \
+ $$PWD/xkbcommon/src/keymap-priv.c \
+ $$PWD/xkbcommon/src/utils.c
SOURCES += \
$$PWD/xkbcommon/src/xkbcomp/action.c \
@@ -29,12 +37,24 @@ SOURCES += \
$$PWD/xkbcommon/src/xkbcomp/keycodes.c \
$$PWD/xkbcommon/src/xkbcomp/keymap-dump.c \
$$PWD/xkbcommon/src/xkbcomp/keymap.c \
- $$PWD/xkbcommon/src/xkbcomp/parser.c \
+ $$PWD/xkbcommon/src/xkbcomp/keywords.c \
$$PWD/xkbcommon/src/xkbcomp/rules.c \
$$PWD/xkbcommon/src/xkbcomp/scanner.c \
$$PWD/xkbcommon/src/xkbcomp/symbols.c \
$$PWD/xkbcommon/src/xkbcomp/types.c \
$$PWD/xkbcommon/src/xkbcomp/vmod.c \
- $$PWD/xkbcommon/src/xkbcomp/xkbcomp.c
+ $$PWD/xkbcommon/src/xkbcomp/xkbcomp.c \
+ $$PWD/xkbcommon/src/xkbcomp/parser.c
+
+!contains(DEFINES, QT_NO_XKB):contains(QT_CONFIG, use-xkbcommon-x11support): {
+ # Build xkbcommon-x11 support library, it depends on -lxcb and -lxcb-xkb, linking is done
+ # in xcb-plugin.pro (linked to system libraries or if Qt was configured with -qt-xcb then
+ # linked to -lxcb-static).
+ INCLUDEPATH += $$PWD/xkbcommon/src/x11
+ SOURCES += \
+ $$PWD/xkbcommon/src/x11/util.c \
+ $$PWD/xkbcommon/src/x11/x11-keymap.c \ # renamed: keymap.c -> x11-keymap.c
+ $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-keymap.c
+}
TR_EXCLUDE += $$PWD/*
diff --git a/src/3rdparty/xkbcommon/NEWS b/src/3rdparty/xkbcommon/NEWS
new file mode 100644
index 0000000000..450b7535ee
--- /dev/null
+++ b/src/3rdparty/xkbcommon/NEWS
@@ -0,0 +1,86 @@
+libxkbcommon 0.4.0
+==================
+
+- Add a new add-on library, xkbcommon-x11, to support creating keymaps
+ with the XKB X11 protocol, by querying the X server directly.
+ See the xkbcommon/xkbcommon-x11.h header file for more details.
+ This library requires libxcb-xkb >= 1.10, and is enabled by default.
+ It can be disabled with the --disable-x11 configure switch.
+ Distributions are encouraged to split the necessary files for this
+ library (libxkbcommon-x11.so, xkbcommon-x11.pc, xkbcommon/xkbcommon-x11.h)
+ to a separate package, such that the main package does not depend on
+ X11 libraries.
+
+- Fix the keysym <-> name lookup table to not require huge amounts of
+ relocations.
+
+- Fix a bug in the keysym <-> name lookup, whereby lookup might fail in
+ some rare cases.
+
+- Reduce memory usage during keymap compilation.
+
+- New API:
+ New keysyms from xproto 7.0.25 (German T3 layout keysyms).
+ XKB_MOD_NAME_NUM for the usual NumLock modifier.
+ xkb_x11_* types and functions, XKB_X11_* constants.
+
+
+libxkbcommon 0.3.2
+==================
+
+- Log messages from the library now look like "xkbcommon: ERROR" by
+ default, instead of xkbcomp-like "Error: ".
+
+- Apply capitalization transformation on keysyms in
+ xkb_keysym_get_one_sym(), to match the behavior specified in the XKB
+ specification:
+ http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
+
+- Support byacc for generating the parser, in addition to Bison.
+
+- New API:
+ XKB_KEY_XF86AudioMicMute keysym from xproto 7.0.24.
+ XKB_KEYSYM_NO_FLAGS
+ XKB_CONTEXT_NO_FLAGS
+ XKB_MAP_COMPILE_NO_FLAGS
+
+- Bug fixes.
+
+
+libxkbcommon 0.3.1
+==================
+
+- Replace the flex scanner with a hand-written one. flex is no longer
+ a build requirement.
+
+- New API:
+ xkb_keymap_min_keycode()
+ xkb_keymap_max_keycode()
+ xkb_keymap_key_for_each()
+
+
+libxkbcommon 0.3.0
+==================
+
+- Allow passing NULL to *_unref() functions; do nothing instead of
+ crashing.
+
+- The functions xkb_keymap_num_levels_for_key() and
+ xkb_keymap_get_syms_by_level() now allow out-of-range values for the
+ 'layout' parameter. The functions now wrap the value around the number
+ of layouts instead of failing.
+
+- The function xkb_keysym_get_name() now types unicode keysyms in
+ uppercase and 0-padding, to match the format used by XKeysymToString().
+
+- Building Linux-specific tests is no longer attempted on non-Linux
+ environments.
+
+- The function xkb_keymap_new_from_names() now accepts a NULL value for
+ the 'names' parameter, instead of failing. This is equivalent to passing
+ a 'struct xkb_rule_names' with all fields set to NULL.
+
+- New API:
+ xkb_keymap_new_from_buffer()
+
+- Bug fixes.
diff --git a/src/3rdparty/xkbcommon/README b/src/3rdparty/xkbcommon/README
index fa8e94c81c..6b99c46620 100644
--- a/src/3rdparty/xkbcommon/README
+++ b/src/3rdparty/xkbcommon/README
@@ -25,27 +25,17 @@ API
While xkbcommon's API is somewhat derived from the classic XKB API as found
in <X11/extensions/XKB.h> and friends, it has been substantially reworked to
-expose fewer internal details to clients. The only supported API is available
-in <xkbcommon/xkbcommon.h>. Any definition not in this header (including
-accessing internal structures through the old macros previously available)
-should be regarded as an implementation detail and is liable to change at any
-time.
+expose fewer internal details to clients. The supported API is available
+in the <xkbcommon/xkbcommon-*.h> files. Additional support is provided for
+X11 (XCB) clients, in the xkbcommon-x11 library, <xkbcommon/xkbcommon-x11.h>.
-During its early development, xkbcommon does not promise API or ABI stability.
-Regardless, we will attempt to not break ABI during a minor release series,
-so applications written against 0.1.0 should be completely compatible with
-0.1.3, but not necessarily with 0.2.0. However, new symbols may be introduced
-in any release. Thus, anyone packaging xkbcommon should make sure any package
-depending on it depends on a release greater than or equal to the version it
-was built against (or earlier, if it doesn't use any newly-introduced
-symbols), but less than the next major release.
-
-xkbcommon 1.x will offer full API and ABI stability for its lifetime, with a
-soname of libxkbcommon.so.1. Any ABI breaks will wait until xkbcommon 2.0,
-which will be libxkbcommon.so.2.
-
-The xkbcomp command-line tool has also been removed, although this will
-likely reappear in a later release.
+The xkbcommon API and ABI are stable. We will attempt to not break ABI during
+a minor release series, so applications written against 0.1.0 should be
+completely compatible with 0.5.3, but not necessarily with 1.0.0. However, new
+symbols may be introduced in any release. Thus, anyone packaging xkbcommon
+should make sure any package depending on it depends on a release greater than
+or equal to the version it was built against (or earlier, if it doesn't use
+any newly-introduced symbols), but less than the next major release.
Relation to X11
@@ -101,19 +91,24 @@ Development
An extremely rudimentary homepage can be found at:
http://xkbcommon.org
-xkbcommon is maintained in git at freedesktop.org:
- git://anongit.freedesktop.org/git/libxkbcommon
+xkbcommon is maintained in git at github.com:
+ https://github.com/xkbcommon/libxkbcommon
Patches are always welcome, and may be sent to either xorg-devel@lists.x.org,
-or wayland-devel@lists.freedesktop.org. Bugs are tracked in Bugzilla at:
- http://bugs.freedesktop.org
+or wayland-devel@lists.freedesktop.org.
+
+Bugs are tracked in Bugzilla at:
+ https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon
+Or in github at:
+ https://github.com/xkbcommon/libxkbcommon/issues
-The maintainer is Daniel Stone, who can be reached at:
+The maintainers are Daniel Stone and Ran Benita, who can be reached at:
<daniel@fooishbar.org>
+ <ran234@gmail.com>
Credits
=======
Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon
-off the ground initially, as well as to Ran Benita for subsequent development.
+off the ground initially.
diff --git a/src/3rdparty/xkbcommon/src/atom.c b/src/3rdparty/xkbcommon/src/atom.c
index a77502336e..044f56681a 100644
--- a/src/3rdparty/xkbcommon/src/atom.c
+++ b/src/3rdparty/xkbcommon/src/atom.c
@@ -74,15 +74,15 @@
#include "atom.h"
struct atom_node {
- struct atom_node *left, *right;
+ xkb_atom_t left, right;
xkb_atom_t atom;
unsigned int fingerprint;
char *string;
};
struct atom_table {
- struct atom_node *root;
- darray(struct atom_node *) table;
+ xkb_atom_t root;
+ darray(struct atom_node) table;
};
struct atom_table *
@@ -95,31 +95,22 @@ atom_table_new(void)
return NULL;
darray_init(table->table);
- darray_growalloc(table->table, 100);
- darray_append(table->table, NULL);
+ /* The original throw-away root is here, at the illegal atom 0. */
+ darray_resize0(table->table, 1);
return table;
}
-static void
-free_atom(struct atom_node *patom)
-{
- if (!patom)
- return;
-
- free_atom(patom->left);
- free_atom(patom->right);
- free(patom->string);
- free(patom);
-}
-
void
atom_table_free(struct atom_table *table)
{
+ struct atom_node *node;
+
if (!table)
return;
- free_atom(table->root);
+ darray_foreach(node, table->table)
+ free(node->string);
darray_free(table->table);
free(table);
}
@@ -127,52 +118,42 @@ atom_table_free(struct atom_table *table)
const char *
atom_text(struct atom_table *table, xkb_atom_t atom)
{
- if (atom >= darray_size(table->table) ||
- darray_item(table->table, atom) == NULL)
+ if (atom == XKB_ATOM_NONE || atom >= darray_size(table->table))
return NULL;
- return darray_item(table->table, atom)->string;
-}
-
-char *
-atom_strdup(struct atom_table *table, xkb_atom_t atom)
-{
- return strdup_safe(atom_text(table, atom));
+ return darray_item(table->table, atom).string;
}
static bool
-find_node_pointer(struct atom_table *table, const char *string,
- struct atom_node ***np_out, unsigned int *fingerprint_out)
+find_atom_pointer(struct atom_table *table, const char *string, size_t len,
+ xkb_atom_t **atomp_out, unsigned int *fingerprint_out)
{
- struct atom_node **np;
- unsigned i;
- int comp;
- unsigned int fp = 0;
- size_t len;
+ xkb_atom_t *atomp = &table->root;
+ unsigned int fingerprint = 0;
bool found = false;
- len = strlen(string);
- np = &table->root;
- for (i = 0; i < (len + 1) / 2; i++) {
- fp = fp * 27 + string[i];
- fp = fp * 27 + string[len - 1 - i];
+ for (size_t i = 0; i < (len + 1) / 2; i++) {
+ fingerprint = fingerprint * 27 + string[i];
+ fingerprint = fingerprint * 27 + string[len - 1 - i];
}
- while (*np) {
- if (fp < (*np)->fingerprint) {
- np = &((*np)->left);
+ while (*atomp != XKB_ATOM_NONE) {
+ struct atom_node *node = &darray_item(table->table, *atomp);
+
+ if (fingerprint < node->fingerprint) {
+ atomp = &node->left;
}
- else if (fp > (*np)->fingerprint) {
- np = &((*np)->right);
+ else if (fingerprint > node->fingerprint) {
+ atomp = &node->right;
}
else {
- /* now start testing the strings */
- comp = strncmp(string, (*np)->string, len);
- if (comp < 0 || (comp == 0 && len < strlen((*np)->string))) {
- np = &((*np)->left);
+ /* Now start testing the strings. */
+ const int cmp = strncmp(string, node->string, len);
+ if (cmp < 0 || (cmp == 0 && len < strlen(node->string))) {
+ atomp = &node->left;
}
- else if (comp > 0) {
- np = &((*np)->right);
+ else if (cmp > 0) {
+ atomp = &node->right;
}
else {
found = true;
@@ -181,68 +162,64 @@ find_node_pointer(struct atom_table *table, const char *string,
}
}
- *fingerprint_out = fp;
- *np_out = np;
+ if (fingerprint_out)
+ *fingerprint_out = fingerprint;
+ if (atomp_out)
+ *atomp_out = atomp;
return found;
}
xkb_atom_t
-atom_lookup(struct atom_table *table, const char *string)
+atom_lookup(struct atom_table *table, const char *string, size_t len)
{
- struct atom_node **np;
- unsigned int fp;
+ xkb_atom_t *atomp;
if (!string)
return XKB_ATOM_NONE;
- if (!find_node_pointer(table, string, &np, &fp))
+ if (!find_atom_pointer(table, string, len, &atomp, NULL))
return XKB_ATOM_NONE;
- return (*np)->atom;
+ return *atomp;
}
/*
* If steal is true, we do not strdup @string; therefore it must be
- * dynamically allocated, not be free'd by the caller and not be used
- * afterwards. Use to avoid some redundant allocations.
+ * dynamically allocated, NUL-terminated, not be free'd by the caller
+ * and not be used afterwards. Use to avoid some redundant allocations.
*/
xkb_atom_t
-atom_intern(struct atom_table *table, const char *string,
+atom_intern(struct atom_table *table, const char *string, size_t len,
bool steal)
{
- struct atom_node **np;
- struct atom_node *nd;
- unsigned int fp;
+ xkb_atom_t *atomp;
+ struct atom_node node;
+ unsigned int fingerprint;
if (!string)
return XKB_ATOM_NONE;
- if (find_node_pointer(table, string, &np, &fp)) {
+ if (find_atom_pointer(table, string, len, &atomp, &fingerprint)) {
if (steal)
free(UNCONSTIFY(string));
- return (*np)->atom;
+ return *atomp;
}
- nd = malloc(sizeof(*nd));
- if (!nd)
- return XKB_ATOM_NONE;
-
if (steal) {
- nd->string = UNCONSTIFY(string);
+ node.string = UNCONSTIFY(string);
}
else {
- nd->string = strdup(string);
- if (!nd->string) {
- free(nd);
+ node.string = strndup(string, len);
+ if (!node.string)
return XKB_ATOM_NONE;
- }
}
- *np = nd;
- nd->left = nd->right = NULL;
- nd->fingerprint = fp;
- nd->atom = darray_size(table->table);
- darray_append(table->table, nd);
+ node.left = node.right = XKB_ATOM_NONE;
+ node.fingerprint = fingerprint;
+ node.atom = darray_size(table->table);
+ /* Do this before the append, as it may realloc and change the offsets. */
+ *atomp = node.atom;
+ darray_append(table->table, node);
- return nd->atom;
+ return node.atom;
}
diff --git a/src/3rdparty/xkbcommon/src/atom.h b/src/3rdparty/xkbcommon/src/atom.h
index f1abf1b72f..1bf8e49b8e 100644
--- a/src/3rdparty/xkbcommon/src/atom.h
+++ b/src/3rdparty/xkbcommon/src/atom.h
@@ -37,15 +37,12 @@ void
atom_table_free(struct atom_table *table);
xkb_atom_t
-atom_lookup(struct atom_table *table, const char *string);
+atom_lookup(struct atom_table *table, const char *string, size_t len);
xkb_atom_t
-atom_intern(struct atom_table *table, const char *string,
+atom_intern(struct atom_table *table, const char *string, size_t len,
bool steal);
-char *
-atom_strdup(struct atom_table *table, xkb_atom_t atom);
-
const char *
atom_text(struct atom_table *table, xkb_atom_t atom);
diff --git a/src/3rdparty/xkbcommon/src/context-priv.c b/src/3rdparty/xkbcommon/src/context-priv.c
new file mode 100644
index 0000000000..4d7b2ed110
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/context-priv.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "xkbcommon/xkbcommon.h"
+#include "utils.h"
+#include "context.h"
+
+unsigned int
+xkb_context_num_failed_include_paths(struct xkb_context *ctx)
+{
+ return darray_size(ctx->failed_includes);
+}
+
+const char *
+xkb_context_failed_include_path_get(struct xkb_context *ctx,
+ unsigned int idx)
+{
+ if (idx >= xkb_context_num_failed_include_paths(ctx))
+ return NULL;
+
+ return darray_item(ctx->failed_includes, idx);
+}
+
+xkb_atom_t
+xkb_atom_lookup(struct xkb_context *ctx, const char *string)
+{
+ return atom_lookup(ctx->atom_table, string, strlen(string));
+}
+
+xkb_atom_t
+xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len)
+{
+ return atom_intern(ctx->atom_table, string, len, false);
+}
+
+xkb_atom_t
+xkb_atom_steal(struct xkb_context *ctx, char *string)
+{
+ return atom_intern(ctx->atom_table, string, strlen(string), true);
+}
+
+const char *
+xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom)
+{
+ return atom_text(ctx->atom_table, atom);
+}
+
+void
+xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity,
+ const char *fmt, ...)
+{
+ va_list args;
+
+ if (ctx->log_level < level || ctx->log_verbosity < verbosity)
+ return;
+
+ va_start(args, fmt);
+ ctx->log_fn(ctx, level, fmt, args);
+ va_end(args);
+}
+
+char *
+xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
+{
+ char *rtrn;
+
+ if (size >= sizeof(ctx->text_buffer))
+ return NULL;
+
+ if (sizeof(ctx->text_buffer) - ctx->text_next <= size)
+ ctx->text_next = 0;
+
+ rtrn = &ctx->text_buffer[ctx->text_next];
+ ctx->text_next += size;
+
+ return rtrn;
+}
+
+#ifndef DEFAULT_XKB_VARIANT
+#define DEFAULT_XKB_VARIANT NULL
+#endif
+
+#ifndef DEFAULT_XKB_OPTIONS
+#define DEFAULT_XKB_OPTIONS NULL
+#endif
+
+const char *
+xkb_context_get_default_rules(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_RULES");
+
+ return env ? env : DEFAULT_XKB_RULES;
+}
+
+const char *
+xkb_context_get_default_model(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_MODEL");
+
+ return env ? env : DEFAULT_XKB_MODEL;
+}
+
+const char *
+xkb_context_get_default_layout(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_LAYOUT");
+
+ return env ? env : DEFAULT_XKB_LAYOUT;
+}
+
+const char *
+xkb_context_get_default_variant(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+ const char *layout = getenv("XKB_DEFAULT_VARIANT");
+
+ /* We don't want to inherit the variant if they haven't also set a
+ * layout, since they're so closely paired. */
+ if (layout && ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_VARIANT");
+
+ return env ? env : DEFAULT_XKB_VARIANT;
+}
+
+const char *
+xkb_context_get_default_options(struct xkb_context *ctx)
+{
+ const char *env = NULL;
+
+ if (ctx->use_environment_names)
+ env = getenv("XKB_DEFAULT_OPTIONS");
+
+ return env ? env : DEFAULT_XKB_OPTIONS;
+}
diff --git a/src/3rdparty/xkbcommon/src/context.c b/src/3rdparty/xkbcommon/src/context.c
index 8d56487004..e64b91542f 100644
--- a/src/3rdparty/xkbcommon/src/context.c
+++ b/src/3rdparty/xkbcommon/src/context.c
@@ -26,7 +26,6 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <ctype.h>
#include <errno.h>
#include <unistd.h>
@@ -34,30 +33,6 @@
#include "utils.h"
#include "context.h"
-struct xkb_context {
- int refcnt;
-
- ATTR_PRINTF(3, 0) void (*log_fn)(struct xkb_context *ctx,
- enum xkb_log_level level,
- const char *fmt, va_list args);
- enum xkb_log_level log_level;
- int log_verbosity;
- void *user_data;
-
- struct xkb_rule_names names_dflt;
-
- darray(char *) includes;
- darray(char *) failed_includes;
-
- struct atom_table *atom_table;
-
- /* Buffer for the *Text() functions. */
- char text_buffer[2048];
- size_t text_next;
-
- unsigned int use_environment_names : 1;
-};
-
/**
* Append one directory to the context's include path.
*/
@@ -155,12 +130,6 @@ xkb_context_num_include_paths(struct xkb_context *ctx)
return darray_size(ctx->includes);
}
-unsigned int
-xkb_context_num_failed_include_paths(struct xkb_context *ctx)
-{
- return darray_size(ctx->failed_includes);
-}
-
/**
* Returns the given entry in the context's include path, or NULL if an
* invalid index is passed.
@@ -174,16 +143,6 @@ xkb_context_include_path_get(struct xkb_context *ctx, unsigned int idx)
return darray_item(ctx->includes, idx);
}
-const char *
-xkb_context_failed_include_path_get(struct xkb_context *ctx,
- unsigned int idx)
-{
- if (idx >= xkb_context_num_failed_include_paths(ctx))
- return NULL;
-
- return darray_item(ctx->failed_includes, idx);
-}
-
/**
* Take a new reference on the context.
*/
@@ -214,15 +173,15 @@ log_level_to_prefix(enum xkb_log_level level)
{
switch (level) {
case XKB_LOG_LEVEL_DEBUG:
- return "Debug:";
+ return "xkbcommon: DEBUG: ";
case XKB_LOG_LEVEL_INFO:
- return "Info:";
+ return "xkbcommon: INFO: ";
case XKB_LOG_LEVEL_WARNING:
- return "Warning:";
+ return "xkbcommon: WARNING: ";
case XKB_LOG_LEVEL_ERROR:
- return "Error:";
+ return "xkbcommon: ERROR: ";
case XKB_LOG_LEVEL_CRITICAL:
- return "Critical:";
+ return "xkbcommon: CRITICAL: ";
default:
return NULL;
}
@@ -235,7 +194,7 @@ default_log_fn(struct xkb_context *ctx, enum xkb_log_level level,
const char *prefix = log_level_to_prefix(level);
if (prefix)
- fprintf(stderr, "%-10s", prefix);
+ fprintf(stderr, "%s", prefix);
vfprintf(stderr, fmt, args);
}
@@ -246,7 +205,7 @@ log_level(const char *level) {
errno = 0;
lvl = strtol(level, &endptr, 10);
- if (errno == 0 && (endptr[0] == '\0' || isspace(endptr[0])))
+ if (errno == 0 && (endptr[0] == '\0' || is_space(endptr[0])))
return lvl;
if (istreq_prefix("crit", level))
return XKB_LOG_LEVEL_CRITICAL;
@@ -275,14 +234,6 @@ log_verbosity(const char *verbosity) {
return 0;
}
-#ifndef DEFAULT_XKB_VARIANT
-#define DEFAULT_XKB_VARIANT NULL
-#endif
-
-#ifndef DEFAULT_XKB_OPTIONS
-#define DEFAULT_XKB_OPTIONS NULL
-#endif
-
/**
* Create a new context.
*/
@@ -328,47 +279,6 @@ xkb_context_new(enum xkb_context_flags flags)
return ctx;
}
-xkb_atom_t
-xkb_atom_lookup(struct xkb_context *ctx, const char *string)
-{
- return atom_lookup(ctx->atom_table, string);
-}
-
-xkb_atom_t
-xkb_atom_intern(struct xkb_context *ctx, const char *string)
-{
- return atom_intern(ctx->atom_table, string, false);
-}
-
-xkb_atom_t
-xkb_atom_steal(struct xkb_context *ctx, char *string)
-{
- return atom_intern(ctx->atom_table, string, true);
-}
-
-char *
-xkb_atom_strdup(struct xkb_context *ctx, xkb_atom_t atom)
-{
- return atom_strdup(ctx->atom_table, atom);
-}
-
-const char *
-xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom)
-{
- return atom_text(ctx->atom_table, atom);
-}
-
-void
-xkb_log(struct xkb_context *ctx, enum xkb_log_level level,
- const char *fmt, ...)
-{
- va_list args;
-
- va_start(args, fmt);
- ctx->log_fn(ctx, level, fmt, args);
- va_end(args);
-}
-
XKB_EXPORT void
xkb_context_set_log_fn(struct xkb_context *ctx,
void (*log_fn)(struct xkb_context *ctx,
@@ -415,78 +325,3 @@ xkb_context_set_user_data(struct xkb_context *ctx, void *user_data)
{
ctx->user_data = user_data;
}
-
-char *
-xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
-{
- char *rtrn;
-
- if (size >= sizeof(ctx->text_buffer))
- return NULL;
-
- if (sizeof(ctx->text_buffer) - ctx->text_next <= size)
- ctx->text_next = 0;
-
- rtrn = &ctx->text_buffer[ctx->text_next];
- ctx->text_next += size;
-
- return rtrn;
-}
-
-const char *
-xkb_context_get_default_rules(struct xkb_context *ctx)
-{
- const char *env = NULL;
-
- if (ctx->use_environment_names)
- env = getenv("XKB_DEFAULT_RULES");
-
- return env ? env : DEFAULT_XKB_RULES;
-}
-
-const char *
-xkb_context_get_default_model(struct xkb_context *ctx)
-{
- const char *env = NULL;
-
- if (ctx->use_environment_names)
- env = getenv("XKB_DEFAULT_MODEL");
-
- return env ? env : DEFAULT_XKB_MODEL;
-}
-
-const char *
-xkb_context_get_default_layout(struct xkb_context *ctx)
-{
- const char *env = NULL;
-
- if (ctx->use_environment_names)
- env = getenv("XKB_DEFAULT_LAYOUT");
-
- return env ? env : DEFAULT_XKB_LAYOUT;
-}
-
-const char *
-xkb_context_get_default_variant(struct xkb_context *ctx)
-{
- const char *env = NULL;
- const char *layout = getenv("XKB_DEFAULT_VARIANT");
-
- /* We don't want to inherit the variant if they haven't also set a
- * layout, since they're so closely paired. */
- if (layout && ctx->use_environment_names)
- env = getenv("XKB_DEFAULT_VARIANT");
-
- return env ? env : DEFAULT_XKB_VARIANT;
-}
-
-const char *
-xkb_context_get_default_options(struct xkb_context *ctx)
-{
- const char *env = NULL;
-
- if (ctx->use_environment_names)
- env = getenv("XKB_DEFAULT_OPTIONS");
-
- return env ? env : DEFAULT_XKB_OPTIONS;
-}
diff --git a/src/3rdparty/xkbcommon/src/context.h b/src/3rdparty/xkbcommon/src/context.h
index 7c061a086f..486f4085a6 100644
--- a/src/3rdparty/xkbcommon/src/context.h
+++ b/src/3rdparty/xkbcommon/src/context.h
@@ -28,6 +28,30 @@
#include "atom.h"
+struct xkb_context {
+ int refcnt;
+
+ ATTR_PRINTF(3, 0) void (*log_fn)(struct xkb_context *ctx,
+ enum xkb_log_level level,
+ const char *fmt, va_list args);
+ enum xkb_log_level log_level;
+ int log_verbosity;
+ void *user_data;
+
+ struct xkb_rule_names names_dflt;
+
+ darray(char *) includes;
+ darray(char *) failed_includes;
+
+ struct atom_table *atom_table;
+
+ /* Buffer for the *Text() functions. */
+ char text_buffer[2048];
+ size_t text_next;
+
+ unsigned int use_environment_names : 1;
+};
+
unsigned int
xkb_context_num_failed_include_paths(struct xkb_context *ctx);
@@ -43,40 +67,30 @@ xkb_atom_t
xkb_atom_lookup(struct xkb_context *ctx, const char *string);
xkb_atom_t
-xkb_atom_intern(struct xkb_context *ctx, const char *string);
+xkb_atom_intern(struct xkb_context *ctx, const char *string, size_t len);
+
+#define xkb_atom_intern_literal(ctx, literal) \
+ xkb_atom_intern((ctx), (literal), sizeof(literal) - 1)
/**
- * If @string is dynamically allocated, free'd immediately after
- * being interned, and not used afterwards, use this function
+ * If @string is dynamically allocated, NUL-terminated, free'd immediately
+ * after being interned, and not used afterwards, use this function
* instead of xkb_atom_intern to avoid some unnecessary allocations.
* The caller should not use or free the passed in string afterwards.
*/
xkb_atom_t
xkb_atom_steal(struct xkb_context *ctx, char *string);
-char *
-xkb_atom_strdup(struct xkb_context *ctx, xkb_atom_t atom);
-
const char *
xkb_atom_text(struct xkb_context *ctx, xkb_atom_t atom);
char *
xkb_context_get_buffer(struct xkb_context *ctx, size_t size);
-ATTR_PRINTF(3, 4) void
-xkb_log(struct xkb_context *ctx, enum xkb_log_level level,
+ATTR_PRINTF(4, 5) void
+xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity,
const char *fmt, ...);
-#define xkb_log_cond_level(ctx, level, ...) do { \
- if (xkb_context_get_log_level(ctx) >= (level)) \
- xkb_log((ctx), (level), __VA_ARGS__); \
-} while (0)
-
-#define xkb_log_cond_verbosity(ctx, level, vrb, ...) do { \
- if (xkb_context_get_log_verbosity(ctx) >= (vrb)) \
- xkb_log_cond_level((ctx), (level), __VA_ARGS__); \
-} while (0)
-
const char *
xkb_context_get_default_rules(struct xkb_context *ctx);
@@ -99,17 +113,17 @@ xkb_context_get_default_options(struct xkb_context *ctx);
* result in an error, though.
*/
#define log_dbg(ctx, ...) \
- xkb_log_cond_level((ctx), XKB_LOG_LEVEL_DEBUG, __VA_ARGS__)
+ xkb_log((ctx), XKB_LOG_LEVEL_DEBUG, 0, __VA_ARGS__)
#define log_info(ctx, ...) \
- xkb_log_cond_level((ctx), XKB_LOG_LEVEL_INFO, __VA_ARGS__)
+ xkb_log((ctx), XKB_LOG_LEVEL_INFO, 0, __VA_ARGS__)
#define log_warn(ctx, ...) \
- xkb_log_cond_level((ctx), XKB_LOG_LEVEL_WARNING, __VA_ARGS__)
+ xkb_log((ctx), XKB_LOG_LEVEL_WARNING, 0, __VA_ARGS__)
#define log_err(ctx, ...) \
- xkb_log_cond_level((ctx), XKB_LOG_LEVEL_ERROR, __VA_ARGS__)
+ xkb_log((ctx), XKB_LOG_LEVEL_ERROR, 0, __VA_ARGS__)
#define log_wsgo(ctx, ...) \
- xkb_log_cond_level((ctx), XKB_LOG_LEVEL_CRITICAL, __VA_ARGS__)
+ xkb_log((ctx), XKB_LOG_LEVEL_CRITICAL, 0, __VA_ARGS__)
#define log_vrb(ctx, vrb, ...) \
- xkb_log_cond_verbosity((ctx), XKB_LOG_LEVEL_WARNING, (vrb), __VA_ARGS__)
+ xkb_log((ctx), XKB_LOG_LEVEL_WARNING, (vrb), __VA_ARGS__)
/*
* Variants which are prefixed by the name of the function they're
diff --git a/src/3rdparty/xkbcommon/src/keymap-priv.c b/src/3rdparty/xkbcommon/src/keymap-priv.c
new file mode 100644
index 0000000000..9f42040828
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/keymap-priv.c
@@ -0,0 +1,121 @@
+/**
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ *
+ * Author: Daniel Stone <daniel@fooishbar.org>
+ */
+
+#include "keymap.h"
+
+static void
+update_builtin_keymap_fields(struct xkb_keymap *keymap)
+{
+ struct xkb_context *ctx = keymap->ctx;
+
+ /*
+ * Add predefined (AKA real, core, X11) modifiers.
+ * The order is important!
+ */
+ darray_appends_t(keymap->mods, struct xkb_mod,
+ { .name = xkb_atom_intern_literal(ctx, "Shift"), .type = MOD_REAL },
+ { .name = xkb_atom_intern_literal(ctx, "Lock"), .type = MOD_REAL },
+ { .name = xkb_atom_intern_literal(ctx, "Control"), .type = MOD_REAL },
+ { .name = xkb_atom_intern_literal(ctx, "Mod1"), .type = MOD_REAL },
+ { .name = xkb_atom_intern_literal(ctx, "Mod2"), .type = MOD_REAL },
+ { .name = xkb_atom_intern_literal(ctx, "Mod3"), .type = MOD_REAL },
+ { .name = xkb_atom_intern_literal(ctx, "Mod4"), .type = MOD_REAL },
+ { .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL });
+}
+
+struct xkb_keymap *
+xkb_keymap_new(struct xkb_context *ctx,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags)
+{
+ struct xkb_keymap *keymap;
+
+ keymap = calloc(1, sizeof(*keymap));
+ if (!keymap)
+ return NULL;
+
+ keymap->refcnt = 1;
+ keymap->ctx = xkb_context_ref(ctx);
+
+ keymap->format = format;
+ keymap->flags = flags;
+
+ update_builtin_keymap_fields(keymap);
+
+ return keymap;
+}
+
+struct xkb_key *
+XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases)
+{
+ struct xkb_key *key;
+
+ xkb_foreach_key(key, keymap)
+ if (key->name == name)
+ return key;
+
+ if (use_aliases) {
+ xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name);
+ if (new_name != XKB_ATOM_NONE)
+ return XkbKeyByName(keymap, new_name, false);
+ }
+
+ return NULL;
+}
+
+xkb_atom_t
+XkbResolveKeyAlias(struct xkb_keymap *keymap, xkb_atom_t name)
+{
+ for (unsigned i = 0; i < keymap->num_key_aliases; i++)
+ if (keymap->key_aliases[i].alias == name)
+ return keymap->key_aliases[i].real;
+
+ return XKB_ATOM_NONE;
+}
+
+void
+XkbEscapeMapName(char *name)
+{
+ /*
+ * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
+ * wildcards.
+ */
+ static const unsigned char legal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+ };
+
+ if (!name)
+ return;
+
+ while (*name) {
+ if (!(legal[*name / 8] & (1 << (*name % 8))))
+ *name = '_';
+ name++;
+ }
+}
diff --git a/src/3rdparty/xkbcommon/src/keymap.h b/src/3rdparty/xkbcommon/src/keymap.h
index c6b884d6bc..5f514ec779 100644
--- a/src/3rdparty/xkbcommon/src/keymap.h
+++ b/src/3rdparty/xkbcommon/src/keymap.h
@@ -133,7 +133,6 @@ enum xkb_action_type {
ACTION_TYPE_SWITCH_VT,
ACTION_TYPE_CTRL_SET,
ACTION_TYPE_CTRL_LOCK,
- ACTION_TYPE_KEY_REDIRECT,
ACTION_TYPE_PRIVATE,
_ACTION_TYPE_NUM_ENTRIES
};
@@ -213,16 +212,6 @@ struct xkb_switch_screen_action {
int8_t screen;
};
-struct xkb_redirect_key_action {
- enum xkb_action_type type;
- enum xkb_action_flags flags;
- xkb_keycode_t new_kc;
- uint8_t mods_mask;
- uint8_t mods;
- uint16_t vmods_mask;
- uint16_t vmods;
-};
-
struct xkb_pointer_action {
enum xkb_action_type type;
enum xkb_action_flags flags;
@@ -250,7 +239,6 @@ union xkb_action {
struct xkb_controls_action ctrls;
struct xkb_pointer_default_action dflt;
struct xkb_switch_screen_action screen;
- struct xkb_redirect_key_action redirect; /* XXX wholly unnecessary? */
struct xkb_pointer_action ptr;
struct xkb_pointer_button_action btn;
struct xkb_private_action priv;
@@ -313,8 +301,8 @@ struct xkb_controls {
/* Such an awkward name. Oh well. */
enum xkb_range_exceed_type {
+ RANGE_WRAP = 0,
RANGE_SATURATE,
- RANGE_WRAP,
RANGE_REDIRECT,
};
@@ -386,7 +374,8 @@ struct xkb_keymap {
struct xkb_key_type *types;
unsigned int num_types;
- darray(struct xkb_sym_interpret) sym_interprets;
+ unsigned int num_sym_interprets;
+ struct xkb_sym_interpret *sym_interprets;
darray(struct xkb_mod) mods;
@@ -423,12 +412,20 @@ XkbKeyGroupWidth(const struct xkb_key *key, xkb_layout_index_t layout)
return key->groups[layout].type->num_levels;
}
+struct xkb_keymap *
+xkb_keymap_new(struct xkb_context *ctx,
+ enum xkb_keymap_format format,
+ enum xkb_keymap_compile_flags flags);
+
struct xkb_key *
XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases);
xkb_atom_t
XkbResolveKeyAlias(struct xkb_keymap *keymap, xkb_atom_t name);
+void
+XkbEscapeMapName(char *name);
+
xkb_layout_index_t
wrap_group_into_range(int32_t group,
xkb_layout_index_t num_groups,
@@ -439,9 +436,7 @@ struct xkb_keymap_format_ops {
bool (*keymap_new_from_names)(struct xkb_keymap *keymap,
const struct xkb_rule_names *names);
bool (*keymap_new_from_string)(struct xkb_keymap *keymap,
- const char *string);
- bool (*keymap_new_from_buffer)(struct xkb_keymap *keymap,
- const char *buffer, size_t length);
+ const char *string, size_t length);
bool (*keymap_new_from_file)(struct xkb_keymap *keymap, FILE *file);
char *(*keymap_get_as_string)(struct xkb_keymap *keymap);
};
diff --git a/src/3rdparty/xkbcommon/src/keysym-utf.c b/src/3rdparty/xkbcommon/src/keysym-utf.c
index 5484a8311d..129da15cf8 100644
--- a/src/3rdparty/xkbcommon/src/keysym-utf.c
+++ b/src/3rdparty/xkbcommon/src/keysym-utf.c
@@ -838,20 +838,19 @@ static const struct codepair keysymtab[] = {
static uint32_t
bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym)
{
- int min = 0;
- int max = length;
- int mid;
+ int first = 0;
+ int last = length;
if (keysym < table[0].keysym || keysym > table[length].keysym)
return 0;
/* binary search in table */
- while (max >= min) {
- mid = (min + max) / 2;
+ while (last >= first) {
+ int mid = (first + last) / 2;
if (table[mid].keysym < keysym)
- min = mid + 1;
+ first = mid + 1;
else if (table[mid].keysym > keysym)
- max = mid - 1;
+ last = mid - 1;
else /* found it */
return table[mid].ucs;
}
diff --git a/src/3rdparty/xkbcommon/src/keysym.c b/src/3rdparty/xkbcommon/src/keysym.c
index 1e92a4ac9f..f52d751973 100644
--- a/src/3rdparty/xkbcommon/src/keysym.c
+++ b/src/3rdparty/xkbcommon/src/keysym.c
@@ -53,24 +53,31 @@
#include "keysym.h"
#include "ks_tables.h"
+static inline const char *
+get_name(const struct name_keysym *entry)
+{
+ return keysym_names + entry->offset;
+}
+
static int
compare_by_keysym(const void *a, const void *b)
{
- const struct name_keysym *key = a, *entry = b;
- return key->keysym - (int32_t)entry->keysym;
+ const xkb_keysym_t *key = a;
+ const struct name_keysym *entry = b;
+ return *key - (int32_t) entry->keysym;
}
static int
compare_by_name(const void *a, const void *b)
{
- const struct name_keysym *key = a, *entry = b;
- return strcasecmp(key->name, entry->name);
+ const char *key = a;
+ const struct name_keysym *entry = b;
+ return strcasecmp(key, get_name(entry));
}
XKB_EXPORT int
xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
{
- const struct name_keysym search = { .name = NULL, .keysym = ks };
const struct name_keysym *entry;
if ((ks & ((unsigned long) ~0x1fffffff)) != 0) {
@@ -78,12 +85,12 @@ xkb_keysym_get_name(xkb_keysym_t ks, char *buffer, size_t size)
return -1;
}
- entry = bsearch(&search, keysym_to_name,
+ entry = bsearch(&ks, keysym_to_name,
ARRAY_SIZE(keysym_to_name),
sizeof(*keysym_to_name),
compare_by_keysym);
if (entry)
- return snprintf(buffer, size, "%s", entry->name);
+ return snprintf(buffer, size, "%s", get_name(entry));
/* Unnamed Unicode codepoint. */
if (ks >= 0x01000100 && ks <= 0x0110ffff) {
@@ -119,25 +126,25 @@ find_sym(const struct name_keysym *entry, const char *name, bool icase)
if (!entry)
return NULL;
- if (!icase && strcmp(entry->name, name) == 0)
+ if (!icase && strcmp(get_name(entry), name) == 0)
return entry;
if (icase && xkb_keysym_is_lower(entry->keysym))
return entry;
for (iter = entry - 1; iter >= name_to_keysym; --iter) {
- if (!icase && strcmp(iter->name, name) == 0)
+ if (!icase && strcmp(get_name(iter), name) == 0)
return iter;
- if (strcasecmp(iter->name, entry->name) != 0)
+ if (strcasecmp(get_name(iter), get_name(entry)) != 0)
break;
if (icase && xkb_keysym_is_lower(iter->keysym))
return iter;
}
last = name_to_keysym + len;
- for (iter = entry + 1; iter < last; --iter) {
- if (!icase && strcmp(iter->name, name) == 0)
+ for (iter = entry + 1; iter < last; ++iter) {
+ if (!icase && strcmp(get_name(iter), name) == 0)
return iter;
- if (strcasecmp(iter->name, entry->name) != 0)
+ if (strcasecmp(get_name(iter), get_name(entry)) != 0)
break;
if (icase && xkb_keysym_is_lower(iter->keysym))
return iter;
@@ -151,7 +158,6 @@ find_sym(const struct name_keysym *entry, const char *name, bool icase)
XKB_EXPORT xkb_keysym_t
xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
{
- const struct name_keysym search = { .name = s, .keysym = 0 };
const struct name_keysym *entry;
char *tmp;
xkb_keysym_t val;
@@ -160,7 +166,7 @@ xkb_keysym_from_name(const char *s, enum xkb_keysym_flags flags)
if (flags & ~XKB_KEYSYM_CASE_INSENSITIVE)
return XKB_KEY_NoSymbol;
- entry = bsearch(&search, name_to_keysym,
+ entry = bsearch(s, name_to_keysym,
ARRAY_SIZE(name_to_keysym),
sizeof(*name_to_keysym),
compare_by_name);
@@ -242,6 +248,26 @@ xkb_keysym_is_upper(xkb_keysym_t ks)
return (ks == upper ? true : false);
}
+xkb_keysym_t
+xkb_keysym_to_lower(xkb_keysym_t ks)
+{
+ xkb_keysym_t lower, upper;
+
+ XConvertCase(ks, &lower, &upper);
+
+ return lower;
+}
+
+xkb_keysym_t
+xkb_keysym_to_upper(xkb_keysym_t ks)
+{
+ xkb_keysym_t lower, upper;
+
+ XConvertCase(ks, &lower, &upper);
+
+ return upper;
+}
+
/*
* The following is copied verbatim from libX11:src/KeyBind.c, commit
* d45b3fc19fbe95c41afc4e51d768df6d42332010, with the following changes:
diff --git a/src/3rdparty/xkbcommon/src/keysym.h b/src/3rdparty/xkbcommon/src/keysym.h
index 6f2280bfd4..e9374dc492 100644
--- a/src/3rdparty/xkbcommon/src/keysym.h
+++ b/src/3rdparty/xkbcommon/src/keysym.h
@@ -59,4 +59,10 @@ xkb_keysym_is_upper(xkb_keysym_t keysym);
bool
xkb_keysym_is_keypad(xkb_keysym_t keysym);
+xkb_keysym_t
+xkb_keysym_to_upper(xkb_keysym_t ks);
+
+xkb_keysym_t
+xkb_keysym_to_lower(xkb_keysym_t ks);
+
#endif
diff --git a/src/3rdparty/xkbcommon/src/ks_tables.h b/src/3rdparty/xkbcommon/src/ks_tables.h
index a7e2b4705f..1010b694e4 100644
--- a/src/3rdparty/xkbcommon/src/ks_tables.h
+++ b/src/3rdparty/xkbcommon/src/ks_tables.h
@@ -1,4681 +1,7104 @@
-/* This file is autogenerated from Makefile.am; please do not commit directly. */
+
+/**
+ * This file comes from libxkbcommon and was generated by makekeys.py
+ * You can always fetch the latest version from:
+ * https://raw.github.com/xkbcommon/libxkbcommon/master/src/ks_tables.h
+ */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Woverlength-strings"
+static const char *keysym_names =
+ "0\0"
+ "1\0"
+ "2\0"
+ "3\0"
+ "3270_AltCursor\0"
+ "3270_Attn\0"
+ "3270_BackTab\0"
+ "3270_ChangeScreen\0"
+ "3270_Copy\0"
+ "3270_CursorBlink\0"
+ "3270_CursorSelect\0"
+ "3270_DeleteWord\0"
+ "3270_Duplicate\0"
+ "3270_Enter\0"
+ "3270_EraseEOF\0"
+ "3270_EraseInput\0"
+ "3270_ExSelect\0"
+ "3270_FieldMark\0"
+ "3270_Ident\0"
+ "3270_Jump\0"
+ "3270_KeyClick\0"
+ "3270_Left2\0"
+ "3270_PA1\0"
+ "3270_PA2\0"
+ "3270_PA3\0"
+ "3270_Play\0"
+ "3270_PrintScreen\0"
+ "3270_Quit\0"
+ "3270_Record\0"
+ "3270_Reset\0"
+ "3270_Right2\0"
+ "3270_Rule\0"
+ "3270_Setup\0"
+ "3270_Test\0"
+ "4\0"
+ "5\0"
+ "6\0"
+ "7\0"
+ "8\0"
+ "9\0"
+ "A\0"
+ "a\0"
+ "Aacute\0"
+ "aacute\0"
+ "Abelowdot\0"
+ "abelowdot\0"
+ "abovedot\0"
+ "Abreve\0"
+ "abreve\0"
+ "Abreveacute\0"
+ "abreveacute\0"
+ "Abrevebelowdot\0"
+ "abrevebelowdot\0"
+ "Abrevegrave\0"
+ "abrevegrave\0"
+ "Abrevehook\0"
+ "abrevehook\0"
+ "Abrevetilde\0"
+ "abrevetilde\0"
+ "AccessX_Enable\0"
+ "AccessX_Feedback_Enable\0"
+ "Acircumflex\0"
+ "acircumflex\0"
+ "Acircumflexacute\0"
+ "acircumflexacute\0"
+ "Acircumflexbelowdot\0"
+ "acircumflexbelowdot\0"
+ "Acircumflexgrave\0"
+ "acircumflexgrave\0"
+ "Acircumflexhook\0"
+ "acircumflexhook\0"
+ "Acircumflextilde\0"
+ "acircumflextilde\0"
+ "acute\0"
+ "Adiaeresis\0"
+ "adiaeresis\0"
+ "AE\0"
+ "ae\0"
+ "Agrave\0"
+ "agrave\0"
+ "Ahook\0"
+ "ahook\0"
+ "Alt_L\0"
+ "Alt_R\0"
+ "Amacron\0"
+ "amacron\0"
+ "ampersand\0"
+ "Aogonek\0"
+ "aogonek\0"
+ "apostrophe\0"
+ "approxeq\0"
+ "approximate\0"
+ "Arabic_0\0"
+ "Arabic_1\0"
+ "Arabic_2\0"
+ "Arabic_3\0"
+ "Arabic_4\0"
+ "Arabic_5\0"
+ "Arabic_6\0"
+ "Arabic_7\0"
+ "Arabic_8\0"
+ "Arabic_9\0"
+ "Arabic_ain\0"
+ "Arabic_alef\0"
+ "Arabic_alefmaksura\0"
+ "Arabic_beh\0"
+ "Arabic_comma\0"
+ "Arabic_dad\0"
+ "Arabic_dal\0"
+ "Arabic_damma\0"
+ "Arabic_dammatan\0"
+ "Arabic_ddal\0"
+ "Arabic_farsi_yeh\0"
+ "Arabic_fatha\0"
+ "Arabic_fathatan\0"
+ "Arabic_feh\0"
+ "Arabic_fullstop\0"
+ "Arabic_gaf\0"
+ "Arabic_ghain\0"
+ "Arabic_ha\0"
+ "Arabic_hah\0"
+ "Arabic_hamza\0"
+ "Arabic_hamza_above\0"
+ "Arabic_hamza_below\0"
+ "Arabic_hamzaonalef\0"
+ "Arabic_hamzaonwaw\0"
+ "Arabic_hamzaonyeh\0"
+ "Arabic_hamzaunderalef\0"
+ "Arabic_heh\0"
+ "Arabic_heh_doachashmee\0"
+ "Arabic_heh_goal\0"
+ "Arabic_jeem\0"
+ "Arabic_jeh\0"
+ "Arabic_kaf\0"
+ "Arabic_kasra\0"
+ "Arabic_kasratan\0"
+ "Arabic_keheh\0"
+ "Arabic_khah\0"
+ "Arabic_lam\0"
+ "Arabic_madda_above\0"
+ "Arabic_maddaonalef\0"
+ "Arabic_meem\0"
+ "Arabic_noon\0"
+ "Arabic_noon_ghunna\0"
+ "Arabic_peh\0"
+ "Arabic_percent\0"
+ "Arabic_qaf\0"
+ "Arabic_question_mark\0"
+ "Arabic_ra\0"
+ "Arabic_rreh\0"
+ "Arabic_sad\0"
+ "Arabic_seen\0"
+ "Arabic_semicolon\0"
+ "Arabic_shadda\0"
+ "Arabic_sheen\0"
+ "Arabic_sukun\0"
+ "Arabic_superscript_alef\0"
+ "Arabic_switch\0"
+ "Arabic_tah\0"
+ "Arabic_tatweel\0"
+ "Arabic_tcheh\0"
+ "Arabic_teh\0"
+ "Arabic_tehmarbuta\0"
+ "Arabic_thal\0"
+ "Arabic_theh\0"
+ "Arabic_tteh\0"
+ "Arabic_veh\0"
+ "Arabic_waw\0"
+ "Arabic_yeh\0"
+ "Arabic_yeh_baree\0"
+ "Arabic_zah\0"
+ "Arabic_zain\0"
+ "Aring\0"
+ "aring\0"
+ "Armenian_accent\0"
+ "Armenian_amanak\0"
+ "Armenian_apostrophe\0"
+ "Armenian_AT\0"
+ "Armenian_at\0"
+ "Armenian_AYB\0"
+ "Armenian_ayb\0"
+ "Armenian_BEN\0"
+ "Armenian_ben\0"
+ "Armenian_but\0"
+ "Armenian_CHA\0"
+ "Armenian_cha\0"
+ "Armenian_DA\0"
+ "Armenian_da\0"
+ "Armenian_DZA\0"
+ "Armenian_dza\0"
+ "Armenian_E\0"
+ "Armenian_e\0"
+ "Armenian_exclam\0"
+ "Armenian_FE\0"
+ "Armenian_fe\0"
+ "Armenian_full_stop\0"
+ "Armenian_GHAT\0"
+ "Armenian_ghat\0"
+ "Armenian_GIM\0"
+ "Armenian_gim\0"
+ "Armenian_HI\0"
+ "Armenian_hi\0"
+ "Armenian_HO\0"
+ "Armenian_ho\0"
+ "Armenian_hyphen\0"
+ "Armenian_INI\0"
+ "Armenian_ini\0"
+ "Armenian_JE\0"
+ "Armenian_je\0"
+ "Armenian_KE\0"
+ "Armenian_ke\0"
+ "Armenian_KEN\0"
+ "Armenian_ken\0"
+ "Armenian_KHE\0"
+ "Armenian_khe\0"
+ "Armenian_ligature_ew\0"
+ "Armenian_LYUN\0"
+ "Armenian_lyun\0"
+ "Armenian_MEN\0"
+ "Armenian_men\0"
+ "Armenian_NU\0"
+ "Armenian_nu\0"
+ "Armenian_O\0"
+ "Armenian_o\0"
+ "Armenian_paruyk\0"
+ "Armenian_PE\0"
+ "Armenian_pe\0"
+ "Armenian_PYUR\0"
+ "Armenian_pyur\0"
+ "Armenian_question\0"
+ "Armenian_RA\0"
+ "Armenian_ra\0"
+ "Armenian_RE\0"
+ "Armenian_re\0"
+ "Armenian_SE\0"
+ "Armenian_se\0"
+ "Armenian_separation_mark\0"
+ "Armenian_SHA\0"
+ "Armenian_sha\0"
+ "Armenian_shesht\0"
+ "Armenian_TCHE\0"
+ "Armenian_tche\0"
+ "Armenian_TO\0"
+ "Armenian_to\0"
+ "Armenian_TSA\0"
+ "Armenian_tsa\0"
+ "Armenian_TSO\0"
+ "Armenian_tso\0"
+ "Armenian_TYUN\0"
+ "Armenian_tyun\0"
+ "Armenian_verjaket\0"
+ "Armenian_VEV\0"
+ "Armenian_vev\0"
+ "Armenian_VO\0"
+ "Armenian_vo\0"
+ "Armenian_VYUN\0"
+ "Armenian_vyun\0"
+ "Armenian_YECH\0"
+ "Armenian_yech\0"
+ "Armenian_yentamna\0"
+ "Armenian_ZA\0"
+ "Armenian_za\0"
+ "Armenian_ZHE\0"
+ "Armenian_zhe\0"
+ "asciicircum\0"
+ "asciitilde\0"
+ "asterisk\0"
+ "at\0"
+ "Atilde\0"
+ "atilde\0"
+ "AudibleBell_Enable\0"
+ "B\0"
+ "b\0"
+ "Babovedot\0"
+ "babovedot\0"
+ "backslash\0"
+ "BackSpace\0"
+ "BackTab\0"
+ "ballotcross\0"
+ "bar\0"
+ "because\0"
+ "Begin\0"
+ "blank\0"
+ "block\0"
+ "botintegral\0"
+ "botleftparens\0"
+ "botleftsqbracket\0"
+ "botleftsummation\0"
+ "botrightparens\0"
+ "botrightsqbracket\0"
+ "botrightsummation\0"
+ "bott\0"
+ "botvertsummationconnector\0"
+ "BounceKeys_Enable\0"
+ "braceleft\0"
+ "braceright\0"
+ "bracketleft\0"
+ "bracketright\0"
+ "braille_blank\0"
+ "braille_dot_1\0"
+ "braille_dot_10\0"
+ "braille_dot_2\0"
+ "braille_dot_3\0"
+ "braille_dot_4\0"
+ "braille_dot_5\0"
+ "braille_dot_6\0"
+ "braille_dot_7\0"
+ "braille_dot_8\0"
+ "braille_dot_9\0"
+ "braille_dots_1\0"
+ "braille_dots_12\0"
+ "braille_dots_123\0"
+ "braille_dots_1234\0"
+ "braille_dots_12345\0"
+ "braille_dots_123456\0"
+ "braille_dots_1234567\0"
+ "braille_dots_12345678\0"
+ "braille_dots_1234568\0"
+ "braille_dots_123457\0"
+ "braille_dots_1234578\0"
+ "braille_dots_123458\0"
+ "braille_dots_12346\0"
+ "braille_dots_123467\0"
+ "braille_dots_1234678\0"
+ "braille_dots_123468\0"
+ "braille_dots_12347\0"
+ "braille_dots_123478\0"
+ "braille_dots_12348\0"
+ "braille_dots_1235\0"
+ "braille_dots_12356\0"
+ "braille_dots_123567\0"
+ "braille_dots_1235678\0"
+ "braille_dots_123568\0"
+ "braille_dots_12357\0"
+ "braille_dots_123578\0"
+ "braille_dots_12358\0"
+ "braille_dots_1236\0"
+ "braille_dots_12367\0"
+ "braille_dots_123678\0"
+ "braille_dots_12368\0"
+ "braille_dots_1237\0"
+ "braille_dots_12378\0"
+ "braille_dots_1238\0"
+ "braille_dots_124\0"
+ "braille_dots_1245\0"
+ "braille_dots_12456\0"
+ "braille_dots_124567\0"
+ "braille_dots_1245678\0"
+ "braille_dots_124568\0"
+ "braille_dots_12457\0"
+ "braille_dots_124578\0"
+ "braille_dots_12458\0"
+ "braille_dots_1246\0"
+ "braille_dots_12467\0"
+ "braille_dots_124678\0"
+ "braille_dots_12468\0"
+ "braille_dots_1247\0"
+ "braille_dots_12478\0"
+ "braille_dots_1248\0"
+ "braille_dots_125\0"
+ "braille_dots_1256\0"
+ "braille_dots_12567\0"
+ "braille_dots_125678\0"
+ "braille_dots_12568\0"
+ "braille_dots_1257\0"
+ "braille_dots_12578\0"
+ "braille_dots_1258\0"
+ "braille_dots_126\0"
+ "braille_dots_1267\0"
+ "braille_dots_12678\0"
+ "braille_dots_1268\0"
+ "braille_dots_127\0"
+ "braille_dots_1278\0"
+ "braille_dots_128\0"
+ "braille_dots_13\0"
+ "braille_dots_134\0"
+ "braille_dots_1345\0"
+ "braille_dots_13456\0"
+ "braille_dots_134567\0"
+ "braille_dots_1345678\0"
+ "braille_dots_134568\0"
+ "braille_dots_13457\0"
+ "braille_dots_134578\0"
+ "braille_dots_13458\0"
+ "braille_dots_1346\0"
+ "braille_dots_13467\0"
+ "braille_dots_134678\0"
+ "braille_dots_13468\0"
+ "braille_dots_1347\0"
+ "braille_dots_13478\0"
+ "braille_dots_1348\0"
+ "braille_dots_135\0"
+ "braille_dots_1356\0"
+ "braille_dots_13567\0"
+ "braille_dots_135678\0"
+ "braille_dots_13568\0"
+ "braille_dots_1357\0"
+ "braille_dots_13578\0"
+ "braille_dots_1358\0"
+ "braille_dots_136\0"
+ "braille_dots_1367\0"
+ "braille_dots_13678\0"
+ "braille_dots_1368\0"
+ "braille_dots_137\0"
+ "braille_dots_1378\0"
+ "braille_dots_138\0"
+ "braille_dots_14\0"
+ "braille_dots_145\0"
+ "braille_dots_1456\0"
+ "braille_dots_14567\0"
+ "braille_dots_145678\0"
+ "braille_dots_14568\0"
+ "braille_dots_1457\0"
+ "braille_dots_14578\0"
+ "braille_dots_1458\0"
+ "braille_dots_146\0"
+ "braille_dots_1467\0"
+ "braille_dots_14678\0"
+ "braille_dots_1468\0"
+ "braille_dots_147\0"
+ "braille_dots_1478\0"
+ "braille_dots_148\0"
+ "braille_dots_15\0"
+ "braille_dots_156\0"
+ "braille_dots_1567\0"
+ "braille_dots_15678\0"
+ "braille_dots_1568\0"
+ "braille_dots_157\0"
+ "braille_dots_1578\0"
+ "braille_dots_158\0"
+ "braille_dots_16\0"
+ "braille_dots_167\0"
+ "braille_dots_1678\0"
+ "braille_dots_168\0"
+ "braille_dots_17\0"
+ "braille_dots_178\0"
+ "braille_dots_18\0"
+ "braille_dots_2\0"
+ "braille_dots_23\0"
+ "braille_dots_234\0"
+ "braille_dots_2345\0"
+ "braille_dots_23456\0"
+ "braille_dots_234567\0"
+ "braille_dots_2345678\0"
+ "braille_dots_234568\0"
+ "braille_dots_23457\0"
+ "braille_dots_234578\0"
+ "braille_dots_23458\0"
+ "braille_dots_2346\0"
+ "braille_dots_23467\0"
+ "braille_dots_234678\0"
+ "braille_dots_23468\0"
+ "braille_dots_2347\0"
+ "braille_dots_23478\0"
+ "braille_dots_2348\0"
+ "braille_dots_235\0"
+ "braille_dots_2356\0"
+ "braille_dots_23567\0"
+ "braille_dots_235678\0"
+ "braille_dots_23568\0"
+ "braille_dots_2357\0"
+ "braille_dots_23578\0"
+ "braille_dots_2358\0"
+ "braille_dots_236\0"
+ "braille_dots_2367\0"
+ "braille_dots_23678\0"
+ "braille_dots_2368\0"
+ "braille_dots_237\0"
+ "braille_dots_2378\0"
+ "braille_dots_238\0"
+ "braille_dots_24\0"
+ "braille_dots_245\0"
+ "braille_dots_2456\0"
+ "braille_dots_24567\0"
+ "braille_dots_245678\0"
+ "braille_dots_24568\0"
+ "braille_dots_2457\0"
+ "braille_dots_24578\0"
+ "braille_dots_2458\0"
+ "braille_dots_246\0"
+ "braille_dots_2467\0"
+ "braille_dots_24678\0"
+ "braille_dots_2468\0"
+ "braille_dots_247\0"
+ "braille_dots_2478\0"
+ "braille_dots_248\0"
+ "braille_dots_25\0"
+ "braille_dots_256\0"
+ "braille_dots_2567\0"
+ "braille_dots_25678\0"
+ "braille_dots_2568\0"
+ "braille_dots_257\0"
+ "braille_dots_2578\0"
+ "braille_dots_258\0"
+ "braille_dots_26\0"
+ "braille_dots_267\0"
+ "braille_dots_2678\0"
+ "braille_dots_268\0"
+ "braille_dots_27\0"
+ "braille_dots_278\0"
+ "braille_dots_28\0"
+ "braille_dots_3\0"
+ "braille_dots_34\0"
+ "braille_dots_345\0"
+ "braille_dots_3456\0"
+ "braille_dots_34567\0"
+ "braille_dots_345678\0"
+ "braille_dots_34568\0"
+ "braille_dots_3457\0"
+ "braille_dots_34578\0"
+ "braille_dots_3458\0"
+ "braille_dots_346\0"
+ "braille_dots_3467\0"
+ "braille_dots_34678\0"
+ "braille_dots_3468\0"
+ "braille_dots_347\0"
+ "braille_dots_3478\0"
+ "braille_dots_348\0"
+ "braille_dots_35\0"
+ "braille_dots_356\0"
+ "braille_dots_3567\0"
+ "braille_dots_35678\0"
+ "braille_dots_3568\0"
+ "braille_dots_357\0"
+ "braille_dots_3578\0"
+ "braille_dots_358\0"
+ "braille_dots_36\0"
+ "braille_dots_367\0"
+ "braille_dots_3678\0"
+ "braille_dots_368\0"
+ "braille_dots_37\0"
+ "braille_dots_378\0"
+ "braille_dots_38\0"
+ "braille_dots_4\0"
+ "braille_dots_45\0"
+ "braille_dots_456\0"
+ "braille_dots_4567\0"
+ "braille_dots_45678\0"
+ "braille_dots_4568\0"
+ "braille_dots_457\0"
+ "braille_dots_4578\0"
+ "braille_dots_458\0"
+ "braille_dots_46\0"
+ "braille_dots_467\0"
+ "braille_dots_4678\0"
+ "braille_dots_468\0"
+ "braille_dots_47\0"
+ "braille_dots_478\0"
+ "braille_dots_48\0"
+ "braille_dots_5\0"
+ "braille_dots_56\0"
+ "braille_dots_567\0"
+ "braille_dots_5678\0"
+ "braille_dots_568\0"
+ "braille_dots_57\0"
+ "braille_dots_578\0"
+ "braille_dots_58\0"
+ "braille_dots_6\0"
+ "braille_dots_67\0"
+ "braille_dots_678\0"
+ "braille_dots_68\0"
+ "braille_dots_7\0"
+ "braille_dots_78\0"
+ "braille_dots_8\0"
+ "Break\0"
+ "breve\0"
+ "brokenbar\0"
+ "Byelorussian_shortu\0"
+ "Byelorussian_SHORTU\0"
+ "C\0"
+ "c\0"
+ "c_h\0"
+ "C_h\0"
+ "C_H\0"
+ "Cabovedot\0"
+ "cabovedot\0"
+ "Cacute\0"
+ "cacute\0"
+ "Cancel\0"
+ "Caps_Lock\0"
+ "careof\0"
+ "caret\0"
+ "caron\0"
+ "Ccaron\0"
+ "ccaron\0"
+ "Ccedilla\0"
+ "ccedilla\0"
+ "Ccircumflex\0"
+ "ccircumflex\0"
+ "cedilla\0"
+ "cent\0"
+ "ch\0"
+ "Ch\0"
+ "CH\0"
+ "checkerboard\0"
+ "checkmark\0"
+ "circle\0"
+ "Clear\0"
+ "ClearLine\0"
+ "club\0"
+ "Codeinput\0"
+ "colon\0"
+ "ColonSign\0"
+ "comma\0"
+ "containsas\0"
+ "Control_L\0"
+ "Control_R\0"
+ "copyright\0"
+ "cr\0"
+ "crossinglines\0"
+ "CruzeiroSign\0"
+ "cuberoot\0"
+ "currency\0"
+ "cursor\0"
+ "Cyrillic_a\0"
+ "Cyrillic_A\0"
+ "Cyrillic_be\0"
+ "Cyrillic_BE\0"
+ "Cyrillic_che\0"
+ "Cyrillic_CHE\0"
+ "Cyrillic_CHE_descender\0"
+ "Cyrillic_che_descender\0"
+ "Cyrillic_CHE_vertstroke\0"
+ "Cyrillic_che_vertstroke\0"
+ "Cyrillic_de\0"
+ "Cyrillic_DE\0"
+ "Cyrillic_dzhe\0"
+ "Cyrillic_DZHE\0"
+ "Cyrillic_e\0"
+ "Cyrillic_E\0"
+ "Cyrillic_ef\0"
+ "Cyrillic_EF\0"
+ "Cyrillic_el\0"
+ "Cyrillic_EL\0"
+ "Cyrillic_em\0"
+ "Cyrillic_EM\0"
+ "Cyrillic_en\0"
+ "Cyrillic_EN\0"
+ "Cyrillic_EN_descender\0"
+ "Cyrillic_en_descender\0"
+ "Cyrillic_er\0"
+ "Cyrillic_ER\0"
+ "Cyrillic_es\0"
+ "Cyrillic_ES\0"
+ "Cyrillic_ghe\0"
+ "Cyrillic_GHE\0"
+ "Cyrillic_GHE_bar\0"
+ "Cyrillic_ghe_bar\0"
+ "Cyrillic_ha\0"
+ "Cyrillic_HA\0"
+ "Cyrillic_HA_descender\0"
+ "Cyrillic_ha_descender\0"
+ "Cyrillic_hardsign\0"
+ "Cyrillic_HARDSIGN\0"
+ "Cyrillic_i\0"
+ "Cyrillic_I\0"
+ "Cyrillic_I_macron\0"
+ "Cyrillic_i_macron\0"
+ "Cyrillic_ie\0"
+ "Cyrillic_IE\0"
+ "Cyrillic_io\0"
+ "Cyrillic_IO\0"
+ "Cyrillic_je\0"
+ "Cyrillic_JE\0"
+ "Cyrillic_ka\0"
+ "Cyrillic_KA\0"
+ "Cyrillic_KA_descender\0"
+ "Cyrillic_ka_descender\0"
+ "Cyrillic_KA_vertstroke\0"
+ "Cyrillic_ka_vertstroke\0"
+ "Cyrillic_lje\0"
+ "Cyrillic_LJE\0"
+ "Cyrillic_nje\0"
+ "Cyrillic_NJE\0"
+ "Cyrillic_o\0"
+ "Cyrillic_O\0"
+ "Cyrillic_O_bar\0"
+ "Cyrillic_o_bar\0"
+ "Cyrillic_pe\0"
+ "Cyrillic_PE\0"
+ "Cyrillic_SCHWA\0"
+ "Cyrillic_schwa\0"
+ "Cyrillic_sha\0"
+ "Cyrillic_SHA\0"
+ "Cyrillic_shcha\0"
+ "Cyrillic_SHCHA\0"
+ "Cyrillic_SHHA\0"
+ "Cyrillic_shha\0"
+ "Cyrillic_shorti\0"
+ "Cyrillic_SHORTI\0"
+ "Cyrillic_softsign\0"
+ "Cyrillic_SOFTSIGN\0"
+ "Cyrillic_te\0"
+ "Cyrillic_TE\0"
+ "Cyrillic_tse\0"
+ "Cyrillic_TSE\0"
+ "Cyrillic_u\0"
+ "Cyrillic_U\0"
+ "Cyrillic_U_macron\0"
+ "Cyrillic_u_macron\0"
+ "Cyrillic_U_straight\0"
+ "Cyrillic_u_straight\0"
+ "Cyrillic_U_straight_bar\0"
+ "Cyrillic_u_straight_bar\0"
+ "Cyrillic_ve\0"
+ "Cyrillic_VE\0"
+ "Cyrillic_ya\0"
+ "Cyrillic_YA\0"
+ "Cyrillic_yeru\0"
+ "Cyrillic_YERU\0"
+ "Cyrillic_yu\0"
+ "Cyrillic_YU\0"
+ "Cyrillic_ze\0"
+ "Cyrillic_ZE\0"
+ "Cyrillic_zhe\0"
+ "Cyrillic_ZHE\0"
+ "Cyrillic_ZHE_descender\0"
+ "Cyrillic_zhe_descender\0"
+ "D\0"
+ "d\0"
+ "Dabovedot\0"
+ "dabovedot\0"
+ "Dacute_accent\0"
+ "dagger\0"
+ "Dcaron\0"
+ "dcaron\0"
+ "Dcedilla_accent\0"
+ "Dcircumflex_accent\0"
+ "Ddiaeresis\0"
+ "dead_a\0"
+ "dead_A\0"
+ "dead_abovecomma\0"
+ "dead_abovedot\0"
+ "dead_abovereversedcomma\0"
+ "dead_abovering\0"
+ "dead_aboveverticalline\0"
+ "dead_acute\0"
+ "dead_belowbreve\0"
+ "dead_belowcircumflex\0"
+ "dead_belowcomma\0"
+ "dead_belowdiaeresis\0"
+ "dead_belowdot\0"
+ "dead_belowmacron\0"
+ "dead_belowring\0"
+ "dead_belowtilde\0"
+ "dead_belowverticalline\0"
+ "dead_breve\0"
+ "dead_capital_schwa\0"
+ "dead_caron\0"
+ "dead_cedilla\0"
+ "dead_circumflex\0"
+ "dead_currency\0"
+ "dead_dasia\0"
+ "dead_diaeresis\0"
+ "dead_doubleacute\0"
+ "dead_doublegrave\0"
+ "dead_e\0"
+ "dead_E\0"
+ "dead_grave\0"
+ "dead_greek\0"
+ "dead_hook\0"
+ "dead_horn\0"
+ "dead_i\0"
+ "dead_I\0"
+ "dead_invertedbreve\0"
+ "dead_iota\0"
+ "dead_longsolidusoverlay\0"
+ "dead_lowline\0"
+ "dead_macron\0"
+ "dead_o\0"
+ "dead_O\0"
+ "dead_ogonek\0"
+ "dead_perispomeni\0"
+ "dead_psili\0"
+ "dead_semivoiced_sound\0"
+ "dead_small_schwa\0"
+ "dead_stroke\0"
+ "dead_tilde\0"
+ "dead_u\0"
+ "dead_U\0"
+ "dead_voiced_sound\0"
+ "decimalpoint\0"
+ "degree\0"
+ "Delete\0"
+ "DeleteChar\0"
+ "DeleteLine\0"
+ "Dgrave_accent\0"
+ "diaeresis\0"
+ "diamond\0"
+ "digitspace\0"
+ "dintegral\0"
+ "division\0"
+ "dollar\0"
+ "DongSign\0"
+ "doubbaselinedot\0"
+ "doubleacute\0"
+ "doubledagger\0"
+ "doublelowquotemark\0"
+ "Down\0"
+ "downarrow\0"
+ "downcaret\0"
+ "downshoe\0"
+ "downstile\0"
+ "downtack\0"
+ "DRemove\0"
+ "Dring_accent\0"
+ "Dstroke\0"
+ "dstroke\0"
+ "Dtilde\0"
+ "E\0"
+ "e\0"
+ "Eabovedot\0"
+ "eabovedot\0"
+ "Eacute\0"
+ "eacute\0"
+ "Ebelowdot\0"
+ "ebelowdot\0"
+ "Ecaron\0"
+ "ecaron\0"
+ "Ecircumflex\0"
+ "ecircumflex\0"
+ "Ecircumflexacute\0"
+ "ecircumflexacute\0"
+ "Ecircumflexbelowdot\0"
+ "ecircumflexbelowdot\0"
+ "Ecircumflexgrave\0"
+ "ecircumflexgrave\0"
+ "Ecircumflexhook\0"
+ "ecircumflexhook\0"
+ "Ecircumflextilde\0"
+ "ecircumflextilde\0"
+ "EcuSign\0"
+ "Ediaeresis\0"
+ "ediaeresis\0"
+ "Egrave\0"
+ "egrave\0"
+ "Ehook\0"
+ "ehook\0"
+ "eightsubscript\0"
+ "eightsuperior\0"
+ "Eisu_Shift\0"
+ "Eisu_toggle\0"
+ "elementof\0"
+ "ellipsis\0"
+ "em3space\0"
+ "em4space\0"
+ "Emacron\0"
+ "emacron\0"
+ "emdash\0"
+ "emfilledcircle\0"
+ "emfilledrect\0"
+ "emopencircle\0"
+ "emopenrectangle\0"
+ "emptyset\0"
+ "emspace\0"
+ "End\0"
+ "endash\0"
+ "enfilledcircbullet\0"
+ "enfilledsqbullet\0"
+ "ENG\0"
+ "eng\0"
+ "enopencircbullet\0"
+ "enopensquarebullet\0"
+ "enspace\0"
+ "Eogonek\0"
+ "eogonek\0"
+ "equal\0"
+ "Escape\0"
+ "ETH\0"
+ "Eth\0"
+ "eth\0"
+ "Etilde\0"
+ "etilde\0"
+ "EuroSign\0"
+ "exclam\0"
+ "exclamdown\0"
+ "Execute\0"
+ "Ext16bit_L\0"
+ "Ext16bit_R\0"
+ "EZH\0"
+ "ezh\0"
+ "F\0"
+ "f\0"
+ "F1\0"
+ "F10\0"
+ "F11\0"
+ "F12\0"
+ "F13\0"
+ "F14\0"
+ "F15\0"
+ "F16\0"
+ "F17\0"
+ "F18\0"
+ "F19\0"
+ "F2\0"
+ "F20\0"
+ "F21\0"
+ "F22\0"
+ "F23\0"
+ "F24\0"
+ "F25\0"
+ "F26\0"
+ "F27\0"
+ "F28\0"
+ "F29\0"
+ "F3\0"
+ "F30\0"
+ "F31\0"
+ "F32\0"
+ "F33\0"
+ "F34\0"
+ "F35\0"
+ "F4\0"
+ "F5\0"
+ "F6\0"
+ "F7\0"
+ "F8\0"
+ "F9\0"
+ "Fabovedot\0"
+ "fabovedot\0"
+ "Farsi_0\0"
+ "Farsi_1\0"
+ "Farsi_2\0"
+ "Farsi_3\0"
+ "Farsi_4\0"
+ "Farsi_5\0"
+ "Farsi_6\0"
+ "Farsi_7\0"
+ "Farsi_8\0"
+ "Farsi_9\0"
+ "Farsi_yeh\0"
+ "femalesymbol\0"
+ "ff\0"
+ "FFrancSign\0"
+ "figdash\0"
+ "filledlefttribullet\0"
+ "filledrectbullet\0"
+ "filledrighttribullet\0"
+ "filledtribulletdown\0"
+ "filledtribulletup\0"
+ "Find\0"
+ "First_Virtual_Screen\0"
+ "fiveeighths\0"
+ "fivesixths\0"
+ "fivesubscript\0"
+ "fivesuperior\0"
+ "fourfifths\0"
+ "foursubscript\0"
+ "foursuperior\0"
+ "fourthroot\0"
+ "function\0"
+ "G\0"
+ "g\0"
+ "Gabovedot\0"
+ "gabovedot\0"
+ "Gbreve\0"
+ "gbreve\0"
+ "Gcaron\0"
+ "gcaron\0"
+ "Gcedilla\0"
+ "gcedilla\0"
+ "Gcircumflex\0"
+ "gcircumflex\0"
+ "Georgian_an\0"
+ "Georgian_ban\0"
+ "Georgian_can\0"
+ "Georgian_char\0"
+ "Georgian_chin\0"
+ "Georgian_cil\0"
+ "Georgian_don\0"
+ "Georgian_en\0"
+ "Georgian_fi\0"
+ "Georgian_gan\0"
+ "Georgian_ghan\0"
+ "Georgian_hae\0"
+ "Georgian_har\0"
+ "Georgian_he\0"
+ "Georgian_hie\0"
+ "Georgian_hoe\0"
+ "Georgian_in\0"
+ "Georgian_jhan\0"
+ "Georgian_jil\0"
+ "Georgian_kan\0"
+ "Georgian_khar\0"
+ "Georgian_las\0"
+ "Georgian_man\0"
+ "Georgian_nar\0"
+ "Georgian_on\0"
+ "Georgian_par\0"
+ "Georgian_phar\0"
+ "Georgian_qar\0"
+ "Georgian_rae\0"
+ "Georgian_san\0"
+ "Georgian_shin\0"
+ "Georgian_tan\0"
+ "Georgian_tar\0"
+ "Georgian_un\0"
+ "Georgian_vin\0"
+ "Georgian_we\0"
+ "Georgian_xan\0"
+ "Georgian_zen\0"
+ "Georgian_zhar\0"
+ "grave\0"
+ "greater\0"
+ "greaterthanequal\0"
+ "Greek_accentdieresis\0"
+ "Greek_ALPHA\0"
+ "Greek_alpha\0"
+ "Greek_ALPHAaccent\0"
+ "Greek_alphaaccent\0"
+ "Greek_BETA\0"
+ "Greek_beta\0"
+ "Greek_CHI\0"
+ "Greek_chi\0"
+ "Greek_DELTA\0"
+ "Greek_delta\0"
+ "Greek_EPSILON\0"
+ "Greek_epsilon\0"
+ "Greek_EPSILONaccent\0"
+ "Greek_epsilonaccent\0"
+ "Greek_ETA\0"
+ "Greek_eta\0"
+ "Greek_ETAaccent\0"
+ "Greek_etaaccent\0"
+ "Greek_finalsmallsigma\0"
+ "Greek_GAMMA\0"
+ "Greek_gamma\0"
+ "Greek_horizbar\0"
+ "Greek_IOTA\0"
+ "Greek_iota\0"
+ "Greek_IOTAaccent\0"
+ "Greek_iotaaccent\0"
+ "Greek_iotaaccentdieresis\0"
+ "Greek_IOTAdiaeresis\0"
+ "Greek_IOTAdieresis\0"
+ "Greek_iotadieresis\0"
+ "Greek_KAPPA\0"
+ "Greek_kappa\0"
+ "Greek_LAMBDA\0"
+ "Greek_lambda\0"
+ "Greek_LAMDA\0"
+ "Greek_lamda\0"
+ "Greek_MU\0"
+ "Greek_mu\0"
+ "Greek_NU\0"
+ "Greek_nu\0"
+ "Greek_OMEGA\0"
+ "Greek_omega\0"
+ "Greek_OMEGAaccent\0"
+ "Greek_omegaaccent\0"
+ "Greek_OMICRON\0"
+ "Greek_omicron\0"
+ "Greek_OMICRONaccent\0"
+ "Greek_omicronaccent\0"
+ "Greek_PHI\0"
+ "Greek_phi\0"
+ "Greek_PI\0"
+ "Greek_pi\0"
+ "Greek_PSI\0"
+ "Greek_psi\0"
+ "Greek_RHO\0"
+ "Greek_rho\0"
+ "Greek_SIGMA\0"
+ "Greek_sigma\0"
+ "Greek_switch\0"
+ "Greek_TAU\0"
+ "Greek_tau\0"
+ "Greek_THETA\0"
+ "Greek_theta\0"
+ "Greek_UPSILON\0"
+ "Greek_upsilon\0"
+ "Greek_UPSILONaccent\0"
+ "Greek_upsilonaccent\0"
+ "Greek_upsilonaccentdieresis\0"
+ "Greek_UPSILONdieresis\0"
+ "Greek_upsilondieresis\0"
+ "Greek_XI\0"
+ "Greek_xi\0"
+ "Greek_ZETA\0"
+ "Greek_zeta\0"
+ "guilder\0"
+ "guillemotleft\0"
+ "guillemotright\0"
+ "H\0"
+ "h\0"
+ "hairspace\0"
+ "Hangul\0"
+ "Hangul_A\0"
+ "Hangul_AE\0"
+ "Hangul_AraeA\0"
+ "Hangul_AraeAE\0"
+ "Hangul_Banja\0"
+ "Hangul_Cieuc\0"
+ "Hangul_Codeinput\0"
+ "Hangul_Dikeud\0"
+ "Hangul_E\0"
+ "Hangul_End\0"
+ "Hangul_EO\0"
+ "Hangul_EU\0"
+ "Hangul_Hanja\0"
+ "Hangul_Hieuh\0"
+ "Hangul_I\0"
+ "Hangul_Ieung\0"
+ "Hangul_J_Cieuc\0"
+ "Hangul_J_Dikeud\0"
+ "Hangul_J_Hieuh\0"
+ "Hangul_J_Ieung\0"
+ "Hangul_J_Jieuj\0"
+ "Hangul_J_Khieuq\0"
+ "Hangul_J_Kiyeog\0"
+ "Hangul_J_KiyeogSios\0"
+ "Hangul_J_KkogjiDalrinIeung\0"
+ "Hangul_J_Mieum\0"
+ "Hangul_J_Nieun\0"
+ "Hangul_J_NieunHieuh\0"
+ "Hangul_J_NieunJieuj\0"
+ "Hangul_J_PanSios\0"
+ "Hangul_J_Phieuf\0"
+ "Hangul_J_Pieub\0"
+ "Hangul_J_PieubSios\0"
+ "Hangul_J_Rieul\0"
+ "Hangul_J_RieulHieuh\0"
+ "Hangul_J_RieulKiyeog\0"
+ "Hangul_J_RieulMieum\0"
+ "Hangul_J_RieulPhieuf\0"
+ "Hangul_J_RieulPieub\0"
+ "Hangul_J_RieulSios\0"
+ "Hangul_J_RieulTieut\0"
+ "Hangul_J_Sios\0"
+ "Hangul_J_SsangKiyeog\0"
+ "Hangul_J_SsangSios\0"
+ "Hangul_J_Tieut\0"
+ "Hangul_J_YeorinHieuh\0"
+ "Hangul_Jamo\0"
+ "Hangul_Jeonja\0"
+ "Hangul_Jieuj\0"
+ "Hangul_Khieuq\0"
+ "Hangul_Kiyeog\0"
+ "Hangul_KiyeogSios\0"
+ "Hangul_KkogjiDalrinIeung\0"
+ "Hangul_Mieum\0"
+ "Hangul_MultipleCandidate\0"
+ "Hangul_Nieun\0"
+ "Hangul_NieunHieuh\0"
+ "Hangul_NieunJieuj\0"
+ "Hangul_O\0"
+ "Hangul_OE\0"
+ "Hangul_PanSios\0"
+ "Hangul_Phieuf\0"
+ "Hangul_Pieub\0"
+ "Hangul_PieubSios\0"
+ "Hangul_PostHanja\0"
+ "Hangul_PreHanja\0"
+ "Hangul_PreviousCandidate\0"
+ "Hangul_Rieul\0"
+ "Hangul_RieulHieuh\0"
+ "Hangul_RieulKiyeog\0"
+ "Hangul_RieulMieum\0"
+ "Hangul_RieulPhieuf\0"
+ "Hangul_RieulPieub\0"
+ "Hangul_RieulSios\0"
+ "Hangul_RieulTieut\0"
+ "Hangul_RieulYeorinHieuh\0"
+ "Hangul_Romaja\0"
+ "Hangul_SingleCandidate\0"
+ "Hangul_Sios\0"
+ "Hangul_Special\0"
+ "Hangul_SsangDikeud\0"
+ "Hangul_SsangJieuj\0"
+ "Hangul_SsangKiyeog\0"
+ "Hangul_SsangPieub\0"
+ "Hangul_SsangSios\0"
+ "Hangul_Start\0"
+ "Hangul_SunkyeongeumMieum\0"
+ "Hangul_SunkyeongeumPhieuf\0"
+ "Hangul_SunkyeongeumPieub\0"
+ "Hangul_switch\0"
+ "Hangul_Tieut\0"
+ "Hangul_U\0"
+ "Hangul_WA\0"
+ "Hangul_WAE\0"
+ "Hangul_WE\0"
+ "Hangul_WEO\0"
+ "Hangul_WI\0"
+ "Hangul_YA\0"
+ "Hangul_YAE\0"
+ "Hangul_YE\0"
+ "Hangul_YEO\0"
+ "Hangul_YeorinHieuh\0"
+ "Hangul_YI\0"
+ "Hangul_YO\0"
+ "Hangul_YU\0"
+ "Hankaku\0"
+ "Hcircumflex\0"
+ "hcircumflex\0"
+ "heart\0"
+ "hebrew_aleph\0"
+ "hebrew_ayin\0"
+ "hebrew_bet\0"
+ "hebrew_beth\0"
+ "hebrew_chet\0"
+ "hebrew_dalet\0"
+ "hebrew_daleth\0"
+ "hebrew_doublelowline\0"
+ "hebrew_finalkaph\0"
+ "hebrew_finalmem\0"
+ "hebrew_finalnun\0"
+ "hebrew_finalpe\0"
+ "hebrew_finalzade\0"
+ "hebrew_finalzadi\0"
+ "hebrew_gimel\0"
+ "hebrew_gimmel\0"
+ "hebrew_he\0"
+ "hebrew_het\0"
+ "hebrew_kaph\0"
+ "hebrew_kuf\0"
+ "hebrew_lamed\0"
+ "hebrew_mem\0"
+ "hebrew_nun\0"
+ "hebrew_pe\0"
+ "hebrew_qoph\0"
+ "hebrew_resh\0"
+ "hebrew_samech\0"
+ "hebrew_samekh\0"
+ "hebrew_shin\0"
+ "Hebrew_switch\0"
+ "hebrew_taf\0"
+ "hebrew_taw\0"
+ "hebrew_tet\0"
+ "hebrew_teth\0"
+ "hebrew_waw\0"
+ "hebrew_yod\0"
+ "hebrew_zade\0"
+ "hebrew_zadi\0"
+ "hebrew_zain\0"
+ "hebrew_zayin\0"
+ "Help\0"
+ "Henkan\0"
+ "Henkan_Mode\0"
+ "hexagram\0"
+ "Hiragana\0"
+ "Hiragana_Katakana\0"
+ "Home\0"
+ "horizconnector\0"
+ "horizlinescan1\0"
+ "horizlinescan3\0"
+ "horizlinescan5\0"
+ "horizlinescan7\0"
+ "horizlinescan9\0"
+ "hpBackTab\0"
+ "hpblock\0"
+ "hpClearLine\0"
+ "hpDeleteChar\0"
+ "hpDeleteLine\0"
+ "hpguilder\0"
+ "hpInsertChar\0"
+ "hpInsertLine\0"
+ "hpIO\0"
+ "hpKP_BackTab\0"
+ "hplira\0"
+ "hplongminus\0"
+ "hpModelock1\0"
+ "hpModelock2\0"
+ "hpmute_acute\0"
+ "hpmute_asciicircum\0"
+ "hpmute_asciitilde\0"
+ "hpmute_diaeresis\0"
+ "hpmute_grave\0"
+ "hpReset\0"
+ "hpSystem\0"
+ "hpUser\0"
+ "hpYdiaeresis\0"
+ "Hstroke\0"
+ "hstroke\0"
+ "ht\0"
+ "Hyper_L\0"
+ "Hyper_R\0"
+ "hyphen\0"
+ "I\0"
+ "i\0"
+ "Iabovedot\0"
+ "Iacute\0"
+ "iacute\0"
+ "Ibelowdot\0"
+ "ibelowdot\0"
+ "Ibreve\0"
+ "ibreve\0"
+ "Icircumflex\0"
+ "icircumflex\0"
+ "identical\0"
+ "Idiaeresis\0"
+ "idiaeresis\0"
+ "idotless\0"
+ "ifonlyif\0"
+ "Igrave\0"
+ "igrave\0"
+ "Ihook\0"
+ "ihook\0"
+ "Imacron\0"
+ "imacron\0"
+ "implies\0"
+ "includedin\0"
+ "includes\0"
+ "infinity\0"
+ "Insert\0"
+ "InsertChar\0"
+ "InsertLine\0"
+ "integral\0"
+ "intersection\0"
+ "IO\0"
+ "Iogonek\0"
+ "iogonek\0"
+ "ISO_Center_Object\0"
+ "ISO_Continuous_Underline\0"
+ "ISO_Discontinuous_Underline\0"
+ "ISO_Emphasize\0"
+ "ISO_Enter\0"
+ "ISO_Fast_Cursor_Down\0"
+ "ISO_Fast_Cursor_Left\0"
+ "ISO_Fast_Cursor_Right\0"
+ "ISO_Fast_Cursor_Up\0"
+ "ISO_First_Group\0"
+ "ISO_First_Group_Lock\0"
+ "ISO_Group_Latch\0"
+ "ISO_Group_Lock\0"
+ "ISO_Group_Shift\0"
+ "ISO_Last_Group\0"
+ "ISO_Last_Group_Lock\0"
+ "ISO_Left_Tab\0"
+ "ISO_Level2_Latch\0"
+ "ISO_Level3_Latch\0"
+ "ISO_Level3_Lock\0"
+ "ISO_Level3_Shift\0"
+ "ISO_Level5_Latch\0"
+ "ISO_Level5_Lock\0"
+ "ISO_Level5_Shift\0"
+ "ISO_Lock\0"
+ "ISO_Move_Line_Down\0"
+ "ISO_Move_Line_Up\0"
+ "ISO_Next_Group\0"
+ "ISO_Next_Group_Lock\0"
+ "ISO_Partial_Line_Down\0"
+ "ISO_Partial_Line_Up\0"
+ "ISO_Partial_Space_Left\0"
+ "ISO_Partial_Space_Right\0"
+ "ISO_Prev_Group\0"
+ "ISO_Prev_Group_Lock\0"
+ "ISO_Release_Both_Margins\0"
+ "ISO_Release_Margin_Left\0"
+ "ISO_Release_Margin_Right\0"
+ "ISO_Set_Margin_Left\0"
+ "ISO_Set_Margin_Right\0"
+ "Itilde\0"
+ "itilde\0"
+ "J\0"
+ "j\0"
+ "Jcircumflex\0"
+ "jcircumflex\0"
+ "jot\0"
+ "K\0"
+ "k\0"
+ "kana_a\0"
+ "kana_A\0"
+ "kana_CHI\0"
+ "kana_closingbracket\0"
+ "kana_comma\0"
+ "kana_conjunctive\0"
+ "kana_e\0"
+ "kana_E\0"
+ "kana_FU\0"
+ "kana_fullstop\0"
+ "kana_HA\0"
+ "kana_HE\0"
+ "kana_HI\0"
+ "kana_HO\0"
+ "kana_HU\0"
+ "kana_i\0"
+ "kana_I\0"
+ "kana_KA\0"
+ "kana_KE\0"
+ "kana_KI\0"
+ "kana_KO\0"
+ "kana_KU\0"
+ "Kana_Lock\0"
+ "kana_MA\0"
+ "kana_ME\0"
+ "kana_MI\0"
+ "kana_middledot\0"
+ "kana_MO\0"
+ "kana_MU\0"
+ "kana_N\0"
+ "kana_NA\0"
+ "kana_NE\0"
+ "kana_NI\0"
+ "kana_NO\0"
+ "kana_NU\0"
+ "kana_o\0"
+ "kana_O\0"
+ "kana_openingbracket\0"
+ "kana_RA\0"
+ "kana_RE\0"
+ "kana_RI\0"
+ "kana_RO\0"
+ "kana_RU\0"
+ "kana_SA\0"
+ "kana_SE\0"
+ "kana_SHI\0"
+ "Kana_Shift\0"
+ "kana_SO\0"
+ "kana_SU\0"
+ "kana_switch\0"
+ "kana_TA\0"
+ "kana_TE\0"
+ "kana_TI\0"
+ "kana_TO\0"
+ "kana_tsu\0"
+ "kana_TSU\0"
+ "kana_tu\0"
+ "kana_TU\0"
+ "kana_u\0"
+ "kana_U\0"
+ "kana_WA\0"
+ "kana_WO\0"
+ "kana_ya\0"
+ "kana_YA\0"
+ "kana_yo\0"
+ "kana_YO\0"
+ "kana_yu\0"
+ "kana_YU\0"
+ "Kanji\0"
+ "Kanji_Bangou\0"
+ "kappa\0"
+ "Katakana\0"
+ "Kcedilla\0"
+ "kcedilla\0"
+ "Korean_Won\0"
+ "KP_0\0"
+ "KP_1\0"
+ "KP_2\0"
+ "KP_3\0"
+ "KP_4\0"
+ "KP_5\0"
+ "KP_6\0"
+ "KP_7\0"
+ "KP_8\0"
+ "KP_9\0"
+ "KP_Add\0"
+ "KP_BackTab\0"
+ "KP_Begin\0"
+ "KP_Decimal\0"
+ "KP_Delete\0"
+ "KP_Divide\0"
+ "KP_Down\0"
+ "KP_End\0"
+ "KP_Enter\0"
+ "KP_Equal\0"
+ "KP_F1\0"
+ "KP_F2\0"
+ "KP_F3\0"
+ "KP_F4\0"
+ "KP_Home\0"
+ "KP_Insert\0"
+ "KP_Left\0"
+ "KP_Multiply\0"
+ "KP_Next\0"
+ "KP_Page_Down\0"
+ "KP_Page_Up\0"
+ "KP_Prior\0"
+ "KP_Right\0"
+ "KP_Separator\0"
+ "KP_Space\0"
+ "KP_Subtract\0"
+ "KP_Tab\0"
+ "KP_Up\0"
+ "kra\0"
+ "L\0"
+ "l\0"
+ "L1\0"
+ "L10\0"
+ "L2\0"
+ "L3\0"
+ "L4\0"
+ "L5\0"
+ "L6\0"
+ "L7\0"
+ "L8\0"
+ "L9\0"
+ "Lacute\0"
+ "lacute\0"
+ "Last_Virtual_Screen\0"
+ "latincross\0"
+ "Lbelowdot\0"
+ "lbelowdot\0"
+ "Lcaron\0"
+ "lcaron\0"
+ "Lcedilla\0"
+ "lcedilla\0"
+ "Left\0"
+ "leftanglebracket\0"
+ "leftarrow\0"
+ "leftcaret\0"
+ "leftdoublequotemark\0"
+ "leftmiddlecurlybrace\0"
+ "leftopentriangle\0"
+ "leftpointer\0"
+ "leftradical\0"
+ "leftshoe\0"
+ "leftsinglequotemark\0"
+ "leftt\0"
+ "lefttack\0"
+ "less\0"
+ "lessthanequal\0"
+ "lf\0"
+ "Linefeed\0"
+ "lira\0"
+ "LiraSign\0"
+ "logicaland\0"
+ "logicalor\0"
+ "longminus\0"
+ "lowleftcorner\0"
+ "lowrightcorner\0"
+ "Lstroke\0"
+ "lstroke\0"
+ "M\0"
+ "m\0"
+ "Mabovedot\0"
+ "mabovedot\0"
+ "Macedonia_dse\0"
+ "Macedonia_DSE\0"
+ "Macedonia_gje\0"
+ "Macedonia_GJE\0"
+ "Macedonia_kje\0"
+ "Macedonia_KJE\0"
+ "macron\0"
+ "Mae_Koho\0"
+ "malesymbol\0"
+ "maltesecross\0"
+ "marker\0"
+ "masculine\0"
+ "Massyo\0"
+ "Menu\0"
+ "Meta_L\0"
+ "Meta_R\0"
+ "MillSign\0"
+ "minus\0"
+ "minutes\0"
+ "Mode_switch\0"
+ "MouseKeys_Accel_Enable\0"
+ "MouseKeys_Enable\0"
+ "mu\0"
+ "Muhenkan\0"
+ "Multi_key\0"
+ "MultipleCandidate\0"
+ "multiply\0"
+ "musicalflat\0"
+ "musicalsharp\0"
+ "mute_acute\0"
+ "mute_asciicircum\0"
+ "mute_asciitilde\0"
+ "mute_diaeresis\0"
+ "mute_grave\0"
+ "N\0"
+ "n\0"
+ "nabla\0"
+ "Nacute\0"
+ "nacute\0"
+ "NairaSign\0"
+ "Ncaron\0"
+ "ncaron\0"
+ "Ncedilla\0"
+ "ncedilla\0"
+ "NewSheqelSign\0"
+ "Next\0"
+ "Next_Virtual_Screen\0"
+ "ninesubscript\0"
+ "ninesuperior\0"
+ "nl\0"
+ "nobreakspace\0"
+ "NoSymbol\0"
+ "notapproxeq\0"
+ "notelementof\0"
+ "notequal\0"
+ "notidentical\0"
+ "notsign\0"
+ "Ntilde\0"
+ "ntilde\0"
+ "Num_Lock\0"
+ "numbersign\0"
+ "numerosign\0"
+ "O\0"
+ "o\0"
+ "Oacute\0"
+ "oacute\0"
+ "Obarred\0"
+ "obarred\0"
+ "Obelowdot\0"
+ "obelowdot\0"
+ "Ocaron\0"
+ "ocaron\0"
+ "Ocircumflex\0"
+ "ocircumflex\0"
+ "Ocircumflexacute\0"
+ "ocircumflexacute\0"
+ "Ocircumflexbelowdot\0"
+ "ocircumflexbelowdot\0"
+ "Ocircumflexgrave\0"
+ "ocircumflexgrave\0"
+ "Ocircumflexhook\0"
+ "ocircumflexhook\0"
+ "Ocircumflextilde\0"
+ "ocircumflextilde\0"
+ "Odiaeresis\0"
+ "odiaeresis\0"
+ "Odoubleacute\0"
+ "odoubleacute\0"
+ "OE\0"
+ "oe\0"
+ "ogonek\0"
+ "Ograve\0"
+ "ograve\0"
+ "Ohook\0"
+ "ohook\0"
+ "Ohorn\0"
+ "ohorn\0"
+ "Ohornacute\0"
+ "ohornacute\0"
+ "Ohornbelowdot\0"
+ "ohornbelowdot\0"
+ "Ohorngrave\0"
+ "ohorngrave\0"
+ "Ohornhook\0"
+ "ohornhook\0"
+ "Ohorntilde\0"
+ "ohorntilde\0"
+ "Omacron\0"
+ "omacron\0"
+ "oneeighth\0"
+ "onefifth\0"
+ "onehalf\0"
+ "onequarter\0"
+ "onesixth\0"
+ "onesubscript\0"
+ "onesuperior\0"
+ "onethird\0"
+ "Ooblique\0"
+ "ooblique\0"
+ "openrectbullet\0"
+ "openstar\0"
+ "opentribulletdown\0"
+ "opentribulletup\0"
+ "ordfeminine\0"
+ "osfActivate\0"
+ "osfAddMode\0"
+ "osfBackSpace\0"
+ "osfBackTab\0"
+ "osfBeginData\0"
+ "osfBeginLine\0"
+ "osfCancel\0"
+ "osfClear\0"
+ "osfCopy\0"
+ "osfCut\0"
+ "osfDelete\0"
+ "osfDeselectAll\0"
+ "osfDown\0"
+ "osfEndData\0"
+ "osfEndLine\0"
+ "osfEscape\0"
+ "osfExtend\0"
+ "osfHelp\0"
+ "osfInsert\0"
+ "osfLeft\0"
+ "osfMenu\0"
+ "osfMenuBar\0"
+ "osfNextField\0"
+ "osfNextMenu\0"
+ "osfPageDown\0"
+ "osfPageLeft\0"
+ "osfPageRight\0"
+ "osfPageUp\0"
+ "osfPaste\0"
+ "osfPrevField\0"
+ "osfPrevMenu\0"
+ "osfPrimaryPaste\0"
+ "osfQuickPaste\0"
+ "osfReselect\0"
+ "osfRestore\0"
+ "osfRight\0"
+ "osfSelect\0"
+ "osfSelectAll\0"
+ "osfUndo\0"
+ "osfUp\0"
+ "Oslash\0"
+ "oslash\0"
+ "Otilde\0"
+ "otilde\0"
+ "overbar\0"
+ "Overlay1_Enable\0"
+ "Overlay2_Enable\0"
+ "overline\0"
+ "P\0"
+ "p\0"
+ "Pabovedot\0"
+ "pabovedot\0"
+ "Page_Down\0"
+ "Page_Up\0"
+ "paragraph\0"
+ "parenleft\0"
+ "parenright\0"
+ "partdifferential\0"
+ "partialderivative\0"
+ "Pause\0"
+ "percent\0"
+ "period\0"
+ "periodcentered\0"
+ "permille\0"
+ "PesetaSign\0"
+ "phonographcopyright\0"
+ "plus\0"
+ "plusminus\0"
+ "Pointer_Accelerate\0"
+ "Pointer_Button1\0"
+ "Pointer_Button2\0"
+ "Pointer_Button3\0"
+ "Pointer_Button4\0"
+ "Pointer_Button5\0"
+ "Pointer_Button_Dflt\0"
+ "Pointer_DblClick1\0"
+ "Pointer_DblClick2\0"
+ "Pointer_DblClick3\0"
+ "Pointer_DblClick4\0"
+ "Pointer_DblClick5\0"
+ "Pointer_DblClick_Dflt\0"
+ "Pointer_DfltBtnNext\0"
+ "Pointer_DfltBtnPrev\0"
+ "Pointer_Down\0"
+ "Pointer_DownLeft\0"
+ "Pointer_DownRight\0"
+ "Pointer_Drag1\0"
+ "Pointer_Drag2\0"
+ "Pointer_Drag3\0"
+ "Pointer_Drag4\0"
+ "Pointer_Drag5\0"
+ "Pointer_Drag_Dflt\0"
+ "Pointer_EnableKeys\0"
+ "Pointer_Left\0"
+ "Pointer_Right\0"
+ "Pointer_Up\0"
+ "Pointer_UpLeft\0"
+ "Pointer_UpRight\0"
+ "prescription\0"
+ "Prev_Virtual_Screen\0"
+ "PreviousCandidate\0"
+ "Print\0"
+ "Prior\0"
+ "prolongedsound\0"
+ "punctspace\0"
+ "Q\0"
+ "q\0"
+ "quad\0"
+ "question\0"
+ "questiondown\0"
+ "quotedbl\0"
+ "quoteleft\0"
+ "quoteright\0"
+ "R\0"
+ "r\0"
+ "R1\0"
+ "R10\0"
+ "R11\0"
+ "R12\0"
+ "R13\0"
+ "R14\0"
+ "R15\0"
+ "R2\0"
+ "R3\0"
+ "R4\0"
+ "R5\0"
+ "R6\0"
+ "R7\0"
+ "R8\0"
+ "R9\0"
+ "Racute\0"
+ "racute\0"
+ "radical\0"
+ "Rcaron\0"
+ "rcaron\0"
+ "Rcedilla\0"
+ "rcedilla\0"
+ "Redo\0"
+ "registered\0"
+ "RepeatKeys_Enable\0"
+ "Reset\0"
+ "Return\0"
+ "Right\0"
+ "rightanglebracket\0"
+ "rightarrow\0"
+ "rightcaret\0"
+ "rightdoublequotemark\0"
+ "rightmiddlecurlybrace\0"
+ "rightmiddlesummation\0"
+ "rightopentriangle\0"
+ "rightpointer\0"
+ "rightshoe\0"
+ "rightsinglequotemark\0"
+ "rightt\0"
+ "righttack\0"
+ "Romaji\0"
+ "RupeeSign\0"
+ "S\0"
+ "s\0"
+ "Sabovedot\0"
+ "sabovedot\0"
+ "Sacute\0"
+ "sacute\0"
+ "Scaron\0"
+ "scaron\0"
+ "Scedilla\0"
+ "scedilla\0"
+ "SCHWA\0"
+ "schwa\0"
+ "Scircumflex\0"
+ "scircumflex\0"
+ "script_switch\0"
+ "Scroll_Lock\0"
+ "seconds\0"
+ "section\0"
+ "Select\0"
+ "semicolon\0"
+ "semivoicedsound\0"
+ "Serbian_dje\0"
+ "Serbian_DJE\0"
+ "Serbian_dze\0"
+ "Serbian_DZE\0"
+ "Serbian_je\0"
+ "Serbian_JE\0"
+ "Serbian_lje\0"
+ "Serbian_LJE\0"
+ "Serbian_nje\0"
+ "Serbian_NJE\0"
+ "Serbian_tshe\0"
+ "Serbian_TSHE\0"
+ "seveneighths\0"
+ "sevensubscript\0"
+ "sevensuperior\0"
+ "Shift_L\0"
+ "Shift_Lock\0"
+ "Shift_R\0"
+ "signaturemark\0"
+ "signifblank\0"
+ "similarequal\0"
+ "SingleCandidate\0"
+ "singlelowquotemark\0"
+ "Sinh_a\0"
+ "Sinh_aa\0"
+ "Sinh_aa2\0"
+ "Sinh_ae\0"
+ "Sinh_ae2\0"
+ "Sinh_aee\0"
+ "Sinh_aee2\0"
+ "Sinh_ai\0"
+ "Sinh_ai2\0"
+ "Sinh_al\0"
+ "Sinh_au\0"
+ "Sinh_au2\0"
+ "Sinh_ba\0"
+ "Sinh_bha\0"
+ "Sinh_ca\0"
+ "Sinh_cha\0"
+ "Sinh_dda\0"
+ "Sinh_ddha\0"
+ "Sinh_dha\0"
+ "Sinh_dhha\0"
+ "Sinh_e\0"
+ "Sinh_e2\0"
+ "Sinh_ee\0"
+ "Sinh_ee2\0"
+ "Sinh_fa\0"
+ "Sinh_ga\0"
+ "Sinh_gha\0"
+ "Sinh_h2\0"
+ "Sinh_ha\0"
+ "Sinh_i\0"
+ "Sinh_i2\0"
+ "Sinh_ii\0"
+ "Sinh_ii2\0"
+ "Sinh_ja\0"
+ "Sinh_jha\0"
+ "Sinh_jnya\0"
+ "Sinh_ka\0"
+ "Sinh_kha\0"
+ "Sinh_kunddaliya\0"
+ "Sinh_la\0"
+ "Sinh_lla\0"
+ "Sinh_lu\0"
+ "Sinh_lu2\0"
+ "Sinh_luu\0"
+ "Sinh_luu2\0"
+ "Sinh_ma\0"
+ "Sinh_mba\0"
+ "Sinh_na\0"
+ "Sinh_ndda\0"
+ "Sinh_ndha\0"
+ "Sinh_ng\0"
+ "Sinh_ng2\0"
+ "Sinh_nga\0"
+ "Sinh_nja\0"
+ "Sinh_nna\0"
+ "Sinh_nya\0"
+ "Sinh_o\0"
+ "Sinh_o2\0"
+ "Sinh_oo\0"
+ "Sinh_oo2\0"
+ "Sinh_pa\0"
+ "Sinh_pha\0"
+ "Sinh_ra\0"
+ "Sinh_ri\0"
+ "Sinh_rii\0"
+ "Sinh_ru2\0"
+ "Sinh_ruu2\0"
+ "Sinh_sa\0"
+ "Sinh_sha\0"
+ "Sinh_ssha\0"
+ "Sinh_tha\0"
+ "Sinh_thha\0"
+ "Sinh_tta\0"
+ "Sinh_ttha\0"
+ "Sinh_u\0"
+ "Sinh_u2\0"
+ "Sinh_uu\0"
+ "Sinh_uu2\0"
+ "Sinh_va\0"
+ "Sinh_ya\0"
+ "sixsubscript\0"
+ "sixsuperior\0"
+ "slash\0"
+ "SlowKeys_Enable\0"
+ "soliddiamond\0"
+ "space\0"
+ "squareroot\0"
+ "ssharp\0"
+ "sterling\0"
+ "StickyKeys_Enable\0"
+ "stricteq\0"
+ "SunAgain\0"
+ "SunAltGraph\0"
+ "SunAudioLowerVolume\0"
+ "SunAudioMute\0"
+ "SunAudioRaiseVolume\0"
+ "SunCompose\0"
+ "SunCopy\0"
+ "SunCut\0"
+ "SunF36\0"
+ "SunF37\0"
+ "SunFA_Acute\0"
+ "SunFA_Cedilla\0"
+ "SunFA_Circum\0"
+ "SunFA_Diaeresis\0"
+ "SunFA_Grave\0"
+ "SunFA_Tilde\0"
+ "SunFind\0"
+ "SunFront\0"
+ "SunOpen\0"
+ "SunPageDown\0"
+ "SunPageUp\0"
+ "SunPaste\0"
+ "SunPowerSwitch\0"
+ "SunPowerSwitchShift\0"
+ "SunPrint_Screen\0"
+ "SunProps\0"
+ "SunStop\0"
+ "SunSys_Req\0"
+ "SunUndo\0"
+ "SunVideoDegauss\0"
+ "SunVideoLowerBrightness\0"
+ "SunVideoRaiseBrightness\0"
+ "Super_L\0"
+ "Super_R\0"
+ "Sys_Req\0"
+ "System\0"
+ "T\0"
+ "t\0"
+ "Tab\0"
+ "Tabovedot\0"
+ "tabovedot\0"
+ "Tcaron\0"
+ "tcaron\0"
+ "Tcedilla\0"
+ "tcedilla\0"
+ "telephone\0"
+ "telephonerecorder\0"
+ "Terminate_Server\0"
+ "Thai_baht\0"
+ "Thai_bobaimai\0"
+ "Thai_chochan\0"
+ "Thai_chochang\0"
+ "Thai_choching\0"
+ "Thai_chochoe\0"
+ "Thai_dochada\0"
+ "Thai_dodek\0"
+ "Thai_fofa\0"
+ "Thai_fofan\0"
+ "Thai_hohip\0"
+ "Thai_honokhuk\0"
+ "Thai_khokhai\0"
+ "Thai_khokhon\0"
+ "Thai_khokhuat\0"
+ "Thai_khokhwai\0"
+ "Thai_khorakhang\0"
+ "Thai_kokai\0"
+ "Thai_lakkhangyao\0"
+ "Thai_lekchet\0"
+ "Thai_lekha\0"
+ "Thai_lekhok\0"
+ "Thai_lekkao\0"
+ "Thai_leknung\0"
+ "Thai_lekpaet\0"
+ "Thai_leksam\0"
+ "Thai_leksi\0"
+ "Thai_leksong\0"
+ "Thai_leksun\0"
+ "Thai_lochula\0"
+ "Thai_loling\0"
+ "Thai_lu\0"
+ "Thai_maichattawa\0"
+ "Thai_maiek\0"
+ "Thai_maihanakat\0"
+ "Thai_maihanakat_maitho\0"
+ "Thai_maitaikhu\0"
+ "Thai_maitho\0"
+ "Thai_maitri\0"
+ "Thai_maiyamok\0"
+ "Thai_moma\0"
+ "Thai_ngongu\0"
+ "Thai_nikhahit\0"
+ "Thai_nonen\0"
+ "Thai_nonu\0"
+ "Thai_oang\0"
+ "Thai_paiyannoi\0"
+ "Thai_phinthu\0"
+ "Thai_phophan\0"
+ "Thai_phophung\0"
+ "Thai_phosamphao\0"
+ "Thai_popla\0"
+ "Thai_rorua\0"
+ "Thai_ru\0"
+ "Thai_saraa\0"
+ "Thai_saraaa\0"
+ "Thai_saraae\0"
+ "Thai_saraaimaimalai\0"
+ "Thai_saraaimaimuan\0"
+ "Thai_saraam\0"
+ "Thai_sarae\0"
+ "Thai_sarai\0"
+ "Thai_saraii\0"
+ "Thai_sarao\0"
+ "Thai_sarau\0"
+ "Thai_saraue\0"
+ "Thai_sarauee\0"
+ "Thai_sarauu\0"
+ "Thai_sorusi\0"
+ "Thai_sosala\0"
+ "Thai_soso\0"
+ "Thai_sosua\0"
+ "Thai_thanthakhat\0"
+ "Thai_thonangmontho\0"
+ "Thai_thophuthao\0"
+ "Thai_thothahan\0"
+ "Thai_thothan\0"
+ "Thai_thothong\0"
+ "Thai_thothung\0"
+ "Thai_topatak\0"
+ "Thai_totao\0"
+ "Thai_wowaen\0"
+ "Thai_yoyak\0"
+ "Thai_yoying\0"
+ "therefore\0"
+ "thinspace\0"
+ "THORN\0"
+ "Thorn\0"
+ "thorn\0"
+ "threeeighths\0"
+ "threefifths\0"
+ "threequarters\0"
+ "threesubscript\0"
+ "threesuperior\0"
+ "tintegral\0"
+ "topintegral\0"
+ "topleftparens\0"
+ "topleftradical\0"
+ "topleftsqbracket\0"
+ "topleftsummation\0"
+ "toprightparens\0"
+ "toprightsqbracket\0"
+ "toprightsummation\0"
+ "topt\0"
+ "topvertsummationconnector\0"
+ "Touroku\0"
+ "trademark\0"
+ "trademarkincircle\0"
+ "Tslash\0"
+ "tslash\0"
+ "twofifths\0"
+ "twosubscript\0"
+ "twosuperior\0"
+ "twothirds\0"
+ "U\0"
+ "u\0"
+ "Uacute\0"
+ "uacute\0"
+ "Ubelowdot\0"
+ "ubelowdot\0"
+ "Ubreve\0"
+ "ubreve\0"
+ "Ucircumflex\0"
+ "ucircumflex\0"
+ "Udiaeresis\0"
+ "udiaeresis\0"
+ "Udoubleacute\0"
+ "udoubleacute\0"
+ "Ugrave\0"
+ "ugrave\0"
+ "Uhook\0"
+ "uhook\0"
+ "Uhorn\0"
+ "uhorn\0"
+ "Uhornacute\0"
+ "uhornacute\0"
+ "Uhornbelowdot\0"
+ "uhornbelowdot\0"
+ "Uhorngrave\0"
+ "uhorngrave\0"
+ "Uhornhook\0"
+ "uhornhook\0"
+ "Uhorntilde\0"
+ "uhorntilde\0"
+ "Ukrainian_ghe_with_upturn\0"
+ "Ukrainian_GHE_WITH_UPTURN\0"
+ "Ukrainian_i\0"
+ "Ukrainian_I\0"
+ "Ukrainian_ie\0"
+ "Ukrainian_IE\0"
+ "Ukrainian_yi\0"
+ "Ukrainian_YI\0"
+ "Ukranian_i\0"
+ "Ukranian_I\0"
+ "Ukranian_je\0"
+ "Ukranian_JE\0"
+ "Ukranian_yi\0"
+ "Ukranian_YI\0"
+ "Umacron\0"
+ "umacron\0"
+ "underbar\0"
+ "underscore\0"
+ "Undo\0"
+ "union\0"
+ "Uogonek\0"
+ "uogonek\0"
+ "Up\0"
+ "uparrow\0"
+ "upcaret\0"
+ "upleftcorner\0"
+ "uprightcorner\0"
+ "upshoe\0"
+ "upstile\0"
+ "uptack\0"
+ "Uring\0"
+ "uring\0"
+ "User\0"
+ "Utilde\0"
+ "utilde\0"
+ "V\0"
+ "v\0"
+ "variation\0"
+ "vertbar\0"
+ "vertconnector\0"
+ "voicedsound\0"
+ "VoidSymbol\0"
+ "vt\0"
+ "W\0"
+ "w\0"
+ "Wacute\0"
+ "wacute\0"
+ "Wcircumflex\0"
+ "wcircumflex\0"
+ "Wdiaeresis\0"
+ "wdiaeresis\0"
+ "Wgrave\0"
+ "wgrave\0"
+ "WonSign\0"
+ "X\0"
+ "x\0"
+ "Xabovedot\0"
+ "xabovedot\0"
+ "XF86AddFavorite\0"
+ "XF86ApplicationLeft\0"
+ "XF86ApplicationRight\0"
+ "XF86AudioCycleTrack\0"
+ "XF86AudioForward\0"
+ "XF86AudioLowerVolume\0"
+ "XF86AudioMedia\0"
+ "XF86AudioMicMute\0"
+ "XF86AudioMute\0"
+ "XF86AudioNext\0"
+ "XF86AudioPause\0"
+ "XF86AudioPlay\0"
+ "XF86AudioPrev\0"
+ "XF86AudioRaiseVolume\0"
+ "XF86AudioRandomPlay\0"
+ "XF86AudioRecord\0"
+ "XF86AudioRepeat\0"
+ "XF86AudioRewind\0"
+ "XF86AudioStop\0"
+ "XF86Away\0"
+ "XF86Back\0"
+ "XF86BackForward\0"
+ "XF86Battery\0"
+ "XF86Blue\0"
+ "XF86Bluetooth\0"
+ "XF86Book\0"
+ "XF86BrightnessAdjust\0"
+ "XF86Calculater\0"
+ "XF86Calculator\0"
+ "XF86Calendar\0"
+ "XF86CD\0"
+ "XF86Clear\0"
+ "XF86ClearGrab\0"
+ "XF86Close\0"
+ "XF86Community\0"
+ "XF86ContrastAdjust\0"
+ "XF86Copy\0"
+ "XF86Cut\0"
+ "XF86CycleAngle\0"
+ "XF86Display\0"
+ "XF86Documents\0"
+ "XF86DOS\0"
+ "XF86Eject\0"
+ "XF86Excel\0"
+ "XF86Explorer\0"
+ "XF86Favorites\0"
+ "XF86Finance\0"
+ "XF86Forward\0"
+ "XF86FrameBack\0"
+ "XF86FrameForward\0"
+ "XF86Game\0"
+ "XF86Go\0"
+ "XF86Green\0"
+ "XF86Hibernate\0"
+ "XF86History\0"
+ "XF86HomePage\0"
+ "XF86HotLinks\0"
+ "XF86iTouch\0"
+ "XF86KbdBrightnessDown\0"
+ "XF86KbdBrightnessUp\0"
+ "XF86KbdLightOnOff\0"
+ "XF86Launch0\0"
+ "XF86Launch1\0"
+ "XF86Launch2\0"
+ "XF86Launch3\0"
+ "XF86Launch4\0"
+ "XF86Launch5\0"
+ "XF86Launch6\0"
+ "XF86Launch7\0"
+ "XF86Launch8\0"
+ "XF86Launch9\0"
+ "XF86LaunchA\0"
+ "XF86LaunchB\0"
+ "XF86LaunchC\0"
+ "XF86LaunchD\0"
+ "XF86LaunchE\0"
+ "XF86LaunchF\0"
+ "XF86LightBulb\0"
+ "XF86LogGrabInfo\0"
+ "XF86LogOff\0"
+ "XF86LogWindowTree\0"
+ "XF86Mail\0"
+ "XF86MailForward\0"
+ "XF86Market\0"
+ "XF86Meeting\0"
+ "XF86Memo\0"
+ "XF86MenuKB\0"
+ "XF86MenuPB\0"
+ "XF86Messenger\0"
+ "XF86ModeLock\0"
+ "XF86MonBrightnessDown\0"
+ "XF86MonBrightnessUp\0"
+ "XF86Music\0"
+ "XF86MyComputer\0"
+ "XF86MySites\0"
+ "XF86New\0"
+ "XF86News\0"
+ "XF86Next_VMode\0"
+ "XF86OfficeHome\0"
+ "XF86Open\0"
+ "XF86OpenURL\0"
+ "XF86Option\0"
+ "XF86Paste\0"
+ "XF86Phone\0"
+ "XF86Pictures\0"
+ "XF86PowerDown\0"
+ "XF86PowerOff\0"
+ "XF86Prev_VMode\0"
+ "XF86Q\0"
+ "XF86Red\0"
+ "XF86Refresh\0"
+ "XF86Reload\0"
+ "XF86Reply\0"
+ "XF86RockerDown\0"
+ "XF86RockerEnter\0"
+ "XF86RockerUp\0"
+ "XF86RotateWindows\0"
+ "XF86RotationKB\0"
+ "XF86RotationPB\0"
+ "XF86Save\0"
+ "XF86ScreenSaver\0"
+ "XF86ScrollClick\0"
+ "XF86ScrollDown\0"
+ "XF86ScrollUp\0"
+ "XF86Search\0"
+ "XF86Select\0"
+ "XF86Send\0"
+ "XF86Shop\0"
+ "XF86Sleep\0"
+ "XF86Spell\0"
+ "XF86SplitScreen\0"
+ "XF86Standby\0"
+ "XF86Start\0"
+ "XF86Stop\0"
+ "XF86Subtitle\0"
+ "XF86Support\0"
+ "XF86Suspend\0"
+ "XF86Switch_VT_1\0"
+ "XF86Switch_VT_10\0"
+ "XF86Switch_VT_11\0"
+ "XF86Switch_VT_12\0"
+ "XF86Switch_VT_2\0"
+ "XF86Switch_VT_3\0"
+ "XF86Switch_VT_4\0"
+ "XF86Switch_VT_5\0"
+ "XF86Switch_VT_6\0"
+ "XF86Switch_VT_7\0"
+ "XF86Switch_VT_8\0"
+ "XF86Switch_VT_9\0"
+ "XF86TaskPane\0"
+ "XF86Terminal\0"
+ "XF86Time\0"
+ "XF86ToDoList\0"
+ "XF86Tools\0"
+ "XF86TopMenu\0"
+ "XF86TouchpadOff\0"
+ "XF86TouchpadOn\0"
+ "XF86TouchpadToggle\0"
+ "XF86Travel\0"
+ "XF86Ungrab\0"
+ "XF86User1KB\0"
+ "XF86User2KB\0"
+ "XF86UserPB\0"
+ "XF86UWB\0"
+ "XF86VendorHome\0"
+ "XF86Video\0"
+ "XF86View\0"
+ "XF86WakeUp\0"
+ "XF86WebCam\0"
+ "XF86WheelButton\0"
+ "XF86WLAN\0"
+ "XF86Word\0"
+ "XF86WWW\0"
+ "XF86Xfer\0"
+ "XF86Yellow\0"
+ "XF86ZoomIn\0"
+ "XF86ZoomOut\0"
+ "Y\0"
+ "y\0"
+ "Yacute\0"
+ "yacute\0"
+ "Ybelowdot\0"
+ "ybelowdot\0"
+ "Ycircumflex\0"
+ "ycircumflex\0"
+ "ydiaeresis\0"
+ "Ydiaeresis\0"
+ "yen\0"
+ "Ygrave\0"
+ "ygrave\0"
+ "Yhook\0"
+ "yhook\0"
+ "Ytilde\0"
+ "ytilde\0"
+ "Z\0"
+ "z\0"
+ "Zabovedot\0"
+ "zabovedot\0"
+ "Zacute\0"
+ "zacute\0"
+ "Zcaron\0"
+ "zcaron\0"
+ "Zen_Koho\0"
+ "Zenkaku\0"
+ "Zenkaku_Hankaku\0"
+ "zerosubscript\0"
+ "zerosuperior\0"
+ "Zstroke\0"
+ "zstroke\0"
+;
+#pragma GCC diagnostic pop
struct name_keysym {
- const char *name;
xkb_keysym_t keysym;
+ uint32_t offset;
};
static const struct name_keysym name_to_keysym[] = {
- { "0", XKB_KEY_0 },
- { "1", XKB_KEY_1 },
- { "2", XKB_KEY_2 },
- { "3", XKB_KEY_3 },
- { "3270_AltCursor", XKB_KEY_3270_AltCursor },
- { "3270_Attn", XKB_KEY_3270_Attn },
- { "3270_BackTab", XKB_KEY_3270_BackTab },
- { "3270_ChangeScreen", XKB_KEY_3270_ChangeScreen },
- { "3270_Copy", XKB_KEY_3270_Copy },
- { "3270_CursorBlink", XKB_KEY_3270_CursorBlink },
- { "3270_CursorSelect", XKB_KEY_3270_CursorSelect },
- { "3270_DeleteWord", XKB_KEY_3270_DeleteWord },
- { "3270_Duplicate", XKB_KEY_3270_Duplicate },
- { "3270_Enter", XKB_KEY_3270_Enter },
- { "3270_EraseEOF", XKB_KEY_3270_EraseEOF },
- { "3270_EraseInput", XKB_KEY_3270_EraseInput },
- { "3270_ExSelect", XKB_KEY_3270_ExSelect },
- { "3270_FieldMark", XKB_KEY_3270_FieldMark },
- { "3270_Ident", XKB_KEY_3270_Ident },
- { "3270_Jump", XKB_KEY_3270_Jump },
- { "3270_KeyClick", XKB_KEY_3270_KeyClick },
- { "3270_Left2", XKB_KEY_3270_Left2 },
- { "3270_PA1", XKB_KEY_3270_PA1 },
- { "3270_PA2", XKB_KEY_3270_PA2 },
- { "3270_PA3", XKB_KEY_3270_PA3 },
- { "3270_Play", XKB_KEY_3270_Play },
- { "3270_PrintScreen", XKB_KEY_3270_PrintScreen },
- { "3270_Quit", XKB_KEY_3270_Quit },
- { "3270_Record", XKB_KEY_3270_Record },
- { "3270_Reset", XKB_KEY_3270_Reset },
- { "3270_Right2", XKB_KEY_3270_Right2 },
- { "3270_Rule", XKB_KEY_3270_Rule },
- { "3270_Setup", XKB_KEY_3270_Setup },
- { "3270_Test", XKB_KEY_3270_Test },
- { "4", XKB_KEY_4 },
- { "5", XKB_KEY_5 },
- { "6", XKB_KEY_6 },
- { "7", XKB_KEY_7 },
- { "8", XKB_KEY_8 },
- { "9", XKB_KEY_9 },
- { "A", XKB_KEY_A },
- { "a", XKB_KEY_a },
- { "Aacute", XKB_KEY_Aacute },
- { "aacute", XKB_KEY_aacute },
- { "Abelowdot", XKB_KEY_Abelowdot },
- { "abelowdot", XKB_KEY_abelowdot },
- { "abovedot", XKB_KEY_abovedot },
- { "Abreve", XKB_KEY_Abreve },
- { "abreve", XKB_KEY_abreve },
- { "Abreveacute", XKB_KEY_Abreveacute },
- { "abreveacute", XKB_KEY_abreveacute },
- { "Abrevebelowdot", XKB_KEY_Abrevebelowdot },
- { "abrevebelowdot", XKB_KEY_abrevebelowdot },
- { "Abrevegrave", XKB_KEY_Abrevegrave },
- { "abrevegrave", XKB_KEY_abrevegrave },
- { "Abrevehook", XKB_KEY_Abrevehook },
- { "abrevehook", XKB_KEY_abrevehook },
- { "Abrevetilde", XKB_KEY_Abrevetilde },
- { "abrevetilde", XKB_KEY_abrevetilde },
- { "AccessX_Enable", XKB_KEY_AccessX_Enable },
- { "AccessX_Feedback_Enable", XKB_KEY_AccessX_Feedback_Enable },
- { "Acircumflex", XKB_KEY_Acircumflex },
- { "acircumflex", XKB_KEY_acircumflex },
- { "Acircumflexacute", XKB_KEY_Acircumflexacute },
- { "acircumflexacute", XKB_KEY_acircumflexacute },
- { "Acircumflexbelowdot", XKB_KEY_Acircumflexbelowdot },
- { "acircumflexbelowdot", XKB_KEY_acircumflexbelowdot },
- { "Acircumflexgrave", XKB_KEY_Acircumflexgrave },
- { "acircumflexgrave", XKB_KEY_acircumflexgrave },
- { "Acircumflexhook", XKB_KEY_Acircumflexhook },
- { "acircumflexhook", XKB_KEY_acircumflexhook },
- { "Acircumflextilde", XKB_KEY_Acircumflextilde },
- { "acircumflextilde", XKB_KEY_acircumflextilde },
- { "acute", XKB_KEY_acute },
- { "Adiaeresis", XKB_KEY_Adiaeresis },
- { "adiaeresis", XKB_KEY_adiaeresis },
- { "AE", XKB_KEY_AE },
- { "ae", XKB_KEY_ae },
- { "Agrave", XKB_KEY_Agrave },
- { "agrave", XKB_KEY_agrave },
- { "Ahook", XKB_KEY_Ahook },
- { "ahook", XKB_KEY_ahook },
- { "Alt_L", XKB_KEY_Alt_L },
- { "Alt_R", XKB_KEY_Alt_R },
- { "Amacron", XKB_KEY_Amacron },
- { "amacron", XKB_KEY_amacron },
- { "ampersand", XKB_KEY_ampersand },
- { "Aogonek", XKB_KEY_Aogonek },
- { "aogonek", XKB_KEY_aogonek },
- { "apostrophe", XKB_KEY_apostrophe },
- { "approxeq", XKB_KEY_approxeq },
- { "approximate", XKB_KEY_approximate },
- { "Arabic_0", XKB_KEY_Arabic_0 },
- { "Arabic_1", XKB_KEY_Arabic_1 },
- { "Arabic_2", XKB_KEY_Arabic_2 },
- { "Arabic_3", XKB_KEY_Arabic_3 },
- { "Arabic_4", XKB_KEY_Arabic_4 },
- { "Arabic_5", XKB_KEY_Arabic_5 },
- { "Arabic_6", XKB_KEY_Arabic_6 },
- { "Arabic_7", XKB_KEY_Arabic_7 },
- { "Arabic_8", XKB_KEY_Arabic_8 },
- { "Arabic_9", XKB_KEY_Arabic_9 },
- { "Arabic_ain", XKB_KEY_Arabic_ain },
- { "Arabic_alef", XKB_KEY_Arabic_alef },
- { "Arabic_alefmaksura", XKB_KEY_Arabic_alefmaksura },
- { "Arabic_beh", XKB_KEY_Arabic_beh },
- { "Arabic_comma", XKB_KEY_Arabic_comma },
- { "Arabic_dad", XKB_KEY_Arabic_dad },
- { "Arabic_dal", XKB_KEY_Arabic_dal },
- { "Arabic_damma", XKB_KEY_Arabic_damma },
- { "Arabic_dammatan", XKB_KEY_Arabic_dammatan },
- { "Arabic_ddal", XKB_KEY_Arabic_ddal },
- { "Arabic_farsi_yeh", XKB_KEY_Arabic_farsi_yeh },
- { "Arabic_fatha", XKB_KEY_Arabic_fatha },
- { "Arabic_fathatan", XKB_KEY_Arabic_fathatan },
- { "Arabic_feh", XKB_KEY_Arabic_feh },
- { "Arabic_fullstop", XKB_KEY_Arabic_fullstop },
- { "Arabic_gaf", XKB_KEY_Arabic_gaf },
- { "Arabic_ghain", XKB_KEY_Arabic_ghain },
- { "Arabic_ha", XKB_KEY_Arabic_ha },
- { "Arabic_hah", XKB_KEY_Arabic_hah },
- { "Arabic_hamza", XKB_KEY_Arabic_hamza },
- { "Arabic_hamza_above", XKB_KEY_Arabic_hamza_above },
- { "Arabic_hamza_below", XKB_KEY_Arabic_hamza_below },
- { "Arabic_hamzaonalef", XKB_KEY_Arabic_hamzaonalef },
- { "Arabic_hamzaonwaw", XKB_KEY_Arabic_hamzaonwaw },
- { "Arabic_hamzaonyeh", XKB_KEY_Arabic_hamzaonyeh },
- { "Arabic_hamzaunderalef", XKB_KEY_Arabic_hamzaunderalef },
- { "Arabic_heh", XKB_KEY_Arabic_heh },
- { "Arabic_heh_doachashmee", XKB_KEY_Arabic_heh_doachashmee },
- { "Arabic_heh_goal", XKB_KEY_Arabic_heh_goal },
- { "Arabic_jeem", XKB_KEY_Arabic_jeem },
- { "Arabic_jeh", XKB_KEY_Arabic_jeh },
- { "Arabic_kaf", XKB_KEY_Arabic_kaf },
- { "Arabic_kasra", XKB_KEY_Arabic_kasra },
- { "Arabic_kasratan", XKB_KEY_Arabic_kasratan },
- { "Arabic_keheh", XKB_KEY_Arabic_keheh },
- { "Arabic_khah", XKB_KEY_Arabic_khah },
- { "Arabic_lam", XKB_KEY_Arabic_lam },
- { "Arabic_madda_above", XKB_KEY_Arabic_madda_above },
- { "Arabic_maddaonalef", XKB_KEY_Arabic_maddaonalef },
- { "Arabic_meem", XKB_KEY_Arabic_meem },
- { "Arabic_noon", XKB_KEY_Arabic_noon },
- { "Arabic_noon_ghunna", XKB_KEY_Arabic_noon_ghunna },
- { "Arabic_peh", XKB_KEY_Arabic_peh },
- { "Arabic_percent", XKB_KEY_Arabic_percent },
- { "Arabic_qaf", XKB_KEY_Arabic_qaf },
- { "Arabic_question_mark", XKB_KEY_Arabic_question_mark },
- { "Arabic_ra", XKB_KEY_Arabic_ra },
- { "Arabic_rreh", XKB_KEY_Arabic_rreh },
- { "Arabic_sad", XKB_KEY_Arabic_sad },
- { "Arabic_seen", XKB_KEY_Arabic_seen },
- { "Arabic_semicolon", XKB_KEY_Arabic_semicolon },
- { "Arabic_shadda", XKB_KEY_Arabic_shadda },
- { "Arabic_sheen", XKB_KEY_Arabic_sheen },
- { "Arabic_sukun", XKB_KEY_Arabic_sukun },
- { "Arabic_superscript_alef", XKB_KEY_Arabic_superscript_alef },
- { "Arabic_switch", XKB_KEY_Arabic_switch },
- { "Arabic_tah", XKB_KEY_Arabic_tah },
- { "Arabic_tatweel", XKB_KEY_Arabic_tatweel },
- { "Arabic_tcheh", XKB_KEY_Arabic_tcheh },
- { "Arabic_teh", XKB_KEY_Arabic_teh },
- { "Arabic_tehmarbuta", XKB_KEY_Arabic_tehmarbuta },
- { "Arabic_thal", XKB_KEY_Arabic_thal },
- { "Arabic_theh", XKB_KEY_Arabic_theh },
- { "Arabic_tteh", XKB_KEY_Arabic_tteh },
- { "Arabic_veh", XKB_KEY_Arabic_veh },
- { "Arabic_waw", XKB_KEY_Arabic_waw },
- { "Arabic_yeh", XKB_KEY_Arabic_yeh },
- { "Arabic_yeh_baree", XKB_KEY_Arabic_yeh_baree },
- { "Arabic_zah", XKB_KEY_Arabic_zah },
- { "Arabic_zain", XKB_KEY_Arabic_zain },
- { "Aring", XKB_KEY_Aring },
- { "aring", XKB_KEY_aring },
- { "Armenian_accent", XKB_KEY_Armenian_accent },
- { "Armenian_amanak", XKB_KEY_Armenian_amanak },
- { "Armenian_apostrophe", XKB_KEY_Armenian_apostrophe },
- { "Armenian_AT", XKB_KEY_Armenian_AT },
- { "Armenian_at", XKB_KEY_Armenian_at },
- { "Armenian_AYB", XKB_KEY_Armenian_AYB },
- { "Armenian_ayb", XKB_KEY_Armenian_ayb },
- { "Armenian_BEN", XKB_KEY_Armenian_BEN },
- { "Armenian_ben", XKB_KEY_Armenian_ben },
- { "Armenian_but", XKB_KEY_Armenian_but },
- { "Armenian_CHA", XKB_KEY_Armenian_CHA },
- { "Armenian_cha", XKB_KEY_Armenian_cha },
- { "Armenian_DA", XKB_KEY_Armenian_DA },
- { "Armenian_da", XKB_KEY_Armenian_da },
- { "Armenian_DZA", XKB_KEY_Armenian_DZA },
- { "Armenian_dza", XKB_KEY_Armenian_dza },
- { "Armenian_E", XKB_KEY_Armenian_E },
- { "Armenian_e", XKB_KEY_Armenian_e },
- { "Armenian_exclam", XKB_KEY_Armenian_exclam },
- { "Armenian_FE", XKB_KEY_Armenian_FE },
- { "Armenian_fe", XKB_KEY_Armenian_fe },
- { "Armenian_full_stop", XKB_KEY_Armenian_full_stop },
- { "Armenian_GHAT", XKB_KEY_Armenian_GHAT },
- { "Armenian_ghat", XKB_KEY_Armenian_ghat },
- { "Armenian_GIM", XKB_KEY_Armenian_GIM },
- { "Armenian_gim", XKB_KEY_Armenian_gim },
- { "Armenian_HI", XKB_KEY_Armenian_HI },
- { "Armenian_hi", XKB_KEY_Armenian_hi },
- { "Armenian_HO", XKB_KEY_Armenian_HO },
- { "Armenian_ho", XKB_KEY_Armenian_ho },
- { "Armenian_hyphen", XKB_KEY_Armenian_hyphen },
- { "Armenian_INI", XKB_KEY_Armenian_INI },
- { "Armenian_ini", XKB_KEY_Armenian_ini },
- { "Armenian_JE", XKB_KEY_Armenian_JE },
- { "Armenian_je", XKB_KEY_Armenian_je },
- { "Armenian_KE", XKB_KEY_Armenian_KE },
- { "Armenian_ke", XKB_KEY_Armenian_ke },
- { "Armenian_KEN", XKB_KEY_Armenian_KEN },
- { "Armenian_ken", XKB_KEY_Armenian_ken },
- { "Armenian_KHE", XKB_KEY_Armenian_KHE },
- { "Armenian_khe", XKB_KEY_Armenian_khe },
- { "Armenian_ligature_ew", XKB_KEY_Armenian_ligature_ew },
- { "Armenian_LYUN", XKB_KEY_Armenian_LYUN },
- { "Armenian_lyun", XKB_KEY_Armenian_lyun },
- { "Armenian_MEN", XKB_KEY_Armenian_MEN },
- { "Armenian_men", XKB_KEY_Armenian_men },
- { "Armenian_NU", XKB_KEY_Armenian_NU },
- { "Armenian_nu", XKB_KEY_Armenian_nu },
- { "Armenian_O", XKB_KEY_Armenian_O },
- { "Armenian_o", XKB_KEY_Armenian_o },
- { "Armenian_paruyk", XKB_KEY_Armenian_paruyk },
- { "Armenian_PE", XKB_KEY_Armenian_PE },
- { "Armenian_pe", XKB_KEY_Armenian_pe },
- { "Armenian_PYUR", XKB_KEY_Armenian_PYUR },
- { "Armenian_pyur", XKB_KEY_Armenian_pyur },
- { "Armenian_question", XKB_KEY_Armenian_question },
- { "Armenian_RA", XKB_KEY_Armenian_RA },
- { "Armenian_ra", XKB_KEY_Armenian_ra },
- { "Armenian_RE", XKB_KEY_Armenian_RE },
- { "Armenian_re", XKB_KEY_Armenian_re },
- { "Armenian_SE", XKB_KEY_Armenian_SE },
- { "Armenian_se", XKB_KEY_Armenian_se },
- { "Armenian_separation_mark", XKB_KEY_Armenian_separation_mark },
- { "Armenian_SHA", XKB_KEY_Armenian_SHA },
- { "Armenian_sha", XKB_KEY_Armenian_sha },
- { "Armenian_shesht", XKB_KEY_Armenian_shesht },
- { "Armenian_TCHE", XKB_KEY_Armenian_TCHE },
- { "Armenian_tche", XKB_KEY_Armenian_tche },
- { "Armenian_TO", XKB_KEY_Armenian_TO },
- { "Armenian_to", XKB_KEY_Armenian_to },
- { "Armenian_TSA", XKB_KEY_Armenian_TSA },
- { "Armenian_tsa", XKB_KEY_Armenian_tsa },
- { "Armenian_TSO", XKB_KEY_Armenian_TSO },
- { "Armenian_tso", XKB_KEY_Armenian_tso },
- { "Armenian_TYUN", XKB_KEY_Armenian_TYUN },
- { "Armenian_tyun", XKB_KEY_Armenian_tyun },
- { "Armenian_verjaket", XKB_KEY_Armenian_verjaket },
- { "Armenian_VEV", XKB_KEY_Armenian_VEV },
- { "Armenian_vev", XKB_KEY_Armenian_vev },
- { "Armenian_VO", XKB_KEY_Armenian_VO },
- { "Armenian_vo", XKB_KEY_Armenian_vo },
- { "Armenian_VYUN", XKB_KEY_Armenian_VYUN },
- { "Armenian_vyun", XKB_KEY_Armenian_vyun },
- { "Armenian_YECH", XKB_KEY_Armenian_YECH },
- { "Armenian_yech", XKB_KEY_Armenian_yech },
- { "Armenian_yentamna", XKB_KEY_Armenian_yentamna },
- { "Armenian_ZA", XKB_KEY_Armenian_ZA },
- { "Armenian_za", XKB_KEY_Armenian_za },
- { "Armenian_ZHE", XKB_KEY_Armenian_ZHE },
- { "Armenian_zhe", XKB_KEY_Armenian_zhe },
- { "asciicircum", XKB_KEY_asciicircum },
- { "asciitilde", XKB_KEY_asciitilde },
- { "asterisk", XKB_KEY_asterisk },
- { "at", XKB_KEY_at },
- { "Atilde", XKB_KEY_Atilde },
- { "atilde", XKB_KEY_atilde },
- { "AudibleBell_Enable", XKB_KEY_AudibleBell_Enable },
- { "B", XKB_KEY_B },
- { "b", XKB_KEY_b },
- { "Babovedot", XKB_KEY_Babovedot },
- { "babovedot", XKB_KEY_babovedot },
- { "backslash", XKB_KEY_backslash },
- { "BackSpace", XKB_KEY_BackSpace },
- { "BackTab", XKB_KEY_BackTab },
- { "ballotcross", XKB_KEY_ballotcross },
- { "bar", XKB_KEY_bar },
- { "because", XKB_KEY_because },
- { "Begin", XKB_KEY_Begin },
- { "blank", XKB_KEY_blank },
- { "block", XKB_KEY_block },
- { "botintegral", XKB_KEY_botintegral },
- { "botleftparens", XKB_KEY_botleftparens },
- { "botleftsqbracket", XKB_KEY_botleftsqbracket },
- { "botleftsummation", XKB_KEY_botleftsummation },
- { "botrightparens", XKB_KEY_botrightparens },
- { "botrightsqbracket", XKB_KEY_botrightsqbracket },
- { "botrightsummation", XKB_KEY_botrightsummation },
- { "bott", XKB_KEY_bott },
- { "botvertsummationconnector", XKB_KEY_botvertsummationconnector },
- { "BounceKeys_Enable", XKB_KEY_BounceKeys_Enable },
- { "braceleft", XKB_KEY_braceleft },
- { "braceright", XKB_KEY_braceright },
- { "bracketleft", XKB_KEY_bracketleft },
- { "bracketright", XKB_KEY_bracketright },
- { "braille_blank", XKB_KEY_braille_blank },
- { "braille_dot_1", XKB_KEY_braille_dot_1 },
- { "braille_dot_10", XKB_KEY_braille_dot_10 },
- { "braille_dot_2", XKB_KEY_braille_dot_2 },
- { "braille_dot_3", XKB_KEY_braille_dot_3 },
- { "braille_dot_4", XKB_KEY_braille_dot_4 },
- { "braille_dot_5", XKB_KEY_braille_dot_5 },
- { "braille_dot_6", XKB_KEY_braille_dot_6 },
- { "braille_dot_7", XKB_KEY_braille_dot_7 },
- { "braille_dot_8", XKB_KEY_braille_dot_8 },
- { "braille_dot_9", XKB_KEY_braille_dot_9 },
- { "braille_dots_1", XKB_KEY_braille_dots_1 },
- { "braille_dots_12", XKB_KEY_braille_dots_12 },
- { "braille_dots_123", XKB_KEY_braille_dots_123 },
- { "braille_dots_1234", XKB_KEY_braille_dots_1234 },
- { "braille_dots_12345", XKB_KEY_braille_dots_12345 },
- { "braille_dots_123456", XKB_KEY_braille_dots_123456 },
- { "braille_dots_1234567", XKB_KEY_braille_dots_1234567 },
- { "braille_dots_12345678", XKB_KEY_braille_dots_12345678 },
- { "braille_dots_1234568", XKB_KEY_braille_dots_1234568 },
- { "braille_dots_123457", XKB_KEY_braille_dots_123457 },
- { "braille_dots_1234578", XKB_KEY_braille_dots_1234578 },
- { "braille_dots_123458", XKB_KEY_braille_dots_123458 },
- { "braille_dots_12346", XKB_KEY_braille_dots_12346 },
- { "braille_dots_123467", XKB_KEY_braille_dots_123467 },
- { "braille_dots_1234678", XKB_KEY_braille_dots_1234678 },
- { "braille_dots_123468", XKB_KEY_braille_dots_123468 },
- { "braille_dots_12347", XKB_KEY_braille_dots_12347 },
- { "braille_dots_123478", XKB_KEY_braille_dots_123478 },
- { "braille_dots_12348", XKB_KEY_braille_dots_12348 },
- { "braille_dots_1235", XKB_KEY_braille_dots_1235 },
- { "braille_dots_12356", XKB_KEY_braille_dots_12356 },
- { "braille_dots_123567", XKB_KEY_braille_dots_123567 },
- { "braille_dots_1235678", XKB_KEY_braille_dots_1235678 },
- { "braille_dots_123568", XKB_KEY_braille_dots_123568 },
- { "braille_dots_12357", XKB_KEY_braille_dots_12357 },
- { "braille_dots_123578", XKB_KEY_braille_dots_123578 },
- { "braille_dots_12358", XKB_KEY_braille_dots_12358 },
- { "braille_dots_1236", XKB_KEY_braille_dots_1236 },
- { "braille_dots_12367", XKB_KEY_braille_dots_12367 },
- { "braille_dots_123678", XKB_KEY_braille_dots_123678 },
- { "braille_dots_12368", XKB_KEY_braille_dots_12368 },
- { "braille_dots_1237", XKB_KEY_braille_dots_1237 },
- { "braille_dots_12378", XKB_KEY_braille_dots_12378 },
- { "braille_dots_1238", XKB_KEY_braille_dots_1238 },
- { "braille_dots_124", XKB_KEY_braille_dots_124 },
- { "braille_dots_1245", XKB_KEY_braille_dots_1245 },
- { "braille_dots_12456", XKB_KEY_braille_dots_12456 },
- { "braille_dots_124567", XKB_KEY_braille_dots_124567 },
- { "braille_dots_1245678", XKB_KEY_braille_dots_1245678 },
- { "braille_dots_124568", XKB_KEY_braille_dots_124568 },
- { "braille_dots_12457", XKB_KEY_braille_dots_12457 },
- { "braille_dots_124578", XKB_KEY_braille_dots_124578 },
- { "braille_dots_12458", XKB_KEY_braille_dots_12458 },
- { "braille_dots_1246", XKB_KEY_braille_dots_1246 },
- { "braille_dots_12467", XKB_KEY_braille_dots_12467 },
- { "braille_dots_124678", XKB_KEY_braille_dots_124678 },
- { "braille_dots_12468", XKB_KEY_braille_dots_12468 },
- { "braille_dots_1247", XKB_KEY_braille_dots_1247 },
- { "braille_dots_12478", XKB_KEY_braille_dots_12478 },
- { "braille_dots_1248", XKB_KEY_braille_dots_1248 },
- { "braille_dots_125", XKB_KEY_braille_dots_125 },
- { "braille_dots_1256", XKB_KEY_braille_dots_1256 },
- { "braille_dots_12567", XKB_KEY_braille_dots_12567 },
- { "braille_dots_125678", XKB_KEY_braille_dots_125678 },
- { "braille_dots_12568", XKB_KEY_braille_dots_12568 },
- { "braille_dots_1257", XKB_KEY_braille_dots_1257 },
- { "braille_dots_12578", XKB_KEY_braille_dots_12578 },
- { "braille_dots_1258", XKB_KEY_braille_dots_1258 },
- { "braille_dots_126", XKB_KEY_braille_dots_126 },
- { "braille_dots_1267", XKB_KEY_braille_dots_1267 },
- { "braille_dots_12678", XKB_KEY_braille_dots_12678 },
- { "braille_dots_1268", XKB_KEY_braille_dots_1268 },
- { "braille_dots_127", XKB_KEY_braille_dots_127 },
- { "braille_dots_1278", XKB_KEY_braille_dots_1278 },
- { "braille_dots_128", XKB_KEY_braille_dots_128 },
- { "braille_dots_13", XKB_KEY_braille_dots_13 },
- { "braille_dots_134", XKB_KEY_braille_dots_134 },
- { "braille_dots_1345", XKB_KEY_braille_dots_1345 },
- { "braille_dots_13456", XKB_KEY_braille_dots_13456 },
- { "braille_dots_134567", XKB_KEY_braille_dots_134567 },
- { "braille_dots_1345678", XKB_KEY_braille_dots_1345678 },
- { "braille_dots_134568", XKB_KEY_braille_dots_134568 },
- { "braille_dots_13457", XKB_KEY_braille_dots_13457 },
- { "braille_dots_134578", XKB_KEY_braille_dots_134578 },
- { "braille_dots_13458", XKB_KEY_braille_dots_13458 },
- { "braille_dots_1346", XKB_KEY_braille_dots_1346 },
- { "braille_dots_13467", XKB_KEY_braille_dots_13467 },
- { "braille_dots_134678", XKB_KEY_braille_dots_134678 },
- { "braille_dots_13468", XKB_KEY_braille_dots_13468 },
- { "braille_dots_1347", XKB_KEY_braille_dots_1347 },
- { "braille_dots_13478", XKB_KEY_braille_dots_13478 },
- { "braille_dots_1348", XKB_KEY_braille_dots_1348 },
- { "braille_dots_135", XKB_KEY_braille_dots_135 },
- { "braille_dots_1356", XKB_KEY_braille_dots_1356 },
- { "braille_dots_13567", XKB_KEY_braille_dots_13567 },
- { "braille_dots_135678", XKB_KEY_braille_dots_135678 },
- { "braille_dots_13568", XKB_KEY_braille_dots_13568 },
- { "braille_dots_1357", XKB_KEY_braille_dots_1357 },
- { "braille_dots_13578", XKB_KEY_braille_dots_13578 },
- { "braille_dots_1358", XKB_KEY_braille_dots_1358 },
- { "braille_dots_136", XKB_KEY_braille_dots_136 },
- { "braille_dots_1367", XKB_KEY_braille_dots_1367 },
- { "braille_dots_13678", XKB_KEY_braille_dots_13678 },
- { "braille_dots_1368", XKB_KEY_braille_dots_1368 },
- { "braille_dots_137", XKB_KEY_braille_dots_137 },
- { "braille_dots_1378", XKB_KEY_braille_dots_1378 },
- { "braille_dots_138", XKB_KEY_braille_dots_138 },
- { "braille_dots_14", XKB_KEY_braille_dots_14 },
- { "braille_dots_145", XKB_KEY_braille_dots_145 },
- { "braille_dots_1456", XKB_KEY_braille_dots_1456 },
- { "braille_dots_14567", XKB_KEY_braille_dots_14567 },
- { "braille_dots_145678", XKB_KEY_braille_dots_145678 },
- { "braille_dots_14568", XKB_KEY_braille_dots_14568 },
- { "braille_dots_1457", XKB_KEY_braille_dots_1457 },
- { "braille_dots_14578", XKB_KEY_braille_dots_14578 },
- { "braille_dots_1458", XKB_KEY_braille_dots_1458 },
- { "braille_dots_146", XKB_KEY_braille_dots_146 },
- { "braille_dots_1467", XKB_KEY_braille_dots_1467 },
- { "braille_dots_14678", XKB_KEY_braille_dots_14678 },
- { "braille_dots_1468", XKB_KEY_braille_dots_1468 },
- { "braille_dots_147", XKB_KEY_braille_dots_147 },
- { "braille_dots_1478", XKB_KEY_braille_dots_1478 },
- { "braille_dots_148", XKB_KEY_braille_dots_148 },
- { "braille_dots_15", XKB_KEY_braille_dots_15 },
- { "braille_dots_156", XKB_KEY_braille_dots_156 },
- { "braille_dots_1567", XKB_KEY_braille_dots_1567 },
- { "braille_dots_15678", XKB_KEY_braille_dots_15678 },
- { "braille_dots_1568", XKB_KEY_braille_dots_1568 },
- { "braille_dots_157", XKB_KEY_braille_dots_157 },
- { "braille_dots_1578", XKB_KEY_braille_dots_1578 },
- { "braille_dots_158", XKB_KEY_braille_dots_158 },
- { "braille_dots_16", XKB_KEY_braille_dots_16 },
- { "braille_dots_167", XKB_KEY_braille_dots_167 },
- { "braille_dots_1678", XKB_KEY_braille_dots_1678 },
- { "braille_dots_168", XKB_KEY_braille_dots_168 },
- { "braille_dots_17", XKB_KEY_braille_dots_17 },
- { "braille_dots_178", XKB_KEY_braille_dots_178 },
- { "braille_dots_18", XKB_KEY_braille_dots_18 },
- { "braille_dots_2", XKB_KEY_braille_dots_2 },
- { "braille_dots_23", XKB_KEY_braille_dots_23 },
- { "braille_dots_234", XKB_KEY_braille_dots_234 },
- { "braille_dots_2345", XKB_KEY_braille_dots_2345 },
- { "braille_dots_23456", XKB_KEY_braille_dots_23456 },
- { "braille_dots_234567", XKB_KEY_braille_dots_234567 },
- { "braille_dots_2345678", XKB_KEY_braille_dots_2345678 },
- { "braille_dots_234568", XKB_KEY_braille_dots_234568 },
- { "braille_dots_23457", XKB_KEY_braille_dots_23457 },
- { "braille_dots_234578", XKB_KEY_braille_dots_234578 },
- { "braille_dots_23458", XKB_KEY_braille_dots_23458 },
- { "braille_dots_2346", XKB_KEY_braille_dots_2346 },
- { "braille_dots_23467", XKB_KEY_braille_dots_23467 },
- { "braille_dots_234678", XKB_KEY_braille_dots_234678 },
- { "braille_dots_23468", XKB_KEY_braille_dots_23468 },
- { "braille_dots_2347", XKB_KEY_braille_dots_2347 },
- { "braille_dots_23478", XKB_KEY_braille_dots_23478 },
- { "braille_dots_2348", XKB_KEY_braille_dots_2348 },
- { "braille_dots_235", XKB_KEY_braille_dots_235 },
- { "braille_dots_2356", XKB_KEY_braille_dots_2356 },
- { "braille_dots_23567", XKB_KEY_braille_dots_23567 },
- { "braille_dots_235678", XKB_KEY_braille_dots_235678 },
- { "braille_dots_23568", XKB_KEY_braille_dots_23568 },
- { "braille_dots_2357", XKB_KEY_braille_dots_2357 },
- { "braille_dots_23578", XKB_KEY_braille_dots_23578 },
- { "braille_dots_2358", XKB_KEY_braille_dots_2358 },
- { "braille_dots_236", XKB_KEY_braille_dots_236 },
- { "braille_dots_2367", XKB_KEY_braille_dots_2367 },
- { "braille_dots_23678", XKB_KEY_braille_dots_23678 },
- { "braille_dots_2368", XKB_KEY_braille_dots_2368 },
- { "braille_dots_237", XKB_KEY_braille_dots_237 },
- { "braille_dots_2378", XKB_KEY_braille_dots_2378 },
- { "braille_dots_238", XKB_KEY_braille_dots_238 },
- { "braille_dots_24", XKB_KEY_braille_dots_24 },
- { "braille_dots_245", XKB_KEY_braille_dots_245 },
- { "braille_dots_2456", XKB_KEY_braille_dots_2456 },
- { "braille_dots_24567", XKB_KEY_braille_dots_24567 },
- { "braille_dots_245678", XKB_KEY_braille_dots_245678 },
- { "braille_dots_24568", XKB_KEY_braille_dots_24568 },
- { "braille_dots_2457", XKB_KEY_braille_dots_2457 },
- { "braille_dots_24578", XKB_KEY_braille_dots_24578 },
- { "braille_dots_2458", XKB_KEY_braille_dots_2458 },
- { "braille_dots_246", XKB_KEY_braille_dots_246 },
- { "braille_dots_2467", XKB_KEY_braille_dots_2467 },
- { "braille_dots_24678", XKB_KEY_braille_dots_24678 },
- { "braille_dots_2468", XKB_KEY_braille_dots_2468 },
- { "braille_dots_247", XKB_KEY_braille_dots_247 },
- { "braille_dots_2478", XKB_KEY_braille_dots_2478 },
- { "braille_dots_248", XKB_KEY_braille_dots_248 },
- { "braille_dots_25", XKB_KEY_braille_dots_25 },
- { "braille_dots_256", XKB_KEY_braille_dots_256 },
- { "braille_dots_2567", XKB_KEY_braille_dots_2567 },
- { "braille_dots_25678", XKB_KEY_braille_dots_25678 },
- { "braille_dots_2568", XKB_KEY_braille_dots_2568 },
- { "braille_dots_257", XKB_KEY_braille_dots_257 },
- { "braille_dots_2578", XKB_KEY_braille_dots_2578 },
- { "braille_dots_258", XKB_KEY_braille_dots_258 },
- { "braille_dots_26", XKB_KEY_braille_dots_26 },
- { "braille_dots_267", XKB_KEY_braille_dots_267 },
- { "braille_dots_2678", XKB_KEY_braille_dots_2678 },
- { "braille_dots_268", XKB_KEY_braille_dots_268 },
- { "braille_dots_27", XKB_KEY_braille_dots_27 },
- { "braille_dots_278", XKB_KEY_braille_dots_278 },
- { "braille_dots_28", XKB_KEY_braille_dots_28 },
- { "braille_dots_3", XKB_KEY_braille_dots_3 },
- { "braille_dots_34", XKB_KEY_braille_dots_34 },
- { "braille_dots_345", XKB_KEY_braille_dots_345 },
- { "braille_dots_3456", XKB_KEY_braille_dots_3456 },
- { "braille_dots_34567", XKB_KEY_braille_dots_34567 },
- { "braille_dots_345678", XKB_KEY_braille_dots_345678 },
- { "braille_dots_34568", XKB_KEY_braille_dots_34568 },
- { "braille_dots_3457", XKB_KEY_braille_dots_3457 },
- { "braille_dots_34578", XKB_KEY_braille_dots_34578 },
- { "braille_dots_3458", XKB_KEY_braille_dots_3458 },
- { "braille_dots_346", XKB_KEY_braille_dots_346 },
- { "braille_dots_3467", XKB_KEY_braille_dots_3467 },
- { "braille_dots_34678", XKB_KEY_braille_dots_34678 },
- { "braille_dots_3468", XKB_KEY_braille_dots_3468 },
- { "braille_dots_347", XKB_KEY_braille_dots_347 },
- { "braille_dots_3478", XKB_KEY_braille_dots_3478 },
- { "braille_dots_348", XKB_KEY_braille_dots_348 },
- { "braille_dots_35", XKB_KEY_braille_dots_35 },
- { "braille_dots_356", XKB_KEY_braille_dots_356 },
- { "braille_dots_3567", XKB_KEY_braille_dots_3567 },
- { "braille_dots_35678", XKB_KEY_braille_dots_35678 },
- { "braille_dots_3568", XKB_KEY_braille_dots_3568 },
- { "braille_dots_357", XKB_KEY_braille_dots_357 },
- { "braille_dots_3578", XKB_KEY_braille_dots_3578 },
- { "braille_dots_358", XKB_KEY_braille_dots_358 },
- { "braille_dots_36", XKB_KEY_braille_dots_36 },
- { "braille_dots_367", XKB_KEY_braille_dots_367 },
- { "braille_dots_3678", XKB_KEY_braille_dots_3678 },
- { "braille_dots_368", XKB_KEY_braille_dots_368 },
- { "braille_dots_37", XKB_KEY_braille_dots_37 },
- { "braille_dots_378", XKB_KEY_braille_dots_378 },
- { "braille_dots_38", XKB_KEY_braille_dots_38 },
- { "braille_dots_4", XKB_KEY_braille_dots_4 },
- { "braille_dots_45", XKB_KEY_braille_dots_45 },
- { "braille_dots_456", XKB_KEY_braille_dots_456 },
- { "braille_dots_4567", XKB_KEY_braille_dots_4567 },
- { "braille_dots_45678", XKB_KEY_braille_dots_45678 },
- { "braille_dots_4568", XKB_KEY_braille_dots_4568 },
- { "braille_dots_457", XKB_KEY_braille_dots_457 },
- { "braille_dots_4578", XKB_KEY_braille_dots_4578 },
- { "braille_dots_458", XKB_KEY_braille_dots_458 },
- { "braille_dots_46", XKB_KEY_braille_dots_46 },
- { "braille_dots_467", XKB_KEY_braille_dots_467 },
- { "braille_dots_4678", XKB_KEY_braille_dots_4678 },
- { "braille_dots_468", XKB_KEY_braille_dots_468 },
- { "braille_dots_47", XKB_KEY_braille_dots_47 },
- { "braille_dots_478", XKB_KEY_braille_dots_478 },
- { "braille_dots_48", XKB_KEY_braille_dots_48 },
- { "braille_dots_5", XKB_KEY_braille_dots_5 },
- { "braille_dots_56", XKB_KEY_braille_dots_56 },
- { "braille_dots_567", XKB_KEY_braille_dots_567 },
- { "braille_dots_5678", XKB_KEY_braille_dots_5678 },
- { "braille_dots_568", XKB_KEY_braille_dots_568 },
- { "braille_dots_57", XKB_KEY_braille_dots_57 },
- { "braille_dots_578", XKB_KEY_braille_dots_578 },
- { "braille_dots_58", XKB_KEY_braille_dots_58 },
- { "braille_dots_6", XKB_KEY_braille_dots_6 },
- { "braille_dots_67", XKB_KEY_braille_dots_67 },
- { "braille_dots_678", XKB_KEY_braille_dots_678 },
- { "braille_dots_68", XKB_KEY_braille_dots_68 },
- { "braille_dots_7", XKB_KEY_braille_dots_7 },
- { "braille_dots_78", XKB_KEY_braille_dots_78 },
- { "braille_dots_8", XKB_KEY_braille_dots_8 },
- { "Break", XKB_KEY_Break },
- { "breve", XKB_KEY_breve },
- { "brokenbar", XKB_KEY_brokenbar },
- { "Byelorussian_shortu", XKB_KEY_Byelorussian_shortu },
- { "Byelorussian_SHORTU", XKB_KEY_Byelorussian_SHORTU },
- { "C", XKB_KEY_C },
- { "c", XKB_KEY_c },
- { "c_h", XKB_KEY_c_h },
- { "C_h", XKB_KEY_C_h },
- { "C_H", XKB_KEY_C_H },
- { "Cabovedot", XKB_KEY_Cabovedot },
- { "cabovedot", XKB_KEY_cabovedot },
- { "Cacute", XKB_KEY_Cacute },
- { "cacute", XKB_KEY_cacute },
- { "Cancel", XKB_KEY_Cancel },
- { "Caps_Lock", XKB_KEY_Caps_Lock },
- { "careof", XKB_KEY_careof },
- { "caret", XKB_KEY_caret },
- { "caron", XKB_KEY_caron },
- { "Ccaron", XKB_KEY_Ccaron },
- { "ccaron", XKB_KEY_ccaron },
- { "Ccedilla", XKB_KEY_Ccedilla },
- { "ccedilla", XKB_KEY_ccedilla },
- { "Ccircumflex", XKB_KEY_Ccircumflex },
- { "ccircumflex", XKB_KEY_ccircumflex },
- { "cedilla", XKB_KEY_cedilla },
- { "cent", XKB_KEY_cent },
- { "ch", XKB_KEY_ch },
- { "Ch", XKB_KEY_Ch },
- { "CH", XKB_KEY_CH },
- { "checkerboard", XKB_KEY_checkerboard },
- { "checkmark", XKB_KEY_checkmark },
- { "circle", XKB_KEY_circle },
- { "Clear", XKB_KEY_Clear },
- { "ClearLine", XKB_KEY_ClearLine },
- { "club", XKB_KEY_club },
- { "Codeinput", XKB_KEY_Codeinput },
- { "colon", XKB_KEY_colon },
- { "ColonSign", XKB_KEY_ColonSign },
- { "comma", XKB_KEY_comma },
- { "containsas", XKB_KEY_containsas },
- { "Control_L", XKB_KEY_Control_L },
- { "Control_R", XKB_KEY_Control_R },
- { "copyright", XKB_KEY_copyright },
- { "cr", XKB_KEY_cr },
- { "crossinglines", XKB_KEY_crossinglines },
- { "CruzeiroSign", XKB_KEY_CruzeiroSign },
- { "cuberoot", XKB_KEY_cuberoot },
- { "currency", XKB_KEY_currency },
- { "cursor", XKB_KEY_cursor },
- { "Cyrillic_a", XKB_KEY_Cyrillic_a },
- { "Cyrillic_A", XKB_KEY_Cyrillic_A },
- { "Cyrillic_be", XKB_KEY_Cyrillic_be },
- { "Cyrillic_BE", XKB_KEY_Cyrillic_BE },
- { "Cyrillic_che", XKB_KEY_Cyrillic_che },
- { "Cyrillic_CHE", XKB_KEY_Cyrillic_CHE },
- { "Cyrillic_CHE_descender", XKB_KEY_Cyrillic_CHE_descender },
- { "Cyrillic_che_descender", XKB_KEY_Cyrillic_che_descender },
- { "Cyrillic_CHE_vertstroke", XKB_KEY_Cyrillic_CHE_vertstroke },
- { "Cyrillic_che_vertstroke", XKB_KEY_Cyrillic_che_vertstroke },
- { "Cyrillic_de", XKB_KEY_Cyrillic_de },
- { "Cyrillic_DE", XKB_KEY_Cyrillic_DE },
- { "Cyrillic_dzhe", XKB_KEY_Cyrillic_dzhe },
- { "Cyrillic_DZHE", XKB_KEY_Cyrillic_DZHE },
- { "Cyrillic_e", XKB_KEY_Cyrillic_e },
- { "Cyrillic_E", XKB_KEY_Cyrillic_E },
- { "Cyrillic_ef", XKB_KEY_Cyrillic_ef },
- { "Cyrillic_EF", XKB_KEY_Cyrillic_EF },
- { "Cyrillic_el", XKB_KEY_Cyrillic_el },
- { "Cyrillic_EL", XKB_KEY_Cyrillic_EL },
- { "Cyrillic_em", XKB_KEY_Cyrillic_em },
- { "Cyrillic_EM", XKB_KEY_Cyrillic_EM },
- { "Cyrillic_en", XKB_KEY_Cyrillic_en },
- { "Cyrillic_EN", XKB_KEY_Cyrillic_EN },
- { "Cyrillic_EN_descender", XKB_KEY_Cyrillic_EN_descender },
- { "Cyrillic_en_descender", XKB_KEY_Cyrillic_en_descender },
- { "Cyrillic_er", XKB_KEY_Cyrillic_er },
- { "Cyrillic_ER", XKB_KEY_Cyrillic_ER },
- { "Cyrillic_es", XKB_KEY_Cyrillic_es },
- { "Cyrillic_ES", XKB_KEY_Cyrillic_ES },
- { "Cyrillic_ghe", XKB_KEY_Cyrillic_ghe },
- { "Cyrillic_GHE", XKB_KEY_Cyrillic_GHE },
- { "Cyrillic_GHE_bar", XKB_KEY_Cyrillic_GHE_bar },
- { "Cyrillic_ghe_bar", XKB_KEY_Cyrillic_ghe_bar },
- { "Cyrillic_ha", XKB_KEY_Cyrillic_ha },
- { "Cyrillic_HA", XKB_KEY_Cyrillic_HA },
- { "Cyrillic_HA_descender", XKB_KEY_Cyrillic_HA_descender },
- { "Cyrillic_ha_descender", XKB_KEY_Cyrillic_ha_descender },
- { "Cyrillic_hardsign", XKB_KEY_Cyrillic_hardsign },
- { "Cyrillic_HARDSIGN", XKB_KEY_Cyrillic_HARDSIGN },
- { "Cyrillic_i", XKB_KEY_Cyrillic_i },
- { "Cyrillic_I", XKB_KEY_Cyrillic_I },
- { "Cyrillic_I_macron", XKB_KEY_Cyrillic_I_macron },
- { "Cyrillic_i_macron", XKB_KEY_Cyrillic_i_macron },
- { "Cyrillic_ie", XKB_KEY_Cyrillic_ie },
- { "Cyrillic_IE", XKB_KEY_Cyrillic_IE },
- { "Cyrillic_io", XKB_KEY_Cyrillic_io },
- { "Cyrillic_IO", XKB_KEY_Cyrillic_IO },
- { "Cyrillic_je", XKB_KEY_Cyrillic_je },
- { "Cyrillic_JE", XKB_KEY_Cyrillic_JE },
- { "Cyrillic_ka", XKB_KEY_Cyrillic_ka },
- { "Cyrillic_KA", XKB_KEY_Cyrillic_KA },
- { "Cyrillic_KA_descender", XKB_KEY_Cyrillic_KA_descender },
- { "Cyrillic_ka_descender", XKB_KEY_Cyrillic_ka_descender },
- { "Cyrillic_KA_vertstroke", XKB_KEY_Cyrillic_KA_vertstroke },
- { "Cyrillic_ka_vertstroke", XKB_KEY_Cyrillic_ka_vertstroke },
- { "Cyrillic_lje", XKB_KEY_Cyrillic_lje },
- { "Cyrillic_LJE", XKB_KEY_Cyrillic_LJE },
- { "Cyrillic_nje", XKB_KEY_Cyrillic_nje },
- { "Cyrillic_NJE", XKB_KEY_Cyrillic_NJE },
- { "Cyrillic_o", XKB_KEY_Cyrillic_o },
- { "Cyrillic_O", XKB_KEY_Cyrillic_O },
- { "Cyrillic_O_bar", XKB_KEY_Cyrillic_O_bar },
- { "Cyrillic_o_bar", XKB_KEY_Cyrillic_o_bar },
- { "Cyrillic_pe", XKB_KEY_Cyrillic_pe },
- { "Cyrillic_PE", XKB_KEY_Cyrillic_PE },
- { "Cyrillic_SCHWA", XKB_KEY_Cyrillic_SCHWA },
- { "Cyrillic_schwa", XKB_KEY_Cyrillic_schwa },
- { "Cyrillic_sha", XKB_KEY_Cyrillic_sha },
- { "Cyrillic_SHA", XKB_KEY_Cyrillic_SHA },
- { "Cyrillic_shcha", XKB_KEY_Cyrillic_shcha },
- { "Cyrillic_SHCHA", XKB_KEY_Cyrillic_SHCHA },
- { "Cyrillic_SHHA", XKB_KEY_Cyrillic_SHHA },
- { "Cyrillic_shha", XKB_KEY_Cyrillic_shha },
- { "Cyrillic_shorti", XKB_KEY_Cyrillic_shorti },
- { "Cyrillic_SHORTI", XKB_KEY_Cyrillic_SHORTI },
- { "Cyrillic_softsign", XKB_KEY_Cyrillic_softsign },
- { "Cyrillic_SOFTSIGN", XKB_KEY_Cyrillic_SOFTSIGN },
- { "Cyrillic_te", XKB_KEY_Cyrillic_te },
- { "Cyrillic_TE", XKB_KEY_Cyrillic_TE },
- { "Cyrillic_tse", XKB_KEY_Cyrillic_tse },
- { "Cyrillic_TSE", XKB_KEY_Cyrillic_TSE },
- { "Cyrillic_u", XKB_KEY_Cyrillic_u },
- { "Cyrillic_U", XKB_KEY_Cyrillic_U },
- { "Cyrillic_U_macron", XKB_KEY_Cyrillic_U_macron },
- { "Cyrillic_u_macron", XKB_KEY_Cyrillic_u_macron },
- { "Cyrillic_U_straight", XKB_KEY_Cyrillic_U_straight },
- { "Cyrillic_u_straight", XKB_KEY_Cyrillic_u_straight },
- { "Cyrillic_U_straight_bar", XKB_KEY_Cyrillic_U_straight_bar },
- { "Cyrillic_u_straight_bar", XKB_KEY_Cyrillic_u_straight_bar },
- { "Cyrillic_ve", XKB_KEY_Cyrillic_ve },
- { "Cyrillic_VE", XKB_KEY_Cyrillic_VE },
- { "Cyrillic_ya", XKB_KEY_Cyrillic_ya },
- { "Cyrillic_YA", XKB_KEY_Cyrillic_YA },
- { "Cyrillic_yeru", XKB_KEY_Cyrillic_yeru },
- { "Cyrillic_YERU", XKB_KEY_Cyrillic_YERU },
- { "Cyrillic_yu", XKB_KEY_Cyrillic_yu },
- { "Cyrillic_YU", XKB_KEY_Cyrillic_YU },
- { "Cyrillic_ze", XKB_KEY_Cyrillic_ze },
- { "Cyrillic_ZE", XKB_KEY_Cyrillic_ZE },
- { "Cyrillic_zhe", XKB_KEY_Cyrillic_zhe },
- { "Cyrillic_ZHE", XKB_KEY_Cyrillic_ZHE },
- { "Cyrillic_ZHE_descender", XKB_KEY_Cyrillic_ZHE_descender },
- { "Cyrillic_zhe_descender", XKB_KEY_Cyrillic_zhe_descender },
- { "D", XKB_KEY_D },
- { "d", XKB_KEY_d },
- { "Dabovedot", XKB_KEY_Dabovedot },
- { "dabovedot", XKB_KEY_dabovedot },
- { "Dacute_accent", XKB_KEY_Dacute_accent },
- { "dagger", XKB_KEY_dagger },
- { "Dcaron", XKB_KEY_Dcaron },
- { "dcaron", XKB_KEY_dcaron },
- { "Dcedilla_accent", XKB_KEY_Dcedilla_accent },
- { "Dcircumflex_accent", XKB_KEY_Dcircumflex_accent },
- { "Ddiaeresis", XKB_KEY_Ddiaeresis },
- { "dead_a", XKB_KEY_dead_a },
- { "dead_A", XKB_KEY_dead_A },
- { "dead_abovecomma", XKB_KEY_dead_abovecomma },
- { "dead_abovedot", XKB_KEY_dead_abovedot },
- { "dead_abovereversedcomma", XKB_KEY_dead_abovereversedcomma },
- { "dead_abovering", XKB_KEY_dead_abovering },
- { "dead_acute", XKB_KEY_dead_acute },
- { "dead_belowbreve", XKB_KEY_dead_belowbreve },
- { "dead_belowcircumflex", XKB_KEY_dead_belowcircumflex },
- { "dead_belowcomma", XKB_KEY_dead_belowcomma },
- { "dead_belowdiaeresis", XKB_KEY_dead_belowdiaeresis },
- { "dead_belowdot", XKB_KEY_dead_belowdot },
- { "dead_belowmacron", XKB_KEY_dead_belowmacron },
- { "dead_belowring", XKB_KEY_dead_belowring },
- { "dead_belowtilde", XKB_KEY_dead_belowtilde },
- { "dead_breve", XKB_KEY_dead_breve },
- { "dead_capital_schwa", XKB_KEY_dead_capital_schwa },
- { "dead_caron", XKB_KEY_dead_caron },
- { "dead_cedilla", XKB_KEY_dead_cedilla },
- { "dead_circumflex", XKB_KEY_dead_circumflex },
- { "dead_currency", XKB_KEY_dead_currency },
- { "dead_dasia", XKB_KEY_dead_dasia },
- { "dead_diaeresis", XKB_KEY_dead_diaeresis },
- { "dead_doubleacute", XKB_KEY_dead_doubleacute },
- { "dead_doublegrave", XKB_KEY_dead_doublegrave },
- { "dead_e", XKB_KEY_dead_e },
- { "dead_E", XKB_KEY_dead_E },
- { "dead_grave", XKB_KEY_dead_grave },
- { "dead_greek", XKB_KEY_dead_greek },
- { "dead_hook", XKB_KEY_dead_hook },
- { "dead_horn", XKB_KEY_dead_horn },
- { "dead_i", XKB_KEY_dead_i },
- { "dead_I", XKB_KEY_dead_I },
- { "dead_invertedbreve", XKB_KEY_dead_invertedbreve },
- { "dead_iota", XKB_KEY_dead_iota },
- { "dead_macron", XKB_KEY_dead_macron },
- { "dead_o", XKB_KEY_dead_o },
- { "dead_O", XKB_KEY_dead_O },
- { "dead_ogonek", XKB_KEY_dead_ogonek },
- { "dead_perispomeni", XKB_KEY_dead_perispomeni },
- { "dead_psili", XKB_KEY_dead_psili },
- { "dead_semivoiced_sound", XKB_KEY_dead_semivoiced_sound },
- { "dead_small_schwa", XKB_KEY_dead_small_schwa },
- { "dead_stroke", XKB_KEY_dead_stroke },
- { "dead_tilde", XKB_KEY_dead_tilde },
- { "dead_u", XKB_KEY_dead_u },
- { "dead_U", XKB_KEY_dead_U },
- { "dead_voiced_sound", XKB_KEY_dead_voiced_sound },
- { "decimalpoint", XKB_KEY_decimalpoint },
- { "degree", XKB_KEY_degree },
- { "Delete", XKB_KEY_Delete },
- { "DeleteChar", XKB_KEY_DeleteChar },
- { "DeleteLine", XKB_KEY_DeleteLine },
- { "Dgrave_accent", XKB_KEY_Dgrave_accent },
- { "diaeresis", XKB_KEY_diaeresis },
- { "diamond", XKB_KEY_diamond },
- { "digitspace", XKB_KEY_digitspace },
- { "dintegral", XKB_KEY_dintegral },
- { "division", XKB_KEY_division },
- { "dollar", XKB_KEY_dollar },
- { "DongSign", XKB_KEY_DongSign },
- { "doubbaselinedot", XKB_KEY_doubbaselinedot },
- { "doubleacute", XKB_KEY_doubleacute },
- { "doubledagger", XKB_KEY_doubledagger },
- { "doublelowquotemark", XKB_KEY_doublelowquotemark },
- { "Down", XKB_KEY_Down },
- { "downarrow", XKB_KEY_downarrow },
- { "downcaret", XKB_KEY_downcaret },
- { "downshoe", XKB_KEY_downshoe },
- { "downstile", XKB_KEY_downstile },
- { "downtack", XKB_KEY_downtack },
- { "DRemove", XKB_KEY_DRemove },
- { "Dring_accent", XKB_KEY_Dring_accent },
- { "Dstroke", XKB_KEY_Dstroke },
- { "dstroke", XKB_KEY_dstroke },
- { "Dtilde", XKB_KEY_Dtilde },
- { "E", XKB_KEY_E },
- { "e", XKB_KEY_e },
- { "Eabovedot", XKB_KEY_Eabovedot },
- { "eabovedot", XKB_KEY_eabovedot },
- { "Eacute", XKB_KEY_Eacute },
- { "eacute", XKB_KEY_eacute },
- { "Ebelowdot", XKB_KEY_Ebelowdot },
- { "ebelowdot", XKB_KEY_ebelowdot },
- { "Ecaron", XKB_KEY_Ecaron },
- { "ecaron", XKB_KEY_ecaron },
- { "Ecircumflex", XKB_KEY_Ecircumflex },
- { "ecircumflex", XKB_KEY_ecircumflex },
- { "Ecircumflexacute", XKB_KEY_Ecircumflexacute },
- { "ecircumflexacute", XKB_KEY_ecircumflexacute },
- { "Ecircumflexbelowdot", XKB_KEY_Ecircumflexbelowdot },
- { "ecircumflexbelowdot", XKB_KEY_ecircumflexbelowdot },
- { "Ecircumflexgrave", XKB_KEY_Ecircumflexgrave },
- { "ecircumflexgrave", XKB_KEY_ecircumflexgrave },
- { "Ecircumflexhook", XKB_KEY_Ecircumflexhook },
- { "ecircumflexhook", XKB_KEY_ecircumflexhook },
- { "Ecircumflextilde", XKB_KEY_Ecircumflextilde },
- { "ecircumflextilde", XKB_KEY_ecircumflextilde },
- { "EcuSign", XKB_KEY_EcuSign },
- { "Ediaeresis", XKB_KEY_Ediaeresis },
- { "ediaeresis", XKB_KEY_ediaeresis },
- { "Egrave", XKB_KEY_Egrave },
- { "egrave", XKB_KEY_egrave },
- { "Ehook", XKB_KEY_Ehook },
- { "ehook", XKB_KEY_ehook },
- { "eightsubscript", XKB_KEY_eightsubscript },
- { "eightsuperior", XKB_KEY_eightsuperior },
- { "Eisu_Shift", XKB_KEY_Eisu_Shift },
- { "Eisu_toggle", XKB_KEY_Eisu_toggle },
- { "elementof", XKB_KEY_elementof },
- { "ellipsis", XKB_KEY_ellipsis },
- { "em3space", XKB_KEY_em3space },
- { "em4space", XKB_KEY_em4space },
- { "Emacron", XKB_KEY_Emacron },
- { "emacron", XKB_KEY_emacron },
- { "emdash", XKB_KEY_emdash },
- { "emfilledcircle", XKB_KEY_emfilledcircle },
- { "emfilledrect", XKB_KEY_emfilledrect },
- { "emopencircle", XKB_KEY_emopencircle },
- { "emopenrectangle", XKB_KEY_emopenrectangle },
- { "emptyset", XKB_KEY_emptyset },
- { "emspace", XKB_KEY_emspace },
- { "End", XKB_KEY_End },
- { "endash", XKB_KEY_endash },
- { "enfilledcircbullet", XKB_KEY_enfilledcircbullet },
- { "enfilledsqbullet", XKB_KEY_enfilledsqbullet },
- { "ENG", XKB_KEY_ENG },
- { "eng", XKB_KEY_eng },
- { "enopencircbullet", XKB_KEY_enopencircbullet },
- { "enopensquarebullet", XKB_KEY_enopensquarebullet },
- { "enspace", XKB_KEY_enspace },
- { "Eogonek", XKB_KEY_Eogonek },
- { "eogonek", XKB_KEY_eogonek },
- { "equal", XKB_KEY_equal },
- { "Escape", XKB_KEY_Escape },
- { "ETH", XKB_KEY_ETH },
- { "Eth", XKB_KEY_Eth },
- { "eth", XKB_KEY_eth },
- { "Etilde", XKB_KEY_Etilde },
- { "etilde", XKB_KEY_etilde },
- { "EuroSign", XKB_KEY_EuroSign },
- { "exclam", XKB_KEY_exclam },
- { "exclamdown", XKB_KEY_exclamdown },
- { "Execute", XKB_KEY_Execute },
- { "Ext16bit_L", XKB_KEY_Ext16bit_L },
- { "Ext16bit_R", XKB_KEY_Ext16bit_R },
- { "EZH", XKB_KEY_EZH },
- { "ezh", XKB_KEY_ezh },
- { "F", XKB_KEY_F },
- { "f", XKB_KEY_f },
- { "F1", XKB_KEY_F1 },
- { "F10", XKB_KEY_F10 },
- { "F11", XKB_KEY_F11 },
- { "F12", XKB_KEY_F12 },
- { "F13", XKB_KEY_F13 },
- { "F14", XKB_KEY_F14 },
- { "F15", XKB_KEY_F15 },
- { "F16", XKB_KEY_F16 },
- { "F17", XKB_KEY_F17 },
- { "F18", XKB_KEY_F18 },
- { "F19", XKB_KEY_F19 },
- { "F2", XKB_KEY_F2 },
- { "F20", XKB_KEY_F20 },
- { "F21", XKB_KEY_F21 },
- { "F22", XKB_KEY_F22 },
- { "F23", XKB_KEY_F23 },
- { "F24", XKB_KEY_F24 },
- { "F25", XKB_KEY_F25 },
- { "F26", XKB_KEY_F26 },
- { "F27", XKB_KEY_F27 },
- { "F28", XKB_KEY_F28 },
- { "F29", XKB_KEY_F29 },
- { "F3", XKB_KEY_F3 },
- { "F30", XKB_KEY_F30 },
- { "F31", XKB_KEY_F31 },
- { "F32", XKB_KEY_F32 },
- { "F33", XKB_KEY_F33 },
- { "F34", XKB_KEY_F34 },
- { "F35", XKB_KEY_F35 },
- { "F4", XKB_KEY_F4 },
- { "F5", XKB_KEY_F5 },
- { "F6", XKB_KEY_F6 },
- { "F7", XKB_KEY_F7 },
- { "F8", XKB_KEY_F8 },
- { "F9", XKB_KEY_F9 },
- { "Fabovedot", XKB_KEY_Fabovedot },
- { "fabovedot", XKB_KEY_fabovedot },
- { "Farsi_0", XKB_KEY_Farsi_0 },
- { "Farsi_1", XKB_KEY_Farsi_1 },
- { "Farsi_2", XKB_KEY_Farsi_2 },
- { "Farsi_3", XKB_KEY_Farsi_3 },
- { "Farsi_4", XKB_KEY_Farsi_4 },
- { "Farsi_5", XKB_KEY_Farsi_5 },
- { "Farsi_6", XKB_KEY_Farsi_6 },
- { "Farsi_7", XKB_KEY_Farsi_7 },
- { "Farsi_8", XKB_KEY_Farsi_8 },
- { "Farsi_9", XKB_KEY_Farsi_9 },
- { "Farsi_yeh", XKB_KEY_Farsi_yeh },
- { "femalesymbol", XKB_KEY_femalesymbol },
- { "ff", XKB_KEY_ff },
- { "FFrancSign", XKB_KEY_FFrancSign },
- { "figdash", XKB_KEY_figdash },
- { "filledlefttribullet", XKB_KEY_filledlefttribullet },
- { "filledrectbullet", XKB_KEY_filledrectbullet },
- { "filledrighttribullet", XKB_KEY_filledrighttribullet },
- { "filledtribulletdown", XKB_KEY_filledtribulletdown },
- { "filledtribulletup", XKB_KEY_filledtribulletup },
- { "Find", XKB_KEY_Find },
- { "First_Virtual_Screen", XKB_KEY_First_Virtual_Screen },
- { "fiveeighths", XKB_KEY_fiveeighths },
- { "fivesixths", XKB_KEY_fivesixths },
- { "fivesubscript", XKB_KEY_fivesubscript },
- { "fivesuperior", XKB_KEY_fivesuperior },
- { "fourfifths", XKB_KEY_fourfifths },
- { "foursubscript", XKB_KEY_foursubscript },
- { "foursuperior", XKB_KEY_foursuperior },
- { "fourthroot", XKB_KEY_fourthroot },
- { "function", XKB_KEY_function },
- { "G", XKB_KEY_G },
- { "g", XKB_KEY_g },
- { "Gabovedot", XKB_KEY_Gabovedot },
- { "gabovedot", XKB_KEY_gabovedot },
- { "Gbreve", XKB_KEY_Gbreve },
- { "gbreve", XKB_KEY_gbreve },
- { "Gcaron", XKB_KEY_Gcaron },
- { "gcaron", XKB_KEY_gcaron },
- { "Gcedilla", XKB_KEY_Gcedilla },
- { "gcedilla", XKB_KEY_gcedilla },
- { "Gcircumflex", XKB_KEY_Gcircumflex },
- { "gcircumflex", XKB_KEY_gcircumflex },
- { "Georgian_an", XKB_KEY_Georgian_an },
- { "Georgian_ban", XKB_KEY_Georgian_ban },
- { "Georgian_can", XKB_KEY_Georgian_can },
- { "Georgian_char", XKB_KEY_Georgian_char },
- { "Georgian_chin", XKB_KEY_Georgian_chin },
- { "Georgian_cil", XKB_KEY_Georgian_cil },
- { "Georgian_don", XKB_KEY_Georgian_don },
- { "Georgian_en", XKB_KEY_Georgian_en },
- { "Georgian_fi", XKB_KEY_Georgian_fi },
- { "Georgian_gan", XKB_KEY_Georgian_gan },
- { "Georgian_ghan", XKB_KEY_Georgian_ghan },
- { "Georgian_hae", XKB_KEY_Georgian_hae },
- { "Georgian_har", XKB_KEY_Georgian_har },
- { "Georgian_he", XKB_KEY_Georgian_he },
- { "Georgian_hie", XKB_KEY_Georgian_hie },
- { "Georgian_hoe", XKB_KEY_Georgian_hoe },
- { "Georgian_in", XKB_KEY_Georgian_in },
- { "Georgian_jhan", XKB_KEY_Georgian_jhan },
- { "Georgian_jil", XKB_KEY_Georgian_jil },
- { "Georgian_kan", XKB_KEY_Georgian_kan },
- { "Georgian_khar", XKB_KEY_Georgian_khar },
- { "Georgian_las", XKB_KEY_Georgian_las },
- { "Georgian_man", XKB_KEY_Georgian_man },
- { "Georgian_nar", XKB_KEY_Georgian_nar },
- { "Georgian_on", XKB_KEY_Georgian_on },
- { "Georgian_par", XKB_KEY_Georgian_par },
- { "Georgian_phar", XKB_KEY_Georgian_phar },
- { "Georgian_qar", XKB_KEY_Georgian_qar },
- { "Georgian_rae", XKB_KEY_Georgian_rae },
- { "Georgian_san", XKB_KEY_Georgian_san },
- { "Georgian_shin", XKB_KEY_Georgian_shin },
- { "Georgian_tan", XKB_KEY_Georgian_tan },
- { "Georgian_tar", XKB_KEY_Georgian_tar },
- { "Georgian_un", XKB_KEY_Georgian_un },
- { "Georgian_vin", XKB_KEY_Georgian_vin },
- { "Georgian_we", XKB_KEY_Georgian_we },
- { "Georgian_xan", XKB_KEY_Georgian_xan },
- { "Georgian_zen", XKB_KEY_Georgian_zen },
- { "Georgian_zhar", XKB_KEY_Georgian_zhar },
- { "grave", XKB_KEY_grave },
- { "greater", XKB_KEY_greater },
- { "greaterthanequal", XKB_KEY_greaterthanequal },
- { "Greek_accentdieresis", XKB_KEY_Greek_accentdieresis },
- { "Greek_ALPHA", XKB_KEY_Greek_ALPHA },
- { "Greek_alpha", XKB_KEY_Greek_alpha },
- { "Greek_ALPHAaccent", XKB_KEY_Greek_ALPHAaccent },
- { "Greek_alphaaccent", XKB_KEY_Greek_alphaaccent },
- { "Greek_BETA", XKB_KEY_Greek_BETA },
- { "Greek_beta", XKB_KEY_Greek_beta },
- { "Greek_CHI", XKB_KEY_Greek_CHI },
- { "Greek_chi", XKB_KEY_Greek_chi },
- { "Greek_DELTA", XKB_KEY_Greek_DELTA },
- { "Greek_delta", XKB_KEY_Greek_delta },
- { "Greek_EPSILON", XKB_KEY_Greek_EPSILON },
- { "Greek_epsilon", XKB_KEY_Greek_epsilon },
- { "Greek_EPSILONaccent", XKB_KEY_Greek_EPSILONaccent },
- { "Greek_epsilonaccent", XKB_KEY_Greek_epsilonaccent },
- { "Greek_ETA", XKB_KEY_Greek_ETA },
- { "Greek_eta", XKB_KEY_Greek_eta },
- { "Greek_ETAaccent", XKB_KEY_Greek_ETAaccent },
- { "Greek_etaaccent", XKB_KEY_Greek_etaaccent },
- { "Greek_finalsmallsigma", XKB_KEY_Greek_finalsmallsigma },
- { "Greek_GAMMA", XKB_KEY_Greek_GAMMA },
- { "Greek_gamma", XKB_KEY_Greek_gamma },
- { "Greek_horizbar", XKB_KEY_Greek_horizbar },
- { "Greek_IOTA", XKB_KEY_Greek_IOTA },
- { "Greek_iota", XKB_KEY_Greek_iota },
- { "Greek_IOTAaccent", XKB_KEY_Greek_IOTAaccent },
- { "Greek_iotaaccent", XKB_KEY_Greek_iotaaccent },
- { "Greek_iotaaccentdieresis", XKB_KEY_Greek_iotaaccentdieresis },
- { "Greek_IOTAdiaeresis", XKB_KEY_Greek_IOTAdiaeresis },
- { "Greek_IOTAdieresis", XKB_KEY_Greek_IOTAdieresis },
- { "Greek_iotadieresis", XKB_KEY_Greek_iotadieresis },
- { "Greek_KAPPA", XKB_KEY_Greek_KAPPA },
- { "Greek_kappa", XKB_KEY_Greek_kappa },
- { "Greek_LAMBDA", XKB_KEY_Greek_LAMBDA },
- { "Greek_lambda", XKB_KEY_Greek_lambda },
- { "Greek_LAMDA", XKB_KEY_Greek_LAMDA },
- { "Greek_lamda", XKB_KEY_Greek_lamda },
- { "Greek_MU", XKB_KEY_Greek_MU },
- { "Greek_mu", XKB_KEY_Greek_mu },
- { "Greek_NU", XKB_KEY_Greek_NU },
- { "Greek_nu", XKB_KEY_Greek_nu },
- { "Greek_OMEGA", XKB_KEY_Greek_OMEGA },
- { "Greek_omega", XKB_KEY_Greek_omega },
- { "Greek_OMEGAaccent", XKB_KEY_Greek_OMEGAaccent },
- { "Greek_omegaaccent", XKB_KEY_Greek_omegaaccent },
- { "Greek_OMICRON", XKB_KEY_Greek_OMICRON },
- { "Greek_omicron", XKB_KEY_Greek_omicron },
- { "Greek_OMICRONaccent", XKB_KEY_Greek_OMICRONaccent },
- { "Greek_omicronaccent", XKB_KEY_Greek_omicronaccent },
- { "Greek_PHI", XKB_KEY_Greek_PHI },
- { "Greek_phi", XKB_KEY_Greek_phi },
- { "Greek_PI", XKB_KEY_Greek_PI },
- { "Greek_pi", XKB_KEY_Greek_pi },
- { "Greek_PSI", XKB_KEY_Greek_PSI },
- { "Greek_psi", XKB_KEY_Greek_psi },
- { "Greek_RHO", XKB_KEY_Greek_RHO },
- { "Greek_rho", XKB_KEY_Greek_rho },
- { "Greek_SIGMA", XKB_KEY_Greek_SIGMA },
- { "Greek_sigma", XKB_KEY_Greek_sigma },
- { "Greek_switch", XKB_KEY_Greek_switch },
- { "Greek_TAU", XKB_KEY_Greek_TAU },
- { "Greek_tau", XKB_KEY_Greek_tau },
- { "Greek_THETA", XKB_KEY_Greek_THETA },
- { "Greek_theta", XKB_KEY_Greek_theta },
- { "Greek_UPSILON", XKB_KEY_Greek_UPSILON },
- { "Greek_upsilon", XKB_KEY_Greek_upsilon },
- { "Greek_UPSILONaccent", XKB_KEY_Greek_UPSILONaccent },
- { "Greek_upsilonaccent", XKB_KEY_Greek_upsilonaccent },
- { "Greek_upsilonaccentdieresis", XKB_KEY_Greek_upsilonaccentdieresis },
- { "Greek_UPSILONdieresis", XKB_KEY_Greek_UPSILONdieresis },
- { "Greek_upsilondieresis", XKB_KEY_Greek_upsilondieresis },
- { "Greek_XI", XKB_KEY_Greek_XI },
- { "Greek_xi", XKB_KEY_Greek_xi },
- { "Greek_ZETA", XKB_KEY_Greek_ZETA },
- { "Greek_zeta", XKB_KEY_Greek_zeta },
- { "guilder", XKB_KEY_guilder },
- { "guillemotleft", XKB_KEY_guillemotleft },
- { "guillemotright", XKB_KEY_guillemotright },
- { "H", XKB_KEY_H },
- { "h", XKB_KEY_h },
- { "hairspace", XKB_KEY_hairspace },
- { "Hangul", XKB_KEY_Hangul },
- { "Hangul_A", XKB_KEY_Hangul_A },
- { "Hangul_AE", XKB_KEY_Hangul_AE },
- { "Hangul_AraeA", XKB_KEY_Hangul_AraeA },
- { "Hangul_AraeAE", XKB_KEY_Hangul_AraeAE },
- { "Hangul_Banja", XKB_KEY_Hangul_Banja },
- { "Hangul_Cieuc", XKB_KEY_Hangul_Cieuc },
- { "Hangul_Codeinput", XKB_KEY_Hangul_Codeinput },
- { "Hangul_Dikeud", XKB_KEY_Hangul_Dikeud },
- { "Hangul_E", XKB_KEY_Hangul_E },
- { "Hangul_End", XKB_KEY_Hangul_End },
- { "Hangul_EO", XKB_KEY_Hangul_EO },
- { "Hangul_EU", XKB_KEY_Hangul_EU },
- { "Hangul_Hanja", XKB_KEY_Hangul_Hanja },
- { "Hangul_Hieuh", XKB_KEY_Hangul_Hieuh },
- { "Hangul_I", XKB_KEY_Hangul_I },
- { "Hangul_Ieung", XKB_KEY_Hangul_Ieung },
- { "Hangul_J_Cieuc", XKB_KEY_Hangul_J_Cieuc },
- { "Hangul_J_Dikeud", XKB_KEY_Hangul_J_Dikeud },
- { "Hangul_J_Hieuh", XKB_KEY_Hangul_J_Hieuh },
- { "Hangul_J_Ieung", XKB_KEY_Hangul_J_Ieung },
- { "Hangul_J_Jieuj", XKB_KEY_Hangul_J_Jieuj },
- { "Hangul_J_Khieuq", XKB_KEY_Hangul_J_Khieuq },
- { "Hangul_J_Kiyeog", XKB_KEY_Hangul_J_Kiyeog },
- { "Hangul_J_KiyeogSios", XKB_KEY_Hangul_J_KiyeogSios },
- { "Hangul_J_KkogjiDalrinIeung", XKB_KEY_Hangul_J_KkogjiDalrinIeung },
- { "Hangul_J_Mieum", XKB_KEY_Hangul_J_Mieum },
- { "Hangul_J_Nieun", XKB_KEY_Hangul_J_Nieun },
- { "Hangul_J_NieunHieuh", XKB_KEY_Hangul_J_NieunHieuh },
- { "Hangul_J_NieunJieuj", XKB_KEY_Hangul_J_NieunJieuj },
- { "Hangul_J_PanSios", XKB_KEY_Hangul_J_PanSios },
- { "Hangul_J_Phieuf", XKB_KEY_Hangul_J_Phieuf },
- { "Hangul_J_Pieub", XKB_KEY_Hangul_J_Pieub },
- { "Hangul_J_PieubSios", XKB_KEY_Hangul_J_PieubSios },
- { "Hangul_J_Rieul", XKB_KEY_Hangul_J_Rieul },
- { "Hangul_J_RieulHieuh", XKB_KEY_Hangul_J_RieulHieuh },
- { "Hangul_J_RieulKiyeog", XKB_KEY_Hangul_J_RieulKiyeog },
- { "Hangul_J_RieulMieum", XKB_KEY_Hangul_J_RieulMieum },
- { "Hangul_J_RieulPhieuf", XKB_KEY_Hangul_J_RieulPhieuf },
- { "Hangul_J_RieulPieub", XKB_KEY_Hangul_J_RieulPieub },
- { "Hangul_J_RieulSios", XKB_KEY_Hangul_J_RieulSios },
- { "Hangul_J_RieulTieut", XKB_KEY_Hangul_J_RieulTieut },
- { "Hangul_J_Sios", XKB_KEY_Hangul_J_Sios },
- { "Hangul_J_SsangKiyeog", XKB_KEY_Hangul_J_SsangKiyeog },
- { "Hangul_J_SsangSios", XKB_KEY_Hangul_J_SsangSios },
- { "Hangul_J_Tieut", XKB_KEY_Hangul_J_Tieut },
- { "Hangul_J_YeorinHieuh", XKB_KEY_Hangul_J_YeorinHieuh },
- { "Hangul_Jamo", XKB_KEY_Hangul_Jamo },
- { "Hangul_Jeonja", XKB_KEY_Hangul_Jeonja },
- { "Hangul_Jieuj", XKB_KEY_Hangul_Jieuj },
- { "Hangul_Khieuq", XKB_KEY_Hangul_Khieuq },
- { "Hangul_Kiyeog", XKB_KEY_Hangul_Kiyeog },
- { "Hangul_KiyeogSios", XKB_KEY_Hangul_KiyeogSios },
- { "Hangul_KkogjiDalrinIeung", XKB_KEY_Hangul_KkogjiDalrinIeung },
- { "Hangul_Mieum", XKB_KEY_Hangul_Mieum },
- { "Hangul_MultipleCandidate", XKB_KEY_Hangul_MultipleCandidate },
- { "Hangul_Nieun", XKB_KEY_Hangul_Nieun },
- { "Hangul_NieunHieuh", XKB_KEY_Hangul_NieunHieuh },
- { "Hangul_NieunJieuj", XKB_KEY_Hangul_NieunJieuj },
- { "Hangul_O", XKB_KEY_Hangul_O },
- { "Hangul_OE", XKB_KEY_Hangul_OE },
- { "Hangul_PanSios", XKB_KEY_Hangul_PanSios },
- { "Hangul_Phieuf", XKB_KEY_Hangul_Phieuf },
- { "Hangul_Pieub", XKB_KEY_Hangul_Pieub },
- { "Hangul_PieubSios", XKB_KEY_Hangul_PieubSios },
- { "Hangul_PostHanja", XKB_KEY_Hangul_PostHanja },
- { "Hangul_PreHanja", XKB_KEY_Hangul_PreHanja },
- { "Hangul_PreviousCandidate", XKB_KEY_Hangul_PreviousCandidate },
- { "Hangul_Rieul", XKB_KEY_Hangul_Rieul },
- { "Hangul_RieulHieuh", XKB_KEY_Hangul_RieulHieuh },
- { "Hangul_RieulKiyeog", XKB_KEY_Hangul_RieulKiyeog },
- { "Hangul_RieulMieum", XKB_KEY_Hangul_RieulMieum },
- { "Hangul_RieulPhieuf", XKB_KEY_Hangul_RieulPhieuf },
- { "Hangul_RieulPieub", XKB_KEY_Hangul_RieulPieub },
- { "Hangul_RieulSios", XKB_KEY_Hangul_RieulSios },
- { "Hangul_RieulTieut", XKB_KEY_Hangul_RieulTieut },
- { "Hangul_RieulYeorinHieuh", XKB_KEY_Hangul_RieulYeorinHieuh },
- { "Hangul_Romaja", XKB_KEY_Hangul_Romaja },
- { "Hangul_SingleCandidate", XKB_KEY_Hangul_SingleCandidate },
- { "Hangul_Sios", XKB_KEY_Hangul_Sios },
- { "Hangul_Special", XKB_KEY_Hangul_Special },
- { "Hangul_SsangDikeud", XKB_KEY_Hangul_SsangDikeud },
- { "Hangul_SsangJieuj", XKB_KEY_Hangul_SsangJieuj },
- { "Hangul_SsangKiyeog", XKB_KEY_Hangul_SsangKiyeog },
- { "Hangul_SsangPieub", XKB_KEY_Hangul_SsangPieub },
- { "Hangul_SsangSios", XKB_KEY_Hangul_SsangSios },
- { "Hangul_Start", XKB_KEY_Hangul_Start },
- { "Hangul_SunkyeongeumMieum", XKB_KEY_Hangul_SunkyeongeumMieum },
- { "Hangul_SunkyeongeumPhieuf", XKB_KEY_Hangul_SunkyeongeumPhieuf },
- { "Hangul_SunkyeongeumPieub", XKB_KEY_Hangul_SunkyeongeumPieub },
- { "Hangul_switch", XKB_KEY_Hangul_switch },
- { "Hangul_Tieut", XKB_KEY_Hangul_Tieut },
- { "Hangul_U", XKB_KEY_Hangul_U },
- { "Hangul_WA", XKB_KEY_Hangul_WA },
- { "Hangul_WAE", XKB_KEY_Hangul_WAE },
- { "Hangul_WE", XKB_KEY_Hangul_WE },
- { "Hangul_WEO", XKB_KEY_Hangul_WEO },
- { "Hangul_WI", XKB_KEY_Hangul_WI },
- { "Hangul_YA", XKB_KEY_Hangul_YA },
- { "Hangul_YAE", XKB_KEY_Hangul_YAE },
- { "Hangul_YE", XKB_KEY_Hangul_YE },
- { "Hangul_YEO", XKB_KEY_Hangul_YEO },
- { "Hangul_YeorinHieuh", XKB_KEY_Hangul_YeorinHieuh },
- { "Hangul_YI", XKB_KEY_Hangul_YI },
- { "Hangul_YO", XKB_KEY_Hangul_YO },
- { "Hangul_YU", XKB_KEY_Hangul_YU },
- { "Hankaku", XKB_KEY_Hankaku },
- { "Hcircumflex", XKB_KEY_Hcircumflex },
- { "hcircumflex", XKB_KEY_hcircumflex },
- { "heart", XKB_KEY_heart },
- { "hebrew_aleph", XKB_KEY_hebrew_aleph },
- { "hebrew_ayin", XKB_KEY_hebrew_ayin },
- { "hebrew_bet", XKB_KEY_hebrew_bet },
- { "hebrew_beth", XKB_KEY_hebrew_beth },
- { "hebrew_chet", XKB_KEY_hebrew_chet },
- { "hebrew_dalet", XKB_KEY_hebrew_dalet },
- { "hebrew_daleth", XKB_KEY_hebrew_daleth },
- { "hebrew_doublelowline", XKB_KEY_hebrew_doublelowline },
- { "hebrew_finalkaph", XKB_KEY_hebrew_finalkaph },
- { "hebrew_finalmem", XKB_KEY_hebrew_finalmem },
- { "hebrew_finalnun", XKB_KEY_hebrew_finalnun },
- { "hebrew_finalpe", XKB_KEY_hebrew_finalpe },
- { "hebrew_finalzade", XKB_KEY_hebrew_finalzade },
- { "hebrew_finalzadi", XKB_KEY_hebrew_finalzadi },
- { "hebrew_gimel", XKB_KEY_hebrew_gimel },
- { "hebrew_gimmel", XKB_KEY_hebrew_gimmel },
- { "hebrew_he", XKB_KEY_hebrew_he },
- { "hebrew_het", XKB_KEY_hebrew_het },
- { "hebrew_kaph", XKB_KEY_hebrew_kaph },
- { "hebrew_kuf", XKB_KEY_hebrew_kuf },
- { "hebrew_lamed", XKB_KEY_hebrew_lamed },
- { "hebrew_mem", XKB_KEY_hebrew_mem },
- { "hebrew_nun", XKB_KEY_hebrew_nun },
- { "hebrew_pe", XKB_KEY_hebrew_pe },
- { "hebrew_qoph", XKB_KEY_hebrew_qoph },
- { "hebrew_resh", XKB_KEY_hebrew_resh },
- { "hebrew_samech", XKB_KEY_hebrew_samech },
- { "hebrew_samekh", XKB_KEY_hebrew_samekh },
- { "hebrew_shin", XKB_KEY_hebrew_shin },
- { "Hebrew_switch", XKB_KEY_Hebrew_switch },
- { "hebrew_taf", XKB_KEY_hebrew_taf },
- { "hebrew_taw", XKB_KEY_hebrew_taw },
- { "hebrew_tet", XKB_KEY_hebrew_tet },
- { "hebrew_teth", XKB_KEY_hebrew_teth },
- { "hebrew_waw", XKB_KEY_hebrew_waw },
- { "hebrew_yod", XKB_KEY_hebrew_yod },
- { "hebrew_zade", XKB_KEY_hebrew_zade },
- { "hebrew_zadi", XKB_KEY_hebrew_zadi },
- { "hebrew_zain", XKB_KEY_hebrew_zain },
- { "hebrew_zayin", XKB_KEY_hebrew_zayin },
- { "Help", XKB_KEY_Help },
- { "Henkan", XKB_KEY_Henkan },
- { "Henkan_Mode", XKB_KEY_Henkan_Mode },
- { "hexagram", XKB_KEY_hexagram },
- { "Hiragana", XKB_KEY_Hiragana },
- { "Hiragana_Katakana", XKB_KEY_Hiragana_Katakana },
- { "Home", XKB_KEY_Home },
- { "horizconnector", XKB_KEY_horizconnector },
- { "horizlinescan1", XKB_KEY_horizlinescan1 },
- { "horizlinescan3", XKB_KEY_horizlinescan3 },
- { "horizlinescan5", XKB_KEY_horizlinescan5 },
- { "horizlinescan7", XKB_KEY_horizlinescan7 },
- { "horizlinescan9", XKB_KEY_horizlinescan9 },
- { "hpBackTab", XKB_KEY_hpBackTab },
- { "hpblock", XKB_KEY_hpblock },
- { "hpClearLine", XKB_KEY_hpClearLine },
- { "hpDeleteChar", XKB_KEY_hpDeleteChar },
- { "hpDeleteLine", XKB_KEY_hpDeleteLine },
- { "hpguilder", XKB_KEY_hpguilder },
- { "hpInsertChar", XKB_KEY_hpInsertChar },
- { "hpInsertLine", XKB_KEY_hpInsertLine },
- { "hpIO", XKB_KEY_hpIO },
- { "hpKP_BackTab", XKB_KEY_hpKP_BackTab },
- { "hplira", XKB_KEY_hplira },
- { "hplongminus", XKB_KEY_hplongminus },
- { "hpModelock1", XKB_KEY_hpModelock1 },
- { "hpModelock2", XKB_KEY_hpModelock2 },
- { "hpmute_acute", XKB_KEY_hpmute_acute },
- { "hpmute_asciicircum", XKB_KEY_hpmute_asciicircum },
- { "hpmute_asciitilde", XKB_KEY_hpmute_asciitilde },
- { "hpmute_diaeresis", XKB_KEY_hpmute_diaeresis },
- { "hpmute_grave", XKB_KEY_hpmute_grave },
- { "hpReset", XKB_KEY_hpReset },
- { "hpSystem", XKB_KEY_hpSystem },
- { "hpUser", XKB_KEY_hpUser },
- { "hpYdiaeresis", XKB_KEY_hpYdiaeresis },
- { "Hstroke", XKB_KEY_Hstroke },
- { "hstroke", XKB_KEY_hstroke },
- { "ht", XKB_KEY_ht },
- { "Hyper_L", XKB_KEY_Hyper_L },
- { "Hyper_R", XKB_KEY_Hyper_R },
- { "hyphen", XKB_KEY_hyphen },
- { "I", XKB_KEY_I },
- { "i", XKB_KEY_i },
- { "Iabovedot", XKB_KEY_Iabovedot },
- { "Iacute", XKB_KEY_Iacute },
- { "iacute", XKB_KEY_iacute },
- { "Ibelowdot", XKB_KEY_Ibelowdot },
- { "ibelowdot", XKB_KEY_ibelowdot },
- { "Ibreve", XKB_KEY_Ibreve },
- { "ibreve", XKB_KEY_ibreve },
- { "Icircumflex", XKB_KEY_Icircumflex },
- { "icircumflex", XKB_KEY_icircumflex },
- { "identical", XKB_KEY_identical },
- { "Idiaeresis", XKB_KEY_Idiaeresis },
- { "idiaeresis", XKB_KEY_idiaeresis },
- { "idotless", XKB_KEY_idotless },
- { "ifonlyif", XKB_KEY_ifonlyif },
- { "Igrave", XKB_KEY_Igrave },
- { "igrave", XKB_KEY_igrave },
- { "Ihook", XKB_KEY_Ihook },
- { "ihook", XKB_KEY_ihook },
- { "Imacron", XKB_KEY_Imacron },
- { "imacron", XKB_KEY_imacron },
- { "implies", XKB_KEY_implies },
- { "includedin", XKB_KEY_includedin },
- { "includes", XKB_KEY_includes },
- { "infinity", XKB_KEY_infinity },
- { "Insert", XKB_KEY_Insert },
- { "InsertChar", XKB_KEY_InsertChar },
- { "InsertLine", XKB_KEY_InsertLine },
- { "integral", XKB_KEY_integral },
- { "intersection", XKB_KEY_intersection },
- { "IO", XKB_KEY_IO },
- { "Iogonek", XKB_KEY_Iogonek },
- { "iogonek", XKB_KEY_iogonek },
- { "ISO_Center_Object", XKB_KEY_ISO_Center_Object },
- { "ISO_Continuous_Underline", XKB_KEY_ISO_Continuous_Underline },
- { "ISO_Discontinuous_Underline", XKB_KEY_ISO_Discontinuous_Underline },
- { "ISO_Emphasize", XKB_KEY_ISO_Emphasize },
- { "ISO_Enter", XKB_KEY_ISO_Enter },
- { "ISO_Fast_Cursor_Down", XKB_KEY_ISO_Fast_Cursor_Down },
- { "ISO_Fast_Cursor_Left", XKB_KEY_ISO_Fast_Cursor_Left },
- { "ISO_Fast_Cursor_Right", XKB_KEY_ISO_Fast_Cursor_Right },
- { "ISO_Fast_Cursor_Up", XKB_KEY_ISO_Fast_Cursor_Up },
- { "ISO_First_Group", XKB_KEY_ISO_First_Group },
- { "ISO_First_Group_Lock", XKB_KEY_ISO_First_Group_Lock },
- { "ISO_Group_Latch", XKB_KEY_ISO_Group_Latch },
- { "ISO_Group_Lock", XKB_KEY_ISO_Group_Lock },
- { "ISO_Group_Shift", XKB_KEY_ISO_Group_Shift },
- { "ISO_Last_Group", XKB_KEY_ISO_Last_Group },
- { "ISO_Last_Group_Lock", XKB_KEY_ISO_Last_Group_Lock },
- { "ISO_Left_Tab", XKB_KEY_ISO_Left_Tab },
- { "ISO_Level2_Latch", XKB_KEY_ISO_Level2_Latch },
- { "ISO_Level3_Latch", XKB_KEY_ISO_Level3_Latch },
- { "ISO_Level3_Lock", XKB_KEY_ISO_Level3_Lock },
- { "ISO_Level3_Shift", XKB_KEY_ISO_Level3_Shift },
- { "ISO_Level5_Latch", XKB_KEY_ISO_Level5_Latch },
- { "ISO_Level5_Lock", XKB_KEY_ISO_Level5_Lock },
- { "ISO_Level5_Shift", XKB_KEY_ISO_Level5_Shift },
- { "ISO_Lock", XKB_KEY_ISO_Lock },
- { "ISO_Move_Line_Down", XKB_KEY_ISO_Move_Line_Down },
- { "ISO_Move_Line_Up", XKB_KEY_ISO_Move_Line_Up },
- { "ISO_Next_Group", XKB_KEY_ISO_Next_Group },
- { "ISO_Next_Group_Lock", XKB_KEY_ISO_Next_Group_Lock },
- { "ISO_Partial_Line_Down", XKB_KEY_ISO_Partial_Line_Down },
- { "ISO_Partial_Line_Up", XKB_KEY_ISO_Partial_Line_Up },
- { "ISO_Partial_Space_Left", XKB_KEY_ISO_Partial_Space_Left },
- { "ISO_Partial_Space_Right", XKB_KEY_ISO_Partial_Space_Right },
- { "ISO_Prev_Group", XKB_KEY_ISO_Prev_Group },
- { "ISO_Prev_Group_Lock", XKB_KEY_ISO_Prev_Group_Lock },
- { "ISO_Release_Both_Margins", XKB_KEY_ISO_Release_Both_Margins },
- { "ISO_Release_Margin_Left", XKB_KEY_ISO_Release_Margin_Left },
- { "ISO_Release_Margin_Right", XKB_KEY_ISO_Release_Margin_Right },
- { "ISO_Set_Margin_Left", XKB_KEY_ISO_Set_Margin_Left },
- { "ISO_Set_Margin_Right", XKB_KEY_ISO_Set_Margin_Right },
- { "Itilde", XKB_KEY_Itilde },
- { "itilde", XKB_KEY_itilde },
- { "J", XKB_KEY_J },
- { "j", XKB_KEY_j },
- { "Jcircumflex", XKB_KEY_Jcircumflex },
- { "jcircumflex", XKB_KEY_jcircumflex },
- { "jot", XKB_KEY_jot },
- { "K", XKB_KEY_K },
- { "k", XKB_KEY_k },
- { "kana_a", XKB_KEY_kana_a },
- { "kana_A", XKB_KEY_kana_A },
- { "kana_CHI", XKB_KEY_kana_CHI },
- { "kana_closingbracket", XKB_KEY_kana_closingbracket },
- { "kana_comma", XKB_KEY_kana_comma },
- { "kana_conjunctive", XKB_KEY_kana_conjunctive },
- { "kana_e", XKB_KEY_kana_e },
- { "kana_E", XKB_KEY_kana_E },
- { "kana_FU", XKB_KEY_kana_FU },
- { "kana_fullstop", XKB_KEY_kana_fullstop },
- { "kana_HA", XKB_KEY_kana_HA },
- { "kana_HE", XKB_KEY_kana_HE },
- { "kana_HI", XKB_KEY_kana_HI },
- { "kana_HO", XKB_KEY_kana_HO },
- { "kana_HU", XKB_KEY_kana_HU },
- { "kana_i", XKB_KEY_kana_i },
- { "kana_I", XKB_KEY_kana_I },
- { "kana_KA", XKB_KEY_kana_KA },
- { "kana_KE", XKB_KEY_kana_KE },
- { "kana_KI", XKB_KEY_kana_KI },
- { "kana_KO", XKB_KEY_kana_KO },
- { "kana_KU", XKB_KEY_kana_KU },
- { "Kana_Lock", XKB_KEY_Kana_Lock },
- { "kana_MA", XKB_KEY_kana_MA },
- { "kana_ME", XKB_KEY_kana_ME },
- { "kana_MI", XKB_KEY_kana_MI },
- { "kana_middledot", XKB_KEY_kana_middledot },
- { "kana_MO", XKB_KEY_kana_MO },
- { "kana_MU", XKB_KEY_kana_MU },
- { "kana_N", XKB_KEY_kana_N },
- { "kana_NA", XKB_KEY_kana_NA },
- { "kana_NE", XKB_KEY_kana_NE },
- { "kana_NI", XKB_KEY_kana_NI },
- { "kana_NO", XKB_KEY_kana_NO },
- { "kana_NU", XKB_KEY_kana_NU },
- { "kana_o", XKB_KEY_kana_o },
- { "kana_O", XKB_KEY_kana_O },
- { "kana_openingbracket", XKB_KEY_kana_openingbracket },
- { "kana_RA", XKB_KEY_kana_RA },
- { "kana_RE", XKB_KEY_kana_RE },
- { "kana_RI", XKB_KEY_kana_RI },
- { "kana_RO", XKB_KEY_kana_RO },
- { "kana_RU", XKB_KEY_kana_RU },
- { "kana_SA", XKB_KEY_kana_SA },
- { "kana_SE", XKB_KEY_kana_SE },
- { "kana_SHI", XKB_KEY_kana_SHI },
- { "Kana_Shift", XKB_KEY_Kana_Shift },
- { "kana_SO", XKB_KEY_kana_SO },
- { "kana_SU", XKB_KEY_kana_SU },
- { "kana_switch", XKB_KEY_kana_switch },
- { "kana_TA", XKB_KEY_kana_TA },
- { "kana_TE", XKB_KEY_kana_TE },
- { "kana_TI", XKB_KEY_kana_TI },
- { "kana_TO", XKB_KEY_kana_TO },
- { "kana_tsu", XKB_KEY_kana_tsu },
- { "kana_TSU", XKB_KEY_kana_TSU },
- { "kana_tu", XKB_KEY_kana_tu },
- { "kana_TU", XKB_KEY_kana_TU },
- { "kana_u", XKB_KEY_kana_u },
- { "kana_U", XKB_KEY_kana_U },
- { "kana_WA", XKB_KEY_kana_WA },
- { "kana_WO", XKB_KEY_kana_WO },
- { "kana_ya", XKB_KEY_kana_ya },
- { "kana_YA", XKB_KEY_kana_YA },
- { "kana_yo", XKB_KEY_kana_yo },
- { "kana_YO", XKB_KEY_kana_YO },
- { "kana_yu", XKB_KEY_kana_yu },
- { "kana_YU", XKB_KEY_kana_YU },
- { "Kanji", XKB_KEY_Kanji },
- { "Kanji_Bangou", XKB_KEY_Kanji_Bangou },
- { "kappa", XKB_KEY_kappa },
- { "Katakana", XKB_KEY_Katakana },
- { "Kcedilla", XKB_KEY_Kcedilla },
- { "kcedilla", XKB_KEY_kcedilla },
- { "Korean_Won", XKB_KEY_Korean_Won },
- { "KP_0", XKB_KEY_KP_0 },
- { "KP_1", XKB_KEY_KP_1 },
- { "KP_2", XKB_KEY_KP_2 },
- { "KP_3", XKB_KEY_KP_3 },
- { "KP_4", XKB_KEY_KP_4 },
- { "KP_5", XKB_KEY_KP_5 },
- { "KP_6", XKB_KEY_KP_6 },
- { "KP_7", XKB_KEY_KP_7 },
- { "KP_8", XKB_KEY_KP_8 },
- { "KP_9", XKB_KEY_KP_9 },
- { "KP_Add", XKB_KEY_KP_Add },
- { "KP_BackTab", XKB_KEY_KP_BackTab },
- { "KP_Begin", XKB_KEY_KP_Begin },
- { "KP_Decimal", XKB_KEY_KP_Decimal },
- { "KP_Delete", XKB_KEY_KP_Delete },
- { "KP_Divide", XKB_KEY_KP_Divide },
- { "KP_Down", XKB_KEY_KP_Down },
- { "KP_End", XKB_KEY_KP_End },
- { "KP_Enter", XKB_KEY_KP_Enter },
- { "KP_Equal", XKB_KEY_KP_Equal },
- { "KP_F1", XKB_KEY_KP_F1 },
- { "KP_F2", XKB_KEY_KP_F2 },
- { "KP_F3", XKB_KEY_KP_F3 },
- { "KP_F4", XKB_KEY_KP_F4 },
- { "KP_Home", XKB_KEY_KP_Home },
- { "KP_Insert", XKB_KEY_KP_Insert },
- { "KP_Left", XKB_KEY_KP_Left },
- { "KP_Multiply", XKB_KEY_KP_Multiply },
- { "KP_Next", XKB_KEY_KP_Next },
- { "KP_Page_Down", XKB_KEY_KP_Page_Down },
- { "KP_Page_Up", XKB_KEY_KP_Page_Up },
- { "KP_Prior", XKB_KEY_KP_Prior },
- { "KP_Right", XKB_KEY_KP_Right },
- { "KP_Separator", XKB_KEY_KP_Separator },
- { "KP_Space", XKB_KEY_KP_Space },
- { "KP_Subtract", XKB_KEY_KP_Subtract },
- { "KP_Tab", XKB_KEY_KP_Tab },
- { "KP_Up", XKB_KEY_KP_Up },
- { "kra", XKB_KEY_kra },
- { "L", XKB_KEY_L },
- { "l", XKB_KEY_l },
- { "L1", XKB_KEY_L1 },
- { "L10", XKB_KEY_L10 },
- { "L2", XKB_KEY_L2 },
- { "L3", XKB_KEY_L3 },
- { "L4", XKB_KEY_L4 },
- { "L5", XKB_KEY_L5 },
- { "L6", XKB_KEY_L6 },
- { "L7", XKB_KEY_L7 },
- { "L8", XKB_KEY_L8 },
- { "L9", XKB_KEY_L9 },
- { "Lacute", XKB_KEY_Lacute },
- { "lacute", XKB_KEY_lacute },
- { "Last_Virtual_Screen", XKB_KEY_Last_Virtual_Screen },
- { "latincross", XKB_KEY_latincross },
- { "Lbelowdot", XKB_KEY_Lbelowdot },
- { "lbelowdot", XKB_KEY_lbelowdot },
- { "Lcaron", XKB_KEY_Lcaron },
- { "lcaron", XKB_KEY_lcaron },
- { "Lcedilla", XKB_KEY_Lcedilla },
- { "lcedilla", XKB_KEY_lcedilla },
- { "Left", XKB_KEY_Left },
- { "leftanglebracket", XKB_KEY_leftanglebracket },
- { "leftarrow", XKB_KEY_leftarrow },
- { "leftcaret", XKB_KEY_leftcaret },
- { "leftdoublequotemark", XKB_KEY_leftdoublequotemark },
- { "leftmiddlecurlybrace", XKB_KEY_leftmiddlecurlybrace },
- { "leftopentriangle", XKB_KEY_leftopentriangle },
- { "leftpointer", XKB_KEY_leftpointer },
- { "leftradical", XKB_KEY_leftradical },
- { "leftshoe", XKB_KEY_leftshoe },
- { "leftsinglequotemark", XKB_KEY_leftsinglequotemark },
- { "leftt", XKB_KEY_leftt },
- { "lefttack", XKB_KEY_lefttack },
- { "less", XKB_KEY_less },
- { "lessthanequal", XKB_KEY_lessthanequal },
- { "lf", XKB_KEY_lf },
- { "Linefeed", XKB_KEY_Linefeed },
- { "lira", XKB_KEY_lira },
- { "LiraSign", XKB_KEY_LiraSign },
- { "logicaland", XKB_KEY_logicaland },
- { "logicalor", XKB_KEY_logicalor },
- { "longminus", XKB_KEY_longminus },
- { "lowleftcorner", XKB_KEY_lowleftcorner },
- { "lowrightcorner", XKB_KEY_lowrightcorner },
- { "Lstroke", XKB_KEY_Lstroke },
- { "lstroke", XKB_KEY_lstroke },
- { "M", XKB_KEY_M },
- { "m", XKB_KEY_m },
- { "Mabovedot", XKB_KEY_Mabovedot },
- { "mabovedot", XKB_KEY_mabovedot },
- { "Macedonia_dse", XKB_KEY_Macedonia_dse },
- { "Macedonia_DSE", XKB_KEY_Macedonia_DSE },
- { "Macedonia_gje", XKB_KEY_Macedonia_gje },
- { "Macedonia_GJE", XKB_KEY_Macedonia_GJE },
- { "Macedonia_kje", XKB_KEY_Macedonia_kje },
- { "Macedonia_KJE", XKB_KEY_Macedonia_KJE },
- { "macron", XKB_KEY_macron },
- { "Mae_Koho", XKB_KEY_Mae_Koho },
- { "malesymbol", XKB_KEY_malesymbol },
- { "maltesecross", XKB_KEY_maltesecross },
- { "marker", XKB_KEY_marker },
- { "masculine", XKB_KEY_masculine },
- { "Massyo", XKB_KEY_Massyo },
- { "Menu", XKB_KEY_Menu },
- { "Meta_L", XKB_KEY_Meta_L },
- { "Meta_R", XKB_KEY_Meta_R },
- { "MillSign", XKB_KEY_MillSign },
- { "minus", XKB_KEY_minus },
- { "minutes", XKB_KEY_minutes },
- { "Mode_switch", XKB_KEY_Mode_switch },
- { "MouseKeys_Accel_Enable", XKB_KEY_MouseKeys_Accel_Enable },
- { "MouseKeys_Enable", XKB_KEY_MouseKeys_Enable },
- { "mu", XKB_KEY_mu },
- { "Muhenkan", XKB_KEY_Muhenkan },
- { "Multi_key", XKB_KEY_Multi_key },
- { "MultipleCandidate", XKB_KEY_MultipleCandidate },
- { "multiply", XKB_KEY_multiply },
- { "musicalflat", XKB_KEY_musicalflat },
- { "musicalsharp", XKB_KEY_musicalsharp },
- { "mute_acute", XKB_KEY_mute_acute },
- { "mute_asciicircum", XKB_KEY_mute_asciicircum },
- { "mute_asciitilde", XKB_KEY_mute_asciitilde },
- { "mute_diaeresis", XKB_KEY_mute_diaeresis },
- { "mute_grave", XKB_KEY_mute_grave },
- { "N", XKB_KEY_N },
- { "n", XKB_KEY_n },
- { "nabla", XKB_KEY_nabla },
- { "Nacute", XKB_KEY_Nacute },
- { "nacute", XKB_KEY_nacute },
- { "NairaSign", XKB_KEY_NairaSign },
- { "Ncaron", XKB_KEY_Ncaron },
- { "ncaron", XKB_KEY_ncaron },
- { "Ncedilla", XKB_KEY_Ncedilla },
- { "ncedilla", XKB_KEY_ncedilla },
- { "NewSheqelSign", XKB_KEY_NewSheqelSign },
- { "Next", XKB_KEY_Next },
- { "Next_Virtual_Screen", XKB_KEY_Next_Virtual_Screen },
- { "ninesubscript", XKB_KEY_ninesubscript },
- { "ninesuperior", XKB_KEY_ninesuperior },
- { "nl", XKB_KEY_nl },
- { "nobreakspace", XKB_KEY_nobreakspace },
- { "NoSymbol", XKB_KEY_NoSymbol },
- { "notapproxeq", XKB_KEY_notapproxeq },
- { "notelementof", XKB_KEY_notelementof },
- { "notequal", XKB_KEY_notequal },
- { "notidentical", XKB_KEY_notidentical },
- { "notsign", XKB_KEY_notsign },
- { "Ntilde", XKB_KEY_Ntilde },
- { "ntilde", XKB_KEY_ntilde },
- { "Num_Lock", XKB_KEY_Num_Lock },
- { "numbersign", XKB_KEY_numbersign },
- { "numerosign", XKB_KEY_numerosign },
- { "O", XKB_KEY_O },
- { "o", XKB_KEY_o },
- { "Oacute", XKB_KEY_Oacute },
- { "oacute", XKB_KEY_oacute },
- { "Obarred", XKB_KEY_Obarred },
- { "obarred", XKB_KEY_obarred },
- { "Obelowdot", XKB_KEY_Obelowdot },
- { "obelowdot", XKB_KEY_obelowdot },
- { "Ocaron", XKB_KEY_Ocaron },
- { "ocaron", XKB_KEY_ocaron },
- { "Ocircumflex", XKB_KEY_Ocircumflex },
- { "ocircumflex", XKB_KEY_ocircumflex },
- { "Ocircumflexacute", XKB_KEY_Ocircumflexacute },
- { "ocircumflexacute", XKB_KEY_ocircumflexacute },
- { "Ocircumflexbelowdot", XKB_KEY_Ocircumflexbelowdot },
- { "ocircumflexbelowdot", XKB_KEY_ocircumflexbelowdot },
- { "Ocircumflexgrave", XKB_KEY_Ocircumflexgrave },
- { "ocircumflexgrave", XKB_KEY_ocircumflexgrave },
- { "Ocircumflexhook", XKB_KEY_Ocircumflexhook },
- { "ocircumflexhook", XKB_KEY_ocircumflexhook },
- { "Ocircumflextilde", XKB_KEY_Ocircumflextilde },
- { "ocircumflextilde", XKB_KEY_ocircumflextilde },
- { "Odiaeresis", XKB_KEY_Odiaeresis },
- { "odiaeresis", XKB_KEY_odiaeresis },
- { "Odoubleacute", XKB_KEY_Odoubleacute },
- { "odoubleacute", XKB_KEY_odoubleacute },
- { "OE", XKB_KEY_OE },
- { "oe", XKB_KEY_oe },
- { "ogonek", XKB_KEY_ogonek },
- { "Ograve", XKB_KEY_Ograve },
- { "ograve", XKB_KEY_ograve },
- { "Ohook", XKB_KEY_Ohook },
- { "ohook", XKB_KEY_ohook },
- { "Ohorn", XKB_KEY_Ohorn },
- { "ohorn", XKB_KEY_ohorn },
- { "Ohornacute", XKB_KEY_Ohornacute },
- { "ohornacute", XKB_KEY_ohornacute },
- { "Ohornbelowdot", XKB_KEY_Ohornbelowdot },
- { "ohornbelowdot", XKB_KEY_ohornbelowdot },
- { "Ohorngrave", XKB_KEY_Ohorngrave },
- { "ohorngrave", XKB_KEY_ohorngrave },
- { "Ohornhook", XKB_KEY_Ohornhook },
- { "ohornhook", XKB_KEY_ohornhook },
- { "Ohorntilde", XKB_KEY_Ohorntilde },
- { "ohorntilde", XKB_KEY_ohorntilde },
- { "Omacron", XKB_KEY_Omacron },
- { "omacron", XKB_KEY_omacron },
- { "oneeighth", XKB_KEY_oneeighth },
- { "onefifth", XKB_KEY_onefifth },
- { "onehalf", XKB_KEY_onehalf },
- { "onequarter", XKB_KEY_onequarter },
- { "onesixth", XKB_KEY_onesixth },
- { "onesubscript", XKB_KEY_onesubscript },
- { "onesuperior", XKB_KEY_onesuperior },
- { "onethird", XKB_KEY_onethird },
- { "Ooblique", XKB_KEY_Ooblique },
- { "ooblique", XKB_KEY_ooblique },
- { "openrectbullet", XKB_KEY_openrectbullet },
- { "openstar", XKB_KEY_openstar },
- { "opentribulletdown", XKB_KEY_opentribulletdown },
- { "opentribulletup", XKB_KEY_opentribulletup },
- { "ordfeminine", XKB_KEY_ordfeminine },
- { "osfActivate", XKB_KEY_osfActivate },
- { "osfAddMode", XKB_KEY_osfAddMode },
- { "osfBackSpace", XKB_KEY_osfBackSpace },
- { "osfBackTab", XKB_KEY_osfBackTab },
- { "osfBeginData", XKB_KEY_osfBeginData },
- { "osfBeginLine", XKB_KEY_osfBeginLine },
- { "osfCancel", XKB_KEY_osfCancel },
- { "osfClear", XKB_KEY_osfClear },
- { "osfCopy", XKB_KEY_osfCopy },
- { "osfCut", XKB_KEY_osfCut },
- { "osfDelete", XKB_KEY_osfDelete },
- { "osfDeselectAll", XKB_KEY_osfDeselectAll },
- { "osfDown", XKB_KEY_osfDown },
- { "osfEndData", XKB_KEY_osfEndData },
- { "osfEndLine", XKB_KEY_osfEndLine },
- { "osfEscape", XKB_KEY_osfEscape },
- { "osfExtend", XKB_KEY_osfExtend },
- { "osfHelp", XKB_KEY_osfHelp },
- { "osfInsert", XKB_KEY_osfInsert },
- { "osfLeft", XKB_KEY_osfLeft },
- { "osfMenu", XKB_KEY_osfMenu },
- { "osfMenuBar", XKB_KEY_osfMenuBar },
- { "osfNextField", XKB_KEY_osfNextField },
- { "osfNextMenu", XKB_KEY_osfNextMenu },
- { "osfPageDown", XKB_KEY_osfPageDown },
- { "osfPageLeft", XKB_KEY_osfPageLeft },
- { "osfPageRight", XKB_KEY_osfPageRight },
- { "osfPageUp", XKB_KEY_osfPageUp },
- { "osfPaste", XKB_KEY_osfPaste },
- { "osfPrevField", XKB_KEY_osfPrevField },
- { "osfPrevMenu", XKB_KEY_osfPrevMenu },
- { "osfPrimaryPaste", XKB_KEY_osfPrimaryPaste },
- { "osfQuickPaste", XKB_KEY_osfQuickPaste },
- { "osfReselect", XKB_KEY_osfReselect },
- { "osfRestore", XKB_KEY_osfRestore },
- { "osfRight", XKB_KEY_osfRight },
- { "osfSelect", XKB_KEY_osfSelect },
- { "osfSelectAll", XKB_KEY_osfSelectAll },
- { "osfUndo", XKB_KEY_osfUndo },
- { "osfUp", XKB_KEY_osfUp },
- { "Oslash", XKB_KEY_Oslash },
- { "oslash", XKB_KEY_oslash },
- { "Otilde", XKB_KEY_Otilde },
- { "otilde", XKB_KEY_otilde },
- { "overbar", XKB_KEY_overbar },
- { "Overlay1_Enable", XKB_KEY_Overlay1_Enable },
- { "Overlay2_Enable", XKB_KEY_Overlay2_Enable },
- { "overline", XKB_KEY_overline },
- { "P", XKB_KEY_P },
- { "p", XKB_KEY_p },
- { "Pabovedot", XKB_KEY_Pabovedot },
- { "pabovedot", XKB_KEY_pabovedot },
- { "Page_Down", XKB_KEY_Page_Down },
- { "Page_Up", XKB_KEY_Page_Up },
- { "paragraph", XKB_KEY_paragraph },
- { "parenleft", XKB_KEY_parenleft },
- { "parenright", XKB_KEY_parenright },
- { "partdifferential", XKB_KEY_partdifferential },
- { "partialderivative", XKB_KEY_partialderivative },
- { "Pause", XKB_KEY_Pause },
- { "percent", XKB_KEY_percent },
- { "period", XKB_KEY_period },
- { "periodcentered", XKB_KEY_periodcentered },
- { "permille", XKB_KEY_permille },
- { "PesetaSign", XKB_KEY_PesetaSign },
- { "phonographcopyright", XKB_KEY_phonographcopyright },
- { "plus", XKB_KEY_plus },
- { "plusminus", XKB_KEY_plusminus },
- { "Pointer_Accelerate", XKB_KEY_Pointer_Accelerate },
- { "Pointer_Button1", XKB_KEY_Pointer_Button1 },
- { "Pointer_Button2", XKB_KEY_Pointer_Button2 },
- { "Pointer_Button3", XKB_KEY_Pointer_Button3 },
- { "Pointer_Button4", XKB_KEY_Pointer_Button4 },
- { "Pointer_Button5", XKB_KEY_Pointer_Button5 },
- { "Pointer_Button_Dflt", XKB_KEY_Pointer_Button_Dflt },
- { "Pointer_DblClick1", XKB_KEY_Pointer_DblClick1 },
- { "Pointer_DblClick2", XKB_KEY_Pointer_DblClick2 },
- { "Pointer_DblClick3", XKB_KEY_Pointer_DblClick3 },
- { "Pointer_DblClick4", XKB_KEY_Pointer_DblClick4 },
- { "Pointer_DblClick5", XKB_KEY_Pointer_DblClick5 },
- { "Pointer_DblClick_Dflt", XKB_KEY_Pointer_DblClick_Dflt },
- { "Pointer_DfltBtnNext", XKB_KEY_Pointer_DfltBtnNext },
- { "Pointer_DfltBtnPrev", XKB_KEY_Pointer_DfltBtnPrev },
- { "Pointer_Down", XKB_KEY_Pointer_Down },
- { "Pointer_DownLeft", XKB_KEY_Pointer_DownLeft },
- { "Pointer_DownRight", XKB_KEY_Pointer_DownRight },
- { "Pointer_Drag1", XKB_KEY_Pointer_Drag1 },
- { "Pointer_Drag2", XKB_KEY_Pointer_Drag2 },
- { "Pointer_Drag3", XKB_KEY_Pointer_Drag3 },
- { "Pointer_Drag4", XKB_KEY_Pointer_Drag4 },
- { "Pointer_Drag5", XKB_KEY_Pointer_Drag5 },
- { "Pointer_Drag_Dflt", XKB_KEY_Pointer_Drag_Dflt },
- { "Pointer_EnableKeys", XKB_KEY_Pointer_EnableKeys },
- { "Pointer_Left", XKB_KEY_Pointer_Left },
- { "Pointer_Right", XKB_KEY_Pointer_Right },
- { "Pointer_Up", XKB_KEY_Pointer_Up },
- { "Pointer_UpLeft", XKB_KEY_Pointer_UpLeft },
- { "Pointer_UpRight", XKB_KEY_Pointer_UpRight },
- { "prescription", XKB_KEY_prescription },
- { "Prev_Virtual_Screen", XKB_KEY_Prev_Virtual_Screen },
- { "PreviousCandidate", XKB_KEY_PreviousCandidate },
- { "Print", XKB_KEY_Print },
- { "Prior", XKB_KEY_Prior },
- { "prolongedsound", XKB_KEY_prolongedsound },
- { "punctspace", XKB_KEY_punctspace },
- { "Q", XKB_KEY_Q },
- { "q", XKB_KEY_q },
- { "quad", XKB_KEY_quad },
- { "question", XKB_KEY_question },
- { "questiondown", XKB_KEY_questiondown },
- { "quotedbl", XKB_KEY_quotedbl },
- { "quoteleft", XKB_KEY_quoteleft },
- { "quoteright", XKB_KEY_quoteright },
- { "R", XKB_KEY_R },
- { "r", XKB_KEY_r },
- { "R1", XKB_KEY_R1 },
- { "R10", XKB_KEY_R10 },
- { "R11", XKB_KEY_R11 },
- { "R12", XKB_KEY_R12 },
- { "R13", XKB_KEY_R13 },
- { "R14", XKB_KEY_R14 },
- { "R15", XKB_KEY_R15 },
- { "R2", XKB_KEY_R2 },
- { "R3", XKB_KEY_R3 },
- { "R4", XKB_KEY_R4 },
- { "R5", XKB_KEY_R5 },
- { "R6", XKB_KEY_R6 },
- { "R7", XKB_KEY_R7 },
- { "R8", XKB_KEY_R8 },
- { "R9", XKB_KEY_R9 },
- { "Racute", XKB_KEY_Racute },
- { "racute", XKB_KEY_racute },
- { "radical", XKB_KEY_radical },
- { "Rcaron", XKB_KEY_Rcaron },
- { "rcaron", XKB_KEY_rcaron },
- { "Rcedilla", XKB_KEY_Rcedilla },
- { "rcedilla", XKB_KEY_rcedilla },
- { "Redo", XKB_KEY_Redo },
- { "registered", XKB_KEY_registered },
- { "RepeatKeys_Enable", XKB_KEY_RepeatKeys_Enable },
- { "Reset", XKB_KEY_Reset },
- { "Return", XKB_KEY_Return },
- { "Right", XKB_KEY_Right },
- { "rightanglebracket", XKB_KEY_rightanglebracket },
- { "rightarrow", XKB_KEY_rightarrow },
- { "rightcaret", XKB_KEY_rightcaret },
- { "rightdoublequotemark", XKB_KEY_rightdoublequotemark },
- { "rightmiddlecurlybrace", XKB_KEY_rightmiddlecurlybrace },
- { "rightmiddlesummation", XKB_KEY_rightmiddlesummation },
- { "rightopentriangle", XKB_KEY_rightopentriangle },
- { "rightpointer", XKB_KEY_rightpointer },
- { "rightshoe", XKB_KEY_rightshoe },
- { "rightsinglequotemark", XKB_KEY_rightsinglequotemark },
- { "rightt", XKB_KEY_rightt },
- { "righttack", XKB_KEY_righttack },
- { "Romaji", XKB_KEY_Romaji },
- { "RupeeSign", XKB_KEY_RupeeSign },
- { "S", XKB_KEY_S },
- { "s", XKB_KEY_s },
- { "Sabovedot", XKB_KEY_Sabovedot },
- { "sabovedot", XKB_KEY_sabovedot },
- { "Sacute", XKB_KEY_Sacute },
- { "sacute", XKB_KEY_sacute },
- { "Scaron", XKB_KEY_Scaron },
- { "scaron", XKB_KEY_scaron },
- { "Scedilla", XKB_KEY_Scedilla },
- { "scedilla", XKB_KEY_scedilla },
- { "SCHWA", XKB_KEY_SCHWA },
- { "schwa", XKB_KEY_schwa },
- { "Scircumflex", XKB_KEY_Scircumflex },
- { "scircumflex", XKB_KEY_scircumflex },
- { "script_switch", XKB_KEY_script_switch },
- { "Scroll_Lock", XKB_KEY_Scroll_Lock },
- { "seconds", XKB_KEY_seconds },
- { "section", XKB_KEY_section },
- { "Select", XKB_KEY_Select },
- { "semicolon", XKB_KEY_semicolon },
- { "semivoicedsound", XKB_KEY_semivoicedsound },
- { "Serbian_dje", XKB_KEY_Serbian_dje },
- { "Serbian_DJE", XKB_KEY_Serbian_DJE },
- { "Serbian_dze", XKB_KEY_Serbian_dze },
- { "Serbian_DZE", XKB_KEY_Serbian_DZE },
- { "Serbian_je", XKB_KEY_Serbian_je },
- { "Serbian_JE", XKB_KEY_Serbian_JE },
- { "Serbian_lje", XKB_KEY_Serbian_lje },
- { "Serbian_LJE", XKB_KEY_Serbian_LJE },
- { "Serbian_nje", XKB_KEY_Serbian_nje },
- { "Serbian_NJE", XKB_KEY_Serbian_NJE },
- { "Serbian_tshe", XKB_KEY_Serbian_tshe },
- { "Serbian_TSHE", XKB_KEY_Serbian_TSHE },
- { "seveneighths", XKB_KEY_seveneighths },
- { "sevensubscript", XKB_KEY_sevensubscript },
- { "sevensuperior", XKB_KEY_sevensuperior },
- { "Shift_L", XKB_KEY_Shift_L },
- { "Shift_Lock", XKB_KEY_Shift_Lock },
- { "Shift_R", XKB_KEY_Shift_R },
- { "signaturemark", XKB_KEY_signaturemark },
- { "signifblank", XKB_KEY_signifblank },
- { "similarequal", XKB_KEY_similarequal },
- { "SingleCandidate", XKB_KEY_SingleCandidate },
- { "singlelowquotemark", XKB_KEY_singlelowquotemark },
- { "Sinh_a", XKB_KEY_Sinh_a },
- { "Sinh_aa", XKB_KEY_Sinh_aa },
- { "Sinh_aa2", XKB_KEY_Sinh_aa2 },
- { "Sinh_ae", XKB_KEY_Sinh_ae },
- { "Sinh_ae2", XKB_KEY_Sinh_ae2 },
- { "Sinh_aee", XKB_KEY_Sinh_aee },
- { "Sinh_aee2", XKB_KEY_Sinh_aee2 },
- { "Sinh_ai", XKB_KEY_Sinh_ai },
- { "Sinh_ai2", XKB_KEY_Sinh_ai2 },
- { "Sinh_al", XKB_KEY_Sinh_al },
- { "Sinh_au", XKB_KEY_Sinh_au },
- { "Sinh_au2", XKB_KEY_Sinh_au2 },
- { "Sinh_ba", XKB_KEY_Sinh_ba },
- { "Sinh_bha", XKB_KEY_Sinh_bha },
- { "Sinh_ca", XKB_KEY_Sinh_ca },
- { "Sinh_cha", XKB_KEY_Sinh_cha },
- { "Sinh_dda", XKB_KEY_Sinh_dda },
- { "Sinh_ddha", XKB_KEY_Sinh_ddha },
- { "Sinh_dha", XKB_KEY_Sinh_dha },
- { "Sinh_dhha", XKB_KEY_Sinh_dhha },
- { "Sinh_e", XKB_KEY_Sinh_e },
- { "Sinh_e2", XKB_KEY_Sinh_e2 },
- { "Sinh_ee", XKB_KEY_Sinh_ee },
- { "Sinh_ee2", XKB_KEY_Sinh_ee2 },
- { "Sinh_fa", XKB_KEY_Sinh_fa },
- { "Sinh_ga", XKB_KEY_Sinh_ga },
- { "Sinh_gha", XKB_KEY_Sinh_gha },
- { "Sinh_h2", XKB_KEY_Sinh_h2 },
- { "Sinh_ha", XKB_KEY_Sinh_ha },
- { "Sinh_i", XKB_KEY_Sinh_i },
- { "Sinh_i2", XKB_KEY_Sinh_i2 },
- { "Sinh_ii", XKB_KEY_Sinh_ii },
- { "Sinh_ii2", XKB_KEY_Sinh_ii2 },
- { "Sinh_ja", XKB_KEY_Sinh_ja },
- { "Sinh_jha", XKB_KEY_Sinh_jha },
- { "Sinh_jnya", XKB_KEY_Sinh_jnya },
- { "Sinh_ka", XKB_KEY_Sinh_ka },
- { "Sinh_kha", XKB_KEY_Sinh_kha },
- { "Sinh_kunddaliya", XKB_KEY_Sinh_kunddaliya },
- { "Sinh_la", XKB_KEY_Sinh_la },
- { "Sinh_lla", XKB_KEY_Sinh_lla },
- { "Sinh_lu", XKB_KEY_Sinh_lu },
- { "Sinh_lu2", XKB_KEY_Sinh_lu2 },
- { "Sinh_luu", XKB_KEY_Sinh_luu },
- { "Sinh_luu2", XKB_KEY_Sinh_luu2 },
- { "Sinh_ma", XKB_KEY_Sinh_ma },
- { "Sinh_mba", XKB_KEY_Sinh_mba },
- { "Sinh_na", XKB_KEY_Sinh_na },
- { "Sinh_ndda", XKB_KEY_Sinh_ndda },
- { "Sinh_ndha", XKB_KEY_Sinh_ndha },
- { "Sinh_ng", XKB_KEY_Sinh_ng },
- { "Sinh_ng2", XKB_KEY_Sinh_ng2 },
- { "Sinh_nga", XKB_KEY_Sinh_nga },
- { "Sinh_nja", XKB_KEY_Sinh_nja },
- { "Sinh_nna", XKB_KEY_Sinh_nna },
- { "Sinh_nya", XKB_KEY_Sinh_nya },
- { "Sinh_o", XKB_KEY_Sinh_o },
- { "Sinh_o2", XKB_KEY_Sinh_o2 },
- { "Sinh_oo", XKB_KEY_Sinh_oo },
- { "Sinh_oo2", XKB_KEY_Sinh_oo2 },
- { "Sinh_pa", XKB_KEY_Sinh_pa },
- { "Sinh_pha", XKB_KEY_Sinh_pha },
- { "Sinh_ra", XKB_KEY_Sinh_ra },
- { "Sinh_ri", XKB_KEY_Sinh_ri },
- { "Sinh_rii", XKB_KEY_Sinh_rii },
- { "Sinh_ru2", XKB_KEY_Sinh_ru2 },
- { "Sinh_ruu2", XKB_KEY_Sinh_ruu2 },
- { "Sinh_sa", XKB_KEY_Sinh_sa },
- { "Sinh_sha", XKB_KEY_Sinh_sha },
- { "Sinh_ssha", XKB_KEY_Sinh_ssha },
- { "Sinh_tha", XKB_KEY_Sinh_tha },
- { "Sinh_thha", XKB_KEY_Sinh_thha },
- { "Sinh_tta", XKB_KEY_Sinh_tta },
- { "Sinh_ttha", XKB_KEY_Sinh_ttha },
- { "Sinh_u", XKB_KEY_Sinh_u },
- { "Sinh_u2", XKB_KEY_Sinh_u2 },
- { "Sinh_uu", XKB_KEY_Sinh_uu },
- { "Sinh_uu2", XKB_KEY_Sinh_uu2 },
- { "Sinh_va", XKB_KEY_Sinh_va },
- { "Sinh_ya", XKB_KEY_Sinh_ya },
- { "sixsubscript", XKB_KEY_sixsubscript },
- { "sixsuperior", XKB_KEY_sixsuperior },
- { "slash", XKB_KEY_slash },
- { "SlowKeys_Enable", XKB_KEY_SlowKeys_Enable },
- { "soliddiamond", XKB_KEY_soliddiamond },
- { "space", XKB_KEY_space },
- { "squareroot", XKB_KEY_squareroot },
- { "ssharp", XKB_KEY_ssharp },
- { "sterling", XKB_KEY_sterling },
- { "StickyKeys_Enable", XKB_KEY_StickyKeys_Enable },
- { "stricteq", XKB_KEY_stricteq },
- { "SunAgain", XKB_KEY_SunAgain },
- { "SunAltGraph", XKB_KEY_SunAltGraph },
- { "SunAudioLowerVolume", XKB_KEY_SunAudioLowerVolume },
- { "SunAudioMute", XKB_KEY_SunAudioMute },
- { "SunAudioRaiseVolume", XKB_KEY_SunAudioRaiseVolume },
- { "SunCompose", XKB_KEY_SunCompose },
- { "SunCopy", XKB_KEY_SunCopy },
- { "SunCut", XKB_KEY_SunCut },
- { "SunF36", XKB_KEY_SunF36 },
- { "SunF37", XKB_KEY_SunF37 },
- { "SunFA_Acute", XKB_KEY_SunFA_Acute },
- { "SunFA_Cedilla", XKB_KEY_SunFA_Cedilla },
- { "SunFA_Circum", XKB_KEY_SunFA_Circum },
- { "SunFA_Diaeresis", XKB_KEY_SunFA_Diaeresis },
- { "SunFA_Grave", XKB_KEY_SunFA_Grave },
- { "SunFA_Tilde", XKB_KEY_SunFA_Tilde },
- { "SunFind", XKB_KEY_SunFind },
- { "SunFront", XKB_KEY_SunFront },
- { "SunOpen", XKB_KEY_SunOpen },
- { "SunPageDown", XKB_KEY_SunPageDown },
- { "SunPageUp", XKB_KEY_SunPageUp },
- { "SunPaste", XKB_KEY_SunPaste },
- { "SunPowerSwitch", XKB_KEY_SunPowerSwitch },
- { "SunPowerSwitchShift", XKB_KEY_SunPowerSwitchShift },
- { "SunPrint_Screen", XKB_KEY_SunPrint_Screen },
- { "SunProps", XKB_KEY_SunProps },
- { "SunStop", XKB_KEY_SunStop },
- { "SunSys_Req", XKB_KEY_SunSys_Req },
- { "SunUndo", XKB_KEY_SunUndo },
- { "SunVideoDegauss", XKB_KEY_SunVideoDegauss },
- { "SunVideoLowerBrightness", XKB_KEY_SunVideoLowerBrightness },
- { "SunVideoRaiseBrightness", XKB_KEY_SunVideoRaiseBrightness },
- { "Super_L", XKB_KEY_Super_L },
- { "Super_R", XKB_KEY_Super_R },
- { "Sys_Req", XKB_KEY_Sys_Req },
- { "System", XKB_KEY_System },
- { "T", XKB_KEY_T },
- { "t", XKB_KEY_t },
- { "Tab", XKB_KEY_Tab },
- { "Tabovedot", XKB_KEY_Tabovedot },
- { "tabovedot", XKB_KEY_tabovedot },
- { "Tcaron", XKB_KEY_Tcaron },
- { "tcaron", XKB_KEY_tcaron },
- { "Tcedilla", XKB_KEY_Tcedilla },
- { "tcedilla", XKB_KEY_tcedilla },
- { "telephone", XKB_KEY_telephone },
- { "telephonerecorder", XKB_KEY_telephonerecorder },
- { "Terminate_Server", XKB_KEY_Terminate_Server },
- { "Thai_baht", XKB_KEY_Thai_baht },
- { "Thai_bobaimai", XKB_KEY_Thai_bobaimai },
- { "Thai_chochan", XKB_KEY_Thai_chochan },
- { "Thai_chochang", XKB_KEY_Thai_chochang },
- { "Thai_choching", XKB_KEY_Thai_choching },
- { "Thai_chochoe", XKB_KEY_Thai_chochoe },
- { "Thai_dochada", XKB_KEY_Thai_dochada },
- { "Thai_dodek", XKB_KEY_Thai_dodek },
- { "Thai_fofa", XKB_KEY_Thai_fofa },
- { "Thai_fofan", XKB_KEY_Thai_fofan },
- { "Thai_hohip", XKB_KEY_Thai_hohip },
- { "Thai_honokhuk", XKB_KEY_Thai_honokhuk },
- { "Thai_khokhai", XKB_KEY_Thai_khokhai },
- { "Thai_khokhon", XKB_KEY_Thai_khokhon },
- { "Thai_khokhuat", XKB_KEY_Thai_khokhuat },
- { "Thai_khokhwai", XKB_KEY_Thai_khokhwai },
- { "Thai_khorakhang", XKB_KEY_Thai_khorakhang },
- { "Thai_kokai", XKB_KEY_Thai_kokai },
- { "Thai_lakkhangyao", XKB_KEY_Thai_lakkhangyao },
- { "Thai_lekchet", XKB_KEY_Thai_lekchet },
- { "Thai_lekha", XKB_KEY_Thai_lekha },
- { "Thai_lekhok", XKB_KEY_Thai_lekhok },
- { "Thai_lekkao", XKB_KEY_Thai_lekkao },
- { "Thai_leknung", XKB_KEY_Thai_leknung },
- { "Thai_lekpaet", XKB_KEY_Thai_lekpaet },
- { "Thai_leksam", XKB_KEY_Thai_leksam },
- { "Thai_leksi", XKB_KEY_Thai_leksi },
- { "Thai_leksong", XKB_KEY_Thai_leksong },
- { "Thai_leksun", XKB_KEY_Thai_leksun },
- { "Thai_lochula", XKB_KEY_Thai_lochula },
- { "Thai_loling", XKB_KEY_Thai_loling },
- { "Thai_lu", XKB_KEY_Thai_lu },
- { "Thai_maichattawa", XKB_KEY_Thai_maichattawa },
- { "Thai_maiek", XKB_KEY_Thai_maiek },
- { "Thai_maihanakat", XKB_KEY_Thai_maihanakat },
- { "Thai_maihanakat_maitho", XKB_KEY_Thai_maihanakat_maitho },
- { "Thai_maitaikhu", XKB_KEY_Thai_maitaikhu },
- { "Thai_maitho", XKB_KEY_Thai_maitho },
- { "Thai_maitri", XKB_KEY_Thai_maitri },
- { "Thai_maiyamok", XKB_KEY_Thai_maiyamok },
- { "Thai_moma", XKB_KEY_Thai_moma },
- { "Thai_ngongu", XKB_KEY_Thai_ngongu },
- { "Thai_nikhahit", XKB_KEY_Thai_nikhahit },
- { "Thai_nonen", XKB_KEY_Thai_nonen },
- { "Thai_nonu", XKB_KEY_Thai_nonu },
- { "Thai_oang", XKB_KEY_Thai_oang },
- { "Thai_paiyannoi", XKB_KEY_Thai_paiyannoi },
- { "Thai_phinthu", XKB_KEY_Thai_phinthu },
- { "Thai_phophan", XKB_KEY_Thai_phophan },
- { "Thai_phophung", XKB_KEY_Thai_phophung },
- { "Thai_phosamphao", XKB_KEY_Thai_phosamphao },
- { "Thai_popla", XKB_KEY_Thai_popla },
- { "Thai_rorua", XKB_KEY_Thai_rorua },
- { "Thai_ru", XKB_KEY_Thai_ru },
- { "Thai_saraa", XKB_KEY_Thai_saraa },
- { "Thai_saraaa", XKB_KEY_Thai_saraaa },
- { "Thai_saraae", XKB_KEY_Thai_saraae },
- { "Thai_saraaimaimalai", XKB_KEY_Thai_saraaimaimalai },
- { "Thai_saraaimaimuan", XKB_KEY_Thai_saraaimaimuan },
- { "Thai_saraam", XKB_KEY_Thai_saraam },
- { "Thai_sarae", XKB_KEY_Thai_sarae },
- { "Thai_sarai", XKB_KEY_Thai_sarai },
- { "Thai_saraii", XKB_KEY_Thai_saraii },
- { "Thai_sarao", XKB_KEY_Thai_sarao },
- { "Thai_sarau", XKB_KEY_Thai_sarau },
- { "Thai_saraue", XKB_KEY_Thai_saraue },
- { "Thai_sarauee", XKB_KEY_Thai_sarauee },
- { "Thai_sarauu", XKB_KEY_Thai_sarauu },
- { "Thai_sorusi", XKB_KEY_Thai_sorusi },
- { "Thai_sosala", XKB_KEY_Thai_sosala },
- { "Thai_soso", XKB_KEY_Thai_soso },
- { "Thai_sosua", XKB_KEY_Thai_sosua },
- { "Thai_thanthakhat", XKB_KEY_Thai_thanthakhat },
- { "Thai_thonangmontho", XKB_KEY_Thai_thonangmontho },
- { "Thai_thophuthao", XKB_KEY_Thai_thophuthao },
- { "Thai_thothahan", XKB_KEY_Thai_thothahan },
- { "Thai_thothan", XKB_KEY_Thai_thothan },
- { "Thai_thothong", XKB_KEY_Thai_thothong },
- { "Thai_thothung", XKB_KEY_Thai_thothung },
- { "Thai_topatak", XKB_KEY_Thai_topatak },
- { "Thai_totao", XKB_KEY_Thai_totao },
- { "Thai_wowaen", XKB_KEY_Thai_wowaen },
- { "Thai_yoyak", XKB_KEY_Thai_yoyak },
- { "Thai_yoying", XKB_KEY_Thai_yoying },
- { "therefore", XKB_KEY_therefore },
- { "thinspace", XKB_KEY_thinspace },
- { "THORN", XKB_KEY_THORN },
- { "Thorn", XKB_KEY_Thorn },
- { "thorn", XKB_KEY_thorn },
- { "threeeighths", XKB_KEY_threeeighths },
- { "threefifths", XKB_KEY_threefifths },
- { "threequarters", XKB_KEY_threequarters },
- { "threesubscript", XKB_KEY_threesubscript },
- { "threesuperior", XKB_KEY_threesuperior },
- { "tintegral", XKB_KEY_tintegral },
- { "topintegral", XKB_KEY_topintegral },
- { "topleftparens", XKB_KEY_topleftparens },
- { "topleftradical", XKB_KEY_topleftradical },
- { "topleftsqbracket", XKB_KEY_topleftsqbracket },
- { "topleftsummation", XKB_KEY_topleftsummation },
- { "toprightparens", XKB_KEY_toprightparens },
- { "toprightsqbracket", XKB_KEY_toprightsqbracket },
- { "toprightsummation", XKB_KEY_toprightsummation },
- { "topt", XKB_KEY_topt },
- { "topvertsummationconnector", XKB_KEY_topvertsummationconnector },
- { "Touroku", XKB_KEY_Touroku },
- { "trademark", XKB_KEY_trademark },
- { "trademarkincircle", XKB_KEY_trademarkincircle },
- { "Tslash", XKB_KEY_Tslash },
- { "tslash", XKB_KEY_tslash },
- { "twofifths", XKB_KEY_twofifths },
- { "twosubscript", XKB_KEY_twosubscript },
- { "twosuperior", XKB_KEY_twosuperior },
- { "twothirds", XKB_KEY_twothirds },
- { "U", XKB_KEY_U },
- { "u", XKB_KEY_u },
- { "Uacute", XKB_KEY_Uacute },
- { "uacute", XKB_KEY_uacute },
- { "Ubelowdot", XKB_KEY_Ubelowdot },
- { "ubelowdot", XKB_KEY_ubelowdot },
- { "Ubreve", XKB_KEY_Ubreve },
- { "ubreve", XKB_KEY_ubreve },
- { "Ucircumflex", XKB_KEY_Ucircumflex },
- { "ucircumflex", XKB_KEY_ucircumflex },
- { "Udiaeresis", XKB_KEY_Udiaeresis },
- { "udiaeresis", XKB_KEY_udiaeresis },
- { "Udoubleacute", XKB_KEY_Udoubleacute },
- { "udoubleacute", XKB_KEY_udoubleacute },
- { "Ugrave", XKB_KEY_Ugrave },
- { "ugrave", XKB_KEY_ugrave },
- { "Uhook", XKB_KEY_Uhook },
- { "uhook", XKB_KEY_uhook },
- { "Uhorn", XKB_KEY_Uhorn },
- { "uhorn", XKB_KEY_uhorn },
- { "Uhornacute", XKB_KEY_Uhornacute },
- { "uhornacute", XKB_KEY_uhornacute },
- { "Uhornbelowdot", XKB_KEY_Uhornbelowdot },
- { "uhornbelowdot", XKB_KEY_uhornbelowdot },
- { "Uhorngrave", XKB_KEY_Uhorngrave },
- { "uhorngrave", XKB_KEY_uhorngrave },
- { "Uhornhook", XKB_KEY_Uhornhook },
- { "uhornhook", XKB_KEY_uhornhook },
- { "Uhorntilde", XKB_KEY_Uhorntilde },
- { "uhorntilde", XKB_KEY_uhorntilde },
- { "Ukrainian_ghe_with_upturn", XKB_KEY_Ukrainian_ghe_with_upturn },
- { "Ukrainian_GHE_WITH_UPTURN", XKB_KEY_Ukrainian_GHE_WITH_UPTURN },
- { "Ukrainian_i", XKB_KEY_Ukrainian_i },
- { "Ukrainian_I", XKB_KEY_Ukrainian_I },
- { "Ukrainian_ie", XKB_KEY_Ukrainian_ie },
- { "Ukrainian_IE", XKB_KEY_Ukrainian_IE },
- { "Ukrainian_yi", XKB_KEY_Ukrainian_yi },
- { "Ukrainian_YI", XKB_KEY_Ukrainian_YI },
- { "Ukranian_i", XKB_KEY_Ukranian_i },
- { "Ukranian_I", XKB_KEY_Ukranian_I },
- { "Ukranian_je", XKB_KEY_Ukranian_je },
- { "Ukranian_JE", XKB_KEY_Ukranian_JE },
- { "Ukranian_yi", XKB_KEY_Ukranian_yi },
- { "Ukranian_YI", XKB_KEY_Ukranian_YI },
- { "Umacron", XKB_KEY_Umacron },
- { "umacron", XKB_KEY_umacron },
- { "underbar", XKB_KEY_underbar },
- { "underscore", XKB_KEY_underscore },
- { "Undo", XKB_KEY_Undo },
- { "union", XKB_KEY_union },
- { "Uogonek", XKB_KEY_Uogonek },
- { "uogonek", XKB_KEY_uogonek },
- { "Up", XKB_KEY_Up },
- { "uparrow", XKB_KEY_uparrow },
- { "upcaret", XKB_KEY_upcaret },
- { "upleftcorner", XKB_KEY_upleftcorner },
- { "uprightcorner", XKB_KEY_uprightcorner },
- { "upshoe", XKB_KEY_upshoe },
- { "upstile", XKB_KEY_upstile },
- { "uptack", XKB_KEY_uptack },
- { "Uring", XKB_KEY_Uring },
- { "uring", XKB_KEY_uring },
- { "User", XKB_KEY_User },
- { "Utilde", XKB_KEY_Utilde },
- { "utilde", XKB_KEY_utilde },
- { "V", XKB_KEY_V },
- { "v", XKB_KEY_v },
- { "variation", XKB_KEY_variation },
- { "vertbar", XKB_KEY_vertbar },
- { "vertconnector", XKB_KEY_vertconnector },
- { "voicedsound", XKB_KEY_voicedsound },
- { "VoidSymbol", XKB_KEY_VoidSymbol },
- { "vt", XKB_KEY_vt },
- { "W", XKB_KEY_W },
- { "w", XKB_KEY_w },
- { "Wacute", XKB_KEY_Wacute },
- { "wacute", XKB_KEY_wacute },
- { "Wcircumflex", XKB_KEY_Wcircumflex },
- { "wcircumflex", XKB_KEY_wcircumflex },
- { "Wdiaeresis", XKB_KEY_Wdiaeresis },
- { "wdiaeresis", XKB_KEY_wdiaeresis },
- { "Wgrave", XKB_KEY_Wgrave },
- { "wgrave", XKB_KEY_wgrave },
- { "WonSign", XKB_KEY_WonSign },
- { "X", XKB_KEY_X },
- { "x", XKB_KEY_x },
- { "Xabovedot", XKB_KEY_Xabovedot },
- { "xabovedot", XKB_KEY_xabovedot },
- { "XF86AddFavorite", XKB_KEY_XF86AddFavorite },
- { "XF86ApplicationLeft", XKB_KEY_XF86ApplicationLeft },
- { "XF86ApplicationRight", XKB_KEY_XF86ApplicationRight },
- { "XF86AudioCycleTrack", XKB_KEY_XF86AudioCycleTrack },
- { "XF86AudioForward", XKB_KEY_XF86AudioForward },
- { "XF86AudioLowerVolume", XKB_KEY_XF86AudioLowerVolume },
- { "XF86AudioMedia", XKB_KEY_XF86AudioMedia },
- { "XF86AudioMute", XKB_KEY_XF86AudioMute },
- { "XF86AudioNext", XKB_KEY_XF86AudioNext },
- { "XF86AudioPause", XKB_KEY_XF86AudioPause },
- { "XF86AudioPlay", XKB_KEY_XF86AudioPlay },
- { "XF86AudioPrev", XKB_KEY_XF86AudioPrev },
- { "XF86AudioRaiseVolume", XKB_KEY_XF86AudioRaiseVolume },
- { "XF86AudioRandomPlay", XKB_KEY_XF86AudioRandomPlay },
- { "XF86AudioRecord", XKB_KEY_XF86AudioRecord },
- { "XF86AudioRepeat", XKB_KEY_XF86AudioRepeat },
- { "XF86AudioRewind", XKB_KEY_XF86AudioRewind },
- { "XF86AudioStop", XKB_KEY_XF86AudioStop },
- { "XF86Away", XKB_KEY_XF86Away },
- { "XF86Back", XKB_KEY_XF86Back },
- { "XF86BackForward", XKB_KEY_XF86BackForward },
- { "XF86Battery", XKB_KEY_XF86Battery },
- { "XF86Blue", XKB_KEY_XF86Blue },
- { "XF86Bluetooth", XKB_KEY_XF86Bluetooth },
- { "XF86Book", XKB_KEY_XF86Book },
- { "XF86BrightnessAdjust", XKB_KEY_XF86BrightnessAdjust },
- { "XF86Calculater", XKB_KEY_XF86Calculater },
- { "XF86Calculator", XKB_KEY_XF86Calculator },
- { "XF86Calendar", XKB_KEY_XF86Calendar },
- { "XF86CD", XKB_KEY_XF86CD },
- { "XF86Clear", XKB_KEY_XF86Clear },
- { "XF86ClearGrab", XKB_KEY_XF86ClearGrab },
- { "XF86Close", XKB_KEY_XF86Close },
- { "XF86Community", XKB_KEY_XF86Community },
- { "XF86ContrastAdjust", XKB_KEY_XF86ContrastAdjust },
- { "XF86Copy", XKB_KEY_XF86Copy },
- { "XF86Cut", XKB_KEY_XF86Cut },
- { "XF86CycleAngle", XKB_KEY_XF86CycleAngle },
- { "XF86Display", XKB_KEY_XF86Display },
- { "XF86Documents", XKB_KEY_XF86Documents },
- { "XF86DOS", XKB_KEY_XF86DOS },
- { "XF86Eject", XKB_KEY_XF86Eject },
- { "XF86Excel", XKB_KEY_XF86Excel },
- { "XF86Explorer", XKB_KEY_XF86Explorer },
- { "XF86Favorites", XKB_KEY_XF86Favorites },
- { "XF86Finance", XKB_KEY_XF86Finance },
- { "XF86Forward", XKB_KEY_XF86Forward },
- { "XF86FrameBack", XKB_KEY_XF86FrameBack },
- { "XF86FrameForward", XKB_KEY_XF86FrameForward },
- { "XF86Game", XKB_KEY_XF86Game },
- { "XF86Go", XKB_KEY_XF86Go },
- { "XF86Green", XKB_KEY_XF86Green },
- { "XF86Hibernate", XKB_KEY_XF86Hibernate },
- { "XF86History", XKB_KEY_XF86History },
- { "XF86HomePage", XKB_KEY_XF86HomePage },
- { "XF86HotLinks", XKB_KEY_XF86HotLinks },
- { "XF86iTouch", XKB_KEY_XF86iTouch },
- { "XF86KbdBrightnessDown", XKB_KEY_XF86KbdBrightnessDown },
- { "XF86KbdBrightnessUp", XKB_KEY_XF86KbdBrightnessUp },
- { "XF86KbdLightOnOff", XKB_KEY_XF86KbdLightOnOff },
- { "XF86Launch0", XKB_KEY_XF86Launch0 },
- { "XF86Launch1", XKB_KEY_XF86Launch1 },
- { "XF86Launch2", XKB_KEY_XF86Launch2 },
- { "XF86Launch3", XKB_KEY_XF86Launch3 },
- { "XF86Launch4", XKB_KEY_XF86Launch4 },
- { "XF86Launch5", XKB_KEY_XF86Launch5 },
- { "XF86Launch6", XKB_KEY_XF86Launch6 },
- { "XF86Launch7", XKB_KEY_XF86Launch7 },
- { "XF86Launch8", XKB_KEY_XF86Launch8 },
- { "XF86Launch9", XKB_KEY_XF86Launch9 },
- { "XF86LaunchA", XKB_KEY_XF86LaunchA },
- { "XF86LaunchB", XKB_KEY_XF86LaunchB },
- { "XF86LaunchC", XKB_KEY_XF86LaunchC },
- { "XF86LaunchD", XKB_KEY_XF86LaunchD },
- { "XF86LaunchE", XKB_KEY_XF86LaunchE },
- { "XF86LaunchF", XKB_KEY_XF86LaunchF },
- { "XF86LightBulb", XKB_KEY_XF86LightBulb },
- { "XF86LogGrabInfo", XKB_KEY_XF86LogGrabInfo },
- { "XF86LogOff", XKB_KEY_XF86LogOff },
- { "XF86LogWindowTree", XKB_KEY_XF86LogWindowTree },
- { "XF86Mail", XKB_KEY_XF86Mail },
- { "XF86MailForward", XKB_KEY_XF86MailForward },
- { "XF86Market", XKB_KEY_XF86Market },
- { "XF86Meeting", XKB_KEY_XF86Meeting },
- { "XF86Memo", XKB_KEY_XF86Memo },
- { "XF86MenuKB", XKB_KEY_XF86MenuKB },
- { "XF86MenuPB", XKB_KEY_XF86MenuPB },
- { "XF86Messenger", XKB_KEY_XF86Messenger },
- { "XF86ModeLock", XKB_KEY_XF86ModeLock },
- { "XF86MonBrightnessDown", XKB_KEY_XF86MonBrightnessDown },
- { "XF86MonBrightnessUp", XKB_KEY_XF86MonBrightnessUp },
- { "XF86Music", XKB_KEY_XF86Music },
- { "XF86MyComputer", XKB_KEY_XF86MyComputer },
- { "XF86MySites", XKB_KEY_XF86MySites },
- { "XF86New", XKB_KEY_XF86New },
- { "XF86News", XKB_KEY_XF86News },
- { "XF86Next_VMode", XKB_KEY_XF86Next_VMode },
- { "XF86OfficeHome", XKB_KEY_XF86OfficeHome },
- { "XF86Open", XKB_KEY_XF86Open },
- { "XF86OpenURL", XKB_KEY_XF86OpenURL },
- { "XF86Option", XKB_KEY_XF86Option },
- { "XF86Paste", XKB_KEY_XF86Paste },
- { "XF86Phone", XKB_KEY_XF86Phone },
- { "XF86Pictures", XKB_KEY_XF86Pictures },
- { "XF86PowerDown", XKB_KEY_XF86PowerDown },
- { "XF86PowerOff", XKB_KEY_XF86PowerOff },
- { "XF86Prev_VMode", XKB_KEY_XF86Prev_VMode },
- { "XF86Q", XKB_KEY_XF86Q },
- { "XF86Red", XKB_KEY_XF86Red },
- { "XF86Refresh", XKB_KEY_XF86Refresh },
- { "XF86Reload", XKB_KEY_XF86Reload },
- { "XF86Reply", XKB_KEY_XF86Reply },
- { "XF86RockerDown", XKB_KEY_XF86RockerDown },
- { "XF86RockerEnter", XKB_KEY_XF86RockerEnter },
- { "XF86RockerUp", XKB_KEY_XF86RockerUp },
- { "XF86RotateWindows", XKB_KEY_XF86RotateWindows },
- { "XF86RotationKB", XKB_KEY_XF86RotationKB },
- { "XF86RotationPB", XKB_KEY_XF86RotationPB },
- { "XF86Save", XKB_KEY_XF86Save },
- { "XF86ScreenSaver", XKB_KEY_XF86ScreenSaver },
- { "XF86ScrollClick", XKB_KEY_XF86ScrollClick },
- { "XF86ScrollDown", XKB_KEY_XF86ScrollDown },
- { "XF86ScrollUp", XKB_KEY_XF86ScrollUp },
- { "XF86Search", XKB_KEY_XF86Search },
- { "XF86Select", XKB_KEY_XF86Select },
- { "XF86Send", XKB_KEY_XF86Send },
- { "XF86Shop", XKB_KEY_XF86Shop },
- { "XF86Sleep", XKB_KEY_XF86Sleep },
- { "XF86Spell", XKB_KEY_XF86Spell },
- { "XF86SplitScreen", XKB_KEY_XF86SplitScreen },
- { "XF86Standby", XKB_KEY_XF86Standby },
- { "XF86Start", XKB_KEY_XF86Start },
- { "XF86Stop", XKB_KEY_XF86Stop },
- { "XF86Subtitle", XKB_KEY_XF86Subtitle },
- { "XF86Support", XKB_KEY_XF86Support },
- { "XF86Suspend", XKB_KEY_XF86Suspend },
- { "XF86Switch_VT_1", XKB_KEY_XF86Switch_VT_1 },
- { "XF86Switch_VT_10", XKB_KEY_XF86Switch_VT_10 },
- { "XF86Switch_VT_11", XKB_KEY_XF86Switch_VT_11 },
- { "XF86Switch_VT_12", XKB_KEY_XF86Switch_VT_12 },
- { "XF86Switch_VT_2", XKB_KEY_XF86Switch_VT_2 },
- { "XF86Switch_VT_3", XKB_KEY_XF86Switch_VT_3 },
- { "XF86Switch_VT_4", XKB_KEY_XF86Switch_VT_4 },
- { "XF86Switch_VT_5", XKB_KEY_XF86Switch_VT_5 },
- { "XF86Switch_VT_6", XKB_KEY_XF86Switch_VT_6 },
- { "XF86Switch_VT_7", XKB_KEY_XF86Switch_VT_7 },
- { "XF86Switch_VT_8", XKB_KEY_XF86Switch_VT_8 },
- { "XF86Switch_VT_9", XKB_KEY_XF86Switch_VT_9 },
- { "XF86TaskPane", XKB_KEY_XF86TaskPane },
- { "XF86Terminal", XKB_KEY_XF86Terminal },
- { "XF86Time", XKB_KEY_XF86Time },
- { "XF86ToDoList", XKB_KEY_XF86ToDoList },
- { "XF86Tools", XKB_KEY_XF86Tools },
- { "XF86TopMenu", XKB_KEY_XF86TopMenu },
- { "XF86TouchpadOff", XKB_KEY_XF86TouchpadOff },
- { "XF86TouchpadOn", XKB_KEY_XF86TouchpadOn },
- { "XF86TouchpadToggle", XKB_KEY_XF86TouchpadToggle },
- { "XF86Travel", XKB_KEY_XF86Travel },
- { "XF86Ungrab", XKB_KEY_XF86Ungrab },
- { "XF86User1KB", XKB_KEY_XF86User1KB },
- { "XF86User2KB", XKB_KEY_XF86User2KB },
- { "XF86UserPB", XKB_KEY_XF86UserPB },
- { "XF86UWB", XKB_KEY_XF86UWB },
- { "XF86VendorHome", XKB_KEY_XF86VendorHome },
- { "XF86Video", XKB_KEY_XF86Video },
- { "XF86View", XKB_KEY_XF86View },
- { "XF86WakeUp", XKB_KEY_XF86WakeUp },
- { "XF86WebCam", XKB_KEY_XF86WebCam },
- { "XF86WheelButton", XKB_KEY_XF86WheelButton },
- { "XF86WLAN", XKB_KEY_XF86WLAN },
- { "XF86Word", XKB_KEY_XF86Word },
- { "XF86WWW", XKB_KEY_XF86WWW },
- { "XF86Xfer", XKB_KEY_XF86Xfer },
- { "XF86Yellow", XKB_KEY_XF86Yellow },
- { "XF86ZoomIn", XKB_KEY_XF86ZoomIn },
- { "XF86ZoomOut", XKB_KEY_XF86ZoomOut },
- { "Y", XKB_KEY_Y },
- { "y", XKB_KEY_y },
- { "Yacute", XKB_KEY_Yacute },
- { "yacute", XKB_KEY_yacute },
- { "Ybelowdot", XKB_KEY_Ybelowdot },
- { "ybelowdot", XKB_KEY_ybelowdot },
- { "Ycircumflex", XKB_KEY_Ycircumflex },
- { "ycircumflex", XKB_KEY_ycircumflex },
- { "ydiaeresis", XKB_KEY_ydiaeresis },
- { "Ydiaeresis", XKB_KEY_Ydiaeresis },
- { "yen", XKB_KEY_yen },
- { "Ygrave", XKB_KEY_Ygrave },
- { "ygrave", XKB_KEY_ygrave },
- { "Yhook", XKB_KEY_Yhook },
- { "yhook", XKB_KEY_yhook },
- { "Ytilde", XKB_KEY_Ytilde },
- { "ytilde", XKB_KEY_ytilde },
- { "Z", XKB_KEY_Z },
- { "z", XKB_KEY_z },
- { "Zabovedot", XKB_KEY_Zabovedot },
- { "zabovedot", XKB_KEY_zabovedot },
- { "Zacute", XKB_KEY_Zacute },
- { "zacute", XKB_KEY_zacute },
- { "Zcaron", XKB_KEY_Zcaron },
- { "zcaron", XKB_KEY_zcaron },
- { "Zen_Koho", XKB_KEY_Zen_Koho },
- { "Zenkaku", XKB_KEY_Zenkaku },
- { "Zenkaku_Hankaku", XKB_KEY_Zenkaku_Hankaku },
- { "zerosubscript", XKB_KEY_zerosubscript },
- { "zerosuperior", XKB_KEY_zerosuperior },
- { "Zstroke", XKB_KEY_Zstroke },
- { "zstroke", XKB_KEY_zstroke },
+ { 0x00000030, 0 }, /* 0 */
+ { 0x00000031, 2 }, /* 1 */
+ { 0x00000032, 4 }, /* 2 */
+ { 0x00000033, 6 }, /* 3 */
+ { 0x0000fd10, 8 }, /* 3270_AltCursor */
+ { 0x0000fd0e, 23 }, /* 3270_Attn */
+ { 0x0000fd05, 33 }, /* 3270_BackTab */
+ { 0x0000fd19, 46 }, /* 3270_ChangeScreen */
+ { 0x0000fd15, 64 }, /* 3270_Copy */
+ { 0x0000fd0f, 74 }, /* 3270_CursorBlink */
+ { 0x0000fd1c, 91 }, /* 3270_CursorSelect */
+ { 0x0000fd1a, 109 }, /* 3270_DeleteWord */
+ { 0x0000fd01, 125 }, /* 3270_Duplicate */
+ { 0x0000fd1e, 140 }, /* 3270_Enter */
+ { 0x0000fd06, 151 }, /* 3270_EraseEOF */
+ { 0x0000fd07, 165 }, /* 3270_EraseInput */
+ { 0x0000fd1b, 181 }, /* 3270_ExSelect */
+ { 0x0000fd02, 195 }, /* 3270_FieldMark */
+ { 0x0000fd13, 210 }, /* 3270_Ident */
+ { 0x0000fd12, 221 }, /* 3270_Jump */
+ { 0x0000fd11, 231 }, /* 3270_KeyClick */
+ { 0x0000fd04, 245 }, /* 3270_Left2 */
+ { 0x0000fd0a, 256 }, /* 3270_PA1 */
+ { 0x0000fd0b, 265 }, /* 3270_PA2 */
+ { 0x0000fd0c, 274 }, /* 3270_PA3 */
+ { 0x0000fd16, 283 }, /* 3270_Play */
+ { 0x0000fd1d, 293 }, /* 3270_PrintScreen */
+ { 0x0000fd09, 310 }, /* 3270_Quit */
+ { 0x0000fd18, 320 }, /* 3270_Record */
+ { 0x0000fd08, 332 }, /* 3270_Reset */
+ { 0x0000fd03, 343 }, /* 3270_Right2 */
+ { 0x0000fd14, 355 }, /* 3270_Rule */
+ { 0x0000fd17, 365 }, /* 3270_Setup */
+ { 0x0000fd0d, 376 }, /* 3270_Test */
+ { 0x00000034, 386 }, /* 4 */
+ { 0x00000035, 388 }, /* 5 */
+ { 0x00000036, 390 }, /* 6 */
+ { 0x00000037, 392 }, /* 7 */
+ { 0x00000038, 394 }, /* 8 */
+ { 0x00000039, 396 }, /* 9 */
+ { 0x00000041, 398 }, /* A */
+ { 0x00000061, 400 }, /* a */
+ { 0x000000c1, 402 }, /* Aacute */
+ { 0x000000e1, 409 }, /* aacute */
+ { 0x01001ea0, 416 }, /* Abelowdot */
+ { 0x01001ea1, 426 }, /* abelowdot */
+ { 0x000001ff, 436 }, /* abovedot */
+ { 0x000001c3, 445 }, /* Abreve */
+ { 0x000001e3, 452 }, /* abreve */
+ { 0x01001eae, 459 }, /* Abreveacute */
+ { 0x01001eaf, 471 }, /* abreveacute */
+ { 0x01001eb6, 483 }, /* Abrevebelowdot */
+ { 0x01001eb7, 498 }, /* abrevebelowdot */
+ { 0x01001eb0, 513 }, /* Abrevegrave */
+ { 0x01001eb1, 525 }, /* abrevegrave */
+ { 0x01001eb2, 537 }, /* Abrevehook */
+ { 0x01001eb3, 548 }, /* abrevehook */
+ { 0x01001eb4, 559 }, /* Abrevetilde */
+ { 0x01001eb5, 571 }, /* abrevetilde */
+ { 0x0000fe70, 583 }, /* AccessX_Enable */
+ { 0x0000fe71, 598 }, /* AccessX_Feedback_Enable */
+ { 0x000000c2, 622 }, /* Acircumflex */
+ { 0x000000e2, 634 }, /* acircumflex */
+ { 0x01001ea4, 646 }, /* Acircumflexacute */
+ { 0x01001ea5, 663 }, /* acircumflexacute */
+ { 0x01001eac, 680 }, /* Acircumflexbelowdot */
+ { 0x01001ead, 700 }, /* acircumflexbelowdot */
+ { 0x01001ea6, 720 }, /* Acircumflexgrave */
+ { 0x01001ea7, 737 }, /* acircumflexgrave */
+ { 0x01001ea8, 754 }, /* Acircumflexhook */
+ { 0x01001ea9, 770 }, /* acircumflexhook */
+ { 0x01001eaa, 786 }, /* Acircumflextilde */
+ { 0x01001eab, 803 }, /* acircumflextilde */
+ { 0x000000b4, 820 }, /* acute */
+ { 0x000000c4, 826 }, /* Adiaeresis */
+ { 0x000000e4, 837 }, /* adiaeresis */
+ { 0x000000c6, 848 }, /* AE */
+ { 0x000000e6, 851 }, /* ae */
+ { 0x000000c0, 854 }, /* Agrave */
+ { 0x000000e0, 861 }, /* agrave */
+ { 0x01001ea2, 868 }, /* Ahook */
+ { 0x01001ea3, 874 }, /* ahook */
+ { 0x0000ffe9, 880 }, /* Alt_L */
+ { 0x0000ffea, 886 }, /* Alt_R */
+ { 0x000003c0, 892 }, /* Amacron */
+ { 0x000003e0, 900 }, /* amacron */
+ { 0x00000026, 908 }, /* ampersand */
+ { 0x000001a1, 918 }, /* Aogonek */
+ { 0x000001b1, 926 }, /* aogonek */
+ { 0x00000027, 934 }, /* apostrophe */
+ { 0x01002248, 945 }, /* approxeq */
+ { 0x000008c8, 954 }, /* approximate */
+ { 0x01000660, 966 }, /* Arabic_0 */
+ { 0x01000661, 975 }, /* Arabic_1 */
+ { 0x01000662, 984 }, /* Arabic_2 */
+ { 0x01000663, 993 }, /* Arabic_3 */
+ { 0x01000664, 1002 }, /* Arabic_4 */
+ { 0x01000665, 1011 }, /* Arabic_5 */
+ { 0x01000666, 1020 }, /* Arabic_6 */
+ { 0x01000667, 1029 }, /* Arabic_7 */
+ { 0x01000668, 1038 }, /* Arabic_8 */
+ { 0x01000669, 1047 }, /* Arabic_9 */
+ { 0x000005d9, 1056 }, /* Arabic_ain */
+ { 0x000005c7, 1067 }, /* Arabic_alef */
+ { 0x000005e9, 1079 }, /* Arabic_alefmaksura */
+ { 0x000005c8, 1098 }, /* Arabic_beh */
+ { 0x000005ac, 1109 }, /* Arabic_comma */
+ { 0x000005d6, 1122 }, /* Arabic_dad */
+ { 0x000005cf, 1133 }, /* Arabic_dal */
+ { 0x000005ef, 1144 }, /* Arabic_damma */
+ { 0x000005ec, 1157 }, /* Arabic_dammatan */
+ { 0x01000688, 1173 }, /* Arabic_ddal */
+ { 0x010006cc, 1185 }, /* Arabic_farsi_yeh */
+ { 0x000005ee, 1202 }, /* Arabic_fatha */
+ { 0x000005eb, 1215 }, /* Arabic_fathatan */
+ { 0x000005e1, 1231 }, /* Arabic_feh */
+ { 0x010006d4, 1242 }, /* Arabic_fullstop */
+ { 0x010006af, 1258 }, /* Arabic_gaf */
+ { 0x000005da, 1269 }, /* Arabic_ghain */
+ { 0x000005e7, 1282 }, /* Arabic_ha */
+ { 0x000005cd, 1292 }, /* Arabic_hah */
+ { 0x000005c1, 1303 }, /* Arabic_hamza */
+ { 0x01000654, 1316 }, /* Arabic_hamza_above */
+ { 0x01000655, 1335 }, /* Arabic_hamza_below */
+ { 0x000005c3, 1354 }, /* Arabic_hamzaonalef */
+ { 0x000005c4, 1373 }, /* Arabic_hamzaonwaw */
+ { 0x000005c6, 1391 }, /* Arabic_hamzaonyeh */
+ { 0x000005c5, 1409 }, /* Arabic_hamzaunderalef */
+ { 0x000005e7, 1431 }, /* Arabic_heh */
+ { 0x010006be, 1442 }, /* Arabic_heh_doachashmee */
+ { 0x010006c1, 1465 }, /* Arabic_heh_goal */
+ { 0x000005cc, 1481 }, /* Arabic_jeem */
+ { 0x01000698, 1493 }, /* Arabic_jeh */
+ { 0x000005e3, 1504 }, /* Arabic_kaf */
+ { 0x000005f0, 1515 }, /* Arabic_kasra */
+ { 0x000005ed, 1528 }, /* Arabic_kasratan */
+ { 0x010006a9, 1544 }, /* Arabic_keheh */
+ { 0x000005ce, 1557 }, /* Arabic_khah */
+ { 0x000005e4, 1569 }, /* Arabic_lam */
+ { 0x01000653, 1580 }, /* Arabic_madda_above */
+ { 0x000005c2, 1599 }, /* Arabic_maddaonalef */
+ { 0x000005e5, 1618 }, /* Arabic_meem */
+ { 0x000005e6, 1630 }, /* Arabic_noon */
+ { 0x010006ba, 1642 }, /* Arabic_noon_ghunna */
+ { 0x0100067e, 1661 }, /* Arabic_peh */
+ { 0x0100066a, 1672 }, /* Arabic_percent */
+ { 0x000005e2, 1687 }, /* Arabic_qaf */
+ { 0x000005bf, 1698 }, /* Arabic_question_mark */
+ { 0x000005d1, 1719 }, /* Arabic_ra */
+ { 0x01000691, 1729 }, /* Arabic_rreh */
+ { 0x000005d5, 1741 }, /* Arabic_sad */
+ { 0x000005d3, 1752 }, /* Arabic_seen */
+ { 0x000005bb, 1764 }, /* Arabic_semicolon */
+ { 0x000005f1, 1781 }, /* Arabic_shadda */
+ { 0x000005d4, 1795 }, /* Arabic_sheen */
+ { 0x000005f2, 1808 }, /* Arabic_sukun */
+ { 0x01000670, 1821 }, /* Arabic_superscript_alef */
+ { 0x0000ff7e, 1845 }, /* Arabic_switch */
+ { 0x000005d7, 1859 }, /* Arabic_tah */
+ { 0x000005e0, 1870 }, /* Arabic_tatweel */
+ { 0x01000686, 1885 }, /* Arabic_tcheh */
+ { 0x000005ca, 1898 }, /* Arabic_teh */
+ { 0x000005c9, 1909 }, /* Arabic_tehmarbuta */
+ { 0x000005d0, 1927 }, /* Arabic_thal */
+ { 0x000005cb, 1939 }, /* Arabic_theh */
+ { 0x01000679, 1951 }, /* Arabic_tteh */
+ { 0x010006a4, 1963 }, /* Arabic_veh */
+ { 0x000005e8, 1974 }, /* Arabic_waw */
+ { 0x000005ea, 1985 }, /* Arabic_yeh */
+ { 0x010006d2, 1996 }, /* Arabic_yeh_baree */
+ { 0x000005d8, 2013 }, /* Arabic_zah */
+ { 0x000005d2, 2024 }, /* Arabic_zain */
+ { 0x000000c5, 2036 }, /* Aring */
+ { 0x000000e5, 2042 }, /* aring */
+ { 0x0100055b, 2048 }, /* Armenian_accent */
+ { 0x0100055c, 2064 }, /* Armenian_amanak */
+ { 0x0100055a, 2080 }, /* Armenian_apostrophe */
+ { 0x01000538, 2100 }, /* Armenian_AT */
+ { 0x01000568, 2112 }, /* Armenian_at */
+ { 0x01000531, 2124 }, /* Armenian_AYB */
+ { 0x01000561, 2137 }, /* Armenian_ayb */
+ { 0x01000532, 2150 }, /* Armenian_BEN */
+ { 0x01000562, 2163 }, /* Armenian_ben */
+ { 0x0100055d, 2176 }, /* Armenian_but */
+ { 0x01000549, 2189 }, /* Armenian_CHA */
+ { 0x01000579, 2202 }, /* Armenian_cha */
+ { 0x01000534, 2215 }, /* Armenian_DA */
+ { 0x01000564, 2227 }, /* Armenian_da */
+ { 0x01000541, 2239 }, /* Armenian_DZA */
+ { 0x01000571, 2252 }, /* Armenian_dza */
+ { 0x01000537, 2265 }, /* Armenian_E */
+ { 0x01000567, 2276 }, /* Armenian_e */
+ { 0x0100055c, 2287 }, /* Armenian_exclam */
+ { 0x01000556, 2303 }, /* Armenian_FE */
+ { 0x01000586, 2315 }, /* Armenian_fe */
+ { 0x01000589, 2327 }, /* Armenian_full_stop */
+ { 0x01000542, 2346 }, /* Armenian_GHAT */
+ { 0x01000572, 2360 }, /* Armenian_ghat */
+ { 0x01000533, 2374 }, /* Armenian_GIM */
+ { 0x01000563, 2387 }, /* Armenian_gim */
+ { 0x01000545, 2400 }, /* Armenian_HI */
+ { 0x01000575, 2412 }, /* Armenian_hi */
+ { 0x01000540, 2424 }, /* Armenian_HO */
+ { 0x01000570, 2436 }, /* Armenian_ho */
+ { 0x0100058a, 2448 }, /* Armenian_hyphen */
+ { 0x0100053b, 2464 }, /* Armenian_INI */
+ { 0x0100056b, 2477 }, /* Armenian_ini */
+ { 0x0100054b, 2490 }, /* Armenian_JE */
+ { 0x0100057b, 2502 }, /* Armenian_je */
+ { 0x01000554, 2514 }, /* Armenian_KE */
+ { 0x01000584, 2526 }, /* Armenian_ke */
+ { 0x0100053f, 2538 }, /* Armenian_KEN */
+ { 0x0100056f, 2551 }, /* Armenian_ken */
+ { 0x0100053d, 2564 }, /* Armenian_KHE */
+ { 0x0100056d, 2577 }, /* Armenian_khe */
+ { 0x01000587, 2590 }, /* Armenian_ligature_ew */
+ { 0x0100053c, 2611 }, /* Armenian_LYUN */
+ { 0x0100056c, 2625 }, /* Armenian_lyun */
+ { 0x01000544, 2639 }, /* Armenian_MEN */
+ { 0x01000574, 2652 }, /* Armenian_men */
+ { 0x01000546, 2665 }, /* Armenian_NU */
+ { 0x01000576, 2677 }, /* Armenian_nu */
+ { 0x01000555, 2689 }, /* Armenian_O */
+ { 0x01000585, 2700 }, /* Armenian_o */
+ { 0x0100055e, 2711 }, /* Armenian_paruyk */
+ { 0x0100054a, 2727 }, /* Armenian_PE */
+ { 0x0100057a, 2739 }, /* Armenian_pe */
+ { 0x01000553, 2751 }, /* Armenian_PYUR */
+ { 0x01000583, 2765 }, /* Armenian_pyur */
+ { 0x0100055e, 2779 }, /* Armenian_question */
+ { 0x0100054c, 2797 }, /* Armenian_RA */
+ { 0x0100057c, 2809 }, /* Armenian_ra */
+ { 0x01000550, 2821 }, /* Armenian_RE */
+ { 0x01000580, 2833 }, /* Armenian_re */
+ { 0x0100054d, 2845 }, /* Armenian_SE */
+ { 0x0100057d, 2857 }, /* Armenian_se */
+ { 0x0100055d, 2869 }, /* Armenian_separation_mark */
+ { 0x01000547, 2894 }, /* Armenian_SHA */
+ { 0x01000577, 2907 }, /* Armenian_sha */
+ { 0x0100055b, 2920 }, /* Armenian_shesht */
+ { 0x01000543, 2936 }, /* Armenian_TCHE */
+ { 0x01000573, 2950 }, /* Armenian_tche */
+ { 0x01000539, 2964 }, /* Armenian_TO */
+ { 0x01000569, 2976 }, /* Armenian_to */
+ { 0x0100053e, 2988 }, /* Armenian_TSA */
+ { 0x0100056e, 3001 }, /* Armenian_tsa */
+ { 0x01000551, 3014 }, /* Armenian_TSO */
+ { 0x01000581, 3027 }, /* Armenian_tso */
+ { 0x0100054f, 3040 }, /* Armenian_TYUN */
+ { 0x0100057f, 3054 }, /* Armenian_tyun */
+ { 0x01000589, 3068 }, /* Armenian_verjaket */
+ { 0x0100054e, 3086 }, /* Armenian_VEV */
+ { 0x0100057e, 3099 }, /* Armenian_vev */
+ { 0x01000548, 3112 }, /* Armenian_VO */
+ { 0x01000578, 3124 }, /* Armenian_vo */
+ { 0x01000552, 3136 }, /* Armenian_VYUN */
+ { 0x01000582, 3150 }, /* Armenian_vyun */
+ { 0x01000535, 3164 }, /* Armenian_YECH */
+ { 0x01000565, 3178 }, /* Armenian_yech */
+ { 0x0100058a, 3192 }, /* Armenian_yentamna */
+ { 0x01000536, 3210 }, /* Armenian_ZA */
+ { 0x01000566, 3222 }, /* Armenian_za */
+ { 0x0100053a, 3234 }, /* Armenian_ZHE */
+ { 0x0100056a, 3247 }, /* Armenian_zhe */
+ { 0x0000005e, 3260 }, /* asciicircum */
+ { 0x0000007e, 3272 }, /* asciitilde */
+ { 0x0000002a, 3283 }, /* asterisk */
+ { 0x00000040, 3292 }, /* at */
+ { 0x000000c3, 3295 }, /* Atilde */
+ { 0x000000e3, 3302 }, /* atilde */
+ { 0x0000fe7a, 3309 }, /* AudibleBell_Enable */
+ { 0x00000042, 3328 }, /* B */
+ { 0x00000062, 3330 }, /* b */
+ { 0x01001e02, 3332 }, /* Babovedot */
+ { 0x01001e03, 3342 }, /* babovedot */
+ { 0x0000005c, 3352 }, /* backslash */
+ { 0x0000ff08, 3362 }, /* BackSpace */
+ { 0x1000ff74, 3372 }, /* BackTab */
+ { 0x00000af4, 3380 }, /* ballotcross */
+ { 0x0000007c, 3392 }, /* bar */
+ { 0x01002235, 3396 }, /* because */
+ { 0x0000ff58, 3404 }, /* Begin */
+ { 0x000009df, 3410 }, /* blank */
+ { 0x100000fc, 3416 }, /* block */
+ { 0x000008a5, 3422 }, /* botintegral */
+ { 0x000008ac, 3434 }, /* botleftparens */
+ { 0x000008a8, 3448 }, /* botleftsqbracket */
+ { 0x000008b2, 3465 }, /* botleftsummation */
+ { 0x000008ae, 3482 }, /* botrightparens */
+ { 0x000008aa, 3497 }, /* botrightsqbracket */
+ { 0x000008b6, 3515 }, /* botrightsummation */
+ { 0x000009f6, 3533 }, /* bott */
+ { 0x000008b4, 3538 }, /* botvertsummationconnector */
+ { 0x0000fe74, 3564 }, /* BounceKeys_Enable */
+ { 0x0000007b, 3582 }, /* braceleft */
+ { 0x0000007d, 3592 }, /* braceright */
+ { 0x0000005b, 3603 }, /* bracketleft */
+ { 0x0000005d, 3615 }, /* bracketright */
+ { 0x01002800, 3628 }, /* braille_blank */
+ { 0x0000fff1, 3642 }, /* braille_dot_1 */
+ { 0x0000fffa, 3656 }, /* braille_dot_10 */
+ { 0x0000fff2, 3671 }, /* braille_dot_2 */
+ { 0x0000fff3, 3685 }, /* braille_dot_3 */
+ { 0x0000fff4, 3699 }, /* braille_dot_4 */
+ { 0x0000fff5, 3713 }, /* braille_dot_5 */
+ { 0x0000fff6, 3727 }, /* braille_dot_6 */
+ { 0x0000fff7, 3741 }, /* braille_dot_7 */
+ { 0x0000fff8, 3755 }, /* braille_dot_8 */
+ { 0x0000fff9, 3769 }, /* braille_dot_9 */
+ { 0x01002801, 3783 }, /* braille_dots_1 */
+ { 0x01002803, 3798 }, /* braille_dots_12 */
+ { 0x01002807, 3814 }, /* braille_dots_123 */
+ { 0x0100280f, 3831 }, /* braille_dots_1234 */
+ { 0x0100281f, 3849 }, /* braille_dots_12345 */
+ { 0x0100283f, 3868 }, /* braille_dots_123456 */
+ { 0x0100287f, 3888 }, /* braille_dots_1234567 */
+ { 0x010028ff, 3909 }, /* braille_dots_12345678 */
+ { 0x010028bf, 3931 }, /* braille_dots_1234568 */
+ { 0x0100285f, 3952 }, /* braille_dots_123457 */
+ { 0x010028df, 3972 }, /* braille_dots_1234578 */
+ { 0x0100289f, 3993 }, /* braille_dots_123458 */
+ { 0x0100282f, 4013 }, /* braille_dots_12346 */
+ { 0x0100286f, 4032 }, /* braille_dots_123467 */
+ { 0x010028ef, 4052 }, /* braille_dots_1234678 */
+ { 0x010028af, 4073 }, /* braille_dots_123468 */
+ { 0x0100284f, 4093 }, /* braille_dots_12347 */
+ { 0x010028cf, 4112 }, /* braille_dots_123478 */
+ { 0x0100288f, 4132 }, /* braille_dots_12348 */
+ { 0x01002817, 4151 }, /* braille_dots_1235 */
+ { 0x01002837, 4169 }, /* braille_dots_12356 */
+ { 0x01002877, 4188 }, /* braille_dots_123567 */
+ { 0x010028f7, 4208 }, /* braille_dots_1235678 */
+ { 0x010028b7, 4229 }, /* braille_dots_123568 */
+ { 0x01002857, 4249 }, /* braille_dots_12357 */
+ { 0x010028d7, 4268 }, /* braille_dots_123578 */
+ { 0x01002897, 4288 }, /* braille_dots_12358 */
+ { 0x01002827, 4307 }, /* braille_dots_1236 */
+ { 0x01002867, 4325 }, /* braille_dots_12367 */
+ { 0x010028e7, 4344 }, /* braille_dots_123678 */
+ { 0x010028a7, 4364 }, /* braille_dots_12368 */
+ { 0x01002847, 4383 }, /* braille_dots_1237 */
+ { 0x010028c7, 4401 }, /* braille_dots_12378 */
+ { 0x01002887, 4420 }, /* braille_dots_1238 */
+ { 0x0100280b, 4438 }, /* braille_dots_124 */
+ { 0x0100281b, 4455 }, /* braille_dots_1245 */
+ { 0x0100283b, 4473 }, /* braille_dots_12456 */
+ { 0x0100287b, 4492 }, /* braille_dots_124567 */
+ { 0x010028fb, 4512 }, /* braille_dots_1245678 */
+ { 0x010028bb, 4533 }, /* braille_dots_124568 */
+ { 0x0100285b, 4553 }, /* braille_dots_12457 */
+ { 0x010028db, 4572 }, /* braille_dots_124578 */
+ { 0x0100289b, 4592 }, /* braille_dots_12458 */
+ { 0x0100282b, 4611 }, /* braille_dots_1246 */
+ { 0x0100286b, 4629 }, /* braille_dots_12467 */
+ { 0x010028eb, 4648 }, /* braille_dots_124678 */
+ { 0x010028ab, 4668 }, /* braille_dots_12468 */
+ { 0x0100284b, 4687 }, /* braille_dots_1247 */
+ { 0x010028cb, 4705 }, /* braille_dots_12478 */
+ { 0x0100288b, 4724 }, /* braille_dots_1248 */
+ { 0x01002813, 4742 }, /* braille_dots_125 */
+ { 0x01002833, 4759 }, /* braille_dots_1256 */
+ { 0x01002873, 4777 }, /* braille_dots_12567 */
+ { 0x010028f3, 4796 }, /* braille_dots_125678 */
+ { 0x010028b3, 4816 }, /* braille_dots_12568 */
+ { 0x01002853, 4835 }, /* braille_dots_1257 */
+ { 0x010028d3, 4853 }, /* braille_dots_12578 */
+ { 0x01002893, 4872 }, /* braille_dots_1258 */
+ { 0x01002823, 4890 }, /* braille_dots_126 */
+ { 0x01002863, 4907 }, /* braille_dots_1267 */
+ { 0x010028e3, 4925 }, /* braille_dots_12678 */
+ { 0x010028a3, 4944 }, /* braille_dots_1268 */
+ { 0x01002843, 4962 }, /* braille_dots_127 */
+ { 0x010028c3, 4979 }, /* braille_dots_1278 */
+ { 0x01002883, 4997 }, /* braille_dots_128 */
+ { 0x01002805, 5014 }, /* braille_dots_13 */
+ { 0x0100280d, 5030 }, /* braille_dots_134 */
+ { 0x0100281d, 5047 }, /* braille_dots_1345 */
+ { 0x0100283d, 5065 }, /* braille_dots_13456 */
+ { 0x0100287d, 5084 }, /* braille_dots_134567 */
+ { 0x010028fd, 5104 }, /* braille_dots_1345678 */
+ { 0x010028bd, 5125 }, /* braille_dots_134568 */
+ { 0x0100285d, 5145 }, /* braille_dots_13457 */
+ { 0x010028dd, 5164 }, /* braille_dots_134578 */
+ { 0x0100289d, 5184 }, /* braille_dots_13458 */
+ { 0x0100282d, 5203 }, /* braille_dots_1346 */
+ { 0x0100286d, 5221 }, /* braille_dots_13467 */
+ { 0x010028ed, 5240 }, /* braille_dots_134678 */
+ { 0x010028ad, 5260 }, /* braille_dots_13468 */
+ { 0x0100284d, 5279 }, /* braille_dots_1347 */
+ { 0x010028cd, 5297 }, /* braille_dots_13478 */
+ { 0x0100288d, 5316 }, /* braille_dots_1348 */
+ { 0x01002815, 5334 }, /* braille_dots_135 */
+ { 0x01002835, 5351 }, /* braille_dots_1356 */
+ { 0x01002875, 5369 }, /* braille_dots_13567 */
+ { 0x010028f5, 5388 }, /* braille_dots_135678 */
+ { 0x010028b5, 5408 }, /* braille_dots_13568 */
+ { 0x01002855, 5427 }, /* braille_dots_1357 */
+ { 0x010028d5, 5445 }, /* braille_dots_13578 */
+ { 0x01002895, 5464 }, /* braille_dots_1358 */
+ { 0x01002825, 5482 }, /* braille_dots_136 */
+ { 0x01002865, 5499 }, /* braille_dots_1367 */
+ { 0x010028e5, 5517 }, /* braille_dots_13678 */
+ { 0x010028a5, 5536 }, /* braille_dots_1368 */
+ { 0x01002845, 5554 }, /* braille_dots_137 */
+ { 0x010028c5, 5571 }, /* braille_dots_1378 */
+ { 0x01002885, 5589 }, /* braille_dots_138 */
+ { 0x01002809, 5606 }, /* braille_dots_14 */
+ { 0x01002819, 5622 }, /* braille_dots_145 */
+ { 0x01002839, 5639 }, /* braille_dots_1456 */
+ { 0x01002879, 5657 }, /* braille_dots_14567 */
+ { 0x010028f9, 5676 }, /* braille_dots_145678 */
+ { 0x010028b9, 5696 }, /* braille_dots_14568 */
+ { 0x01002859, 5715 }, /* braille_dots_1457 */
+ { 0x010028d9, 5733 }, /* braille_dots_14578 */
+ { 0x01002899, 5752 }, /* braille_dots_1458 */
+ { 0x01002829, 5770 }, /* braille_dots_146 */
+ { 0x01002869, 5787 }, /* braille_dots_1467 */
+ { 0x010028e9, 5805 }, /* braille_dots_14678 */
+ { 0x010028a9, 5824 }, /* braille_dots_1468 */
+ { 0x01002849, 5842 }, /* braille_dots_147 */
+ { 0x010028c9, 5859 }, /* braille_dots_1478 */
+ { 0x01002889, 5877 }, /* braille_dots_148 */
+ { 0x01002811, 5894 }, /* braille_dots_15 */
+ { 0x01002831, 5910 }, /* braille_dots_156 */
+ { 0x01002871, 5927 }, /* braille_dots_1567 */
+ { 0x010028f1, 5945 }, /* braille_dots_15678 */
+ { 0x010028b1, 5964 }, /* braille_dots_1568 */
+ { 0x01002851, 5982 }, /* braille_dots_157 */
+ { 0x010028d1, 5999 }, /* braille_dots_1578 */
+ { 0x01002891, 6017 }, /* braille_dots_158 */
+ { 0x01002821, 6034 }, /* braille_dots_16 */
+ { 0x01002861, 6050 }, /* braille_dots_167 */
+ { 0x010028e1, 6067 }, /* braille_dots_1678 */
+ { 0x010028a1, 6085 }, /* braille_dots_168 */
+ { 0x01002841, 6102 }, /* braille_dots_17 */
+ { 0x010028c1, 6118 }, /* braille_dots_178 */
+ { 0x01002881, 6135 }, /* braille_dots_18 */
+ { 0x01002802, 6151 }, /* braille_dots_2 */
+ { 0x01002806, 6166 }, /* braille_dots_23 */
+ { 0x0100280e, 6182 }, /* braille_dots_234 */
+ { 0x0100281e, 6199 }, /* braille_dots_2345 */
+ { 0x0100283e, 6217 }, /* braille_dots_23456 */
+ { 0x0100287e, 6236 }, /* braille_dots_234567 */
+ { 0x010028fe, 6256 }, /* braille_dots_2345678 */
+ { 0x010028be, 6277 }, /* braille_dots_234568 */
+ { 0x0100285e, 6297 }, /* braille_dots_23457 */
+ { 0x010028de, 6316 }, /* braille_dots_234578 */
+ { 0x0100289e, 6336 }, /* braille_dots_23458 */
+ { 0x0100282e, 6355 }, /* braille_dots_2346 */
+ { 0x0100286e, 6373 }, /* braille_dots_23467 */
+ { 0x010028ee, 6392 }, /* braille_dots_234678 */
+ { 0x010028ae, 6412 }, /* braille_dots_23468 */
+ { 0x0100284e, 6431 }, /* braille_dots_2347 */
+ { 0x010028ce, 6449 }, /* braille_dots_23478 */
+ { 0x0100288e, 6468 }, /* braille_dots_2348 */
+ { 0x01002816, 6486 }, /* braille_dots_235 */
+ { 0x01002836, 6503 }, /* braille_dots_2356 */
+ { 0x01002876, 6521 }, /* braille_dots_23567 */
+ { 0x010028f6, 6540 }, /* braille_dots_235678 */
+ { 0x010028b6, 6560 }, /* braille_dots_23568 */
+ { 0x01002856, 6579 }, /* braille_dots_2357 */
+ { 0x010028d6, 6597 }, /* braille_dots_23578 */
+ { 0x01002896, 6616 }, /* braille_dots_2358 */
+ { 0x01002826, 6634 }, /* braille_dots_236 */
+ { 0x01002866, 6651 }, /* braille_dots_2367 */
+ { 0x010028e6, 6669 }, /* braille_dots_23678 */
+ { 0x010028a6, 6688 }, /* braille_dots_2368 */
+ { 0x01002846, 6706 }, /* braille_dots_237 */
+ { 0x010028c6, 6723 }, /* braille_dots_2378 */
+ { 0x01002886, 6741 }, /* braille_dots_238 */
+ { 0x0100280a, 6758 }, /* braille_dots_24 */
+ { 0x0100281a, 6774 }, /* braille_dots_245 */
+ { 0x0100283a, 6791 }, /* braille_dots_2456 */
+ { 0x0100287a, 6809 }, /* braille_dots_24567 */
+ { 0x010028fa, 6828 }, /* braille_dots_245678 */
+ { 0x010028ba, 6848 }, /* braille_dots_24568 */
+ { 0x0100285a, 6867 }, /* braille_dots_2457 */
+ { 0x010028da, 6885 }, /* braille_dots_24578 */
+ { 0x0100289a, 6904 }, /* braille_dots_2458 */
+ { 0x0100282a, 6922 }, /* braille_dots_246 */
+ { 0x0100286a, 6939 }, /* braille_dots_2467 */
+ { 0x010028ea, 6957 }, /* braille_dots_24678 */
+ { 0x010028aa, 6976 }, /* braille_dots_2468 */
+ { 0x0100284a, 6994 }, /* braille_dots_247 */
+ { 0x010028ca, 7011 }, /* braille_dots_2478 */
+ { 0x0100288a, 7029 }, /* braille_dots_248 */
+ { 0x01002812, 7046 }, /* braille_dots_25 */
+ { 0x01002832, 7062 }, /* braille_dots_256 */
+ { 0x01002872, 7079 }, /* braille_dots_2567 */
+ { 0x010028f2, 7097 }, /* braille_dots_25678 */
+ { 0x010028b2, 7116 }, /* braille_dots_2568 */
+ { 0x01002852, 7134 }, /* braille_dots_257 */
+ { 0x010028d2, 7151 }, /* braille_dots_2578 */
+ { 0x01002892, 7169 }, /* braille_dots_258 */
+ { 0x01002822, 7186 }, /* braille_dots_26 */
+ { 0x01002862, 7202 }, /* braille_dots_267 */
+ { 0x010028e2, 7219 }, /* braille_dots_2678 */
+ { 0x010028a2, 7237 }, /* braille_dots_268 */
+ { 0x01002842, 7254 }, /* braille_dots_27 */
+ { 0x010028c2, 7270 }, /* braille_dots_278 */
+ { 0x01002882, 7287 }, /* braille_dots_28 */
+ { 0x01002804, 7303 }, /* braille_dots_3 */
+ { 0x0100280c, 7318 }, /* braille_dots_34 */
+ { 0x0100281c, 7334 }, /* braille_dots_345 */
+ { 0x0100283c, 7351 }, /* braille_dots_3456 */
+ { 0x0100287c, 7369 }, /* braille_dots_34567 */
+ { 0x010028fc, 7388 }, /* braille_dots_345678 */
+ { 0x010028bc, 7408 }, /* braille_dots_34568 */
+ { 0x0100285c, 7427 }, /* braille_dots_3457 */
+ { 0x010028dc, 7445 }, /* braille_dots_34578 */
+ { 0x0100289c, 7464 }, /* braille_dots_3458 */
+ { 0x0100282c, 7482 }, /* braille_dots_346 */
+ { 0x0100286c, 7499 }, /* braille_dots_3467 */
+ { 0x010028ec, 7517 }, /* braille_dots_34678 */
+ { 0x010028ac, 7536 }, /* braille_dots_3468 */
+ { 0x0100284c, 7554 }, /* braille_dots_347 */
+ { 0x010028cc, 7571 }, /* braille_dots_3478 */
+ { 0x0100288c, 7589 }, /* braille_dots_348 */
+ { 0x01002814, 7606 }, /* braille_dots_35 */
+ { 0x01002834, 7622 }, /* braille_dots_356 */
+ { 0x01002874, 7639 }, /* braille_dots_3567 */
+ { 0x010028f4, 7657 }, /* braille_dots_35678 */
+ { 0x010028b4, 7676 }, /* braille_dots_3568 */
+ { 0x01002854, 7694 }, /* braille_dots_357 */
+ { 0x010028d4, 7711 }, /* braille_dots_3578 */
+ { 0x01002894, 7729 }, /* braille_dots_358 */
+ { 0x01002824, 7746 }, /* braille_dots_36 */
+ { 0x01002864, 7762 }, /* braille_dots_367 */
+ { 0x010028e4, 7779 }, /* braille_dots_3678 */
+ { 0x010028a4, 7797 }, /* braille_dots_368 */
+ { 0x01002844, 7814 }, /* braille_dots_37 */
+ { 0x010028c4, 7830 }, /* braille_dots_378 */
+ { 0x01002884, 7847 }, /* braille_dots_38 */
+ { 0x01002808, 7863 }, /* braille_dots_4 */
+ { 0x01002818, 7878 }, /* braille_dots_45 */
+ { 0x01002838, 7894 }, /* braille_dots_456 */
+ { 0x01002878, 7911 }, /* braille_dots_4567 */
+ { 0x010028f8, 7929 }, /* braille_dots_45678 */
+ { 0x010028b8, 7948 }, /* braille_dots_4568 */
+ { 0x01002858, 7966 }, /* braille_dots_457 */
+ { 0x010028d8, 7983 }, /* braille_dots_4578 */
+ { 0x01002898, 8001 }, /* braille_dots_458 */
+ { 0x01002828, 8018 }, /* braille_dots_46 */
+ { 0x01002868, 8034 }, /* braille_dots_467 */
+ { 0x010028e8, 8051 }, /* braille_dots_4678 */
+ { 0x010028a8, 8069 }, /* braille_dots_468 */
+ { 0x01002848, 8086 }, /* braille_dots_47 */
+ { 0x010028c8, 8102 }, /* braille_dots_478 */
+ { 0x01002888, 8119 }, /* braille_dots_48 */
+ { 0x01002810, 8135 }, /* braille_dots_5 */
+ { 0x01002830, 8150 }, /* braille_dots_56 */
+ { 0x01002870, 8166 }, /* braille_dots_567 */
+ { 0x010028f0, 8183 }, /* braille_dots_5678 */
+ { 0x010028b0, 8201 }, /* braille_dots_568 */
+ { 0x01002850, 8218 }, /* braille_dots_57 */
+ { 0x010028d0, 8234 }, /* braille_dots_578 */
+ { 0x01002890, 8251 }, /* braille_dots_58 */
+ { 0x01002820, 8267 }, /* braille_dots_6 */
+ { 0x01002860, 8282 }, /* braille_dots_67 */
+ { 0x010028e0, 8298 }, /* braille_dots_678 */
+ { 0x010028a0, 8315 }, /* braille_dots_68 */
+ { 0x01002840, 8331 }, /* braille_dots_7 */
+ { 0x010028c0, 8346 }, /* braille_dots_78 */
+ { 0x01002880, 8362 }, /* braille_dots_8 */
+ { 0x0000ff6b, 8377 }, /* Break */
+ { 0x000001a2, 8383 }, /* breve */
+ { 0x000000a6, 8389 }, /* brokenbar */
+ { 0x000006ae, 8399 }, /* Byelorussian_shortu */
+ { 0x000006be, 8419 }, /* Byelorussian_SHORTU */
+ { 0x00000043, 8439 }, /* C */
+ { 0x00000063, 8441 }, /* c */
+ { 0x0000fea3, 8443 }, /* c_h */
+ { 0x0000fea4, 8447 }, /* C_h */
+ { 0x0000fea5, 8451 }, /* C_H */
+ { 0x000002c5, 8455 }, /* Cabovedot */
+ { 0x000002e5, 8465 }, /* cabovedot */
+ { 0x000001c6, 8475 }, /* Cacute */
+ { 0x000001e6, 8482 }, /* cacute */
+ { 0x0000ff69, 8489 }, /* Cancel */
+ { 0x0000ffe5, 8496 }, /* Caps_Lock */
+ { 0x00000ab8, 8506 }, /* careof */
+ { 0x00000afc, 8513 }, /* caret */
+ { 0x000001b7, 8519 }, /* caron */
+ { 0x000001c8, 8525 }, /* Ccaron */
+ { 0x000001e8, 8532 }, /* ccaron */
+ { 0x000000c7, 8539 }, /* Ccedilla */
+ { 0x000000e7, 8548 }, /* ccedilla */
+ { 0x000002c6, 8557 }, /* Ccircumflex */
+ { 0x000002e6, 8569 }, /* ccircumflex */
+ { 0x000000b8, 8581 }, /* cedilla */
+ { 0x000000a2, 8589 }, /* cent */
+ { 0x0000fea0, 8594 }, /* ch */
+ { 0x0000fea1, 8597 }, /* Ch */
+ { 0x0000fea2, 8600 }, /* CH */
+ { 0x000009e1, 8603 }, /* checkerboard */
+ { 0x00000af3, 8616 }, /* checkmark */
+ { 0x00000bcf, 8626 }, /* circle */
+ { 0x0000ff0b, 8633 }, /* Clear */
+ { 0x1000ff6f, 8639 }, /* ClearLine */
+ { 0x00000aec, 8649 }, /* club */
+ { 0x0000ff37, 8654 }, /* Codeinput */
+ { 0x0000003a, 8664 }, /* colon */
+ { 0x010020a1, 8670 }, /* ColonSign */
+ { 0x0000002c, 8680 }, /* comma */
+ { 0x0100220b, 8686 }, /* containsas */
+ { 0x0000ffe3, 8697 }, /* Control_L */
+ { 0x0000ffe4, 8707 }, /* Control_R */
+ { 0x000000a9, 8717 }, /* copyright */
+ { 0x000009e4, 8727 }, /* cr */
+ { 0x000009ee, 8730 }, /* crossinglines */
+ { 0x010020a2, 8744 }, /* CruzeiroSign */
+ { 0x0100221b, 8757 }, /* cuberoot */
+ { 0x000000a4, 8766 }, /* currency */
+ { 0x00000aff, 8775 }, /* cursor */
+ { 0x000006c1, 8782 }, /* Cyrillic_a */
+ { 0x000006e1, 8793 }, /* Cyrillic_A */
+ { 0x000006c2, 8804 }, /* Cyrillic_be */
+ { 0x000006e2, 8816 }, /* Cyrillic_BE */
+ { 0x000006de, 8828 }, /* Cyrillic_che */
+ { 0x000006fe, 8841 }, /* Cyrillic_CHE */
+ { 0x010004b6, 8854 }, /* Cyrillic_CHE_descender */
+ { 0x010004b7, 8877 }, /* Cyrillic_che_descender */
+ { 0x010004b8, 8900 }, /* Cyrillic_CHE_vertstroke */
+ { 0x010004b9, 8924 }, /* Cyrillic_che_vertstroke */
+ { 0x000006c4, 8948 }, /* Cyrillic_de */
+ { 0x000006e4, 8960 }, /* Cyrillic_DE */
+ { 0x000006af, 8972 }, /* Cyrillic_dzhe */
+ { 0x000006bf, 8986 }, /* Cyrillic_DZHE */
+ { 0x000006dc, 9000 }, /* Cyrillic_e */
+ { 0x000006fc, 9011 }, /* Cyrillic_E */
+ { 0x000006c6, 9022 }, /* Cyrillic_ef */
+ { 0x000006e6, 9034 }, /* Cyrillic_EF */
+ { 0x000006cc, 9046 }, /* Cyrillic_el */
+ { 0x000006ec, 9058 }, /* Cyrillic_EL */
+ { 0x000006cd, 9070 }, /* Cyrillic_em */
+ { 0x000006ed, 9082 }, /* Cyrillic_EM */
+ { 0x000006ce, 9094 }, /* Cyrillic_en */
+ { 0x000006ee, 9106 }, /* Cyrillic_EN */
+ { 0x010004a2, 9118 }, /* Cyrillic_EN_descender */
+ { 0x010004a3, 9140 }, /* Cyrillic_en_descender */
+ { 0x000006d2, 9162 }, /* Cyrillic_er */
+ { 0x000006f2, 9174 }, /* Cyrillic_ER */
+ { 0x000006d3, 9186 }, /* Cyrillic_es */
+ { 0x000006f3, 9198 }, /* Cyrillic_ES */
+ { 0x000006c7, 9210 }, /* Cyrillic_ghe */
+ { 0x000006e7, 9223 }, /* Cyrillic_GHE */
+ { 0x01000492, 9236 }, /* Cyrillic_GHE_bar */
+ { 0x01000493, 9253 }, /* Cyrillic_ghe_bar */
+ { 0x000006c8, 9270 }, /* Cyrillic_ha */
+ { 0x000006e8, 9282 }, /* Cyrillic_HA */
+ { 0x010004b2, 9294 }, /* Cyrillic_HA_descender */
+ { 0x010004b3, 9316 }, /* Cyrillic_ha_descender */
+ { 0x000006df, 9338 }, /* Cyrillic_hardsign */
+ { 0x000006ff, 9356 }, /* Cyrillic_HARDSIGN */
+ { 0x000006c9, 9374 }, /* Cyrillic_i */
+ { 0x000006e9, 9385 }, /* Cyrillic_I */
+ { 0x010004e2, 9396 }, /* Cyrillic_I_macron */
+ { 0x010004e3, 9414 }, /* Cyrillic_i_macron */
+ { 0x000006c5, 9432 }, /* Cyrillic_ie */
+ { 0x000006e5, 9444 }, /* Cyrillic_IE */
+ { 0x000006a3, 9456 }, /* Cyrillic_io */
+ { 0x000006b3, 9468 }, /* Cyrillic_IO */
+ { 0x000006a8, 9480 }, /* Cyrillic_je */
+ { 0x000006b8, 9492 }, /* Cyrillic_JE */
+ { 0x000006cb, 9504 }, /* Cyrillic_ka */
+ { 0x000006eb, 9516 }, /* Cyrillic_KA */
+ { 0x0100049a, 9528 }, /* Cyrillic_KA_descender */
+ { 0x0100049b, 9550 }, /* Cyrillic_ka_descender */
+ { 0x0100049c, 9572 }, /* Cyrillic_KA_vertstroke */
+ { 0x0100049d, 9595 }, /* Cyrillic_ka_vertstroke */
+ { 0x000006a9, 9618 }, /* Cyrillic_lje */
+ { 0x000006b9, 9631 }, /* Cyrillic_LJE */
+ { 0x000006aa, 9644 }, /* Cyrillic_nje */
+ { 0x000006ba, 9657 }, /* Cyrillic_NJE */
+ { 0x000006cf, 9670 }, /* Cyrillic_o */
+ { 0x000006ef, 9681 }, /* Cyrillic_O */
+ { 0x010004e8, 9692 }, /* Cyrillic_O_bar */
+ { 0x010004e9, 9707 }, /* Cyrillic_o_bar */
+ { 0x000006d0, 9722 }, /* Cyrillic_pe */
+ { 0x000006f0, 9734 }, /* Cyrillic_PE */
+ { 0x010004d8, 9746 }, /* Cyrillic_SCHWA */
+ { 0x010004d9, 9761 }, /* Cyrillic_schwa */
+ { 0x000006db, 9776 }, /* Cyrillic_sha */
+ { 0x000006fb, 9789 }, /* Cyrillic_SHA */
+ { 0x000006dd, 9802 }, /* Cyrillic_shcha */
+ { 0x000006fd, 9817 }, /* Cyrillic_SHCHA */
+ { 0x010004ba, 9832 }, /* Cyrillic_SHHA */
+ { 0x010004bb, 9846 }, /* Cyrillic_shha */
+ { 0x000006ca, 9860 }, /* Cyrillic_shorti */
+ { 0x000006ea, 9876 }, /* Cyrillic_SHORTI */
+ { 0x000006d8, 9892 }, /* Cyrillic_softsign */
+ { 0x000006f8, 9910 }, /* Cyrillic_SOFTSIGN */
+ { 0x000006d4, 9928 }, /* Cyrillic_te */
+ { 0x000006f4, 9940 }, /* Cyrillic_TE */
+ { 0x000006c3, 9952 }, /* Cyrillic_tse */
+ { 0x000006e3, 9965 }, /* Cyrillic_TSE */
+ { 0x000006d5, 9978 }, /* Cyrillic_u */
+ { 0x000006f5, 9989 }, /* Cyrillic_U */
+ { 0x010004ee, 10000 }, /* Cyrillic_U_macron */
+ { 0x010004ef, 10018 }, /* Cyrillic_u_macron */
+ { 0x010004ae, 10036 }, /* Cyrillic_U_straight */
+ { 0x010004af, 10056 }, /* Cyrillic_u_straight */
+ { 0x010004b0, 10076 }, /* Cyrillic_U_straight_bar */
+ { 0x010004b1, 10100 }, /* Cyrillic_u_straight_bar */
+ { 0x000006d7, 10124 }, /* Cyrillic_ve */
+ { 0x000006f7, 10136 }, /* Cyrillic_VE */
+ { 0x000006d1, 10148 }, /* Cyrillic_ya */
+ { 0x000006f1, 10160 }, /* Cyrillic_YA */
+ { 0x000006d9, 10172 }, /* Cyrillic_yeru */
+ { 0x000006f9, 10186 }, /* Cyrillic_YERU */
+ { 0x000006c0, 10200 }, /* Cyrillic_yu */
+ { 0x000006e0, 10212 }, /* Cyrillic_YU */
+ { 0x000006da, 10224 }, /* Cyrillic_ze */
+ { 0x000006fa, 10236 }, /* Cyrillic_ZE */
+ { 0x000006d6, 10248 }, /* Cyrillic_zhe */
+ { 0x000006f6, 10261 }, /* Cyrillic_ZHE */
+ { 0x01000496, 10274 }, /* Cyrillic_ZHE_descender */
+ { 0x01000497, 10297 }, /* Cyrillic_zhe_descender */
+ { 0x00000044, 10320 }, /* D */
+ { 0x00000064, 10322 }, /* d */
+ { 0x01001e0a, 10324 }, /* Dabovedot */
+ { 0x01001e0b, 10334 }, /* dabovedot */
+ { 0x1000fe27, 10344 }, /* Dacute_accent */
+ { 0x00000af1, 10358 }, /* dagger */
+ { 0x000001cf, 10365 }, /* Dcaron */
+ { 0x000001ef, 10372 }, /* dcaron */
+ { 0x1000fe2c, 10379 }, /* Dcedilla_accent */
+ { 0x1000fe5e, 10395 }, /* Dcircumflex_accent */
+ { 0x1000fe22, 10414 }, /* Ddiaeresis */
+ { 0x0000fe80, 10425 }, /* dead_a */
+ { 0x0000fe81, 10432 }, /* dead_A */
+ { 0x0000fe64, 10439 }, /* dead_abovecomma */
+ { 0x0000fe56, 10455 }, /* dead_abovedot */
+ { 0x0000fe65, 10469 }, /* dead_abovereversedcomma */
+ { 0x0000fe58, 10493 }, /* dead_abovering */
+ { 0x0000fe91, 10508 }, /* dead_aboveverticalline */
+ { 0x0000fe51, 10531 }, /* dead_acute */
+ { 0x0000fe6b, 10542 }, /* dead_belowbreve */
+ { 0x0000fe69, 10558 }, /* dead_belowcircumflex */
+ { 0x0000fe6e, 10579 }, /* dead_belowcomma */
+ { 0x0000fe6c, 10595 }, /* dead_belowdiaeresis */
+ { 0x0000fe60, 10615 }, /* dead_belowdot */
+ { 0x0000fe68, 10629 }, /* dead_belowmacron */
+ { 0x0000fe67, 10646 }, /* dead_belowring */
+ { 0x0000fe6a, 10661 }, /* dead_belowtilde */
+ { 0x0000fe92, 10677 }, /* dead_belowverticalline */
+ { 0x0000fe55, 10700 }, /* dead_breve */
+ { 0x0000fe8b, 10711 }, /* dead_capital_schwa */
+ { 0x0000fe5a, 10730 }, /* dead_caron */
+ { 0x0000fe5b, 10741 }, /* dead_cedilla */
+ { 0x0000fe52, 10754 }, /* dead_circumflex */
+ { 0x0000fe6f, 10770 }, /* dead_currency */
+ { 0x0000fe65, 10784 }, /* dead_dasia */
+ { 0x0000fe57, 10795 }, /* dead_diaeresis */
+ { 0x0000fe59, 10810 }, /* dead_doubleacute */
+ { 0x0000fe66, 10827 }, /* dead_doublegrave */
+ { 0x0000fe82, 10844 }, /* dead_e */
+ { 0x0000fe83, 10851 }, /* dead_E */
+ { 0x0000fe50, 10858 }, /* dead_grave */
+ { 0x0000fe8c, 10869 }, /* dead_greek */
+ { 0x0000fe61, 10880 }, /* dead_hook */
+ { 0x0000fe62, 10890 }, /* dead_horn */
+ { 0x0000fe84, 10900 }, /* dead_i */
+ { 0x0000fe85, 10907 }, /* dead_I */
+ { 0x0000fe6d, 10914 }, /* dead_invertedbreve */
+ { 0x0000fe5d, 10933 }, /* dead_iota */
+ { 0x0000fe93, 10943 }, /* dead_longsolidusoverlay */
+ { 0x0000fe90, 10967 }, /* dead_lowline */
+ { 0x0000fe54, 10980 }, /* dead_macron */
+ { 0x0000fe86, 10992 }, /* dead_o */
+ { 0x0000fe87, 10999 }, /* dead_O */
+ { 0x0000fe5c, 11006 }, /* dead_ogonek */
+ { 0x0000fe53, 11018 }, /* dead_perispomeni */
+ { 0x0000fe64, 11035 }, /* dead_psili */
+ { 0x0000fe5f, 11046 }, /* dead_semivoiced_sound */
+ { 0x0000fe8a, 11068 }, /* dead_small_schwa */
+ { 0x0000fe63, 11085 }, /* dead_stroke */
+ { 0x0000fe53, 11097 }, /* dead_tilde */
+ { 0x0000fe88, 11108 }, /* dead_u */
+ { 0x0000fe89, 11115 }, /* dead_U */
+ { 0x0000fe5e, 11122 }, /* dead_voiced_sound */
+ { 0x00000abd, 11140 }, /* decimalpoint */
+ { 0x000000b0, 11153 }, /* degree */
+ { 0x0000ffff, 11160 }, /* Delete */
+ { 0x1000ff73, 11167 }, /* DeleteChar */
+ { 0x1000ff71, 11178 }, /* DeleteLine */
+ { 0x1000fe60, 11189 }, /* Dgrave_accent */
+ { 0x000000a8, 11203 }, /* diaeresis */
+ { 0x00000aed, 11213 }, /* diamond */
+ { 0x00000aa5, 11221 }, /* digitspace */
+ { 0x0100222c, 11232 }, /* dintegral */
+ { 0x000000f7, 11242 }, /* division */
+ { 0x00000024, 11251 }, /* dollar */
+ { 0x010020ab, 11258 }, /* DongSign */
+ { 0x00000aaf, 11267 }, /* doubbaselinedot */
+ { 0x000001bd, 11283 }, /* doubleacute */
+ { 0x00000af2, 11295 }, /* doubledagger */
+ { 0x00000afe, 11308 }, /* doublelowquotemark */
+ { 0x0000ff54, 11327 }, /* Down */
+ { 0x000008fe, 11332 }, /* downarrow */
+ { 0x00000ba8, 11342 }, /* downcaret */
+ { 0x00000bd6, 11352 }, /* downshoe */
+ { 0x00000bc4, 11361 }, /* downstile */
+ { 0x00000bc2, 11371 }, /* downtack */
+ { 0x1000ff00, 11380 }, /* DRemove */
+ { 0x1000feb0, 11388 }, /* Dring_accent */
+ { 0x000001d0, 11401 }, /* Dstroke */
+ { 0x000001f0, 11409 }, /* dstroke */
+ { 0x1000fe7e, 11417 }, /* Dtilde */
+ { 0x00000045, 11424 }, /* E */
+ { 0x00000065, 11426 }, /* e */
+ { 0x000003cc, 11428 }, /* Eabovedot */
+ { 0x000003ec, 11438 }, /* eabovedot */
+ { 0x000000c9, 11448 }, /* Eacute */
+ { 0x000000e9, 11455 }, /* eacute */
+ { 0x01001eb8, 11462 }, /* Ebelowdot */
+ { 0x01001eb9, 11472 }, /* ebelowdot */
+ { 0x000001cc, 11482 }, /* Ecaron */
+ { 0x000001ec, 11489 }, /* ecaron */
+ { 0x000000ca, 11496 }, /* Ecircumflex */
+ { 0x000000ea, 11508 }, /* ecircumflex */
+ { 0x01001ebe, 11520 }, /* Ecircumflexacute */
+ { 0x01001ebf, 11537 }, /* ecircumflexacute */
+ { 0x01001ec6, 11554 }, /* Ecircumflexbelowdot */
+ { 0x01001ec7, 11574 }, /* ecircumflexbelowdot */
+ { 0x01001ec0, 11594 }, /* Ecircumflexgrave */
+ { 0x01001ec1, 11611 }, /* ecircumflexgrave */
+ { 0x01001ec2, 11628 }, /* Ecircumflexhook */
+ { 0x01001ec3, 11644 }, /* ecircumflexhook */
+ { 0x01001ec4, 11660 }, /* Ecircumflextilde */
+ { 0x01001ec5, 11677 }, /* ecircumflextilde */
+ { 0x010020a0, 11694 }, /* EcuSign */
+ { 0x000000cb, 11702 }, /* Ediaeresis */
+ { 0x000000eb, 11713 }, /* ediaeresis */
+ { 0x000000c8, 11724 }, /* Egrave */
+ { 0x000000e8, 11731 }, /* egrave */
+ { 0x01001eba, 11738 }, /* Ehook */
+ { 0x01001ebb, 11744 }, /* ehook */
+ { 0x01002088, 11750 }, /* eightsubscript */
+ { 0x01002078, 11765 }, /* eightsuperior */
+ { 0x0000ff2f, 11779 }, /* Eisu_Shift */
+ { 0x0000ff30, 11790 }, /* Eisu_toggle */
+ { 0x01002208, 11802 }, /* elementof */
+ { 0x00000aae, 11812 }, /* ellipsis */
+ { 0x00000aa3, 11821 }, /* em3space */
+ { 0x00000aa4, 11830 }, /* em4space */
+ { 0x000003aa, 11839 }, /* Emacron */
+ { 0x000003ba, 11847 }, /* emacron */
+ { 0x00000aa9, 11855 }, /* emdash */
+ { 0x00000ade, 11862 }, /* emfilledcircle */
+ { 0x00000adf, 11877 }, /* emfilledrect */
+ { 0x00000ace, 11890 }, /* emopencircle */
+ { 0x00000acf, 11903 }, /* emopenrectangle */
+ { 0x01002205, 11919 }, /* emptyset */
+ { 0x00000aa1, 11928 }, /* emspace */
+ { 0x0000ff57, 11936 }, /* End */
+ { 0x00000aaa, 11940 }, /* endash */
+ { 0x00000ae6, 11947 }, /* enfilledcircbullet */
+ { 0x00000ae7, 11966 }, /* enfilledsqbullet */
+ { 0x000003bd, 11983 }, /* ENG */
+ { 0x000003bf, 11987 }, /* eng */
+ { 0x00000ae0, 11991 }, /* enopencircbullet */
+ { 0x00000ae1, 12008 }, /* enopensquarebullet */
+ { 0x00000aa2, 12027 }, /* enspace */
+ { 0x000001ca, 12035 }, /* Eogonek */
+ { 0x000001ea, 12043 }, /* eogonek */
+ { 0x0000003d, 12051 }, /* equal */
+ { 0x0000ff1b, 12057 }, /* Escape */
+ { 0x000000d0, 12064 }, /* ETH */
+ { 0x000000d0, 12068 }, /* Eth */
+ { 0x000000f0, 12072 }, /* eth */
+ { 0x01001ebc, 12076 }, /* Etilde */
+ { 0x01001ebd, 12083 }, /* etilde */
+ { 0x000020ac, 12090 }, /* EuroSign */
+ { 0x00000021, 12099 }, /* exclam */
+ { 0x000000a1, 12106 }, /* exclamdown */
+ { 0x0000ff62, 12117 }, /* Execute */
+ { 0x1000ff76, 12125 }, /* Ext16bit_L */
+ { 0x1000ff77, 12136 }, /* Ext16bit_R */
+ { 0x010001b7, 12147 }, /* EZH */
+ { 0x01000292, 12151 }, /* ezh */
+ { 0x00000046, 12155 }, /* F */
+ { 0x00000066, 12157 }, /* f */
+ { 0x0000ffbe, 12159 }, /* F1 */
+ { 0x0000ffc7, 12162 }, /* F10 */
+ { 0x0000ffc8, 12166 }, /* F11 */
+ { 0x0000ffc9, 12170 }, /* F12 */
+ { 0x0000ffca, 12174 }, /* F13 */
+ { 0x0000ffcb, 12178 }, /* F14 */
+ { 0x0000ffcc, 12182 }, /* F15 */
+ { 0x0000ffcd, 12186 }, /* F16 */
+ { 0x0000ffce, 12190 }, /* F17 */
+ { 0x0000ffcf, 12194 }, /* F18 */
+ { 0x0000ffd0, 12198 }, /* F19 */
+ { 0x0000ffbf, 12202 }, /* F2 */
+ { 0x0000ffd1, 12205 }, /* F20 */
+ { 0x0000ffd2, 12209 }, /* F21 */
+ { 0x0000ffd3, 12213 }, /* F22 */
+ { 0x0000ffd4, 12217 }, /* F23 */
+ { 0x0000ffd5, 12221 }, /* F24 */
+ { 0x0000ffd6, 12225 }, /* F25 */
+ { 0x0000ffd7, 12229 }, /* F26 */
+ { 0x0000ffd8, 12233 }, /* F27 */
+ { 0x0000ffd9, 12237 }, /* F28 */
+ { 0x0000ffda, 12241 }, /* F29 */
+ { 0x0000ffc0, 12245 }, /* F3 */
+ { 0x0000ffdb, 12248 }, /* F30 */
+ { 0x0000ffdc, 12252 }, /* F31 */
+ { 0x0000ffdd, 12256 }, /* F32 */
+ { 0x0000ffde, 12260 }, /* F33 */
+ { 0x0000ffdf, 12264 }, /* F34 */
+ { 0x0000ffe0, 12268 }, /* F35 */
+ { 0x0000ffc1, 12272 }, /* F4 */
+ { 0x0000ffc2, 12275 }, /* F5 */
+ { 0x0000ffc3, 12278 }, /* F6 */
+ { 0x0000ffc4, 12281 }, /* F7 */
+ { 0x0000ffc5, 12284 }, /* F8 */
+ { 0x0000ffc6, 12287 }, /* F9 */
+ { 0x01001e1e, 12290 }, /* Fabovedot */
+ { 0x01001e1f, 12300 }, /* fabovedot */
+ { 0x010006f0, 12310 }, /* Farsi_0 */
+ { 0x010006f1, 12318 }, /* Farsi_1 */
+ { 0x010006f2, 12326 }, /* Farsi_2 */
+ { 0x010006f3, 12334 }, /* Farsi_3 */
+ { 0x010006f4, 12342 }, /* Farsi_4 */
+ { 0x010006f5, 12350 }, /* Farsi_5 */
+ { 0x010006f6, 12358 }, /* Farsi_6 */
+ { 0x010006f7, 12366 }, /* Farsi_7 */
+ { 0x010006f8, 12374 }, /* Farsi_8 */
+ { 0x010006f9, 12382 }, /* Farsi_9 */
+ { 0x010006cc, 12390 }, /* Farsi_yeh */
+ { 0x00000af8, 12400 }, /* femalesymbol */
+ { 0x000009e3, 12413 }, /* ff */
+ { 0x010020a3, 12416 }, /* FFrancSign */
+ { 0x00000abb, 12427 }, /* figdash */
+ { 0x00000adc, 12435 }, /* filledlefttribullet */
+ { 0x00000adb, 12455 }, /* filledrectbullet */
+ { 0x00000add, 12472 }, /* filledrighttribullet */
+ { 0x00000ae9, 12493 }, /* filledtribulletdown */
+ { 0x00000ae8, 12513 }, /* filledtribulletup */
+ { 0x0000ff68, 12531 }, /* Find */
+ { 0x0000fed0, 12536 }, /* First_Virtual_Screen */
+ { 0x00000ac5, 12557 }, /* fiveeighths */
+ { 0x00000ab7, 12569 }, /* fivesixths */
+ { 0x01002085, 12580 }, /* fivesubscript */
+ { 0x01002075, 12594 }, /* fivesuperior */
+ { 0x00000ab5, 12607 }, /* fourfifths */
+ { 0x01002084, 12618 }, /* foursubscript */
+ { 0x01002074, 12632 }, /* foursuperior */
+ { 0x0100221c, 12645 }, /* fourthroot */
+ { 0x000008f6, 12656 }, /* function */
+ { 0x00000047, 12665 }, /* G */
+ { 0x00000067, 12667 }, /* g */
+ { 0x000002d5, 12669 }, /* Gabovedot */
+ { 0x000002f5, 12679 }, /* gabovedot */
+ { 0x000002ab, 12689 }, /* Gbreve */
+ { 0x000002bb, 12696 }, /* gbreve */
+ { 0x010001e6, 12703 }, /* Gcaron */
+ { 0x010001e7, 12710 }, /* gcaron */
+ { 0x000003ab, 12717 }, /* Gcedilla */
+ { 0x000003bb, 12726 }, /* gcedilla */
+ { 0x000002d8, 12735 }, /* Gcircumflex */
+ { 0x000002f8, 12747 }, /* gcircumflex */
+ { 0x010010d0, 12759 }, /* Georgian_an */
+ { 0x010010d1, 12771 }, /* Georgian_ban */
+ { 0x010010ea, 12784 }, /* Georgian_can */
+ { 0x010010ed, 12797 }, /* Georgian_char */
+ { 0x010010e9, 12811 }, /* Georgian_chin */
+ { 0x010010ec, 12825 }, /* Georgian_cil */
+ { 0x010010d3, 12838 }, /* Georgian_don */
+ { 0x010010d4, 12851 }, /* Georgian_en */
+ { 0x010010f6, 12863 }, /* Georgian_fi */
+ { 0x010010d2, 12875 }, /* Georgian_gan */
+ { 0x010010e6, 12888 }, /* Georgian_ghan */
+ { 0x010010f0, 12902 }, /* Georgian_hae */
+ { 0x010010f4, 12915 }, /* Georgian_har */
+ { 0x010010f1, 12928 }, /* Georgian_he */
+ { 0x010010f2, 12940 }, /* Georgian_hie */
+ { 0x010010f5, 12953 }, /* Georgian_hoe */
+ { 0x010010d8, 12966 }, /* Georgian_in */
+ { 0x010010ef, 12978 }, /* Georgian_jhan */
+ { 0x010010eb, 12992 }, /* Georgian_jil */
+ { 0x010010d9, 13005 }, /* Georgian_kan */
+ { 0x010010e5, 13018 }, /* Georgian_khar */
+ { 0x010010da, 13032 }, /* Georgian_las */
+ { 0x010010db, 13045 }, /* Georgian_man */
+ { 0x010010dc, 13058 }, /* Georgian_nar */
+ { 0x010010dd, 13071 }, /* Georgian_on */
+ { 0x010010de, 13083 }, /* Georgian_par */
+ { 0x010010e4, 13096 }, /* Georgian_phar */
+ { 0x010010e7, 13110 }, /* Georgian_qar */
+ { 0x010010e0, 13123 }, /* Georgian_rae */
+ { 0x010010e1, 13136 }, /* Georgian_san */
+ { 0x010010e8, 13149 }, /* Georgian_shin */
+ { 0x010010d7, 13163 }, /* Georgian_tan */
+ { 0x010010e2, 13176 }, /* Georgian_tar */
+ { 0x010010e3, 13189 }, /* Georgian_un */
+ { 0x010010d5, 13201 }, /* Georgian_vin */
+ { 0x010010f3, 13214 }, /* Georgian_we */
+ { 0x010010ee, 13226 }, /* Georgian_xan */
+ { 0x010010d6, 13239 }, /* Georgian_zen */
+ { 0x010010df, 13252 }, /* Georgian_zhar */
+ { 0x00000060, 13266 }, /* grave */
+ { 0x0000003e, 13272 }, /* greater */
+ { 0x000008be, 13280 }, /* greaterthanequal */
+ { 0x000007ae, 13297 }, /* Greek_accentdieresis */
+ { 0x000007c1, 13318 }, /* Greek_ALPHA */
+ { 0x000007e1, 13330 }, /* Greek_alpha */
+ { 0x000007a1, 13342 }, /* Greek_ALPHAaccent */
+ { 0x000007b1, 13360 }, /* Greek_alphaaccent */
+ { 0x000007c2, 13378 }, /* Greek_BETA */
+ { 0x000007e2, 13389 }, /* Greek_beta */
+ { 0x000007d7, 13400 }, /* Greek_CHI */
+ { 0x000007f7, 13410 }, /* Greek_chi */
+ { 0x000007c4, 13420 }, /* Greek_DELTA */
+ { 0x000007e4, 13432 }, /* Greek_delta */
+ { 0x000007c5, 13444 }, /* Greek_EPSILON */
+ { 0x000007e5, 13458 }, /* Greek_epsilon */
+ { 0x000007a2, 13472 }, /* Greek_EPSILONaccent */
+ { 0x000007b2, 13492 }, /* Greek_epsilonaccent */
+ { 0x000007c7, 13512 }, /* Greek_ETA */
+ { 0x000007e7, 13522 }, /* Greek_eta */
+ { 0x000007a3, 13532 }, /* Greek_ETAaccent */
+ { 0x000007b3, 13548 }, /* Greek_etaaccent */
+ { 0x000007f3, 13564 }, /* Greek_finalsmallsigma */
+ { 0x000007c3, 13586 }, /* Greek_GAMMA */
+ { 0x000007e3, 13598 }, /* Greek_gamma */
+ { 0x000007af, 13610 }, /* Greek_horizbar */
+ { 0x000007c9, 13625 }, /* Greek_IOTA */
+ { 0x000007e9, 13636 }, /* Greek_iota */
+ { 0x000007a4, 13647 }, /* Greek_IOTAaccent */
+ { 0x000007b4, 13664 }, /* Greek_iotaaccent */
+ { 0x000007b6, 13681 }, /* Greek_iotaaccentdieresis */
+ { 0x000007a5, 13706 }, /* Greek_IOTAdiaeresis */
+ { 0x000007a5, 13726 }, /* Greek_IOTAdieresis */
+ { 0x000007b5, 13745 }, /* Greek_iotadieresis */
+ { 0x000007ca, 13764 }, /* Greek_KAPPA */
+ { 0x000007ea, 13776 }, /* Greek_kappa */
+ { 0x000007cb, 13788 }, /* Greek_LAMBDA */
+ { 0x000007eb, 13801 }, /* Greek_lambda */
+ { 0x000007cb, 13814 }, /* Greek_LAMDA */
+ { 0x000007eb, 13826 }, /* Greek_lamda */
+ { 0x000007cc, 13838 }, /* Greek_MU */
+ { 0x000007ec, 13847 }, /* Greek_mu */
+ { 0x000007cd, 13856 }, /* Greek_NU */
+ { 0x000007ed, 13865 }, /* Greek_nu */
+ { 0x000007d9, 13874 }, /* Greek_OMEGA */
+ { 0x000007f9, 13886 }, /* Greek_omega */
+ { 0x000007ab, 13898 }, /* Greek_OMEGAaccent */
+ { 0x000007bb, 13916 }, /* Greek_omegaaccent */
+ { 0x000007cf, 13934 }, /* Greek_OMICRON */
+ { 0x000007ef, 13948 }, /* Greek_omicron */
+ { 0x000007a7, 13962 }, /* Greek_OMICRONaccent */
+ { 0x000007b7, 13982 }, /* Greek_omicronaccent */
+ { 0x000007d6, 14002 }, /* Greek_PHI */
+ { 0x000007f6, 14012 }, /* Greek_phi */
+ { 0x000007d0, 14022 }, /* Greek_PI */
+ { 0x000007f0, 14031 }, /* Greek_pi */
+ { 0x000007d8, 14040 }, /* Greek_PSI */
+ { 0x000007f8, 14050 }, /* Greek_psi */
+ { 0x000007d1, 14060 }, /* Greek_RHO */
+ { 0x000007f1, 14070 }, /* Greek_rho */
+ { 0x000007d2, 14080 }, /* Greek_SIGMA */
+ { 0x000007f2, 14092 }, /* Greek_sigma */
+ { 0x0000ff7e, 14104 }, /* Greek_switch */
+ { 0x000007d4, 14117 }, /* Greek_TAU */
+ { 0x000007f4, 14127 }, /* Greek_tau */
+ { 0x000007c8, 14137 }, /* Greek_THETA */
+ { 0x000007e8, 14149 }, /* Greek_theta */
+ { 0x000007d5, 14161 }, /* Greek_UPSILON */
+ { 0x000007f5, 14175 }, /* Greek_upsilon */
+ { 0x000007a8, 14189 }, /* Greek_UPSILONaccent */
+ { 0x000007b8, 14209 }, /* Greek_upsilonaccent */
+ { 0x000007ba, 14229 }, /* Greek_upsilonaccentdieresis */
+ { 0x000007a9, 14257 }, /* Greek_UPSILONdieresis */
+ { 0x000007b9, 14279 }, /* Greek_upsilondieresis */
+ { 0x000007ce, 14301 }, /* Greek_XI */
+ { 0x000007ee, 14310 }, /* Greek_xi */
+ { 0x000007c6, 14319 }, /* Greek_ZETA */
+ { 0x000007e6, 14330 }, /* Greek_zeta */
+ { 0x100000be, 14341 }, /* guilder */
+ { 0x000000ab, 14349 }, /* guillemotleft */
+ { 0x000000bb, 14363 }, /* guillemotright */
+ { 0x00000048, 14378 }, /* H */
+ { 0x00000068, 14380 }, /* h */
+ { 0x00000aa8, 14382 }, /* hairspace */
+ { 0x0000ff31, 14392 }, /* Hangul */
+ { 0x00000ebf, 14399 }, /* Hangul_A */
+ { 0x00000ec0, 14408 }, /* Hangul_AE */
+ { 0x00000ef6, 14418 }, /* Hangul_AraeA */
+ { 0x00000ef7, 14431 }, /* Hangul_AraeAE */
+ { 0x0000ff39, 14445 }, /* Hangul_Banja */
+ { 0x00000eba, 14458 }, /* Hangul_Cieuc */
+ { 0x0000ff37, 14471 }, /* Hangul_Codeinput */
+ { 0x00000ea7, 14488 }, /* Hangul_Dikeud */
+ { 0x00000ec4, 14502 }, /* Hangul_E */
+ { 0x0000ff33, 14511 }, /* Hangul_End */
+ { 0x00000ec3, 14522 }, /* Hangul_EO */
+ { 0x00000ed1, 14532 }, /* Hangul_EU */
+ { 0x0000ff34, 14542 }, /* Hangul_Hanja */
+ { 0x00000ebe, 14555 }, /* Hangul_Hieuh */
+ { 0x00000ed3, 14568 }, /* Hangul_I */
+ { 0x00000eb7, 14577 }, /* Hangul_Ieung */
+ { 0x00000eea, 14590 }, /* Hangul_J_Cieuc */
+ { 0x00000eda, 14605 }, /* Hangul_J_Dikeud */
+ { 0x00000eee, 14621 }, /* Hangul_J_Hieuh */
+ { 0x00000ee8, 14636 }, /* Hangul_J_Ieung */
+ { 0x00000ee9, 14651 }, /* Hangul_J_Jieuj */
+ { 0x00000eeb, 14666 }, /* Hangul_J_Khieuq */
+ { 0x00000ed4, 14682 }, /* Hangul_J_Kiyeog */
+ { 0x00000ed6, 14698 }, /* Hangul_J_KiyeogSios */
+ { 0x00000ef9, 14718 }, /* Hangul_J_KkogjiDalrinIeung */
+ { 0x00000ee3, 14745 }, /* Hangul_J_Mieum */
+ { 0x00000ed7, 14760 }, /* Hangul_J_Nieun */
+ { 0x00000ed9, 14775 }, /* Hangul_J_NieunHieuh */
+ { 0x00000ed8, 14795 }, /* Hangul_J_NieunJieuj */
+ { 0x00000ef8, 14815 }, /* Hangul_J_PanSios */
+ { 0x00000eed, 14832 }, /* Hangul_J_Phieuf */
+ { 0x00000ee4, 14848 }, /* Hangul_J_Pieub */
+ { 0x00000ee5, 14863 }, /* Hangul_J_PieubSios */
+ { 0x00000edb, 14882 }, /* Hangul_J_Rieul */
+ { 0x00000ee2, 14897 }, /* Hangul_J_RieulHieuh */
+ { 0x00000edc, 14917 }, /* Hangul_J_RieulKiyeog */
+ { 0x00000edd, 14938 }, /* Hangul_J_RieulMieum */
+ { 0x00000ee1, 14958 }, /* Hangul_J_RieulPhieuf */
+ { 0x00000ede, 14979 }, /* Hangul_J_RieulPieub */
+ { 0x00000edf, 14999 }, /* Hangul_J_RieulSios */
+ { 0x00000ee0, 15018 }, /* Hangul_J_RieulTieut */
+ { 0x00000ee6, 15038 }, /* Hangul_J_Sios */
+ { 0x00000ed5, 15052 }, /* Hangul_J_SsangKiyeog */
+ { 0x00000ee7, 15073 }, /* Hangul_J_SsangSios */
+ { 0x00000eec, 15092 }, /* Hangul_J_Tieut */
+ { 0x00000efa, 15107 }, /* Hangul_J_YeorinHieuh */
+ { 0x0000ff35, 15128 }, /* Hangul_Jamo */
+ { 0x0000ff38, 15140 }, /* Hangul_Jeonja */
+ { 0x00000eb8, 15154 }, /* Hangul_Jieuj */
+ { 0x00000ebb, 15167 }, /* Hangul_Khieuq */
+ { 0x00000ea1, 15181 }, /* Hangul_Kiyeog */
+ { 0x00000ea3, 15195 }, /* Hangul_KiyeogSios */
+ { 0x00000ef3, 15213 }, /* Hangul_KkogjiDalrinIeung */
+ { 0x00000eb1, 15238 }, /* Hangul_Mieum */
+ { 0x0000ff3d, 15251 }, /* Hangul_MultipleCandidate */
+ { 0x00000ea4, 15276 }, /* Hangul_Nieun */
+ { 0x00000ea6, 15289 }, /* Hangul_NieunHieuh */
+ { 0x00000ea5, 15307 }, /* Hangul_NieunJieuj */
+ { 0x00000ec7, 15325 }, /* Hangul_O */
+ { 0x00000eca, 15334 }, /* Hangul_OE */
+ { 0x00000ef2, 15344 }, /* Hangul_PanSios */
+ { 0x00000ebd, 15359 }, /* Hangul_Phieuf */
+ { 0x00000eb2, 15373 }, /* Hangul_Pieub */
+ { 0x00000eb4, 15386 }, /* Hangul_PieubSios */
+ { 0x0000ff3b, 15403 }, /* Hangul_PostHanja */
+ { 0x0000ff3a, 15420 }, /* Hangul_PreHanja */
+ { 0x0000ff3e, 15436 }, /* Hangul_PreviousCandidate */
+ { 0x00000ea9, 15461 }, /* Hangul_Rieul */
+ { 0x00000eb0, 15474 }, /* Hangul_RieulHieuh */
+ { 0x00000eaa, 15492 }, /* Hangul_RieulKiyeog */
+ { 0x00000eab, 15511 }, /* Hangul_RieulMieum */
+ { 0x00000eaf, 15529 }, /* Hangul_RieulPhieuf */
+ { 0x00000eac, 15548 }, /* Hangul_RieulPieub */
+ { 0x00000ead, 15566 }, /* Hangul_RieulSios */
+ { 0x00000eae, 15583 }, /* Hangul_RieulTieut */
+ { 0x00000eef, 15601 }, /* Hangul_RieulYeorinHieuh */
+ { 0x0000ff36, 15625 }, /* Hangul_Romaja */
+ { 0x0000ff3c, 15639 }, /* Hangul_SingleCandidate */
+ { 0x00000eb5, 15662 }, /* Hangul_Sios */
+ { 0x0000ff3f, 15674 }, /* Hangul_Special */
+ { 0x00000ea8, 15689 }, /* Hangul_SsangDikeud */
+ { 0x00000eb9, 15708 }, /* Hangul_SsangJieuj */
+ { 0x00000ea2, 15726 }, /* Hangul_SsangKiyeog */
+ { 0x00000eb3, 15745 }, /* Hangul_SsangPieub */
+ { 0x00000eb6, 15763 }, /* Hangul_SsangSios */
+ { 0x0000ff32, 15780 }, /* Hangul_Start */
+ { 0x00000ef0, 15793 }, /* Hangul_SunkyeongeumMieum */
+ { 0x00000ef4, 15818 }, /* Hangul_SunkyeongeumPhieuf */
+ { 0x00000ef1, 15844 }, /* Hangul_SunkyeongeumPieub */
+ { 0x0000ff7e, 15869 }, /* Hangul_switch */
+ { 0x00000ebc, 15883 }, /* Hangul_Tieut */
+ { 0x00000ecc, 15896 }, /* Hangul_U */
+ { 0x00000ec8, 15905 }, /* Hangul_WA */
+ { 0x00000ec9, 15915 }, /* Hangul_WAE */
+ { 0x00000ece, 15926 }, /* Hangul_WE */
+ { 0x00000ecd, 15936 }, /* Hangul_WEO */
+ { 0x00000ecf, 15947 }, /* Hangul_WI */
+ { 0x00000ec1, 15957 }, /* Hangul_YA */
+ { 0x00000ec2, 15967 }, /* Hangul_YAE */
+ { 0x00000ec6, 15978 }, /* Hangul_YE */
+ { 0x00000ec5, 15988 }, /* Hangul_YEO */
+ { 0x00000ef5, 15999 }, /* Hangul_YeorinHieuh */
+ { 0x00000ed2, 16018 }, /* Hangul_YI */
+ { 0x00000ecb, 16028 }, /* Hangul_YO */
+ { 0x00000ed0, 16038 }, /* Hangul_YU */
+ { 0x0000ff29, 16048 }, /* Hankaku */
+ { 0x000002a6, 16056 }, /* Hcircumflex */
+ { 0x000002b6, 16068 }, /* hcircumflex */
+ { 0x00000aee, 16080 }, /* heart */
+ { 0x00000ce0, 16086 }, /* hebrew_aleph */
+ { 0x00000cf2, 16099 }, /* hebrew_ayin */
+ { 0x00000ce1, 16111 }, /* hebrew_bet */
+ { 0x00000ce1, 16122 }, /* hebrew_beth */
+ { 0x00000ce7, 16134 }, /* hebrew_chet */
+ { 0x00000ce3, 16146 }, /* hebrew_dalet */
+ { 0x00000ce3, 16159 }, /* hebrew_daleth */
+ { 0x00000cdf, 16173 }, /* hebrew_doublelowline */
+ { 0x00000cea, 16194 }, /* hebrew_finalkaph */
+ { 0x00000ced, 16211 }, /* hebrew_finalmem */
+ { 0x00000cef, 16227 }, /* hebrew_finalnun */
+ { 0x00000cf3, 16243 }, /* hebrew_finalpe */
+ { 0x00000cf5, 16258 }, /* hebrew_finalzade */
+ { 0x00000cf5, 16275 }, /* hebrew_finalzadi */
+ { 0x00000ce2, 16292 }, /* hebrew_gimel */
+ { 0x00000ce2, 16305 }, /* hebrew_gimmel */
+ { 0x00000ce4, 16319 }, /* hebrew_he */
+ { 0x00000ce7, 16329 }, /* hebrew_het */
+ { 0x00000ceb, 16340 }, /* hebrew_kaph */
+ { 0x00000cf7, 16352 }, /* hebrew_kuf */
+ { 0x00000cec, 16363 }, /* hebrew_lamed */
+ { 0x00000cee, 16376 }, /* hebrew_mem */
+ { 0x00000cf0, 16387 }, /* hebrew_nun */
+ { 0x00000cf4, 16398 }, /* hebrew_pe */
+ { 0x00000cf7, 16408 }, /* hebrew_qoph */
+ { 0x00000cf8, 16420 }, /* hebrew_resh */
+ { 0x00000cf1, 16432 }, /* hebrew_samech */
+ { 0x00000cf1, 16446 }, /* hebrew_samekh */
+ { 0x00000cf9, 16460 }, /* hebrew_shin */
+ { 0x0000ff7e, 16472 }, /* Hebrew_switch */
+ { 0x00000cfa, 16486 }, /* hebrew_taf */
+ { 0x00000cfa, 16497 }, /* hebrew_taw */
+ { 0x00000ce8, 16508 }, /* hebrew_tet */
+ { 0x00000ce8, 16519 }, /* hebrew_teth */
+ { 0x00000ce5, 16531 }, /* hebrew_waw */
+ { 0x00000ce9, 16542 }, /* hebrew_yod */
+ { 0x00000cf6, 16553 }, /* hebrew_zade */
+ { 0x00000cf6, 16565 }, /* hebrew_zadi */
+ { 0x00000ce6, 16577 }, /* hebrew_zain */
+ { 0x00000ce6, 16589 }, /* hebrew_zayin */
+ { 0x0000ff6a, 16602 }, /* Help */
+ { 0x0000ff23, 16607 }, /* Henkan */
+ { 0x0000ff23, 16614 }, /* Henkan_Mode */
+ { 0x00000ada, 16626 }, /* hexagram */
+ { 0x0000ff25, 16635 }, /* Hiragana */
+ { 0x0000ff27, 16644 }, /* Hiragana_Katakana */
+ { 0x0000ff50, 16662 }, /* Home */
+ { 0x000008a3, 16667 }, /* horizconnector */
+ { 0x000009ef, 16682 }, /* horizlinescan1 */
+ { 0x000009f0, 16697 }, /* horizlinescan3 */
+ { 0x000009f1, 16712 }, /* horizlinescan5 */
+ { 0x000009f2, 16727 }, /* horizlinescan7 */
+ { 0x000009f3, 16742 }, /* horizlinescan9 */
+ { 0x1000ff74, 16757 }, /* hpBackTab */
+ { 0x100000fc, 16767 }, /* hpblock */
+ { 0x1000ff6f, 16775 }, /* hpClearLine */
+ { 0x1000ff73, 16787 }, /* hpDeleteChar */
+ { 0x1000ff71, 16800 }, /* hpDeleteLine */
+ { 0x100000be, 16813 }, /* hpguilder */
+ { 0x1000ff72, 16823 }, /* hpInsertChar */
+ { 0x1000ff70, 16836 }, /* hpInsertLine */
+ { 0x100000ee, 16849 }, /* hpIO */
+ { 0x1000ff75, 16854 }, /* hpKP_BackTab */
+ { 0x100000af, 16867 }, /* hplira */
+ { 0x100000f6, 16874 }, /* hplongminus */
+ { 0x1000ff48, 16886 }, /* hpModelock1 */
+ { 0x1000ff49, 16898 }, /* hpModelock2 */
+ { 0x100000a8, 16910 }, /* hpmute_acute */
+ { 0x100000aa, 16923 }, /* hpmute_asciicircum */
+ { 0x100000ac, 16942 }, /* hpmute_asciitilde */
+ { 0x100000ab, 16960 }, /* hpmute_diaeresis */
+ { 0x100000a9, 16977 }, /* hpmute_grave */
+ { 0x1000ff6c, 16990 }, /* hpReset */
+ { 0x1000ff6d, 16998 }, /* hpSystem */
+ { 0x1000ff6e, 17007 }, /* hpUser */
+ { 0x100000ee, 17014 }, /* hpYdiaeresis */
+ { 0x000002a1, 17027 }, /* Hstroke */
+ { 0x000002b1, 17035 }, /* hstroke */
+ { 0x000009e2, 17043 }, /* ht */
+ { 0x0000ffed, 17046 }, /* Hyper_L */
+ { 0x0000ffee, 17054 }, /* Hyper_R */
+ { 0x000000ad, 17062 }, /* hyphen */
+ { 0x00000049, 17069 }, /* I */
+ { 0x00000069, 17071 }, /* i */
+ { 0x000002a9, 17073 }, /* Iabovedot */
+ { 0x000000cd, 17083 }, /* Iacute */
+ { 0x000000ed, 17090 }, /* iacute */
+ { 0x01001eca, 17097 }, /* Ibelowdot */
+ { 0x01001ecb, 17107 }, /* ibelowdot */
+ { 0x0100012c, 17117 }, /* Ibreve */
+ { 0x0100012d, 17124 }, /* ibreve */
+ { 0x000000ce, 17131 }, /* Icircumflex */
+ { 0x000000ee, 17143 }, /* icircumflex */
+ { 0x000008cf, 17155 }, /* identical */
+ { 0x000000cf, 17165 }, /* Idiaeresis */
+ { 0x000000ef, 17176 }, /* idiaeresis */
+ { 0x000002b9, 17187 }, /* idotless */
+ { 0x000008cd, 17196 }, /* ifonlyif */
+ { 0x000000cc, 17205 }, /* Igrave */
+ { 0x000000ec, 17212 }, /* igrave */
+ { 0x01001ec8, 17219 }, /* Ihook */
+ { 0x01001ec9, 17225 }, /* ihook */
+ { 0x000003cf, 17231 }, /* Imacron */
+ { 0x000003ef, 17239 }, /* imacron */
+ { 0x000008ce, 17247 }, /* implies */
+ { 0x000008da, 17255 }, /* includedin */
+ { 0x000008db, 17266 }, /* includes */
+ { 0x000008c2, 17275 }, /* infinity */
+ { 0x0000ff63, 17284 }, /* Insert */
+ { 0x1000ff72, 17291 }, /* InsertChar */
+ { 0x1000ff70, 17302 }, /* InsertLine */
+ { 0x000008bf, 17313 }, /* integral */
+ { 0x000008dc, 17322 }, /* intersection */
+ { 0x100000ee, 17335 }, /* IO */
+ { 0x000003c7, 17338 }, /* Iogonek */
+ { 0x000003e7, 17346 }, /* iogonek */
+ { 0x0000fe33, 17354 }, /* ISO_Center_Object */
+ { 0x0000fe30, 17372 }, /* ISO_Continuous_Underline */
+ { 0x0000fe31, 17397 }, /* ISO_Discontinuous_Underline */
+ { 0x0000fe32, 17425 }, /* ISO_Emphasize */
+ { 0x0000fe34, 17439 }, /* ISO_Enter */
+ { 0x0000fe2f, 17449 }, /* ISO_Fast_Cursor_Down */
+ { 0x0000fe2c, 17470 }, /* ISO_Fast_Cursor_Left */
+ { 0x0000fe2d, 17491 }, /* ISO_Fast_Cursor_Right */
+ { 0x0000fe2e, 17513 }, /* ISO_Fast_Cursor_Up */
+ { 0x0000fe0c, 17532 }, /* ISO_First_Group */
+ { 0x0000fe0d, 17548 }, /* ISO_First_Group_Lock */
+ { 0x0000fe06, 17569 }, /* ISO_Group_Latch */
+ { 0x0000fe07, 17585 }, /* ISO_Group_Lock */
+ { 0x0000ff7e, 17600 }, /* ISO_Group_Shift */
+ { 0x0000fe0e, 17616 }, /* ISO_Last_Group */
+ { 0x0000fe0f, 17631 }, /* ISO_Last_Group_Lock */
+ { 0x0000fe20, 17651 }, /* ISO_Left_Tab */
+ { 0x0000fe02, 17664 }, /* ISO_Level2_Latch */
+ { 0x0000fe04, 17681 }, /* ISO_Level3_Latch */
+ { 0x0000fe05, 17698 }, /* ISO_Level3_Lock */
+ { 0x0000fe03, 17714 }, /* ISO_Level3_Shift */
+ { 0x0000fe12, 17731 }, /* ISO_Level5_Latch */
+ { 0x0000fe13, 17748 }, /* ISO_Level5_Lock */
+ { 0x0000fe11, 17764 }, /* ISO_Level5_Shift */
+ { 0x0000fe01, 17781 }, /* ISO_Lock */
+ { 0x0000fe22, 17790 }, /* ISO_Move_Line_Down */
+ { 0x0000fe21, 17809 }, /* ISO_Move_Line_Up */
+ { 0x0000fe08, 17826 }, /* ISO_Next_Group */
+ { 0x0000fe09, 17841 }, /* ISO_Next_Group_Lock */
+ { 0x0000fe24, 17861 }, /* ISO_Partial_Line_Down */
+ { 0x0000fe23, 17883 }, /* ISO_Partial_Line_Up */
+ { 0x0000fe25, 17903 }, /* ISO_Partial_Space_Left */
+ { 0x0000fe26, 17926 }, /* ISO_Partial_Space_Right */
+ { 0x0000fe0a, 17950 }, /* ISO_Prev_Group */
+ { 0x0000fe0b, 17965 }, /* ISO_Prev_Group_Lock */
+ { 0x0000fe2b, 17985 }, /* ISO_Release_Both_Margins */
+ { 0x0000fe29, 18010 }, /* ISO_Release_Margin_Left */
+ { 0x0000fe2a, 18034 }, /* ISO_Release_Margin_Right */
+ { 0x0000fe27, 18059 }, /* ISO_Set_Margin_Left */
+ { 0x0000fe28, 18079 }, /* ISO_Set_Margin_Right */
+ { 0x000003a5, 18100 }, /* Itilde */
+ { 0x000003b5, 18107 }, /* itilde */
+ { 0x0000004a, 18114 }, /* J */
+ { 0x0000006a, 18116 }, /* j */
+ { 0x000002ac, 18118 }, /* Jcircumflex */
+ { 0x000002bc, 18130 }, /* jcircumflex */
+ { 0x00000bca, 18142 }, /* jot */
+ { 0x0000004b, 18146 }, /* K */
+ { 0x0000006b, 18148 }, /* k */
+ { 0x000004a7, 18150 }, /* kana_a */
+ { 0x000004b1, 18157 }, /* kana_A */
+ { 0x000004c1, 18164 }, /* kana_CHI */
+ { 0x000004a3, 18173 }, /* kana_closingbracket */
+ { 0x000004a4, 18193 }, /* kana_comma */
+ { 0x000004a5, 18204 }, /* kana_conjunctive */
+ { 0x000004aa, 18221 }, /* kana_e */
+ { 0x000004b4, 18228 }, /* kana_E */
+ { 0x000004cc, 18235 }, /* kana_FU */
+ { 0x000004a1, 18243 }, /* kana_fullstop */
+ { 0x000004ca, 18257 }, /* kana_HA */
+ { 0x000004cd, 18265 }, /* kana_HE */
+ { 0x000004cb, 18273 }, /* kana_HI */
+ { 0x000004ce, 18281 }, /* kana_HO */
+ { 0x000004cc, 18289 }, /* kana_HU */
+ { 0x000004a8, 18297 }, /* kana_i */
+ { 0x000004b2, 18304 }, /* kana_I */
+ { 0x000004b6, 18311 }, /* kana_KA */
+ { 0x000004b9, 18319 }, /* kana_KE */
+ { 0x000004b7, 18327 }, /* kana_KI */
+ { 0x000004ba, 18335 }, /* kana_KO */
+ { 0x000004b8, 18343 }, /* kana_KU */
+ { 0x0000ff2d, 18351 }, /* Kana_Lock */
+ { 0x000004cf, 18361 }, /* kana_MA */
+ { 0x000004d2, 18369 }, /* kana_ME */
+ { 0x000004d0, 18377 }, /* kana_MI */
+ { 0x000004a5, 18385 }, /* kana_middledot */
+ { 0x000004d3, 18400 }, /* kana_MO */
+ { 0x000004d1, 18408 }, /* kana_MU */
+ { 0x000004dd, 18416 }, /* kana_N */
+ { 0x000004c5, 18423 }, /* kana_NA */
+ { 0x000004c8, 18431 }, /* kana_NE */
+ { 0x000004c6, 18439 }, /* kana_NI */
+ { 0x000004c9, 18447 }, /* kana_NO */
+ { 0x000004c7, 18455 }, /* kana_NU */
+ { 0x000004ab, 18463 }, /* kana_o */
+ { 0x000004b5, 18470 }, /* kana_O */
+ { 0x000004a2, 18477 }, /* kana_openingbracket */
+ { 0x000004d7, 18497 }, /* kana_RA */
+ { 0x000004da, 18505 }, /* kana_RE */
+ { 0x000004d8, 18513 }, /* kana_RI */
+ { 0x000004db, 18521 }, /* kana_RO */
+ { 0x000004d9, 18529 }, /* kana_RU */
+ { 0x000004bb, 18537 }, /* kana_SA */
+ { 0x000004be, 18545 }, /* kana_SE */
+ { 0x000004bc, 18553 }, /* kana_SHI */
+ { 0x0000ff2e, 18562 }, /* Kana_Shift */
+ { 0x000004bf, 18573 }, /* kana_SO */
+ { 0x000004bd, 18581 }, /* kana_SU */
+ { 0x0000ff7e, 18589 }, /* kana_switch */
+ { 0x000004c0, 18601 }, /* kana_TA */
+ { 0x000004c3, 18609 }, /* kana_TE */
+ { 0x000004c1, 18617 }, /* kana_TI */
+ { 0x000004c4, 18625 }, /* kana_TO */
+ { 0x000004af, 18633 }, /* kana_tsu */
+ { 0x000004c2, 18642 }, /* kana_TSU */
+ { 0x000004af, 18651 }, /* kana_tu */
+ { 0x000004c2, 18659 }, /* kana_TU */
+ { 0x000004a9, 18667 }, /* kana_u */
+ { 0x000004b3, 18674 }, /* kana_U */
+ { 0x000004dc, 18681 }, /* kana_WA */
+ { 0x000004a6, 18689 }, /* kana_WO */
+ { 0x000004ac, 18697 }, /* kana_ya */
+ { 0x000004d4, 18705 }, /* kana_YA */
+ { 0x000004ae, 18713 }, /* kana_yo */
+ { 0x000004d6, 18721 }, /* kana_YO */
+ { 0x000004ad, 18729 }, /* kana_yu */
+ { 0x000004d5, 18737 }, /* kana_YU */
+ { 0x0000ff21, 18745 }, /* Kanji */
+ { 0x0000ff37, 18751 }, /* Kanji_Bangou */
+ { 0x000003a2, 18764 }, /* kappa */
+ { 0x0000ff26, 18770 }, /* Katakana */
+ { 0x000003d3, 18779 }, /* Kcedilla */
+ { 0x000003f3, 18788 }, /* kcedilla */
+ { 0x00000eff, 18797 }, /* Korean_Won */
+ { 0x0000ffb0, 18808 }, /* KP_0 */
+ { 0x0000ffb1, 18813 }, /* KP_1 */
+ { 0x0000ffb2, 18818 }, /* KP_2 */
+ { 0x0000ffb3, 18823 }, /* KP_3 */
+ { 0x0000ffb4, 18828 }, /* KP_4 */
+ { 0x0000ffb5, 18833 }, /* KP_5 */
+ { 0x0000ffb6, 18838 }, /* KP_6 */
+ { 0x0000ffb7, 18843 }, /* KP_7 */
+ { 0x0000ffb8, 18848 }, /* KP_8 */
+ { 0x0000ffb9, 18853 }, /* KP_9 */
+ { 0x0000ffab, 18858 }, /* KP_Add */
+ { 0x1000ff75, 18865 }, /* KP_BackTab */
+ { 0x0000ff9d, 18876 }, /* KP_Begin */
+ { 0x0000ffae, 18885 }, /* KP_Decimal */
+ { 0x0000ff9f, 18896 }, /* KP_Delete */
+ { 0x0000ffaf, 18906 }, /* KP_Divide */
+ { 0x0000ff99, 18916 }, /* KP_Down */
+ { 0x0000ff9c, 18924 }, /* KP_End */
+ { 0x0000ff8d, 18931 }, /* KP_Enter */
+ { 0x0000ffbd, 18940 }, /* KP_Equal */
+ { 0x0000ff91, 18949 }, /* KP_F1 */
+ { 0x0000ff92, 18955 }, /* KP_F2 */
+ { 0x0000ff93, 18961 }, /* KP_F3 */
+ { 0x0000ff94, 18967 }, /* KP_F4 */
+ { 0x0000ff95, 18973 }, /* KP_Home */
+ { 0x0000ff9e, 18981 }, /* KP_Insert */
+ { 0x0000ff96, 18991 }, /* KP_Left */
+ { 0x0000ffaa, 18999 }, /* KP_Multiply */
+ { 0x0000ff9b, 19011 }, /* KP_Next */
+ { 0x0000ff9b, 19019 }, /* KP_Page_Down */
+ { 0x0000ff9a, 19032 }, /* KP_Page_Up */
+ { 0x0000ff9a, 19043 }, /* KP_Prior */
+ { 0x0000ff98, 19052 }, /* KP_Right */
+ { 0x0000ffac, 19061 }, /* KP_Separator */
+ { 0x0000ff80, 19074 }, /* KP_Space */
+ { 0x0000ffad, 19083 }, /* KP_Subtract */
+ { 0x0000ff89, 19095 }, /* KP_Tab */
+ { 0x0000ff97, 19102 }, /* KP_Up */
+ { 0x000003a2, 19108 }, /* kra */
+ { 0x0000004c, 19112 }, /* L */
+ { 0x0000006c, 19114 }, /* l */
+ { 0x0000ffc8, 19116 }, /* L1 */
+ { 0x0000ffd1, 19119 }, /* L10 */
+ { 0x0000ffc9, 19123 }, /* L2 */
+ { 0x0000ffca, 19126 }, /* L3 */
+ { 0x0000ffcb, 19129 }, /* L4 */
+ { 0x0000ffcc, 19132 }, /* L5 */
+ { 0x0000ffcd, 19135 }, /* L6 */
+ { 0x0000ffce, 19138 }, /* L7 */
+ { 0x0000ffcf, 19141 }, /* L8 */
+ { 0x0000ffd0, 19144 }, /* L9 */
+ { 0x000001c5, 19147 }, /* Lacute */
+ { 0x000001e5, 19154 }, /* lacute */
+ { 0x0000fed4, 19161 }, /* Last_Virtual_Screen */
+ { 0x00000ad9, 19181 }, /* latincross */
+ { 0x01001e36, 19192 }, /* Lbelowdot */
+ { 0x01001e37, 19202 }, /* lbelowdot */
+ { 0x000001a5, 19212 }, /* Lcaron */
+ { 0x000001b5, 19219 }, /* lcaron */
+ { 0x000003a6, 19226 }, /* Lcedilla */
+ { 0x000003b6, 19235 }, /* lcedilla */
+ { 0x0000ff51, 19244 }, /* Left */
+ { 0x00000abc, 19249 }, /* leftanglebracket */
+ { 0x000008fb, 19266 }, /* leftarrow */
+ { 0x00000ba3, 19276 }, /* leftcaret */
+ { 0x00000ad2, 19286 }, /* leftdoublequotemark */
+ { 0x000008af, 19306 }, /* leftmiddlecurlybrace */
+ { 0x00000acc, 19327 }, /* leftopentriangle */
+ { 0x00000aea, 19344 }, /* leftpointer */
+ { 0x000008a1, 19356 }, /* leftradical */
+ { 0x00000bda, 19368 }, /* leftshoe */
+ { 0x00000ad0, 19377 }, /* leftsinglequotemark */
+ { 0x000009f4, 19397 }, /* leftt */
+ { 0x00000bdc, 19403 }, /* lefttack */
+ { 0x0000003c, 19412 }, /* less */
+ { 0x000008bc, 19417 }, /* lessthanequal */
+ { 0x000009e5, 19431 }, /* lf */
+ { 0x0000ff0a, 19434 }, /* Linefeed */
+ { 0x100000af, 19443 }, /* lira */
+ { 0x010020a4, 19448 }, /* LiraSign */
+ { 0x000008de, 19457 }, /* logicaland */
+ { 0x000008df, 19468 }, /* logicalor */
+ { 0x100000f6, 19478 }, /* longminus */
+ { 0x000009ed, 19488 }, /* lowleftcorner */
+ { 0x000009ea, 19502 }, /* lowrightcorner */
+ { 0x000001a3, 19517 }, /* Lstroke */
+ { 0x000001b3, 19525 }, /* lstroke */
+ { 0x0000004d, 19533 }, /* M */
+ { 0x0000006d, 19535 }, /* m */
+ { 0x01001e40, 19537 }, /* Mabovedot */
+ { 0x01001e41, 19547 }, /* mabovedot */
+ { 0x000006a5, 19557 }, /* Macedonia_dse */
+ { 0x000006b5, 19571 }, /* Macedonia_DSE */
+ { 0x000006a2, 19585 }, /* Macedonia_gje */
+ { 0x000006b2, 19599 }, /* Macedonia_GJE */
+ { 0x000006ac, 19613 }, /* Macedonia_kje */
+ { 0x000006bc, 19627 }, /* Macedonia_KJE */
+ { 0x000000af, 19641 }, /* macron */
+ { 0x0000ff3e, 19648 }, /* Mae_Koho */
+ { 0x00000af7, 19657 }, /* malesymbol */
+ { 0x00000af0, 19668 }, /* maltesecross */
+ { 0x00000abf, 19681 }, /* marker */
+ { 0x000000ba, 19688 }, /* masculine */
+ { 0x0000ff2c, 19698 }, /* Massyo */
+ { 0x0000ff67, 19705 }, /* Menu */
+ { 0x0000ffe7, 19710 }, /* Meta_L */
+ { 0x0000ffe8, 19717 }, /* Meta_R */
+ { 0x010020a5, 19724 }, /* MillSign */
+ { 0x0000002d, 19733 }, /* minus */
+ { 0x00000ad6, 19739 }, /* minutes */
+ { 0x0000ff7e, 19747 }, /* Mode_switch */
+ { 0x0000fe77, 19759 }, /* MouseKeys_Accel_Enable */
+ { 0x0000fe76, 19782 }, /* MouseKeys_Enable */
+ { 0x000000b5, 19799 }, /* mu */
+ { 0x0000ff22, 19802 }, /* Muhenkan */
+ { 0x0000ff20, 19811 }, /* Multi_key */
+ { 0x0000ff3d, 19821 }, /* MultipleCandidate */
+ { 0x000000d7, 19839 }, /* multiply */
+ { 0x00000af6, 19848 }, /* musicalflat */
+ { 0x00000af5, 19860 }, /* musicalsharp */
+ { 0x100000a8, 19873 }, /* mute_acute */
+ { 0x100000aa, 19884 }, /* mute_asciicircum */
+ { 0x100000ac, 19901 }, /* mute_asciitilde */
+ { 0x100000ab, 19917 }, /* mute_diaeresis */
+ { 0x100000a9, 19932 }, /* mute_grave */
+ { 0x0000004e, 19943 }, /* N */
+ { 0x0000006e, 19945 }, /* n */
+ { 0x000008c5, 19947 }, /* nabla */
+ { 0x000001d1, 19953 }, /* Nacute */
+ { 0x000001f1, 19960 }, /* nacute */
+ { 0x010020a6, 19967 }, /* NairaSign */
+ { 0x000001d2, 19977 }, /* Ncaron */
+ { 0x000001f2, 19984 }, /* ncaron */
+ { 0x000003d1, 19991 }, /* Ncedilla */
+ { 0x000003f1, 20000 }, /* ncedilla */
+ { 0x010020aa, 20009 }, /* NewSheqelSign */
+ { 0x0000ff56, 20023 }, /* Next */
+ { 0x0000fed2, 20028 }, /* Next_Virtual_Screen */
+ { 0x01002089, 20048 }, /* ninesubscript */
+ { 0x01002079, 20062 }, /* ninesuperior */
+ { 0x000009e8, 20075 }, /* nl */
+ { 0x000000a0, 20078 }, /* nobreakspace */
+ { 0x00000000, 20091 }, /* NoSymbol */
+ { 0x01002247, 20100 }, /* notapproxeq */
+ { 0x01002209, 20112 }, /* notelementof */
+ { 0x000008bd, 20125 }, /* notequal */
+ { 0x01002262, 20134 }, /* notidentical */
+ { 0x000000ac, 20147 }, /* notsign */
+ { 0x000000d1, 20155 }, /* Ntilde */
+ { 0x000000f1, 20162 }, /* ntilde */
+ { 0x0000ff7f, 20169 }, /* Num_Lock */
+ { 0x00000023, 20178 }, /* numbersign */
+ { 0x000006b0, 20189 }, /* numerosign */
+ { 0x0000004f, 20200 }, /* O */
+ { 0x0000006f, 20202 }, /* o */
+ { 0x000000d3, 20204 }, /* Oacute */
+ { 0x000000f3, 20211 }, /* oacute */
+ { 0x0100019f, 20218 }, /* Obarred */
+ { 0x01000275, 20226 }, /* obarred */
+ { 0x01001ecc, 20234 }, /* Obelowdot */
+ { 0x01001ecd, 20244 }, /* obelowdot */
+ { 0x010001d1, 20254 }, /* Ocaron */
+ { 0x010001d2, 20261 }, /* ocaron */
+ { 0x000000d4, 20268 }, /* Ocircumflex */
+ { 0x000000f4, 20280 }, /* ocircumflex */
+ { 0x01001ed0, 20292 }, /* Ocircumflexacute */
+ { 0x01001ed1, 20309 }, /* ocircumflexacute */
+ { 0x01001ed8, 20326 }, /* Ocircumflexbelowdot */
+ { 0x01001ed9, 20346 }, /* ocircumflexbelowdot */
+ { 0x01001ed2, 20366 }, /* Ocircumflexgrave */
+ { 0x01001ed3, 20383 }, /* ocircumflexgrave */
+ { 0x01001ed4, 20400 }, /* Ocircumflexhook */
+ { 0x01001ed5, 20416 }, /* ocircumflexhook */
+ { 0x01001ed6, 20432 }, /* Ocircumflextilde */
+ { 0x01001ed7, 20449 }, /* ocircumflextilde */
+ { 0x000000d6, 20466 }, /* Odiaeresis */
+ { 0x000000f6, 20477 }, /* odiaeresis */
+ { 0x000001d5, 20488 }, /* Odoubleacute */
+ { 0x000001f5, 20501 }, /* odoubleacute */
+ { 0x000013bc, 20514 }, /* OE */
+ { 0x000013bd, 20517 }, /* oe */
+ { 0x000001b2, 20520 }, /* ogonek */
+ { 0x000000d2, 20527 }, /* Ograve */
+ { 0x000000f2, 20534 }, /* ograve */
+ { 0x01001ece, 20541 }, /* Ohook */
+ { 0x01001ecf, 20547 }, /* ohook */
+ { 0x010001a0, 20553 }, /* Ohorn */
+ { 0x010001a1, 20559 }, /* ohorn */
+ { 0x01001eda, 20565 }, /* Ohornacute */
+ { 0x01001edb, 20576 }, /* ohornacute */
+ { 0x01001ee2, 20587 }, /* Ohornbelowdot */
+ { 0x01001ee3, 20601 }, /* ohornbelowdot */
+ { 0x01001edc, 20615 }, /* Ohorngrave */
+ { 0x01001edd, 20626 }, /* ohorngrave */
+ { 0x01001ede, 20637 }, /* Ohornhook */
+ { 0x01001edf, 20647 }, /* ohornhook */
+ { 0x01001ee0, 20657 }, /* Ohorntilde */
+ { 0x01001ee1, 20668 }, /* ohorntilde */
+ { 0x000003d2, 20679 }, /* Omacron */
+ { 0x000003f2, 20687 }, /* omacron */
+ { 0x00000ac3, 20695 }, /* oneeighth */
+ { 0x00000ab2, 20705 }, /* onefifth */
+ { 0x000000bd, 20714 }, /* onehalf */
+ { 0x000000bc, 20722 }, /* onequarter */
+ { 0x00000ab6, 20733 }, /* onesixth */
+ { 0x01002081, 20742 }, /* onesubscript */
+ { 0x000000b9, 20755 }, /* onesuperior */
+ { 0x00000ab0, 20767 }, /* onethird */
+ { 0x000000d8, 20776 }, /* Ooblique */
+ { 0x000000f8, 20785 }, /* ooblique */
+ { 0x00000ae2, 20794 }, /* openrectbullet */
+ { 0x00000ae5, 20809 }, /* openstar */
+ { 0x00000ae4, 20818 }, /* opentribulletdown */
+ { 0x00000ae3, 20836 }, /* opentribulletup */
+ { 0x000000aa, 20852 }, /* ordfeminine */
+ { 0x1004ff44, 20864 }, /* osfActivate */
+ { 0x1004ff31, 20876 }, /* osfAddMode */
+ { 0x1004ff08, 20887 }, /* osfBackSpace */
+ { 0x1004ff07, 20900 }, /* osfBackTab */
+ { 0x1004ff5a, 20911 }, /* osfBeginData */
+ { 0x1004ff58, 20924 }, /* osfBeginLine */
+ { 0x1004ff69, 20937 }, /* osfCancel */
+ { 0x1004ff0b, 20947 }, /* osfClear */
+ { 0x1004ff02, 20956 }, /* osfCopy */
+ { 0x1004ff03, 20964 }, /* osfCut */
+ { 0x1004ffff, 20971 }, /* osfDelete */
+ { 0x1004ff72, 20981 }, /* osfDeselectAll */
+ { 0x1004ff54, 20996 }, /* osfDown */
+ { 0x1004ff59, 21004 }, /* osfEndData */
+ { 0x1004ff57, 21015 }, /* osfEndLine */
+ { 0x1004ff1b, 21026 }, /* osfEscape */
+ { 0x1004ff74, 21036 }, /* osfExtend */
+ { 0x1004ff6a, 21046 }, /* osfHelp */
+ { 0x1004ff63, 21054 }, /* osfInsert */
+ { 0x1004ff51, 21064 }, /* osfLeft */
+ { 0x1004ff67, 21072 }, /* osfMenu */
+ { 0x1004ff45, 21080 }, /* osfMenuBar */
+ { 0x1004ff5e, 21091 }, /* osfNextField */
+ { 0x1004ff5c, 21104 }, /* osfNextMenu */
+ { 0x1004ff42, 21116 }, /* osfPageDown */
+ { 0x1004ff40, 21128 }, /* osfPageLeft */
+ { 0x1004ff43, 21140 }, /* osfPageRight */
+ { 0x1004ff41, 21153 }, /* osfPageUp */
+ { 0x1004ff04, 21163 }, /* osfPaste */
+ { 0x1004ff5d, 21172 }, /* osfPrevField */
+ { 0x1004ff5b, 21185 }, /* osfPrevMenu */
+ { 0x1004ff32, 21197 }, /* osfPrimaryPaste */
+ { 0x1004ff33, 21213 }, /* osfQuickPaste */
+ { 0x1004ff73, 21227 }, /* osfReselect */
+ { 0x1004ff78, 21239 }, /* osfRestore */
+ { 0x1004ff53, 21250 }, /* osfRight */
+ { 0x1004ff60, 21259 }, /* osfSelect */
+ { 0x1004ff71, 21269 }, /* osfSelectAll */
+ { 0x1004ff65, 21282 }, /* osfUndo */
+ { 0x1004ff52, 21290 }, /* osfUp */
+ { 0x000000d8, 21296 }, /* Oslash */
+ { 0x000000f8, 21303 }, /* oslash */
+ { 0x000000d5, 21310 }, /* Otilde */
+ { 0x000000f5, 21317 }, /* otilde */
+ { 0x00000bc0, 21324 }, /* overbar */
+ { 0x0000fe78, 21332 }, /* Overlay1_Enable */
+ { 0x0000fe79, 21348 }, /* Overlay2_Enable */
+ { 0x0000047e, 21364 }, /* overline */
+ { 0x00000050, 21373 }, /* P */
+ { 0x00000070, 21375 }, /* p */
+ { 0x01001e56, 21377 }, /* Pabovedot */
+ { 0x01001e57, 21387 }, /* pabovedot */
+ { 0x0000ff56, 21397 }, /* Page_Down */
+ { 0x0000ff55, 21407 }, /* Page_Up */
+ { 0x000000b6, 21415 }, /* paragraph */
+ { 0x00000028, 21425 }, /* parenleft */
+ { 0x00000029, 21435 }, /* parenright */
+ { 0x01002202, 21446 }, /* partdifferential */
+ { 0x000008ef, 21463 }, /* partialderivative */
+ { 0x0000ff13, 21481 }, /* Pause */
+ { 0x00000025, 21487 }, /* percent */
+ { 0x0000002e, 21495 }, /* period */
+ { 0x000000b7, 21502 }, /* periodcentered */
+ { 0x00000ad5, 21517 }, /* permille */
+ { 0x010020a7, 21526 }, /* PesetaSign */
+ { 0x00000afb, 21537 }, /* phonographcopyright */
+ { 0x0000002b, 21557 }, /* plus */
+ { 0x000000b1, 21562 }, /* plusminus */
+ { 0x0000fefa, 21572 }, /* Pointer_Accelerate */
+ { 0x0000fee9, 21591 }, /* Pointer_Button1 */
+ { 0x0000feea, 21607 }, /* Pointer_Button2 */
+ { 0x0000feeb, 21623 }, /* Pointer_Button3 */
+ { 0x0000feec, 21639 }, /* Pointer_Button4 */
+ { 0x0000feed, 21655 }, /* Pointer_Button5 */
+ { 0x0000fee8, 21671 }, /* Pointer_Button_Dflt */
+ { 0x0000feef, 21691 }, /* Pointer_DblClick1 */
+ { 0x0000fef0, 21709 }, /* Pointer_DblClick2 */
+ { 0x0000fef1, 21727 }, /* Pointer_DblClick3 */
+ { 0x0000fef2, 21745 }, /* Pointer_DblClick4 */
+ { 0x0000fef3, 21763 }, /* Pointer_DblClick5 */
+ { 0x0000feee, 21781 }, /* Pointer_DblClick_Dflt */
+ { 0x0000fefb, 21803 }, /* Pointer_DfltBtnNext */
+ { 0x0000fefc, 21823 }, /* Pointer_DfltBtnPrev */
+ { 0x0000fee3, 21843 }, /* Pointer_Down */
+ { 0x0000fee6, 21856 }, /* Pointer_DownLeft */
+ { 0x0000fee7, 21873 }, /* Pointer_DownRight */
+ { 0x0000fef5, 21891 }, /* Pointer_Drag1 */
+ { 0x0000fef6, 21905 }, /* Pointer_Drag2 */
+ { 0x0000fef7, 21919 }, /* Pointer_Drag3 */
+ { 0x0000fef8, 21933 }, /* Pointer_Drag4 */
+ { 0x0000fefd, 21947 }, /* Pointer_Drag5 */
+ { 0x0000fef4, 21961 }, /* Pointer_Drag_Dflt */
+ { 0x0000fef9, 21979 }, /* Pointer_EnableKeys */
+ { 0x0000fee0, 21998 }, /* Pointer_Left */
+ { 0x0000fee1, 22011 }, /* Pointer_Right */
+ { 0x0000fee2, 22025 }, /* Pointer_Up */
+ { 0x0000fee4, 22036 }, /* Pointer_UpLeft */
+ { 0x0000fee5, 22051 }, /* Pointer_UpRight */
+ { 0x00000ad4, 22067 }, /* prescription */
+ { 0x0000fed1, 22080 }, /* Prev_Virtual_Screen */
+ { 0x0000ff3e, 22100 }, /* PreviousCandidate */
+ { 0x0000ff61, 22118 }, /* Print */
+ { 0x0000ff55, 22124 }, /* Prior */
+ { 0x000004b0, 22130 }, /* prolongedsound */
+ { 0x00000aa6, 22145 }, /* punctspace */
+ { 0x00000051, 22156 }, /* Q */
+ { 0x00000071, 22158 }, /* q */
+ { 0x00000bcc, 22160 }, /* quad */
+ { 0x0000003f, 22165 }, /* question */
+ { 0x000000bf, 22174 }, /* questiondown */
+ { 0x00000022, 22187 }, /* quotedbl */
+ { 0x00000060, 22196 }, /* quoteleft */
+ { 0x00000027, 22206 }, /* quoteright */
+ { 0x00000052, 22217 }, /* R */
+ { 0x00000072, 22219 }, /* r */
+ { 0x0000ffd2, 22221 }, /* R1 */
+ { 0x0000ffdb, 22224 }, /* R10 */
+ { 0x0000ffdc, 22228 }, /* R11 */
+ { 0x0000ffdd, 22232 }, /* R12 */
+ { 0x0000ffde, 22236 }, /* R13 */
+ { 0x0000ffdf, 22240 }, /* R14 */
+ { 0x0000ffe0, 22244 }, /* R15 */
+ { 0x0000ffd3, 22248 }, /* R2 */
+ { 0x0000ffd4, 22251 }, /* R3 */
+ { 0x0000ffd5, 22254 }, /* R4 */
+ { 0x0000ffd6, 22257 }, /* R5 */
+ { 0x0000ffd7, 22260 }, /* R6 */
+ { 0x0000ffd8, 22263 }, /* R7 */
+ { 0x0000ffd9, 22266 }, /* R8 */
+ { 0x0000ffda, 22269 }, /* R9 */
+ { 0x000001c0, 22272 }, /* Racute */
+ { 0x000001e0, 22279 }, /* racute */
+ { 0x000008d6, 22286 }, /* radical */
+ { 0x000001d8, 22294 }, /* Rcaron */
+ { 0x000001f8, 22301 }, /* rcaron */
+ { 0x000003a3, 22308 }, /* Rcedilla */
+ { 0x000003b3, 22317 }, /* rcedilla */
+ { 0x0000ff66, 22326 }, /* Redo */
+ { 0x000000ae, 22331 }, /* registered */
+ { 0x0000fe72, 22342 }, /* RepeatKeys_Enable */
+ { 0x1000ff6c, 22360 }, /* Reset */
+ { 0x0000ff0d, 22366 }, /* Return */
+ { 0x0000ff53, 22373 }, /* Right */
+ { 0x00000abe, 22379 }, /* rightanglebracket */
+ { 0x000008fd, 22397 }, /* rightarrow */
+ { 0x00000ba6, 22408 }, /* rightcaret */
+ { 0x00000ad3, 22419 }, /* rightdoublequotemark */
+ { 0x000008b0, 22440 }, /* rightmiddlecurlybrace */
+ { 0x000008b7, 22462 }, /* rightmiddlesummation */
+ { 0x00000acd, 22483 }, /* rightopentriangle */
+ { 0x00000aeb, 22501 }, /* rightpointer */
+ { 0x00000bd8, 22514 }, /* rightshoe */
+ { 0x00000ad1, 22524 }, /* rightsinglequotemark */
+ { 0x000009f5, 22545 }, /* rightt */
+ { 0x00000bfc, 22552 }, /* righttack */
+ { 0x0000ff24, 22562 }, /* Romaji */
+ { 0x010020a8, 22569 }, /* RupeeSign */
+ { 0x00000053, 22579 }, /* S */
+ { 0x00000073, 22581 }, /* s */
+ { 0x01001e60, 22583 }, /* Sabovedot */
+ { 0x01001e61, 22593 }, /* sabovedot */
+ { 0x000001a6, 22603 }, /* Sacute */
+ { 0x000001b6, 22610 }, /* sacute */
+ { 0x000001a9, 22617 }, /* Scaron */
+ { 0x000001b9, 22624 }, /* scaron */
+ { 0x000001aa, 22631 }, /* Scedilla */
+ { 0x000001ba, 22640 }, /* scedilla */
+ { 0x0100018f, 22649 }, /* SCHWA */
+ { 0x01000259, 22655 }, /* schwa */
+ { 0x000002de, 22661 }, /* Scircumflex */
+ { 0x000002fe, 22673 }, /* scircumflex */
+ { 0x0000ff7e, 22685 }, /* script_switch */
+ { 0x0000ff14, 22699 }, /* Scroll_Lock */
+ { 0x00000ad7, 22711 }, /* seconds */
+ { 0x000000a7, 22719 }, /* section */
+ { 0x0000ff60, 22727 }, /* Select */
+ { 0x0000003b, 22734 }, /* semicolon */
+ { 0x000004df, 22744 }, /* semivoicedsound */
+ { 0x000006a1, 22760 }, /* Serbian_dje */
+ { 0x000006b1, 22772 }, /* Serbian_DJE */
+ { 0x000006af, 22784 }, /* Serbian_dze */
+ { 0x000006bf, 22796 }, /* Serbian_DZE */
+ { 0x000006a8, 22808 }, /* Serbian_je */
+ { 0x000006b8, 22819 }, /* Serbian_JE */
+ { 0x000006a9, 22830 }, /* Serbian_lje */
+ { 0x000006b9, 22842 }, /* Serbian_LJE */
+ { 0x000006aa, 22854 }, /* Serbian_nje */
+ { 0x000006ba, 22866 }, /* Serbian_NJE */
+ { 0x000006ab, 22878 }, /* Serbian_tshe */
+ { 0x000006bb, 22891 }, /* Serbian_TSHE */
+ { 0x00000ac6, 22904 }, /* seveneighths */
+ { 0x01002087, 22917 }, /* sevensubscript */
+ { 0x01002077, 22932 }, /* sevensuperior */
+ { 0x0000ffe1, 22946 }, /* Shift_L */
+ { 0x0000ffe6, 22954 }, /* Shift_Lock */
+ { 0x0000ffe2, 22965 }, /* Shift_R */
+ { 0x00000aca, 22973 }, /* signaturemark */
+ { 0x00000aac, 22987 }, /* signifblank */
+ { 0x000008c9, 22999 }, /* similarequal */
+ { 0x0000ff3c, 23012 }, /* SingleCandidate */
+ { 0x00000afd, 23028 }, /* singlelowquotemark */
+ { 0x01000d85, 23047 }, /* Sinh_a */
+ { 0x01000d86, 23054 }, /* Sinh_aa */
+ { 0x01000dcf, 23062 }, /* Sinh_aa2 */
+ { 0x01000d87, 23071 }, /* Sinh_ae */
+ { 0x01000dd0, 23079 }, /* Sinh_ae2 */
+ { 0x01000d88, 23088 }, /* Sinh_aee */
+ { 0x01000dd1, 23097 }, /* Sinh_aee2 */
+ { 0x01000d93, 23107 }, /* Sinh_ai */
+ { 0x01000ddb, 23115 }, /* Sinh_ai2 */
+ { 0x01000dca, 23124 }, /* Sinh_al */
+ { 0x01000d96, 23132 }, /* Sinh_au */
+ { 0x01000dde, 23140 }, /* Sinh_au2 */
+ { 0x01000db6, 23149 }, /* Sinh_ba */
+ { 0x01000db7, 23157 }, /* Sinh_bha */
+ { 0x01000da0, 23166 }, /* Sinh_ca */
+ { 0x01000da1, 23174 }, /* Sinh_cha */
+ { 0x01000da9, 23183 }, /* Sinh_dda */
+ { 0x01000daa, 23192 }, /* Sinh_ddha */
+ { 0x01000daf, 23202 }, /* Sinh_dha */
+ { 0x01000db0, 23211 }, /* Sinh_dhha */
+ { 0x01000d91, 23221 }, /* Sinh_e */
+ { 0x01000dd9, 23228 }, /* Sinh_e2 */
+ { 0x01000d92, 23236 }, /* Sinh_ee */
+ { 0x01000dda, 23244 }, /* Sinh_ee2 */
+ { 0x01000dc6, 23253 }, /* Sinh_fa */
+ { 0x01000d9c, 23261 }, /* Sinh_ga */
+ { 0x01000d9d, 23269 }, /* Sinh_gha */
+ { 0x01000d83, 23278 }, /* Sinh_h2 */
+ { 0x01000dc4, 23286 }, /* Sinh_ha */
+ { 0x01000d89, 23294 }, /* Sinh_i */
+ { 0x01000dd2, 23301 }, /* Sinh_i2 */
+ { 0x01000d8a, 23309 }, /* Sinh_ii */
+ { 0x01000dd3, 23317 }, /* Sinh_ii2 */
+ { 0x01000da2, 23326 }, /* Sinh_ja */
+ { 0x01000da3, 23334 }, /* Sinh_jha */
+ { 0x01000da5, 23343 }, /* Sinh_jnya */
+ { 0x01000d9a, 23353 }, /* Sinh_ka */
+ { 0x01000d9b, 23361 }, /* Sinh_kha */
+ { 0x01000df4, 23370 }, /* Sinh_kunddaliya */
+ { 0x01000dbd, 23386 }, /* Sinh_la */
+ { 0x01000dc5, 23394 }, /* Sinh_lla */
+ { 0x01000d8f, 23403 }, /* Sinh_lu */
+ { 0x01000ddf, 23411 }, /* Sinh_lu2 */
+ { 0x01000d90, 23420 }, /* Sinh_luu */
+ { 0x01000df3, 23429 }, /* Sinh_luu2 */
+ { 0x01000db8, 23439 }, /* Sinh_ma */
+ { 0x01000db9, 23447 }, /* Sinh_mba */
+ { 0x01000db1, 23456 }, /* Sinh_na */
+ { 0x01000dac, 23464 }, /* Sinh_ndda */
+ { 0x01000db3, 23474 }, /* Sinh_ndha */
+ { 0x01000d82, 23484 }, /* Sinh_ng */
+ { 0x01000d9e, 23492 }, /* Sinh_ng2 */
+ { 0x01000d9f, 23501 }, /* Sinh_nga */
+ { 0x01000da6, 23510 }, /* Sinh_nja */
+ { 0x01000dab, 23519 }, /* Sinh_nna */
+ { 0x01000da4, 23528 }, /* Sinh_nya */
+ { 0x01000d94, 23537 }, /* Sinh_o */
+ { 0x01000ddc, 23544 }, /* Sinh_o2 */
+ { 0x01000d95, 23552 }, /* Sinh_oo */
+ { 0x01000ddd, 23560 }, /* Sinh_oo2 */
+ { 0x01000db4, 23569 }, /* Sinh_pa */
+ { 0x01000db5, 23577 }, /* Sinh_pha */
+ { 0x01000dbb, 23586 }, /* Sinh_ra */
+ { 0x01000d8d, 23594 }, /* Sinh_ri */
+ { 0x01000d8e, 23602 }, /* Sinh_rii */
+ { 0x01000dd8, 23611 }, /* Sinh_ru2 */
+ { 0x01000df2, 23620 }, /* Sinh_ruu2 */
+ { 0x01000dc3, 23630 }, /* Sinh_sa */
+ { 0x01000dc1, 23638 }, /* Sinh_sha */
+ { 0x01000dc2, 23647 }, /* Sinh_ssha */
+ { 0x01000dad, 23657 }, /* Sinh_tha */
+ { 0x01000dae, 23666 }, /* Sinh_thha */
+ { 0x01000da7, 23676 }, /* Sinh_tta */
+ { 0x01000da8, 23685 }, /* Sinh_ttha */
+ { 0x01000d8b, 23695 }, /* Sinh_u */
+ { 0x01000dd4, 23702 }, /* Sinh_u2 */
+ { 0x01000d8c, 23710 }, /* Sinh_uu */
+ { 0x01000dd6, 23718 }, /* Sinh_uu2 */
+ { 0x01000dc0, 23727 }, /* Sinh_va */
+ { 0x01000dba, 23735 }, /* Sinh_ya */
+ { 0x01002086, 23743 }, /* sixsubscript */
+ { 0x01002076, 23756 }, /* sixsuperior */
+ { 0x0000002f, 23768 }, /* slash */
+ { 0x0000fe73, 23774 }, /* SlowKeys_Enable */
+ { 0x000009e0, 23790 }, /* soliddiamond */
+ { 0x00000020, 23803 }, /* space */
+ { 0x0100221a, 23809 }, /* squareroot */
+ { 0x000000df, 23820 }, /* ssharp */
+ { 0x000000a3, 23827 }, /* sterling */
+ { 0x0000fe75, 23836 }, /* StickyKeys_Enable */
+ { 0x01002263, 23854 }, /* stricteq */
+ { 0x0000ff66, 23863 }, /* SunAgain */
+ { 0x0000ff7e, 23872 }, /* SunAltGraph */
+ { 0x1005ff77, 23884 }, /* SunAudioLowerVolume */
+ { 0x1005ff78, 23904 }, /* SunAudioMute */
+ { 0x1005ff79, 23917 }, /* SunAudioRaiseVolume */
+ { 0x0000ff20, 23937 }, /* SunCompose */
+ { 0x1005ff72, 23948 }, /* SunCopy */
+ { 0x1005ff75, 23956 }, /* SunCut */
+ { 0x1005ff10, 23963 }, /* SunF36 */
+ { 0x1005ff11, 23970 }, /* SunF37 */
+ { 0x1005ff03, 23977 }, /* SunFA_Acute */
+ { 0x1005ff05, 23989 }, /* SunFA_Cedilla */
+ { 0x1005ff01, 24003 }, /* SunFA_Circum */
+ { 0x1005ff04, 24016 }, /* SunFA_Diaeresis */
+ { 0x1005ff00, 24032 }, /* SunFA_Grave */
+ { 0x1005ff02, 24044 }, /* SunFA_Tilde */
+ { 0x0000ff68, 24056 }, /* SunFind */
+ { 0x1005ff71, 24064 }, /* SunFront */
+ { 0x1005ff73, 24073 }, /* SunOpen */
+ { 0x0000ff56, 24081 }, /* SunPageDown */
+ { 0x0000ff55, 24093 }, /* SunPageUp */
+ { 0x1005ff74, 24103 }, /* SunPaste */
+ { 0x1005ff76, 24112 }, /* SunPowerSwitch */
+ { 0x1005ff7d, 24127 }, /* SunPowerSwitchShift */
+ { 0x0000ff61, 24147 }, /* SunPrint_Screen */
+ { 0x1005ff70, 24163 }, /* SunProps */
+ { 0x0000ff69, 24172 }, /* SunStop */
+ { 0x1005ff60, 24180 }, /* SunSys_Req */
+ { 0x0000ff65, 24191 }, /* SunUndo */
+ { 0x1005ff7a, 24199 }, /* SunVideoDegauss */
+ { 0x1005ff7b, 24215 }, /* SunVideoLowerBrightness */
+ { 0x1005ff7c, 24239 }, /* SunVideoRaiseBrightness */
+ { 0x0000ffeb, 24263 }, /* Super_L */
+ { 0x0000ffec, 24271 }, /* Super_R */
+ { 0x0000ff15, 24279 }, /* Sys_Req */
+ { 0x1000ff6d, 24287 }, /* System */
+ { 0x00000054, 24294 }, /* T */
+ { 0x00000074, 24296 }, /* t */
+ { 0x0000ff09, 24298 }, /* Tab */
+ { 0x01001e6a, 24302 }, /* Tabovedot */
+ { 0x01001e6b, 24312 }, /* tabovedot */
+ { 0x000001ab, 24322 }, /* Tcaron */
+ { 0x000001bb, 24329 }, /* tcaron */
+ { 0x000001de, 24336 }, /* Tcedilla */
+ { 0x000001fe, 24345 }, /* tcedilla */
+ { 0x00000af9, 24354 }, /* telephone */
+ { 0x00000afa, 24364 }, /* telephonerecorder */
+ { 0x0000fed5, 24382 }, /* Terminate_Server */
+ { 0x00000ddf, 24399 }, /* Thai_baht */
+ { 0x00000dba, 24409 }, /* Thai_bobaimai */
+ { 0x00000da8, 24423 }, /* Thai_chochan */
+ { 0x00000daa, 24436 }, /* Thai_chochang */
+ { 0x00000da9, 24450 }, /* Thai_choching */
+ { 0x00000dac, 24464 }, /* Thai_chochoe */
+ { 0x00000dae, 24477 }, /* Thai_dochada */
+ { 0x00000db4, 24490 }, /* Thai_dodek */
+ { 0x00000dbd, 24501 }, /* Thai_fofa */
+ { 0x00000dbf, 24511 }, /* Thai_fofan */
+ { 0x00000dcb, 24522 }, /* Thai_hohip */
+ { 0x00000dce, 24533 }, /* Thai_honokhuk */
+ { 0x00000da2, 24547 }, /* Thai_khokhai */
+ { 0x00000da5, 24560 }, /* Thai_khokhon */
+ { 0x00000da3, 24573 }, /* Thai_khokhuat */
+ { 0x00000da4, 24587 }, /* Thai_khokhwai */
+ { 0x00000da6, 24601 }, /* Thai_khorakhang */
+ { 0x00000da1, 24617 }, /* Thai_kokai */
+ { 0x00000de5, 24628 }, /* Thai_lakkhangyao */
+ { 0x00000df7, 24645 }, /* Thai_lekchet */
+ { 0x00000df5, 24658 }, /* Thai_lekha */
+ { 0x00000df6, 24669 }, /* Thai_lekhok */
+ { 0x00000df9, 24681 }, /* Thai_lekkao */
+ { 0x00000df1, 24693 }, /* Thai_leknung */
+ { 0x00000df8, 24706 }, /* Thai_lekpaet */
+ { 0x00000df3, 24719 }, /* Thai_leksam */
+ { 0x00000df4, 24731 }, /* Thai_leksi */
+ { 0x00000df2, 24742 }, /* Thai_leksong */
+ { 0x00000df0, 24755 }, /* Thai_leksun */
+ { 0x00000dcc, 24767 }, /* Thai_lochula */
+ { 0x00000dc5, 24780 }, /* Thai_loling */
+ { 0x00000dc6, 24792 }, /* Thai_lu */
+ { 0x00000deb, 24800 }, /* Thai_maichattawa */
+ { 0x00000de8, 24817 }, /* Thai_maiek */
+ { 0x00000dd1, 24828 }, /* Thai_maihanakat */
+ { 0x00000dde, 24844 }, /* Thai_maihanakat_maitho */
+ { 0x00000de7, 24867 }, /* Thai_maitaikhu */
+ { 0x00000de9, 24882 }, /* Thai_maitho */
+ { 0x00000dea, 24894 }, /* Thai_maitri */
+ { 0x00000de6, 24906 }, /* Thai_maiyamok */
+ { 0x00000dc1, 24920 }, /* Thai_moma */
+ { 0x00000da7, 24930 }, /* Thai_ngongu */
+ { 0x00000ded, 24942 }, /* Thai_nikhahit */
+ { 0x00000db3, 24956 }, /* Thai_nonen */
+ { 0x00000db9, 24967 }, /* Thai_nonu */
+ { 0x00000dcd, 24977 }, /* Thai_oang */
+ { 0x00000dcf, 24987 }, /* Thai_paiyannoi */
+ { 0x00000dda, 25002 }, /* Thai_phinthu */
+ { 0x00000dbe, 25015 }, /* Thai_phophan */
+ { 0x00000dbc, 25028 }, /* Thai_phophung */
+ { 0x00000dc0, 25042 }, /* Thai_phosamphao */
+ { 0x00000dbb, 25058 }, /* Thai_popla */
+ { 0x00000dc3, 25069 }, /* Thai_rorua */
+ { 0x00000dc4, 25080 }, /* Thai_ru */
+ { 0x00000dd0, 25088 }, /* Thai_saraa */
+ { 0x00000dd2, 25099 }, /* Thai_saraaa */
+ { 0x00000de1, 25111 }, /* Thai_saraae */
+ { 0x00000de4, 25123 }, /* Thai_saraaimaimalai */
+ { 0x00000de3, 25143 }, /* Thai_saraaimaimuan */
+ { 0x00000dd3, 25162 }, /* Thai_saraam */
+ { 0x00000de0, 25174 }, /* Thai_sarae */
+ { 0x00000dd4, 25185 }, /* Thai_sarai */
+ { 0x00000dd5, 25196 }, /* Thai_saraii */
+ { 0x00000de2, 25208 }, /* Thai_sarao */
+ { 0x00000dd8, 25219 }, /* Thai_sarau */
+ { 0x00000dd6, 25230 }, /* Thai_saraue */
+ { 0x00000dd7, 25242 }, /* Thai_sarauee */
+ { 0x00000dd9, 25255 }, /* Thai_sarauu */
+ { 0x00000dc9, 25267 }, /* Thai_sorusi */
+ { 0x00000dc8, 25279 }, /* Thai_sosala */
+ { 0x00000dab, 25291 }, /* Thai_soso */
+ { 0x00000dca, 25301 }, /* Thai_sosua */
+ { 0x00000dec, 25312 }, /* Thai_thanthakhat */
+ { 0x00000db1, 25329 }, /* Thai_thonangmontho */
+ { 0x00000db2, 25348 }, /* Thai_thophuthao */
+ { 0x00000db7, 25364 }, /* Thai_thothahan */
+ { 0x00000db0, 25379 }, /* Thai_thothan */
+ { 0x00000db8, 25392 }, /* Thai_thothong */
+ { 0x00000db6, 25406 }, /* Thai_thothung */
+ { 0x00000daf, 25420 }, /* Thai_topatak */
+ { 0x00000db5, 25433 }, /* Thai_totao */
+ { 0x00000dc7, 25444 }, /* Thai_wowaen */
+ { 0x00000dc2, 25456 }, /* Thai_yoyak */
+ { 0x00000dad, 25467 }, /* Thai_yoying */
+ { 0x000008c0, 25479 }, /* therefore */
+ { 0x00000aa7, 25489 }, /* thinspace */
+ { 0x000000de, 25499 }, /* THORN */
+ { 0x000000de, 25505 }, /* Thorn */
+ { 0x000000fe, 25511 }, /* thorn */
+ { 0x00000ac4, 25517 }, /* threeeighths */
+ { 0x00000ab4, 25530 }, /* threefifths */
+ { 0x000000be, 25542 }, /* threequarters */
+ { 0x01002083, 25556 }, /* threesubscript */
+ { 0x000000b3, 25571 }, /* threesuperior */
+ { 0x0100222d, 25585 }, /* tintegral */
+ { 0x000008a4, 25595 }, /* topintegral */
+ { 0x000008ab, 25607 }, /* topleftparens */
+ { 0x000008a2, 25621 }, /* topleftradical */
+ { 0x000008a7, 25636 }, /* topleftsqbracket */
+ { 0x000008b1, 25653 }, /* topleftsummation */
+ { 0x000008ad, 25670 }, /* toprightparens */
+ { 0x000008a9, 25685 }, /* toprightsqbracket */
+ { 0x000008b5, 25703 }, /* toprightsummation */
+ { 0x000009f7, 25721 }, /* topt */
+ { 0x000008b3, 25726 }, /* topvertsummationconnector */
+ { 0x0000ff2b, 25752 }, /* Touroku */
+ { 0x00000ac9, 25760 }, /* trademark */
+ { 0x00000acb, 25770 }, /* trademarkincircle */
+ { 0x000003ac, 25788 }, /* Tslash */
+ { 0x000003bc, 25795 }, /* tslash */
+ { 0x00000ab3, 25802 }, /* twofifths */
+ { 0x01002082, 25812 }, /* twosubscript */
+ { 0x000000b2, 25825 }, /* twosuperior */
+ { 0x00000ab1, 25837 }, /* twothirds */
+ { 0x00000055, 25847 }, /* U */
+ { 0x00000075, 25849 }, /* u */
+ { 0x000000da, 25851 }, /* Uacute */
+ { 0x000000fa, 25858 }, /* uacute */
+ { 0x01001ee4, 25865 }, /* Ubelowdot */
+ { 0x01001ee5, 25875 }, /* ubelowdot */
+ { 0x000002dd, 25885 }, /* Ubreve */
+ { 0x000002fd, 25892 }, /* ubreve */
+ { 0x000000db, 25899 }, /* Ucircumflex */
+ { 0x000000fb, 25911 }, /* ucircumflex */
+ { 0x000000dc, 25923 }, /* Udiaeresis */
+ { 0x000000fc, 25934 }, /* udiaeresis */
+ { 0x000001db, 25945 }, /* Udoubleacute */
+ { 0x000001fb, 25958 }, /* udoubleacute */
+ { 0x000000d9, 25971 }, /* Ugrave */
+ { 0x000000f9, 25978 }, /* ugrave */
+ { 0x01001ee6, 25985 }, /* Uhook */
+ { 0x01001ee7, 25991 }, /* uhook */
+ { 0x010001af, 25997 }, /* Uhorn */
+ { 0x010001b0, 26003 }, /* uhorn */
+ { 0x01001ee8, 26009 }, /* Uhornacute */
+ { 0x01001ee9, 26020 }, /* uhornacute */
+ { 0x01001ef0, 26031 }, /* Uhornbelowdot */
+ { 0x01001ef1, 26045 }, /* uhornbelowdot */
+ { 0x01001eea, 26059 }, /* Uhorngrave */
+ { 0x01001eeb, 26070 }, /* uhorngrave */
+ { 0x01001eec, 26081 }, /* Uhornhook */
+ { 0x01001eed, 26091 }, /* uhornhook */
+ { 0x01001eee, 26101 }, /* Uhorntilde */
+ { 0x01001eef, 26112 }, /* uhorntilde */
+ { 0x000006ad, 26123 }, /* Ukrainian_ghe_with_upturn */
+ { 0x000006bd, 26149 }, /* Ukrainian_GHE_WITH_UPTURN */
+ { 0x000006a6, 26175 }, /* Ukrainian_i */
+ { 0x000006b6, 26187 }, /* Ukrainian_I */
+ { 0x000006a4, 26199 }, /* Ukrainian_ie */
+ { 0x000006b4, 26212 }, /* Ukrainian_IE */
+ { 0x000006a7, 26225 }, /* Ukrainian_yi */
+ { 0x000006b7, 26238 }, /* Ukrainian_YI */
+ { 0x000006a6, 26251 }, /* Ukranian_i */
+ { 0x000006b6, 26262 }, /* Ukranian_I */
+ { 0x000006a4, 26273 }, /* Ukranian_je */
+ { 0x000006b4, 26285 }, /* Ukranian_JE */
+ { 0x000006a7, 26297 }, /* Ukranian_yi */
+ { 0x000006b7, 26309 }, /* Ukranian_YI */
+ { 0x000003de, 26321 }, /* Umacron */
+ { 0x000003fe, 26329 }, /* umacron */
+ { 0x00000bc6, 26337 }, /* underbar */
+ { 0x0000005f, 26346 }, /* underscore */
+ { 0x0000ff65, 26357 }, /* Undo */
+ { 0x000008dd, 26362 }, /* union */
+ { 0x000003d9, 26368 }, /* Uogonek */
+ { 0x000003f9, 26376 }, /* uogonek */
+ { 0x0000ff52, 26384 }, /* Up */
+ { 0x000008fc, 26387 }, /* uparrow */
+ { 0x00000ba9, 26395 }, /* upcaret */
+ { 0x000009ec, 26403 }, /* upleftcorner */
+ { 0x000009eb, 26416 }, /* uprightcorner */
+ { 0x00000bc3, 26430 }, /* upshoe */
+ { 0x00000bd3, 26437 }, /* upstile */
+ { 0x00000bce, 26445 }, /* uptack */
+ { 0x000001d9, 26452 }, /* Uring */
+ { 0x000001f9, 26458 }, /* uring */
+ { 0x1000ff6e, 26464 }, /* User */
+ { 0x000003dd, 26469 }, /* Utilde */
+ { 0x000003fd, 26476 }, /* utilde */
+ { 0x00000056, 26483 }, /* V */
+ { 0x00000076, 26485 }, /* v */
+ { 0x000008c1, 26487 }, /* variation */
+ { 0x000009f8, 26497 }, /* vertbar */
+ { 0x000008a6, 26505 }, /* vertconnector */
+ { 0x000004de, 26519 }, /* voicedsound */
+ { 0x00ffffff, 26531 }, /* VoidSymbol */
+ { 0x000009e9, 26542 }, /* vt */
+ { 0x00000057, 26545 }, /* W */
+ { 0x00000077, 26547 }, /* w */
+ { 0x01001e82, 26549 }, /* Wacute */
+ { 0x01001e83, 26556 }, /* wacute */
+ { 0x01000174, 26563 }, /* Wcircumflex */
+ { 0x01000175, 26575 }, /* wcircumflex */
+ { 0x01001e84, 26587 }, /* Wdiaeresis */
+ { 0x01001e85, 26598 }, /* wdiaeresis */
+ { 0x01001e80, 26609 }, /* Wgrave */
+ { 0x01001e81, 26616 }, /* wgrave */
+ { 0x010020a9, 26623 }, /* WonSign */
+ { 0x00000058, 26631 }, /* X */
+ { 0x00000078, 26633 }, /* x */
+ { 0x01001e8a, 26635 }, /* Xabovedot */
+ { 0x01001e8b, 26645 }, /* xabovedot */
+ { 0x1008ff39, 26655 }, /* XF86AddFavorite */
+ { 0x1008ff50, 26671 }, /* XF86ApplicationLeft */
+ { 0x1008ff51, 26691 }, /* XF86ApplicationRight */
+ { 0x1008ff9b, 26712 }, /* XF86AudioCycleTrack */
+ { 0x1008ff97, 26732 }, /* XF86AudioForward */
+ { 0x1008ff11, 26749 }, /* XF86AudioLowerVolume */
+ { 0x1008ff32, 26770 }, /* XF86AudioMedia */
+ { 0x1008ffb2, 26785 }, /* XF86AudioMicMute */
+ { 0x1008ff12, 26802 }, /* XF86AudioMute */
+ { 0x1008ff17, 26816 }, /* XF86AudioNext */
+ { 0x1008ff31, 26830 }, /* XF86AudioPause */
+ { 0x1008ff14, 26845 }, /* XF86AudioPlay */
+ { 0x1008ff16, 26859 }, /* XF86AudioPrev */
+ { 0x1008ff13, 26873 }, /* XF86AudioRaiseVolume */
+ { 0x1008ff99, 26894 }, /* XF86AudioRandomPlay */
+ { 0x1008ff1c, 26914 }, /* XF86AudioRecord */
+ { 0x1008ff98, 26930 }, /* XF86AudioRepeat */
+ { 0x1008ff3e, 26946 }, /* XF86AudioRewind */
+ { 0x1008ff15, 26962 }, /* XF86AudioStop */
+ { 0x1008ff8d, 26976 }, /* XF86Away */
+ { 0x1008ff26, 26985 }, /* XF86Back */
+ { 0x1008ff3f, 26994 }, /* XF86BackForward */
+ { 0x1008ff93, 27010 }, /* XF86Battery */
+ { 0x1008ffa6, 27022 }, /* XF86Blue */
+ { 0x1008ff94, 27031 }, /* XF86Bluetooth */
+ { 0x1008ff52, 27045 }, /* XF86Book */
+ { 0x1008ff3b, 27054 }, /* XF86BrightnessAdjust */
+ { 0x1008ff54, 27075 }, /* XF86Calculater */
+ { 0x1008ff1d, 27090 }, /* XF86Calculator */
+ { 0x1008ff20, 27105 }, /* XF86Calendar */
+ { 0x1008ff53, 27118 }, /* XF86CD */
+ { 0x1008ff55, 27125 }, /* XF86Clear */
+ { 0x1008fe21, 27135 }, /* XF86ClearGrab */
+ { 0x1008ff56, 27149 }, /* XF86Close */
+ { 0x1008ff3d, 27159 }, /* XF86Community */
+ { 0x1008ff22, 27173 }, /* XF86ContrastAdjust */
+ { 0x1008ff57, 27192 }, /* XF86Copy */
+ { 0x1008ff58, 27201 }, /* XF86Cut */
+ { 0x1008ff9c, 27209 }, /* XF86CycleAngle */
+ { 0x1008ff59, 27224 }, /* XF86Display */
+ { 0x1008ff5b, 27236 }, /* XF86Documents */
+ { 0x1008ff5a, 27250 }, /* XF86DOS */
+ { 0x1008ff2c, 27258 }, /* XF86Eject */
+ { 0x1008ff5c, 27268 }, /* XF86Excel */
+ { 0x1008ff5d, 27278 }, /* XF86Explorer */
+ { 0x1008ff30, 27291 }, /* XF86Favorites */
+ { 0x1008ff3c, 27305 }, /* XF86Finance */
+ { 0x1008ff27, 27317 }, /* XF86Forward */
+ { 0x1008ff9d, 27329 }, /* XF86FrameBack */
+ { 0x1008ff9e, 27343 }, /* XF86FrameForward */
+ { 0x1008ff5e, 27360 }, /* XF86Game */
+ { 0x1008ff5f, 27369 }, /* XF86Go */
+ { 0x1008ffa4, 27376 }, /* XF86Green */
+ { 0x1008ffa8, 27386 }, /* XF86Hibernate */
+ { 0x1008ff37, 27400 }, /* XF86History */
+ { 0x1008ff18, 27412 }, /* XF86HomePage */
+ { 0x1008ff3a, 27425 }, /* XF86HotLinks */
+ { 0x1008ff60, 27438 }, /* XF86iTouch */
+ { 0x1008ff06, 27449 }, /* XF86KbdBrightnessDown */
+ { 0x1008ff05, 27471 }, /* XF86KbdBrightnessUp */
+ { 0x1008ff04, 27491 }, /* XF86KbdLightOnOff */
+ { 0x1008ff40, 27509 }, /* XF86Launch0 */
+ { 0x1008ff41, 27521 }, /* XF86Launch1 */
+ { 0x1008ff42, 27533 }, /* XF86Launch2 */
+ { 0x1008ff43, 27545 }, /* XF86Launch3 */
+ { 0x1008ff44, 27557 }, /* XF86Launch4 */
+ { 0x1008ff45, 27569 }, /* XF86Launch5 */
+ { 0x1008ff46, 27581 }, /* XF86Launch6 */
+ { 0x1008ff47, 27593 }, /* XF86Launch7 */
+ { 0x1008ff48, 27605 }, /* XF86Launch8 */
+ { 0x1008ff49, 27617 }, /* XF86Launch9 */
+ { 0x1008ff4a, 27629 }, /* XF86LaunchA */
+ { 0x1008ff4b, 27641 }, /* XF86LaunchB */
+ { 0x1008ff4c, 27653 }, /* XF86LaunchC */
+ { 0x1008ff4d, 27665 }, /* XF86LaunchD */
+ { 0x1008ff4e, 27677 }, /* XF86LaunchE */
+ { 0x1008ff4f, 27689 }, /* XF86LaunchF */
+ { 0x1008ff35, 27701 }, /* XF86LightBulb */
+ { 0x1008fe25, 27715 }, /* XF86LogGrabInfo */
+ { 0x1008ff61, 27731 }, /* XF86LogOff */
+ { 0x1008fe24, 27742 }, /* XF86LogWindowTree */
+ { 0x1008ff19, 27760 }, /* XF86Mail */
+ { 0x1008ff90, 27769 }, /* XF86MailForward */
+ { 0x1008ff62, 27785 }, /* XF86Market */
+ { 0x1008ff63, 27796 }, /* XF86Meeting */
+ { 0x1008ff1e, 27808 }, /* XF86Memo */
+ { 0x1008ff65, 27817 }, /* XF86MenuKB */
+ { 0x1008ff66, 27828 }, /* XF86MenuPB */
+ { 0x1008ff8e, 27839 }, /* XF86Messenger */
+ { 0x1008ff01, 27853 }, /* XF86ModeLock */
+ { 0x1008ff03, 27866 }, /* XF86MonBrightnessDown */
+ { 0x1008ff02, 27888 }, /* XF86MonBrightnessUp */
+ { 0x1008ff92, 27908 }, /* XF86Music */
+ { 0x1008ff33, 27918 }, /* XF86MyComputer */
+ { 0x1008ff67, 27933 }, /* XF86MySites */
+ { 0x1008ff68, 27945 }, /* XF86New */
+ { 0x1008ff69, 27953 }, /* XF86News */
+ { 0x1008fe22, 27962 }, /* XF86Next_VMode */
+ { 0x1008ff6a, 27977 }, /* XF86OfficeHome */
+ { 0x1008ff6b, 27992 }, /* XF86Open */
+ { 0x1008ff38, 28001 }, /* XF86OpenURL */
+ { 0x1008ff6c, 28013 }, /* XF86Option */
+ { 0x1008ff6d, 28024 }, /* XF86Paste */
+ { 0x1008ff6e, 28034 }, /* XF86Phone */
+ { 0x1008ff91, 28044 }, /* XF86Pictures */
+ { 0x1008ff21, 28057 }, /* XF86PowerDown */
+ { 0x1008ff2a, 28071 }, /* XF86PowerOff */
+ { 0x1008fe23, 28084 }, /* XF86Prev_VMode */
+ { 0x1008ff70, 28099 }, /* XF86Q */
+ { 0x1008ffa3, 28105 }, /* XF86Red */
+ { 0x1008ff29, 28113 }, /* XF86Refresh */
+ { 0x1008ff73, 28125 }, /* XF86Reload */
+ { 0x1008ff72, 28136 }, /* XF86Reply */
+ { 0x1008ff24, 28146 }, /* XF86RockerDown */
+ { 0x1008ff25, 28161 }, /* XF86RockerEnter */
+ { 0x1008ff23, 28177 }, /* XF86RockerUp */
+ { 0x1008ff74, 28190 }, /* XF86RotateWindows */
+ { 0x1008ff76, 28208 }, /* XF86RotationKB */
+ { 0x1008ff75, 28223 }, /* XF86RotationPB */
+ { 0x1008ff77, 28238 }, /* XF86Save */
+ { 0x1008ff2d, 28247 }, /* XF86ScreenSaver */
+ { 0x1008ff7a, 28263 }, /* XF86ScrollClick */
+ { 0x1008ff79, 28279 }, /* XF86ScrollDown */
+ { 0x1008ff78, 28294 }, /* XF86ScrollUp */
+ { 0x1008ff1b, 28307 }, /* XF86Search */
+ { 0x1008ffa0, 28318 }, /* XF86Select */
+ { 0x1008ff7b, 28329 }, /* XF86Send */
+ { 0x1008ff36, 28338 }, /* XF86Shop */
+ { 0x1008ff2f, 28347 }, /* XF86Sleep */
+ { 0x1008ff7c, 28357 }, /* XF86Spell */
+ { 0x1008ff7d, 28367 }, /* XF86SplitScreen */
+ { 0x1008ff10, 28383 }, /* XF86Standby */
+ { 0x1008ff1a, 28395 }, /* XF86Start */
+ { 0x1008ff28, 28405 }, /* XF86Stop */
+ { 0x1008ff9a, 28414 }, /* XF86Subtitle */
+ { 0x1008ff7e, 28427 }, /* XF86Support */
+ { 0x1008ffa7, 28439 }, /* XF86Suspend */
+ { 0x1008fe01, 28451 }, /* XF86Switch_VT_1 */
+ { 0x1008fe0a, 28467 }, /* XF86Switch_VT_10 */
+ { 0x1008fe0b, 28484 }, /* XF86Switch_VT_11 */
+ { 0x1008fe0c, 28501 }, /* XF86Switch_VT_12 */
+ { 0x1008fe02, 28518 }, /* XF86Switch_VT_2 */
+ { 0x1008fe03, 28534 }, /* XF86Switch_VT_3 */
+ { 0x1008fe04, 28550 }, /* XF86Switch_VT_4 */
+ { 0x1008fe05, 28566 }, /* XF86Switch_VT_5 */
+ { 0x1008fe06, 28582 }, /* XF86Switch_VT_6 */
+ { 0x1008fe07, 28598 }, /* XF86Switch_VT_7 */
+ { 0x1008fe08, 28614 }, /* XF86Switch_VT_8 */
+ { 0x1008fe09, 28630 }, /* XF86Switch_VT_9 */
+ { 0x1008ff7f, 28646 }, /* XF86TaskPane */
+ { 0x1008ff80, 28659 }, /* XF86Terminal */
+ { 0x1008ff9f, 28672 }, /* XF86Time */
+ { 0x1008ff1f, 28681 }, /* XF86ToDoList */
+ { 0x1008ff81, 28694 }, /* XF86Tools */
+ { 0x1008ffa2, 28704 }, /* XF86TopMenu */
+ { 0x1008ffb1, 28716 }, /* XF86TouchpadOff */
+ { 0x1008ffb0, 28732 }, /* XF86TouchpadOn */
+ { 0x1008ffa9, 28747 }, /* XF86TouchpadToggle */
+ { 0x1008ff82, 28766 }, /* XF86Travel */
+ { 0x1008fe20, 28777 }, /* XF86Ungrab */
+ { 0x1008ff85, 28788 }, /* XF86User1KB */
+ { 0x1008ff86, 28800 }, /* XF86User2KB */
+ { 0x1008ff84, 28812 }, /* XF86UserPB */
+ { 0x1008ff96, 28823 }, /* XF86UWB */
+ { 0x1008ff34, 28831 }, /* XF86VendorHome */
+ { 0x1008ff87, 28846 }, /* XF86Video */
+ { 0x1008ffa1, 28856 }, /* XF86View */
+ { 0x1008ff2b, 28865 }, /* XF86WakeUp */
+ { 0x1008ff8f, 28876 }, /* XF86WebCam */
+ { 0x1008ff88, 28887 }, /* XF86WheelButton */
+ { 0x1008ff95, 28903 }, /* XF86WLAN */
+ { 0x1008ff89, 28912 }, /* XF86Word */
+ { 0x1008ff2e, 28921 }, /* XF86WWW */
+ { 0x1008ff8a, 28929 }, /* XF86Xfer */
+ { 0x1008ffa5, 28938 }, /* XF86Yellow */
+ { 0x1008ff8b, 28949 }, /* XF86ZoomIn */
+ { 0x1008ff8c, 28960 }, /* XF86ZoomOut */
+ { 0x00000059, 28972 }, /* Y */
+ { 0x00000079, 28974 }, /* y */
+ { 0x000000dd, 28976 }, /* Yacute */
+ { 0x000000fd, 28983 }, /* yacute */
+ { 0x01001ef4, 28990 }, /* Ybelowdot */
+ { 0x01001ef5, 29000 }, /* ybelowdot */
+ { 0x01000176, 29010 }, /* Ycircumflex */
+ { 0x01000177, 29022 }, /* ycircumflex */
+ { 0x000000ff, 29034 }, /* ydiaeresis */
+ { 0x000013be, 29045 }, /* Ydiaeresis */
+ { 0x000000a5, 29056 }, /* yen */
+ { 0x01001ef2, 29060 }, /* Ygrave */
+ { 0x01001ef3, 29067 }, /* ygrave */
+ { 0x01001ef6, 29074 }, /* Yhook */
+ { 0x01001ef7, 29080 }, /* yhook */
+ { 0x01001ef8, 29086 }, /* Ytilde */
+ { 0x01001ef9, 29093 }, /* ytilde */
+ { 0x0000005a, 29100 }, /* Z */
+ { 0x0000007a, 29102 }, /* z */
+ { 0x000001af, 29104 }, /* Zabovedot */
+ { 0x000001bf, 29114 }, /* zabovedot */
+ { 0x000001ac, 29124 }, /* Zacute */
+ { 0x000001bc, 29131 }, /* zacute */
+ { 0x000001ae, 29138 }, /* Zcaron */
+ { 0x000001be, 29145 }, /* zcaron */
+ { 0x0000ff3d, 29152 }, /* Zen_Koho */
+ { 0x0000ff28, 29161 }, /* Zenkaku */
+ { 0x0000ff2a, 29169 }, /* Zenkaku_Hankaku */
+ { 0x01002080, 29185 }, /* zerosubscript */
+ { 0x01002070, 29199 }, /* zerosuperior */
+ { 0x010001b5, 29212 }, /* Zstroke */
+ { 0x010001b6, 29220 }, /* zstroke */
};
static const struct name_keysym keysym_to_name[] = {
- { "NoSymbol", XKB_KEY_NoSymbol },
- { "space", XKB_KEY_space },
- { "exclam", XKB_KEY_exclam },
- { "quotedbl", XKB_KEY_quotedbl },
- { "numbersign", XKB_KEY_numbersign },
- { "dollar", XKB_KEY_dollar },
- { "percent", XKB_KEY_percent },
- { "ampersand", XKB_KEY_ampersand },
- { "apostrophe", XKB_KEY_apostrophe },
- { "parenleft", XKB_KEY_parenleft },
- { "parenright", XKB_KEY_parenright },
- { "asterisk", XKB_KEY_asterisk },
- { "plus", XKB_KEY_plus },
- { "comma", XKB_KEY_comma },
- { "minus", XKB_KEY_minus },
- { "period", XKB_KEY_period },
- { "slash", XKB_KEY_slash },
- { "0", XKB_KEY_0 },
- { "1", XKB_KEY_1 },
- { "2", XKB_KEY_2 },
- { "3", XKB_KEY_3 },
- { "4", XKB_KEY_4 },
- { "5", XKB_KEY_5 },
- { "6", XKB_KEY_6 },
- { "7", XKB_KEY_7 },
- { "8", XKB_KEY_8 },
- { "9", XKB_KEY_9 },
- { "colon", XKB_KEY_colon },
- { "semicolon", XKB_KEY_semicolon },
- { "less", XKB_KEY_less },
- { "equal", XKB_KEY_equal },
- { "greater", XKB_KEY_greater },
- { "question", XKB_KEY_question },
- { "at", XKB_KEY_at },
- { "A", XKB_KEY_A },
- { "B", XKB_KEY_B },
- { "C", XKB_KEY_C },
- { "D", XKB_KEY_D },
- { "E", XKB_KEY_E },
- { "F", XKB_KEY_F },
- { "G", XKB_KEY_G },
- { "H", XKB_KEY_H },
- { "I", XKB_KEY_I },
- { "J", XKB_KEY_J },
- { "K", XKB_KEY_K },
- { "L", XKB_KEY_L },
- { "M", XKB_KEY_M },
- { "N", XKB_KEY_N },
- { "O", XKB_KEY_O },
- { "P", XKB_KEY_P },
- { "Q", XKB_KEY_Q },
- { "R", XKB_KEY_R },
- { "S", XKB_KEY_S },
- { "T", XKB_KEY_T },
- { "U", XKB_KEY_U },
- { "V", XKB_KEY_V },
- { "W", XKB_KEY_W },
- { "X", XKB_KEY_X },
- { "Y", XKB_KEY_Y },
- { "Z", XKB_KEY_Z },
- { "bracketleft", XKB_KEY_bracketleft },
- { "backslash", XKB_KEY_backslash },
- { "bracketright", XKB_KEY_bracketright },
- { "asciicircum", XKB_KEY_asciicircum },
- { "underscore", XKB_KEY_underscore },
- { "grave", XKB_KEY_grave },
- { "a", XKB_KEY_a },
- { "b", XKB_KEY_b },
- { "c", XKB_KEY_c },
- { "d", XKB_KEY_d },
- { "e", XKB_KEY_e },
- { "f", XKB_KEY_f },
- { "g", XKB_KEY_g },
- { "h", XKB_KEY_h },
- { "i", XKB_KEY_i },
- { "j", XKB_KEY_j },
- { "k", XKB_KEY_k },
- { "l", XKB_KEY_l },
- { "m", XKB_KEY_m },
- { "n", XKB_KEY_n },
- { "o", XKB_KEY_o },
- { "p", XKB_KEY_p },
- { "q", XKB_KEY_q },
- { "r", XKB_KEY_r },
- { "s", XKB_KEY_s },
- { "t", XKB_KEY_t },
- { "u", XKB_KEY_u },
- { "v", XKB_KEY_v },
- { "w", XKB_KEY_w },
- { "x", XKB_KEY_x },
- { "y", XKB_KEY_y },
- { "z", XKB_KEY_z },
- { "braceleft", XKB_KEY_braceleft },
- { "bar", XKB_KEY_bar },
- { "braceright", XKB_KEY_braceright },
- { "asciitilde", XKB_KEY_asciitilde },
- { "nobreakspace", XKB_KEY_nobreakspace },
- { "exclamdown", XKB_KEY_exclamdown },
- { "cent", XKB_KEY_cent },
- { "sterling", XKB_KEY_sterling },
- { "currency", XKB_KEY_currency },
- { "yen", XKB_KEY_yen },
- { "brokenbar", XKB_KEY_brokenbar },
- { "section", XKB_KEY_section },
- { "diaeresis", XKB_KEY_diaeresis },
- { "copyright", XKB_KEY_copyright },
- { "ordfeminine", XKB_KEY_ordfeminine },
- { "guillemotleft", XKB_KEY_guillemotleft },
- { "notsign", XKB_KEY_notsign },
- { "hyphen", XKB_KEY_hyphen },
- { "registered", XKB_KEY_registered },
- { "macron", XKB_KEY_macron },
- { "degree", XKB_KEY_degree },
- { "plusminus", XKB_KEY_plusminus },
- { "twosuperior", XKB_KEY_twosuperior },
- { "threesuperior", XKB_KEY_threesuperior },
- { "acute", XKB_KEY_acute },
- { "mu", XKB_KEY_mu },
- { "paragraph", XKB_KEY_paragraph },
- { "periodcentered", XKB_KEY_periodcentered },
- { "cedilla", XKB_KEY_cedilla },
- { "onesuperior", XKB_KEY_onesuperior },
- { "masculine", XKB_KEY_masculine },
- { "guillemotright", XKB_KEY_guillemotright },
- { "onequarter", XKB_KEY_onequarter },
- { "onehalf", XKB_KEY_onehalf },
- { "threequarters", XKB_KEY_threequarters },
- { "questiondown", XKB_KEY_questiondown },
- { "Agrave", XKB_KEY_Agrave },
- { "Aacute", XKB_KEY_Aacute },
- { "Acircumflex", XKB_KEY_Acircumflex },
- { "Atilde", XKB_KEY_Atilde },
- { "Adiaeresis", XKB_KEY_Adiaeresis },
- { "Aring", XKB_KEY_Aring },
- { "AE", XKB_KEY_AE },
- { "Ccedilla", XKB_KEY_Ccedilla },
- { "Egrave", XKB_KEY_Egrave },
- { "Eacute", XKB_KEY_Eacute },
- { "Ecircumflex", XKB_KEY_Ecircumflex },
- { "Ediaeresis", XKB_KEY_Ediaeresis },
- { "Igrave", XKB_KEY_Igrave },
- { "Iacute", XKB_KEY_Iacute },
- { "Icircumflex", XKB_KEY_Icircumflex },
- { "Idiaeresis", XKB_KEY_Idiaeresis },
- { "ETH", XKB_KEY_ETH },
- { "Ntilde", XKB_KEY_Ntilde },
- { "Ograve", XKB_KEY_Ograve },
- { "Oacute", XKB_KEY_Oacute },
- { "Ocircumflex", XKB_KEY_Ocircumflex },
- { "Otilde", XKB_KEY_Otilde },
- { "Odiaeresis", XKB_KEY_Odiaeresis },
- { "multiply", XKB_KEY_multiply },
- { "Oslash", XKB_KEY_Oslash },
- { "Ugrave", XKB_KEY_Ugrave },
- { "Uacute", XKB_KEY_Uacute },
- { "Ucircumflex", XKB_KEY_Ucircumflex },
- { "Udiaeresis", XKB_KEY_Udiaeresis },
- { "Yacute", XKB_KEY_Yacute },
- { "THORN", XKB_KEY_THORN },
- { "ssharp", XKB_KEY_ssharp },
- { "agrave", XKB_KEY_agrave },
- { "aacute", XKB_KEY_aacute },
- { "acircumflex", XKB_KEY_acircumflex },
- { "atilde", XKB_KEY_atilde },
- { "adiaeresis", XKB_KEY_adiaeresis },
- { "aring", XKB_KEY_aring },
- { "ae", XKB_KEY_ae },
- { "ccedilla", XKB_KEY_ccedilla },
- { "egrave", XKB_KEY_egrave },
- { "eacute", XKB_KEY_eacute },
- { "ecircumflex", XKB_KEY_ecircumflex },
- { "ediaeresis", XKB_KEY_ediaeresis },
- { "igrave", XKB_KEY_igrave },
- { "iacute", XKB_KEY_iacute },
- { "icircumflex", XKB_KEY_icircumflex },
- { "idiaeresis", XKB_KEY_idiaeresis },
- { "eth", XKB_KEY_eth },
- { "ntilde", XKB_KEY_ntilde },
- { "ograve", XKB_KEY_ograve },
- { "oacute", XKB_KEY_oacute },
- { "ocircumflex", XKB_KEY_ocircumflex },
- { "otilde", XKB_KEY_otilde },
- { "odiaeresis", XKB_KEY_odiaeresis },
- { "division", XKB_KEY_division },
- { "oslash", XKB_KEY_oslash },
- { "ugrave", XKB_KEY_ugrave },
- { "uacute", XKB_KEY_uacute },
- { "ucircumflex", XKB_KEY_ucircumflex },
- { "udiaeresis", XKB_KEY_udiaeresis },
- { "yacute", XKB_KEY_yacute },
- { "thorn", XKB_KEY_thorn },
- { "ydiaeresis", XKB_KEY_ydiaeresis },
- { "Aogonek", XKB_KEY_Aogonek },
- { "breve", XKB_KEY_breve },
- { "Lstroke", XKB_KEY_Lstroke },
- { "Lcaron", XKB_KEY_Lcaron },
- { "Sacute", XKB_KEY_Sacute },
- { "Scaron", XKB_KEY_Scaron },
- { "Scedilla", XKB_KEY_Scedilla },
- { "Tcaron", XKB_KEY_Tcaron },
- { "Zacute", XKB_KEY_Zacute },
- { "Zcaron", XKB_KEY_Zcaron },
- { "Zabovedot", XKB_KEY_Zabovedot },
- { "aogonek", XKB_KEY_aogonek },
- { "ogonek", XKB_KEY_ogonek },
- { "lstroke", XKB_KEY_lstroke },
- { "lcaron", XKB_KEY_lcaron },
- { "sacute", XKB_KEY_sacute },
- { "caron", XKB_KEY_caron },
- { "scaron", XKB_KEY_scaron },
- { "scedilla", XKB_KEY_scedilla },
- { "tcaron", XKB_KEY_tcaron },
- { "zacute", XKB_KEY_zacute },
- { "doubleacute", XKB_KEY_doubleacute },
- { "zcaron", XKB_KEY_zcaron },
- { "zabovedot", XKB_KEY_zabovedot },
- { "Racute", XKB_KEY_Racute },
- { "Abreve", XKB_KEY_Abreve },
- { "Lacute", XKB_KEY_Lacute },
- { "Cacute", XKB_KEY_Cacute },
- { "Ccaron", XKB_KEY_Ccaron },
- { "Eogonek", XKB_KEY_Eogonek },
- { "Ecaron", XKB_KEY_Ecaron },
- { "Dcaron", XKB_KEY_Dcaron },
- { "Dstroke", XKB_KEY_Dstroke },
- { "Nacute", XKB_KEY_Nacute },
- { "Ncaron", XKB_KEY_Ncaron },
- { "Odoubleacute", XKB_KEY_Odoubleacute },
- { "Rcaron", XKB_KEY_Rcaron },
- { "Uring", XKB_KEY_Uring },
- { "Udoubleacute", XKB_KEY_Udoubleacute },
- { "Tcedilla", XKB_KEY_Tcedilla },
- { "racute", XKB_KEY_racute },
- { "abreve", XKB_KEY_abreve },
- { "lacute", XKB_KEY_lacute },
- { "cacute", XKB_KEY_cacute },
- { "ccaron", XKB_KEY_ccaron },
- { "eogonek", XKB_KEY_eogonek },
- { "ecaron", XKB_KEY_ecaron },
- { "dcaron", XKB_KEY_dcaron },
- { "dstroke", XKB_KEY_dstroke },
- { "nacute", XKB_KEY_nacute },
- { "ncaron", XKB_KEY_ncaron },
- { "odoubleacute", XKB_KEY_odoubleacute },
- { "rcaron", XKB_KEY_rcaron },
- { "uring", XKB_KEY_uring },
- { "udoubleacute", XKB_KEY_udoubleacute },
- { "tcedilla", XKB_KEY_tcedilla },
- { "abovedot", XKB_KEY_abovedot },
- { "Hstroke", XKB_KEY_Hstroke },
- { "Hcircumflex", XKB_KEY_Hcircumflex },
- { "Iabovedot", XKB_KEY_Iabovedot },
- { "Gbreve", XKB_KEY_Gbreve },
- { "Jcircumflex", XKB_KEY_Jcircumflex },
- { "hstroke", XKB_KEY_hstroke },
- { "hcircumflex", XKB_KEY_hcircumflex },
- { "idotless", XKB_KEY_idotless },
- { "gbreve", XKB_KEY_gbreve },
- { "jcircumflex", XKB_KEY_jcircumflex },
- { "Cabovedot", XKB_KEY_Cabovedot },
- { "Ccircumflex", XKB_KEY_Ccircumflex },
- { "Gabovedot", XKB_KEY_Gabovedot },
- { "Gcircumflex", XKB_KEY_Gcircumflex },
- { "Ubreve", XKB_KEY_Ubreve },
- { "Scircumflex", XKB_KEY_Scircumflex },
- { "cabovedot", XKB_KEY_cabovedot },
- { "ccircumflex", XKB_KEY_ccircumflex },
- { "gabovedot", XKB_KEY_gabovedot },
- { "gcircumflex", XKB_KEY_gcircumflex },
- { "ubreve", XKB_KEY_ubreve },
- { "scircumflex", XKB_KEY_scircumflex },
- { "kra", XKB_KEY_kra },
- { "Rcedilla", XKB_KEY_Rcedilla },
- { "Itilde", XKB_KEY_Itilde },
- { "Lcedilla", XKB_KEY_Lcedilla },
- { "Emacron", XKB_KEY_Emacron },
- { "Gcedilla", XKB_KEY_Gcedilla },
- { "Tslash", XKB_KEY_Tslash },
- { "rcedilla", XKB_KEY_rcedilla },
- { "itilde", XKB_KEY_itilde },
- { "lcedilla", XKB_KEY_lcedilla },
- { "emacron", XKB_KEY_emacron },
- { "gcedilla", XKB_KEY_gcedilla },
- { "tslash", XKB_KEY_tslash },
- { "ENG", XKB_KEY_ENG },
- { "eng", XKB_KEY_eng },
- { "Amacron", XKB_KEY_Amacron },
- { "Iogonek", XKB_KEY_Iogonek },
- { "Eabovedot", XKB_KEY_Eabovedot },
- { "Imacron", XKB_KEY_Imacron },
- { "Ncedilla", XKB_KEY_Ncedilla },
- { "Omacron", XKB_KEY_Omacron },
- { "Kcedilla", XKB_KEY_Kcedilla },
- { "Uogonek", XKB_KEY_Uogonek },
- { "Utilde", XKB_KEY_Utilde },
- { "Umacron", XKB_KEY_Umacron },
- { "amacron", XKB_KEY_amacron },
- { "iogonek", XKB_KEY_iogonek },
- { "eabovedot", XKB_KEY_eabovedot },
- { "imacron", XKB_KEY_imacron },
- { "ncedilla", XKB_KEY_ncedilla },
- { "omacron", XKB_KEY_omacron },
- { "kcedilla", XKB_KEY_kcedilla },
- { "uogonek", XKB_KEY_uogonek },
- { "utilde", XKB_KEY_utilde },
- { "umacron", XKB_KEY_umacron },
- { "overline", XKB_KEY_overline },
- { "kana_fullstop", XKB_KEY_kana_fullstop },
- { "kana_openingbracket", XKB_KEY_kana_openingbracket },
- { "kana_closingbracket", XKB_KEY_kana_closingbracket },
- { "kana_comma", XKB_KEY_kana_comma },
- { "kana_conjunctive", XKB_KEY_kana_conjunctive },
- { "kana_WO", XKB_KEY_kana_WO },
- { "kana_a", XKB_KEY_kana_a },
- { "kana_i", XKB_KEY_kana_i },
- { "kana_u", XKB_KEY_kana_u },
- { "kana_e", XKB_KEY_kana_e },
- { "kana_o", XKB_KEY_kana_o },
- { "kana_ya", XKB_KEY_kana_ya },
- { "kana_yu", XKB_KEY_kana_yu },
- { "kana_yo", XKB_KEY_kana_yo },
- { "kana_tsu", XKB_KEY_kana_tsu },
- { "prolongedsound", XKB_KEY_prolongedsound },
- { "kana_A", XKB_KEY_kana_A },
- { "kana_I", XKB_KEY_kana_I },
- { "kana_U", XKB_KEY_kana_U },
- { "kana_E", XKB_KEY_kana_E },
- { "kana_O", XKB_KEY_kana_O },
- { "kana_KA", XKB_KEY_kana_KA },
- { "kana_KI", XKB_KEY_kana_KI },
- { "kana_KU", XKB_KEY_kana_KU },
- { "kana_KE", XKB_KEY_kana_KE },
- { "kana_KO", XKB_KEY_kana_KO },
- { "kana_SA", XKB_KEY_kana_SA },
- { "kana_SHI", XKB_KEY_kana_SHI },
- { "kana_SU", XKB_KEY_kana_SU },
- { "kana_SE", XKB_KEY_kana_SE },
- { "kana_SO", XKB_KEY_kana_SO },
- { "kana_TA", XKB_KEY_kana_TA },
- { "kana_CHI", XKB_KEY_kana_CHI },
- { "kana_TSU", XKB_KEY_kana_TSU },
- { "kana_TE", XKB_KEY_kana_TE },
- { "kana_TO", XKB_KEY_kana_TO },
- { "kana_NA", XKB_KEY_kana_NA },
- { "kana_NI", XKB_KEY_kana_NI },
- { "kana_NU", XKB_KEY_kana_NU },
- { "kana_NE", XKB_KEY_kana_NE },
- { "kana_NO", XKB_KEY_kana_NO },
- { "kana_HA", XKB_KEY_kana_HA },
- { "kana_HI", XKB_KEY_kana_HI },
- { "kana_FU", XKB_KEY_kana_FU },
- { "kana_HE", XKB_KEY_kana_HE },
- { "kana_HO", XKB_KEY_kana_HO },
- { "kana_MA", XKB_KEY_kana_MA },
- { "kana_MI", XKB_KEY_kana_MI },
- { "kana_MU", XKB_KEY_kana_MU },
- { "kana_ME", XKB_KEY_kana_ME },
- { "kana_MO", XKB_KEY_kana_MO },
- { "kana_YA", XKB_KEY_kana_YA },
- { "kana_YU", XKB_KEY_kana_YU },
- { "kana_YO", XKB_KEY_kana_YO },
- { "kana_RA", XKB_KEY_kana_RA },
- { "kana_RI", XKB_KEY_kana_RI },
- { "kana_RU", XKB_KEY_kana_RU },
- { "kana_RE", XKB_KEY_kana_RE },
- { "kana_RO", XKB_KEY_kana_RO },
- { "kana_WA", XKB_KEY_kana_WA },
- { "kana_N", XKB_KEY_kana_N },
- { "voicedsound", XKB_KEY_voicedsound },
- { "semivoicedsound", XKB_KEY_semivoicedsound },
- { "Arabic_comma", XKB_KEY_Arabic_comma },
- { "Arabic_semicolon", XKB_KEY_Arabic_semicolon },
- { "Arabic_question_mark", XKB_KEY_Arabic_question_mark },
- { "Arabic_hamza", XKB_KEY_Arabic_hamza },
- { "Arabic_maddaonalef", XKB_KEY_Arabic_maddaonalef },
- { "Arabic_hamzaonalef", XKB_KEY_Arabic_hamzaonalef },
- { "Arabic_hamzaonwaw", XKB_KEY_Arabic_hamzaonwaw },
- { "Arabic_hamzaunderalef", XKB_KEY_Arabic_hamzaunderalef },
- { "Arabic_hamzaonyeh", XKB_KEY_Arabic_hamzaonyeh },
- { "Arabic_alef", XKB_KEY_Arabic_alef },
- { "Arabic_beh", XKB_KEY_Arabic_beh },
- { "Arabic_tehmarbuta", XKB_KEY_Arabic_tehmarbuta },
- { "Arabic_teh", XKB_KEY_Arabic_teh },
- { "Arabic_theh", XKB_KEY_Arabic_theh },
- { "Arabic_jeem", XKB_KEY_Arabic_jeem },
- { "Arabic_hah", XKB_KEY_Arabic_hah },
- { "Arabic_khah", XKB_KEY_Arabic_khah },
- { "Arabic_dal", XKB_KEY_Arabic_dal },
- { "Arabic_thal", XKB_KEY_Arabic_thal },
- { "Arabic_ra", XKB_KEY_Arabic_ra },
- { "Arabic_zain", XKB_KEY_Arabic_zain },
- { "Arabic_seen", XKB_KEY_Arabic_seen },
- { "Arabic_sheen", XKB_KEY_Arabic_sheen },
- { "Arabic_sad", XKB_KEY_Arabic_sad },
- { "Arabic_dad", XKB_KEY_Arabic_dad },
- { "Arabic_tah", XKB_KEY_Arabic_tah },
- { "Arabic_zah", XKB_KEY_Arabic_zah },
- { "Arabic_ain", XKB_KEY_Arabic_ain },
- { "Arabic_ghain", XKB_KEY_Arabic_ghain },
- { "Arabic_tatweel", XKB_KEY_Arabic_tatweel },
- { "Arabic_feh", XKB_KEY_Arabic_feh },
- { "Arabic_qaf", XKB_KEY_Arabic_qaf },
- { "Arabic_kaf", XKB_KEY_Arabic_kaf },
- { "Arabic_lam", XKB_KEY_Arabic_lam },
- { "Arabic_meem", XKB_KEY_Arabic_meem },
- { "Arabic_noon", XKB_KEY_Arabic_noon },
- { "Arabic_ha", XKB_KEY_Arabic_ha },
- { "Arabic_waw", XKB_KEY_Arabic_waw },
- { "Arabic_alefmaksura", XKB_KEY_Arabic_alefmaksura },
- { "Arabic_yeh", XKB_KEY_Arabic_yeh },
- { "Arabic_fathatan", XKB_KEY_Arabic_fathatan },
- { "Arabic_dammatan", XKB_KEY_Arabic_dammatan },
- { "Arabic_kasratan", XKB_KEY_Arabic_kasratan },
- { "Arabic_fatha", XKB_KEY_Arabic_fatha },
- { "Arabic_damma", XKB_KEY_Arabic_damma },
- { "Arabic_kasra", XKB_KEY_Arabic_kasra },
- { "Arabic_shadda", XKB_KEY_Arabic_shadda },
- { "Arabic_sukun", XKB_KEY_Arabic_sukun },
- { "Serbian_dje", XKB_KEY_Serbian_dje },
- { "Macedonia_gje", XKB_KEY_Macedonia_gje },
- { "Cyrillic_io", XKB_KEY_Cyrillic_io },
- { "Ukrainian_ie", XKB_KEY_Ukrainian_ie },
- { "Macedonia_dse", XKB_KEY_Macedonia_dse },
- { "Ukrainian_i", XKB_KEY_Ukrainian_i },
- { "Ukrainian_yi", XKB_KEY_Ukrainian_yi },
- { "Cyrillic_je", XKB_KEY_Cyrillic_je },
- { "Cyrillic_lje", XKB_KEY_Cyrillic_lje },
- { "Cyrillic_nje", XKB_KEY_Cyrillic_nje },
- { "Serbian_tshe", XKB_KEY_Serbian_tshe },
- { "Macedonia_kje", XKB_KEY_Macedonia_kje },
- { "Ukrainian_ghe_with_upturn", XKB_KEY_Ukrainian_ghe_with_upturn },
- { "Byelorussian_shortu", XKB_KEY_Byelorussian_shortu },
- { "Cyrillic_dzhe", XKB_KEY_Cyrillic_dzhe },
- { "numerosign", XKB_KEY_numerosign },
- { "Serbian_DJE", XKB_KEY_Serbian_DJE },
- { "Macedonia_GJE", XKB_KEY_Macedonia_GJE },
- { "Cyrillic_IO", XKB_KEY_Cyrillic_IO },
- { "Ukrainian_IE", XKB_KEY_Ukrainian_IE },
- { "Macedonia_DSE", XKB_KEY_Macedonia_DSE },
- { "Ukrainian_I", XKB_KEY_Ukrainian_I },
- { "Ukrainian_YI", XKB_KEY_Ukrainian_YI },
- { "Cyrillic_JE", XKB_KEY_Cyrillic_JE },
- { "Cyrillic_LJE", XKB_KEY_Cyrillic_LJE },
- { "Cyrillic_NJE", XKB_KEY_Cyrillic_NJE },
- { "Serbian_TSHE", XKB_KEY_Serbian_TSHE },
- { "Macedonia_KJE", XKB_KEY_Macedonia_KJE },
- { "Ukrainian_GHE_WITH_UPTURN", XKB_KEY_Ukrainian_GHE_WITH_UPTURN },
- { "Byelorussian_SHORTU", XKB_KEY_Byelorussian_SHORTU },
- { "Cyrillic_DZHE", XKB_KEY_Cyrillic_DZHE },
- { "Cyrillic_yu", XKB_KEY_Cyrillic_yu },
- { "Cyrillic_a", XKB_KEY_Cyrillic_a },
- { "Cyrillic_be", XKB_KEY_Cyrillic_be },
- { "Cyrillic_tse", XKB_KEY_Cyrillic_tse },
- { "Cyrillic_de", XKB_KEY_Cyrillic_de },
- { "Cyrillic_ie", XKB_KEY_Cyrillic_ie },
- { "Cyrillic_ef", XKB_KEY_Cyrillic_ef },
- { "Cyrillic_ghe", XKB_KEY_Cyrillic_ghe },
- { "Cyrillic_ha", XKB_KEY_Cyrillic_ha },
- { "Cyrillic_i", XKB_KEY_Cyrillic_i },
- { "Cyrillic_shorti", XKB_KEY_Cyrillic_shorti },
- { "Cyrillic_ka", XKB_KEY_Cyrillic_ka },
- { "Cyrillic_el", XKB_KEY_Cyrillic_el },
- { "Cyrillic_em", XKB_KEY_Cyrillic_em },
- { "Cyrillic_en", XKB_KEY_Cyrillic_en },
- { "Cyrillic_o", XKB_KEY_Cyrillic_o },
- { "Cyrillic_pe", XKB_KEY_Cyrillic_pe },
- { "Cyrillic_ya", XKB_KEY_Cyrillic_ya },
- { "Cyrillic_er", XKB_KEY_Cyrillic_er },
- { "Cyrillic_es", XKB_KEY_Cyrillic_es },
- { "Cyrillic_te", XKB_KEY_Cyrillic_te },
- { "Cyrillic_u", XKB_KEY_Cyrillic_u },
- { "Cyrillic_zhe", XKB_KEY_Cyrillic_zhe },
- { "Cyrillic_ve", XKB_KEY_Cyrillic_ve },
- { "Cyrillic_softsign", XKB_KEY_Cyrillic_softsign },
- { "Cyrillic_yeru", XKB_KEY_Cyrillic_yeru },
- { "Cyrillic_ze", XKB_KEY_Cyrillic_ze },
- { "Cyrillic_sha", XKB_KEY_Cyrillic_sha },
- { "Cyrillic_e", XKB_KEY_Cyrillic_e },
- { "Cyrillic_shcha", XKB_KEY_Cyrillic_shcha },
- { "Cyrillic_che", XKB_KEY_Cyrillic_che },
- { "Cyrillic_hardsign", XKB_KEY_Cyrillic_hardsign },
- { "Cyrillic_YU", XKB_KEY_Cyrillic_YU },
- { "Cyrillic_A", XKB_KEY_Cyrillic_A },
- { "Cyrillic_BE", XKB_KEY_Cyrillic_BE },
- { "Cyrillic_TSE", XKB_KEY_Cyrillic_TSE },
- { "Cyrillic_DE", XKB_KEY_Cyrillic_DE },
- { "Cyrillic_IE", XKB_KEY_Cyrillic_IE },
- { "Cyrillic_EF", XKB_KEY_Cyrillic_EF },
- { "Cyrillic_GHE", XKB_KEY_Cyrillic_GHE },
- { "Cyrillic_HA", XKB_KEY_Cyrillic_HA },
- { "Cyrillic_I", XKB_KEY_Cyrillic_I },
- { "Cyrillic_SHORTI", XKB_KEY_Cyrillic_SHORTI },
- { "Cyrillic_KA", XKB_KEY_Cyrillic_KA },
- { "Cyrillic_EL", XKB_KEY_Cyrillic_EL },
- { "Cyrillic_EM", XKB_KEY_Cyrillic_EM },
- { "Cyrillic_EN", XKB_KEY_Cyrillic_EN },
- { "Cyrillic_O", XKB_KEY_Cyrillic_O },
- { "Cyrillic_PE", XKB_KEY_Cyrillic_PE },
- { "Cyrillic_YA", XKB_KEY_Cyrillic_YA },
- { "Cyrillic_ER", XKB_KEY_Cyrillic_ER },
- { "Cyrillic_ES", XKB_KEY_Cyrillic_ES },
- { "Cyrillic_TE", XKB_KEY_Cyrillic_TE },
- { "Cyrillic_U", XKB_KEY_Cyrillic_U },
- { "Cyrillic_ZHE", XKB_KEY_Cyrillic_ZHE },
- { "Cyrillic_VE", XKB_KEY_Cyrillic_VE },
- { "Cyrillic_SOFTSIGN", XKB_KEY_Cyrillic_SOFTSIGN },
- { "Cyrillic_YERU", XKB_KEY_Cyrillic_YERU },
- { "Cyrillic_ZE", XKB_KEY_Cyrillic_ZE },
- { "Cyrillic_SHA", XKB_KEY_Cyrillic_SHA },
- { "Cyrillic_E", XKB_KEY_Cyrillic_E },
- { "Cyrillic_SHCHA", XKB_KEY_Cyrillic_SHCHA },
- { "Cyrillic_CHE", XKB_KEY_Cyrillic_CHE },
- { "Cyrillic_HARDSIGN", XKB_KEY_Cyrillic_HARDSIGN },
- { "Greek_ALPHAaccent", XKB_KEY_Greek_ALPHAaccent },
- { "Greek_EPSILONaccent", XKB_KEY_Greek_EPSILONaccent },
- { "Greek_ETAaccent", XKB_KEY_Greek_ETAaccent },
- { "Greek_IOTAaccent", XKB_KEY_Greek_IOTAaccent },
- { "Greek_IOTAdieresis", XKB_KEY_Greek_IOTAdieresis },
- { "Greek_OMICRONaccent", XKB_KEY_Greek_OMICRONaccent },
- { "Greek_UPSILONaccent", XKB_KEY_Greek_UPSILONaccent },
- { "Greek_UPSILONdieresis", XKB_KEY_Greek_UPSILONdieresis },
- { "Greek_OMEGAaccent", XKB_KEY_Greek_OMEGAaccent },
- { "Greek_accentdieresis", XKB_KEY_Greek_accentdieresis },
- { "Greek_horizbar", XKB_KEY_Greek_horizbar },
- { "Greek_alphaaccent", XKB_KEY_Greek_alphaaccent },
- { "Greek_epsilonaccent", XKB_KEY_Greek_epsilonaccent },
- { "Greek_etaaccent", XKB_KEY_Greek_etaaccent },
- { "Greek_iotaaccent", XKB_KEY_Greek_iotaaccent },
- { "Greek_iotadieresis", XKB_KEY_Greek_iotadieresis },
- { "Greek_iotaaccentdieresis", XKB_KEY_Greek_iotaaccentdieresis },
- { "Greek_omicronaccent", XKB_KEY_Greek_omicronaccent },
- { "Greek_upsilonaccent", XKB_KEY_Greek_upsilonaccent },
- { "Greek_upsilondieresis", XKB_KEY_Greek_upsilondieresis },
- { "Greek_upsilonaccentdieresis", XKB_KEY_Greek_upsilonaccentdieresis },
- { "Greek_omegaaccent", XKB_KEY_Greek_omegaaccent },
- { "Greek_ALPHA", XKB_KEY_Greek_ALPHA },
- { "Greek_BETA", XKB_KEY_Greek_BETA },
- { "Greek_GAMMA", XKB_KEY_Greek_GAMMA },
- { "Greek_DELTA", XKB_KEY_Greek_DELTA },
- { "Greek_EPSILON", XKB_KEY_Greek_EPSILON },
- { "Greek_ZETA", XKB_KEY_Greek_ZETA },
- { "Greek_ETA", XKB_KEY_Greek_ETA },
- { "Greek_THETA", XKB_KEY_Greek_THETA },
- { "Greek_IOTA", XKB_KEY_Greek_IOTA },
- { "Greek_KAPPA", XKB_KEY_Greek_KAPPA },
- { "Greek_LAMDA", XKB_KEY_Greek_LAMDA },
- { "Greek_MU", XKB_KEY_Greek_MU },
- { "Greek_NU", XKB_KEY_Greek_NU },
- { "Greek_XI", XKB_KEY_Greek_XI },
- { "Greek_OMICRON", XKB_KEY_Greek_OMICRON },
- { "Greek_PI", XKB_KEY_Greek_PI },
- { "Greek_RHO", XKB_KEY_Greek_RHO },
- { "Greek_SIGMA", XKB_KEY_Greek_SIGMA },
- { "Greek_TAU", XKB_KEY_Greek_TAU },
- { "Greek_UPSILON", XKB_KEY_Greek_UPSILON },
- { "Greek_PHI", XKB_KEY_Greek_PHI },
- { "Greek_CHI", XKB_KEY_Greek_CHI },
- { "Greek_PSI", XKB_KEY_Greek_PSI },
- { "Greek_OMEGA", XKB_KEY_Greek_OMEGA },
- { "Greek_alpha", XKB_KEY_Greek_alpha },
- { "Greek_beta", XKB_KEY_Greek_beta },
- { "Greek_gamma", XKB_KEY_Greek_gamma },
- { "Greek_delta", XKB_KEY_Greek_delta },
- { "Greek_epsilon", XKB_KEY_Greek_epsilon },
- { "Greek_zeta", XKB_KEY_Greek_zeta },
- { "Greek_eta", XKB_KEY_Greek_eta },
- { "Greek_theta", XKB_KEY_Greek_theta },
- { "Greek_iota", XKB_KEY_Greek_iota },
- { "Greek_kappa", XKB_KEY_Greek_kappa },
- { "Greek_lamda", XKB_KEY_Greek_lamda },
- { "Greek_mu", XKB_KEY_Greek_mu },
- { "Greek_nu", XKB_KEY_Greek_nu },
- { "Greek_xi", XKB_KEY_Greek_xi },
- { "Greek_omicron", XKB_KEY_Greek_omicron },
- { "Greek_pi", XKB_KEY_Greek_pi },
- { "Greek_rho", XKB_KEY_Greek_rho },
- { "Greek_sigma", XKB_KEY_Greek_sigma },
- { "Greek_finalsmallsigma", XKB_KEY_Greek_finalsmallsigma },
- { "Greek_tau", XKB_KEY_Greek_tau },
- { "Greek_upsilon", XKB_KEY_Greek_upsilon },
- { "Greek_phi", XKB_KEY_Greek_phi },
- { "Greek_chi", XKB_KEY_Greek_chi },
- { "Greek_psi", XKB_KEY_Greek_psi },
- { "Greek_omega", XKB_KEY_Greek_omega },
- { "leftradical", XKB_KEY_leftradical },
- { "topleftradical", XKB_KEY_topleftradical },
- { "horizconnector", XKB_KEY_horizconnector },
- { "topintegral", XKB_KEY_topintegral },
- { "botintegral", XKB_KEY_botintegral },
- { "vertconnector", XKB_KEY_vertconnector },
- { "topleftsqbracket", XKB_KEY_topleftsqbracket },
- { "botleftsqbracket", XKB_KEY_botleftsqbracket },
- { "toprightsqbracket", XKB_KEY_toprightsqbracket },
- { "botrightsqbracket", XKB_KEY_botrightsqbracket },
- { "topleftparens", XKB_KEY_topleftparens },
- { "botleftparens", XKB_KEY_botleftparens },
- { "toprightparens", XKB_KEY_toprightparens },
- { "botrightparens", XKB_KEY_botrightparens },
- { "leftmiddlecurlybrace", XKB_KEY_leftmiddlecurlybrace },
- { "rightmiddlecurlybrace", XKB_KEY_rightmiddlecurlybrace },
- { "topleftsummation", XKB_KEY_topleftsummation },
- { "botleftsummation", XKB_KEY_botleftsummation },
- { "topvertsummationconnector", XKB_KEY_topvertsummationconnector },
- { "botvertsummationconnector", XKB_KEY_botvertsummationconnector },
- { "toprightsummation", XKB_KEY_toprightsummation },
- { "botrightsummation", XKB_KEY_botrightsummation },
- { "rightmiddlesummation", XKB_KEY_rightmiddlesummation },
- { "lessthanequal", XKB_KEY_lessthanequal },
- { "notequal", XKB_KEY_notequal },
- { "greaterthanequal", XKB_KEY_greaterthanequal },
- { "integral", XKB_KEY_integral },
- { "therefore", XKB_KEY_therefore },
- { "variation", XKB_KEY_variation },
- { "infinity", XKB_KEY_infinity },
- { "nabla", XKB_KEY_nabla },
- { "approximate", XKB_KEY_approximate },
- { "similarequal", XKB_KEY_similarequal },
- { "ifonlyif", XKB_KEY_ifonlyif },
- { "implies", XKB_KEY_implies },
- { "identical", XKB_KEY_identical },
- { "radical", XKB_KEY_radical },
- { "includedin", XKB_KEY_includedin },
- { "includes", XKB_KEY_includes },
- { "intersection", XKB_KEY_intersection },
- { "union", XKB_KEY_union },
- { "logicaland", XKB_KEY_logicaland },
- { "logicalor", XKB_KEY_logicalor },
- { "partialderivative", XKB_KEY_partialderivative },
- { "function", XKB_KEY_function },
- { "leftarrow", XKB_KEY_leftarrow },
- { "uparrow", XKB_KEY_uparrow },
- { "rightarrow", XKB_KEY_rightarrow },
- { "downarrow", XKB_KEY_downarrow },
- { "blank", XKB_KEY_blank },
- { "soliddiamond", XKB_KEY_soliddiamond },
- { "checkerboard", XKB_KEY_checkerboard },
- { "ht", XKB_KEY_ht },
- { "ff", XKB_KEY_ff },
- { "cr", XKB_KEY_cr },
- { "lf", XKB_KEY_lf },
- { "nl", XKB_KEY_nl },
- { "vt", XKB_KEY_vt },
- { "lowrightcorner", XKB_KEY_lowrightcorner },
- { "uprightcorner", XKB_KEY_uprightcorner },
- { "upleftcorner", XKB_KEY_upleftcorner },
- { "lowleftcorner", XKB_KEY_lowleftcorner },
- { "crossinglines", XKB_KEY_crossinglines },
- { "horizlinescan1", XKB_KEY_horizlinescan1 },
- { "horizlinescan3", XKB_KEY_horizlinescan3 },
- { "horizlinescan5", XKB_KEY_horizlinescan5 },
- { "horizlinescan7", XKB_KEY_horizlinescan7 },
- { "horizlinescan9", XKB_KEY_horizlinescan9 },
- { "leftt", XKB_KEY_leftt },
- { "rightt", XKB_KEY_rightt },
- { "bott", XKB_KEY_bott },
- { "topt", XKB_KEY_topt },
- { "vertbar", XKB_KEY_vertbar },
- { "emspace", XKB_KEY_emspace },
- { "enspace", XKB_KEY_enspace },
- { "em3space", XKB_KEY_em3space },
- { "em4space", XKB_KEY_em4space },
- { "digitspace", XKB_KEY_digitspace },
- { "punctspace", XKB_KEY_punctspace },
- { "thinspace", XKB_KEY_thinspace },
- { "hairspace", XKB_KEY_hairspace },
- { "emdash", XKB_KEY_emdash },
- { "endash", XKB_KEY_endash },
- { "signifblank", XKB_KEY_signifblank },
- { "ellipsis", XKB_KEY_ellipsis },
- { "doubbaselinedot", XKB_KEY_doubbaselinedot },
- { "onethird", XKB_KEY_onethird },
- { "twothirds", XKB_KEY_twothirds },
- { "onefifth", XKB_KEY_onefifth },
- { "twofifths", XKB_KEY_twofifths },
- { "threefifths", XKB_KEY_threefifths },
- { "fourfifths", XKB_KEY_fourfifths },
- { "onesixth", XKB_KEY_onesixth },
- { "fivesixths", XKB_KEY_fivesixths },
- { "careof", XKB_KEY_careof },
- { "figdash", XKB_KEY_figdash },
- { "leftanglebracket", XKB_KEY_leftanglebracket },
- { "decimalpoint", XKB_KEY_decimalpoint },
- { "rightanglebracket", XKB_KEY_rightanglebracket },
- { "marker", XKB_KEY_marker },
- { "oneeighth", XKB_KEY_oneeighth },
- { "threeeighths", XKB_KEY_threeeighths },
- { "fiveeighths", XKB_KEY_fiveeighths },
- { "seveneighths", XKB_KEY_seveneighths },
- { "trademark", XKB_KEY_trademark },
- { "signaturemark", XKB_KEY_signaturemark },
- { "trademarkincircle", XKB_KEY_trademarkincircle },
- { "leftopentriangle", XKB_KEY_leftopentriangle },
- { "rightopentriangle", XKB_KEY_rightopentriangle },
- { "emopencircle", XKB_KEY_emopencircle },
- { "emopenrectangle", XKB_KEY_emopenrectangle },
- { "leftsinglequotemark", XKB_KEY_leftsinglequotemark },
- { "rightsinglequotemark", XKB_KEY_rightsinglequotemark },
- { "leftdoublequotemark", XKB_KEY_leftdoublequotemark },
- { "rightdoublequotemark", XKB_KEY_rightdoublequotemark },
- { "prescription", XKB_KEY_prescription },
- { "permille", XKB_KEY_permille },
- { "minutes", XKB_KEY_minutes },
- { "seconds", XKB_KEY_seconds },
- { "latincross", XKB_KEY_latincross },
- { "hexagram", XKB_KEY_hexagram },
- { "filledrectbullet", XKB_KEY_filledrectbullet },
- { "filledlefttribullet", XKB_KEY_filledlefttribullet },
- { "filledrighttribullet", XKB_KEY_filledrighttribullet },
- { "emfilledcircle", XKB_KEY_emfilledcircle },
- { "emfilledrect", XKB_KEY_emfilledrect },
- { "enopencircbullet", XKB_KEY_enopencircbullet },
- { "enopensquarebullet", XKB_KEY_enopensquarebullet },
- { "openrectbullet", XKB_KEY_openrectbullet },
- { "opentribulletup", XKB_KEY_opentribulletup },
- { "opentribulletdown", XKB_KEY_opentribulletdown },
- { "openstar", XKB_KEY_openstar },
- { "enfilledcircbullet", XKB_KEY_enfilledcircbullet },
- { "enfilledsqbullet", XKB_KEY_enfilledsqbullet },
- { "filledtribulletup", XKB_KEY_filledtribulletup },
- { "filledtribulletdown", XKB_KEY_filledtribulletdown },
- { "leftpointer", XKB_KEY_leftpointer },
- { "rightpointer", XKB_KEY_rightpointer },
- { "club", XKB_KEY_club },
- { "diamond", XKB_KEY_diamond },
- { "heart", XKB_KEY_heart },
- { "maltesecross", XKB_KEY_maltesecross },
- { "dagger", XKB_KEY_dagger },
- { "doubledagger", XKB_KEY_doubledagger },
- { "checkmark", XKB_KEY_checkmark },
- { "ballotcross", XKB_KEY_ballotcross },
- { "musicalsharp", XKB_KEY_musicalsharp },
- { "musicalflat", XKB_KEY_musicalflat },
- { "malesymbol", XKB_KEY_malesymbol },
- { "femalesymbol", XKB_KEY_femalesymbol },
- { "telephone", XKB_KEY_telephone },
- { "telephonerecorder", XKB_KEY_telephonerecorder },
- { "phonographcopyright", XKB_KEY_phonographcopyright },
- { "caret", XKB_KEY_caret },
- { "singlelowquotemark", XKB_KEY_singlelowquotemark },
- { "doublelowquotemark", XKB_KEY_doublelowquotemark },
- { "cursor", XKB_KEY_cursor },
- { "leftcaret", XKB_KEY_leftcaret },
- { "rightcaret", XKB_KEY_rightcaret },
- { "downcaret", XKB_KEY_downcaret },
- { "upcaret", XKB_KEY_upcaret },
- { "overbar", XKB_KEY_overbar },
- { "downtack", XKB_KEY_downtack },
- { "upshoe", XKB_KEY_upshoe },
- { "downstile", XKB_KEY_downstile },
- { "underbar", XKB_KEY_underbar },
- { "jot", XKB_KEY_jot },
- { "quad", XKB_KEY_quad },
- { "uptack", XKB_KEY_uptack },
- { "circle", XKB_KEY_circle },
- { "upstile", XKB_KEY_upstile },
- { "downshoe", XKB_KEY_downshoe },
- { "rightshoe", XKB_KEY_rightshoe },
- { "leftshoe", XKB_KEY_leftshoe },
- { "lefttack", XKB_KEY_lefttack },
- { "righttack", XKB_KEY_righttack },
- { "hebrew_doublelowline", XKB_KEY_hebrew_doublelowline },
- { "hebrew_aleph", XKB_KEY_hebrew_aleph },
- { "hebrew_bet", XKB_KEY_hebrew_bet },
- { "hebrew_gimel", XKB_KEY_hebrew_gimel },
- { "hebrew_dalet", XKB_KEY_hebrew_dalet },
- { "hebrew_he", XKB_KEY_hebrew_he },
- { "hebrew_waw", XKB_KEY_hebrew_waw },
- { "hebrew_zain", XKB_KEY_hebrew_zain },
- { "hebrew_chet", XKB_KEY_hebrew_chet },
- { "hebrew_tet", XKB_KEY_hebrew_tet },
- { "hebrew_yod", XKB_KEY_hebrew_yod },
- { "hebrew_finalkaph", XKB_KEY_hebrew_finalkaph },
- { "hebrew_kaph", XKB_KEY_hebrew_kaph },
- { "hebrew_lamed", XKB_KEY_hebrew_lamed },
- { "hebrew_finalmem", XKB_KEY_hebrew_finalmem },
- { "hebrew_mem", XKB_KEY_hebrew_mem },
- { "hebrew_finalnun", XKB_KEY_hebrew_finalnun },
- { "hebrew_nun", XKB_KEY_hebrew_nun },
- { "hebrew_samech", XKB_KEY_hebrew_samech },
- { "hebrew_ayin", XKB_KEY_hebrew_ayin },
- { "hebrew_finalpe", XKB_KEY_hebrew_finalpe },
- { "hebrew_pe", XKB_KEY_hebrew_pe },
- { "hebrew_finalzade", XKB_KEY_hebrew_finalzade },
- { "hebrew_zade", XKB_KEY_hebrew_zade },
- { "hebrew_qoph", XKB_KEY_hebrew_qoph },
- { "hebrew_resh", XKB_KEY_hebrew_resh },
- { "hebrew_shin", XKB_KEY_hebrew_shin },
- { "hebrew_taw", XKB_KEY_hebrew_taw },
- { "Thai_kokai", XKB_KEY_Thai_kokai },
- { "Thai_khokhai", XKB_KEY_Thai_khokhai },
- { "Thai_khokhuat", XKB_KEY_Thai_khokhuat },
- { "Thai_khokhwai", XKB_KEY_Thai_khokhwai },
- { "Thai_khokhon", XKB_KEY_Thai_khokhon },
- { "Thai_khorakhang", XKB_KEY_Thai_khorakhang },
- { "Thai_ngongu", XKB_KEY_Thai_ngongu },
- { "Thai_chochan", XKB_KEY_Thai_chochan },
- { "Thai_choching", XKB_KEY_Thai_choching },
- { "Thai_chochang", XKB_KEY_Thai_chochang },
- { "Thai_soso", XKB_KEY_Thai_soso },
- { "Thai_chochoe", XKB_KEY_Thai_chochoe },
- { "Thai_yoying", XKB_KEY_Thai_yoying },
- { "Thai_dochada", XKB_KEY_Thai_dochada },
- { "Thai_topatak", XKB_KEY_Thai_topatak },
- { "Thai_thothan", XKB_KEY_Thai_thothan },
- { "Thai_thonangmontho", XKB_KEY_Thai_thonangmontho },
- { "Thai_thophuthao", XKB_KEY_Thai_thophuthao },
- { "Thai_nonen", XKB_KEY_Thai_nonen },
- { "Thai_dodek", XKB_KEY_Thai_dodek },
- { "Thai_totao", XKB_KEY_Thai_totao },
- { "Thai_thothung", XKB_KEY_Thai_thothung },
- { "Thai_thothahan", XKB_KEY_Thai_thothahan },
- { "Thai_thothong", XKB_KEY_Thai_thothong },
- { "Thai_nonu", XKB_KEY_Thai_nonu },
- { "Thai_bobaimai", XKB_KEY_Thai_bobaimai },
- { "Thai_popla", XKB_KEY_Thai_popla },
- { "Thai_phophung", XKB_KEY_Thai_phophung },
- { "Thai_fofa", XKB_KEY_Thai_fofa },
- { "Thai_phophan", XKB_KEY_Thai_phophan },
- { "Thai_fofan", XKB_KEY_Thai_fofan },
- { "Thai_phosamphao", XKB_KEY_Thai_phosamphao },
- { "Thai_moma", XKB_KEY_Thai_moma },
- { "Thai_yoyak", XKB_KEY_Thai_yoyak },
- { "Thai_rorua", XKB_KEY_Thai_rorua },
- { "Thai_ru", XKB_KEY_Thai_ru },
- { "Thai_loling", XKB_KEY_Thai_loling },
- { "Thai_lu", XKB_KEY_Thai_lu },
- { "Thai_wowaen", XKB_KEY_Thai_wowaen },
- { "Thai_sosala", XKB_KEY_Thai_sosala },
- { "Thai_sorusi", XKB_KEY_Thai_sorusi },
- { "Thai_sosua", XKB_KEY_Thai_sosua },
- { "Thai_hohip", XKB_KEY_Thai_hohip },
- { "Thai_lochula", XKB_KEY_Thai_lochula },
- { "Thai_oang", XKB_KEY_Thai_oang },
- { "Thai_honokhuk", XKB_KEY_Thai_honokhuk },
- { "Thai_paiyannoi", XKB_KEY_Thai_paiyannoi },
- { "Thai_saraa", XKB_KEY_Thai_saraa },
- { "Thai_maihanakat", XKB_KEY_Thai_maihanakat },
- { "Thai_saraaa", XKB_KEY_Thai_saraaa },
- { "Thai_saraam", XKB_KEY_Thai_saraam },
- { "Thai_sarai", XKB_KEY_Thai_sarai },
- { "Thai_saraii", XKB_KEY_Thai_saraii },
- { "Thai_saraue", XKB_KEY_Thai_saraue },
- { "Thai_sarauee", XKB_KEY_Thai_sarauee },
- { "Thai_sarau", XKB_KEY_Thai_sarau },
- { "Thai_sarauu", XKB_KEY_Thai_sarauu },
- { "Thai_phinthu", XKB_KEY_Thai_phinthu },
- { "Thai_maihanakat_maitho", XKB_KEY_Thai_maihanakat_maitho },
- { "Thai_baht", XKB_KEY_Thai_baht },
- { "Thai_sarae", XKB_KEY_Thai_sarae },
- { "Thai_saraae", XKB_KEY_Thai_saraae },
- { "Thai_sarao", XKB_KEY_Thai_sarao },
- { "Thai_saraaimaimuan", XKB_KEY_Thai_saraaimaimuan },
- { "Thai_saraaimaimalai", XKB_KEY_Thai_saraaimaimalai },
- { "Thai_lakkhangyao", XKB_KEY_Thai_lakkhangyao },
- { "Thai_maiyamok", XKB_KEY_Thai_maiyamok },
- { "Thai_maitaikhu", XKB_KEY_Thai_maitaikhu },
- { "Thai_maiek", XKB_KEY_Thai_maiek },
- { "Thai_maitho", XKB_KEY_Thai_maitho },
- { "Thai_maitri", XKB_KEY_Thai_maitri },
- { "Thai_maichattawa", XKB_KEY_Thai_maichattawa },
- { "Thai_thanthakhat", XKB_KEY_Thai_thanthakhat },
- { "Thai_nikhahit", XKB_KEY_Thai_nikhahit },
- { "Thai_leksun", XKB_KEY_Thai_leksun },
- { "Thai_leknung", XKB_KEY_Thai_leknung },
- { "Thai_leksong", XKB_KEY_Thai_leksong },
- { "Thai_leksam", XKB_KEY_Thai_leksam },
- { "Thai_leksi", XKB_KEY_Thai_leksi },
- { "Thai_lekha", XKB_KEY_Thai_lekha },
- { "Thai_lekhok", XKB_KEY_Thai_lekhok },
- { "Thai_lekchet", XKB_KEY_Thai_lekchet },
- { "Thai_lekpaet", XKB_KEY_Thai_lekpaet },
- { "Thai_lekkao", XKB_KEY_Thai_lekkao },
- { "Hangul_Kiyeog", XKB_KEY_Hangul_Kiyeog },
- { "Hangul_SsangKiyeog", XKB_KEY_Hangul_SsangKiyeog },
- { "Hangul_KiyeogSios", XKB_KEY_Hangul_KiyeogSios },
- { "Hangul_Nieun", XKB_KEY_Hangul_Nieun },
- { "Hangul_NieunJieuj", XKB_KEY_Hangul_NieunJieuj },
- { "Hangul_NieunHieuh", XKB_KEY_Hangul_NieunHieuh },
- { "Hangul_Dikeud", XKB_KEY_Hangul_Dikeud },
- { "Hangul_SsangDikeud", XKB_KEY_Hangul_SsangDikeud },
- { "Hangul_Rieul", XKB_KEY_Hangul_Rieul },
- { "Hangul_RieulKiyeog", XKB_KEY_Hangul_RieulKiyeog },
- { "Hangul_RieulMieum", XKB_KEY_Hangul_RieulMieum },
- { "Hangul_RieulPieub", XKB_KEY_Hangul_RieulPieub },
- { "Hangul_RieulSios", XKB_KEY_Hangul_RieulSios },
- { "Hangul_RieulTieut", XKB_KEY_Hangul_RieulTieut },
- { "Hangul_RieulPhieuf", XKB_KEY_Hangul_RieulPhieuf },
- { "Hangul_RieulHieuh", XKB_KEY_Hangul_RieulHieuh },
- { "Hangul_Mieum", XKB_KEY_Hangul_Mieum },
- { "Hangul_Pieub", XKB_KEY_Hangul_Pieub },
- { "Hangul_SsangPieub", XKB_KEY_Hangul_SsangPieub },
- { "Hangul_PieubSios", XKB_KEY_Hangul_PieubSios },
- { "Hangul_Sios", XKB_KEY_Hangul_Sios },
- { "Hangul_SsangSios", XKB_KEY_Hangul_SsangSios },
- { "Hangul_Ieung", XKB_KEY_Hangul_Ieung },
- { "Hangul_Jieuj", XKB_KEY_Hangul_Jieuj },
- { "Hangul_SsangJieuj", XKB_KEY_Hangul_SsangJieuj },
- { "Hangul_Cieuc", XKB_KEY_Hangul_Cieuc },
- { "Hangul_Khieuq", XKB_KEY_Hangul_Khieuq },
- { "Hangul_Tieut", XKB_KEY_Hangul_Tieut },
- { "Hangul_Phieuf", XKB_KEY_Hangul_Phieuf },
- { "Hangul_Hieuh", XKB_KEY_Hangul_Hieuh },
- { "Hangul_A", XKB_KEY_Hangul_A },
- { "Hangul_AE", XKB_KEY_Hangul_AE },
- { "Hangul_YA", XKB_KEY_Hangul_YA },
- { "Hangul_YAE", XKB_KEY_Hangul_YAE },
- { "Hangul_EO", XKB_KEY_Hangul_EO },
- { "Hangul_E", XKB_KEY_Hangul_E },
- { "Hangul_YEO", XKB_KEY_Hangul_YEO },
- { "Hangul_YE", XKB_KEY_Hangul_YE },
- { "Hangul_O", XKB_KEY_Hangul_O },
- { "Hangul_WA", XKB_KEY_Hangul_WA },
- { "Hangul_WAE", XKB_KEY_Hangul_WAE },
- { "Hangul_OE", XKB_KEY_Hangul_OE },
- { "Hangul_YO", XKB_KEY_Hangul_YO },
- { "Hangul_U", XKB_KEY_Hangul_U },
- { "Hangul_WEO", XKB_KEY_Hangul_WEO },
- { "Hangul_WE", XKB_KEY_Hangul_WE },
- { "Hangul_WI", XKB_KEY_Hangul_WI },
- { "Hangul_YU", XKB_KEY_Hangul_YU },
- { "Hangul_EU", XKB_KEY_Hangul_EU },
- { "Hangul_YI", XKB_KEY_Hangul_YI },
- { "Hangul_I", XKB_KEY_Hangul_I },
- { "Hangul_J_Kiyeog", XKB_KEY_Hangul_J_Kiyeog },
- { "Hangul_J_SsangKiyeog", XKB_KEY_Hangul_J_SsangKiyeog },
- { "Hangul_J_KiyeogSios", XKB_KEY_Hangul_J_KiyeogSios },
- { "Hangul_J_Nieun", XKB_KEY_Hangul_J_Nieun },
- { "Hangul_J_NieunJieuj", XKB_KEY_Hangul_J_NieunJieuj },
- { "Hangul_J_NieunHieuh", XKB_KEY_Hangul_J_NieunHieuh },
- { "Hangul_J_Dikeud", XKB_KEY_Hangul_J_Dikeud },
- { "Hangul_J_Rieul", XKB_KEY_Hangul_J_Rieul },
- { "Hangul_J_RieulKiyeog", XKB_KEY_Hangul_J_RieulKiyeog },
- { "Hangul_J_RieulMieum", XKB_KEY_Hangul_J_RieulMieum },
- { "Hangul_J_RieulPieub", XKB_KEY_Hangul_J_RieulPieub },
- { "Hangul_J_RieulSios", XKB_KEY_Hangul_J_RieulSios },
- { "Hangul_J_RieulTieut", XKB_KEY_Hangul_J_RieulTieut },
- { "Hangul_J_RieulPhieuf", XKB_KEY_Hangul_J_RieulPhieuf },
- { "Hangul_J_RieulHieuh", XKB_KEY_Hangul_J_RieulHieuh },
- { "Hangul_J_Mieum", XKB_KEY_Hangul_J_Mieum },
- { "Hangul_J_Pieub", XKB_KEY_Hangul_J_Pieub },
- { "Hangul_J_PieubSios", XKB_KEY_Hangul_J_PieubSios },
- { "Hangul_J_Sios", XKB_KEY_Hangul_J_Sios },
- { "Hangul_J_SsangSios", XKB_KEY_Hangul_J_SsangSios },
- { "Hangul_J_Ieung", XKB_KEY_Hangul_J_Ieung },
- { "Hangul_J_Jieuj", XKB_KEY_Hangul_J_Jieuj },
- { "Hangul_J_Cieuc", XKB_KEY_Hangul_J_Cieuc },
- { "Hangul_J_Khieuq", XKB_KEY_Hangul_J_Khieuq },
- { "Hangul_J_Tieut", XKB_KEY_Hangul_J_Tieut },
- { "Hangul_J_Phieuf", XKB_KEY_Hangul_J_Phieuf },
- { "Hangul_J_Hieuh", XKB_KEY_Hangul_J_Hieuh },
- { "Hangul_RieulYeorinHieuh", XKB_KEY_Hangul_RieulYeorinHieuh },
- { "Hangul_SunkyeongeumMieum", XKB_KEY_Hangul_SunkyeongeumMieum },
- { "Hangul_SunkyeongeumPieub", XKB_KEY_Hangul_SunkyeongeumPieub },
- { "Hangul_PanSios", XKB_KEY_Hangul_PanSios },
- { "Hangul_KkogjiDalrinIeung", XKB_KEY_Hangul_KkogjiDalrinIeung },
- { "Hangul_SunkyeongeumPhieuf", XKB_KEY_Hangul_SunkyeongeumPhieuf },
- { "Hangul_YeorinHieuh", XKB_KEY_Hangul_YeorinHieuh },
- { "Hangul_AraeA", XKB_KEY_Hangul_AraeA },
- { "Hangul_AraeAE", XKB_KEY_Hangul_AraeAE },
- { "Hangul_J_PanSios", XKB_KEY_Hangul_J_PanSios },
- { "Hangul_J_KkogjiDalrinIeung", XKB_KEY_Hangul_J_KkogjiDalrinIeung },
- { "Hangul_J_YeorinHieuh", XKB_KEY_Hangul_J_YeorinHieuh },
- { "Korean_Won", XKB_KEY_Korean_Won },
- { "OE", XKB_KEY_OE },
- { "oe", XKB_KEY_oe },
- { "Ydiaeresis", XKB_KEY_Ydiaeresis },
- { "EuroSign", XKB_KEY_EuroSign },
- { "3270_Duplicate", XKB_KEY_3270_Duplicate },
- { "3270_FieldMark", XKB_KEY_3270_FieldMark },
- { "3270_Right2", XKB_KEY_3270_Right2 },
- { "3270_Left2", XKB_KEY_3270_Left2 },
- { "3270_BackTab", XKB_KEY_3270_BackTab },
- { "3270_EraseEOF", XKB_KEY_3270_EraseEOF },
- { "3270_EraseInput", XKB_KEY_3270_EraseInput },
- { "3270_Reset", XKB_KEY_3270_Reset },
- { "3270_Quit", XKB_KEY_3270_Quit },
- { "3270_PA1", XKB_KEY_3270_PA1 },
- { "3270_PA2", XKB_KEY_3270_PA2 },
- { "3270_PA3", XKB_KEY_3270_PA3 },
- { "3270_Test", XKB_KEY_3270_Test },
- { "3270_Attn", XKB_KEY_3270_Attn },
- { "3270_CursorBlink", XKB_KEY_3270_CursorBlink },
- { "3270_AltCursor", XKB_KEY_3270_AltCursor },
- { "3270_KeyClick", XKB_KEY_3270_KeyClick },
- { "3270_Jump", XKB_KEY_3270_Jump },
- { "3270_Ident", XKB_KEY_3270_Ident },
- { "3270_Rule", XKB_KEY_3270_Rule },
- { "3270_Copy", XKB_KEY_3270_Copy },
- { "3270_Play", XKB_KEY_3270_Play },
- { "3270_Setup", XKB_KEY_3270_Setup },
- { "3270_Record", XKB_KEY_3270_Record },
- { "3270_ChangeScreen", XKB_KEY_3270_ChangeScreen },
- { "3270_DeleteWord", XKB_KEY_3270_DeleteWord },
- { "3270_ExSelect", XKB_KEY_3270_ExSelect },
- { "3270_CursorSelect", XKB_KEY_3270_CursorSelect },
- { "3270_PrintScreen", XKB_KEY_3270_PrintScreen },
- { "3270_Enter", XKB_KEY_3270_Enter },
- { "ISO_Lock", XKB_KEY_ISO_Lock },
- { "ISO_Level2_Latch", XKB_KEY_ISO_Level2_Latch },
- { "ISO_Level3_Shift", XKB_KEY_ISO_Level3_Shift },
- { "ISO_Level3_Latch", XKB_KEY_ISO_Level3_Latch },
- { "ISO_Level3_Lock", XKB_KEY_ISO_Level3_Lock },
- { "ISO_Group_Latch", XKB_KEY_ISO_Group_Latch },
- { "ISO_Group_Lock", XKB_KEY_ISO_Group_Lock },
- { "ISO_Next_Group", XKB_KEY_ISO_Next_Group },
- { "ISO_Next_Group_Lock", XKB_KEY_ISO_Next_Group_Lock },
- { "ISO_Prev_Group", XKB_KEY_ISO_Prev_Group },
- { "ISO_Prev_Group_Lock", XKB_KEY_ISO_Prev_Group_Lock },
- { "ISO_First_Group", XKB_KEY_ISO_First_Group },
- { "ISO_First_Group_Lock", XKB_KEY_ISO_First_Group_Lock },
- { "ISO_Last_Group", XKB_KEY_ISO_Last_Group },
- { "ISO_Last_Group_Lock", XKB_KEY_ISO_Last_Group_Lock },
- { "ISO_Level5_Shift", XKB_KEY_ISO_Level5_Shift },
- { "ISO_Level5_Latch", XKB_KEY_ISO_Level5_Latch },
- { "ISO_Level5_Lock", XKB_KEY_ISO_Level5_Lock },
- { "ISO_Left_Tab", XKB_KEY_ISO_Left_Tab },
- { "ISO_Move_Line_Up", XKB_KEY_ISO_Move_Line_Up },
- { "ISO_Move_Line_Down", XKB_KEY_ISO_Move_Line_Down },
- { "ISO_Partial_Line_Up", XKB_KEY_ISO_Partial_Line_Up },
- { "ISO_Partial_Line_Down", XKB_KEY_ISO_Partial_Line_Down },
- { "ISO_Partial_Space_Left", XKB_KEY_ISO_Partial_Space_Left },
- { "ISO_Partial_Space_Right", XKB_KEY_ISO_Partial_Space_Right },
- { "ISO_Set_Margin_Left", XKB_KEY_ISO_Set_Margin_Left },
- { "ISO_Set_Margin_Right", XKB_KEY_ISO_Set_Margin_Right },
- { "ISO_Release_Margin_Left", XKB_KEY_ISO_Release_Margin_Left },
- { "ISO_Release_Margin_Right", XKB_KEY_ISO_Release_Margin_Right },
- { "ISO_Release_Both_Margins", XKB_KEY_ISO_Release_Both_Margins },
- { "ISO_Fast_Cursor_Left", XKB_KEY_ISO_Fast_Cursor_Left },
- { "ISO_Fast_Cursor_Right", XKB_KEY_ISO_Fast_Cursor_Right },
- { "ISO_Fast_Cursor_Up", XKB_KEY_ISO_Fast_Cursor_Up },
- { "ISO_Fast_Cursor_Down", XKB_KEY_ISO_Fast_Cursor_Down },
- { "ISO_Continuous_Underline", XKB_KEY_ISO_Continuous_Underline },
- { "ISO_Discontinuous_Underline", XKB_KEY_ISO_Discontinuous_Underline },
- { "ISO_Emphasize", XKB_KEY_ISO_Emphasize },
- { "ISO_Center_Object", XKB_KEY_ISO_Center_Object },
- { "ISO_Enter", XKB_KEY_ISO_Enter },
- { "dead_grave", XKB_KEY_dead_grave },
- { "dead_acute", XKB_KEY_dead_acute },
- { "dead_circumflex", XKB_KEY_dead_circumflex },
- { "dead_tilde", XKB_KEY_dead_tilde },
- { "dead_macron", XKB_KEY_dead_macron },
- { "dead_breve", XKB_KEY_dead_breve },
- { "dead_abovedot", XKB_KEY_dead_abovedot },
- { "dead_diaeresis", XKB_KEY_dead_diaeresis },
- { "dead_abovering", XKB_KEY_dead_abovering },
- { "dead_doubleacute", XKB_KEY_dead_doubleacute },
- { "dead_caron", XKB_KEY_dead_caron },
- { "dead_cedilla", XKB_KEY_dead_cedilla },
- { "dead_ogonek", XKB_KEY_dead_ogonek },
- { "dead_iota", XKB_KEY_dead_iota },
- { "dead_voiced_sound", XKB_KEY_dead_voiced_sound },
- { "dead_semivoiced_sound", XKB_KEY_dead_semivoiced_sound },
- { "dead_belowdot", XKB_KEY_dead_belowdot },
- { "dead_hook", XKB_KEY_dead_hook },
- { "dead_horn", XKB_KEY_dead_horn },
- { "dead_stroke", XKB_KEY_dead_stroke },
- { "dead_abovecomma", XKB_KEY_dead_abovecomma },
- { "dead_abovereversedcomma", XKB_KEY_dead_abovereversedcomma },
- { "dead_doublegrave", XKB_KEY_dead_doublegrave },
- { "dead_belowring", XKB_KEY_dead_belowring },
- { "dead_belowmacron", XKB_KEY_dead_belowmacron },
- { "dead_belowcircumflex", XKB_KEY_dead_belowcircumflex },
- { "dead_belowtilde", XKB_KEY_dead_belowtilde },
- { "dead_belowbreve", XKB_KEY_dead_belowbreve },
- { "dead_belowdiaeresis", XKB_KEY_dead_belowdiaeresis },
- { "dead_invertedbreve", XKB_KEY_dead_invertedbreve },
- { "dead_belowcomma", XKB_KEY_dead_belowcomma },
- { "dead_currency", XKB_KEY_dead_currency },
- { "AccessX_Enable", XKB_KEY_AccessX_Enable },
- { "AccessX_Feedback_Enable", XKB_KEY_AccessX_Feedback_Enable },
- { "RepeatKeys_Enable", XKB_KEY_RepeatKeys_Enable },
- { "SlowKeys_Enable", XKB_KEY_SlowKeys_Enable },
- { "BounceKeys_Enable", XKB_KEY_BounceKeys_Enable },
- { "StickyKeys_Enable", XKB_KEY_StickyKeys_Enable },
- { "MouseKeys_Enable", XKB_KEY_MouseKeys_Enable },
- { "MouseKeys_Accel_Enable", XKB_KEY_MouseKeys_Accel_Enable },
- { "Overlay1_Enable", XKB_KEY_Overlay1_Enable },
- { "Overlay2_Enable", XKB_KEY_Overlay2_Enable },
- { "AudibleBell_Enable", XKB_KEY_AudibleBell_Enable },
- { "dead_a", XKB_KEY_dead_a },
- { "dead_A", XKB_KEY_dead_A },
- { "dead_e", XKB_KEY_dead_e },
- { "dead_E", XKB_KEY_dead_E },
- { "dead_i", XKB_KEY_dead_i },
- { "dead_I", XKB_KEY_dead_I },
- { "dead_o", XKB_KEY_dead_o },
- { "dead_O", XKB_KEY_dead_O },
- { "dead_u", XKB_KEY_dead_u },
- { "dead_U", XKB_KEY_dead_U },
- { "dead_small_schwa", XKB_KEY_dead_small_schwa },
- { "dead_capital_schwa", XKB_KEY_dead_capital_schwa },
- { "dead_greek", XKB_KEY_dead_greek },
- { "ch", XKB_KEY_ch },
- { "Ch", XKB_KEY_Ch },
- { "CH", XKB_KEY_CH },
- { "c_h", XKB_KEY_c_h },
- { "C_h", XKB_KEY_C_h },
- { "C_H", XKB_KEY_C_H },
- { "First_Virtual_Screen", XKB_KEY_First_Virtual_Screen },
- { "Prev_Virtual_Screen", XKB_KEY_Prev_Virtual_Screen },
- { "Next_Virtual_Screen", XKB_KEY_Next_Virtual_Screen },
- { "Last_Virtual_Screen", XKB_KEY_Last_Virtual_Screen },
- { "Terminate_Server", XKB_KEY_Terminate_Server },
- { "Pointer_Left", XKB_KEY_Pointer_Left },
- { "Pointer_Right", XKB_KEY_Pointer_Right },
- { "Pointer_Up", XKB_KEY_Pointer_Up },
- { "Pointer_Down", XKB_KEY_Pointer_Down },
- { "Pointer_UpLeft", XKB_KEY_Pointer_UpLeft },
- { "Pointer_UpRight", XKB_KEY_Pointer_UpRight },
- { "Pointer_DownLeft", XKB_KEY_Pointer_DownLeft },
- { "Pointer_DownRight", XKB_KEY_Pointer_DownRight },
- { "Pointer_Button_Dflt", XKB_KEY_Pointer_Button_Dflt },
- { "Pointer_Button1", XKB_KEY_Pointer_Button1 },
- { "Pointer_Button2", XKB_KEY_Pointer_Button2 },
- { "Pointer_Button3", XKB_KEY_Pointer_Button3 },
- { "Pointer_Button4", XKB_KEY_Pointer_Button4 },
- { "Pointer_Button5", XKB_KEY_Pointer_Button5 },
- { "Pointer_DblClick_Dflt", XKB_KEY_Pointer_DblClick_Dflt },
- { "Pointer_DblClick1", XKB_KEY_Pointer_DblClick1 },
- { "Pointer_DblClick2", XKB_KEY_Pointer_DblClick2 },
- { "Pointer_DblClick3", XKB_KEY_Pointer_DblClick3 },
- { "Pointer_DblClick4", XKB_KEY_Pointer_DblClick4 },
- { "Pointer_DblClick5", XKB_KEY_Pointer_DblClick5 },
- { "Pointer_Drag_Dflt", XKB_KEY_Pointer_Drag_Dflt },
- { "Pointer_Drag1", XKB_KEY_Pointer_Drag1 },
- { "Pointer_Drag2", XKB_KEY_Pointer_Drag2 },
- { "Pointer_Drag3", XKB_KEY_Pointer_Drag3 },
- { "Pointer_Drag4", XKB_KEY_Pointer_Drag4 },
- { "Pointer_EnableKeys", XKB_KEY_Pointer_EnableKeys },
- { "Pointer_Accelerate", XKB_KEY_Pointer_Accelerate },
- { "Pointer_DfltBtnNext", XKB_KEY_Pointer_DfltBtnNext },
- { "Pointer_DfltBtnPrev", XKB_KEY_Pointer_DfltBtnPrev },
- { "Pointer_Drag5", XKB_KEY_Pointer_Drag5 },
- { "BackSpace", XKB_KEY_BackSpace },
- { "Tab", XKB_KEY_Tab },
- { "Linefeed", XKB_KEY_Linefeed },
- { "Clear", XKB_KEY_Clear },
- { "Return", XKB_KEY_Return },
- { "Pause", XKB_KEY_Pause },
- { "Scroll_Lock", XKB_KEY_Scroll_Lock },
- { "Sys_Req", XKB_KEY_Sys_Req },
- { "Escape", XKB_KEY_Escape },
- { "Multi_key", XKB_KEY_Multi_key },
- { "Kanji", XKB_KEY_Kanji },
- { "Muhenkan", XKB_KEY_Muhenkan },
- { "Henkan_Mode", XKB_KEY_Henkan_Mode },
- { "Romaji", XKB_KEY_Romaji },
- { "Hiragana", XKB_KEY_Hiragana },
- { "Katakana", XKB_KEY_Katakana },
- { "Hiragana_Katakana", XKB_KEY_Hiragana_Katakana },
- { "Zenkaku", XKB_KEY_Zenkaku },
- { "Hankaku", XKB_KEY_Hankaku },
- { "Zenkaku_Hankaku", XKB_KEY_Zenkaku_Hankaku },
- { "Touroku", XKB_KEY_Touroku },
- { "Massyo", XKB_KEY_Massyo },
- { "Kana_Lock", XKB_KEY_Kana_Lock },
- { "Kana_Shift", XKB_KEY_Kana_Shift },
- { "Eisu_Shift", XKB_KEY_Eisu_Shift },
- { "Eisu_toggle", XKB_KEY_Eisu_toggle },
- { "Hangul", XKB_KEY_Hangul },
- { "Hangul_Start", XKB_KEY_Hangul_Start },
- { "Hangul_End", XKB_KEY_Hangul_End },
- { "Hangul_Hanja", XKB_KEY_Hangul_Hanja },
- { "Hangul_Jamo", XKB_KEY_Hangul_Jamo },
- { "Hangul_Romaja", XKB_KEY_Hangul_Romaja },
- { "Codeinput", XKB_KEY_Codeinput },
- { "Hangul_Jeonja", XKB_KEY_Hangul_Jeonja },
- { "Hangul_Banja", XKB_KEY_Hangul_Banja },
- { "Hangul_PreHanja", XKB_KEY_Hangul_PreHanja },
- { "Hangul_PostHanja", XKB_KEY_Hangul_PostHanja },
- { "SingleCandidate", XKB_KEY_SingleCandidate },
- { "MultipleCandidate", XKB_KEY_MultipleCandidate },
- { "PreviousCandidate", XKB_KEY_PreviousCandidate },
- { "Hangul_Special", XKB_KEY_Hangul_Special },
- { "Home", XKB_KEY_Home },
- { "Left", XKB_KEY_Left },
- { "Up", XKB_KEY_Up },
- { "Right", XKB_KEY_Right },
- { "Down", XKB_KEY_Down },
- { "Prior", XKB_KEY_Prior },
- { "Next", XKB_KEY_Next },
- { "End", XKB_KEY_End },
- { "Begin", XKB_KEY_Begin },
- { "Select", XKB_KEY_Select },
- { "Print", XKB_KEY_Print },
- { "Execute", XKB_KEY_Execute },
- { "Insert", XKB_KEY_Insert },
- { "Undo", XKB_KEY_Undo },
- { "Redo", XKB_KEY_Redo },
- { "Menu", XKB_KEY_Menu },
- { "Find", XKB_KEY_Find },
- { "Cancel", XKB_KEY_Cancel },
- { "Help", XKB_KEY_Help },
- { "Break", XKB_KEY_Break },
- { "Mode_switch", XKB_KEY_Mode_switch },
- { "Num_Lock", XKB_KEY_Num_Lock },
- { "KP_Space", XKB_KEY_KP_Space },
- { "KP_Tab", XKB_KEY_KP_Tab },
- { "KP_Enter", XKB_KEY_KP_Enter },
- { "KP_F1", XKB_KEY_KP_F1 },
- { "KP_F2", XKB_KEY_KP_F2 },
- { "KP_F3", XKB_KEY_KP_F3 },
- { "KP_F4", XKB_KEY_KP_F4 },
- { "KP_Home", XKB_KEY_KP_Home },
- { "KP_Left", XKB_KEY_KP_Left },
- { "KP_Up", XKB_KEY_KP_Up },
- { "KP_Right", XKB_KEY_KP_Right },
- { "KP_Down", XKB_KEY_KP_Down },
- { "KP_Prior", XKB_KEY_KP_Prior },
- { "KP_Next", XKB_KEY_KP_Next },
- { "KP_End", XKB_KEY_KP_End },
- { "KP_Begin", XKB_KEY_KP_Begin },
- { "KP_Insert", XKB_KEY_KP_Insert },
- { "KP_Delete", XKB_KEY_KP_Delete },
- { "KP_Multiply", XKB_KEY_KP_Multiply },
- { "KP_Add", XKB_KEY_KP_Add },
- { "KP_Separator", XKB_KEY_KP_Separator },
- { "KP_Subtract", XKB_KEY_KP_Subtract },
- { "KP_Decimal", XKB_KEY_KP_Decimal },
- { "KP_Divide", XKB_KEY_KP_Divide },
- { "KP_0", XKB_KEY_KP_0 },
- { "KP_1", XKB_KEY_KP_1 },
- { "KP_2", XKB_KEY_KP_2 },
- { "KP_3", XKB_KEY_KP_3 },
- { "KP_4", XKB_KEY_KP_4 },
- { "KP_5", XKB_KEY_KP_5 },
- { "KP_6", XKB_KEY_KP_6 },
- { "KP_7", XKB_KEY_KP_7 },
- { "KP_8", XKB_KEY_KP_8 },
- { "KP_9", XKB_KEY_KP_9 },
- { "KP_Equal", XKB_KEY_KP_Equal },
- { "F1", XKB_KEY_F1 },
- { "F2", XKB_KEY_F2 },
- { "F3", XKB_KEY_F3 },
- { "F4", XKB_KEY_F4 },
- { "F5", XKB_KEY_F5 },
- { "F6", XKB_KEY_F6 },
- { "F7", XKB_KEY_F7 },
- { "F8", XKB_KEY_F8 },
- { "F9", XKB_KEY_F9 },
- { "F10", XKB_KEY_F10 },
- { "F11", XKB_KEY_F11 },
- { "F12", XKB_KEY_F12 },
- { "F13", XKB_KEY_F13 },
- { "F14", XKB_KEY_F14 },
- { "F15", XKB_KEY_F15 },
- { "F16", XKB_KEY_F16 },
- { "F17", XKB_KEY_F17 },
- { "F18", XKB_KEY_F18 },
- { "F19", XKB_KEY_F19 },
- { "F20", XKB_KEY_F20 },
- { "F21", XKB_KEY_F21 },
- { "F22", XKB_KEY_F22 },
- { "F23", XKB_KEY_F23 },
- { "F24", XKB_KEY_F24 },
- { "F25", XKB_KEY_F25 },
- { "F26", XKB_KEY_F26 },
- { "F27", XKB_KEY_F27 },
- { "F28", XKB_KEY_F28 },
- { "F29", XKB_KEY_F29 },
- { "F30", XKB_KEY_F30 },
- { "F31", XKB_KEY_F31 },
- { "F32", XKB_KEY_F32 },
- { "F33", XKB_KEY_F33 },
- { "F34", XKB_KEY_F34 },
- { "F35", XKB_KEY_F35 },
- { "Shift_L", XKB_KEY_Shift_L },
- { "Shift_R", XKB_KEY_Shift_R },
- { "Control_L", XKB_KEY_Control_L },
- { "Control_R", XKB_KEY_Control_R },
- { "Caps_Lock", XKB_KEY_Caps_Lock },
- { "Shift_Lock", XKB_KEY_Shift_Lock },
- { "Meta_L", XKB_KEY_Meta_L },
- { "Meta_R", XKB_KEY_Meta_R },
- { "Alt_L", XKB_KEY_Alt_L },
- { "Alt_R", XKB_KEY_Alt_R },
- { "Super_L", XKB_KEY_Super_L },
- { "Super_R", XKB_KEY_Super_R },
- { "Hyper_L", XKB_KEY_Hyper_L },
- { "Hyper_R", XKB_KEY_Hyper_R },
- { "braille_dot_1", XKB_KEY_braille_dot_1 },
- { "braille_dot_2", XKB_KEY_braille_dot_2 },
- { "braille_dot_3", XKB_KEY_braille_dot_3 },
- { "braille_dot_4", XKB_KEY_braille_dot_4 },
- { "braille_dot_5", XKB_KEY_braille_dot_5 },
- { "braille_dot_6", XKB_KEY_braille_dot_6 },
- { "braille_dot_7", XKB_KEY_braille_dot_7 },
- { "braille_dot_8", XKB_KEY_braille_dot_8 },
- { "braille_dot_9", XKB_KEY_braille_dot_9 },
- { "braille_dot_10", XKB_KEY_braille_dot_10 },
- { "Delete", XKB_KEY_Delete },
- { "VoidSymbol", XKB_KEY_VoidSymbol },
- { "Ibreve", XKB_KEY_Ibreve },
- { "ibreve", XKB_KEY_ibreve },
- { "Wcircumflex", XKB_KEY_Wcircumflex },
- { "wcircumflex", XKB_KEY_wcircumflex },
- { "Ycircumflex", XKB_KEY_Ycircumflex },
- { "ycircumflex", XKB_KEY_ycircumflex },
- { "SCHWA", XKB_KEY_SCHWA },
- { "Obarred", XKB_KEY_Obarred },
- { "Ohorn", XKB_KEY_Ohorn },
- { "ohorn", XKB_KEY_ohorn },
- { "Uhorn", XKB_KEY_Uhorn },
- { "uhorn", XKB_KEY_uhorn },
- { "Zstroke", XKB_KEY_Zstroke },
- { "zstroke", XKB_KEY_zstroke },
- { "EZH", XKB_KEY_EZH },
- { "Ocaron", XKB_KEY_Ocaron },
- { "ocaron", XKB_KEY_ocaron },
- { "Gcaron", XKB_KEY_Gcaron },
- { "gcaron", XKB_KEY_gcaron },
- { "schwa", XKB_KEY_schwa },
- { "obarred", XKB_KEY_obarred },
- { "ezh", XKB_KEY_ezh },
- { "Cyrillic_GHE_bar", XKB_KEY_Cyrillic_GHE_bar },
- { "Cyrillic_ghe_bar", XKB_KEY_Cyrillic_ghe_bar },
- { "Cyrillic_ZHE_descender", XKB_KEY_Cyrillic_ZHE_descender },
- { "Cyrillic_zhe_descender", XKB_KEY_Cyrillic_zhe_descender },
- { "Cyrillic_KA_descender", XKB_KEY_Cyrillic_KA_descender },
- { "Cyrillic_ka_descender", XKB_KEY_Cyrillic_ka_descender },
- { "Cyrillic_KA_vertstroke", XKB_KEY_Cyrillic_KA_vertstroke },
- { "Cyrillic_ka_vertstroke", XKB_KEY_Cyrillic_ka_vertstroke },
- { "Cyrillic_EN_descender", XKB_KEY_Cyrillic_EN_descender },
- { "Cyrillic_en_descender", XKB_KEY_Cyrillic_en_descender },
- { "Cyrillic_U_straight", XKB_KEY_Cyrillic_U_straight },
- { "Cyrillic_u_straight", XKB_KEY_Cyrillic_u_straight },
- { "Cyrillic_U_straight_bar", XKB_KEY_Cyrillic_U_straight_bar },
- { "Cyrillic_u_straight_bar", XKB_KEY_Cyrillic_u_straight_bar },
- { "Cyrillic_HA_descender", XKB_KEY_Cyrillic_HA_descender },
- { "Cyrillic_ha_descender", XKB_KEY_Cyrillic_ha_descender },
- { "Cyrillic_CHE_descender", XKB_KEY_Cyrillic_CHE_descender },
- { "Cyrillic_che_descender", XKB_KEY_Cyrillic_che_descender },
- { "Cyrillic_CHE_vertstroke", XKB_KEY_Cyrillic_CHE_vertstroke },
- { "Cyrillic_che_vertstroke", XKB_KEY_Cyrillic_che_vertstroke },
- { "Cyrillic_SHHA", XKB_KEY_Cyrillic_SHHA },
- { "Cyrillic_shha", XKB_KEY_Cyrillic_shha },
- { "Cyrillic_SCHWA", XKB_KEY_Cyrillic_SCHWA },
- { "Cyrillic_schwa", XKB_KEY_Cyrillic_schwa },
- { "Cyrillic_I_macron", XKB_KEY_Cyrillic_I_macron },
- { "Cyrillic_i_macron", XKB_KEY_Cyrillic_i_macron },
- { "Cyrillic_O_bar", XKB_KEY_Cyrillic_O_bar },
- { "Cyrillic_o_bar", XKB_KEY_Cyrillic_o_bar },
- { "Cyrillic_U_macron", XKB_KEY_Cyrillic_U_macron },
- { "Cyrillic_u_macron", XKB_KEY_Cyrillic_u_macron },
- { "Armenian_AYB", XKB_KEY_Armenian_AYB },
- { "Armenian_BEN", XKB_KEY_Armenian_BEN },
- { "Armenian_GIM", XKB_KEY_Armenian_GIM },
- { "Armenian_DA", XKB_KEY_Armenian_DA },
- { "Armenian_YECH", XKB_KEY_Armenian_YECH },
- { "Armenian_ZA", XKB_KEY_Armenian_ZA },
- { "Armenian_E", XKB_KEY_Armenian_E },
- { "Armenian_AT", XKB_KEY_Armenian_AT },
- { "Armenian_TO", XKB_KEY_Armenian_TO },
- { "Armenian_ZHE", XKB_KEY_Armenian_ZHE },
- { "Armenian_INI", XKB_KEY_Armenian_INI },
- { "Armenian_LYUN", XKB_KEY_Armenian_LYUN },
- { "Armenian_KHE", XKB_KEY_Armenian_KHE },
- { "Armenian_TSA", XKB_KEY_Armenian_TSA },
- { "Armenian_KEN", XKB_KEY_Armenian_KEN },
- { "Armenian_HO", XKB_KEY_Armenian_HO },
- { "Armenian_DZA", XKB_KEY_Armenian_DZA },
- { "Armenian_GHAT", XKB_KEY_Armenian_GHAT },
- { "Armenian_TCHE", XKB_KEY_Armenian_TCHE },
- { "Armenian_MEN", XKB_KEY_Armenian_MEN },
- { "Armenian_HI", XKB_KEY_Armenian_HI },
- { "Armenian_NU", XKB_KEY_Armenian_NU },
- { "Armenian_SHA", XKB_KEY_Armenian_SHA },
- { "Armenian_VO", XKB_KEY_Armenian_VO },
- { "Armenian_CHA", XKB_KEY_Armenian_CHA },
- { "Armenian_PE", XKB_KEY_Armenian_PE },
- { "Armenian_JE", XKB_KEY_Armenian_JE },
- { "Armenian_RA", XKB_KEY_Armenian_RA },
- { "Armenian_SE", XKB_KEY_Armenian_SE },
- { "Armenian_VEV", XKB_KEY_Armenian_VEV },
- { "Armenian_TYUN", XKB_KEY_Armenian_TYUN },
- { "Armenian_RE", XKB_KEY_Armenian_RE },
- { "Armenian_TSO", XKB_KEY_Armenian_TSO },
- { "Armenian_VYUN", XKB_KEY_Armenian_VYUN },
- { "Armenian_PYUR", XKB_KEY_Armenian_PYUR },
- { "Armenian_KE", XKB_KEY_Armenian_KE },
- { "Armenian_O", XKB_KEY_Armenian_O },
- { "Armenian_FE", XKB_KEY_Armenian_FE },
- { "Armenian_apostrophe", XKB_KEY_Armenian_apostrophe },
- { "Armenian_accent", XKB_KEY_Armenian_accent },
- { "Armenian_exclam", XKB_KEY_Armenian_exclam },
- { "Armenian_separation_mark", XKB_KEY_Armenian_separation_mark },
- { "Armenian_question", XKB_KEY_Armenian_question },
- { "Armenian_ayb", XKB_KEY_Armenian_ayb },
- { "Armenian_ben", XKB_KEY_Armenian_ben },
- { "Armenian_gim", XKB_KEY_Armenian_gim },
- { "Armenian_da", XKB_KEY_Armenian_da },
- { "Armenian_yech", XKB_KEY_Armenian_yech },
- { "Armenian_za", XKB_KEY_Armenian_za },
- { "Armenian_e", XKB_KEY_Armenian_e },
- { "Armenian_at", XKB_KEY_Armenian_at },
- { "Armenian_to", XKB_KEY_Armenian_to },
- { "Armenian_zhe", XKB_KEY_Armenian_zhe },
- { "Armenian_ini", XKB_KEY_Armenian_ini },
- { "Armenian_lyun", XKB_KEY_Armenian_lyun },
- { "Armenian_khe", XKB_KEY_Armenian_khe },
- { "Armenian_tsa", XKB_KEY_Armenian_tsa },
- { "Armenian_ken", XKB_KEY_Armenian_ken },
- { "Armenian_ho", XKB_KEY_Armenian_ho },
- { "Armenian_dza", XKB_KEY_Armenian_dza },
- { "Armenian_ghat", XKB_KEY_Armenian_ghat },
- { "Armenian_tche", XKB_KEY_Armenian_tche },
- { "Armenian_men", XKB_KEY_Armenian_men },
- { "Armenian_hi", XKB_KEY_Armenian_hi },
- { "Armenian_nu", XKB_KEY_Armenian_nu },
- { "Armenian_sha", XKB_KEY_Armenian_sha },
- { "Armenian_vo", XKB_KEY_Armenian_vo },
- { "Armenian_cha", XKB_KEY_Armenian_cha },
- { "Armenian_pe", XKB_KEY_Armenian_pe },
- { "Armenian_je", XKB_KEY_Armenian_je },
- { "Armenian_ra", XKB_KEY_Armenian_ra },
- { "Armenian_se", XKB_KEY_Armenian_se },
- { "Armenian_vev", XKB_KEY_Armenian_vev },
- { "Armenian_tyun", XKB_KEY_Armenian_tyun },
- { "Armenian_re", XKB_KEY_Armenian_re },
- { "Armenian_tso", XKB_KEY_Armenian_tso },
- { "Armenian_vyun", XKB_KEY_Armenian_vyun },
- { "Armenian_pyur", XKB_KEY_Armenian_pyur },
- { "Armenian_ke", XKB_KEY_Armenian_ke },
- { "Armenian_o", XKB_KEY_Armenian_o },
- { "Armenian_fe", XKB_KEY_Armenian_fe },
- { "Armenian_ligature_ew", XKB_KEY_Armenian_ligature_ew },
- { "Armenian_full_stop", XKB_KEY_Armenian_full_stop },
- { "Armenian_hyphen", XKB_KEY_Armenian_hyphen },
- { "Arabic_madda_above", XKB_KEY_Arabic_madda_above },
- { "Arabic_hamza_above", XKB_KEY_Arabic_hamza_above },
- { "Arabic_hamza_below", XKB_KEY_Arabic_hamza_below },
- { "Arabic_0", XKB_KEY_Arabic_0 },
- { "Arabic_1", XKB_KEY_Arabic_1 },
- { "Arabic_2", XKB_KEY_Arabic_2 },
- { "Arabic_3", XKB_KEY_Arabic_3 },
- { "Arabic_4", XKB_KEY_Arabic_4 },
- { "Arabic_5", XKB_KEY_Arabic_5 },
- { "Arabic_6", XKB_KEY_Arabic_6 },
- { "Arabic_7", XKB_KEY_Arabic_7 },
- { "Arabic_8", XKB_KEY_Arabic_8 },
- { "Arabic_9", XKB_KEY_Arabic_9 },
- { "Arabic_percent", XKB_KEY_Arabic_percent },
- { "Arabic_superscript_alef", XKB_KEY_Arabic_superscript_alef },
- { "Arabic_tteh", XKB_KEY_Arabic_tteh },
- { "Arabic_peh", XKB_KEY_Arabic_peh },
- { "Arabic_tcheh", XKB_KEY_Arabic_tcheh },
- { "Arabic_ddal", XKB_KEY_Arabic_ddal },
- { "Arabic_rreh", XKB_KEY_Arabic_rreh },
- { "Arabic_jeh", XKB_KEY_Arabic_jeh },
- { "Arabic_veh", XKB_KEY_Arabic_veh },
- { "Arabic_keheh", XKB_KEY_Arabic_keheh },
- { "Arabic_gaf", XKB_KEY_Arabic_gaf },
- { "Arabic_noon_ghunna", XKB_KEY_Arabic_noon_ghunna },
- { "Arabic_heh_doachashmee", XKB_KEY_Arabic_heh_doachashmee },
- { "Arabic_heh_goal", XKB_KEY_Arabic_heh_goal },
- { "Farsi_yeh", XKB_KEY_Farsi_yeh },
- { "Arabic_yeh_baree", XKB_KEY_Arabic_yeh_baree },
- { "Arabic_fullstop", XKB_KEY_Arabic_fullstop },
- { "Farsi_0", XKB_KEY_Farsi_0 },
- { "Farsi_1", XKB_KEY_Farsi_1 },
- { "Farsi_2", XKB_KEY_Farsi_2 },
- { "Farsi_3", XKB_KEY_Farsi_3 },
- { "Farsi_4", XKB_KEY_Farsi_4 },
- { "Farsi_5", XKB_KEY_Farsi_5 },
- { "Farsi_6", XKB_KEY_Farsi_6 },
- { "Farsi_7", XKB_KEY_Farsi_7 },
- { "Farsi_8", XKB_KEY_Farsi_8 },
- { "Farsi_9", XKB_KEY_Farsi_9 },
- { "Sinh_ng", XKB_KEY_Sinh_ng },
- { "Sinh_h2", XKB_KEY_Sinh_h2 },
- { "Sinh_a", XKB_KEY_Sinh_a },
- { "Sinh_aa", XKB_KEY_Sinh_aa },
- { "Sinh_ae", XKB_KEY_Sinh_ae },
- { "Sinh_aee", XKB_KEY_Sinh_aee },
- { "Sinh_i", XKB_KEY_Sinh_i },
- { "Sinh_ii", XKB_KEY_Sinh_ii },
- { "Sinh_u", XKB_KEY_Sinh_u },
- { "Sinh_uu", XKB_KEY_Sinh_uu },
- { "Sinh_ri", XKB_KEY_Sinh_ri },
- { "Sinh_rii", XKB_KEY_Sinh_rii },
- { "Sinh_lu", XKB_KEY_Sinh_lu },
- { "Sinh_luu", XKB_KEY_Sinh_luu },
- { "Sinh_e", XKB_KEY_Sinh_e },
- { "Sinh_ee", XKB_KEY_Sinh_ee },
- { "Sinh_ai", XKB_KEY_Sinh_ai },
- { "Sinh_o", XKB_KEY_Sinh_o },
- { "Sinh_oo", XKB_KEY_Sinh_oo },
- { "Sinh_au", XKB_KEY_Sinh_au },
- { "Sinh_ka", XKB_KEY_Sinh_ka },
- { "Sinh_kha", XKB_KEY_Sinh_kha },
- { "Sinh_ga", XKB_KEY_Sinh_ga },
- { "Sinh_gha", XKB_KEY_Sinh_gha },
- { "Sinh_ng2", XKB_KEY_Sinh_ng2 },
- { "Sinh_nga", XKB_KEY_Sinh_nga },
- { "Sinh_ca", XKB_KEY_Sinh_ca },
- { "Sinh_cha", XKB_KEY_Sinh_cha },
- { "Sinh_ja", XKB_KEY_Sinh_ja },
- { "Sinh_jha", XKB_KEY_Sinh_jha },
- { "Sinh_nya", XKB_KEY_Sinh_nya },
- { "Sinh_jnya", XKB_KEY_Sinh_jnya },
- { "Sinh_nja", XKB_KEY_Sinh_nja },
- { "Sinh_tta", XKB_KEY_Sinh_tta },
- { "Sinh_ttha", XKB_KEY_Sinh_ttha },
- { "Sinh_dda", XKB_KEY_Sinh_dda },
- { "Sinh_ddha", XKB_KEY_Sinh_ddha },
- { "Sinh_nna", XKB_KEY_Sinh_nna },
- { "Sinh_ndda", XKB_KEY_Sinh_ndda },
- { "Sinh_tha", XKB_KEY_Sinh_tha },
- { "Sinh_thha", XKB_KEY_Sinh_thha },
- { "Sinh_dha", XKB_KEY_Sinh_dha },
- { "Sinh_dhha", XKB_KEY_Sinh_dhha },
- { "Sinh_na", XKB_KEY_Sinh_na },
- { "Sinh_ndha", XKB_KEY_Sinh_ndha },
- { "Sinh_pa", XKB_KEY_Sinh_pa },
- { "Sinh_pha", XKB_KEY_Sinh_pha },
- { "Sinh_ba", XKB_KEY_Sinh_ba },
- { "Sinh_bha", XKB_KEY_Sinh_bha },
- { "Sinh_ma", XKB_KEY_Sinh_ma },
- { "Sinh_mba", XKB_KEY_Sinh_mba },
- { "Sinh_ya", XKB_KEY_Sinh_ya },
- { "Sinh_ra", XKB_KEY_Sinh_ra },
- { "Sinh_la", XKB_KEY_Sinh_la },
- { "Sinh_va", XKB_KEY_Sinh_va },
- { "Sinh_sha", XKB_KEY_Sinh_sha },
- { "Sinh_ssha", XKB_KEY_Sinh_ssha },
- { "Sinh_sa", XKB_KEY_Sinh_sa },
- { "Sinh_ha", XKB_KEY_Sinh_ha },
- { "Sinh_lla", XKB_KEY_Sinh_lla },
- { "Sinh_fa", XKB_KEY_Sinh_fa },
- { "Sinh_al", XKB_KEY_Sinh_al },
- { "Sinh_aa2", XKB_KEY_Sinh_aa2 },
- { "Sinh_ae2", XKB_KEY_Sinh_ae2 },
- { "Sinh_aee2", XKB_KEY_Sinh_aee2 },
- { "Sinh_i2", XKB_KEY_Sinh_i2 },
- { "Sinh_ii2", XKB_KEY_Sinh_ii2 },
- { "Sinh_u2", XKB_KEY_Sinh_u2 },
- { "Sinh_uu2", XKB_KEY_Sinh_uu2 },
- { "Sinh_ru2", XKB_KEY_Sinh_ru2 },
- { "Sinh_e2", XKB_KEY_Sinh_e2 },
- { "Sinh_ee2", XKB_KEY_Sinh_ee2 },
- { "Sinh_ai2", XKB_KEY_Sinh_ai2 },
- { "Sinh_o2", XKB_KEY_Sinh_o2 },
- { "Sinh_oo2", XKB_KEY_Sinh_oo2 },
- { "Sinh_au2", XKB_KEY_Sinh_au2 },
- { "Sinh_lu2", XKB_KEY_Sinh_lu2 },
- { "Sinh_ruu2", XKB_KEY_Sinh_ruu2 },
- { "Sinh_luu2", XKB_KEY_Sinh_luu2 },
- { "Sinh_kunddaliya", XKB_KEY_Sinh_kunddaliya },
- { "Georgian_an", XKB_KEY_Georgian_an },
- { "Georgian_ban", XKB_KEY_Georgian_ban },
- { "Georgian_gan", XKB_KEY_Georgian_gan },
- { "Georgian_don", XKB_KEY_Georgian_don },
- { "Georgian_en", XKB_KEY_Georgian_en },
- { "Georgian_vin", XKB_KEY_Georgian_vin },
- { "Georgian_zen", XKB_KEY_Georgian_zen },
- { "Georgian_tan", XKB_KEY_Georgian_tan },
- { "Georgian_in", XKB_KEY_Georgian_in },
- { "Georgian_kan", XKB_KEY_Georgian_kan },
- { "Georgian_las", XKB_KEY_Georgian_las },
- { "Georgian_man", XKB_KEY_Georgian_man },
- { "Georgian_nar", XKB_KEY_Georgian_nar },
- { "Georgian_on", XKB_KEY_Georgian_on },
- { "Georgian_par", XKB_KEY_Georgian_par },
- { "Georgian_zhar", XKB_KEY_Georgian_zhar },
- { "Georgian_rae", XKB_KEY_Georgian_rae },
- { "Georgian_san", XKB_KEY_Georgian_san },
- { "Georgian_tar", XKB_KEY_Georgian_tar },
- { "Georgian_un", XKB_KEY_Georgian_un },
- { "Georgian_phar", XKB_KEY_Georgian_phar },
- { "Georgian_khar", XKB_KEY_Georgian_khar },
- { "Georgian_ghan", XKB_KEY_Georgian_ghan },
- { "Georgian_qar", XKB_KEY_Georgian_qar },
- { "Georgian_shin", XKB_KEY_Georgian_shin },
- { "Georgian_chin", XKB_KEY_Georgian_chin },
- { "Georgian_can", XKB_KEY_Georgian_can },
- { "Georgian_jil", XKB_KEY_Georgian_jil },
- { "Georgian_cil", XKB_KEY_Georgian_cil },
- { "Georgian_char", XKB_KEY_Georgian_char },
- { "Georgian_xan", XKB_KEY_Georgian_xan },
- { "Georgian_jhan", XKB_KEY_Georgian_jhan },
- { "Georgian_hae", XKB_KEY_Georgian_hae },
- { "Georgian_he", XKB_KEY_Georgian_he },
- { "Georgian_hie", XKB_KEY_Georgian_hie },
- { "Georgian_we", XKB_KEY_Georgian_we },
- { "Georgian_har", XKB_KEY_Georgian_har },
- { "Georgian_hoe", XKB_KEY_Georgian_hoe },
- { "Georgian_fi", XKB_KEY_Georgian_fi },
- { "Babovedot", XKB_KEY_Babovedot },
- { "babovedot", XKB_KEY_babovedot },
- { "Dabovedot", XKB_KEY_Dabovedot },
- { "dabovedot", XKB_KEY_dabovedot },
- { "Fabovedot", XKB_KEY_Fabovedot },
- { "fabovedot", XKB_KEY_fabovedot },
- { "Lbelowdot", XKB_KEY_Lbelowdot },
- { "lbelowdot", XKB_KEY_lbelowdot },
- { "Mabovedot", XKB_KEY_Mabovedot },
- { "mabovedot", XKB_KEY_mabovedot },
- { "Pabovedot", XKB_KEY_Pabovedot },
- { "pabovedot", XKB_KEY_pabovedot },
- { "Sabovedot", XKB_KEY_Sabovedot },
- { "sabovedot", XKB_KEY_sabovedot },
- { "Tabovedot", XKB_KEY_Tabovedot },
- { "tabovedot", XKB_KEY_tabovedot },
- { "Wgrave", XKB_KEY_Wgrave },
- { "wgrave", XKB_KEY_wgrave },
- { "Wacute", XKB_KEY_Wacute },
- { "wacute", XKB_KEY_wacute },
- { "Wdiaeresis", XKB_KEY_Wdiaeresis },
- { "wdiaeresis", XKB_KEY_wdiaeresis },
- { "Xabovedot", XKB_KEY_Xabovedot },
- { "xabovedot", XKB_KEY_xabovedot },
- { "Abelowdot", XKB_KEY_Abelowdot },
- { "abelowdot", XKB_KEY_abelowdot },
- { "Ahook", XKB_KEY_Ahook },
- { "ahook", XKB_KEY_ahook },
- { "Acircumflexacute", XKB_KEY_Acircumflexacute },
- { "acircumflexacute", XKB_KEY_acircumflexacute },
- { "Acircumflexgrave", XKB_KEY_Acircumflexgrave },
- { "acircumflexgrave", XKB_KEY_acircumflexgrave },
- { "Acircumflexhook", XKB_KEY_Acircumflexhook },
- { "acircumflexhook", XKB_KEY_acircumflexhook },
- { "Acircumflextilde", XKB_KEY_Acircumflextilde },
- { "acircumflextilde", XKB_KEY_acircumflextilde },
- { "Acircumflexbelowdot", XKB_KEY_Acircumflexbelowdot },
- { "acircumflexbelowdot", XKB_KEY_acircumflexbelowdot },
- { "Abreveacute", XKB_KEY_Abreveacute },
- { "abreveacute", XKB_KEY_abreveacute },
- { "Abrevegrave", XKB_KEY_Abrevegrave },
- { "abrevegrave", XKB_KEY_abrevegrave },
- { "Abrevehook", XKB_KEY_Abrevehook },
- { "abrevehook", XKB_KEY_abrevehook },
- { "Abrevetilde", XKB_KEY_Abrevetilde },
- { "abrevetilde", XKB_KEY_abrevetilde },
- { "Abrevebelowdot", XKB_KEY_Abrevebelowdot },
- { "abrevebelowdot", XKB_KEY_abrevebelowdot },
- { "Ebelowdot", XKB_KEY_Ebelowdot },
- { "ebelowdot", XKB_KEY_ebelowdot },
- { "Ehook", XKB_KEY_Ehook },
- { "ehook", XKB_KEY_ehook },
- { "Etilde", XKB_KEY_Etilde },
- { "etilde", XKB_KEY_etilde },
- { "Ecircumflexacute", XKB_KEY_Ecircumflexacute },
- { "ecircumflexacute", XKB_KEY_ecircumflexacute },
- { "Ecircumflexgrave", XKB_KEY_Ecircumflexgrave },
- { "ecircumflexgrave", XKB_KEY_ecircumflexgrave },
- { "Ecircumflexhook", XKB_KEY_Ecircumflexhook },
- { "ecircumflexhook", XKB_KEY_ecircumflexhook },
- { "Ecircumflextilde", XKB_KEY_Ecircumflextilde },
- { "ecircumflextilde", XKB_KEY_ecircumflextilde },
- { "Ecircumflexbelowdot", XKB_KEY_Ecircumflexbelowdot },
- { "ecircumflexbelowdot", XKB_KEY_ecircumflexbelowdot },
- { "Ihook", XKB_KEY_Ihook },
- { "ihook", XKB_KEY_ihook },
- { "Ibelowdot", XKB_KEY_Ibelowdot },
- { "ibelowdot", XKB_KEY_ibelowdot },
- { "Obelowdot", XKB_KEY_Obelowdot },
- { "obelowdot", XKB_KEY_obelowdot },
- { "Ohook", XKB_KEY_Ohook },
- { "ohook", XKB_KEY_ohook },
- { "Ocircumflexacute", XKB_KEY_Ocircumflexacute },
- { "ocircumflexacute", XKB_KEY_ocircumflexacute },
- { "Ocircumflexgrave", XKB_KEY_Ocircumflexgrave },
- { "ocircumflexgrave", XKB_KEY_ocircumflexgrave },
- { "Ocircumflexhook", XKB_KEY_Ocircumflexhook },
- { "ocircumflexhook", XKB_KEY_ocircumflexhook },
- { "Ocircumflextilde", XKB_KEY_Ocircumflextilde },
- { "ocircumflextilde", XKB_KEY_ocircumflextilde },
- { "Ocircumflexbelowdot", XKB_KEY_Ocircumflexbelowdot },
- { "ocircumflexbelowdot", XKB_KEY_ocircumflexbelowdot },
- { "Ohornacute", XKB_KEY_Ohornacute },
- { "ohornacute", XKB_KEY_ohornacute },
- { "Ohorngrave", XKB_KEY_Ohorngrave },
- { "ohorngrave", XKB_KEY_ohorngrave },
- { "Ohornhook", XKB_KEY_Ohornhook },
- { "ohornhook", XKB_KEY_ohornhook },
- { "Ohorntilde", XKB_KEY_Ohorntilde },
- { "ohorntilde", XKB_KEY_ohorntilde },
- { "Ohornbelowdot", XKB_KEY_Ohornbelowdot },
- { "ohornbelowdot", XKB_KEY_ohornbelowdot },
- { "Ubelowdot", XKB_KEY_Ubelowdot },
- { "ubelowdot", XKB_KEY_ubelowdot },
- { "Uhook", XKB_KEY_Uhook },
- { "uhook", XKB_KEY_uhook },
- { "Uhornacute", XKB_KEY_Uhornacute },
- { "uhornacute", XKB_KEY_uhornacute },
- { "Uhorngrave", XKB_KEY_Uhorngrave },
- { "uhorngrave", XKB_KEY_uhorngrave },
- { "Uhornhook", XKB_KEY_Uhornhook },
- { "uhornhook", XKB_KEY_uhornhook },
- { "Uhorntilde", XKB_KEY_Uhorntilde },
- { "uhorntilde", XKB_KEY_uhorntilde },
- { "Uhornbelowdot", XKB_KEY_Uhornbelowdot },
- { "uhornbelowdot", XKB_KEY_uhornbelowdot },
- { "Ygrave", XKB_KEY_Ygrave },
- { "ygrave", XKB_KEY_ygrave },
- { "Ybelowdot", XKB_KEY_Ybelowdot },
- { "ybelowdot", XKB_KEY_ybelowdot },
- { "Yhook", XKB_KEY_Yhook },
- { "yhook", XKB_KEY_yhook },
- { "Ytilde", XKB_KEY_Ytilde },
- { "ytilde", XKB_KEY_ytilde },
- { "zerosuperior", XKB_KEY_zerosuperior },
- { "foursuperior", XKB_KEY_foursuperior },
- { "fivesuperior", XKB_KEY_fivesuperior },
- { "sixsuperior", XKB_KEY_sixsuperior },
- { "sevensuperior", XKB_KEY_sevensuperior },
- { "eightsuperior", XKB_KEY_eightsuperior },
- { "ninesuperior", XKB_KEY_ninesuperior },
- { "zerosubscript", XKB_KEY_zerosubscript },
- { "onesubscript", XKB_KEY_onesubscript },
- { "twosubscript", XKB_KEY_twosubscript },
- { "threesubscript", XKB_KEY_threesubscript },
- { "foursubscript", XKB_KEY_foursubscript },
- { "fivesubscript", XKB_KEY_fivesubscript },
- { "sixsubscript", XKB_KEY_sixsubscript },
- { "sevensubscript", XKB_KEY_sevensubscript },
- { "eightsubscript", XKB_KEY_eightsubscript },
- { "ninesubscript", XKB_KEY_ninesubscript },
- { "EcuSign", XKB_KEY_EcuSign },
- { "ColonSign", XKB_KEY_ColonSign },
- { "CruzeiroSign", XKB_KEY_CruzeiroSign },
- { "FFrancSign", XKB_KEY_FFrancSign },
- { "LiraSign", XKB_KEY_LiraSign },
- { "MillSign", XKB_KEY_MillSign },
- { "NairaSign", XKB_KEY_NairaSign },
- { "PesetaSign", XKB_KEY_PesetaSign },
- { "RupeeSign", XKB_KEY_RupeeSign },
- { "WonSign", XKB_KEY_WonSign },
- { "NewSheqelSign", XKB_KEY_NewSheqelSign },
- { "DongSign", XKB_KEY_DongSign },
- { "partdifferential", XKB_KEY_partdifferential },
- { "emptyset", XKB_KEY_emptyset },
- { "elementof", XKB_KEY_elementof },
- { "notelementof", XKB_KEY_notelementof },
- { "containsas", XKB_KEY_containsas },
- { "squareroot", XKB_KEY_squareroot },
- { "cuberoot", XKB_KEY_cuberoot },
- { "fourthroot", XKB_KEY_fourthroot },
- { "dintegral", XKB_KEY_dintegral },
- { "tintegral", XKB_KEY_tintegral },
- { "because", XKB_KEY_because },
- { "notapproxeq", XKB_KEY_notapproxeq },
- { "approxeq", XKB_KEY_approxeq },
- { "notidentical", XKB_KEY_notidentical },
- { "stricteq", XKB_KEY_stricteq },
- { "braille_blank", XKB_KEY_braille_blank },
- { "braille_dots_1", XKB_KEY_braille_dots_1 },
- { "braille_dots_2", XKB_KEY_braille_dots_2 },
- { "braille_dots_12", XKB_KEY_braille_dots_12 },
- { "braille_dots_3", XKB_KEY_braille_dots_3 },
- { "braille_dots_13", XKB_KEY_braille_dots_13 },
- { "braille_dots_23", XKB_KEY_braille_dots_23 },
- { "braille_dots_123", XKB_KEY_braille_dots_123 },
- { "braille_dots_4", XKB_KEY_braille_dots_4 },
- { "braille_dots_14", XKB_KEY_braille_dots_14 },
- { "braille_dots_24", XKB_KEY_braille_dots_24 },
- { "braille_dots_124", XKB_KEY_braille_dots_124 },
- { "braille_dots_34", XKB_KEY_braille_dots_34 },
- { "braille_dots_134", XKB_KEY_braille_dots_134 },
- { "braille_dots_234", XKB_KEY_braille_dots_234 },
- { "braille_dots_1234", XKB_KEY_braille_dots_1234 },
- { "braille_dots_5", XKB_KEY_braille_dots_5 },
- { "braille_dots_15", XKB_KEY_braille_dots_15 },
- { "braille_dots_25", XKB_KEY_braille_dots_25 },
- { "braille_dots_125", XKB_KEY_braille_dots_125 },
- { "braille_dots_35", XKB_KEY_braille_dots_35 },
- { "braille_dots_135", XKB_KEY_braille_dots_135 },
- { "braille_dots_235", XKB_KEY_braille_dots_235 },
- { "braille_dots_1235", XKB_KEY_braille_dots_1235 },
- { "braille_dots_45", XKB_KEY_braille_dots_45 },
- { "braille_dots_145", XKB_KEY_braille_dots_145 },
- { "braille_dots_245", XKB_KEY_braille_dots_245 },
- { "braille_dots_1245", XKB_KEY_braille_dots_1245 },
- { "braille_dots_345", XKB_KEY_braille_dots_345 },
- { "braille_dots_1345", XKB_KEY_braille_dots_1345 },
- { "braille_dots_2345", XKB_KEY_braille_dots_2345 },
- { "braille_dots_12345", XKB_KEY_braille_dots_12345 },
- { "braille_dots_6", XKB_KEY_braille_dots_6 },
- { "braille_dots_16", XKB_KEY_braille_dots_16 },
- { "braille_dots_26", XKB_KEY_braille_dots_26 },
- { "braille_dots_126", XKB_KEY_braille_dots_126 },
- { "braille_dots_36", XKB_KEY_braille_dots_36 },
- { "braille_dots_136", XKB_KEY_braille_dots_136 },
- { "braille_dots_236", XKB_KEY_braille_dots_236 },
- { "braille_dots_1236", XKB_KEY_braille_dots_1236 },
- { "braille_dots_46", XKB_KEY_braille_dots_46 },
- { "braille_dots_146", XKB_KEY_braille_dots_146 },
- { "braille_dots_246", XKB_KEY_braille_dots_246 },
- { "braille_dots_1246", XKB_KEY_braille_dots_1246 },
- { "braille_dots_346", XKB_KEY_braille_dots_346 },
- { "braille_dots_1346", XKB_KEY_braille_dots_1346 },
- { "braille_dots_2346", XKB_KEY_braille_dots_2346 },
- { "braille_dots_12346", XKB_KEY_braille_dots_12346 },
- { "braille_dots_56", XKB_KEY_braille_dots_56 },
- { "braille_dots_156", XKB_KEY_braille_dots_156 },
- { "braille_dots_256", XKB_KEY_braille_dots_256 },
- { "braille_dots_1256", XKB_KEY_braille_dots_1256 },
- { "braille_dots_356", XKB_KEY_braille_dots_356 },
- { "braille_dots_1356", XKB_KEY_braille_dots_1356 },
- { "braille_dots_2356", XKB_KEY_braille_dots_2356 },
- { "braille_dots_12356", XKB_KEY_braille_dots_12356 },
- { "braille_dots_456", XKB_KEY_braille_dots_456 },
- { "braille_dots_1456", XKB_KEY_braille_dots_1456 },
- { "braille_dots_2456", XKB_KEY_braille_dots_2456 },
- { "braille_dots_12456", XKB_KEY_braille_dots_12456 },
- { "braille_dots_3456", XKB_KEY_braille_dots_3456 },
- { "braille_dots_13456", XKB_KEY_braille_dots_13456 },
- { "braille_dots_23456", XKB_KEY_braille_dots_23456 },
- { "braille_dots_123456", XKB_KEY_braille_dots_123456 },
- { "braille_dots_7", XKB_KEY_braille_dots_7 },
- { "braille_dots_17", XKB_KEY_braille_dots_17 },
- { "braille_dots_27", XKB_KEY_braille_dots_27 },
- { "braille_dots_127", XKB_KEY_braille_dots_127 },
- { "braille_dots_37", XKB_KEY_braille_dots_37 },
- { "braille_dots_137", XKB_KEY_braille_dots_137 },
- { "braille_dots_237", XKB_KEY_braille_dots_237 },
- { "braille_dots_1237", XKB_KEY_braille_dots_1237 },
- { "braille_dots_47", XKB_KEY_braille_dots_47 },
- { "braille_dots_147", XKB_KEY_braille_dots_147 },
- { "braille_dots_247", XKB_KEY_braille_dots_247 },
- { "braille_dots_1247", XKB_KEY_braille_dots_1247 },
- { "braille_dots_347", XKB_KEY_braille_dots_347 },
- { "braille_dots_1347", XKB_KEY_braille_dots_1347 },
- { "braille_dots_2347", XKB_KEY_braille_dots_2347 },
- { "braille_dots_12347", XKB_KEY_braille_dots_12347 },
- { "braille_dots_57", XKB_KEY_braille_dots_57 },
- { "braille_dots_157", XKB_KEY_braille_dots_157 },
- { "braille_dots_257", XKB_KEY_braille_dots_257 },
- { "braille_dots_1257", XKB_KEY_braille_dots_1257 },
- { "braille_dots_357", XKB_KEY_braille_dots_357 },
- { "braille_dots_1357", XKB_KEY_braille_dots_1357 },
- { "braille_dots_2357", XKB_KEY_braille_dots_2357 },
- { "braille_dots_12357", XKB_KEY_braille_dots_12357 },
- { "braille_dots_457", XKB_KEY_braille_dots_457 },
- { "braille_dots_1457", XKB_KEY_braille_dots_1457 },
- { "braille_dots_2457", XKB_KEY_braille_dots_2457 },
- { "braille_dots_12457", XKB_KEY_braille_dots_12457 },
- { "braille_dots_3457", XKB_KEY_braille_dots_3457 },
- { "braille_dots_13457", XKB_KEY_braille_dots_13457 },
- { "braille_dots_23457", XKB_KEY_braille_dots_23457 },
- { "braille_dots_123457", XKB_KEY_braille_dots_123457 },
- { "braille_dots_67", XKB_KEY_braille_dots_67 },
- { "braille_dots_167", XKB_KEY_braille_dots_167 },
- { "braille_dots_267", XKB_KEY_braille_dots_267 },
- { "braille_dots_1267", XKB_KEY_braille_dots_1267 },
- { "braille_dots_367", XKB_KEY_braille_dots_367 },
- { "braille_dots_1367", XKB_KEY_braille_dots_1367 },
- { "braille_dots_2367", XKB_KEY_braille_dots_2367 },
- { "braille_dots_12367", XKB_KEY_braille_dots_12367 },
- { "braille_dots_467", XKB_KEY_braille_dots_467 },
- { "braille_dots_1467", XKB_KEY_braille_dots_1467 },
- { "braille_dots_2467", XKB_KEY_braille_dots_2467 },
- { "braille_dots_12467", XKB_KEY_braille_dots_12467 },
- { "braille_dots_3467", XKB_KEY_braille_dots_3467 },
- { "braille_dots_13467", XKB_KEY_braille_dots_13467 },
- { "braille_dots_23467", XKB_KEY_braille_dots_23467 },
- { "braille_dots_123467", XKB_KEY_braille_dots_123467 },
- { "braille_dots_567", XKB_KEY_braille_dots_567 },
- { "braille_dots_1567", XKB_KEY_braille_dots_1567 },
- { "braille_dots_2567", XKB_KEY_braille_dots_2567 },
- { "braille_dots_12567", XKB_KEY_braille_dots_12567 },
- { "braille_dots_3567", XKB_KEY_braille_dots_3567 },
- { "braille_dots_13567", XKB_KEY_braille_dots_13567 },
- { "braille_dots_23567", XKB_KEY_braille_dots_23567 },
- { "braille_dots_123567", XKB_KEY_braille_dots_123567 },
- { "braille_dots_4567", XKB_KEY_braille_dots_4567 },
- { "braille_dots_14567", XKB_KEY_braille_dots_14567 },
- { "braille_dots_24567", XKB_KEY_braille_dots_24567 },
- { "braille_dots_124567", XKB_KEY_braille_dots_124567 },
- { "braille_dots_34567", XKB_KEY_braille_dots_34567 },
- { "braille_dots_134567", XKB_KEY_braille_dots_134567 },
- { "braille_dots_234567", XKB_KEY_braille_dots_234567 },
- { "braille_dots_1234567", XKB_KEY_braille_dots_1234567 },
- { "braille_dots_8", XKB_KEY_braille_dots_8 },
- { "braille_dots_18", XKB_KEY_braille_dots_18 },
- { "braille_dots_28", XKB_KEY_braille_dots_28 },
- { "braille_dots_128", XKB_KEY_braille_dots_128 },
- { "braille_dots_38", XKB_KEY_braille_dots_38 },
- { "braille_dots_138", XKB_KEY_braille_dots_138 },
- { "braille_dots_238", XKB_KEY_braille_dots_238 },
- { "braille_dots_1238", XKB_KEY_braille_dots_1238 },
- { "braille_dots_48", XKB_KEY_braille_dots_48 },
- { "braille_dots_148", XKB_KEY_braille_dots_148 },
- { "braille_dots_248", XKB_KEY_braille_dots_248 },
- { "braille_dots_1248", XKB_KEY_braille_dots_1248 },
- { "braille_dots_348", XKB_KEY_braille_dots_348 },
- { "braille_dots_1348", XKB_KEY_braille_dots_1348 },
- { "braille_dots_2348", XKB_KEY_braille_dots_2348 },
- { "braille_dots_12348", XKB_KEY_braille_dots_12348 },
- { "braille_dots_58", XKB_KEY_braille_dots_58 },
- { "braille_dots_158", XKB_KEY_braille_dots_158 },
- { "braille_dots_258", XKB_KEY_braille_dots_258 },
- { "braille_dots_1258", XKB_KEY_braille_dots_1258 },
- { "braille_dots_358", XKB_KEY_braille_dots_358 },
- { "braille_dots_1358", XKB_KEY_braille_dots_1358 },
- { "braille_dots_2358", XKB_KEY_braille_dots_2358 },
- { "braille_dots_12358", XKB_KEY_braille_dots_12358 },
- { "braille_dots_458", XKB_KEY_braille_dots_458 },
- { "braille_dots_1458", XKB_KEY_braille_dots_1458 },
- { "braille_dots_2458", XKB_KEY_braille_dots_2458 },
- { "braille_dots_12458", XKB_KEY_braille_dots_12458 },
- { "braille_dots_3458", XKB_KEY_braille_dots_3458 },
- { "braille_dots_13458", XKB_KEY_braille_dots_13458 },
- { "braille_dots_23458", XKB_KEY_braille_dots_23458 },
- { "braille_dots_123458", XKB_KEY_braille_dots_123458 },
- { "braille_dots_68", XKB_KEY_braille_dots_68 },
- { "braille_dots_168", XKB_KEY_braille_dots_168 },
- { "braille_dots_268", XKB_KEY_braille_dots_268 },
- { "braille_dots_1268", XKB_KEY_braille_dots_1268 },
- { "braille_dots_368", XKB_KEY_braille_dots_368 },
- { "braille_dots_1368", XKB_KEY_braille_dots_1368 },
- { "braille_dots_2368", XKB_KEY_braille_dots_2368 },
- { "braille_dots_12368", XKB_KEY_braille_dots_12368 },
- { "braille_dots_468", XKB_KEY_braille_dots_468 },
- { "braille_dots_1468", XKB_KEY_braille_dots_1468 },
- { "braille_dots_2468", XKB_KEY_braille_dots_2468 },
- { "braille_dots_12468", XKB_KEY_braille_dots_12468 },
- { "braille_dots_3468", XKB_KEY_braille_dots_3468 },
- { "braille_dots_13468", XKB_KEY_braille_dots_13468 },
- { "braille_dots_23468", XKB_KEY_braille_dots_23468 },
- { "braille_dots_123468", XKB_KEY_braille_dots_123468 },
- { "braille_dots_568", XKB_KEY_braille_dots_568 },
- { "braille_dots_1568", XKB_KEY_braille_dots_1568 },
- { "braille_dots_2568", XKB_KEY_braille_dots_2568 },
- { "braille_dots_12568", XKB_KEY_braille_dots_12568 },
- { "braille_dots_3568", XKB_KEY_braille_dots_3568 },
- { "braille_dots_13568", XKB_KEY_braille_dots_13568 },
- { "braille_dots_23568", XKB_KEY_braille_dots_23568 },
- { "braille_dots_123568", XKB_KEY_braille_dots_123568 },
- { "braille_dots_4568", XKB_KEY_braille_dots_4568 },
- { "braille_dots_14568", XKB_KEY_braille_dots_14568 },
- { "braille_dots_24568", XKB_KEY_braille_dots_24568 },
- { "braille_dots_124568", XKB_KEY_braille_dots_124568 },
- { "braille_dots_34568", XKB_KEY_braille_dots_34568 },
- { "braille_dots_134568", XKB_KEY_braille_dots_134568 },
- { "braille_dots_234568", XKB_KEY_braille_dots_234568 },
- { "braille_dots_1234568", XKB_KEY_braille_dots_1234568 },
- { "braille_dots_78", XKB_KEY_braille_dots_78 },
- { "braille_dots_178", XKB_KEY_braille_dots_178 },
- { "braille_dots_278", XKB_KEY_braille_dots_278 },
- { "braille_dots_1278", XKB_KEY_braille_dots_1278 },
- { "braille_dots_378", XKB_KEY_braille_dots_378 },
- { "braille_dots_1378", XKB_KEY_braille_dots_1378 },
- { "braille_dots_2378", XKB_KEY_braille_dots_2378 },
- { "braille_dots_12378", XKB_KEY_braille_dots_12378 },
- { "braille_dots_478", XKB_KEY_braille_dots_478 },
- { "braille_dots_1478", XKB_KEY_braille_dots_1478 },
- { "braille_dots_2478", XKB_KEY_braille_dots_2478 },
- { "braille_dots_12478", XKB_KEY_braille_dots_12478 },
- { "braille_dots_3478", XKB_KEY_braille_dots_3478 },
- { "braille_dots_13478", XKB_KEY_braille_dots_13478 },
- { "braille_dots_23478", XKB_KEY_braille_dots_23478 },
- { "braille_dots_123478", XKB_KEY_braille_dots_123478 },
- { "braille_dots_578", XKB_KEY_braille_dots_578 },
- { "braille_dots_1578", XKB_KEY_braille_dots_1578 },
- { "braille_dots_2578", XKB_KEY_braille_dots_2578 },
- { "braille_dots_12578", XKB_KEY_braille_dots_12578 },
- { "braille_dots_3578", XKB_KEY_braille_dots_3578 },
- { "braille_dots_13578", XKB_KEY_braille_dots_13578 },
- { "braille_dots_23578", XKB_KEY_braille_dots_23578 },
- { "braille_dots_123578", XKB_KEY_braille_dots_123578 },
- { "braille_dots_4578", XKB_KEY_braille_dots_4578 },
- { "braille_dots_14578", XKB_KEY_braille_dots_14578 },
- { "braille_dots_24578", XKB_KEY_braille_dots_24578 },
- { "braille_dots_124578", XKB_KEY_braille_dots_124578 },
- { "braille_dots_34578", XKB_KEY_braille_dots_34578 },
- { "braille_dots_134578", XKB_KEY_braille_dots_134578 },
- { "braille_dots_234578", XKB_KEY_braille_dots_234578 },
- { "braille_dots_1234578", XKB_KEY_braille_dots_1234578 },
- { "braille_dots_678", XKB_KEY_braille_dots_678 },
- { "braille_dots_1678", XKB_KEY_braille_dots_1678 },
- { "braille_dots_2678", XKB_KEY_braille_dots_2678 },
- { "braille_dots_12678", XKB_KEY_braille_dots_12678 },
- { "braille_dots_3678", XKB_KEY_braille_dots_3678 },
- { "braille_dots_13678", XKB_KEY_braille_dots_13678 },
- { "braille_dots_23678", XKB_KEY_braille_dots_23678 },
- { "braille_dots_123678", XKB_KEY_braille_dots_123678 },
- { "braille_dots_4678", XKB_KEY_braille_dots_4678 },
- { "braille_dots_14678", XKB_KEY_braille_dots_14678 },
- { "braille_dots_24678", XKB_KEY_braille_dots_24678 },
- { "braille_dots_124678", XKB_KEY_braille_dots_124678 },
- { "braille_dots_34678", XKB_KEY_braille_dots_34678 },
- { "braille_dots_134678", XKB_KEY_braille_dots_134678 },
- { "braille_dots_234678", XKB_KEY_braille_dots_234678 },
- { "braille_dots_1234678", XKB_KEY_braille_dots_1234678 },
- { "braille_dots_5678", XKB_KEY_braille_dots_5678 },
- { "braille_dots_15678", XKB_KEY_braille_dots_15678 },
- { "braille_dots_25678", XKB_KEY_braille_dots_25678 },
- { "braille_dots_125678", XKB_KEY_braille_dots_125678 },
- { "braille_dots_35678", XKB_KEY_braille_dots_35678 },
- { "braille_dots_135678", XKB_KEY_braille_dots_135678 },
- { "braille_dots_235678", XKB_KEY_braille_dots_235678 },
- { "braille_dots_1235678", XKB_KEY_braille_dots_1235678 },
- { "braille_dots_45678", XKB_KEY_braille_dots_45678 },
- { "braille_dots_145678", XKB_KEY_braille_dots_145678 },
- { "braille_dots_245678", XKB_KEY_braille_dots_245678 },
- { "braille_dots_1245678", XKB_KEY_braille_dots_1245678 },
- { "braille_dots_345678", XKB_KEY_braille_dots_345678 },
- { "braille_dots_1345678", XKB_KEY_braille_dots_1345678 },
- { "braille_dots_2345678", XKB_KEY_braille_dots_2345678 },
- { "braille_dots_12345678", XKB_KEY_braille_dots_12345678 },
- { "hpmute_acute", XKB_KEY_hpmute_acute },
- { "hpmute_grave", XKB_KEY_hpmute_grave },
- { "hpmute_asciicircum", XKB_KEY_hpmute_asciicircum },
- { "hpmute_diaeresis", XKB_KEY_hpmute_diaeresis },
- { "hpmute_asciitilde", XKB_KEY_hpmute_asciitilde },
- { "hplira", XKB_KEY_hplira },
- { "hpguilder", XKB_KEY_hpguilder },
- { "hpYdiaeresis", XKB_KEY_hpYdiaeresis },
- { "hplongminus", XKB_KEY_hplongminus },
- { "hpblock", XKB_KEY_hpblock },
- { "Ddiaeresis", XKB_KEY_Ddiaeresis },
- { "Dacute_accent", XKB_KEY_Dacute_accent },
- { "Dcedilla_accent", XKB_KEY_Dcedilla_accent },
- { "Dcircumflex_accent", XKB_KEY_Dcircumflex_accent },
- { "Dgrave_accent", XKB_KEY_Dgrave_accent },
- { "Dtilde", XKB_KEY_Dtilde },
- { "Dring_accent", XKB_KEY_Dring_accent },
- { "DRemove", XKB_KEY_DRemove },
- { "hpModelock1", XKB_KEY_hpModelock1 },
- { "hpModelock2", XKB_KEY_hpModelock2 },
- { "hpReset", XKB_KEY_hpReset },
- { "hpSystem", XKB_KEY_hpSystem },
- { "hpUser", XKB_KEY_hpUser },
- { "hpClearLine", XKB_KEY_hpClearLine },
- { "hpInsertLine", XKB_KEY_hpInsertLine },
- { "hpDeleteLine", XKB_KEY_hpDeleteLine },
- { "hpInsertChar", XKB_KEY_hpInsertChar },
- { "hpDeleteChar", XKB_KEY_hpDeleteChar },
- { "hpBackTab", XKB_KEY_hpBackTab },
- { "hpKP_BackTab", XKB_KEY_hpKP_BackTab },
- { "Ext16bit_L", XKB_KEY_Ext16bit_L },
- { "Ext16bit_R", XKB_KEY_Ext16bit_R },
- { "osfCopy", XKB_KEY_osfCopy },
- { "osfCut", XKB_KEY_osfCut },
- { "osfPaste", XKB_KEY_osfPaste },
- { "osfBackTab", XKB_KEY_osfBackTab },
- { "osfBackSpace", XKB_KEY_osfBackSpace },
- { "osfClear", XKB_KEY_osfClear },
- { "osfEscape", XKB_KEY_osfEscape },
- { "osfAddMode", XKB_KEY_osfAddMode },
- { "osfPrimaryPaste", XKB_KEY_osfPrimaryPaste },
- { "osfQuickPaste", XKB_KEY_osfQuickPaste },
- { "osfPageLeft", XKB_KEY_osfPageLeft },
- { "osfPageUp", XKB_KEY_osfPageUp },
- { "osfPageDown", XKB_KEY_osfPageDown },
- { "osfPageRight", XKB_KEY_osfPageRight },
- { "osfActivate", XKB_KEY_osfActivate },
- { "osfMenuBar", XKB_KEY_osfMenuBar },
- { "osfLeft", XKB_KEY_osfLeft },
- { "osfUp", XKB_KEY_osfUp },
- { "osfRight", XKB_KEY_osfRight },
- { "osfDown", XKB_KEY_osfDown },
- { "osfEndLine", XKB_KEY_osfEndLine },
- { "osfBeginLine", XKB_KEY_osfBeginLine },
- { "osfEndData", XKB_KEY_osfEndData },
- { "osfBeginData", XKB_KEY_osfBeginData },
- { "osfPrevMenu", XKB_KEY_osfPrevMenu },
- { "osfNextMenu", XKB_KEY_osfNextMenu },
- { "osfPrevField", XKB_KEY_osfPrevField },
- { "osfNextField", XKB_KEY_osfNextField },
- { "osfSelect", XKB_KEY_osfSelect },
- { "osfInsert", XKB_KEY_osfInsert },
- { "osfUndo", XKB_KEY_osfUndo },
- { "osfMenu", XKB_KEY_osfMenu },
- { "osfCancel", XKB_KEY_osfCancel },
- { "osfHelp", XKB_KEY_osfHelp },
- { "osfSelectAll", XKB_KEY_osfSelectAll },
- { "osfDeselectAll", XKB_KEY_osfDeselectAll },
- { "osfReselect", XKB_KEY_osfReselect },
- { "osfExtend", XKB_KEY_osfExtend },
- { "osfRestore", XKB_KEY_osfRestore },
- { "osfDelete", XKB_KEY_osfDelete },
- { "SunFA_Grave", XKB_KEY_SunFA_Grave },
- { "SunFA_Circum", XKB_KEY_SunFA_Circum },
- { "SunFA_Tilde", XKB_KEY_SunFA_Tilde },
- { "SunFA_Acute", XKB_KEY_SunFA_Acute },
- { "SunFA_Diaeresis", XKB_KEY_SunFA_Diaeresis },
- { "SunFA_Cedilla", XKB_KEY_SunFA_Cedilla },
- { "SunF36", XKB_KEY_SunF36 },
- { "SunF37", XKB_KEY_SunF37 },
- { "SunSys_Req", XKB_KEY_SunSys_Req },
- { "SunProps", XKB_KEY_SunProps },
- { "SunFront", XKB_KEY_SunFront },
- { "SunCopy", XKB_KEY_SunCopy },
- { "SunOpen", XKB_KEY_SunOpen },
- { "SunPaste", XKB_KEY_SunPaste },
- { "SunCut", XKB_KEY_SunCut },
- { "SunPowerSwitch", XKB_KEY_SunPowerSwitch },
- { "SunAudioLowerVolume", XKB_KEY_SunAudioLowerVolume },
- { "SunAudioMute", XKB_KEY_SunAudioMute },
- { "SunAudioRaiseVolume", XKB_KEY_SunAudioRaiseVolume },
- { "SunVideoDegauss", XKB_KEY_SunVideoDegauss },
- { "SunVideoLowerBrightness", XKB_KEY_SunVideoLowerBrightness },
- { "SunVideoRaiseBrightness", XKB_KEY_SunVideoRaiseBrightness },
- { "SunPowerSwitchShift", XKB_KEY_SunPowerSwitchShift },
- { "XF86Switch_VT_1", XKB_KEY_XF86Switch_VT_1 },
- { "XF86Switch_VT_2", XKB_KEY_XF86Switch_VT_2 },
- { "XF86Switch_VT_3", XKB_KEY_XF86Switch_VT_3 },
- { "XF86Switch_VT_4", XKB_KEY_XF86Switch_VT_4 },
- { "XF86Switch_VT_5", XKB_KEY_XF86Switch_VT_5 },
- { "XF86Switch_VT_6", XKB_KEY_XF86Switch_VT_6 },
- { "XF86Switch_VT_7", XKB_KEY_XF86Switch_VT_7 },
- { "XF86Switch_VT_8", XKB_KEY_XF86Switch_VT_8 },
- { "XF86Switch_VT_9", XKB_KEY_XF86Switch_VT_9 },
- { "XF86Switch_VT_10", XKB_KEY_XF86Switch_VT_10 },
- { "XF86Switch_VT_11", XKB_KEY_XF86Switch_VT_11 },
- { "XF86Switch_VT_12", XKB_KEY_XF86Switch_VT_12 },
- { "XF86Ungrab", XKB_KEY_XF86Ungrab },
- { "XF86ClearGrab", XKB_KEY_XF86ClearGrab },
- { "XF86Next_VMode", XKB_KEY_XF86Next_VMode },
- { "XF86Prev_VMode", XKB_KEY_XF86Prev_VMode },
- { "XF86LogWindowTree", XKB_KEY_XF86LogWindowTree },
- { "XF86LogGrabInfo", XKB_KEY_XF86LogGrabInfo },
- { "XF86ModeLock", XKB_KEY_XF86ModeLock },
- { "XF86MonBrightnessUp", XKB_KEY_XF86MonBrightnessUp },
- { "XF86MonBrightnessDown", XKB_KEY_XF86MonBrightnessDown },
- { "XF86KbdLightOnOff", XKB_KEY_XF86KbdLightOnOff },
- { "XF86KbdBrightnessUp", XKB_KEY_XF86KbdBrightnessUp },
- { "XF86KbdBrightnessDown", XKB_KEY_XF86KbdBrightnessDown },
- { "XF86Standby", XKB_KEY_XF86Standby },
- { "XF86AudioLowerVolume", XKB_KEY_XF86AudioLowerVolume },
- { "XF86AudioMute", XKB_KEY_XF86AudioMute },
- { "XF86AudioRaiseVolume", XKB_KEY_XF86AudioRaiseVolume },
- { "XF86AudioPlay", XKB_KEY_XF86AudioPlay },
- { "XF86AudioStop", XKB_KEY_XF86AudioStop },
- { "XF86AudioPrev", XKB_KEY_XF86AudioPrev },
- { "XF86AudioNext", XKB_KEY_XF86AudioNext },
- { "XF86HomePage", XKB_KEY_XF86HomePage },
- { "XF86Mail", XKB_KEY_XF86Mail },
- { "XF86Start", XKB_KEY_XF86Start },
- { "XF86Search", XKB_KEY_XF86Search },
- { "XF86AudioRecord", XKB_KEY_XF86AudioRecord },
- { "XF86Calculator", XKB_KEY_XF86Calculator },
- { "XF86Memo", XKB_KEY_XF86Memo },
- { "XF86ToDoList", XKB_KEY_XF86ToDoList },
- { "XF86Calendar", XKB_KEY_XF86Calendar },
- { "XF86PowerDown", XKB_KEY_XF86PowerDown },
- { "XF86ContrastAdjust", XKB_KEY_XF86ContrastAdjust },
- { "XF86RockerUp", XKB_KEY_XF86RockerUp },
- { "XF86RockerDown", XKB_KEY_XF86RockerDown },
- { "XF86RockerEnter", XKB_KEY_XF86RockerEnter },
- { "XF86Back", XKB_KEY_XF86Back },
- { "XF86Forward", XKB_KEY_XF86Forward },
- { "XF86Stop", XKB_KEY_XF86Stop },
- { "XF86Refresh", XKB_KEY_XF86Refresh },
- { "XF86PowerOff", XKB_KEY_XF86PowerOff },
- { "XF86WakeUp", XKB_KEY_XF86WakeUp },
- { "XF86Eject", XKB_KEY_XF86Eject },
- { "XF86ScreenSaver", XKB_KEY_XF86ScreenSaver },
- { "XF86WWW", XKB_KEY_XF86WWW },
- { "XF86Sleep", XKB_KEY_XF86Sleep },
- { "XF86Favorites", XKB_KEY_XF86Favorites },
- { "XF86AudioPause", XKB_KEY_XF86AudioPause },
- { "XF86AudioMedia", XKB_KEY_XF86AudioMedia },
- { "XF86MyComputer", XKB_KEY_XF86MyComputer },
- { "XF86VendorHome", XKB_KEY_XF86VendorHome },
- { "XF86LightBulb", XKB_KEY_XF86LightBulb },
- { "XF86Shop", XKB_KEY_XF86Shop },
- { "XF86History", XKB_KEY_XF86History },
- { "XF86OpenURL", XKB_KEY_XF86OpenURL },
- { "XF86AddFavorite", XKB_KEY_XF86AddFavorite },
- { "XF86HotLinks", XKB_KEY_XF86HotLinks },
- { "XF86BrightnessAdjust", XKB_KEY_XF86BrightnessAdjust },
- { "XF86Finance", XKB_KEY_XF86Finance },
- { "XF86Community", XKB_KEY_XF86Community },
- { "XF86AudioRewind", XKB_KEY_XF86AudioRewind },
- { "XF86BackForward", XKB_KEY_XF86BackForward },
- { "XF86Launch0", XKB_KEY_XF86Launch0 },
- { "XF86Launch1", XKB_KEY_XF86Launch1 },
- { "XF86Launch2", XKB_KEY_XF86Launch2 },
- { "XF86Launch3", XKB_KEY_XF86Launch3 },
- { "XF86Launch4", XKB_KEY_XF86Launch4 },
- { "XF86Launch5", XKB_KEY_XF86Launch5 },
- { "XF86Launch6", XKB_KEY_XF86Launch6 },
- { "XF86Launch7", XKB_KEY_XF86Launch7 },
- { "XF86Launch8", XKB_KEY_XF86Launch8 },
- { "XF86Launch9", XKB_KEY_XF86Launch9 },
- { "XF86LaunchA", XKB_KEY_XF86LaunchA },
- { "XF86LaunchB", XKB_KEY_XF86LaunchB },
- { "XF86LaunchC", XKB_KEY_XF86LaunchC },
- { "XF86LaunchD", XKB_KEY_XF86LaunchD },
- { "XF86LaunchE", XKB_KEY_XF86LaunchE },
- { "XF86LaunchF", XKB_KEY_XF86LaunchF },
- { "XF86ApplicationLeft", XKB_KEY_XF86ApplicationLeft },
- { "XF86ApplicationRight", XKB_KEY_XF86ApplicationRight },
- { "XF86Book", XKB_KEY_XF86Book },
- { "XF86CD", XKB_KEY_XF86CD },
- { "XF86Calculater", XKB_KEY_XF86Calculater },
- { "XF86Clear", XKB_KEY_XF86Clear },
- { "XF86Close", XKB_KEY_XF86Close },
- { "XF86Copy", XKB_KEY_XF86Copy },
- { "XF86Cut", XKB_KEY_XF86Cut },
- { "XF86Display", XKB_KEY_XF86Display },
- { "XF86DOS", XKB_KEY_XF86DOS },
- { "XF86Documents", XKB_KEY_XF86Documents },
- { "XF86Excel", XKB_KEY_XF86Excel },
- { "XF86Explorer", XKB_KEY_XF86Explorer },
- { "XF86Game", XKB_KEY_XF86Game },
- { "XF86Go", XKB_KEY_XF86Go },
- { "XF86iTouch", XKB_KEY_XF86iTouch },
- { "XF86LogOff", XKB_KEY_XF86LogOff },
- { "XF86Market", XKB_KEY_XF86Market },
- { "XF86Meeting", XKB_KEY_XF86Meeting },
- { "XF86MenuKB", XKB_KEY_XF86MenuKB },
- { "XF86MenuPB", XKB_KEY_XF86MenuPB },
- { "XF86MySites", XKB_KEY_XF86MySites },
- { "XF86New", XKB_KEY_XF86New },
- { "XF86News", XKB_KEY_XF86News },
- { "XF86OfficeHome", XKB_KEY_XF86OfficeHome },
- { "XF86Open", XKB_KEY_XF86Open },
- { "XF86Option", XKB_KEY_XF86Option },
- { "XF86Paste", XKB_KEY_XF86Paste },
- { "XF86Phone", XKB_KEY_XF86Phone },
- { "XF86Q", XKB_KEY_XF86Q },
- { "XF86Reply", XKB_KEY_XF86Reply },
- { "XF86Reload", XKB_KEY_XF86Reload },
- { "XF86RotateWindows", XKB_KEY_XF86RotateWindows },
- { "XF86RotationPB", XKB_KEY_XF86RotationPB },
- { "XF86RotationKB", XKB_KEY_XF86RotationKB },
- { "XF86Save", XKB_KEY_XF86Save },
- { "XF86ScrollUp", XKB_KEY_XF86ScrollUp },
- { "XF86ScrollDown", XKB_KEY_XF86ScrollDown },
- { "XF86ScrollClick", XKB_KEY_XF86ScrollClick },
- { "XF86Send", XKB_KEY_XF86Send },
- { "XF86Spell", XKB_KEY_XF86Spell },
- { "XF86SplitScreen", XKB_KEY_XF86SplitScreen },
- { "XF86Support", XKB_KEY_XF86Support },
- { "XF86TaskPane", XKB_KEY_XF86TaskPane },
- { "XF86Terminal", XKB_KEY_XF86Terminal },
- { "XF86Tools", XKB_KEY_XF86Tools },
- { "XF86Travel", XKB_KEY_XF86Travel },
- { "XF86UserPB", XKB_KEY_XF86UserPB },
- { "XF86User1KB", XKB_KEY_XF86User1KB },
- { "XF86User2KB", XKB_KEY_XF86User2KB },
- { "XF86Video", XKB_KEY_XF86Video },
- { "XF86WheelButton", XKB_KEY_XF86WheelButton },
- { "XF86Word", XKB_KEY_XF86Word },
- { "XF86Xfer", XKB_KEY_XF86Xfer },
- { "XF86ZoomIn", XKB_KEY_XF86ZoomIn },
- { "XF86ZoomOut", XKB_KEY_XF86ZoomOut },
- { "XF86Away", XKB_KEY_XF86Away },
- { "XF86Messenger", XKB_KEY_XF86Messenger },
- { "XF86WebCam", XKB_KEY_XF86WebCam },
- { "XF86MailForward", XKB_KEY_XF86MailForward },
- { "XF86Pictures", XKB_KEY_XF86Pictures },
- { "XF86Music", XKB_KEY_XF86Music },
- { "XF86Battery", XKB_KEY_XF86Battery },
- { "XF86Bluetooth", XKB_KEY_XF86Bluetooth },
- { "XF86WLAN", XKB_KEY_XF86WLAN },
- { "XF86UWB", XKB_KEY_XF86UWB },
- { "XF86AudioForward", XKB_KEY_XF86AudioForward },
- { "XF86AudioRepeat", XKB_KEY_XF86AudioRepeat },
- { "XF86AudioRandomPlay", XKB_KEY_XF86AudioRandomPlay },
- { "XF86Subtitle", XKB_KEY_XF86Subtitle },
- { "XF86AudioCycleTrack", XKB_KEY_XF86AudioCycleTrack },
- { "XF86CycleAngle", XKB_KEY_XF86CycleAngle },
- { "XF86FrameBack", XKB_KEY_XF86FrameBack },
- { "XF86FrameForward", XKB_KEY_XF86FrameForward },
- { "XF86Time", XKB_KEY_XF86Time },
- { "XF86Select", XKB_KEY_XF86Select },
- { "XF86View", XKB_KEY_XF86View },
- { "XF86TopMenu", XKB_KEY_XF86TopMenu },
- { "XF86Red", XKB_KEY_XF86Red },
- { "XF86Green", XKB_KEY_XF86Green },
- { "XF86Yellow", XKB_KEY_XF86Yellow },
- { "XF86Blue", XKB_KEY_XF86Blue },
- { "XF86Suspend", XKB_KEY_XF86Suspend },
- { "XF86Hibernate", XKB_KEY_XF86Hibernate },
- { "XF86TouchpadToggle", XKB_KEY_XF86TouchpadToggle },
- { "XF86TouchpadOn", XKB_KEY_XF86TouchpadOn },
- { "XF86TouchpadOff", XKB_KEY_XF86TouchpadOff },
+ { 0x00000000, 20091 }, /* NoSymbol */
+ { 0x00000020, 23803 }, /* space */
+ { 0x00000021, 12099 }, /* exclam */
+ { 0x00000022, 22187 }, /* quotedbl */
+ { 0x00000023, 20178 }, /* numbersign */
+ { 0x00000024, 11251 }, /* dollar */
+ { 0x00000025, 21487 }, /* percent */
+ { 0x00000026, 908 }, /* ampersand */
+ { 0x00000027, 934 }, /* apostrophe */
+ { 0x00000028, 21425 }, /* parenleft */
+ { 0x00000029, 21435 }, /* parenright */
+ { 0x0000002a, 3283 }, /* asterisk */
+ { 0x0000002b, 21557 }, /* plus */
+ { 0x0000002c, 8680 }, /* comma */
+ { 0x0000002d, 19733 }, /* minus */
+ { 0x0000002e, 21495 }, /* period */
+ { 0x0000002f, 23768 }, /* slash */
+ { 0x00000030, 0 }, /* 0 */
+ { 0x00000031, 2 }, /* 1 */
+ { 0x00000032, 4 }, /* 2 */
+ { 0x00000033, 6 }, /* 3 */
+ { 0x00000034, 386 }, /* 4 */
+ { 0x00000035, 388 }, /* 5 */
+ { 0x00000036, 390 }, /* 6 */
+ { 0x00000037, 392 }, /* 7 */
+ { 0x00000038, 394 }, /* 8 */
+ { 0x00000039, 396 }, /* 9 */
+ { 0x0000003a, 8664 }, /* colon */
+ { 0x0000003b, 22734 }, /* semicolon */
+ { 0x0000003c, 19412 }, /* less */
+ { 0x0000003d, 12051 }, /* equal */
+ { 0x0000003e, 13272 }, /* greater */
+ { 0x0000003f, 22165 }, /* question */
+ { 0x00000040, 3292 }, /* at */
+ { 0x00000041, 398 }, /* A */
+ { 0x00000042, 3328 }, /* B */
+ { 0x00000043, 8439 }, /* C */
+ { 0x00000044, 10320 }, /* D */
+ { 0x00000045, 11424 }, /* E */
+ { 0x00000046, 12155 }, /* F */
+ { 0x00000047, 12665 }, /* G */
+ { 0x00000048, 14378 }, /* H */
+ { 0x00000049, 17069 }, /* I */
+ { 0x0000004a, 18114 }, /* J */
+ { 0x0000004b, 18146 }, /* K */
+ { 0x0000004c, 19112 }, /* L */
+ { 0x0000004d, 19533 }, /* M */
+ { 0x0000004e, 19943 }, /* N */
+ { 0x0000004f, 20200 }, /* O */
+ { 0x00000050, 21373 }, /* P */
+ { 0x00000051, 22156 }, /* Q */
+ { 0x00000052, 22217 }, /* R */
+ { 0x00000053, 22579 }, /* S */
+ { 0x00000054, 24294 }, /* T */
+ { 0x00000055, 25847 }, /* U */
+ { 0x00000056, 26483 }, /* V */
+ { 0x00000057, 26545 }, /* W */
+ { 0x00000058, 26631 }, /* X */
+ { 0x00000059, 28972 }, /* Y */
+ { 0x0000005a, 29100 }, /* Z */
+ { 0x0000005b, 3603 }, /* bracketleft */
+ { 0x0000005c, 3352 }, /* backslash */
+ { 0x0000005d, 3615 }, /* bracketright */
+ { 0x0000005e, 3260 }, /* asciicircum */
+ { 0x0000005f, 26346 }, /* underscore */
+ { 0x00000060, 13266 }, /* grave */
+ { 0x00000061, 400 }, /* a */
+ { 0x00000062, 3330 }, /* b */
+ { 0x00000063, 8441 }, /* c */
+ { 0x00000064, 10322 }, /* d */
+ { 0x00000065, 11426 }, /* e */
+ { 0x00000066, 12157 }, /* f */
+ { 0x00000067, 12667 }, /* g */
+ { 0x00000068, 14380 }, /* h */
+ { 0x00000069, 17071 }, /* i */
+ { 0x0000006a, 18116 }, /* j */
+ { 0x0000006b, 18148 }, /* k */
+ { 0x0000006c, 19114 }, /* l */
+ { 0x0000006d, 19535 }, /* m */
+ { 0x0000006e, 19945 }, /* n */
+ { 0x0000006f, 20202 }, /* o */
+ { 0x00000070, 21375 }, /* p */
+ { 0x00000071, 22158 }, /* q */
+ { 0x00000072, 22219 }, /* r */
+ { 0x00000073, 22581 }, /* s */
+ { 0x00000074, 24296 }, /* t */
+ { 0x00000075, 25849 }, /* u */
+ { 0x00000076, 26485 }, /* v */
+ { 0x00000077, 26547 }, /* w */
+ { 0x00000078, 26633 }, /* x */
+ { 0x00000079, 28974 }, /* y */
+ { 0x0000007a, 29102 }, /* z */
+ { 0x0000007b, 3582 }, /* braceleft */
+ { 0x0000007c, 3392 }, /* bar */
+ { 0x0000007d, 3592 }, /* braceright */
+ { 0x0000007e, 3272 }, /* asciitilde */
+ { 0x000000a0, 20078 }, /* nobreakspace */
+ { 0x000000a1, 12106 }, /* exclamdown */
+ { 0x000000a2, 8589 }, /* cent */
+ { 0x000000a3, 23827 }, /* sterling */
+ { 0x000000a4, 8766 }, /* currency */
+ { 0x000000a5, 29056 }, /* yen */
+ { 0x000000a6, 8389 }, /* brokenbar */
+ { 0x000000a7, 22719 }, /* section */
+ { 0x000000a8, 11203 }, /* diaeresis */
+ { 0x000000a9, 8717 }, /* copyright */
+ { 0x000000aa, 20852 }, /* ordfeminine */
+ { 0x000000ab, 14349 }, /* guillemotleft */
+ { 0x000000ac, 20147 }, /* notsign */
+ { 0x000000ad, 17062 }, /* hyphen */
+ { 0x000000ae, 22331 }, /* registered */
+ { 0x000000af, 19641 }, /* macron */
+ { 0x000000b0, 11153 }, /* degree */
+ { 0x000000b1, 21562 }, /* plusminus */
+ { 0x000000b2, 25825 }, /* twosuperior */
+ { 0x000000b3, 25571 }, /* threesuperior */
+ { 0x000000b4, 820 }, /* acute */
+ { 0x000000b5, 19799 }, /* mu */
+ { 0x000000b6, 21415 }, /* paragraph */
+ { 0x000000b7, 21502 }, /* periodcentered */
+ { 0x000000b8, 8581 }, /* cedilla */
+ { 0x000000b9, 20755 }, /* onesuperior */
+ { 0x000000ba, 19688 }, /* masculine */
+ { 0x000000bb, 14363 }, /* guillemotright */
+ { 0x000000bc, 20722 }, /* onequarter */
+ { 0x000000bd, 20714 }, /* onehalf */
+ { 0x000000be, 25542 }, /* threequarters */
+ { 0x000000bf, 22174 }, /* questiondown */
+ { 0x000000c0, 854 }, /* Agrave */
+ { 0x000000c1, 402 }, /* Aacute */
+ { 0x000000c2, 622 }, /* Acircumflex */
+ { 0x000000c3, 3295 }, /* Atilde */
+ { 0x000000c4, 826 }, /* Adiaeresis */
+ { 0x000000c5, 2036 }, /* Aring */
+ { 0x000000c6, 848 }, /* AE */
+ { 0x000000c7, 8539 }, /* Ccedilla */
+ { 0x000000c8, 11724 }, /* Egrave */
+ { 0x000000c9, 11448 }, /* Eacute */
+ { 0x000000ca, 11496 }, /* Ecircumflex */
+ { 0x000000cb, 11702 }, /* Ediaeresis */
+ { 0x000000cc, 17205 }, /* Igrave */
+ { 0x000000cd, 17083 }, /* Iacute */
+ { 0x000000ce, 17131 }, /* Icircumflex */
+ { 0x000000cf, 17165 }, /* Idiaeresis */
+ { 0x000000d0, 12064 }, /* ETH */
+ { 0x000000d1, 20155 }, /* Ntilde */
+ { 0x000000d2, 20527 }, /* Ograve */
+ { 0x000000d3, 20204 }, /* Oacute */
+ { 0x000000d4, 20268 }, /* Ocircumflex */
+ { 0x000000d5, 21310 }, /* Otilde */
+ { 0x000000d6, 20466 }, /* Odiaeresis */
+ { 0x000000d7, 19839 }, /* multiply */
+ { 0x000000d8, 21296 }, /* Oslash */
+ { 0x000000d9, 25971 }, /* Ugrave */
+ { 0x000000da, 25851 }, /* Uacute */
+ { 0x000000db, 25899 }, /* Ucircumflex */
+ { 0x000000dc, 25923 }, /* Udiaeresis */
+ { 0x000000dd, 28976 }, /* Yacute */
+ { 0x000000de, 25499 }, /* THORN */
+ { 0x000000df, 23820 }, /* ssharp */
+ { 0x000000e0, 861 }, /* agrave */
+ { 0x000000e1, 409 }, /* aacute */
+ { 0x000000e2, 634 }, /* acircumflex */
+ { 0x000000e3, 3302 }, /* atilde */
+ { 0x000000e4, 837 }, /* adiaeresis */
+ { 0x000000e5, 2042 }, /* aring */
+ { 0x000000e6, 851 }, /* ae */
+ { 0x000000e7, 8548 }, /* ccedilla */
+ { 0x000000e8, 11731 }, /* egrave */
+ { 0x000000e9, 11455 }, /* eacute */
+ { 0x000000ea, 11508 }, /* ecircumflex */
+ { 0x000000eb, 11713 }, /* ediaeresis */
+ { 0x000000ec, 17212 }, /* igrave */
+ { 0x000000ed, 17090 }, /* iacute */
+ { 0x000000ee, 17143 }, /* icircumflex */
+ { 0x000000ef, 17176 }, /* idiaeresis */
+ { 0x000000f0, 12072 }, /* eth */
+ { 0x000000f1, 20162 }, /* ntilde */
+ { 0x000000f2, 20534 }, /* ograve */
+ { 0x000000f3, 20211 }, /* oacute */
+ { 0x000000f4, 20280 }, /* ocircumflex */
+ { 0x000000f5, 21317 }, /* otilde */
+ { 0x000000f6, 20477 }, /* odiaeresis */
+ { 0x000000f7, 11242 }, /* division */
+ { 0x000000f8, 21303 }, /* oslash */
+ { 0x000000f9, 25978 }, /* ugrave */
+ { 0x000000fa, 25858 }, /* uacute */
+ { 0x000000fb, 25911 }, /* ucircumflex */
+ { 0x000000fc, 25934 }, /* udiaeresis */
+ { 0x000000fd, 28983 }, /* yacute */
+ { 0x000000fe, 25511 }, /* thorn */
+ { 0x000000ff, 29034 }, /* ydiaeresis */
+ { 0x000001a1, 918 }, /* Aogonek */
+ { 0x000001a2, 8383 }, /* breve */
+ { 0x000001a3, 19517 }, /* Lstroke */
+ { 0x000001a5, 19212 }, /* Lcaron */
+ { 0x000001a6, 22603 }, /* Sacute */
+ { 0x000001a9, 22617 }, /* Scaron */
+ { 0x000001aa, 22631 }, /* Scedilla */
+ { 0x000001ab, 24322 }, /* Tcaron */
+ { 0x000001ac, 29124 }, /* Zacute */
+ { 0x000001ae, 29138 }, /* Zcaron */
+ { 0x000001af, 29104 }, /* Zabovedot */
+ { 0x000001b1, 926 }, /* aogonek */
+ { 0x000001b2, 20520 }, /* ogonek */
+ { 0x000001b3, 19525 }, /* lstroke */
+ { 0x000001b5, 19219 }, /* lcaron */
+ { 0x000001b6, 22610 }, /* sacute */
+ { 0x000001b7, 8519 }, /* caron */
+ { 0x000001b9, 22624 }, /* scaron */
+ { 0x000001ba, 22640 }, /* scedilla */
+ { 0x000001bb, 24329 }, /* tcaron */
+ { 0x000001bc, 29131 }, /* zacute */
+ { 0x000001bd, 11283 }, /* doubleacute */
+ { 0x000001be, 29145 }, /* zcaron */
+ { 0x000001bf, 29114 }, /* zabovedot */
+ { 0x000001c0, 22272 }, /* Racute */
+ { 0x000001c3, 445 }, /* Abreve */
+ { 0x000001c5, 19147 }, /* Lacute */
+ { 0x000001c6, 8475 }, /* Cacute */
+ { 0x000001c8, 8525 }, /* Ccaron */
+ { 0x000001ca, 12035 }, /* Eogonek */
+ { 0x000001cc, 11482 }, /* Ecaron */
+ { 0x000001cf, 10365 }, /* Dcaron */
+ { 0x000001d0, 11401 }, /* Dstroke */
+ { 0x000001d1, 19953 }, /* Nacute */
+ { 0x000001d2, 19977 }, /* Ncaron */
+ { 0x000001d5, 20488 }, /* Odoubleacute */
+ { 0x000001d8, 22294 }, /* Rcaron */
+ { 0x000001d9, 26452 }, /* Uring */
+ { 0x000001db, 25945 }, /* Udoubleacute */
+ { 0x000001de, 24336 }, /* Tcedilla */
+ { 0x000001e0, 22279 }, /* racute */
+ { 0x000001e3, 452 }, /* abreve */
+ { 0x000001e5, 19154 }, /* lacute */
+ { 0x000001e6, 8482 }, /* cacute */
+ { 0x000001e8, 8532 }, /* ccaron */
+ { 0x000001ea, 12043 }, /* eogonek */
+ { 0x000001ec, 11489 }, /* ecaron */
+ { 0x000001ef, 10372 }, /* dcaron */
+ { 0x000001f0, 11409 }, /* dstroke */
+ { 0x000001f1, 19960 }, /* nacute */
+ { 0x000001f2, 19984 }, /* ncaron */
+ { 0x000001f5, 20501 }, /* odoubleacute */
+ { 0x000001f8, 22301 }, /* rcaron */
+ { 0x000001f9, 26458 }, /* uring */
+ { 0x000001fb, 25958 }, /* udoubleacute */
+ { 0x000001fe, 24345 }, /* tcedilla */
+ { 0x000001ff, 436 }, /* abovedot */
+ { 0x000002a1, 17027 }, /* Hstroke */
+ { 0x000002a6, 16056 }, /* Hcircumflex */
+ { 0x000002a9, 17073 }, /* Iabovedot */
+ { 0x000002ab, 12689 }, /* Gbreve */
+ { 0x000002ac, 18118 }, /* Jcircumflex */
+ { 0x000002b1, 17035 }, /* hstroke */
+ { 0x000002b6, 16068 }, /* hcircumflex */
+ { 0x000002b9, 17187 }, /* idotless */
+ { 0x000002bb, 12696 }, /* gbreve */
+ { 0x000002bc, 18130 }, /* jcircumflex */
+ { 0x000002c5, 8455 }, /* Cabovedot */
+ { 0x000002c6, 8557 }, /* Ccircumflex */
+ { 0x000002d5, 12669 }, /* Gabovedot */
+ { 0x000002d8, 12735 }, /* Gcircumflex */
+ { 0x000002dd, 25885 }, /* Ubreve */
+ { 0x000002de, 22661 }, /* Scircumflex */
+ { 0x000002e5, 8465 }, /* cabovedot */
+ { 0x000002e6, 8569 }, /* ccircumflex */
+ { 0x000002f5, 12679 }, /* gabovedot */
+ { 0x000002f8, 12747 }, /* gcircumflex */
+ { 0x000002fd, 25892 }, /* ubreve */
+ { 0x000002fe, 22673 }, /* scircumflex */
+ { 0x000003a2, 19108 }, /* kra */
+ { 0x000003a3, 22308 }, /* Rcedilla */
+ { 0x000003a5, 18100 }, /* Itilde */
+ { 0x000003a6, 19226 }, /* Lcedilla */
+ { 0x000003aa, 11839 }, /* Emacron */
+ { 0x000003ab, 12717 }, /* Gcedilla */
+ { 0x000003ac, 25788 }, /* Tslash */
+ { 0x000003b3, 22317 }, /* rcedilla */
+ { 0x000003b5, 18107 }, /* itilde */
+ { 0x000003b6, 19235 }, /* lcedilla */
+ { 0x000003ba, 11847 }, /* emacron */
+ { 0x000003bb, 12726 }, /* gcedilla */
+ { 0x000003bc, 25795 }, /* tslash */
+ { 0x000003bd, 11983 }, /* ENG */
+ { 0x000003bf, 11987 }, /* eng */
+ { 0x000003c0, 892 }, /* Amacron */
+ { 0x000003c7, 17338 }, /* Iogonek */
+ { 0x000003cc, 11428 }, /* Eabovedot */
+ { 0x000003cf, 17231 }, /* Imacron */
+ { 0x000003d1, 19991 }, /* Ncedilla */
+ { 0x000003d2, 20679 }, /* Omacron */
+ { 0x000003d3, 18779 }, /* Kcedilla */
+ { 0x000003d9, 26368 }, /* Uogonek */
+ { 0x000003dd, 26469 }, /* Utilde */
+ { 0x000003de, 26321 }, /* Umacron */
+ { 0x000003e0, 900 }, /* amacron */
+ { 0x000003e7, 17346 }, /* iogonek */
+ { 0x000003ec, 11438 }, /* eabovedot */
+ { 0x000003ef, 17239 }, /* imacron */
+ { 0x000003f1, 20000 }, /* ncedilla */
+ { 0x000003f2, 20687 }, /* omacron */
+ { 0x000003f3, 18788 }, /* kcedilla */
+ { 0x000003f9, 26376 }, /* uogonek */
+ { 0x000003fd, 26476 }, /* utilde */
+ { 0x000003fe, 26329 }, /* umacron */
+ { 0x0000047e, 21364 }, /* overline */
+ { 0x000004a1, 18243 }, /* kana_fullstop */
+ { 0x000004a2, 18477 }, /* kana_openingbracket */
+ { 0x000004a3, 18173 }, /* kana_closingbracket */
+ { 0x000004a4, 18193 }, /* kana_comma */
+ { 0x000004a5, 18204 }, /* kana_conjunctive */
+ { 0x000004a6, 18689 }, /* kana_WO */
+ { 0x000004a7, 18150 }, /* kana_a */
+ { 0x000004a8, 18297 }, /* kana_i */
+ { 0x000004a9, 18667 }, /* kana_u */
+ { 0x000004aa, 18221 }, /* kana_e */
+ { 0x000004ab, 18463 }, /* kana_o */
+ { 0x000004ac, 18697 }, /* kana_ya */
+ { 0x000004ad, 18729 }, /* kana_yu */
+ { 0x000004ae, 18713 }, /* kana_yo */
+ { 0x000004af, 18633 }, /* kana_tsu */
+ { 0x000004b0, 22130 }, /* prolongedsound */
+ { 0x000004b1, 18157 }, /* kana_A */
+ { 0x000004b2, 18304 }, /* kana_I */
+ { 0x000004b3, 18674 }, /* kana_U */
+ { 0x000004b4, 18228 }, /* kana_E */
+ { 0x000004b5, 18470 }, /* kana_O */
+ { 0x000004b6, 18311 }, /* kana_KA */
+ { 0x000004b7, 18327 }, /* kana_KI */
+ { 0x000004b8, 18343 }, /* kana_KU */
+ { 0x000004b9, 18319 }, /* kana_KE */
+ { 0x000004ba, 18335 }, /* kana_KO */
+ { 0x000004bb, 18537 }, /* kana_SA */
+ { 0x000004bc, 18553 }, /* kana_SHI */
+ { 0x000004bd, 18581 }, /* kana_SU */
+ { 0x000004be, 18545 }, /* kana_SE */
+ { 0x000004bf, 18573 }, /* kana_SO */
+ { 0x000004c0, 18601 }, /* kana_TA */
+ { 0x000004c1, 18164 }, /* kana_CHI */
+ { 0x000004c2, 18642 }, /* kana_TSU */
+ { 0x000004c3, 18609 }, /* kana_TE */
+ { 0x000004c4, 18625 }, /* kana_TO */
+ { 0x000004c5, 18423 }, /* kana_NA */
+ { 0x000004c6, 18439 }, /* kana_NI */
+ { 0x000004c7, 18455 }, /* kana_NU */
+ { 0x000004c8, 18431 }, /* kana_NE */
+ { 0x000004c9, 18447 }, /* kana_NO */
+ { 0x000004ca, 18257 }, /* kana_HA */
+ { 0x000004cb, 18273 }, /* kana_HI */
+ { 0x000004cc, 18235 }, /* kana_FU */
+ { 0x000004cd, 18265 }, /* kana_HE */
+ { 0x000004ce, 18281 }, /* kana_HO */
+ { 0x000004cf, 18361 }, /* kana_MA */
+ { 0x000004d0, 18377 }, /* kana_MI */
+ { 0x000004d1, 18408 }, /* kana_MU */
+ { 0x000004d2, 18369 }, /* kana_ME */
+ { 0x000004d3, 18400 }, /* kana_MO */
+ { 0x000004d4, 18705 }, /* kana_YA */
+ { 0x000004d5, 18737 }, /* kana_YU */
+ { 0x000004d6, 18721 }, /* kana_YO */
+ { 0x000004d7, 18497 }, /* kana_RA */
+ { 0x000004d8, 18513 }, /* kana_RI */
+ { 0x000004d9, 18529 }, /* kana_RU */
+ { 0x000004da, 18505 }, /* kana_RE */
+ { 0x000004db, 18521 }, /* kana_RO */
+ { 0x000004dc, 18681 }, /* kana_WA */
+ { 0x000004dd, 18416 }, /* kana_N */
+ { 0x000004de, 26519 }, /* voicedsound */
+ { 0x000004df, 22744 }, /* semivoicedsound */
+ { 0x000005ac, 1109 }, /* Arabic_comma */
+ { 0x000005bb, 1764 }, /* Arabic_semicolon */
+ { 0x000005bf, 1698 }, /* Arabic_question_mark */
+ { 0x000005c1, 1303 }, /* Arabic_hamza */
+ { 0x000005c2, 1599 }, /* Arabic_maddaonalef */
+ { 0x000005c3, 1354 }, /* Arabic_hamzaonalef */
+ { 0x000005c4, 1373 }, /* Arabic_hamzaonwaw */
+ { 0x000005c5, 1409 }, /* Arabic_hamzaunderalef */
+ { 0x000005c6, 1391 }, /* Arabic_hamzaonyeh */
+ { 0x000005c7, 1067 }, /* Arabic_alef */
+ { 0x000005c8, 1098 }, /* Arabic_beh */
+ { 0x000005c9, 1909 }, /* Arabic_tehmarbuta */
+ { 0x000005ca, 1898 }, /* Arabic_teh */
+ { 0x000005cb, 1939 }, /* Arabic_theh */
+ { 0x000005cc, 1481 }, /* Arabic_jeem */
+ { 0x000005cd, 1292 }, /* Arabic_hah */
+ { 0x000005ce, 1557 }, /* Arabic_khah */
+ { 0x000005cf, 1133 }, /* Arabic_dal */
+ { 0x000005d0, 1927 }, /* Arabic_thal */
+ { 0x000005d1, 1719 }, /* Arabic_ra */
+ { 0x000005d2, 2024 }, /* Arabic_zain */
+ { 0x000005d3, 1752 }, /* Arabic_seen */
+ { 0x000005d4, 1795 }, /* Arabic_sheen */
+ { 0x000005d5, 1741 }, /* Arabic_sad */
+ { 0x000005d6, 1122 }, /* Arabic_dad */
+ { 0x000005d7, 1859 }, /* Arabic_tah */
+ { 0x000005d8, 2013 }, /* Arabic_zah */
+ { 0x000005d9, 1056 }, /* Arabic_ain */
+ { 0x000005da, 1269 }, /* Arabic_ghain */
+ { 0x000005e0, 1870 }, /* Arabic_tatweel */
+ { 0x000005e1, 1231 }, /* Arabic_feh */
+ { 0x000005e2, 1687 }, /* Arabic_qaf */
+ { 0x000005e3, 1504 }, /* Arabic_kaf */
+ { 0x000005e4, 1569 }, /* Arabic_lam */
+ { 0x000005e5, 1618 }, /* Arabic_meem */
+ { 0x000005e6, 1630 }, /* Arabic_noon */
+ { 0x000005e7, 1282 }, /* Arabic_ha */
+ { 0x000005e8, 1974 }, /* Arabic_waw */
+ { 0x000005e9, 1079 }, /* Arabic_alefmaksura */
+ { 0x000005ea, 1985 }, /* Arabic_yeh */
+ { 0x000005eb, 1215 }, /* Arabic_fathatan */
+ { 0x000005ec, 1157 }, /* Arabic_dammatan */
+ { 0x000005ed, 1528 }, /* Arabic_kasratan */
+ { 0x000005ee, 1202 }, /* Arabic_fatha */
+ { 0x000005ef, 1144 }, /* Arabic_damma */
+ { 0x000005f0, 1515 }, /* Arabic_kasra */
+ { 0x000005f1, 1781 }, /* Arabic_shadda */
+ { 0x000005f2, 1808 }, /* Arabic_sukun */
+ { 0x000006a1, 22760 }, /* Serbian_dje */
+ { 0x000006a2, 19585 }, /* Macedonia_gje */
+ { 0x000006a3, 9456 }, /* Cyrillic_io */
+ { 0x000006a4, 26199 }, /* Ukrainian_ie */
+ { 0x000006a5, 19557 }, /* Macedonia_dse */
+ { 0x000006a6, 26175 }, /* Ukrainian_i */
+ { 0x000006a7, 26225 }, /* Ukrainian_yi */
+ { 0x000006a8, 9480 }, /* Cyrillic_je */
+ { 0x000006a9, 9618 }, /* Cyrillic_lje */
+ { 0x000006aa, 9644 }, /* Cyrillic_nje */
+ { 0x000006ab, 22878 }, /* Serbian_tshe */
+ { 0x000006ac, 19613 }, /* Macedonia_kje */
+ { 0x000006ad, 26123 }, /* Ukrainian_ghe_with_upturn */
+ { 0x000006ae, 8399 }, /* Byelorussian_shortu */
+ { 0x000006af, 8972 }, /* Cyrillic_dzhe */
+ { 0x000006b0, 20189 }, /* numerosign */
+ { 0x000006b1, 22772 }, /* Serbian_DJE */
+ { 0x000006b2, 19599 }, /* Macedonia_GJE */
+ { 0x000006b3, 9468 }, /* Cyrillic_IO */
+ { 0x000006b4, 26212 }, /* Ukrainian_IE */
+ { 0x000006b5, 19571 }, /* Macedonia_DSE */
+ { 0x000006b6, 26187 }, /* Ukrainian_I */
+ { 0x000006b7, 26238 }, /* Ukrainian_YI */
+ { 0x000006b8, 9492 }, /* Cyrillic_JE */
+ { 0x000006b9, 9631 }, /* Cyrillic_LJE */
+ { 0x000006ba, 9657 }, /* Cyrillic_NJE */
+ { 0x000006bb, 22891 }, /* Serbian_TSHE */
+ { 0x000006bc, 19627 }, /* Macedonia_KJE */
+ { 0x000006bd, 26149 }, /* Ukrainian_GHE_WITH_UPTURN */
+ { 0x000006be, 8419 }, /* Byelorussian_SHORTU */
+ { 0x000006bf, 8986 }, /* Cyrillic_DZHE */
+ { 0x000006c0, 10200 }, /* Cyrillic_yu */
+ { 0x000006c1, 8782 }, /* Cyrillic_a */
+ { 0x000006c2, 8804 }, /* Cyrillic_be */
+ { 0x000006c3, 9952 }, /* Cyrillic_tse */
+ { 0x000006c4, 8948 }, /* Cyrillic_de */
+ { 0x000006c5, 9432 }, /* Cyrillic_ie */
+ { 0x000006c6, 9022 }, /* Cyrillic_ef */
+ { 0x000006c7, 9210 }, /* Cyrillic_ghe */
+ { 0x000006c8, 9270 }, /* Cyrillic_ha */
+ { 0x000006c9, 9374 }, /* Cyrillic_i */
+ { 0x000006ca, 9860 }, /* Cyrillic_shorti */
+ { 0x000006cb, 9504 }, /* Cyrillic_ka */
+ { 0x000006cc, 9046 }, /* Cyrillic_el */
+ { 0x000006cd, 9070 }, /* Cyrillic_em */
+ { 0x000006ce, 9094 }, /* Cyrillic_en */
+ { 0x000006cf, 9670 }, /* Cyrillic_o */
+ { 0x000006d0, 9722 }, /* Cyrillic_pe */
+ { 0x000006d1, 10148 }, /* Cyrillic_ya */
+ { 0x000006d2, 9162 }, /* Cyrillic_er */
+ { 0x000006d3, 9186 }, /* Cyrillic_es */
+ { 0x000006d4, 9928 }, /* Cyrillic_te */
+ { 0x000006d5, 9978 }, /* Cyrillic_u */
+ { 0x000006d6, 10248 }, /* Cyrillic_zhe */
+ { 0x000006d7, 10124 }, /* Cyrillic_ve */
+ { 0x000006d8, 9892 }, /* Cyrillic_softsign */
+ { 0x000006d9, 10172 }, /* Cyrillic_yeru */
+ { 0x000006da, 10224 }, /* Cyrillic_ze */
+ { 0x000006db, 9776 }, /* Cyrillic_sha */
+ { 0x000006dc, 9000 }, /* Cyrillic_e */
+ { 0x000006dd, 9802 }, /* Cyrillic_shcha */
+ { 0x000006de, 8828 }, /* Cyrillic_che */
+ { 0x000006df, 9338 }, /* Cyrillic_hardsign */
+ { 0x000006e0, 10212 }, /* Cyrillic_YU */
+ { 0x000006e1, 8793 }, /* Cyrillic_A */
+ { 0x000006e2, 8816 }, /* Cyrillic_BE */
+ { 0x000006e3, 9965 }, /* Cyrillic_TSE */
+ { 0x000006e4, 8960 }, /* Cyrillic_DE */
+ { 0x000006e5, 9444 }, /* Cyrillic_IE */
+ { 0x000006e6, 9034 }, /* Cyrillic_EF */
+ { 0x000006e7, 9223 }, /* Cyrillic_GHE */
+ { 0x000006e8, 9282 }, /* Cyrillic_HA */
+ { 0x000006e9, 9385 }, /* Cyrillic_I */
+ { 0x000006ea, 9876 }, /* Cyrillic_SHORTI */
+ { 0x000006eb, 9516 }, /* Cyrillic_KA */
+ { 0x000006ec, 9058 }, /* Cyrillic_EL */
+ { 0x000006ed, 9082 }, /* Cyrillic_EM */
+ { 0x000006ee, 9106 }, /* Cyrillic_EN */
+ { 0x000006ef, 9681 }, /* Cyrillic_O */
+ { 0x000006f0, 9734 }, /* Cyrillic_PE */
+ { 0x000006f1, 10160 }, /* Cyrillic_YA */
+ { 0x000006f2, 9174 }, /* Cyrillic_ER */
+ { 0x000006f3, 9198 }, /* Cyrillic_ES */
+ { 0x000006f4, 9940 }, /* Cyrillic_TE */
+ { 0x000006f5, 9989 }, /* Cyrillic_U */
+ { 0x000006f6, 10261 }, /* Cyrillic_ZHE */
+ { 0x000006f7, 10136 }, /* Cyrillic_VE */
+ { 0x000006f8, 9910 }, /* Cyrillic_SOFTSIGN */
+ { 0x000006f9, 10186 }, /* Cyrillic_YERU */
+ { 0x000006fa, 10236 }, /* Cyrillic_ZE */
+ { 0x000006fb, 9789 }, /* Cyrillic_SHA */
+ { 0x000006fc, 9011 }, /* Cyrillic_E */
+ { 0x000006fd, 9817 }, /* Cyrillic_SHCHA */
+ { 0x000006fe, 8841 }, /* Cyrillic_CHE */
+ { 0x000006ff, 9356 }, /* Cyrillic_HARDSIGN */
+ { 0x000007a1, 13342 }, /* Greek_ALPHAaccent */
+ { 0x000007a2, 13472 }, /* Greek_EPSILONaccent */
+ { 0x000007a3, 13532 }, /* Greek_ETAaccent */
+ { 0x000007a4, 13647 }, /* Greek_IOTAaccent */
+ { 0x000007a5, 13726 }, /* Greek_IOTAdieresis */
+ { 0x000007a7, 13962 }, /* Greek_OMICRONaccent */
+ { 0x000007a8, 14189 }, /* Greek_UPSILONaccent */
+ { 0x000007a9, 14257 }, /* Greek_UPSILONdieresis */
+ { 0x000007ab, 13898 }, /* Greek_OMEGAaccent */
+ { 0x000007ae, 13297 }, /* Greek_accentdieresis */
+ { 0x000007af, 13610 }, /* Greek_horizbar */
+ { 0x000007b1, 13360 }, /* Greek_alphaaccent */
+ { 0x000007b2, 13492 }, /* Greek_epsilonaccent */
+ { 0x000007b3, 13548 }, /* Greek_etaaccent */
+ { 0x000007b4, 13664 }, /* Greek_iotaaccent */
+ { 0x000007b5, 13745 }, /* Greek_iotadieresis */
+ { 0x000007b6, 13681 }, /* Greek_iotaaccentdieresis */
+ { 0x000007b7, 13982 }, /* Greek_omicronaccent */
+ { 0x000007b8, 14209 }, /* Greek_upsilonaccent */
+ { 0x000007b9, 14279 }, /* Greek_upsilondieresis */
+ { 0x000007ba, 14229 }, /* Greek_upsilonaccentdieresis */
+ { 0x000007bb, 13916 }, /* Greek_omegaaccent */
+ { 0x000007c1, 13318 }, /* Greek_ALPHA */
+ { 0x000007c2, 13378 }, /* Greek_BETA */
+ { 0x000007c3, 13586 }, /* Greek_GAMMA */
+ { 0x000007c4, 13420 }, /* Greek_DELTA */
+ { 0x000007c5, 13444 }, /* Greek_EPSILON */
+ { 0x000007c6, 14319 }, /* Greek_ZETA */
+ { 0x000007c7, 13512 }, /* Greek_ETA */
+ { 0x000007c8, 14137 }, /* Greek_THETA */
+ { 0x000007c9, 13625 }, /* Greek_IOTA */
+ { 0x000007ca, 13764 }, /* Greek_KAPPA */
+ { 0x000007cb, 13814 }, /* Greek_LAMDA */
+ { 0x000007cc, 13838 }, /* Greek_MU */
+ { 0x000007cd, 13856 }, /* Greek_NU */
+ { 0x000007ce, 14301 }, /* Greek_XI */
+ { 0x000007cf, 13934 }, /* Greek_OMICRON */
+ { 0x000007d0, 14022 }, /* Greek_PI */
+ { 0x000007d1, 14060 }, /* Greek_RHO */
+ { 0x000007d2, 14080 }, /* Greek_SIGMA */
+ { 0x000007d4, 14117 }, /* Greek_TAU */
+ { 0x000007d5, 14161 }, /* Greek_UPSILON */
+ { 0x000007d6, 14002 }, /* Greek_PHI */
+ { 0x000007d7, 13400 }, /* Greek_CHI */
+ { 0x000007d8, 14040 }, /* Greek_PSI */
+ { 0x000007d9, 13874 }, /* Greek_OMEGA */
+ { 0x000007e1, 13330 }, /* Greek_alpha */
+ { 0x000007e2, 13389 }, /* Greek_beta */
+ { 0x000007e3, 13598 }, /* Greek_gamma */
+ { 0x000007e4, 13432 }, /* Greek_delta */
+ { 0x000007e5, 13458 }, /* Greek_epsilon */
+ { 0x000007e6, 14330 }, /* Greek_zeta */
+ { 0x000007e7, 13522 }, /* Greek_eta */
+ { 0x000007e8, 14149 }, /* Greek_theta */
+ { 0x000007e9, 13636 }, /* Greek_iota */
+ { 0x000007ea, 13776 }, /* Greek_kappa */
+ { 0x000007eb, 13826 }, /* Greek_lamda */
+ { 0x000007ec, 13847 }, /* Greek_mu */
+ { 0x000007ed, 13865 }, /* Greek_nu */
+ { 0x000007ee, 14310 }, /* Greek_xi */
+ { 0x000007ef, 13948 }, /* Greek_omicron */
+ { 0x000007f0, 14031 }, /* Greek_pi */
+ { 0x000007f1, 14070 }, /* Greek_rho */
+ { 0x000007f2, 14092 }, /* Greek_sigma */
+ { 0x000007f3, 13564 }, /* Greek_finalsmallsigma */
+ { 0x000007f4, 14127 }, /* Greek_tau */
+ { 0x000007f5, 14175 }, /* Greek_upsilon */
+ { 0x000007f6, 14012 }, /* Greek_phi */
+ { 0x000007f7, 13410 }, /* Greek_chi */
+ { 0x000007f8, 14050 }, /* Greek_psi */
+ { 0x000007f9, 13886 }, /* Greek_omega */
+ { 0x000008a1, 19356 }, /* leftradical */
+ { 0x000008a2, 25621 }, /* topleftradical */
+ { 0x000008a3, 16667 }, /* horizconnector */
+ { 0x000008a4, 25595 }, /* topintegral */
+ { 0x000008a5, 3422 }, /* botintegral */
+ { 0x000008a6, 26505 }, /* vertconnector */
+ { 0x000008a7, 25636 }, /* topleftsqbracket */
+ { 0x000008a8, 3448 }, /* botleftsqbracket */
+ { 0x000008a9, 25685 }, /* toprightsqbracket */
+ { 0x000008aa, 3497 }, /* botrightsqbracket */
+ { 0x000008ab, 25607 }, /* topleftparens */
+ { 0x000008ac, 3434 }, /* botleftparens */
+ { 0x000008ad, 25670 }, /* toprightparens */
+ { 0x000008ae, 3482 }, /* botrightparens */
+ { 0x000008af, 19306 }, /* leftmiddlecurlybrace */
+ { 0x000008b0, 22440 }, /* rightmiddlecurlybrace */
+ { 0x000008b1, 25653 }, /* topleftsummation */
+ { 0x000008b2, 3465 }, /* botleftsummation */
+ { 0x000008b3, 25726 }, /* topvertsummationconnector */
+ { 0x000008b4, 3538 }, /* botvertsummationconnector */
+ { 0x000008b5, 25703 }, /* toprightsummation */
+ { 0x000008b6, 3515 }, /* botrightsummation */
+ { 0x000008b7, 22462 }, /* rightmiddlesummation */
+ { 0x000008bc, 19417 }, /* lessthanequal */
+ { 0x000008bd, 20125 }, /* notequal */
+ { 0x000008be, 13280 }, /* greaterthanequal */
+ { 0x000008bf, 17313 }, /* integral */
+ { 0x000008c0, 25479 }, /* therefore */
+ { 0x000008c1, 26487 }, /* variation */
+ { 0x000008c2, 17275 }, /* infinity */
+ { 0x000008c5, 19947 }, /* nabla */
+ { 0x000008c8, 954 }, /* approximate */
+ { 0x000008c9, 22999 }, /* similarequal */
+ { 0x000008cd, 17196 }, /* ifonlyif */
+ { 0x000008ce, 17247 }, /* implies */
+ { 0x000008cf, 17155 }, /* identical */
+ { 0x000008d6, 22286 }, /* radical */
+ { 0x000008da, 17255 }, /* includedin */
+ { 0x000008db, 17266 }, /* includes */
+ { 0x000008dc, 17322 }, /* intersection */
+ { 0x000008dd, 26362 }, /* union */
+ { 0x000008de, 19457 }, /* logicaland */
+ { 0x000008df, 19468 }, /* logicalor */
+ { 0x000008ef, 21463 }, /* partialderivative */
+ { 0x000008f6, 12656 }, /* function */
+ { 0x000008fb, 19266 }, /* leftarrow */
+ { 0x000008fc, 26387 }, /* uparrow */
+ { 0x000008fd, 22397 }, /* rightarrow */
+ { 0x000008fe, 11332 }, /* downarrow */
+ { 0x000009df, 3410 }, /* blank */
+ { 0x000009e0, 23790 }, /* soliddiamond */
+ { 0x000009e1, 8603 }, /* checkerboard */
+ { 0x000009e2, 17043 }, /* ht */
+ { 0x000009e3, 12413 }, /* ff */
+ { 0x000009e4, 8727 }, /* cr */
+ { 0x000009e5, 19431 }, /* lf */
+ { 0x000009e8, 20075 }, /* nl */
+ { 0x000009e9, 26542 }, /* vt */
+ { 0x000009ea, 19502 }, /* lowrightcorner */
+ { 0x000009eb, 26416 }, /* uprightcorner */
+ { 0x000009ec, 26403 }, /* upleftcorner */
+ { 0x000009ed, 19488 }, /* lowleftcorner */
+ { 0x000009ee, 8730 }, /* crossinglines */
+ { 0x000009ef, 16682 }, /* horizlinescan1 */
+ { 0x000009f0, 16697 }, /* horizlinescan3 */
+ { 0x000009f1, 16712 }, /* horizlinescan5 */
+ { 0x000009f2, 16727 }, /* horizlinescan7 */
+ { 0x000009f3, 16742 }, /* horizlinescan9 */
+ { 0x000009f4, 19397 }, /* leftt */
+ { 0x000009f5, 22545 }, /* rightt */
+ { 0x000009f6, 3533 }, /* bott */
+ { 0x000009f7, 25721 }, /* topt */
+ { 0x000009f8, 26497 }, /* vertbar */
+ { 0x00000aa1, 11928 }, /* emspace */
+ { 0x00000aa2, 12027 }, /* enspace */
+ { 0x00000aa3, 11821 }, /* em3space */
+ { 0x00000aa4, 11830 }, /* em4space */
+ { 0x00000aa5, 11221 }, /* digitspace */
+ { 0x00000aa6, 22145 }, /* punctspace */
+ { 0x00000aa7, 25489 }, /* thinspace */
+ { 0x00000aa8, 14382 }, /* hairspace */
+ { 0x00000aa9, 11855 }, /* emdash */
+ { 0x00000aaa, 11940 }, /* endash */
+ { 0x00000aac, 22987 }, /* signifblank */
+ { 0x00000aae, 11812 }, /* ellipsis */
+ { 0x00000aaf, 11267 }, /* doubbaselinedot */
+ { 0x00000ab0, 20767 }, /* onethird */
+ { 0x00000ab1, 25837 }, /* twothirds */
+ { 0x00000ab2, 20705 }, /* onefifth */
+ { 0x00000ab3, 25802 }, /* twofifths */
+ { 0x00000ab4, 25530 }, /* threefifths */
+ { 0x00000ab5, 12607 }, /* fourfifths */
+ { 0x00000ab6, 20733 }, /* onesixth */
+ { 0x00000ab7, 12569 }, /* fivesixths */
+ { 0x00000ab8, 8506 }, /* careof */
+ { 0x00000abb, 12427 }, /* figdash */
+ { 0x00000abc, 19249 }, /* leftanglebracket */
+ { 0x00000abd, 11140 }, /* decimalpoint */
+ { 0x00000abe, 22379 }, /* rightanglebracket */
+ { 0x00000abf, 19681 }, /* marker */
+ { 0x00000ac3, 20695 }, /* oneeighth */
+ { 0x00000ac4, 25517 }, /* threeeighths */
+ { 0x00000ac5, 12557 }, /* fiveeighths */
+ { 0x00000ac6, 22904 }, /* seveneighths */
+ { 0x00000ac9, 25760 }, /* trademark */
+ { 0x00000aca, 22973 }, /* signaturemark */
+ { 0x00000acb, 25770 }, /* trademarkincircle */
+ { 0x00000acc, 19327 }, /* leftopentriangle */
+ { 0x00000acd, 22483 }, /* rightopentriangle */
+ { 0x00000ace, 11890 }, /* emopencircle */
+ { 0x00000acf, 11903 }, /* emopenrectangle */
+ { 0x00000ad0, 19377 }, /* leftsinglequotemark */
+ { 0x00000ad1, 22524 }, /* rightsinglequotemark */
+ { 0x00000ad2, 19286 }, /* leftdoublequotemark */
+ { 0x00000ad3, 22419 }, /* rightdoublequotemark */
+ { 0x00000ad4, 22067 }, /* prescription */
+ { 0x00000ad5, 21517 }, /* permille */
+ { 0x00000ad6, 19739 }, /* minutes */
+ { 0x00000ad7, 22711 }, /* seconds */
+ { 0x00000ad9, 19181 }, /* latincross */
+ { 0x00000ada, 16626 }, /* hexagram */
+ { 0x00000adb, 12455 }, /* filledrectbullet */
+ { 0x00000adc, 12435 }, /* filledlefttribullet */
+ { 0x00000add, 12472 }, /* filledrighttribullet */
+ { 0x00000ade, 11862 }, /* emfilledcircle */
+ { 0x00000adf, 11877 }, /* emfilledrect */
+ { 0x00000ae0, 11991 }, /* enopencircbullet */
+ { 0x00000ae1, 12008 }, /* enopensquarebullet */
+ { 0x00000ae2, 20794 }, /* openrectbullet */
+ { 0x00000ae3, 20836 }, /* opentribulletup */
+ { 0x00000ae4, 20818 }, /* opentribulletdown */
+ { 0x00000ae5, 20809 }, /* openstar */
+ { 0x00000ae6, 11947 }, /* enfilledcircbullet */
+ { 0x00000ae7, 11966 }, /* enfilledsqbullet */
+ { 0x00000ae8, 12513 }, /* filledtribulletup */
+ { 0x00000ae9, 12493 }, /* filledtribulletdown */
+ { 0x00000aea, 19344 }, /* leftpointer */
+ { 0x00000aeb, 22501 }, /* rightpointer */
+ { 0x00000aec, 8649 }, /* club */
+ { 0x00000aed, 11213 }, /* diamond */
+ { 0x00000aee, 16080 }, /* heart */
+ { 0x00000af0, 19668 }, /* maltesecross */
+ { 0x00000af1, 10358 }, /* dagger */
+ { 0x00000af2, 11295 }, /* doubledagger */
+ { 0x00000af3, 8616 }, /* checkmark */
+ { 0x00000af4, 3380 }, /* ballotcross */
+ { 0x00000af5, 19860 }, /* musicalsharp */
+ { 0x00000af6, 19848 }, /* musicalflat */
+ { 0x00000af7, 19657 }, /* malesymbol */
+ { 0x00000af8, 12400 }, /* femalesymbol */
+ { 0x00000af9, 24354 }, /* telephone */
+ { 0x00000afa, 24364 }, /* telephonerecorder */
+ { 0x00000afb, 21537 }, /* phonographcopyright */
+ { 0x00000afc, 8513 }, /* caret */
+ { 0x00000afd, 23028 }, /* singlelowquotemark */
+ { 0x00000afe, 11308 }, /* doublelowquotemark */
+ { 0x00000aff, 8775 }, /* cursor */
+ { 0x00000ba3, 19276 }, /* leftcaret */
+ { 0x00000ba6, 22408 }, /* rightcaret */
+ { 0x00000ba8, 11342 }, /* downcaret */
+ { 0x00000ba9, 26395 }, /* upcaret */
+ { 0x00000bc0, 21324 }, /* overbar */
+ { 0x00000bc2, 11371 }, /* downtack */
+ { 0x00000bc3, 26430 }, /* upshoe */
+ { 0x00000bc4, 11361 }, /* downstile */
+ { 0x00000bc6, 26337 }, /* underbar */
+ { 0x00000bca, 18142 }, /* jot */
+ { 0x00000bcc, 22160 }, /* quad */
+ { 0x00000bce, 26445 }, /* uptack */
+ { 0x00000bcf, 8626 }, /* circle */
+ { 0x00000bd3, 26437 }, /* upstile */
+ { 0x00000bd6, 11352 }, /* downshoe */
+ { 0x00000bd8, 22514 }, /* rightshoe */
+ { 0x00000bda, 19368 }, /* leftshoe */
+ { 0x00000bdc, 19403 }, /* lefttack */
+ { 0x00000bfc, 22552 }, /* righttack */
+ { 0x00000cdf, 16173 }, /* hebrew_doublelowline */
+ { 0x00000ce0, 16086 }, /* hebrew_aleph */
+ { 0x00000ce1, 16111 }, /* hebrew_bet */
+ { 0x00000ce2, 16292 }, /* hebrew_gimel */
+ { 0x00000ce3, 16146 }, /* hebrew_dalet */
+ { 0x00000ce4, 16319 }, /* hebrew_he */
+ { 0x00000ce5, 16531 }, /* hebrew_waw */
+ { 0x00000ce6, 16577 }, /* hebrew_zain */
+ { 0x00000ce7, 16134 }, /* hebrew_chet */
+ { 0x00000ce8, 16508 }, /* hebrew_tet */
+ { 0x00000ce9, 16542 }, /* hebrew_yod */
+ { 0x00000cea, 16194 }, /* hebrew_finalkaph */
+ { 0x00000ceb, 16340 }, /* hebrew_kaph */
+ { 0x00000cec, 16363 }, /* hebrew_lamed */
+ { 0x00000ced, 16211 }, /* hebrew_finalmem */
+ { 0x00000cee, 16376 }, /* hebrew_mem */
+ { 0x00000cef, 16227 }, /* hebrew_finalnun */
+ { 0x00000cf0, 16387 }, /* hebrew_nun */
+ { 0x00000cf1, 16432 }, /* hebrew_samech */
+ { 0x00000cf2, 16099 }, /* hebrew_ayin */
+ { 0x00000cf3, 16243 }, /* hebrew_finalpe */
+ { 0x00000cf4, 16398 }, /* hebrew_pe */
+ { 0x00000cf5, 16258 }, /* hebrew_finalzade */
+ { 0x00000cf6, 16553 }, /* hebrew_zade */
+ { 0x00000cf7, 16408 }, /* hebrew_qoph */
+ { 0x00000cf8, 16420 }, /* hebrew_resh */
+ { 0x00000cf9, 16460 }, /* hebrew_shin */
+ { 0x00000cfa, 16497 }, /* hebrew_taw */
+ { 0x00000da1, 24617 }, /* Thai_kokai */
+ { 0x00000da2, 24547 }, /* Thai_khokhai */
+ { 0x00000da3, 24573 }, /* Thai_khokhuat */
+ { 0x00000da4, 24587 }, /* Thai_khokhwai */
+ { 0x00000da5, 24560 }, /* Thai_khokhon */
+ { 0x00000da6, 24601 }, /* Thai_khorakhang */
+ { 0x00000da7, 24930 }, /* Thai_ngongu */
+ { 0x00000da8, 24423 }, /* Thai_chochan */
+ { 0x00000da9, 24450 }, /* Thai_choching */
+ { 0x00000daa, 24436 }, /* Thai_chochang */
+ { 0x00000dab, 25291 }, /* Thai_soso */
+ { 0x00000dac, 24464 }, /* Thai_chochoe */
+ { 0x00000dad, 25467 }, /* Thai_yoying */
+ { 0x00000dae, 24477 }, /* Thai_dochada */
+ { 0x00000daf, 25420 }, /* Thai_topatak */
+ { 0x00000db0, 25379 }, /* Thai_thothan */
+ { 0x00000db1, 25329 }, /* Thai_thonangmontho */
+ { 0x00000db2, 25348 }, /* Thai_thophuthao */
+ { 0x00000db3, 24956 }, /* Thai_nonen */
+ { 0x00000db4, 24490 }, /* Thai_dodek */
+ { 0x00000db5, 25433 }, /* Thai_totao */
+ { 0x00000db6, 25406 }, /* Thai_thothung */
+ { 0x00000db7, 25364 }, /* Thai_thothahan */
+ { 0x00000db8, 25392 }, /* Thai_thothong */
+ { 0x00000db9, 24967 }, /* Thai_nonu */
+ { 0x00000dba, 24409 }, /* Thai_bobaimai */
+ { 0x00000dbb, 25058 }, /* Thai_popla */
+ { 0x00000dbc, 25028 }, /* Thai_phophung */
+ { 0x00000dbd, 24501 }, /* Thai_fofa */
+ { 0x00000dbe, 25015 }, /* Thai_phophan */
+ { 0x00000dbf, 24511 }, /* Thai_fofan */
+ { 0x00000dc0, 25042 }, /* Thai_phosamphao */
+ { 0x00000dc1, 24920 }, /* Thai_moma */
+ { 0x00000dc2, 25456 }, /* Thai_yoyak */
+ { 0x00000dc3, 25069 }, /* Thai_rorua */
+ { 0x00000dc4, 25080 }, /* Thai_ru */
+ { 0x00000dc5, 24780 }, /* Thai_loling */
+ { 0x00000dc6, 24792 }, /* Thai_lu */
+ { 0x00000dc7, 25444 }, /* Thai_wowaen */
+ { 0x00000dc8, 25279 }, /* Thai_sosala */
+ { 0x00000dc9, 25267 }, /* Thai_sorusi */
+ { 0x00000dca, 25301 }, /* Thai_sosua */
+ { 0x00000dcb, 24522 }, /* Thai_hohip */
+ { 0x00000dcc, 24767 }, /* Thai_lochula */
+ { 0x00000dcd, 24977 }, /* Thai_oang */
+ { 0x00000dce, 24533 }, /* Thai_honokhuk */
+ { 0x00000dcf, 24987 }, /* Thai_paiyannoi */
+ { 0x00000dd0, 25088 }, /* Thai_saraa */
+ { 0x00000dd1, 24828 }, /* Thai_maihanakat */
+ { 0x00000dd2, 25099 }, /* Thai_saraaa */
+ { 0x00000dd3, 25162 }, /* Thai_saraam */
+ { 0x00000dd4, 25185 }, /* Thai_sarai */
+ { 0x00000dd5, 25196 }, /* Thai_saraii */
+ { 0x00000dd6, 25230 }, /* Thai_saraue */
+ { 0x00000dd7, 25242 }, /* Thai_sarauee */
+ { 0x00000dd8, 25219 }, /* Thai_sarau */
+ { 0x00000dd9, 25255 }, /* Thai_sarauu */
+ { 0x00000dda, 25002 }, /* Thai_phinthu */
+ { 0x00000dde, 24844 }, /* Thai_maihanakat_maitho */
+ { 0x00000ddf, 24399 }, /* Thai_baht */
+ { 0x00000de0, 25174 }, /* Thai_sarae */
+ { 0x00000de1, 25111 }, /* Thai_saraae */
+ { 0x00000de2, 25208 }, /* Thai_sarao */
+ { 0x00000de3, 25143 }, /* Thai_saraaimaimuan */
+ { 0x00000de4, 25123 }, /* Thai_saraaimaimalai */
+ { 0x00000de5, 24628 }, /* Thai_lakkhangyao */
+ { 0x00000de6, 24906 }, /* Thai_maiyamok */
+ { 0x00000de7, 24867 }, /* Thai_maitaikhu */
+ { 0x00000de8, 24817 }, /* Thai_maiek */
+ { 0x00000de9, 24882 }, /* Thai_maitho */
+ { 0x00000dea, 24894 }, /* Thai_maitri */
+ { 0x00000deb, 24800 }, /* Thai_maichattawa */
+ { 0x00000dec, 25312 }, /* Thai_thanthakhat */
+ { 0x00000ded, 24942 }, /* Thai_nikhahit */
+ { 0x00000df0, 24755 }, /* Thai_leksun */
+ { 0x00000df1, 24693 }, /* Thai_leknung */
+ { 0x00000df2, 24742 }, /* Thai_leksong */
+ { 0x00000df3, 24719 }, /* Thai_leksam */
+ { 0x00000df4, 24731 }, /* Thai_leksi */
+ { 0x00000df5, 24658 }, /* Thai_lekha */
+ { 0x00000df6, 24669 }, /* Thai_lekhok */
+ { 0x00000df7, 24645 }, /* Thai_lekchet */
+ { 0x00000df8, 24706 }, /* Thai_lekpaet */
+ { 0x00000df9, 24681 }, /* Thai_lekkao */
+ { 0x00000ea1, 15181 }, /* Hangul_Kiyeog */
+ { 0x00000ea2, 15726 }, /* Hangul_SsangKiyeog */
+ { 0x00000ea3, 15195 }, /* Hangul_KiyeogSios */
+ { 0x00000ea4, 15276 }, /* Hangul_Nieun */
+ { 0x00000ea5, 15307 }, /* Hangul_NieunJieuj */
+ { 0x00000ea6, 15289 }, /* Hangul_NieunHieuh */
+ { 0x00000ea7, 14488 }, /* Hangul_Dikeud */
+ { 0x00000ea8, 15689 }, /* Hangul_SsangDikeud */
+ { 0x00000ea9, 15461 }, /* Hangul_Rieul */
+ { 0x00000eaa, 15492 }, /* Hangul_RieulKiyeog */
+ { 0x00000eab, 15511 }, /* Hangul_RieulMieum */
+ { 0x00000eac, 15548 }, /* Hangul_RieulPieub */
+ { 0x00000ead, 15566 }, /* Hangul_RieulSios */
+ { 0x00000eae, 15583 }, /* Hangul_RieulTieut */
+ { 0x00000eaf, 15529 }, /* Hangul_RieulPhieuf */
+ { 0x00000eb0, 15474 }, /* Hangul_RieulHieuh */
+ { 0x00000eb1, 15238 }, /* Hangul_Mieum */
+ { 0x00000eb2, 15373 }, /* Hangul_Pieub */
+ { 0x00000eb3, 15745 }, /* Hangul_SsangPieub */
+ { 0x00000eb4, 15386 }, /* Hangul_PieubSios */
+ { 0x00000eb5, 15662 }, /* Hangul_Sios */
+ { 0x00000eb6, 15763 }, /* Hangul_SsangSios */
+ { 0x00000eb7, 14577 }, /* Hangul_Ieung */
+ { 0x00000eb8, 15154 }, /* Hangul_Jieuj */
+ { 0x00000eb9, 15708 }, /* Hangul_SsangJieuj */
+ { 0x00000eba, 14458 }, /* Hangul_Cieuc */
+ { 0x00000ebb, 15167 }, /* Hangul_Khieuq */
+ { 0x00000ebc, 15883 }, /* Hangul_Tieut */
+ { 0x00000ebd, 15359 }, /* Hangul_Phieuf */
+ { 0x00000ebe, 14555 }, /* Hangul_Hieuh */
+ { 0x00000ebf, 14399 }, /* Hangul_A */
+ { 0x00000ec0, 14408 }, /* Hangul_AE */
+ { 0x00000ec1, 15957 }, /* Hangul_YA */
+ { 0x00000ec2, 15967 }, /* Hangul_YAE */
+ { 0x00000ec3, 14522 }, /* Hangul_EO */
+ { 0x00000ec4, 14502 }, /* Hangul_E */
+ { 0x00000ec5, 15988 }, /* Hangul_YEO */
+ { 0x00000ec6, 15978 }, /* Hangul_YE */
+ { 0x00000ec7, 15325 }, /* Hangul_O */
+ { 0x00000ec8, 15905 }, /* Hangul_WA */
+ { 0x00000ec9, 15915 }, /* Hangul_WAE */
+ { 0x00000eca, 15334 }, /* Hangul_OE */
+ { 0x00000ecb, 16028 }, /* Hangul_YO */
+ { 0x00000ecc, 15896 }, /* Hangul_U */
+ { 0x00000ecd, 15936 }, /* Hangul_WEO */
+ { 0x00000ece, 15926 }, /* Hangul_WE */
+ { 0x00000ecf, 15947 }, /* Hangul_WI */
+ { 0x00000ed0, 16038 }, /* Hangul_YU */
+ { 0x00000ed1, 14532 }, /* Hangul_EU */
+ { 0x00000ed2, 16018 }, /* Hangul_YI */
+ { 0x00000ed3, 14568 }, /* Hangul_I */
+ { 0x00000ed4, 14682 }, /* Hangul_J_Kiyeog */
+ { 0x00000ed5, 15052 }, /* Hangul_J_SsangKiyeog */
+ { 0x00000ed6, 14698 }, /* Hangul_J_KiyeogSios */
+ { 0x00000ed7, 14760 }, /* Hangul_J_Nieun */
+ { 0x00000ed8, 14795 }, /* Hangul_J_NieunJieuj */
+ { 0x00000ed9, 14775 }, /* Hangul_J_NieunHieuh */
+ { 0x00000eda, 14605 }, /* Hangul_J_Dikeud */
+ { 0x00000edb, 14882 }, /* Hangul_J_Rieul */
+ { 0x00000edc, 14917 }, /* Hangul_J_RieulKiyeog */
+ { 0x00000edd, 14938 }, /* Hangul_J_RieulMieum */
+ { 0x00000ede, 14979 }, /* Hangul_J_RieulPieub */
+ { 0x00000edf, 14999 }, /* Hangul_J_RieulSios */
+ { 0x00000ee0, 15018 }, /* Hangul_J_RieulTieut */
+ { 0x00000ee1, 14958 }, /* Hangul_J_RieulPhieuf */
+ { 0x00000ee2, 14897 }, /* Hangul_J_RieulHieuh */
+ { 0x00000ee3, 14745 }, /* Hangul_J_Mieum */
+ { 0x00000ee4, 14848 }, /* Hangul_J_Pieub */
+ { 0x00000ee5, 14863 }, /* Hangul_J_PieubSios */
+ { 0x00000ee6, 15038 }, /* Hangul_J_Sios */
+ { 0x00000ee7, 15073 }, /* Hangul_J_SsangSios */
+ { 0x00000ee8, 14636 }, /* Hangul_J_Ieung */
+ { 0x00000ee9, 14651 }, /* Hangul_J_Jieuj */
+ { 0x00000eea, 14590 }, /* Hangul_J_Cieuc */
+ { 0x00000eeb, 14666 }, /* Hangul_J_Khieuq */
+ { 0x00000eec, 15092 }, /* Hangul_J_Tieut */
+ { 0x00000eed, 14832 }, /* Hangul_J_Phieuf */
+ { 0x00000eee, 14621 }, /* Hangul_J_Hieuh */
+ { 0x00000eef, 15601 }, /* Hangul_RieulYeorinHieuh */
+ { 0x00000ef0, 15793 }, /* Hangul_SunkyeongeumMieum */
+ { 0x00000ef1, 15844 }, /* Hangul_SunkyeongeumPieub */
+ { 0x00000ef2, 15344 }, /* Hangul_PanSios */
+ { 0x00000ef3, 15213 }, /* Hangul_KkogjiDalrinIeung */
+ { 0x00000ef4, 15818 }, /* Hangul_SunkyeongeumPhieuf */
+ { 0x00000ef5, 15999 }, /* Hangul_YeorinHieuh */
+ { 0x00000ef6, 14418 }, /* Hangul_AraeA */
+ { 0x00000ef7, 14431 }, /* Hangul_AraeAE */
+ { 0x00000ef8, 14815 }, /* Hangul_J_PanSios */
+ { 0x00000ef9, 14718 }, /* Hangul_J_KkogjiDalrinIeung */
+ { 0x00000efa, 15107 }, /* Hangul_J_YeorinHieuh */
+ { 0x00000eff, 18797 }, /* Korean_Won */
+ { 0x000013bc, 20514 }, /* OE */
+ { 0x000013bd, 20517 }, /* oe */
+ { 0x000013be, 29045 }, /* Ydiaeresis */
+ { 0x000020ac, 12090 }, /* EuroSign */
+ { 0x0000fd01, 125 }, /* 3270_Duplicate */
+ { 0x0000fd02, 195 }, /* 3270_FieldMark */
+ { 0x0000fd03, 343 }, /* 3270_Right2 */
+ { 0x0000fd04, 245 }, /* 3270_Left2 */
+ { 0x0000fd05, 33 }, /* 3270_BackTab */
+ { 0x0000fd06, 151 }, /* 3270_EraseEOF */
+ { 0x0000fd07, 165 }, /* 3270_EraseInput */
+ { 0x0000fd08, 332 }, /* 3270_Reset */
+ { 0x0000fd09, 310 }, /* 3270_Quit */
+ { 0x0000fd0a, 256 }, /* 3270_PA1 */
+ { 0x0000fd0b, 265 }, /* 3270_PA2 */
+ { 0x0000fd0c, 274 }, /* 3270_PA3 */
+ { 0x0000fd0d, 376 }, /* 3270_Test */
+ { 0x0000fd0e, 23 }, /* 3270_Attn */
+ { 0x0000fd0f, 74 }, /* 3270_CursorBlink */
+ { 0x0000fd10, 8 }, /* 3270_AltCursor */
+ { 0x0000fd11, 231 }, /* 3270_KeyClick */
+ { 0x0000fd12, 221 }, /* 3270_Jump */
+ { 0x0000fd13, 210 }, /* 3270_Ident */
+ { 0x0000fd14, 355 }, /* 3270_Rule */
+ { 0x0000fd15, 64 }, /* 3270_Copy */
+ { 0x0000fd16, 283 }, /* 3270_Play */
+ { 0x0000fd17, 365 }, /* 3270_Setup */
+ { 0x0000fd18, 320 }, /* 3270_Record */
+ { 0x0000fd19, 46 }, /* 3270_ChangeScreen */
+ { 0x0000fd1a, 109 }, /* 3270_DeleteWord */
+ { 0x0000fd1b, 181 }, /* 3270_ExSelect */
+ { 0x0000fd1c, 91 }, /* 3270_CursorSelect */
+ { 0x0000fd1d, 293 }, /* 3270_PrintScreen */
+ { 0x0000fd1e, 140 }, /* 3270_Enter */
+ { 0x0000fe01, 17781 }, /* ISO_Lock */
+ { 0x0000fe02, 17664 }, /* ISO_Level2_Latch */
+ { 0x0000fe03, 17714 }, /* ISO_Level3_Shift */
+ { 0x0000fe04, 17681 }, /* ISO_Level3_Latch */
+ { 0x0000fe05, 17698 }, /* ISO_Level3_Lock */
+ { 0x0000fe06, 17569 }, /* ISO_Group_Latch */
+ { 0x0000fe07, 17585 }, /* ISO_Group_Lock */
+ { 0x0000fe08, 17826 }, /* ISO_Next_Group */
+ { 0x0000fe09, 17841 }, /* ISO_Next_Group_Lock */
+ { 0x0000fe0a, 17950 }, /* ISO_Prev_Group */
+ { 0x0000fe0b, 17965 }, /* ISO_Prev_Group_Lock */
+ { 0x0000fe0c, 17532 }, /* ISO_First_Group */
+ { 0x0000fe0d, 17548 }, /* ISO_First_Group_Lock */
+ { 0x0000fe0e, 17616 }, /* ISO_Last_Group */
+ { 0x0000fe0f, 17631 }, /* ISO_Last_Group_Lock */
+ { 0x0000fe11, 17764 }, /* ISO_Level5_Shift */
+ { 0x0000fe12, 17731 }, /* ISO_Level5_Latch */
+ { 0x0000fe13, 17748 }, /* ISO_Level5_Lock */
+ { 0x0000fe20, 17651 }, /* ISO_Left_Tab */
+ { 0x0000fe21, 17809 }, /* ISO_Move_Line_Up */
+ { 0x0000fe22, 17790 }, /* ISO_Move_Line_Down */
+ { 0x0000fe23, 17883 }, /* ISO_Partial_Line_Up */
+ { 0x0000fe24, 17861 }, /* ISO_Partial_Line_Down */
+ { 0x0000fe25, 17903 }, /* ISO_Partial_Space_Left */
+ { 0x0000fe26, 17926 }, /* ISO_Partial_Space_Right */
+ { 0x0000fe27, 18059 }, /* ISO_Set_Margin_Left */
+ { 0x0000fe28, 18079 }, /* ISO_Set_Margin_Right */
+ { 0x0000fe29, 18010 }, /* ISO_Release_Margin_Left */
+ { 0x0000fe2a, 18034 }, /* ISO_Release_Margin_Right */
+ { 0x0000fe2b, 17985 }, /* ISO_Release_Both_Margins */
+ { 0x0000fe2c, 17470 }, /* ISO_Fast_Cursor_Left */
+ { 0x0000fe2d, 17491 }, /* ISO_Fast_Cursor_Right */
+ { 0x0000fe2e, 17513 }, /* ISO_Fast_Cursor_Up */
+ { 0x0000fe2f, 17449 }, /* ISO_Fast_Cursor_Down */
+ { 0x0000fe30, 17372 }, /* ISO_Continuous_Underline */
+ { 0x0000fe31, 17397 }, /* ISO_Discontinuous_Underline */
+ { 0x0000fe32, 17425 }, /* ISO_Emphasize */
+ { 0x0000fe33, 17354 }, /* ISO_Center_Object */
+ { 0x0000fe34, 17439 }, /* ISO_Enter */
+ { 0x0000fe50, 10858 }, /* dead_grave */
+ { 0x0000fe51, 10531 }, /* dead_acute */
+ { 0x0000fe52, 10754 }, /* dead_circumflex */
+ { 0x0000fe53, 11097 }, /* dead_tilde */
+ { 0x0000fe54, 10980 }, /* dead_macron */
+ { 0x0000fe55, 10700 }, /* dead_breve */
+ { 0x0000fe56, 10455 }, /* dead_abovedot */
+ { 0x0000fe57, 10795 }, /* dead_diaeresis */
+ { 0x0000fe58, 10493 }, /* dead_abovering */
+ { 0x0000fe59, 10810 }, /* dead_doubleacute */
+ { 0x0000fe5a, 10730 }, /* dead_caron */
+ { 0x0000fe5b, 10741 }, /* dead_cedilla */
+ { 0x0000fe5c, 11006 }, /* dead_ogonek */
+ { 0x0000fe5d, 10933 }, /* dead_iota */
+ { 0x0000fe5e, 11122 }, /* dead_voiced_sound */
+ { 0x0000fe5f, 11046 }, /* dead_semivoiced_sound */
+ { 0x0000fe60, 10615 }, /* dead_belowdot */
+ { 0x0000fe61, 10880 }, /* dead_hook */
+ { 0x0000fe62, 10890 }, /* dead_horn */
+ { 0x0000fe63, 11085 }, /* dead_stroke */
+ { 0x0000fe64, 10439 }, /* dead_abovecomma */
+ { 0x0000fe65, 10469 }, /* dead_abovereversedcomma */
+ { 0x0000fe66, 10827 }, /* dead_doublegrave */
+ { 0x0000fe67, 10646 }, /* dead_belowring */
+ { 0x0000fe68, 10629 }, /* dead_belowmacron */
+ { 0x0000fe69, 10558 }, /* dead_belowcircumflex */
+ { 0x0000fe6a, 10661 }, /* dead_belowtilde */
+ { 0x0000fe6b, 10542 }, /* dead_belowbreve */
+ { 0x0000fe6c, 10595 }, /* dead_belowdiaeresis */
+ { 0x0000fe6d, 10914 }, /* dead_invertedbreve */
+ { 0x0000fe6e, 10579 }, /* dead_belowcomma */
+ { 0x0000fe6f, 10770 }, /* dead_currency */
+ { 0x0000fe70, 583 }, /* AccessX_Enable */
+ { 0x0000fe71, 598 }, /* AccessX_Feedback_Enable */
+ { 0x0000fe72, 22342 }, /* RepeatKeys_Enable */
+ { 0x0000fe73, 23774 }, /* SlowKeys_Enable */
+ { 0x0000fe74, 3564 }, /* BounceKeys_Enable */
+ { 0x0000fe75, 23836 }, /* StickyKeys_Enable */
+ { 0x0000fe76, 19782 }, /* MouseKeys_Enable */
+ { 0x0000fe77, 19759 }, /* MouseKeys_Accel_Enable */
+ { 0x0000fe78, 21332 }, /* Overlay1_Enable */
+ { 0x0000fe79, 21348 }, /* Overlay2_Enable */
+ { 0x0000fe7a, 3309 }, /* AudibleBell_Enable */
+ { 0x0000fe80, 10425 }, /* dead_a */
+ { 0x0000fe81, 10432 }, /* dead_A */
+ { 0x0000fe82, 10844 }, /* dead_e */
+ { 0x0000fe83, 10851 }, /* dead_E */
+ { 0x0000fe84, 10900 }, /* dead_i */
+ { 0x0000fe85, 10907 }, /* dead_I */
+ { 0x0000fe86, 10992 }, /* dead_o */
+ { 0x0000fe87, 10999 }, /* dead_O */
+ { 0x0000fe88, 11108 }, /* dead_u */
+ { 0x0000fe89, 11115 }, /* dead_U */
+ { 0x0000fe8a, 11068 }, /* dead_small_schwa */
+ { 0x0000fe8b, 10711 }, /* dead_capital_schwa */
+ { 0x0000fe8c, 10869 }, /* dead_greek */
+ { 0x0000fe90, 10967 }, /* dead_lowline */
+ { 0x0000fe91, 10508 }, /* dead_aboveverticalline */
+ { 0x0000fe92, 10677 }, /* dead_belowverticalline */
+ { 0x0000fe93, 10943 }, /* dead_longsolidusoverlay */
+ { 0x0000fea0, 8594 }, /* ch */
+ { 0x0000fea1, 8597 }, /* Ch */
+ { 0x0000fea2, 8600 }, /* CH */
+ { 0x0000fea3, 8443 }, /* c_h */
+ { 0x0000fea4, 8447 }, /* C_h */
+ { 0x0000fea5, 8451 }, /* C_H */
+ { 0x0000fed0, 12536 }, /* First_Virtual_Screen */
+ { 0x0000fed1, 22080 }, /* Prev_Virtual_Screen */
+ { 0x0000fed2, 20028 }, /* Next_Virtual_Screen */
+ { 0x0000fed4, 19161 }, /* Last_Virtual_Screen */
+ { 0x0000fed5, 24382 }, /* Terminate_Server */
+ { 0x0000fee0, 21998 }, /* Pointer_Left */
+ { 0x0000fee1, 22011 }, /* Pointer_Right */
+ { 0x0000fee2, 22025 }, /* Pointer_Up */
+ { 0x0000fee3, 21843 }, /* Pointer_Down */
+ { 0x0000fee4, 22036 }, /* Pointer_UpLeft */
+ { 0x0000fee5, 22051 }, /* Pointer_UpRight */
+ { 0x0000fee6, 21856 }, /* Pointer_DownLeft */
+ { 0x0000fee7, 21873 }, /* Pointer_DownRight */
+ { 0x0000fee8, 21671 }, /* Pointer_Button_Dflt */
+ { 0x0000fee9, 21591 }, /* Pointer_Button1 */
+ { 0x0000feea, 21607 }, /* Pointer_Button2 */
+ { 0x0000feeb, 21623 }, /* Pointer_Button3 */
+ { 0x0000feec, 21639 }, /* Pointer_Button4 */
+ { 0x0000feed, 21655 }, /* Pointer_Button5 */
+ { 0x0000feee, 21781 }, /* Pointer_DblClick_Dflt */
+ { 0x0000feef, 21691 }, /* Pointer_DblClick1 */
+ { 0x0000fef0, 21709 }, /* Pointer_DblClick2 */
+ { 0x0000fef1, 21727 }, /* Pointer_DblClick3 */
+ { 0x0000fef2, 21745 }, /* Pointer_DblClick4 */
+ { 0x0000fef3, 21763 }, /* Pointer_DblClick5 */
+ { 0x0000fef4, 21961 }, /* Pointer_Drag_Dflt */
+ { 0x0000fef5, 21891 }, /* Pointer_Drag1 */
+ { 0x0000fef6, 21905 }, /* Pointer_Drag2 */
+ { 0x0000fef7, 21919 }, /* Pointer_Drag3 */
+ { 0x0000fef8, 21933 }, /* Pointer_Drag4 */
+ { 0x0000fef9, 21979 }, /* Pointer_EnableKeys */
+ { 0x0000fefa, 21572 }, /* Pointer_Accelerate */
+ { 0x0000fefb, 21803 }, /* Pointer_DfltBtnNext */
+ { 0x0000fefc, 21823 }, /* Pointer_DfltBtnPrev */
+ { 0x0000fefd, 21947 }, /* Pointer_Drag5 */
+ { 0x0000ff08, 3362 }, /* BackSpace */
+ { 0x0000ff09, 24298 }, /* Tab */
+ { 0x0000ff0a, 19434 }, /* Linefeed */
+ { 0x0000ff0b, 8633 }, /* Clear */
+ { 0x0000ff0d, 22366 }, /* Return */
+ { 0x0000ff13, 21481 }, /* Pause */
+ { 0x0000ff14, 22699 }, /* Scroll_Lock */
+ { 0x0000ff15, 24279 }, /* Sys_Req */
+ { 0x0000ff1b, 12057 }, /* Escape */
+ { 0x0000ff20, 19811 }, /* Multi_key */
+ { 0x0000ff21, 18745 }, /* Kanji */
+ { 0x0000ff22, 19802 }, /* Muhenkan */
+ { 0x0000ff23, 16614 }, /* Henkan_Mode */
+ { 0x0000ff24, 22562 }, /* Romaji */
+ { 0x0000ff25, 16635 }, /* Hiragana */
+ { 0x0000ff26, 18770 }, /* Katakana */
+ { 0x0000ff27, 16644 }, /* Hiragana_Katakana */
+ { 0x0000ff28, 29161 }, /* Zenkaku */
+ { 0x0000ff29, 16048 }, /* Hankaku */
+ { 0x0000ff2a, 29169 }, /* Zenkaku_Hankaku */
+ { 0x0000ff2b, 25752 }, /* Touroku */
+ { 0x0000ff2c, 19698 }, /* Massyo */
+ { 0x0000ff2d, 18351 }, /* Kana_Lock */
+ { 0x0000ff2e, 18562 }, /* Kana_Shift */
+ { 0x0000ff2f, 11779 }, /* Eisu_Shift */
+ { 0x0000ff30, 11790 }, /* Eisu_toggle */
+ { 0x0000ff31, 14392 }, /* Hangul */
+ { 0x0000ff32, 15780 }, /* Hangul_Start */
+ { 0x0000ff33, 14511 }, /* Hangul_End */
+ { 0x0000ff34, 14542 }, /* Hangul_Hanja */
+ { 0x0000ff35, 15128 }, /* Hangul_Jamo */
+ { 0x0000ff36, 15625 }, /* Hangul_Romaja */
+ { 0x0000ff37, 8654 }, /* Codeinput */
+ { 0x0000ff38, 15140 }, /* Hangul_Jeonja */
+ { 0x0000ff39, 14445 }, /* Hangul_Banja */
+ { 0x0000ff3a, 15420 }, /* Hangul_PreHanja */
+ { 0x0000ff3b, 15403 }, /* Hangul_PostHanja */
+ { 0x0000ff3c, 23012 }, /* SingleCandidate */
+ { 0x0000ff3d, 19821 }, /* MultipleCandidate */
+ { 0x0000ff3e, 22100 }, /* PreviousCandidate */
+ { 0x0000ff3f, 15674 }, /* Hangul_Special */
+ { 0x0000ff50, 16662 }, /* Home */
+ { 0x0000ff51, 19244 }, /* Left */
+ { 0x0000ff52, 26384 }, /* Up */
+ { 0x0000ff53, 22373 }, /* Right */
+ { 0x0000ff54, 11327 }, /* Down */
+ { 0x0000ff55, 22124 }, /* Prior */
+ { 0x0000ff56, 20023 }, /* Next */
+ { 0x0000ff57, 11936 }, /* End */
+ { 0x0000ff58, 3404 }, /* Begin */
+ { 0x0000ff60, 22727 }, /* Select */
+ { 0x0000ff61, 22118 }, /* Print */
+ { 0x0000ff62, 12117 }, /* Execute */
+ { 0x0000ff63, 17284 }, /* Insert */
+ { 0x0000ff65, 26357 }, /* Undo */
+ { 0x0000ff66, 22326 }, /* Redo */
+ { 0x0000ff67, 19705 }, /* Menu */
+ { 0x0000ff68, 12531 }, /* Find */
+ { 0x0000ff69, 8489 }, /* Cancel */
+ { 0x0000ff6a, 16602 }, /* Help */
+ { 0x0000ff6b, 8377 }, /* Break */
+ { 0x0000ff7e, 19747 }, /* Mode_switch */
+ { 0x0000ff7f, 20169 }, /* Num_Lock */
+ { 0x0000ff80, 19074 }, /* KP_Space */
+ { 0x0000ff89, 19095 }, /* KP_Tab */
+ { 0x0000ff8d, 18931 }, /* KP_Enter */
+ { 0x0000ff91, 18949 }, /* KP_F1 */
+ { 0x0000ff92, 18955 }, /* KP_F2 */
+ { 0x0000ff93, 18961 }, /* KP_F3 */
+ { 0x0000ff94, 18967 }, /* KP_F4 */
+ { 0x0000ff95, 18973 }, /* KP_Home */
+ { 0x0000ff96, 18991 }, /* KP_Left */
+ { 0x0000ff97, 19102 }, /* KP_Up */
+ { 0x0000ff98, 19052 }, /* KP_Right */
+ { 0x0000ff99, 18916 }, /* KP_Down */
+ { 0x0000ff9a, 19043 }, /* KP_Prior */
+ { 0x0000ff9b, 19011 }, /* KP_Next */
+ { 0x0000ff9c, 18924 }, /* KP_End */
+ { 0x0000ff9d, 18876 }, /* KP_Begin */
+ { 0x0000ff9e, 18981 }, /* KP_Insert */
+ { 0x0000ff9f, 18896 }, /* KP_Delete */
+ { 0x0000ffaa, 18999 }, /* KP_Multiply */
+ { 0x0000ffab, 18858 }, /* KP_Add */
+ { 0x0000ffac, 19061 }, /* KP_Separator */
+ { 0x0000ffad, 19083 }, /* KP_Subtract */
+ { 0x0000ffae, 18885 }, /* KP_Decimal */
+ { 0x0000ffaf, 18906 }, /* KP_Divide */
+ { 0x0000ffb0, 18808 }, /* KP_0 */
+ { 0x0000ffb1, 18813 }, /* KP_1 */
+ { 0x0000ffb2, 18818 }, /* KP_2 */
+ { 0x0000ffb3, 18823 }, /* KP_3 */
+ { 0x0000ffb4, 18828 }, /* KP_4 */
+ { 0x0000ffb5, 18833 }, /* KP_5 */
+ { 0x0000ffb6, 18838 }, /* KP_6 */
+ { 0x0000ffb7, 18843 }, /* KP_7 */
+ { 0x0000ffb8, 18848 }, /* KP_8 */
+ { 0x0000ffb9, 18853 }, /* KP_9 */
+ { 0x0000ffbd, 18940 }, /* KP_Equal */
+ { 0x0000ffbe, 12159 }, /* F1 */
+ { 0x0000ffbf, 12202 }, /* F2 */
+ { 0x0000ffc0, 12245 }, /* F3 */
+ { 0x0000ffc1, 12272 }, /* F4 */
+ { 0x0000ffc2, 12275 }, /* F5 */
+ { 0x0000ffc3, 12278 }, /* F6 */
+ { 0x0000ffc4, 12281 }, /* F7 */
+ { 0x0000ffc5, 12284 }, /* F8 */
+ { 0x0000ffc6, 12287 }, /* F9 */
+ { 0x0000ffc7, 12162 }, /* F10 */
+ { 0x0000ffc8, 12166 }, /* F11 */
+ { 0x0000ffc9, 12170 }, /* F12 */
+ { 0x0000ffca, 12174 }, /* F13 */
+ { 0x0000ffcb, 12178 }, /* F14 */
+ { 0x0000ffcc, 12182 }, /* F15 */
+ { 0x0000ffcd, 12186 }, /* F16 */
+ { 0x0000ffce, 12190 }, /* F17 */
+ { 0x0000ffcf, 12194 }, /* F18 */
+ { 0x0000ffd0, 12198 }, /* F19 */
+ { 0x0000ffd1, 12205 }, /* F20 */
+ { 0x0000ffd2, 12209 }, /* F21 */
+ { 0x0000ffd3, 12213 }, /* F22 */
+ { 0x0000ffd4, 12217 }, /* F23 */
+ { 0x0000ffd5, 12221 }, /* F24 */
+ { 0x0000ffd6, 12225 }, /* F25 */
+ { 0x0000ffd7, 12229 }, /* F26 */
+ { 0x0000ffd8, 12233 }, /* F27 */
+ { 0x0000ffd9, 12237 }, /* F28 */
+ { 0x0000ffda, 12241 }, /* F29 */
+ { 0x0000ffdb, 12248 }, /* F30 */
+ { 0x0000ffdc, 12252 }, /* F31 */
+ { 0x0000ffdd, 12256 }, /* F32 */
+ { 0x0000ffde, 12260 }, /* F33 */
+ { 0x0000ffdf, 12264 }, /* F34 */
+ { 0x0000ffe0, 12268 }, /* F35 */
+ { 0x0000ffe1, 22946 }, /* Shift_L */
+ { 0x0000ffe2, 22965 }, /* Shift_R */
+ { 0x0000ffe3, 8697 }, /* Control_L */
+ { 0x0000ffe4, 8707 }, /* Control_R */
+ { 0x0000ffe5, 8496 }, /* Caps_Lock */
+ { 0x0000ffe6, 22954 }, /* Shift_Lock */
+ { 0x0000ffe7, 19710 }, /* Meta_L */
+ { 0x0000ffe8, 19717 }, /* Meta_R */
+ { 0x0000ffe9, 880 }, /* Alt_L */
+ { 0x0000ffea, 886 }, /* Alt_R */
+ { 0x0000ffeb, 24263 }, /* Super_L */
+ { 0x0000ffec, 24271 }, /* Super_R */
+ { 0x0000ffed, 17046 }, /* Hyper_L */
+ { 0x0000ffee, 17054 }, /* Hyper_R */
+ { 0x0000fff1, 3642 }, /* braille_dot_1 */
+ { 0x0000fff2, 3671 }, /* braille_dot_2 */
+ { 0x0000fff3, 3685 }, /* braille_dot_3 */
+ { 0x0000fff4, 3699 }, /* braille_dot_4 */
+ { 0x0000fff5, 3713 }, /* braille_dot_5 */
+ { 0x0000fff6, 3727 }, /* braille_dot_6 */
+ { 0x0000fff7, 3741 }, /* braille_dot_7 */
+ { 0x0000fff8, 3755 }, /* braille_dot_8 */
+ { 0x0000fff9, 3769 }, /* braille_dot_9 */
+ { 0x0000fffa, 3656 }, /* braille_dot_10 */
+ { 0x0000ffff, 11160 }, /* Delete */
+ { 0x00ffffff, 26531 }, /* VoidSymbol */
+ { 0x0100012c, 17117 }, /* Ibreve */
+ { 0x0100012d, 17124 }, /* ibreve */
+ { 0x01000174, 26563 }, /* Wcircumflex */
+ { 0x01000175, 26575 }, /* wcircumflex */
+ { 0x01000176, 29010 }, /* Ycircumflex */
+ { 0x01000177, 29022 }, /* ycircumflex */
+ { 0x0100018f, 22649 }, /* SCHWA */
+ { 0x0100019f, 20218 }, /* Obarred */
+ { 0x010001a0, 20553 }, /* Ohorn */
+ { 0x010001a1, 20559 }, /* ohorn */
+ { 0x010001af, 25997 }, /* Uhorn */
+ { 0x010001b0, 26003 }, /* uhorn */
+ { 0x010001b5, 29212 }, /* Zstroke */
+ { 0x010001b6, 29220 }, /* zstroke */
+ { 0x010001b7, 12147 }, /* EZH */
+ { 0x010001d1, 20254 }, /* Ocaron */
+ { 0x010001d2, 20261 }, /* ocaron */
+ { 0x010001e6, 12703 }, /* Gcaron */
+ { 0x010001e7, 12710 }, /* gcaron */
+ { 0x01000259, 22655 }, /* schwa */
+ { 0x01000275, 20226 }, /* obarred */
+ { 0x01000292, 12151 }, /* ezh */
+ { 0x01000492, 9236 }, /* Cyrillic_GHE_bar */
+ { 0x01000493, 9253 }, /* Cyrillic_ghe_bar */
+ { 0x01000496, 10274 }, /* Cyrillic_ZHE_descender */
+ { 0x01000497, 10297 }, /* Cyrillic_zhe_descender */
+ { 0x0100049a, 9528 }, /* Cyrillic_KA_descender */
+ { 0x0100049b, 9550 }, /* Cyrillic_ka_descender */
+ { 0x0100049c, 9572 }, /* Cyrillic_KA_vertstroke */
+ { 0x0100049d, 9595 }, /* Cyrillic_ka_vertstroke */
+ { 0x010004a2, 9118 }, /* Cyrillic_EN_descender */
+ { 0x010004a3, 9140 }, /* Cyrillic_en_descender */
+ { 0x010004ae, 10036 }, /* Cyrillic_U_straight */
+ { 0x010004af, 10056 }, /* Cyrillic_u_straight */
+ { 0x010004b0, 10076 }, /* Cyrillic_U_straight_bar */
+ { 0x010004b1, 10100 }, /* Cyrillic_u_straight_bar */
+ { 0x010004b2, 9294 }, /* Cyrillic_HA_descender */
+ { 0x010004b3, 9316 }, /* Cyrillic_ha_descender */
+ { 0x010004b6, 8854 }, /* Cyrillic_CHE_descender */
+ { 0x010004b7, 8877 }, /* Cyrillic_che_descender */
+ { 0x010004b8, 8900 }, /* Cyrillic_CHE_vertstroke */
+ { 0x010004b9, 8924 }, /* Cyrillic_che_vertstroke */
+ { 0x010004ba, 9832 }, /* Cyrillic_SHHA */
+ { 0x010004bb, 9846 }, /* Cyrillic_shha */
+ { 0x010004d8, 9746 }, /* Cyrillic_SCHWA */
+ { 0x010004d9, 9761 }, /* Cyrillic_schwa */
+ { 0x010004e2, 9396 }, /* Cyrillic_I_macron */
+ { 0x010004e3, 9414 }, /* Cyrillic_i_macron */
+ { 0x010004e8, 9692 }, /* Cyrillic_O_bar */
+ { 0x010004e9, 9707 }, /* Cyrillic_o_bar */
+ { 0x010004ee, 10000 }, /* Cyrillic_U_macron */
+ { 0x010004ef, 10018 }, /* Cyrillic_u_macron */
+ { 0x01000531, 2124 }, /* Armenian_AYB */
+ { 0x01000532, 2150 }, /* Armenian_BEN */
+ { 0x01000533, 2374 }, /* Armenian_GIM */
+ { 0x01000534, 2215 }, /* Armenian_DA */
+ { 0x01000535, 3164 }, /* Armenian_YECH */
+ { 0x01000536, 3210 }, /* Armenian_ZA */
+ { 0x01000537, 2265 }, /* Armenian_E */
+ { 0x01000538, 2100 }, /* Armenian_AT */
+ { 0x01000539, 2964 }, /* Armenian_TO */
+ { 0x0100053a, 3234 }, /* Armenian_ZHE */
+ { 0x0100053b, 2464 }, /* Armenian_INI */
+ { 0x0100053c, 2611 }, /* Armenian_LYUN */
+ { 0x0100053d, 2564 }, /* Armenian_KHE */
+ { 0x0100053e, 2988 }, /* Armenian_TSA */
+ { 0x0100053f, 2538 }, /* Armenian_KEN */
+ { 0x01000540, 2424 }, /* Armenian_HO */
+ { 0x01000541, 2239 }, /* Armenian_DZA */
+ { 0x01000542, 2346 }, /* Armenian_GHAT */
+ { 0x01000543, 2936 }, /* Armenian_TCHE */
+ { 0x01000544, 2639 }, /* Armenian_MEN */
+ { 0x01000545, 2400 }, /* Armenian_HI */
+ { 0x01000546, 2665 }, /* Armenian_NU */
+ { 0x01000547, 2894 }, /* Armenian_SHA */
+ { 0x01000548, 3112 }, /* Armenian_VO */
+ { 0x01000549, 2189 }, /* Armenian_CHA */
+ { 0x0100054a, 2727 }, /* Armenian_PE */
+ { 0x0100054b, 2490 }, /* Armenian_JE */
+ { 0x0100054c, 2797 }, /* Armenian_RA */
+ { 0x0100054d, 2845 }, /* Armenian_SE */
+ { 0x0100054e, 3086 }, /* Armenian_VEV */
+ { 0x0100054f, 3040 }, /* Armenian_TYUN */
+ { 0x01000550, 2821 }, /* Armenian_RE */
+ { 0x01000551, 3014 }, /* Armenian_TSO */
+ { 0x01000552, 3136 }, /* Armenian_VYUN */
+ { 0x01000553, 2751 }, /* Armenian_PYUR */
+ { 0x01000554, 2514 }, /* Armenian_KE */
+ { 0x01000555, 2689 }, /* Armenian_O */
+ { 0x01000556, 2303 }, /* Armenian_FE */
+ { 0x0100055a, 2080 }, /* Armenian_apostrophe */
+ { 0x0100055b, 2048 }, /* Armenian_accent */
+ { 0x0100055c, 2287 }, /* Armenian_exclam */
+ { 0x0100055d, 2869 }, /* Armenian_separation_mark */
+ { 0x0100055e, 2779 }, /* Armenian_question */
+ { 0x01000561, 2137 }, /* Armenian_ayb */
+ { 0x01000562, 2163 }, /* Armenian_ben */
+ { 0x01000563, 2387 }, /* Armenian_gim */
+ { 0x01000564, 2227 }, /* Armenian_da */
+ { 0x01000565, 3178 }, /* Armenian_yech */
+ { 0x01000566, 3222 }, /* Armenian_za */
+ { 0x01000567, 2276 }, /* Armenian_e */
+ { 0x01000568, 2112 }, /* Armenian_at */
+ { 0x01000569, 2976 }, /* Armenian_to */
+ { 0x0100056a, 3247 }, /* Armenian_zhe */
+ { 0x0100056b, 2477 }, /* Armenian_ini */
+ { 0x0100056c, 2625 }, /* Armenian_lyun */
+ { 0x0100056d, 2577 }, /* Armenian_khe */
+ { 0x0100056e, 3001 }, /* Armenian_tsa */
+ { 0x0100056f, 2551 }, /* Armenian_ken */
+ { 0x01000570, 2436 }, /* Armenian_ho */
+ { 0x01000571, 2252 }, /* Armenian_dza */
+ { 0x01000572, 2360 }, /* Armenian_ghat */
+ { 0x01000573, 2950 }, /* Armenian_tche */
+ { 0x01000574, 2652 }, /* Armenian_men */
+ { 0x01000575, 2412 }, /* Armenian_hi */
+ { 0x01000576, 2677 }, /* Armenian_nu */
+ { 0x01000577, 2907 }, /* Armenian_sha */
+ { 0x01000578, 3124 }, /* Armenian_vo */
+ { 0x01000579, 2202 }, /* Armenian_cha */
+ { 0x0100057a, 2739 }, /* Armenian_pe */
+ { 0x0100057b, 2502 }, /* Armenian_je */
+ { 0x0100057c, 2809 }, /* Armenian_ra */
+ { 0x0100057d, 2857 }, /* Armenian_se */
+ { 0x0100057e, 3099 }, /* Armenian_vev */
+ { 0x0100057f, 3054 }, /* Armenian_tyun */
+ { 0x01000580, 2833 }, /* Armenian_re */
+ { 0x01000581, 3027 }, /* Armenian_tso */
+ { 0x01000582, 3150 }, /* Armenian_vyun */
+ { 0x01000583, 2765 }, /* Armenian_pyur */
+ { 0x01000584, 2526 }, /* Armenian_ke */
+ { 0x01000585, 2700 }, /* Armenian_o */
+ { 0x01000586, 2315 }, /* Armenian_fe */
+ { 0x01000587, 2590 }, /* Armenian_ligature_ew */
+ { 0x01000589, 2327 }, /* Armenian_full_stop */
+ { 0x0100058a, 2448 }, /* Armenian_hyphen */
+ { 0x01000653, 1580 }, /* Arabic_madda_above */
+ { 0x01000654, 1316 }, /* Arabic_hamza_above */
+ { 0x01000655, 1335 }, /* Arabic_hamza_below */
+ { 0x01000660, 966 }, /* Arabic_0 */
+ { 0x01000661, 975 }, /* Arabic_1 */
+ { 0x01000662, 984 }, /* Arabic_2 */
+ { 0x01000663, 993 }, /* Arabic_3 */
+ { 0x01000664, 1002 }, /* Arabic_4 */
+ { 0x01000665, 1011 }, /* Arabic_5 */
+ { 0x01000666, 1020 }, /* Arabic_6 */
+ { 0x01000667, 1029 }, /* Arabic_7 */
+ { 0x01000668, 1038 }, /* Arabic_8 */
+ { 0x01000669, 1047 }, /* Arabic_9 */
+ { 0x0100066a, 1672 }, /* Arabic_percent */
+ { 0x01000670, 1821 }, /* Arabic_superscript_alef */
+ { 0x01000679, 1951 }, /* Arabic_tteh */
+ { 0x0100067e, 1661 }, /* Arabic_peh */
+ { 0x01000686, 1885 }, /* Arabic_tcheh */
+ { 0x01000688, 1173 }, /* Arabic_ddal */
+ { 0x01000691, 1729 }, /* Arabic_rreh */
+ { 0x01000698, 1493 }, /* Arabic_jeh */
+ { 0x010006a4, 1963 }, /* Arabic_veh */
+ { 0x010006a9, 1544 }, /* Arabic_keheh */
+ { 0x010006af, 1258 }, /* Arabic_gaf */
+ { 0x010006ba, 1642 }, /* Arabic_noon_ghunna */
+ { 0x010006be, 1442 }, /* Arabic_heh_doachashmee */
+ { 0x010006c1, 1465 }, /* Arabic_heh_goal */
+ { 0x010006cc, 12390 }, /* Farsi_yeh */
+ { 0x010006d2, 1996 }, /* Arabic_yeh_baree */
+ { 0x010006d4, 1242 }, /* Arabic_fullstop */
+ { 0x010006f0, 12310 }, /* Farsi_0 */
+ { 0x010006f1, 12318 }, /* Farsi_1 */
+ { 0x010006f2, 12326 }, /* Farsi_2 */
+ { 0x010006f3, 12334 }, /* Farsi_3 */
+ { 0x010006f4, 12342 }, /* Farsi_4 */
+ { 0x010006f5, 12350 }, /* Farsi_5 */
+ { 0x010006f6, 12358 }, /* Farsi_6 */
+ { 0x010006f7, 12366 }, /* Farsi_7 */
+ { 0x010006f8, 12374 }, /* Farsi_8 */
+ { 0x010006f9, 12382 }, /* Farsi_9 */
+ { 0x01000d82, 23484 }, /* Sinh_ng */
+ { 0x01000d83, 23278 }, /* Sinh_h2 */
+ { 0x01000d85, 23047 }, /* Sinh_a */
+ { 0x01000d86, 23054 }, /* Sinh_aa */
+ { 0x01000d87, 23071 }, /* Sinh_ae */
+ { 0x01000d88, 23088 }, /* Sinh_aee */
+ { 0x01000d89, 23294 }, /* Sinh_i */
+ { 0x01000d8a, 23309 }, /* Sinh_ii */
+ { 0x01000d8b, 23695 }, /* Sinh_u */
+ { 0x01000d8c, 23710 }, /* Sinh_uu */
+ { 0x01000d8d, 23594 }, /* Sinh_ri */
+ { 0x01000d8e, 23602 }, /* Sinh_rii */
+ { 0x01000d8f, 23403 }, /* Sinh_lu */
+ { 0x01000d90, 23420 }, /* Sinh_luu */
+ { 0x01000d91, 23221 }, /* Sinh_e */
+ { 0x01000d92, 23236 }, /* Sinh_ee */
+ { 0x01000d93, 23107 }, /* Sinh_ai */
+ { 0x01000d94, 23537 }, /* Sinh_o */
+ { 0x01000d95, 23552 }, /* Sinh_oo */
+ { 0x01000d96, 23132 }, /* Sinh_au */
+ { 0x01000d9a, 23353 }, /* Sinh_ka */
+ { 0x01000d9b, 23361 }, /* Sinh_kha */
+ { 0x01000d9c, 23261 }, /* Sinh_ga */
+ { 0x01000d9d, 23269 }, /* Sinh_gha */
+ { 0x01000d9e, 23492 }, /* Sinh_ng2 */
+ { 0x01000d9f, 23501 }, /* Sinh_nga */
+ { 0x01000da0, 23166 }, /* Sinh_ca */
+ { 0x01000da1, 23174 }, /* Sinh_cha */
+ { 0x01000da2, 23326 }, /* Sinh_ja */
+ { 0x01000da3, 23334 }, /* Sinh_jha */
+ { 0x01000da4, 23528 }, /* Sinh_nya */
+ { 0x01000da5, 23343 }, /* Sinh_jnya */
+ { 0x01000da6, 23510 }, /* Sinh_nja */
+ { 0x01000da7, 23676 }, /* Sinh_tta */
+ { 0x01000da8, 23685 }, /* Sinh_ttha */
+ { 0x01000da9, 23183 }, /* Sinh_dda */
+ { 0x01000daa, 23192 }, /* Sinh_ddha */
+ { 0x01000dab, 23519 }, /* Sinh_nna */
+ { 0x01000dac, 23464 }, /* Sinh_ndda */
+ { 0x01000dad, 23657 }, /* Sinh_tha */
+ { 0x01000dae, 23666 }, /* Sinh_thha */
+ { 0x01000daf, 23202 }, /* Sinh_dha */
+ { 0x01000db0, 23211 }, /* Sinh_dhha */
+ { 0x01000db1, 23456 }, /* Sinh_na */
+ { 0x01000db3, 23474 }, /* Sinh_ndha */
+ { 0x01000db4, 23569 }, /* Sinh_pa */
+ { 0x01000db5, 23577 }, /* Sinh_pha */
+ { 0x01000db6, 23149 }, /* Sinh_ba */
+ { 0x01000db7, 23157 }, /* Sinh_bha */
+ { 0x01000db8, 23439 }, /* Sinh_ma */
+ { 0x01000db9, 23447 }, /* Sinh_mba */
+ { 0x01000dba, 23735 }, /* Sinh_ya */
+ { 0x01000dbb, 23586 }, /* Sinh_ra */
+ { 0x01000dbd, 23386 }, /* Sinh_la */
+ { 0x01000dc0, 23727 }, /* Sinh_va */
+ { 0x01000dc1, 23638 }, /* Sinh_sha */
+ { 0x01000dc2, 23647 }, /* Sinh_ssha */
+ { 0x01000dc3, 23630 }, /* Sinh_sa */
+ { 0x01000dc4, 23286 }, /* Sinh_ha */
+ { 0x01000dc5, 23394 }, /* Sinh_lla */
+ { 0x01000dc6, 23253 }, /* Sinh_fa */
+ { 0x01000dca, 23124 }, /* Sinh_al */
+ { 0x01000dcf, 23062 }, /* Sinh_aa2 */
+ { 0x01000dd0, 23079 }, /* Sinh_ae2 */
+ { 0x01000dd1, 23097 }, /* Sinh_aee2 */
+ { 0x01000dd2, 23301 }, /* Sinh_i2 */
+ { 0x01000dd3, 23317 }, /* Sinh_ii2 */
+ { 0x01000dd4, 23702 }, /* Sinh_u2 */
+ { 0x01000dd6, 23718 }, /* Sinh_uu2 */
+ { 0x01000dd8, 23611 }, /* Sinh_ru2 */
+ { 0x01000dd9, 23228 }, /* Sinh_e2 */
+ { 0x01000dda, 23244 }, /* Sinh_ee2 */
+ { 0x01000ddb, 23115 }, /* Sinh_ai2 */
+ { 0x01000ddc, 23544 }, /* Sinh_o2 */
+ { 0x01000ddd, 23560 }, /* Sinh_oo2 */
+ { 0x01000dde, 23140 }, /* Sinh_au2 */
+ { 0x01000ddf, 23411 }, /* Sinh_lu2 */
+ { 0x01000df2, 23620 }, /* Sinh_ruu2 */
+ { 0x01000df3, 23429 }, /* Sinh_luu2 */
+ { 0x01000df4, 23370 }, /* Sinh_kunddaliya */
+ { 0x010010d0, 12759 }, /* Georgian_an */
+ { 0x010010d1, 12771 }, /* Georgian_ban */
+ { 0x010010d2, 12875 }, /* Georgian_gan */
+ { 0x010010d3, 12838 }, /* Georgian_don */
+ { 0x010010d4, 12851 }, /* Georgian_en */
+ { 0x010010d5, 13201 }, /* Georgian_vin */
+ { 0x010010d6, 13239 }, /* Georgian_zen */
+ { 0x010010d7, 13163 }, /* Georgian_tan */
+ { 0x010010d8, 12966 }, /* Georgian_in */
+ { 0x010010d9, 13005 }, /* Georgian_kan */
+ { 0x010010da, 13032 }, /* Georgian_las */
+ { 0x010010db, 13045 }, /* Georgian_man */
+ { 0x010010dc, 13058 }, /* Georgian_nar */
+ { 0x010010dd, 13071 }, /* Georgian_on */
+ { 0x010010de, 13083 }, /* Georgian_par */
+ { 0x010010df, 13252 }, /* Georgian_zhar */
+ { 0x010010e0, 13123 }, /* Georgian_rae */
+ { 0x010010e1, 13136 }, /* Georgian_san */
+ { 0x010010e2, 13176 }, /* Georgian_tar */
+ { 0x010010e3, 13189 }, /* Georgian_un */
+ { 0x010010e4, 13096 }, /* Georgian_phar */
+ { 0x010010e5, 13018 }, /* Georgian_khar */
+ { 0x010010e6, 12888 }, /* Georgian_ghan */
+ { 0x010010e7, 13110 }, /* Georgian_qar */
+ { 0x010010e8, 13149 }, /* Georgian_shin */
+ { 0x010010e9, 12811 }, /* Georgian_chin */
+ { 0x010010ea, 12784 }, /* Georgian_can */
+ { 0x010010eb, 12992 }, /* Georgian_jil */
+ { 0x010010ec, 12825 }, /* Georgian_cil */
+ { 0x010010ed, 12797 }, /* Georgian_char */
+ { 0x010010ee, 13226 }, /* Georgian_xan */
+ { 0x010010ef, 12978 }, /* Georgian_jhan */
+ { 0x010010f0, 12902 }, /* Georgian_hae */
+ { 0x010010f1, 12928 }, /* Georgian_he */
+ { 0x010010f2, 12940 }, /* Georgian_hie */
+ { 0x010010f3, 13214 }, /* Georgian_we */
+ { 0x010010f4, 12915 }, /* Georgian_har */
+ { 0x010010f5, 12953 }, /* Georgian_hoe */
+ { 0x010010f6, 12863 }, /* Georgian_fi */
+ { 0x01001e02, 3332 }, /* Babovedot */
+ { 0x01001e03, 3342 }, /* babovedot */
+ { 0x01001e0a, 10324 }, /* Dabovedot */
+ { 0x01001e0b, 10334 }, /* dabovedot */
+ { 0x01001e1e, 12290 }, /* Fabovedot */
+ { 0x01001e1f, 12300 }, /* fabovedot */
+ { 0x01001e36, 19192 }, /* Lbelowdot */
+ { 0x01001e37, 19202 }, /* lbelowdot */
+ { 0x01001e40, 19537 }, /* Mabovedot */
+ { 0x01001e41, 19547 }, /* mabovedot */
+ { 0x01001e56, 21377 }, /* Pabovedot */
+ { 0x01001e57, 21387 }, /* pabovedot */
+ { 0x01001e60, 22583 }, /* Sabovedot */
+ { 0x01001e61, 22593 }, /* sabovedot */
+ { 0x01001e6a, 24302 }, /* Tabovedot */
+ { 0x01001e6b, 24312 }, /* tabovedot */
+ { 0x01001e80, 26609 }, /* Wgrave */
+ { 0x01001e81, 26616 }, /* wgrave */
+ { 0x01001e82, 26549 }, /* Wacute */
+ { 0x01001e83, 26556 }, /* wacute */
+ { 0x01001e84, 26587 }, /* Wdiaeresis */
+ { 0x01001e85, 26598 }, /* wdiaeresis */
+ { 0x01001e8a, 26635 }, /* Xabovedot */
+ { 0x01001e8b, 26645 }, /* xabovedot */
+ { 0x01001ea0, 416 }, /* Abelowdot */
+ { 0x01001ea1, 426 }, /* abelowdot */
+ { 0x01001ea2, 868 }, /* Ahook */
+ { 0x01001ea3, 874 }, /* ahook */
+ { 0x01001ea4, 646 }, /* Acircumflexacute */
+ { 0x01001ea5, 663 }, /* acircumflexacute */
+ { 0x01001ea6, 720 }, /* Acircumflexgrave */
+ { 0x01001ea7, 737 }, /* acircumflexgrave */
+ { 0x01001ea8, 754 }, /* Acircumflexhook */
+ { 0x01001ea9, 770 }, /* acircumflexhook */
+ { 0x01001eaa, 786 }, /* Acircumflextilde */
+ { 0x01001eab, 803 }, /* acircumflextilde */
+ { 0x01001eac, 680 }, /* Acircumflexbelowdot */
+ { 0x01001ead, 700 }, /* acircumflexbelowdot */
+ { 0x01001eae, 459 }, /* Abreveacute */
+ { 0x01001eaf, 471 }, /* abreveacute */
+ { 0x01001eb0, 513 }, /* Abrevegrave */
+ { 0x01001eb1, 525 }, /* abrevegrave */
+ { 0x01001eb2, 537 }, /* Abrevehook */
+ { 0x01001eb3, 548 }, /* abrevehook */
+ { 0x01001eb4, 559 }, /* Abrevetilde */
+ { 0x01001eb5, 571 }, /* abrevetilde */
+ { 0x01001eb6, 483 }, /* Abrevebelowdot */
+ { 0x01001eb7, 498 }, /* abrevebelowdot */
+ { 0x01001eb8, 11462 }, /* Ebelowdot */
+ { 0x01001eb9, 11472 }, /* ebelowdot */
+ { 0x01001eba, 11738 }, /* Ehook */
+ { 0x01001ebb, 11744 }, /* ehook */
+ { 0x01001ebc, 12076 }, /* Etilde */
+ { 0x01001ebd, 12083 }, /* etilde */
+ { 0x01001ebe, 11520 }, /* Ecircumflexacute */
+ { 0x01001ebf, 11537 }, /* ecircumflexacute */
+ { 0x01001ec0, 11594 }, /* Ecircumflexgrave */
+ { 0x01001ec1, 11611 }, /* ecircumflexgrave */
+ { 0x01001ec2, 11628 }, /* Ecircumflexhook */
+ { 0x01001ec3, 11644 }, /* ecircumflexhook */
+ { 0x01001ec4, 11660 }, /* Ecircumflextilde */
+ { 0x01001ec5, 11677 }, /* ecircumflextilde */
+ { 0x01001ec6, 11554 }, /* Ecircumflexbelowdot */
+ { 0x01001ec7, 11574 }, /* ecircumflexbelowdot */
+ { 0x01001ec8, 17219 }, /* Ihook */
+ { 0x01001ec9, 17225 }, /* ihook */
+ { 0x01001eca, 17097 }, /* Ibelowdot */
+ { 0x01001ecb, 17107 }, /* ibelowdot */
+ { 0x01001ecc, 20234 }, /* Obelowdot */
+ { 0x01001ecd, 20244 }, /* obelowdot */
+ { 0x01001ece, 20541 }, /* Ohook */
+ { 0x01001ecf, 20547 }, /* ohook */
+ { 0x01001ed0, 20292 }, /* Ocircumflexacute */
+ { 0x01001ed1, 20309 }, /* ocircumflexacute */
+ { 0x01001ed2, 20366 }, /* Ocircumflexgrave */
+ { 0x01001ed3, 20383 }, /* ocircumflexgrave */
+ { 0x01001ed4, 20400 }, /* Ocircumflexhook */
+ { 0x01001ed5, 20416 }, /* ocircumflexhook */
+ { 0x01001ed6, 20432 }, /* Ocircumflextilde */
+ { 0x01001ed7, 20449 }, /* ocircumflextilde */
+ { 0x01001ed8, 20326 }, /* Ocircumflexbelowdot */
+ { 0x01001ed9, 20346 }, /* ocircumflexbelowdot */
+ { 0x01001eda, 20565 }, /* Ohornacute */
+ { 0x01001edb, 20576 }, /* ohornacute */
+ { 0x01001edc, 20615 }, /* Ohorngrave */
+ { 0x01001edd, 20626 }, /* ohorngrave */
+ { 0x01001ede, 20637 }, /* Ohornhook */
+ { 0x01001edf, 20647 }, /* ohornhook */
+ { 0x01001ee0, 20657 }, /* Ohorntilde */
+ { 0x01001ee1, 20668 }, /* ohorntilde */
+ { 0x01001ee2, 20587 }, /* Ohornbelowdot */
+ { 0x01001ee3, 20601 }, /* ohornbelowdot */
+ { 0x01001ee4, 25865 }, /* Ubelowdot */
+ { 0x01001ee5, 25875 }, /* ubelowdot */
+ { 0x01001ee6, 25985 }, /* Uhook */
+ { 0x01001ee7, 25991 }, /* uhook */
+ { 0x01001ee8, 26009 }, /* Uhornacute */
+ { 0x01001ee9, 26020 }, /* uhornacute */
+ { 0x01001eea, 26059 }, /* Uhorngrave */
+ { 0x01001eeb, 26070 }, /* uhorngrave */
+ { 0x01001eec, 26081 }, /* Uhornhook */
+ { 0x01001eed, 26091 }, /* uhornhook */
+ { 0x01001eee, 26101 }, /* Uhorntilde */
+ { 0x01001eef, 26112 }, /* uhorntilde */
+ { 0x01001ef0, 26031 }, /* Uhornbelowdot */
+ { 0x01001ef1, 26045 }, /* uhornbelowdot */
+ { 0x01001ef2, 29060 }, /* Ygrave */
+ { 0x01001ef3, 29067 }, /* ygrave */
+ { 0x01001ef4, 28990 }, /* Ybelowdot */
+ { 0x01001ef5, 29000 }, /* ybelowdot */
+ { 0x01001ef6, 29074 }, /* Yhook */
+ { 0x01001ef7, 29080 }, /* yhook */
+ { 0x01001ef8, 29086 }, /* Ytilde */
+ { 0x01001ef9, 29093 }, /* ytilde */
+ { 0x01002070, 29199 }, /* zerosuperior */
+ { 0x01002074, 12632 }, /* foursuperior */
+ { 0x01002075, 12594 }, /* fivesuperior */
+ { 0x01002076, 23756 }, /* sixsuperior */
+ { 0x01002077, 22932 }, /* sevensuperior */
+ { 0x01002078, 11765 }, /* eightsuperior */
+ { 0x01002079, 20062 }, /* ninesuperior */
+ { 0x01002080, 29185 }, /* zerosubscript */
+ { 0x01002081, 20742 }, /* onesubscript */
+ { 0x01002082, 25812 }, /* twosubscript */
+ { 0x01002083, 25556 }, /* threesubscript */
+ { 0x01002084, 12618 }, /* foursubscript */
+ { 0x01002085, 12580 }, /* fivesubscript */
+ { 0x01002086, 23743 }, /* sixsubscript */
+ { 0x01002087, 22917 }, /* sevensubscript */
+ { 0x01002088, 11750 }, /* eightsubscript */
+ { 0x01002089, 20048 }, /* ninesubscript */
+ { 0x010020a0, 11694 }, /* EcuSign */
+ { 0x010020a1, 8670 }, /* ColonSign */
+ { 0x010020a2, 8744 }, /* CruzeiroSign */
+ { 0x010020a3, 12416 }, /* FFrancSign */
+ { 0x010020a4, 19448 }, /* LiraSign */
+ { 0x010020a5, 19724 }, /* MillSign */
+ { 0x010020a6, 19967 }, /* NairaSign */
+ { 0x010020a7, 21526 }, /* PesetaSign */
+ { 0x010020a8, 22569 }, /* RupeeSign */
+ { 0x010020a9, 26623 }, /* WonSign */
+ { 0x010020aa, 20009 }, /* NewSheqelSign */
+ { 0x010020ab, 11258 }, /* DongSign */
+ { 0x01002202, 21446 }, /* partdifferential */
+ { 0x01002205, 11919 }, /* emptyset */
+ { 0x01002208, 11802 }, /* elementof */
+ { 0x01002209, 20112 }, /* notelementof */
+ { 0x0100220b, 8686 }, /* containsas */
+ { 0x0100221a, 23809 }, /* squareroot */
+ { 0x0100221b, 8757 }, /* cuberoot */
+ { 0x0100221c, 12645 }, /* fourthroot */
+ { 0x0100222c, 11232 }, /* dintegral */
+ { 0x0100222d, 25585 }, /* tintegral */
+ { 0x01002235, 3396 }, /* because */
+ { 0x01002247, 20100 }, /* notapproxeq */
+ { 0x01002248, 945 }, /* approxeq */
+ { 0x01002262, 20134 }, /* notidentical */
+ { 0x01002263, 23854 }, /* stricteq */
+ { 0x01002800, 3628 }, /* braille_blank */
+ { 0x01002801, 3783 }, /* braille_dots_1 */
+ { 0x01002802, 6151 }, /* braille_dots_2 */
+ { 0x01002803, 3798 }, /* braille_dots_12 */
+ { 0x01002804, 7303 }, /* braille_dots_3 */
+ { 0x01002805, 5014 }, /* braille_dots_13 */
+ { 0x01002806, 6166 }, /* braille_dots_23 */
+ { 0x01002807, 3814 }, /* braille_dots_123 */
+ { 0x01002808, 7863 }, /* braille_dots_4 */
+ { 0x01002809, 5606 }, /* braille_dots_14 */
+ { 0x0100280a, 6758 }, /* braille_dots_24 */
+ { 0x0100280b, 4438 }, /* braille_dots_124 */
+ { 0x0100280c, 7318 }, /* braille_dots_34 */
+ { 0x0100280d, 5030 }, /* braille_dots_134 */
+ { 0x0100280e, 6182 }, /* braille_dots_234 */
+ { 0x0100280f, 3831 }, /* braille_dots_1234 */
+ { 0x01002810, 8135 }, /* braille_dots_5 */
+ { 0x01002811, 5894 }, /* braille_dots_15 */
+ { 0x01002812, 7046 }, /* braille_dots_25 */
+ { 0x01002813, 4742 }, /* braille_dots_125 */
+ { 0x01002814, 7606 }, /* braille_dots_35 */
+ { 0x01002815, 5334 }, /* braille_dots_135 */
+ { 0x01002816, 6486 }, /* braille_dots_235 */
+ { 0x01002817, 4151 }, /* braille_dots_1235 */
+ { 0x01002818, 7878 }, /* braille_dots_45 */
+ { 0x01002819, 5622 }, /* braille_dots_145 */
+ { 0x0100281a, 6774 }, /* braille_dots_245 */
+ { 0x0100281b, 4455 }, /* braille_dots_1245 */
+ { 0x0100281c, 7334 }, /* braille_dots_345 */
+ { 0x0100281d, 5047 }, /* braille_dots_1345 */
+ { 0x0100281e, 6199 }, /* braille_dots_2345 */
+ { 0x0100281f, 3849 }, /* braille_dots_12345 */
+ { 0x01002820, 8267 }, /* braille_dots_6 */
+ { 0x01002821, 6034 }, /* braille_dots_16 */
+ { 0x01002822, 7186 }, /* braille_dots_26 */
+ { 0x01002823, 4890 }, /* braille_dots_126 */
+ { 0x01002824, 7746 }, /* braille_dots_36 */
+ { 0x01002825, 5482 }, /* braille_dots_136 */
+ { 0x01002826, 6634 }, /* braille_dots_236 */
+ { 0x01002827, 4307 }, /* braille_dots_1236 */
+ { 0x01002828, 8018 }, /* braille_dots_46 */
+ { 0x01002829, 5770 }, /* braille_dots_146 */
+ { 0x0100282a, 6922 }, /* braille_dots_246 */
+ { 0x0100282b, 4611 }, /* braille_dots_1246 */
+ { 0x0100282c, 7482 }, /* braille_dots_346 */
+ { 0x0100282d, 5203 }, /* braille_dots_1346 */
+ { 0x0100282e, 6355 }, /* braille_dots_2346 */
+ { 0x0100282f, 4013 }, /* braille_dots_12346 */
+ { 0x01002830, 8150 }, /* braille_dots_56 */
+ { 0x01002831, 5910 }, /* braille_dots_156 */
+ { 0x01002832, 7062 }, /* braille_dots_256 */
+ { 0x01002833, 4759 }, /* braille_dots_1256 */
+ { 0x01002834, 7622 }, /* braille_dots_356 */
+ { 0x01002835, 5351 }, /* braille_dots_1356 */
+ { 0x01002836, 6503 }, /* braille_dots_2356 */
+ { 0x01002837, 4169 }, /* braille_dots_12356 */
+ { 0x01002838, 7894 }, /* braille_dots_456 */
+ { 0x01002839, 5639 }, /* braille_dots_1456 */
+ { 0x0100283a, 6791 }, /* braille_dots_2456 */
+ { 0x0100283b, 4473 }, /* braille_dots_12456 */
+ { 0x0100283c, 7351 }, /* braille_dots_3456 */
+ { 0x0100283d, 5065 }, /* braille_dots_13456 */
+ { 0x0100283e, 6217 }, /* braille_dots_23456 */
+ { 0x0100283f, 3868 }, /* braille_dots_123456 */
+ { 0x01002840, 8331 }, /* braille_dots_7 */
+ { 0x01002841, 6102 }, /* braille_dots_17 */
+ { 0x01002842, 7254 }, /* braille_dots_27 */
+ { 0x01002843, 4962 }, /* braille_dots_127 */
+ { 0x01002844, 7814 }, /* braille_dots_37 */
+ { 0x01002845, 5554 }, /* braille_dots_137 */
+ { 0x01002846, 6706 }, /* braille_dots_237 */
+ { 0x01002847, 4383 }, /* braille_dots_1237 */
+ { 0x01002848, 8086 }, /* braille_dots_47 */
+ { 0x01002849, 5842 }, /* braille_dots_147 */
+ { 0x0100284a, 6994 }, /* braille_dots_247 */
+ { 0x0100284b, 4687 }, /* braille_dots_1247 */
+ { 0x0100284c, 7554 }, /* braille_dots_347 */
+ { 0x0100284d, 5279 }, /* braille_dots_1347 */
+ { 0x0100284e, 6431 }, /* braille_dots_2347 */
+ { 0x0100284f, 4093 }, /* braille_dots_12347 */
+ { 0x01002850, 8218 }, /* braille_dots_57 */
+ { 0x01002851, 5982 }, /* braille_dots_157 */
+ { 0x01002852, 7134 }, /* braille_dots_257 */
+ { 0x01002853, 4835 }, /* braille_dots_1257 */
+ { 0x01002854, 7694 }, /* braille_dots_357 */
+ { 0x01002855, 5427 }, /* braille_dots_1357 */
+ { 0x01002856, 6579 }, /* braille_dots_2357 */
+ { 0x01002857, 4249 }, /* braille_dots_12357 */
+ { 0x01002858, 7966 }, /* braille_dots_457 */
+ { 0x01002859, 5715 }, /* braille_dots_1457 */
+ { 0x0100285a, 6867 }, /* braille_dots_2457 */
+ { 0x0100285b, 4553 }, /* braille_dots_12457 */
+ { 0x0100285c, 7427 }, /* braille_dots_3457 */
+ { 0x0100285d, 5145 }, /* braille_dots_13457 */
+ { 0x0100285e, 6297 }, /* braille_dots_23457 */
+ { 0x0100285f, 3952 }, /* braille_dots_123457 */
+ { 0x01002860, 8282 }, /* braille_dots_67 */
+ { 0x01002861, 6050 }, /* braille_dots_167 */
+ { 0x01002862, 7202 }, /* braille_dots_267 */
+ { 0x01002863, 4907 }, /* braille_dots_1267 */
+ { 0x01002864, 7762 }, /* braille_dots_367 */
+ { 0x01002865, 5499 }, /* braille_dots_1367 */
+ { 0x01002866, 6651 }, /* braille_dots_2367 */
+ { 0x01002867, 4325 }, /* braille_dots_12367 */
+ { 0x01002868, 8034 }, /* braille_dots_467 */
+ { 0x01002869, 5787 }, /* braille_dots_1467 */
+ { 0x0100286a, 6939 }, /* braille_dots_2467 */
+ { 0x0100286b, 4629 }, /* braille_dots_12467 */
+ { 0x0100286c, 7499 }, /* braille_dots_3467 */
+ { 0x0100286d, 5221 }, /* braille_dots_13467 */
+ { 0x0100286e, 6373 }, /* braille_dots_23467 */
+ { 0x0100286f, 4032 }, /* braille_dots_123467 */
+ { 0x01002870, 8166 }, /* braille_dots_567 */
+ { 0x01002871, 5927 }, /* braille_dots_1567 */
+ { 0x01002872, 7079 }, /* braille_dots_2567 */
+ { 0x01002873, 4777 }, /* braille_dots_12567 */
+ { 0x01002874, 7639 }, /* braille_dots_3567 */
+ { 0x01002875, 5369 }, /* braille_dots_13567 */
+ { 0x01002876, 6521 }, /* braille_dots_23567 */
+ { 0x01002877, 4188 }, /* braille_dots_123567 */
+ { 0x01002878, 7911 }, /* braille_dots_4567 */
+ { 0x01002879, 5657 }, /* braille_dots_14567 */
+ { 0x0100287a, 6809 }, /* braille_dots_24567 */
+ { 0x0100287b, 4492 }, /* braille_dots_124567 */
+ { 0x0100287c, 7369 }, /* braille_dots_34567 */
+ { 0x0100287d, 5084 }, /* braille_dots_134567 */
+ { 0x0100287e, 6236 }, /* braille_dots_234567 */
+ { 0x0100287f, 3888 }, /* braille_dots_1234567 */
+ { 0x01002880, 8362 }, /* braille_dots_8 */
+ { 0x01002881, 6135 }, /* braille_dots_18 */
+ { 0x01002882, 7287 }, /* braille_dots_28 */
+ { 0x01002883, 4997 }, /* braille_dots_128 */
+ { 0x01002884, 7847 }, /* braille_dots_38 */
+ { 0x01002885, 5589 }, /* braille_dots_138 */
+ { 0x01002886, 6741 }, /* braille_dots_238 */
+ { 0x01002887, 4420 }, /* braille_dots_1238 */
+ { 0x01002888, 8119 }, /* braille_dots_48 */
+ { 0x01002889, 5877 }, /* braille_dots_148 */
+ { 0x0100288a, 7029 }, /* braille_dots_248 */
+ { 0x0100288b, 4724 }, /* braille_dots_1248 */
+ { 0x0100288c, 7589 }, /* braille_dots_348 */
+ { 0x0100288d, 5316 }, /* braille_dots_1348 */
+ { 0x0100288e, 6468 }, /* braille_dots_2348 */
+ { 0x0100288f, 4132 }, /* braille_dots_12348 */
+ { 0x01002890, 8251 }, /* braille_dots_58 */
+ { 0x01002891, 6017 }, /* braille_dots_158 */
+ { 0x01002892, 7169 }, /* braille_dots_258 */
+ { 0x01002893, 4872 }, /* braille_dots_1258 */
+ { 0x01002894, 7729 }, /* braille_dots_358 */
+ { 0x01002895, 5464 }, /* braille_dots_1358 */
+ { 0x01002896, 6616 }, /* braille_dots_2358 */
+ { 0x01002897, 4288 }, /* braille_dots_12358 */
+ { 0x01002898, 8001 }, /* braille_dots_458 */
+ { 0x01002899, 5752 }, /* braille_dots_1458 */
+ { 0x0100289a, 6904 }, /* braille_dots_2458 */
+ { 0x0100289b, 4592 }, /* braille_dots_12458 */
+ { 0x0100289c, 7464 }, /* braille_dots_3458 */
+ { 0x0100289d, 5184 }, /* braille_dots_13458 */
+ { 0x0100289e, 6336 }, /* braille_dots_23458 */
+ { 0x0100289f, 3993 }, /* braille_dots_123458 */
+ { 0x010028a0, 8315 }, /* braille_dots_68 */
+ { 0x010028a1, 6085 }, /* braille_dots_168 */
+ { 0x010028a2, 7237 }, /* braille_dots_268 */
+ { 0x010028a3, 4944 }, /* braille_dots_1268 */
+ { 0x010028a4, 7797 }, /* braille_dots_368 */
+ { 0x010028a5, 5536 }, /* braille_dots_1368 */
+ { 0x010028a6, 6688 }, /* braille_dots_2368 */
+ { 0x010028a7, 4364 }, /* braille_dots_12368 */
+ { 0x010028a8, 8069 }, /* braille_dots_468 */
+ { 0x010028a9, 5824 }, /* braille_dots_1468 */
+ { 0x010028aa, 6976 }, /* braille_dots_2468 */
+ { 0x010028ab, 4668 }, /* braille_dots_12468 */
+ { 0x010028ac, 7536 }, /* braille_dots_3468 */
+ { 0x010028ad, 5260 }, /* braille_dots_13468 */
+ { 0x010028ae, 6412 }, /* braille_dots_23468 */
+ { 0x010028af, 4073 }, /* braille_dots_123468 */
+ { 0x010028b0, 8201 }, /* braille_dots_568 */
+ { 0x010028b1, 5964 }, /* braille_dots_1568 */
+ { 0x010028b2, 7116 }, /* braille_dots_2568 */
+ { 0x010028b3, 4816 }, /* braille_dots_12568 */
+ { 0x010028b4, 7676 }, /* braille_dots_3568 */
+ { 0x010028b5, 5408 }, /* braille_dots_13568 */
+ { 0x010028b6, 6560 }, /* braille_dots_23568 */
+ { 0x010028b7, 4229 }, /* braille_dots_123568 */
+ { 0x010028b8, 7948 }, /* braille_dots_4568 */
+ { 0x010028b9, 5696 }, /* braille_dots_14568 */
+ { 0x010028ba, 6848 }, /* braille_dots_24568 */
+ { 0x010028bb, 4533 }, /* braille_dots_124568 */
+ { 0x010028bc, 7408 }, /* braille_dots_34568 */
+ { 0x010028bd, 5125 }, /* braille_dots_134568 */
+ { 0x010028be, 6277 }, /* braille_dots_234568 */
+ { 0x010028bf, 3931 }, /* braille_dots_1234568 */
+ { 0x010028c0, 8346 }, /* braille_dots_78 */
+ { 0x010028c1, 6118 }, /* braille_dots_178 */
+ { 0x010028c2, 7270 }, /* braille_dots_278 */
+ { 0x010028c3, 4979 }, /* braille_dots_1278 */
+ { 0x010028c4, 7830 }, /* braille_dots_378 */
+ { 0x010028c5, 5571 }, /* braille_dots_1378 */
+ { 0x010028c6, 6723 }, /* braille_dots_2378 */
+ { 0x010028c7, 4401 }, /* braille_dots_12378 */
+ { 0x010028c8, 8102 }, /* braille_dots_478 */
+ { 0x010028c9, 5859 }, /* braille_dots_1478 */
+ { 0x010028ca, 7011 }, /* braille_dots_2478 */
+ { 0x010028cb, 4705 }, /* braille_dots_12478 */
+ { 0x010028cc, 7571 }, /* braille_dots_3478 */
+ { 0x010028cd, 5297 }, /* braille_dots_13478 */
+ { 0x010028ce, 6449 }, /* braille_dots_23478 */
+ { 0x010028cf, 4112 }, /* braille_dots_123478 */
+ { 0x010028d0, 8234 }, /* braille_dots_578 */
+ { 0x010028d1, 5999 }, /* braille_dots_1578 */
+ { 0x010028d2, 7151 }, /* braille_dots_2578 */
+ { 0x010028d3, 4853 }, /* braille_dots_12578 */
+ { 0x010028d4, 7711 }, /* braille_dots_3578 */
+ { 0x010028d5, 5445 }, /* braille_dots_13578 */
+ { 0x010028d6, 6597 }, /* braille_dots_23578 */
+ { 0x010028d7, 4268 }, /* braille_dots_123578 */
+ { 0x010028d8, 7983 }, /* braille_dots_4578 */
+ { 0x010028d9, 5733 }, /* braille_dots_14578 */
+ { 0x010028da, 6885 }, /* braille_dots_24578 */
+ { 0x010028db, 4572 }, /* braille_dots_124578 */
+ { 0x010028dc, 7445 }, /* braille_dots_34578 */
+ { 0x010028dd, 5164 }, /* braille_dots_134578 */
+ { 0x010028de, 6316 }, /* braille_dots_234578 */
+ { 0x010028df, 3972 }, /* braille_dots_1234578 */
+ { 0x010028e0, 8298 }, /* braille_dots_678 */
+ { 0x010028e1, 6067 }, /* braille_dots_1678 */
+ { 0x010028e2, 7219 }, /* braille_dots_2678 */
+ { 0x010028e3, 4925 }, /* braille_dots_12678 */
+ { 0x010028e4, 7779 }, /* braille_dots_3678 */
+ { 0x010028e5, 5517 }, /* braille_dots_13678 */
+ { 0x010028e6, 6669 }, /* braille_dots_23678 */
+ { 0x010028e7, 4344 }, /* braille_dots_123678 */
+ { 0x010028e8, 8051 }, /* braille_dots_4678 */
+ { 0x010028e9, 5805 }, /* braille_dots_14678 */
+ { 0x010028ea, 6957 }, /* braille_dots_24678 */
+ { 0x010028eb, 4648 }, /* braille_dots_124678 */
+ { 0x010028ec, 7517 }, /* braille_dots_34678 */
+ { 0x010028ed, 5240 }, /* braille_dots_134678 */
+ { 0x010028ee, 6392 }, /* braille_dots_234678 */
+ { 0x010028ef, 4052 }, /* braille_dots_1234678 */
+ { 0x010028f0, 8183 }, /* braille_dots_5678 */
+ { 0x010028f1, 5945 }, /* braille_dots_15678 */
+ { 0x010028f2, 7097 }, /* braille_dots_25678 */
+ { 0x010028f3, 4796 }, /* braille_dots_125678 */
+ { 0x010028f4, 7657 }, /* braille_dots_35678 */
+ { 0x010028f5, 5388 }, /* braille_dots_135678 */
+ { 0x010028f6, 6540 }, /* braille_dots_235678 */
+ { 0x010028f7, 4208 }, /* braille_dots_1235678 */
+ { 0x010028f8, 7929 }, /* braille_dots_45678 */
+ { 0x010028f9, 5676 }, /* braille_dots_145678 */
+ { 0x010028fa, 6828 }, /* braille_dots_245678 */
+ { 0x010028fb, 4512 }, /* braille_dots_1245678 */
+ { 0x010028fc, 7388 }, /* braille_dots_345678 */
+ { 0x010028fd, 5104 }, /* braille_dots_1345678 */
+ { 0x010028fe, 6256 }, /* braille_dots_2345678 */
+ { 0x010028ff, 3909 }, /* braille_dots_12345678 */
+ { 0x100000a8, 16910 }, /* hpmute_acute */
+ { 0x100000a9, 16977 }, /* hpmute_grave */
+ { 0x100000aa, 16923 }, /* hpmute_asciicircum */
+ { 0x100000ab, 16960 }, /* hpmute_diaeresis */
+ { 0x100000ac, 16942 }, /* hpmute_asciitilde */
+ { 0x100000af, 16867 }, /* hplira */
+ { 0x100000be, 16813 }, /* hpguilder */
+ { 0x100000ee, 17014 }, /* hpYdiaeresis */
+ { 0x100000f6, 16874 }, /* hplongminus */
+ { 0x100000fc, 16767 }, /* hpblock */
+ { 0x1000fe22, 10414 }, /* Ddiaeresis */
+ { 0x1000fe27, 10344 }, /* Dacute_accent */
+ { 0x1000fe2c, 10379 }, /* Dcedilla_accent */
+ { 0x1000fe5e, 10395 }, /* Dcircumflex_accent */
+ { 0x1000fe60, 11189 }, /* Dgrave_accent */
+ { 0x1000fe7e, 11417 }, /* Dtilde */
+ { 0x1000feb0, 11388 }, /* Dring_accent */
+ { 0x1000ff00, 11380 }, /* DRemove */
+ { 0x1000ff48, 16886 }, /* hpModelock1 */
+ { 0x1000ff49, 16898 }, /* hpModelock2 */
+ { 0x1000ff6c, 16990 }, /* hpReset */
+ { 0x1000ff6d, 16998 }, /* hpSystem */
+ { 0x1000ff6e, 17007 }, /* hpUser */
+ { 0x1000ff6f, 16775 }, /* hpClearLine */
+ { 0x1000ff70, 16836 }, /* hpInsertLine */
+ { 0x1000ff71, 16800 }, /* hpDeleteLine */
+ { 0x1000ff72, 16823 }, /* hpInsertChar */
+ { 0x1000ff73, 16787 }, /* hpDeleteChar */
+ { 0x1000ff74, 16757 }, /* hpBackTab */
+ { 0x1000ff75, 16854 }, /* hpKP_BackTab */
+ { 0x1000ff76, 12125 }, /* Ext16bit_L */
+ { 0x1000ff77, 12136 }, /* Ext16bit_R */
+ { 0x1004ff02, 20956 }, /* osfCopy */
+ { 0x1004ff03, 20964 }, /* osfCut */
+ { 0x1004ff04, 21163 }, /* osfPaste */
+ { 0x1004ff07, 20900 }, /* osfBackTab */
+ { 0x1004ff08, 20887 }, /* osfBackSpace */
+ { 0x1004ff0b, 20947 }, /* osfClear */
+ { 0x1004ff1b, 21026 }, /* osfEscape */
+ { 0x1004ff31, 20876 }, /* osfAddMode */
+ { 0x1004ff32, 21197 }, /* osfPrimaryPaste */
+ { 0x1004ff33, 21213 }, /* osfQuickPaste */
+ { 0x1004ff40, 21128 }, /* osfPageLeft */
+ { 0x1004ff41, 21153 }, /* osfPageUp */
+ { 0x1004ff42, 21116 }, /* osfPageDown */
+ { 0x1004ff43, 21140 }, /* osfPageRight */
+ { 0x1004ff44, 20864 }, /* osfActivate */
+ { 0x1004ff45, 21080 }, /* osfMenuBar */
+ { 0x1004ff51, 21064 }, /* osfLeft */
+ { 0x1004ff52, 21290 }, /* osfUp */
+ { 0x1004ff53, 21250 }, /* osfRight */
+ { 0x1004ff54, 20996 }, /* osfDown */
+ { 0x1004ff57, 21015 }, /* osfEndLine */
+ { 0x1004ff58, 20924 }, /* osfBeginLine */
+ { 0x1004ff59, 21004 }, /* osfEndData */
+ { 0x1004ff5a, 20911 }, /* osfBeginData */
+ { 0x1004ff5b, 21185 }, /* osfPrevMenu */
+ { 0x1004ff5c, 21104 }, /* osfNextMenu */
+ { 0x1004ff5d, 21172 }, /* osfPrevField */
+ { 0x1004ff5e, 21091 }, /* osfNextField */
+ { 0x1004ff60, 21259 }, /* osfSelect */
+ { 0x1004ff63, 21054 }, /* osfInsert */
+ { 0x1004ff65, 21282 }, /* osfUndo */
+ { 0x1004ff67, 21072 }, /* osfMenu */
+ { 0x1004ff69, 20937 }, /* osfCancel */
+ { 0x1004ff6a, 21046 }, /* osfHelp */
+ { 0x1004ff71, 21269 }, /* osfSelectAll */
+ { 0x1004ff72, 20981 }, /* osfDeselectAll */
+ { 0x1004ff73, 21227 }, /* osfReselect */
+ { 0x1004ff74, 21036 }, /* osfExtend */
+ { 0x1004ff78, 21239 }, /* osfRestore */
+ { 0x1004ffff, 20971 }, /* osfDelete */
+ { 0x1005ff00, 24032 }, /* SunFA_Grave */
+ { 0x1005ff01, 24003 }, /* SunFA_Circum */
+ { 0x1005ff02, 24044 }, /* SunFA_Tilde */
+ { 0x1005ff03, 23977 }, /* SunFA_Acute */
+ { 0x1005ff04, 24016 }, /* SunFA_Diaeresis */
+ { 0x1005ff05, 23989 }, /* SunFA_Cedilla */
+ { 0x1005ff10, 23963 }, /* SunF36 */
+ { 0x1005ff11, 23970 }, /* SunF37 */
+ { 0x1005ff60, 24180 }, /* SunSys_Req */
+ { 0x1005ff70, 24163 }, /* SunProps */
+ { 0x1005ff71, 24064 }, /* SunFront */
+ { 0x1005ff72, 23948 }, /* SunCopy */
+ { 0x1005ff73, 24073 }, /* SunOpen */
+ { 0x1005ff74, 24103 }, /* SunPaste */
+ { 0x1005ff75, 23956 }, /* SunCut */
+ { 0x1005ff76, 24112 }, /* SunPowerSwitch */
+ { 0x1005ff77, 23884 }, /* SunAudioLowerVolume */
+ { 0x1005ff78, 23904 }, /* SunAudioMute */
+ { 0x1005ff79, 23917 }, /* SunAudioRaiseVolume */
+ { 0x1005ff7a, 24199 }, /* SunVideoDegauss */
+ { 0x1005ff7b, 24215 }, /* SunVideoLowerBrightness */
+ { 0x1005ff7c, 24239 }, /* SunVideoRaiseBrightness */
+ { 0x1005ff7d, 24127 }, /* SunPowerSwitchShift */
+ { 0x1008fe01, 28451 }, /* XF86Switch_VT_1 */
+ { 0x1008fe02, 28518 }, /* XF86Switch_VT_2 */
+ { 0x1008fe03, 28534 }, /* XF86Switch_VT_3 */
+ { 0x1008fe04, 28550 }, /* XF86Switch_VT_4 */
+ { 0x1008fe05, 28566 }, /* XF86Switch_VT_5 */
+ { 0x1008fe06, 28582 }, /* XF86Switch_VT_6 */
+ { 0x1008fe07, 28598 }, /* XF86Switch_VT_7 */
+ { 0x1008fe08, 28614 }, /* XF86Switch_VT_8 */
+ { 0x1008fe09, 28630 }, /* XF86Switch_VT_9 */
+ { 0x1008fe0a, 28467 }, /* XF86Switch_VT_10 */
+ { 0x1008fe0b, 28484 }, /* XF86Switch_VT_11 */
+ { 0x1008fe0c, 28501 }, /* XF86Switch_VT_12 */
+ { 0x1008fe20, 28777 }, /* XF86Ungrab */
+ { 0x1008fe21, 27135 }, /* XF86ClearGrab */
+ { 0x1008fe22, 27962 }, /* XF86Next_VMode */
+ { 0x1008fe23, 28084 }, /* XF86Prev_VMode */
+ { 0x1008fe24, 27742 }, /* XF86LogWindowTree */
+ { 0x1008fe25, 27715 }, /* XF86LogGrabInfo */
+ { 0x1008ff01, 27853 }, /* XF86ModeLock */
+ { 0x1008ff02, 27888 }, /* XF86MonBrightnessUp */
+ { 0x1008ff03, 27866 }, /* XF86MonBrightnessDown */
+ { 0x1008ff04, 27491 }, /* XF86KbdLightOnOff */
+ { 0x1008ff05, 27471 }, /* XF86KbdBrightnessUp */
+ { 0x1008ff06, 27449 }, /* XF86KbdBrightnessDown */
+ { 0x1008ff10, 28383 }, /* XF86Standby */
+ { 0x1008ff11, 26749 }, /* XF86AudioLowerVolume */
+ { 0x1008ff12, 26802 }, /* XF86AudioMute */
+ { 0x1008ff13, 26873 }, /* XF86AudioRaiseVolume */
+ { 0x1008ff14, 26845 }, /* XF86AudioPlay */
+ { 0x1008ff15, 26962 }, /* XF86AudioStop */
+ { 0x1008ff16, 26859 }, /* XF86AudioPrev */
+ { 0x1008ff17, 26816 }, /* XF86AudioNext */
+ { 0x1008ff18, 27412 }, /* XF86HomePage */
+ { 0x1008ff19, 27760 }, /* XF86Mail */
+ { 0x1008ff1a, 28395 }, /* XF86Start */
+ { 0x1008ff1b, 28307 }, /* XF86Search */
+ { 0x1008ff1c, 26914 }, /* XF86AudioRecord */
+ { 0x1008ff1d, 27090 }, /* XF86Calculator */
+ { 0x1008ff1e, 27808 }, /* XF86Memo */
+ { 0x1008ff1f, 28681 }, /* XF86ToDoList */
+ { 0x1008ff20, 27105 }, /* XF86Calendar */
+ { 0x1008ff21, 28057 }, /* XF86PowerDown */
+ { 0x1008ff22, 27173 }, /* XF86ContrastAdjust */
+ { 0x1008ff23, 28177 }, /* XF86RockerUp */
+ { 0x1008ff24, 28146 }, /* XF86RockerDown */
+ { 0x1008ff25, 28161 }, /* XF86RockerEnter */
+ { 0x1008ff26, 26985 }, /* XF86Back */
+ { 0x1008ff27, 27317 }, /* XF86Forward */
+ { 0x1008ff28, 28405 }, /* XF86Stop */
+ { 0x1008ff29, 28113 }, /* XF86Refresh */
+ { 0x1008ff2a, 28071 }, /* XF86PowerOff */
+ { 0x1008ff2b, 28865 }, /* XF86WakeUp */
+ { 0x1008ff2c, 27258 }, /* XF86Eject */
+ { 0x1008ff2d, 28247 }, /* XF86ScreenSaver */
+ { 0x1008ff2e, 28921 }, /* XF86WWW */
+ { 0x1008ff2f, 28347 }, /* XF86Sleep */
+ { 0x1008ff30, 27291 }, /* XF86Favorites */
+ { 0x1008ff31, 26830 }, /* XF86AudioPause */
+ { 0x1008ff32, 26770 }, /* XF86AudioMedia */
+ { 0x1008ff33, 27918 }, /* XF86MyComputer */
+ { 0x1008ff34, 28831 }, /* XF86VendorHome */
+ { 0x1008ff35, 27701 }, /* XF86LightBulb */
+ { 0x1008ff36, 28338 }, /* XF86Shop */
+ { 0x1008ff37, 27400 }, /* XF86History */
+ { 0x1008ff38, 28001 }, /* XF86OpenURL */
+ { 0x1008ff39, 26655 }, /* XF86AddFavorite */
+ { 0x1008ff3a, 27425 }, /* XF86HotLinks */
+ { 0x1008ff3b, 27054 }, /* XF86BrightnessAdjust */
+ { 0x1008ff3c, 27305 }, /* XF86Finance */
+ { 0x1008ff3d, 27159 }, /* XF86Community */
+ { 0x1008ff3e, 26946 }, /* XF86AudioRewind */
+ { 0x1008ff3f, 26994 }, /* XF86BackForward */
+ { 0x1008ff40, 27509 }, /* XF86Launch0 */
+ { 0x1008ff41, 27521 }, /* XF86Launch1 */
+ { 0x1008ff42, 27533 }, /* XF86Launch2 */
+ { 0x1008ff43, 27545 }, /* XF86Launch3 */
+ { 0x1008ff44, 27557 }, /* XF86Launch4 */
+ { 0x1008ff45, 27569 }, /* XF86Launch5 */
+ { 0x1008ff46, 27581 }, /* XF86Launch6 */
+ { 0x1008ff47, 27593 }, /* XF86Launch7 */
+ { 0x1008ff48, 27605 }, /* XF86Launch8 */
+ { 0x1008ff49, 27617 }, /* XF86Launch9 */
+ { 0x1008ff4a, 27629 }, /* XF86LaunchA */
+ { 0x1008ff4b, 27641 }, /* XF86LaunchB */
+ { 0x1008ff4c, 27653 }, /* XF86LaunchC */
+ { 0x1008ff4d, 27665 }, /* XF86LaunchD */
+ { 0x1008ff4e, 27677 }, /* XF86LaunchE */
+ { 0x1008ff4f, 27689 }, /* XF86LaunchF */
+ { 0x1008ff50, 26671 }, /* XF86ApplicationLeft */
+ { 0x1008ff51, 26691 }, /* XF86ApplicationRight */
+ { 0x1008ff52, 27045 }, /* XF86Book */
+ { 0x1008ff53, 27118 }, /* XF86CD */
+ { 0x1008ff54, 27075 }, /* XF86Calculater */
+ { 0x1008ff55, 27125 }, /* XF86Clear */
+ { 0x1008ff56, 27149 }, /* XF86Close */
+ { 0x1008ff57, 27192 }, /* XF86Copy */
+ { 0x1008ff58, 27201 }, /* XF86Cut */
+ { 0x1008ff59, 27224 }, /* XF86Display */
+ { 0x1008ff5a, 27250 }, /* XF86DOS */
+ { 0x1008ff5b, 27236 }, /* XF86Documents */
+ { 0x1008ff5c, 27268 }, /* XF86Excel */
+ { 0x1008ff5d, 27278 }, /* XF86Explorer */
+ { 0x1008ff5e, 27360 }, /* XF86Game */
+ { 0x1008ff5f, 27369 }, /* XF86Go */
+ { 0x1008ff60, 27438 }, /* XF86iTouch */
+ { 0x1008ff61, 27731 }, /* XF86LogOff */
+ { 0x1008ff62, 27785 }, /* XF86Market */
+ { 0x1008ff63, 27796 }, /* XF86Meeting */
+ { 0x1008ff65, 27817 }, /* XF86MenuKB */
+ { 0x1008ff66, 27828 }, /* XF86MenuPB */
+ { 0x1008ff67, 27933 }, /* XF86MySites */
+ { 0x1008ff68, 27945 }, /* XF86New */
+ { 0x1008ff69, 27953 }, /* XF86News */
+ { 0x1008ff6a, 27977 }, /* XF86OfficeHome */
+ { 0x1008ff6b, 27992 }, /* XF86Open */
+ { 0x1008ff6c, 28013 }, /* XF86Option */
+ { 0x1008ff6d, 28024 }, /* XF86Paste */
+ { 0x1008ff6e, 28034 }, /* XF86Phone */
+ { 0x1008ff70, 28099 }, /* XF86Q */
+ { 0x1008ff72, 28136 }, /* XF86Reply */
+ { 0x1008ff73, 28125 }, /* XF86Reload */
+ { 0x1008ff74, 28190 }, /* XF86RotateWindows */
+ { 0x1008ff75, 28223 }, /* XF86RotationPB */
+ { 0x1008ff76, 28208 }, /* XF86RotationKB */
+ { 0x1008ff77, 28238 }, /* XF86Save */
+ { 0x1008ff78, 28294 }, /* XF86ScrollUp */
+ { 0x1008ff79, 28279 }, /* XF86ScrollDown */
+ { 0x1008ff7a, 28263 }, /* XF86ScrollClick */
+ { 0x1008ff7b, 28329 }, /* XF86Send */
+ { 0x1008ff7c, 28357 }, /* XF86Spell */
+ { 0x1008ff7d, 28367 }, /* XF86SplitScreen */
+ { 0x1008ff7e, 28427 }, /* XF86Support */
+ { 0x1008ff7f, 28646 }, /* XF86TaskPane */
+ { 0x1008ff80, 28659 }, /* XF86Terminal */
+ { 0x1008ff81, 28694 }, /* XF86Tools */
+ { 0x1008ff82, 28766 }, /* XF86Travel */
+ { 0x1008ff84, 28812 }, /* XF86UserPB */
+ { 0x1008ff85, 28788 }, /* XF86User1KB */
+ { 0x1008ff86, 28800 }, /* XF86User2KB */
+ { 0x1008ff87, 28846 }, /* XF86Video */
+ { 0x1008ff88, 28887 }, /* XF86WheelButton */
+ { 0x1008ff89, 28912 }, /* XF86Word */
+ { 0x1008ff8a, 28929 }, /* XF86Xfer */
+ { 0x1008ff8b, 28949 }, /* XF86ZoomIn */
+ { 0x1008ff8c, 28960 }, /* XF86ZoomOut */
+ { 0x1008ff8d, 26976 }, /* XF86Away */
+ { 0x1008ff8e, 27839 }, /* XF86Messenger */
+ { 0x1008ff8f, 28876 }, /* XF86WebCam */
+ { 0x1008ff90, 27769 }, /* XF86MailForward */
+ { 0x1008ff91, 28044 }, /* XF86Pictures */
+ { 0x1008ff92, 27908 }, /* XF86Music */
+ { 0x1008ff93, 27010 }, /* XF86Battery */
+ { 0x1008ff94, 27031 }, /* XF86Bluetooth */
+ { 0x1008ff95, 28903 }, /* XF86WLAN */
+ { 0x1008ff96, 28823 }, /* XF86UWB */
+ { 0x1008ff97, 26732 }, /* XF86AudioForward */
+ { 0x1008ff98, 26930 }, /* XF86AudioRepeat */
+ { 0x1008ff99, 26894 }, /* XF86AudioRandomPlay */
+ { 0x1008ff9a, 28414 }, /* XF86Subtitle */
+ { 0x1008ff9b, 26712 }, /* XF86AudioCycleTrack */
+ { 0x1008ff9c, 27209 }, /* XF86CycleAngle */
+ { 0x1008ff9d, 27329 }, /* XF86FrameBack */
+ { 0x1008ff9e, 27343 }, /* XF86FrameForward */
+ { 0x1008ff9f, 28672 }, /* XF86Time */
+ { 0x1008ffa0, 28318 }, /* XF86Select */
+ { 0x1008ffa1, 28856 }, /* XF86View */
+ { 0x1008ffa2, 28704 }, /* XF86TopMenu */
+ { 0x1008ffa3, 28105 }, /* XF86Red */
+ { 0x1008ffa4, 27376 }, /* XF86Green */
+ { 0x1008ffa5, 28938 }, /* XF86Yellow */
+ { 0x1008ffa6, 27022 }, /* XF86Blue */
+ { 0x1008ffa7, 28439 }, /* XF86Suspend */
+ { 0x1008ffa8, 27386 }, /* XF86Hibernate */
+ { 0x1008ffa9, 28747 }, /* XF86TouchpadToggle */
+ { 0x1008ffb0, 28732 }, /* XF86TouchpadOn */
+ { 0x1008ffb1, 28716 }, /* XF86TouchpadOff */
+ { 0x1008ffb2, 26785 }, /* XF86AudioMicMute */
};
diff --git a/src/3rdparty/xkbcommon/src/state.c b/src/3rdparty/xkbcommon/src/state.c
index ac4576f5b8..768d47c182 100644
--- a/src/3rdparty/xkbcommon/src/state.c
+++ b/src/3rdparty/xkbcommon/src/state.c
@@ -60,6 +60,7 @@
*/
#include "keymap.h"
+#include "keysym.h"
struct xkb_filter {
union xkb_action action;
@@ -405,7 +406,6 @@ xkb_action_breaks_latch(const union xkb_action *action)
case ACTION_TYPE_PTR_LOCK:
case ACTION_TYPE_CTRL_SET:
case ACTION_TYPE_CTRL_LOCK:
- case ACTION_TYPE_KEY_REDIRECT:
case ACTION_TYPE_SWITCH_VT:
case ACTION_TYPE_TERMINATE:
return true;
@@ -833,13 +833,26 @@ XKB_EXPORT xkb_keysym_t
xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
{
const xkb_keysym_t *syms;
+ xkb_keysym_t sym;
int num_syms;
+ xkb_mod_index_t caps;
num_syms = xkb_state_key_get_syms(state, kc, &syms);
if (num_syms != 1)
return XKB_KEY_NoSymbol;
- return syms[0];
+ sym = syms[0];
+
+ /*
+ * Perform capitalization transformation, see:
+ * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
+ */
+ caps = xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
+ if (xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 &&
+ xkb_state_mod_index_is_consumed(state, kc, caps) == 0)
+ sym = xkb_keysym_to_upper(sym);
+
+ return sym;
}
/**
@@ -989,13 +1002,12 @@ xkb_state_mod_names_are_active(struct xkb_state *state,
{
va_list ap;
xkb_mod_index_t idx = 0;
- const char *str;
xkb_mod_mask_t wanted = 0;
int ret = 0;
va_start(ap, match);
while (1) {
- str = va_arg(ap, const char *);
+ const char *str = va_arg(ap, const char *);
if (str == NULL)
break;
idx = xkb_keymap_mod_get_index(state->keymap, str);
diff --git a/src/3rdparty/xkbcommon/src/text.c b/src/3rdparty/xkbcommon/src/text.c
index 4b8ad0984f..59d6c775cb 100644
--- a/src/3rdparty/xkbcommon/src/text.c
+++ b/src/3rdparty/xkbcommon/src/text.c
@@ -175,10 +175,10 @@ const LookupEntry actionTypeNames[] = {
{ "SwitchScreen", ACTION_TYPE_SWITCH_VT },
{ "SetControls", ACTION_TYPE_CTRL_SET },
{ "LockControls", ACTION_TYPE_CTRL_LOCK },
- { "RedirectKey", ACTION_TYPE_KEY_REDIRECT },
- { "Redirect", ACTION_TYPE_KEY_REDIRECT },
{ "Private", ACTION_TYPE_PRIVATE },
/* deprecated actions below here - unused */
+ { "RedirectKey", ACTION_TYPE_NONE },
+ { "Redirect", ACTION_TYPE_NONE },
{ "ISOLock", ACTION_TYPE_NONE },
{ "ActionMessage", ACTION_TYPE_NONE },
{ "MessageAction", ACTION_TYPE_NONE },
@@ -251,9 +251,9 @@ const char *
KeyNameText(struct xkb_context *ctx, xkb_atom_t name)
{
const char *sname = xkb_atom_text(ctx, name);
- size_t len = strlen(sname) + 3;
+ size_t len = strlen_safe(sname) + 3;
char *buf = xkb_context_get_buffer(ctx, len);
- snprintf(buf, len, "<%s>", sname);
+ snprintf(buf, len, "<%s>", strempty(sname));
return buf;
}
diff --git a/src/3rdparty/xkbcommon/src/utils.c b/src/3rdparty/xkbcommon/src/utils.c
new file mode 100644
index 0000000000..a00b04eeec
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/utils.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2013 Ran Benita <ran234@gmail.com>
+ *
+ * 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 (including the next
+ * paragraph) 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 "utils.h"
+
+#ifdef HAVE_MMAP
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+bool
+map_file(FILE *file, const char **string_out, size_t *size_out)
+{
+ struct stat stat_buf;
+ const int fd = fileno(file);
+ char *string;
+
+ /* Make sure to keep the errno on failure! */
+
+ if (fstat(fd, &stat_buf) != 0)
+ return false;
+
+ string = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (string == MAP_FAILED)
+ return false;
+
+ *string_out = string;
+ *size_out = stat_buf.st_size;
+ return true;
+}
+
+void
+unmap_file(const char *str, size_t size)
+{
+ munmap(UNCONSTIFY(str), size);
+}
+
+#else
+
+bool
+map_file(FILE *file, const char **string_out, size_t *size_out)
+{
+ long ret;
+ size_t ret_s;
+ char *string;
+ size_t size;
+
+ /* Make sure to keep the errno on failure! */
+
+ ret = fseek(file, 0, SEEK_END);
+ if (ret != 0)
+ return false;
+
+ ret = ftell(file);
+ if (ret < 0)
+ return false;
+ size = (size_t) ret;
+
+ ret = fseek(file, 0, SEEK_SET);
+ if (ret < 0)
+ return false;
+
+ string = malloc(size);
+ if (!string)
+ return false;
+
+ ret_s = fread(string, 1, size, file);
+ if (ret_s < size) {
+ free(string);
+ return false;
+ }
+
+ *string_out = string;
+ *size_out = size;
+ return true;
+}
+
+void
+unmap_file(const char *str, size_t size)
+{
+ free(UNCONSTIFY(str));
+}
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/utils.h b/src/3rdparty/xkbcommon/src/utils.h
index b4daaddaaa..81d1cc9412 100644
--- a/src/3rdparty/xkbcommon/src/utils.h
+++ b/src/3rdparty/xkbcommon/src/utils.h
@@ -24,8 +24,10 @@
#ifndef UTILS_H
#define UTILS_H 1
+#include <errno.h>
#include <inttypes.h>
#include <stdbool.h>
+#include <stdio.h>
#include <string.h>
#include <strings.h>
@@ -70,6 +72,12 @@ strdup_safe(const char *s)
return s ? strdup(s) : NULL;
}
+static inline size_t
+strlen_safe(const char *s)
+{
+ return s ? strlen(s) : 0;
+}
+
static inline bool
isempty(const char *s)
{
@@ -82,6 +90,12 @@ strnull(const char *s)
return s ? s : "(null)";
}
+static inline const char *
+strempty(const char *s)
+{
+ return s ? s : "";
+}
+
static inline void *
memdup(const void *mem, size_t nmemb, size_t size)
{
@@ -91,6 +105,81 @@ memdup(const void *mem, size_t nmemb, size_t size)
return p;
}
+static inline int
+min(int misc, int other)
+{
+ return (misc < other) ? misc : other;
+}
+
+static inline int
+max(int misc, int other)
+{
+ return (misc > other) ? misc : other;
+}
+
+/* ctype.h is locale-dependent and has other oddities. */
+static inline bool
+is_space(char ch)
+{
+ return ch == ' ' || (ch >= '\t' && ch <= '\r');
+}
+
+static inline bool
+is_alpha(char ch)
+{
+ return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
+}
+
+static inline bool
+is_digit(char ch)
+{
+ return ch >= '0' && ch <= '9';
+}
+
+static inline bool
+is_alnum(char ch)
+{
+ return is_alpha(ch) || is_digit(ch);
+}
+
+static inline bool
+is_xdigit(char ch)
+{
+ return
+ (ch >= '0' && ch <= '9') ||
+ (ch >= 'a' && ch <= 'f') ||
+ (ch >= 'A' && ch <= 'F');
+}
+
+static inline bool
+is_graph(char ch)
+{
+ /* See table in ascii(7). */
+ return ch >= '!' && ch <= '~';
+}
+
+/*
+ * Return the bit position of the most significant bit.
+ * Note: this is 1-based! It's more useful this way, and returns 0 when
+ * mask is all 0s.
+ */
+static inline int
+msb_pos(uint32_t mask)
+{
+ int pos = 0;
+ while (mask) {
+ pos++;
+ mask >>= 1;
+ }
+ return pos;
+}
+
+bool
+map_file(FILE *file, const char **string_out, size_t *size_out);
+
+void
+unmap_file(const char *str, size_t size);
+
#define ARRAY_SIZE(arr) ((sizeof(arr) / sizeof(*(arr))))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -133,4 +222,10 @@ memdup(const void *mem, size_t nmemb, size_t size)
# define ATTR_NULL_SENTINEL
#endif /* GNUC >= 4 */
+#if (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 295)
+#define ATTR_PACKED __attribute__((__packed__))
+#else
+#define ATTR_PACKED
+#endif
+
#endif /* UTILS_H */
diff --git a/src/3rdparty/xkbcommon/src/x11/util.c b/src/3rdparty/xkbcommon/src/x11/util.c
new file mode 100644
index 0000000000..92ff2e630e
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/x11/util.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright © 2013 Ran Benita
+ *
+ * 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 (including the next
+ * paragraph) 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 "x11-priv.h"
+
+XKB_EXPORT int
+xkb_x11_setup_xkb_extension(xcb_connection_t *conn,
+ uint16_t major_xkb_version,
+ uint16_t minor_xkb_version,
+ enum xkb_x11_setup_xkb_extension_flags flags,
+ uint16_t *major_xkb_version_out,
+ uint16_t *minor_xkb_version_out,
+ uint8_t *base_event_out,
+ uint8_t *base_error_out)
+{
+ uint8_t base_event, base_error;
+ uint16_t server_major, server_minor;
+
+ if (flags & ~(XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS)) {
+ /* log_err_func(ctx, "unrecognized flags: %#x\n", flags); */
+ return 0;
+ }
+
+ {
+ const xcb_query_extension_reply_t *reply =
+ xcb_get_extension_data(conn, &xcb_xkb_id);
+ if (!reply) {
+ /* log_err_func(ctx, "failed to query for XKB extension\n"); */
+ return 0;
+ }
+
+ if (!reply->present) {
+ /* log_err_func(ctx, "failed to start using XKB extension: not available in server\n"); */
+ return 0;
+ }
+
+ base_event = reply->first_event;
+ base_error = reply->first_error;
+ }
+
+ {
+ xcb_generic_error_t *error = NULL;
+ xcb_xkb_use_extension_cookie_t cookie =
+ xcb_xkb_use_extension(conn, major_xkb_version, minor_xkb_version);
+ xcb_xkb_use_extension_reply_t *reply =
+ xcb_xkb_use_extension_reply(conn, cookie, &error);
+
+ if (!reply) {
+ /* log_err_func(ctx, */
+ /* "failed to start using XKB extension: error code %d\n", */
+ /* error ? error->error_code : -1); */
+ free(error);
+ return 0;
+ }
+
+ if (!reply->supported) {
+ /* log_err_func(ctx, */
+ /* "failed to start using XKB extension: server doesn't support version %d.%d\n", */
+ /* major_xkb_version, minor_xkb_version); */
+ free(reply);
+ return 0;
+ }
+
+ server_major = reply->serverMajor;
+ server_minor = reply->serverMinor;
+
+ free(reply);
+ }
+
+ /*
+ * The XkbUseExtension() in libX11 has a *bunch* of legacy stuff, but
+ * it doesn't seem like any of it is useful to us.
+ */
+
+ if (major_xkb_version_out)
+ *major_xkb_version_out = server_major;
+ if (minor_xkb_version_out)
+ *minor_xkb_version_out = server_minor;
+ if (base_event_out)
+ *base_event_out = base_event;
+ if (base_error_out)
+ *base_error_out = base_error;
+
+ return 1;
+}
+
+XKB_EXPORT int32_t
+xkb_x11_get_core_keyboard_device_id(xcb_connection_t *conn)
+{
+ int32_t device_id;
+ xcb_xkb_get_device_info_cookie_t cookie =
+ xcb_xkb_get_device_info(conn, XCB_XKB_ID_USE_CORE_KBD,
+ 0, 0, 0, 0, 0, 0);
+ xcb_xkb_get_device_info_reply_t *reply =
+ xcb_xkb_get_device_info_reply(conn, cookie, NULL);
+
+ if (!reply)
+ return -1;
+
+ device_id = reply->deviceID;
+ free(reply);
+ return device_id;
+}
+
+bool
+get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out)
+{
+ xcb_get_atom_name_cookie_t cookie;
+ xcb_get_atom_name_reply_t *reply;
+ int length;
+ char *name;
+
+ if (atom == 0) {
+ *out = NULL;
+ return true;
+ }
+
+ cookie = xcb_get_atom_name(conn, atom);
+ reply = xcb_get_atom_name_reply(conn, cookie, NULL);
+ if (!reply)
+ return false;
+
+ length = xcb_get_atom_name_name_length(reply);
+ name = xcb_get_atom_name_name(reply);
+
+ *out = strndup(name, length);
+ if (!*out) {
+ free(reply);
+ return false;
+ }
+
+ free(reply);
+ return true;
+}
+
+bool
+adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
+ const xcb_atom_t *from, xkb_atom_t *to, const size_t count)
+{
+ enum { SIZE = 128 };
+ xcb_get_atom_name_cookie_t cookies[SIZE];
+
+ /* Send and collect the atoms in batches of reasonable SIZE. */
+ for (size_t batch = 0; batch <= count / SIZE; batch++) {
+ const size_t start = batch * SIZE;
+ const size_t stop = min((batch + 1) * SIZE, count);
+
+ /* Send. */
+ for (size_t i = start; i < stop; i++)
+ if (from[i] != XCB_ATOM_NONE)
+ cookies[i % SIZE] = xcb_get_atom_name(conn, from[i]);
+
+ /* Collect. */
+ for (size_t i = start; i < stop; i++) {
+ xcb_get_atom_name_reply_t *reply;
+
+ if (from[i] == XCB_ATOM_NONE) {
+ to[i] = XKB_ATOM_NONE;
+ continue;
+ }
+
+ reply = xcb_get_atom_name_reply(conn, cookies[i % SIZE], NULL);
+ if (!reply)
+ goto err_discard;
+
+ to[i] = xkb_atom_intern(ctx,
+ xcb_get_atom_name_name(reply),
+ xcb_get_atom_name_name_length(reply));
+ free(reply);
+
+ if (to[i] == XKB_ATOM_NONE)
+ goto err_discard;
+
+ continue;
+
+ /*
+ * If we don't discard the uncollected replies, they just
+ * sit there waiting. Sad.
+ */
+err_discard:
+ for (size_t j = i + 1; j < stop; j++)
+ xcb_discard_reply(conn, cookies[j].sequence);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool
+adopt_atom(struct xkb_context *ctx, xcb_connection_t *conn, xcb_atom_t atom,
+ xkb_atom_t *out)
+{
+ return adopt_atoms(ctx, conn, &atom, out, 1);
+}
diff --git a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
new file mode 100644
index 0000000000..968f187621
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
@@ -0,0 +1,1146 @@
+/*
+ * Copyright © 2013 Ran Benita
+ *
+ * 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 (including the next
+ * paragraph) 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 "x11-priv.h"
+
+/*
+ * References for the lonesome traveler:
+ * Xkb protocol specification:
+ * http://www.x.org/releases/current/doc/kbproto/xkbproto.html
+ * The XCB xkb XML protocol file:
+ * /user/share/xcb/xkb.xml
+ * The XCB xkb header file:
+ * /usr/include/xcb/xkb.h
+ * The old kbproto header files:
+ * /usr/include/X11/extensions/XKB{,proto,str}.h
+ * Xlib XKB source code:
+ * <libX11>/src/xkb/XKBGetMap.c (and friends)
+ * X server XKB protocol handling:
+ * <xserver>/xkb/xkb.c
+ * Man pages:
+ * XkbGetMap(3), XkbGetCompatMap(3), etc.
+ */
+
+/* Constants from /usr/include/X11/extensions/XKB.h */
+/* XkbNumModifiers. */
+#define NUM_REAL_MODS 8
+/* XkbNumVirtualMods. */
+#define NUM_VMODS 16
+/* XkbNoModifier. */
+#define NO_MODIFIER 0xff
+/* XkbNumIndicators. */
+#define NUM_INDICATORS 32
+/* XkbAllIndicatorsMask. */
+#define ALL_INDICATORS_MASK 0xffffffff
+
+/* Some macros. Not very nice but it'd be worse without them. */
+
+/*
+ * We try not to trust the server too much and be paranoid. If we get
+ * something which we definitely shouldn't, we fail.
+ */
+#define STRINGIFY(expr) #expr
+#define FAIL_UNLESS(expr) do { \
+ if (!(expr)) { \
+ log_err(keymap->ctx, \
+ "x11: failed to get keymap from X server: unmet condition in %s(): %s\n", \
+ __func__, STRINGIFY(expr)); \
+ goto fail; \
+ } \
+} while (0)
+
+#define FAIL_IF_BAD_REPLY(reply, request_name) do { \
+ if (!reply) { \
+ log_err(keymap->ctx, \
+ "x11: failed to get keymap from X server: %s request failed\n", \
+ (request_name)); \
+ goto fail; \
+ } \
+} while (0)
+
+#define ALLOC_OR_FAIL(arr, nmemb) do { \
+ if ((nmemb) > 0) { \
+ (arr) = calloc((nmemb), sizeof(*(arr))); \
+ if (!(arr)) \
+ goto fail; \
+ } \
+} while (0)
+
+
+static xkb_mod_mask_t
+translate_mods(uint8_t rmods, uint16_t vmods_low, uint16_t vmods_high)
+{
+ /* We represent mod masks in a single uint32_t value, with real mods
+ * first and vmods after (though we don't make these distinctions). */
+ return rmods | (vmods_low << 8) | (vmods_high << 16);
+}
+
+static enum xkb_action_controls
+translate_controls_mask(uint16_t wire)
+{
+ enum xkb_action_controls ret = 0;
+ if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS)
+ ret |= CONTROL_REPEAT;
+ if (wire & XCB_XKB_BOOL_CTRL_SLOW_KEYS)
+ ret |= CONTROL_SLOW;
+ if (wire & XCB_XKB_BOOL_CTRL_BOUNCE_KEYS)
+ ret |= CONTROL_DEBOUNCE;
+ if (wire & XCB_XKB_BOOL_CTRL_STICKY_KEYS)
+ ret |= CONTROL_STICKY;
+ if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS)
+ ret |= CONTROL_MOUSEKEYS;
+ if (wire & XCB_XKB_BOOL_CTRL_MOUSE_KEYS_ACCEL)
+ ret |= CONTROL_MOUSEKEYS_ACCEL;
+ if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_KEYS)
+ ret |= CONTROL_AX;
+ if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_TIMEOUT_MASK)
+ ret |= CONTROL_AX_TIMEOUT;
+ if (wire & XCB_XKB_BOOL_CTRL_ACCESS_X_FEEDBACK_MASK)
+ ret |= CONTROL_AX_FEEDBACK;
+ if (wire & XCB_XKB_BOOL_CTRL_AUDIBLE_BELL_MASK)
+ ret |= CONTROL_BELL;
+ if (wire & XCB_XKB_BOOL_CTRL_IGNORE_GROUP_LOCK_MASK)
+ ret |= CONTROL_IGNORE_GROUP_LOCK;
+ /* Some controls are not supported and don't appear here. */
+ return ret;
+}
+
+static void
+translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
+{
+ switch (wire->type) {
+ case XCB_XKB_SA_TYPE_SET_MODS:
+ action->type = ACTION_TYPE_MOD_SET;
+
+ action->mods.mods.mods = translate_mods(wire->setmods.realMods,
+ wire->setmods.vmodsLow,
+ wire->setmods.vmodsHigh);
+ action->mods.mods.mask = translate_mods(wire->setmods.mask, 0, 0);
+
+ if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
+ action->mods.flags |= ACTION_LOCK_CLEAR;
+ if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
+ action->mods.flags |= ACTION_LATCH_TO_LOCK;
+ if (wire->setmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
+ action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
+
+ break;
+ case XCB_XKB_SA_TYPE_LATCH_MODS:
+ action->type = ACTION_TYPE_MOD_LATCH;
+
+ action->mods.mods.mods = translate_mods(wire->latchmods.realMods,
+ wire->latchmods.vmodsLow,
+ wire->latchmods.vmodsHigh);
+ action->mods.mods.mask = translate_mods(wire->latchmods.mask, 0, 0);
+
+ if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
+ action->mods.flags |= ACTION_LOCK_CLEAR;
+ if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
+ action->mods.flags |= ACTION_LATCH_TO_LOCK;
+ if (wire->latchmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
+ action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
+
+ break;
+ case XCB_XKB_SA_TYPE_LOCK_MODS:
+ action->type = ACTION_TYPE_MOD_LOCK;
+
+ action->mods.mods.mods = translate_mods(wire->lockmods.realMods,
+ wire->lockmods.vmodsLow,
+ wire->lockmods.vmodsHigh);
+ action->mods.mods.mask = translate_mods(wire->lockmods.mask, 0, 0);
+
+ if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK)
+ action->mods.flags |= ACTION_LOCK_NO_LOCK;
+ if (wire->lockmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK)
+ action->mods.flags |= ACTION_LOCK_NO_UNLOCK;
+ if (wire->lockmods.flags & XCB_XKB_SA_USE_MOD_MAP_MODS)
+ action->mods.flags |= ACTION_MODS_LOOKUP_MODMAP;
+
+ break;
+ case XCB_XKB_SA_TYPE_SET_GROUP:
+ action->type = ACTION_TYPE_GROUP_SET;
+
+ action->group.group = wire->setgroup.group;
+
+ if (wire->setmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
+ action->group.flags |= ACTION_LOCK_CLEAR;
+ if (wire->setmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
+ action->group.flags |= ACTION_LATCH_TO_LOCK;
+ if (wire->setmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
+ action->group.flags |= ACTION_ABSOLUTE_SWITCH;
+
+ break;
+ case XCB_XKB_SA_TYPE_LATCH_GROUP:
+ action->type = ACTION_TYPE_GROUP_LATCH;
+
+ action->group.group = wire->latchgroup.group;
+
+ if (wire->latchmods.flags & XCB_XKB_SA_CLEAR_LOCKS)
+ action->group.flags |= ACTION_LOCK_CLEAR;
+ if (wire->latchmods.flags & XCB_XKB_SA_LATCH_TO_LOCK)
+ action->group.flags |= ACTION_LATCH_TO_LOCK;
+ if (wire->latchmods.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
+ action->group.flags |= ACTION_ABSOLUTE_SWITCH;
+
+ break;
+ case XCB_XKB_SA_TYPE_LOCK_GROUP:
+ action->type = ACTION_TYPE_GROUP_LOCK;
+
+ action->group.group = wire->lockgroup.group;
+
+ if (wire->lockgroup.flags & XCB_XKB_SA_ISO_LOCK_FLAG_GROUP_ABSOLUTE)
+ action->group.flags |= ACTION_ABSOLUTE_SWITCH;
+
+ break;
+ case XCB_XKB_SA_TYPE_MOVE_PTR:
+ action->type = ACTION_TYPE_PTR_MOVE;
+
+ action->ptr.x = (wire->moveptr.xLow | (wire->moveptr.xHigh << 8));
+ action->ptr.y = (wire->moveptr.yLow | (wire->moveptr.yHigh << 8));
+
+ if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_NO_ACCELERATION)
+ action->ptr.flags |= ACTION_NO_ACCEL;
+ if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_X)
+ action->ptr.flags |= ACTION_ABSOLUTE_X;
+ if (wire->moveptr.flags & XCB_XKB_SA_MOVE_PTR_FLAG_MOVE_ABSOLUTE_Y)
+ action->ptr.flags |= ACTION_ABSOLUTE_Y;
+
+ break;
+ case XCB_XKB_SA_TYPE_PTR_BTN:
+ action->type = ACTION_TYPE_PTR_BUTTON;
+
+ action->btn.count = wire->ptrbtn.count;
+ action->btn.button = wire->ptrbtn.button;
+ action->btn.flags = 0;
+
+ break;
+ case XCB_XKB_SA_TYPE_LOCK_PTR_BTN:
+ action->type = ACTION_TYPE_PTR_LOCK;
+
+ action->btn.button = wire->lockptrbtn.button;
+
+ if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_LOCK)
+ action->btn.flags |= ACTION_LOCK_NO_LOCK;
+ if (wire->lockptrbtn.flags & XCB_XKB_SA_ISO_LOCK_FLAG_NO_UNLOCK)
+ action->btn.flags |= ACTION_LOCK_NO_UNLOCK;
+
+ break;
+ case XCB_XKB_SA_TYPE_SET_PTR_DFLT:
+ action->type = ACTION_TYPE_PTR_DEFAULT;
+
+ action->dflt.value = wire->setptrdflt.value;
+
+ if (wire->setptrdflt.flags & XCB_XKB_SA_SET_PTR_DFLT_FLAG_DFLT_BTN_ABSOLUTE)
+ action->dflt.flags |= ACTION_ABSOLUTE_SWITCH;
+
+ break;
+ case XCB_XKB_SA_TYPE_TERMINATE:
+ action->type = ACTION_TYPE_TERMINATE;
+
+ break;
+ case XCB_XKB_SA_TYPE_SWITCH_SCREEN:
+ action->type = ACTION_TYPE_SWITCH_VT;
+
+ action->screen.screen = wire->switchscreen.newScreen;
+
+ if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION)
+ action->screen.flags |= ACTION_SAME_SCREEN;
+ if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_ABSOLUTE)
+ action->screen.flags |= ACTION_ABSOLUTE_SWITCH;
+
+ break;
+ case XCB_XKB_SA_TYPE_SET_CONTROLS:
+ action->type = ACTION_TYPE_CTRL_SET;
+ {
+ const uint16_t mask = (wire->setcontrols.boolCtrlsLow |
+ (wire->setcontrols.boolCtrlsHigh << 8));
+ action->ctrls.ctrls = translate_controls_mask(mask);
+ }
+ break;
+ case XCB_XKB_SA_TYPE_LOCK_CONTROLS:
+ action->type = ACTION_TYPE_CTRL_LOCK;
+ {
+ const uint16_t mask = (wire->lockcontrols.boolCtrlsLow |
+ (wire->lockcontrols.boolCtrlsHigh << 8));
+ action->ctrls.ctrls = translate_controls_mask(mask);
+ }
+ break;
+
+ case XCB_XKB_SA_TYPE_NO_ACTION:
+ /* We don't support these. */
+ case XCB_XKB_SA_TYPE_ISO_LOCK:
+ case XCB_XKB_SA_TYPE_REDIRECT_KEY:
+ case XCB_XKB_SA_TYPE_ACTION_MESSAGE:
+ case XCB_XKB_SA_TYPE_DEVICE_BTN:
+ case XCB_XKB_SA_TYPE_LOCK_DEVICE_BTN:
+ case XCB_XKB_SA_TYPE_DEVICE_VALUATOR:
+ action->type = ACTION_TYPE_NONE;
+ break;
+ }
+}
+
+static bool
+get_types(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
+{
+ int types_length = xcb_xkb_get_map_map_types_rtrn_length(reply, map);
+ xcb_xkb_key_type_iterator_t types_iter =
+ xcb_xkb_get_map_map_types_rtrn_iterator(reply, map);
+
+ FAIL_UNLESS(reply->firstType == 0);
+
+ keymap->num_types = reply->nTypes;
+ ALLOC_OR_FAIL(keymap->types, keymap->num_types);
+
+ for (int i = 0; i < types_length; i++) {
+ xcb_xkb_key_type_t *wire_type = types_iter.data;
+ struct xkb_key_type *type = &keymap->types[i];
+
+ FAIL_UNLESS(wire_type->numLevels > 0);
+
+ type->mods.mods = translate_mods(wire_type->mods_mods,
+ wire_type->mods_vmods, 0);
+ type->mods.mask = translate_mods(wire_type->mods_mask, 0, 0);
+ type->num_levels = wire_type->numLevels;
+
+ {
+ int entries_length = xcb_xkb_key_type_map_length(wire_type);
+ xcb_xkb_kt_map_entry_iterator_t entries_iter =
+ xcb_xkb_key_type_map_iterator(wire_type);
+
+ type->num_entries = wire_type->nMapEntries;
+ ALLOC_OR_FAIL(type->entries, type->num_entries);
+
+ for (int j = 0; j < entries_length; j++) {
+ xcb_xkb_kt_map_entry_t *wire_entry = entries_iter.data;
+ struct xkb_key_type_entry *entry = &type->entries[j];
+
+ FAIL_UNLESS(wire_entry->level < type->num_levels);
+
+ entry->level = wire_entry->level;
+ entry->mods.mods = translate_mods(wire_entry->mods_mods,
+ wire_entry->mods_vmods, 0);
+ entry->mods.mask = translate_mods(wire_entry->mods_mask, 0, 0);
+
+ xcb_xkb_kt_map_entry_next(&entries_iter);
+ }
+ }
+
+ {
+ int preserves_length = xcb_xkb_key_type_preserve_length(wire_type);
+ xcb_xkb_mod_def_iterator_t preserves_iter =
+ xcb_xkb_key_type_preserve_iterator(wire_type);
+
+ FAIL_UNLESS(preserves_length <= type->num_entries);
+
+ for (int j = 0; j < preserves_length; j++) {
+ xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data;
+ struct xkb_key_type_entry *entry = &type->entries[j];
+
+ entry->preserve.mods = translate_mods(wire_preserve->realMods,
+ wire_preserve->vmods, 0);
+ entry->preserve.mask = translate_mods(wire_preserve->mask, 0, 0);
+
+ xcb_xkb_mod_def_next(&preserves_iter);
+ }
+ }
+
+ xcb_xkb_key_type_next(&types_iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
+{
+ int sym_maps_length = xcb_xkb_get_map_map_syms_rtrn_length(reply, map);
+ xcb_xkb_key_sym_map_iterator_t sym_maps_iter =
+ xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map);
+
+ FAIL_UNLESS(reply->minKeyCode <= reply->maxKeyCode);
+ FAIL_UNLESS(reply->firstKeySym >= reply->minKeyCode);
+ FAIL_UNLESS(reply->firstKeySym + reply->nKeySyms <= reply->maxKeyCode + 1);
+
+ keymap->min_key_code = reply->minKeyCode;
+ keymap->max_key_code = reply->maxKeyCode;
+
+ ALLOC_OR_FAIL(keymap->keys, keymap->max_key_code + 1);
+
+ for (xkb_keycode_t kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++)
+ keymap->keys[kc].keycode = kc;
+
+ for (int i = 0; i < sym_maps_length; i++) {
+ xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
+ struct xkb_key *key = &keymap->keys[reply->firstKeySym + i];
+
+ key->num_groups = wire_sym_map->groupInfo & 0x0f;
+ FAIL_UNLESS(key->num_groups <= ARRAY_SIZE(wire_sym_map->kt_index));
+ ALLOC_OR_FAIL(key->groups, key->num_groups);
+
+ for (int j = 0; j < key->num_groups; j++) {
+ FAIL_UNLESS(wire_sym_map->kt_index[j] < keymap->num_types);
+ key->groups[j].type = &keymap->types[wire_sym_map->kt_index[j]];
+
+ ALLOC_OR_FAIL(key->groups[j].levels, key->groups[j].type->num_levels);
+ }
+
+ key->out_of_range_group_number = (wire_sym_map->groupInfo & 0x30) >> 4;
+
+ FAIL_UNLESS(key->out_of_range_group_number <= key->num_groups);
+
+ if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_CLAMP_INTO_RANGE)
+ key->out_of_range_group_action = RANGE_SATURATE;
+ else if (wire_sym_map->groupInfo & XCB_XKB_GROUPS_WRAP_REDIRECT_INTO_RANGE)
+ key->out_of_range_group_action = RANGE_REDIRECT;
+ else
+ key->out_of_range_group_action = RANGE_WRAP;
+
+ {
+ int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
+ xcb_keysym_t *syms_iter = xcb_xkb_key_sym_map_syms(wire_sym_map);
+
+ FAIL_UNLESS(syms_length == wire_sym_map->width * key->num_groups);
+
+ for (int j = 0; j < syms_length; j++) {
+ xcb_keysym_t wire_keysym = *syms_iter;
+ const xkb_layout_index_t group = j / wire_sym_map->width;
+ const xkb_level_index_t level = j % wire_sym_map->width;
+
+ if (level < key->groups[group].type->num_levels &&
+ wire_keysym != XKB_KEY_NoSymbol) {
+ key->groups[group].levels[level].num_syms = 1;
+ key->groups[group].levels[level].u.sym = wire_keysym;
+ }
+
+ syms_iter++;
+ }
+ }
+
+ xcb_xkb_key_sym_map_next(&sym_maps_iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
+{
+ int acts_count_length =
+ xcb_xkb_get_map_map_acts_rtrn_count_length(reply, map);
+ uint8_t *acts_count_iter = xcb_xkb_get_map_map_acts_rtrn_count(map);
+ xcb_xkb_action_iterator_t acts_iter =
+ xcb_xkb_get_map_map_acts_rtrn_acts_iterator(reply, map);
+ xcb_xkb_key_sym_map_iterator_t sym_maps_iter =
+ xcb_xkb_get_map_map_syms_rtrn_iterator(reply, map);
+
+ FAIL_UNLESS(reply->firstKeyAction == keymap->min_key_code);
+ FAIL_UNLESS(reply->firstKeyAction + reply->nKeyActions ==
+ keymap->max_key_code + 1);
+
+ for (int i = 0; i < acts_count_length; i++) {
+ xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
+ uint8_t wire_count = *acts_count_iter;
+ struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i];
+
+ for (int j = 0; j < wire_count; j++) {
+ xcb_xkb_action_t *wire_action = acts_iter.data;
+ const xkb_layout_index_t group = j / wire_sym_map->width;
+ const xkb_level_index_t level = j % wire_sym_map->width;
+
+ if (level < key->groups[group].type->num_levels) {
+ union xkb_action *action =
+ &key->groups[group].levels[level].action;
+
+ translate_action(action, wire_action);
+ }
+
+ xcb_xkb_action_next(&acts_iter);
+ }
+
+ acts_count_iter++;
+ xcb_xkb_key_sym_map_next(&sym_maps_iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
+{
+ uint8_t *iter = xcb_xkb_get_map_map_vmods_rtrn(map);
+
+ darray_resize0(keymap->mods,
+ NUM_REAL_MODS + msb_pos(reply->virtualMods));
+
+ for (int i = 0; i < NUM_VMODS; i++) {
+ if (reply->virtualMods & (1 << i)) {
+ uint8_t wire = *iter;
+ struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i);
+
+ mod->type = MOD_VIRT;
+ mod->mapping = translate_mods(wire, 0, 0);
+
+ iter++;
+ }
+ }
+
+ return true;
+}
+
+static bool
+get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
+{
+ int length = xcb_xkb_get_map_map_explicit_rtrn_length(reply, map);
+ xcb_xkb_set_explicit_iterator_t iter =
+ xcb_xkb_get_map_map_explicit_rtrn_iterator(reply, map);
+
+ for (int i = 0; i < length; i++) {
+ xcb_xkb_set_explicit_t *wire = iter.data;
+ struct xkb_key *key = &keymap->keys[wire->keycode];
+
+ FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
+ wire->keycode <= keymap->max_key_code);
+
+ if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) &&
+ key->num_groups > 0)
+ key->groups[0].explicit_type = true;
+ if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_2) &&
+ key->num_groups > 1)
+ key->groups[1].explicit_type = true;
+ if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_3) &&
+ key->num_groups > 2)
+ key->groups[2].explicit_type = true;
+ if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_4) &&
+ key->num_groups > 3)
+ key->groups[3].explicit_type = true;
+ if (wire->explicit & XCB_XKB_EXPLICIT_INTERPRET)
+ key->explicit |= EXPLICIT_INTERP;
+ if (wire->explicit & XCB_XKB_EXPLICIT_AUTO_REPEAT)
+ key->explicit |= EXPLICIT_REPEAT;
+ if (wire->explicit & XCB_XKB_EXPLICIT_V_MOD_MAP)
+ key->explicit |= EXPLICIT_VMODMAP;
+
+ xcb_xkb_set_explicit_next(&iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
+{
+ int length = xcb_xkb_get_map_map_modmap_rtrn_length(reply, map);
+ xcb_xkb_key_mod_map_iterator_t iter =
+ xcb_xkb_get_map_map_modmap_rtrn_iterator(reply, map);
+
+ for (int i = 0; i < length; i++) {
+ xcb_xkb_key_mod_map_t *wire = iter.data;
+ struct xkb_key *key = &keymap->keys[wire->keycode];
+
+ FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
+ wire->keycode <= keymap->max_key_code);
+
+ key->modmap = wire->mods;
+
+ xcb_xkb_key_mod_map_next(&iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_map_reply_t *reply, xcb_xkb_get_map_map_t *map)
+{
+ int length = xcb_xkb_get_map_map_vmodmap_rtrn_length(reply, map);
+ xcb_xkb_key_v_mod_map_iterator_t iter =
+ xcb_xkb_get_map_map_vmodmap_rtrn_iterator(reply, map);
+
+ for (int i = 0; i < length; i++) {
+ xcb_xkb_key_v_mod_map_t *wire = iter.data;
+ struct xkb_key *key = &keymap->keys[wire->keycode];
+
+ FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
+ wire->keycode <= keymap->max_key_code);
+
+ key->vmodmap = translate_mods(0, wire->vmods, 0);
+
+ xcb_xkb_key_v_mod_map_next(&iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_map(struct xkb_keymap *keymap, xcb_connection_t *conn, uint16_t device_id)
+{
+ static const xcb_xkb_map_part_t required_components =
+ (XCB_XKB_MAP_PART_KEY_TYPES |
+ XCB_XKB_MAP_PART_KEY_SYMS |
+ XCB_XKB_MAP_PART_MODIFIER_MAP |
+ XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
+ XCB_XKB_MAP_PART_KEY_ACTIONS |
+ XCB_XKB_MAP_PART_VIRTUAL_MODS |
+ XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
+
+ xcb_xkb_get_map_cookie_t cookie =
+ xcb_xkb_get_map(conn, device_id, required_components,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ xcb_xkb_get_map_reply_t *reply = xcb_xkb_get_map_reply(conn, cookie, NULL);
+ xcb_xkb_get_map_map_t map;
+
+ FAIL_IF_BAD_REPLY(reply, "XkbGetMap");
+
+ if ((reply->present & required_components) != required_components)
+ goto fail;
+
+ xcb_xkb_get_map_map_unpack(xcb_xkb_get_map_map(reply),
+ reply->nTypes,
+ reply->nKeySyms,
+ reply->nKeyActions,
+ reply->totalActions,
+ reply->totalKeyBehaviors,
+ reply->virtualMods,
+ reply->totalKeyExplicit,
+ reply->totalModMapKeys,
+ reply->totalVModMapKeys,
+ reply->present,
+ &map);
+
+ if (!get_types(keymap, conn, reply, &map) ||
+ !get_sym_maps(keymap, conn, reply, &map) ||
+ !get_actions(keymap, conn, reply, &map) ||
+ !get_vmods(keymap, conn, reply, &map) ||
+ !get_explicits(keymap, conn, reply, &map) ||
+ !get_modmaps(keymap, conn, reply, &map) ||
+ !get_vmodmaps(keymap, conn, reply, &map))
+ goto fail;
+
+ free(reply);
+ return true;
+
+fail:
+ free(reply);
+ return false;
+}
+
+static bool
+get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_indicator_map_reply_t *reply)
+{
+ xcb_xkb_indicator_map_iterator_t iter =
+ xcb_xkb_get_indicator_map_maps_iterator(reply);
+
+ darray_resize0(keymap->leds, msb_pos(reply->which));
+
+ for (int i = 0; i < NUM_INDICATORS; i++) {
+ if (reply->which & (1 << i)) {
+ xcb_xkb_indicator_map_t *wire = iter.data;
+ struct xkb_led *led = &darray_item(keymap->leds, i);
+
+ if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_BASE)
+ led->which_groups |= XKB_STATE_LAYOUT_DEPRESSED;
+ if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LATCHED)
+ led->which_groups |= XKB_STATE_LAYOUT_LATCHED;
+ if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_LOCKED)
+ led->which_groups |= XKB_STATE_LAYOUT_LOCKED;
+ if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_EFFECTIVE)
+ led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE;
+ if (wire->whichGroups & XCB_XKB_IM_GROUPS_WHICH_USE_COMPAT)
+ led->which_groups |= XKB_STATE_LAYOUT_EFFECTIVE;
+
+ led->groups = wire->groups;
+
+ if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_BASE)
+ led->which_mods |= XKB_STATE_MODS_DEPRESSED;
+ if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LATCHED)
+ led->which_mods |= XKB_STATE_MODS_LATCHED;
+ if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_LOCKED)
+ led->which_mods |= XKB_STATE_MODS_LOCKED;
+ if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_EFFECTIVE)
+ led->which_mods |= XKB_STATE_MODS_EFFECTIVE;
+ if (wire->whichMods & XCB_XKB_IM_MODS_WHICH_USE_COMPAT)
+ led->which_mods |= XKB_STATE_MODS_EFFECTIVE;
+
+ led->mods.mods = translate_mods(wire->realMods, wire->vmods, 0);
+ led->mods.mask = translate_mods(wire->mods, 0, 0);
+
+ led->ctrls = translate_controls_mask(wire->ctrls);
+
+ xcb_xkb_indicator_map_next(&iter);
+ }
+ }
+
+ return true;
+}
+
+static bool
+get_indicator_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ uint16_t device_id)
+{
+ xcb_xkb_get_indicator_map_cookie_t cookie =
+ xcb_xkb_get_indicator_map(conn, device_id, ALL_INDICATORS_MASK);
+ xcb_xkb_get_indicator_map_reply_t *reply =
+ xcb_xkb_get_indicator_map_reply(conn, cookie, NULL);
+
+ FAIL_IF_BAD_REPLY(reply, "XkbGetIndicatorMap");
+
+ if (!get_indicators(keymap, conn, reply))
+ goto fail;
+
+ free(reply);
+ return true;
+
+fail:
+ free(reply);
+ return false;
+}
+
+static bool
+get_sym_interprets(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_compat_map_reply_t *reply)
+{
+ int length = xcb_xkb_get_compat_map_si_rtrn_length(reply);
+ xcb_xkb_sym_interpret_iterator_t iter =
+ xcb_xkb_get_compat_map_si_rtrn_iterator(reply);
+
+ FAIL_UNLESS(reply->firstSIRtrn == 0);
+ FAIL_UNLESS(reply->nSIRtrn == reply->nTotalSI);
+
+ keymap->num_sym_interprets = reply->nSIRtrn;
+ ALLOC_OR_FAIL(keymap->sym_interprets, keymap->num_sym_interprets);
+
+ for (int i = 0; i < length; i++) {
+ xcb_xkb_sym_interpret_t *wire = iter.data;
+ struct xkb_sym_interpret *sym_interpret = &keymap->sym_interprets[i];
+
+ sym_interpret->sym = wire->sym;
+
+ switch (wire->match & XCB_XKB_SYM_INTERP_MATCH_OP_MASK) {
+ case XCB_XKB_SYM_INTERPRET_MATCH_NONE_OF:
+ sym_interpret->match = MATCH_NONE;
+ break;
+ case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF_OR_NONE:
+ sym_interpret->match = MATCH_ANY_OR_NONE;
+ break;
+ case XCB_XKB_SYM_INTERPRET_MATCH_ANY_OF:
+ sym_interpret->match = MATCH_ANY;
+ break;
+ case XCB_XKB_SYM_INTERPRET_MATCH_ALL_OF:
+ sym_interpret->match = MATCH_ALL;
+ break;
+ case XCB_XKB_SYM_INTERPRET_MATCH_EXACTLY:
+ sym_interpret->match = MATCH_EXACTLY;
+ break;
+ }
+
+ sym_interpret->level_one_only =
+ !!(wire->match & XCB_XKB_SYM_INTERP_MATCH_LEVEL_ONE_ONLY);
+ sym_interpret->mods = wire->mods;
+
+ if (wire->virtualMod == NO_MODIFIER)
+ sym_interpret->virtual_mod = XKB_MOD_INVALID;
+ else
+ sym_interpret->virtual_mod = NUM_REAL_MODS + wire->virtualMod;
+
+ sym_interpret->repeat = !!(wire->flags & 0x01);
+ translate_action(&sym_interpret->action,
+ (xcb_xkb_action_t *) &wire->action);
+
+ xcb_xkb_sym_interpret_next(&iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_compat_map(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ uint16_t device_id)
+{
+ xcb_xkb_get_compat_map_cookie_t cookie =
+ xcb_xkb_get_compat_map(conn, device_id, 0, true, 0, 0);
+ xcb_xkb_get_compat_map_reply_t *reply =
+ xcb_xkb_get_compat_map_reply(conn, cookie, NULL);
+
+ FAIL_IF_BAD_REPLY(reply, "XkbGetCompatMap");
+
+ if (!get_sym_interprets(keymap, conn, reply))
+ goto fail;
+
+ free(reply);
+ return true;
+
+fail:
+ free(reply);
+ return false;
+}
+
+static bool
+get_type_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_names_reply_t *reply,
+ xcb_xkb_get_names_value_list_t *list)
+{
+ int key_type_names_length =
+ xcb_xkb_get_names_value_list_type_names_length(reply, list);
+ xcb_atom_t *key_type_names_iter =
+ xcb_xkb_get_names_value_list_type_names(list);
+ int n_levels_per_type_length =
+ xcb_xkb_get_names_value_list_n_levels_per_type_length(reply, list);
+ uint8_t *n_levels_per_type_iter =
+ xcb_xkb_get_names_value_list_n_levels_per_type(list);
+ xcb_atom_t *kt_level_names_iter =
+ xcb_xkb_get_names_value_list_kt_level_names(list);
+
+ FAIL_UNLESS(reply->nTypes == keymap->num_types);
+ FAIL_UNLESS(key_type_names_length == n_levels_per_type_length);
+
+ for (int i = 0; i < key_type_names_length; i++) {
+ xcb_atom_t wire_type_name = *key_type_names_iter;
+ uint8_t wire_num_levels = *n_levels_per_type_iter;
+ struct xkb_key_type *type = &keymap->types[i];
+
+ /* Levels must have names. */
+ FAIL_UNLESS(type->num_levels == wire_num_levels);
+
+ ALLOC_OR_FAIL(type->level_names, type->num_levels);
+
+ if (!adopt_atom(keymap->ctx, conn, wire_type_name, &type->name))
+ goto fail;
+
+ if (!adopt_atoms(keymap->ctx, conn,
+ kt_level_names_iter, type->level_names,
+ wire_num_levels))
+ goto fail;
+
+ kt_level_names_iter += wire_num_levels;
+ key_type_names_iter++;
+ n_levels_per_type_iter++;
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_names_reply_t *reply,
+ xcb_xkb_get_names_value_list_t *list)
+{
+ xcb_atom_t *iter = xcb_xkb_get_names_value_list_indicator_names(list);
+
+ FAIL_UNLESS(msb_pos(reply->indicators) <= darray_size(keymap->leds));
+
+ for (int i = 0; i < NUM_INDICATORS; i++) {
+ if (reply->indicators & (1 << i)) {
+ xcb_atom_t wire = *iter;
+ struct xkb_led *led = &darray_item(keymap->leds, i);
+
+ if (!adopt_atom(keymap->ctx, conn, wire, &led->name))
+ return false;
+
+ iter++;
+ }
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_names_reply_t *reply,
+ xcb_xkb_get_names_value_list_t *list)
+{
+ xcb_atom_t *iter = xcb_xkb_get_names_value_list_virtual_mod_names(list);
+
+ /*
+ * GetMap's reply->virtualMods is always 0xffff. This one really
+ * tells us which vmods exist (a vmod must have a name), so we fix
+ * up the size here.
+ */
+ darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods));
+
+ for (int i = 0; i < NUM_VMODS; i++) {
+ if (reply->virtualMods & (1 << i)) {
+ xcb_atom_t wire = *iter;
+ struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i);
+
+ if (!adopt_atom(keymap->ctx, conn, wire, &mod->name))
+ return false;
+
+ iter++;
+ }
+ }
+
+ return true;
+}
+
+static bool
+get_group_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_names_reply_t *reply,
+ xcb_xkb_get_names_value_list_t *list)
+{
+ int length = xcb_xkb_get_names_value_list_groups_length(reply, list);
+ xcb_atom_t *iter = xcb_xkb_get_names_value_list_groups(list);
+
+ keymap->num_group_names = msb_pos(reply->groupNames);
+ ALLOC_OR_FAIL(keymap->group_names, keymap->num_group_names);
+
+ if (!adopt_atoms(keymap->ctx, conn,
+ iter, keymap->group_names, length))
+ goto fail;
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_names_reply_t *reply,
+ xcb_xkb_get_names_value_list_t *list)
+{
+ int length = xcb_xkb_get_names_value_list_key_names_length(reply, list);
+ xcb_xkb_key_name_iterator_t iter =
+ xcb_xkb_get_names_value_list_key_names_iterator(reply, list);
+
+ FAIL_UNLESS(reply->minKeyCode == keymap->min_key_code);
+ FAIL_UNLESS(reply->maxKeyCode == keymap->max_key_code);
+ FAIL_UNLESS(reply->firstKey == keymap->min_key_code);
+ FAIL_UNLESS(reply->firstKey + reply->nKeys - 1 == keymap->max_key_code);
+
+ for (int i = 0; i < length; i++) {
+ xcb_xkb_key_name_t *wire = iter.data;
+ xkb_atom_t *key_name = &keymap->keys[reply->firstKey + i].name;
+
+ if (wire->name[0] == '\0') {
+ *key_name = XKB_ATOM_NONE;
+ }
+ else {
+ *key_name = xkb_atom_intern(keymap->ctx, wire->name,
+ strnlen(wire->name,
+ XCB_XKB_CONST_KEY_NAME_LENGTH));
+ if (!*key_name)
+ return false;
+ }
+
+ xcb_xkb_key_name_next(&iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_aliases(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ xcb_xkb_get_names_reply_t *reply,
+ xcb_xkb_get_names_value_list_t *list)
+{
+ int length = xcb_xkb_get_names_value_list_key_aliases_length(reply, list);
+ xcb_xkb_key_alias_iterator_t iter =
+ xcb_xkb_get_names_value_list_key_aliases_iterator(reply, list);
+
+ keymap->num_key_aliases = reply->nKeyAliases;
+ ALLOC_OR_FAIL(keymap->key_aliases, keymap->num_key_aliases);
+
+ for (int i = 0; i < length; i++) {
+ xcb_xkb_key_alias_t *wire = iter.data;
+ struct xkb_key_alias *alias = &keymap->key_aliases[i];
+
+ alias->real =
+ xkb_atom_intern(keymap->ctx, wire->real,
+ strnlen(wire->real, XCB_XKB_CONST_KEY_NAME_LENGTH));
+ alias->alias =
+ xkb_atom_intern(keymap->ctx, wire->alias,
+ strnlen(wire->alias, XCB_XKB_CONST_KEY_NAME_LENGTH));
+ if (!alias->real || !alias->alias)
+ goto fail;
+
+ xcb_xkb_key_alias_next(&iter);
+ }
+
+ return true;
+
+fail:
+ return false;
+}
+
+static bool
+get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ uint16_t device_id)
+{
+ static const xcb_xkb_name_detail_t required_names =
+ (XCB_XKB_NAME_DETAIL_KEYCODES |
+ XCB_XKB_NAME_DETAIL_SYMBOLS |
+ XCB_XKB_NAME_DETAIL_TYPES |
+ XCB_XKB_NAME_DETAIL_COMPAT |
+ XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
+ XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
+ XCB_XKB_NAME_DETAIL_INDICATOR_NAMES |
+ XCB_XKB_NAME_DETAIL_KEY_NAMES |
+ XCB_XKB_NAME_DETAIL_KEY_ALIASES |
+ XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES |
+ XCB_XKB_NAME_DETAIL_GROUP_NAMES);
+
+ xcb_xkb_get_names_cookie_t cookie =
+ xcb_xkb_get_names(conn, device_id, required_names);
+ xcb_xkb_get_names_reply_t *reply =
+ xcb_xkb_get_names_reply(conn, cookie, NULL);
+ xcb_xkb_get_names_value_list_t list;
+
+ FAIL_IF_BAD_REPLY(reply, "XkbGetNames");
+
+ if ((reply->which & required_names) != required_names)
+ goto fail;
+
+ xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply),
+ reply->nTypes,
+ reply->indicators,
+ reply->virtualMods,
+ reply->groupNames,
+ reply->nKeys,
+ reply->nKeyAliases,
+ reply->nRadioGroups,
+ reply->which,
+ &list);
+
+ if (!get_atom_name(conn, list.keycodesName, &keymap->keycodes_section_name) ||
+ !get_atom_name(conn, list.symbolsName, &keymap->symbols_section_name) ||
+ !get_atom_name(conn, list.typesName, &keymap->types_section_name) ||
+ !get_atom_name(conn, list.compatName, &keymap->compat_section_name) ||
+ !get_type_names(keymap, conn, reply, &list) ||
+ !get_indicator_names(keymap, conn, reply, &list) ||
+ !get_vmod_names(keymap, conn, reply, &list) ||
+ !get_group_names(keymap, conn, reply, &list) ||
+ !get_key_names(keymap, conn, reply, &list) ||
+ !get_aliases(keymap, conn, reply, &list))
+ goto fail;
+
+ XkbEscapeMapName(keymap->keycodes_section_name);
+ XkbEscapeMapName(keymap->symbols_section_name);
+ XkbEscapeMapName(keymap->types_section_name);
+ XkbEscapeMapName(keymap->compat_section_name);
+
+ free(reply);
+ return true;
+
+fail:
+ free(reply);
+ return false;
+}
+
+static bool
+get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn,
+ uint16_t device_id)
+{
+ xcb_xkb_get_controls_cookie_t cookie =
+ xcb_xkb_get_controls(conn, device_id);
+ xcb_xkb_get_controls_reply_t *reply =
+ xcb_xkb_get_controls_reply(conn, cookie, NULL);
+
+ FAIL_IF_BAD_REPLY(reply, "XkbGetControls");
+
+ keymap->enabled_ctrls = translate_controls_mask(reply->enabledControls);
+ keymap->num_groups = reply->numGroups;
+
+ FAIL_UNLESS(keymap->max_key_code < XCB_XKB_CONST_PER_KEY_BIT_ARRAY_SIZE * 8);
+
+ for (int i = keymap->min_key_code; i <= keymap->max_key_code; i++)
+ keymap->keys[i].repeats = !!(reply->perKeyRepeat[i / 8] & (1 << (i % 8)));
+
+ free(reply);
+ return true;
+
+fail:
+ free(reply);
+ return false;
+}
+
+XKB_EXPORT struct xkb_keymap *
+xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
+ xcb_connection_t *conn,
+ int32_t device_id,
+ enum xkb_keymap_compile_flags flags)
+{
+ struct xkb_keymap *keymap;
+ const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
+
+ if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ log_err_func(ctx, "unrecognized flags: %#x\n", flags);
+ return NULL;
+ }
+
+ if (device_id < 0 || device_id > 255) {
+ log_err_func(ctx, "illegal device ID: %d\n", device_id);
+ return NULL;
+ }
+
+ keymap = xkb_keymap_new(ctx, format, flags);
+ if (!keymap)
+ return NULL;
+
+ if (!get_map(keymap, conn, device_id) ||
+ !get_indicator_map(keymap, conn, device_id) ||
+ !get_compat_map(keymap, conn, device_id) ||
+ !get_names(keymap, conn, device_id) ||
+ !get_controls(keymap, conn, device_id)) {
+ xkb_keymap_unref(keymap);
+ return NULL;
+ }
+
+ return keymap;
+}
diff --git a/src/3rdparty/xkbcommon/src/x11/x11-priv.h b/src/3rdparty/xkbcommon/src/x11/x11-priv.h
new file mode 100644
index 0000000000..03f9ee6710
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/x11/x11-priv.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright © 2013 Ran Benita
+ *
+ * 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 (including the next
+ * paragraph) 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 _XKBCOMMON_X11_PRIV_H
+#define _XKBCOMMON_X11_PRIV_H
+
+#include <xcb/xkb.h>
+
+#include "xkbcommon/xkbcommon-x11.h"
+#include "keymap.h"
+
+/* Get a strdup'd name of an X atom. */
+bool
+get_atom_name(xcb_connection_t *conn, xcb_atom_t atom, char **out);
+
+/*
+ * Make a xkb_atom_t's from X atoms (prefer to send as many as possible
+ * at once, to avoid many roundtrips).
+ *
+ * TODO: We can make this more flexible, such that @to doesn't have to
+ * be sequential. Then we can convert most adopt_atom() calls to
+ * adopt_atoms().
+ * Atom caching would also likely be useful for avoiding quite a
+ * few requests.
+ */
+bool
+adopt_atoms(struct xkb_context *ctx, xcb_connection_t *conn,
+ const xcb_atom_t *from, xkb_atom_t *to, size_t count);
+
+bool
+adopt_atom(struct xkb_context *ctx, xcb_connection_t *conn, xcb_atom_t atom,
+ xkb_atom_t *out);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/x11/x11-state.c b/src/3rdparty/xkbcommon/src/x11/x11-state.c
new file mode 100644
index 0000000000..da7dcc23c2
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/x11/x11-state.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2013 Ran Benita
+ *
+ * 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 (including the next
+ * paragraph) 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 "x11-priv.h"
+
+static bool
+update_initial_state(struct xkb_state *state, xcb_connection_t *conn,
+ uint16_t device_id)
+{
+ xcb_xkb_get_state_cookie_t cookie =
+ xcb_xkb_get_state(conn, device_id);
+ xcb_xkb_get_state_reply_t *reply =
+ xcb_xkb_get_state_reply(conn, cookie, NULL);
+
+ if (!reply)
+ return false;
+
+ xkb_state_update_mask(state,
+ reply->baseMods,
+ reply->latchedMods,
+ reply->lockedMods,
+ reply->baseGroup,
+ reply->latchedGroup,
+ reply->lockedGroup);
+
+ free(reply);
+ return true;
+}
+
+XKB_EXPORT struct xkb_state *
+xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
+ xcb_connection_t *conn, int32_t device_id)
+{
+ struct xkb_state *state;
+
+ if (device_id < 0 || device_id > 255) {
+ log_err_func(keymap->ctx, "illegal device ID: %d", device_id);
+ return NULL;
+ }
+
+ state = xkb_state_new(keymap);
+ if (!state)
+ return NULL;
+
+ if (!update_initial_state(state, conn, device_id)) {
+ xkb_state_unref(state);
+ return NULL;
+ }
+
+ return state;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkb-keymap.c b/src/3rdparty/xkbcommon/src/xkb-keymap.c
index 3df183a64f..7d991d535d 100644
--- a/src/3rdparty/xkbcommon/src/xkb-keymap.c
+++ b/src/3rdparty/xkbcommon/src/xkb-keymap.c
@@ -53,26 +53,6 @@
#include "keymap.h"
#include "text.h"
-static struct xkb_keymap *
-xkb_keymap_new(struct xkb_context *ctx,
- enum xkb_keymap_format format,
- enum xkb_keymap_compile_flags flags)
-{
- struct xkb_keymap *keymap;
-
- keymap = calloc(1, sizeof(*keymap));
- if (!keymap)
- return NULL;
-
- keymap->refcnt = 1;
- keymap->ctx = xkb_context_ref(ctx);
-
- keymap->format = format;
- keymap->flags = flags;
-
- return keymap;
-}
-
XKB_EXPORT struct xkb_keymap *
xkb_keymap_ref(struct xkb_keymap *keymap)
{
@@ -83,30 +63,34 @@ xkb_keymap_ref(struct xkb_keymap *keymap)
XKB_EXPORT void
xkb_keymap_unref(struct xkb_keymap *keymap)
{
- unsigned int i, j;
- struct xkb_key *key;
-
if (!keymap || --keymap->refcnt > 0)
return;
if (keymap->keys) {
+ struct xkb_key *key;
xkb_foreach_key(key, keymap) {
- for (i = 0; i < key->num_groups; i++) {
- for (j = 0; j < XkbKeyGroupWidth(key, i); j++)
- if (key->groups[i].levels[j].num_syms > 1)
- free(key->groups[i].levels[j].u.syms);
- free(key->groups[i].levels);
+ if (key->groups) {
+ for (unsigned i = 0; i < key->num_groups; i++) {
+ if (key->groups[i].levels) {
+ for (unsigned j = 0; j < XkbKeyGroupWidth(key, i); j++)
+ if (key->groups[i].levels[j].num_syms > 1)
+ free(key->groups[i].levels[j].u.syms);
+ free(key->groups[i].levels);
+ }
+ }
+ free(key->groups);
}
- free(key->groups);
}
free(keymap->keys);
}
- for (i = 0; i < keymap->num_types; i++) {
- free(keymap->types[i].entries);
- free(keymap->types[i].level_names);
+ if (keymap->types) {
+ for (unsigned i = 0; i < keymap->num_types; i++) {
+ free(keymap->types[i].entries);
+ free(keymap->types[i].level_names);
+ }
+ free(keymap->types);
}
- free(keymap->types);
- darray_free(keymap->sym_interprets);
+ free(keymap->sym_interprets);
free(keymap->key_aliases);
free(keymap->group_names);
darray_free(keymap->mods);
@@ -190,35 +174,8 @@ xkb_keymap_new_from_string(struct xkb_context *ctx,
enum xkb_keymap_format format,
enum xkb_keymap_compile_flags flags)
{
- struct xkb_keymap *keymap;
- const struct xkb_keymap_format_ops *ops;
-
- ops = get_keymap_format_ops(format);
- if (!ops || !ops->keymap_new_from_string) {
- log_err_func(ctx, "unsupported keymap format: %d\n", format);
- return NULL;
- }
-
- if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
- log_err_func(ctx, "unrecognized flags: %#x\n", flags);
- return NULL;
- }
-
- if (!string) {
- log_err_func1(ctx, "no string specified\n");
- return NULL;
- }
-
- keymap = xkb_keymap_new(ctx, format, flags);
- if (!keymap)
- return NULL;
-
- if (!ops->keymap_new_from_string(keymap, string)) {
- xkb_keymap_unref(keymap);
- return NULL;
- }
-
- return keymap;
+ return xkb_keymap_new_from_buffer(ctx, string, strlen(string),
+ format, flags);
}
XKB_EXPORT struct xkb_keymap *
@@ -250,7 +207,7 @@ xkb_keymap_new_from_buffer(struct xkb_context *ctx,
if (!keymap)
return NULL;
- if (!ops->keymap_new_from_buffer(keymap, buffer, length)) {
+ if (!ops->keymap_new_from_string(keymap, buffer, length)) {
xkb_keymap_unref(keymap);
return NULL;
}
@@ -512,44 +469,38 @@ err:
return 0;
}
-/**
- * Simple boolean specifying whether or not the key should repeat.
- */
-XKB_EXPORT int
-xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
+XKB_EXPORT xkb_keycode_t
+xkb_keymap_min_keycode(struct xkb_keymap *keymap)
{
- const struct xkb_key *key = XkbKey(keymap, kc);
-
- if (!key)
- return 0;
+ return keymap->min_key_code;
+}
- return key->repeats;
+XKB_EXPORT xkb_keycode_t
+xkb_keymap_max_keycode(struct xkb_keymap *keymap)
+{
+ return keymap->max_key_code;
}
-struct xkb_key *
-XkbKeyByName(struct xkb_keymap *keymap, xkb_atom_t name, bool use_aliases)
+XKB_EXPORT void
+xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
+ void *data)
{
struct xkb_key *key;
xkb_foreach_key(key, keymap)
- if (key->name == name)
- return key;
-
- if (use_aliases) {
- xkb_atom_t new_name = XkbResolveKeyAlias(keymap, name);
- if (new_name != XKB_ATOM_NONE)
- return XkbKeyByName(keymap, new_name, false);
- }
-
- return NULL;
+ iter(keymap, key->keycode, data);
}
-xkb_atom_t
-XkbResolveKeyAlias(struct xkb_keymap *keymap, xkb_atom_t name)
+/**
+ * Simple boolean specifying whether or not the key should repeat.
+ */
+XKB_EXPORT int
+xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t kc)
{
- for (unsigned i = 0; i < keymap->num_key_aliases; i++)
- if (keymap->key_aliases[i].alias == name)
- return keymap->key_aliases[i].real;
+ const struct xkb_key *key = XkbKey(keymap, kc);
- return XKB_ATOM_NONE;
+ if (!key)
+ return 0;
+
+ return key->repeats;
}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.c b/src/3rdparty/xkbcommon/src/xkbcomp/action.c
index 88323f9952..2bd0bd1589 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/action.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/action.c
@@ -56,18 +56,22 @@
#include "expr.h"
#include "action.h"
-static const ExprDef constTrue = {
- .common = { .type = STMT_EXPR, .next = NULL },
- .op = EXPR_VALUE,
- .value_type = EXPR_TYPE_BOOLEAN,
- .value = { .ival = 1 },
+static const ExprBoolean constTrue = {
+ .expr = {
+ .common = { .type = STMT_EXPR, .next = NULL },
+ .op = EXPR_VALUE,
+ .value_type = EXPR_TYPE_BOOLEAN,
+ },
+ .set = true,
};
-static const ExprDef constFalse = {
- .common = { .type = STMT_EXPR, .next = NULL },
- .op = EXPR_VALUE,
- .value_type = EXPR_TYPE_BOOLEAN,
- .value = { .ival = 0 },
+static const ExprBoolean constFalse = {
+ .expr = {
+ .common = { .type = STMT_EXPR, .next = NULL },
+ .op = EXPR_VALUE,
+ .value_type = EXPR_TYPE_BOOLEAN,
+ },
+ .set = false,
};
enum action_field {
@@ -214,17 +218,6 @@ ReportActionNotArray(struct xkb_keymap *keymap, enum xkb_action_type action,
return false;
}
-static inline bool
-ReportNotFound(struct xkb_keymap *keymap, enum xkb_action_type action,
- enum action_field field, const char *what, const char *bad)
-{
- log_err(keymap->ctx,
- "%s named %s not found; "
- "Ignoring the %s field of an %s action\n",
- what, bad, fieldText(field), ActionTypeText(action));
- return false;
-}
-
static bool
HandleNoAction(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx,
@@ -265,9 +258,9 @@ CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action,
const ExprDef *value, enum xkb_action_flags *flags_inout,
xkb_mod_mask_t *mods_rtrn)
{
- if (value->op == EXPR_IDENT) {
+ if (value->expr.op == EXPR_IDENT) {
const char *valStr;
- valStr = xkb_atom_text(keymap->ctx, value->value.str);
+ valStr = xkb_atom_text(keymap->ctx, value->ident.ident);
if (valStr && (istreq(valStr, "usemodmapmods") ||
istreq(valStr, "modmapmods"))) {
@@ -367,9 +360,9 @@ CheckGroupField(struct xkb_keymap *keymap, unsigned action,
{
const ExprDef *spec;
- if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
+ if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) {
*flags_inout &= ~ACTION_ABSOLUTE_SWITCH;
- spec = value->value.child;
+ spec = value->unary.child;
}
else {
*flags_inout |= ACTION_ABSOLUTE_SWITCH;
@@ -380,9 +373,9 @@ CheckGroupField(struct xkb_keymap *keymap, unsigned action,
return ReportMismatch(keymap, action, ACTION_FIELD_GROUP,
"integer (range 1..8)");
- if (value->op == EXPR_NEGATE)
+ if (value->expr.op == EXPR_NEGATE)
*grp_rtrn = -*grp_rtrn;
- else if (value->op != EXPR_UNARY_PLUS)
+ else if (value->expr.op != EXPR_UNARY_PLUS)
(*grp_rtrn)--;
return true;
@@ -464,18 +457,14 @@ HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action,
const ExprDef *value)
{
struct xkb_pointer_action *act = &action->ptr;
- bool absolute;
if (array_ndx && (field == ACTION_FIELD_X || field == ACTION_FIELD_Y))
return ReportActionNotArray(keymap, action->type, field);
if (field == ACTION_FIELD_X || field == ACTION_FIELD_Y) {
int val;
-
- if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS)
- absolute = false;
- else
- absolute = true;
+ const bool absolute = (value->expr.op != EXPR_NEGATE &&
+ value->expr.op != EXPR_UNARY_PLUS);
if (!ExprResolveInteger(keymap->ctx, value, &val))
return ReportMismatch(keymap, action->type, field, "integer");
@@ -613,9 +602,10 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
if (array_ndx)
return ReportActionNotArray(keymap, action->type, field);
- if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
+ if (value->expr.op == EXPR_NEGATE ||
+ value->expr.op == EXPR_UNARY_PLUS) {
act->flags &= ~ACTION_ABSOLUTE_SWITCH;
- button = value->value.child;
+ button = value->unary.child;
}
else {
act->flags |= ACTION_ABSOLUTE_SWITCH;
@@ -639,7 +629,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
return false;
}
- act->value = (value->op == EXPR_NEGATE ? -btn: btn);
+ act->value = (value->expr.op == EXPR_NEGATE ? -btn: btn);
return true;
}
@@ -660,9 +650,10 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
if (array_ndx)
return ReportActionNotArray(keymap, action->type, field);
- if (value->op == EXPR_NEGATE || value->op == EXPR_UNARY_PLUS) {
+ if (value->expr.op == EXPR_NEGATE ||
+ value->expr.op == EXPR_UNARY_PLUS) {
act->flags &= ~ACTION_ABSOLUTE_SWITCH;
- scrn = value->value.child;
+ scrn = value->unary.child;
}
else {
act->flags |= ACTION_ABSOLUTE_SWITCH;
@@ -680,7 +671,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
return false;
}
- act->screen = (value->op == EXPR_NEGATE ? -val : val);
+ act->screen = (value->expr.op == EXPR_NEGATE ? -val : val);
return true;
}
else if (field == ACTION_FIELD_SAME) {
@@ -861,13 +852,13 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
const char *str;
unsigned handler_type;
- if (def->op != EXPR_ACTION_DECL) {
+ if (def->expr.op != EXPR_ACTION_DECL) {
log_err(keymap->ctx, "Expected an action definition, found %s\n",
- expr_op_type_to_string(def->op));
+ expr_op_type_to_string(def->expr.op));
return false;
}
- str = xkb_atom_text(keymap->ctx, def->value.action.name);
+ str = xkb_atom_text(keymap->ctx, def->action.name);
if (!stringToAction(str, &handler_type)) {
log_err(keymap->ctx, "Unknown action %s\n", str);
return false;
@@ -885,24 +876,24 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
* particular instance, e.g. "modifiers" and "clearLocks" in:
* SetMods(modifiers=Alt,clearLocks);
*/
- for (arg = def->value.action.args; arg != NULL;
+ for (arg = def->action.args; arg != NULL;
arg = (ExprDef *) arg->common.next) {
const ExprDef *value;
ExprDef *field, *arrayRtrn;
const char *elemRtrn, *fieldRtrn;
enum action_field fieldNdx;
- if (arg->op == EXPR_ASSIGN) {
- field = arg->value.binary.left;
- value = arg->value.binary.right;
+ if (arg->expr.op == EXPR_ASSIGN) {
+ field = arg->binary.left;
+ value = arg->binary.right;
}
- else if (arg->op == EXPR_NOT || arg->op == EXPR_INVERT) {
- field = arg->value.child;
- value = &constFalse;
+ else if (arg->expr.op == EXPR_NOT || arg->expr.op == EXPR_INVERT) {
+ field = arg->unary.child;
+ value = (const ExprDef *) &constFalse;
}
else {
field = arg;
- value = &constTrue;
+ value = (const ExprDef *) &constTrue;
}
if (!ExprResolveLhs(keymap->ctx, field, &elemRtrn, &fieldRtrn,
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
index c9b7cb0a3e..d470884e78 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
@@ -70,57 +70,173 @@ AppendStmt(ParseCommon *to, ParseCommon *append)
return to;
}
-ExprDef *
-ExprCreate(enum expr_op_type op, enum expr_value_type type)
+static ExprDef *
+ExprCreate(enum expr_op_type op, enum expr_value_type type, size_t size)
{
- ExprDef *expr = malloc(sizeof(*expr));
+ ExprDef *expr = malloc(size);
if (!expr)
return NULL;
expr->common.type = STMT_EXPR;
expr->common.next = NULL;
- expr->op = op;
- expr->value_type = type;
+ expr->expr.op = op;
+ expr->expr.value_type = type;
return expr;
}
+#define EXPR_CREATE(type_, name_, op_, value_type_) \
+ ExprDef *name_ = ExprCreate(op_, value_type_, sizeof(type_)); \
+ if (!name_) \
+ return NULL;
+
+ExprDef *
+ExprCreateString(xkb_atom_t str)
+{
+ EXPR_CREATE(ExprString, expr, EXPR_VALUE, EXPR_TYPE_STRING);
+ expr->string.str = str;
+ return expr;
+}
+
+ExprDef *
+ExprCreateInteger(int ival)
+{
+ EXPR_CREATE(ExprInteger, expr, EXPR_VALUE, EXPR_TYPE_INT);
+ expr->integer.ival = ival;
+ return expr;
+}
+
+ExprDef *
+ExprCreateBoolean(bool set)
+{
+ EXPR_CREATE(ExprBoolean, expr, EXPR_VALUE, EXPR_TYPE_BOOLEAN);
+ expr->boolean.set = set;
+ return expr;
+}
+
+ExprDef *
+ExprCreateKeyName(xkb_atom_t key_name)
+{
+ EXPR_CREATE(ExprKeyName, expr, EXPR_VALUE, EXPR_TYPE_KEYNAME);
+ expr->key_name.key_name = key_name;
+ return expr;
+}
+
+ExprDef *
+ExprCreateIdent(xkb_atom_t ident)
+{
+ EXPR_CREATE(ExprIdent, expr, EXPR_IDENT, EXPR_TYPE_UNKNOWN);
+ expr->ident.ident = ident;
+ return expr;
+}
+
ExprDef *
ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
ExprDef *child)
{
- ExprDef *expr = malloc(sizeof(*expr));
- if (!expr)
- return NULL;
+ EXPR_CREATE(ExprUnary, expr, op, type);
+ expr->unary.child = child;
+ return expr;
+}
- expr->common.type = STMT_EXPR;
- expr->common.next = NULL;
- expr->op = op;
- expr->value_type = type;
- expr->value.child = child;
+ExprDef *
+ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
+{
+ EXPR_CREATE(ExprBinary, expr, op, EXPR_TYPE_UNKNOWN);
+
+ if (op == EXPR_ASSIGN || left->expr.value_type == EXPR_TYPE_UNKNOWN)
+ expr->expr.value_type = right->expr.value_type;
+ else if (left->expr.value_type == right->expr.value_type ||
+ right->expr.value_type == EXPR_TYPE_UNKNOWN)
+ expr->expr.value_type = left->expr.value_type;
+ expr->binary.left = left;
+ expr->binary.right = right;
return expr;
}
ExprDef *
-ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right)
+ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field)
{
- ExprDef *expr = malloc(sizeof(*expr));
- if (!expr)
- return NULL;
+ EXPR_CREATE(ExprFieldRef, expr, EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
+ expr->field_ref.element = element;
+ expr->field_ref.field = field;
+ return expr;
+}
- expr->common.type = STMT_EXPR;
- expr->common.next = NULL;
- expr->op = op;
- if (op == EXPR_ASSIGN || left->value_type == EXPR_TYPE_UNKNOWN)
- expr->value_type = right->value_type;
- else if (left->value_type == right->value_type ||
- right->value_type == EXPR_TYPE_UNKNOWN)
- expr->value_type = left->value_type;
- else
- expr->value_type = EXPR_TYPE_UNKNOWN;
- expr->value.binary.left = left;
- expr->value.binary.right = right;
+ExprDef *
+ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry)
+{
+ EXPR_CREATE(ExprArrayRef, expr, EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
+ expr->array_ref.element = element;
+ expr->array_ref.field = field;
+ expr->array_ref.entry = entry;
+ return expr;
+}
+
+ExprDef *
+ExprCreateAction(xkb_atom_t name, ExprDef *args)
+{
+ EXPR_CREATE(ExprAction, expr, EXPR_ACTION_DECL, EXPR_TYPE_UNKNOWN);
+ expr->action.name = name;
+ expr->action.args = args;
+ return expr;
+}
+
+ExprDef *
+ExprCreateKeysymList(xkb_keysym_t sym)
+{
+ EXPR_CREATE(ExprKeysymList, expr, EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
+
+ darray_init(expr->keysym_list.syms);
+ darray_init(expr->keysym_list.symsMapIndex);
+ darray_init(expr->keysym_list.symsNumEntries);
+
+ darray_append(expr->keysym_list.syms, sym);
+ darray_append(expr->keysym_list.symsMapIndex, 0);
+ darray_append(expr->keysym_list.symsNumEntries, 1);
+
+ return expr;
+}
+
+ExprDef *
+ExprCreateMultiKeysymList(ExprDef *expr)
+{
+ size_t nLevels = darray_size(expr->keysym_list.symsMapIndex);
+
+ darray_resize(expr->keysym_list.symsMapIndex, 1);
+ darray_resize(expr->keysym_list.symsNumEntries, 1);
+ darray_item(expr->keysym_list.symsMapIndex, 0) = 0;
+ darray_item(expr->keysym_list.symsNumEntries, 0) = nLevels;
+
+ return expr;
+}
+
+ExprDef *
+ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
+{
+ size_t nSyms = darray_size(expr->keysym_list.syms);
+
+ darray_append(expr->keysym_list.symsMapIndex, nSyms);
+ darray_append(expr->keysym_list.symsNumEntries, 1);
+ darray_append(expr->keysym_list.syms, sym);
+
+ return expr;
+}
+
+ExprDef *
+ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append)
+{
+ size_t nSyms = darray_size(expr->keysym_list.syms);
+ size_t numEntries = darray_size(append->keysym_list.syms);
+
+ darray_append(expr->keysym_list.symsMapIndex, nSyms);
+ darray_append(expr->keysym_list.symsNumEntries, numEntries);
+ darray_append_items(expr->keysym_list.syms,
+ darray_mem(append->keysym_list.syms, 0), numEntries);
+
+ darray_resize(append->keysym_list.syms, 0);
+ FreeStmt(&append->common);
return expr;
}
@@ -186,22 +302,14 @@ VarCreate(ExprDef *name, ExprDef *value)
}
VarDef *
-BoolVarCreate(xkb_atom_t nameToken, unsigned set)
+BoolVarCreate(xkb_atom_t ident, bool set)
{
- ExprDef *name, *value;
- VarDef *def;
-
- name = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
- name->value.str = nameToken;
- value = ExprCreate(EXPR_VALUE, EXPR_TYPE_BOOLEAN);
- value->value.uval = set;
- def = VarCreate(name, value);
-
- return def;
+ return VarCreate((ExprDef *) ExprCreateIdent(ident),
+ (ExprDef *) ExprCreateBoolean(set));
}
InterpDef *
-InterpCreate(char *sym, ExprDef *match)
+InterpCreate(xkb_keysym_t sym, ExprDef *match)
{
InterpDef *def = malloc(sizeof(*def));
if (!def)
@@ -232,7 +340,7 @@ KeyTypeCreate(xkb_atom_t name, VarDef *body)
}
SymbolsDef *
-SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols)
+SymbolsCreate(xkb_atom_t keyName, VarDef *symbols)
{
SymbolsDef *def = malloc(sizeof(*def));
if (!def)
@@ -312,83 +420,6 @@ LedNameCreate(int ndx, ExprDef *name, bool virtual)
return def;
}
-ExprDef *
-ActionCreate(xkb_atom_t name, ExprDef *args)
-{
- ExprDef *act = malloc(sizeof(*act));
- if (!act)
- return NULL;
-
- act->common.type = STMT_EXPR;
- act->common.next = NULL;
- act->op = EXPR_ACTION_DECL;
- act->value.action.name = name;
- act->value.action.args = args;
-
- return act;
-}
-
-ExprDef *
-CreateKeysymList(char *sym)
-{
- ExprDef *def;
-
- def = ExprCreate(EXPR_KEYSYM_LIST, EXPR_TYPE_SYMBOLS);
-
- darray_init(def->value.list.syms);
- darray_init(def->value.list.symsMapIndex);
- darray_init(def->value.list.symsNumEntries);
-
- darray_append(def->value.list.syms, sym);
- darray_append(def->value.list.symsMapIndex, 0);
- darray_append(def->value.list.symsNumEntries, 1);
-
- return def;
-}
-
-ExprDef *
-CreateMultiKeysymList(ExprDef *list)
-{
- size_t nLevels = darray_size(list->value.list.symsMapIndex);
-
- darray_resize(list->value.list.symsMapIndex, 1);
- darray_resize(list->value.list.symsNumEntries, 1);
- darray_item(list->value.list.symsMapIndex, 0) = 0;
- darray_item(list->value.list.symsNumEntries, 0) = nLevels;
-
- return list;
-}
-
-ExprDef *
-AppendKeysymList(ExprDef *list, char *sym)
-{
- size_t nSyms = darray_size(list->value.list.syms);
-
- darray_append(list->value.list.symsMapIndex, nSyms);
- darray_append(list->value.list.symsNumEntries, 1);
- darray_append(list->value.list.syms, sym);
-
- return list;
-}
-
-ExprDef *
-AppendMultiKeysymList(ExprDef *list, ExprDef *append)
-{
- size_t nSyms = darray_size(list->value.list.syms);
- size_t numEntries = darray_size(append->value.list.syms);
-
- darray_append(list->value.list.symsMapIndex, nSyms);
- darray_append(list->value.list.symsNumEntries, numEntries);
- darray_append_items(list->value.list.syms,
- darray_mem(append->value.list.syms, 0),
- numEntries);
-
- darray_resize(append->value.list.syms, 0);
- FreeStmt(&append->common);
-
- return list;
-}
-
static void
FreeInclude(IncludeStmt *incl);
@@ -464,30 +495,6 @@ err:
return NULL;
}
-static void
-EscapeMapName(char *name)
-{
- /*
- * All latin-1 alphanumerics, plus parens, slash, minus, underscore and
- * wildcards.
- */
- static const unsigned char legal[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x83,
- 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
- };
-
- if (!name)
- return;
-
- while (*name) {
- if (!(legal[*name / 8] & (1 << (*name % 8))))
- *name = '_';
- name++;
- }
-}
-
XkbFile *
XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
ParseCommon *defs, enum xkb_map_flags flags)
@@ -498,7 +505,7 @@ XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
if (!file)
return NULL;
- EscapeMapName(name);
+ XkbEscapeMapName(name);
file->file_type = type;
file->topName = strdup_safe(name);
file->name = name;
@@ -549,18 +556,16 @@ err:
static void
FreeExpr(ExprDef *expr)
{
- char **sym;
-
if (!expr)
return;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_ACTION_LIST:
case EXPR_NEGATE:
case EXPR_UNARY_PLUS:
case EXPR_NOT:
case EXPR_INVERT:
- FreeStmt(&expr->value.child->common);
+ FreeStmt(&expr->unary.child->common);
break;
case EXPR_DIVIDE:
@@ -568,24 +573,22 @@ FreeExpr(ExprDef *expr)
case EXPR_SUBTRACT:
case EXPR_MULTIPLY:
case EXPR_ASSIGN:
- FreeStmt(&expr->value.binary.left->common);
- FreeStmt(&expr->value.binary.right->common);
+ FreeStmt(&expr->binary.left->common);
+ FreeStmt(&expr->binary.right->common);
break;
case EXPR_ACTION_DECL:
- FreeStmt(&expr->value.action.args->common);
+ FreeStmt(&expr->action.args->common);
break;
case EXPR_ARRAY_REF:
- FreeStmt(&expr->value.array.entry->common);
+ FreeStmt(&expr->array_ref.entry->common);
break;
case EXPR_KEYSYM_LIST:
- darray_foreach(sym, expr->value.list.syms)
- free(*sym);
- darray_free(expr->value.list.syms);
- darray_free(expr->value.list.symsMapIndex);
- darray_free(expr->value.list.symsNumEntries);
+ darray_free(expr->keysym_list.syms);
+ darray_free(expr->keysym_list.symsMapIndex);
+ darray_free(expr->keysym_list.symsNumEntries);
break;
default:
@@ -640,7 +643,6 @@ FreeStmt(ParseCommon *stmt)
FreeStmt(&u.keyType->body->common);
break;
case STMT_INTERP:
- free(u.interp->sym);
FreeStmt(&u.interp->match->common);
FreeStmt(&u.interp->def->common);
break;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
index 0ecd124145..8146b066d1 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
@@ -31,7 +31,19 @@ ParseCommon *
AppendStmt(ParseCommon *to, ParseCommon *append);
ExprDef *
-ExprCreate(enum expr_op_type op, enum expr_value_type type);
+ExprCreateString(xkb_atom_t str);
+
+ExprDef *
+ExprCreateInteger(int ival);
+
+ExprDef *
+ExprCreateBoolean(bool set);
+
+ExprDef *
+ExprCreateKeyName(xkb_atom_t key_name);
+
+ExprDef *
+ExprCreateIdent(xkb_atom_t ident);
ExprDef *
ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
@@ -40,6 +52,27 @@ ExprCreateUnary(enum expr_op_type op, enum expr_value_type type,
ExprDef *
ExprCreateBinary(enum expr_op_type op, ExprDef *left, ExprDef *right);
+ExprDef *
+ExprCreateFieldRef(xkb_atom_t element, xkb_atom_t field);
+
+ExprDef *
+ExprCreateArrayRef(xkb_atom_t element, xkb_atom_t field, ExprDef *entry);
+
+ExprDef *
+ExprCreateAction(xkb_atom_t name, ExprDef *args);
+
+ExprDef *
+ExprCreateMultiKeysymList(ExprDef *list);
+
+ExprDef *
+ExprCreateKeysymList(xkb_keysym_t sym);
+
+ExprDef *
+ExprAppendMultiKeysymList(ExprDef *list, ExprDef *append);
+
+ExprDef *
+ExprAppendKeysymList(ExprDef *list, xkb_keysym_t sym);
+
KeycodeDef *
KeycodeCreate(xkb_atom_t name, int64_t value);
@@ -53,16 +86,16 @@ VarDef *
VarCreate(ExprDef *name, ExprDef *value);
VarDef *
-BoolVarCreate(xkb_atom_t nameToken, unsigned set);
+BoolVarCreate(xkb_atom_t ident, bool set);
InterpDef *
-InterpCreate(char *sym, ExprDef *match);
+InterpCreate(xkb_keysym_t sym, ExprDef *match);
KeyTypeDef *
KeyTypeCreate(xkb_atom_t name, VarDef *body);
SymbolsDef *
-SymbolsCreate(xkb_atom_t keyName, ExprDef *symbols);
+SymbolsCreate(xkb_atom_t keyName, VarDef *symbols);
GroupCompatDef *
GroupCompatCreate(int group, ExprDef *def);
@@ -76,27 +109,12 @@ LedMapCreate(xkb_atom_t name, VarDef *body);
LedNameDef *
LedNameCreate(int ndx, ExprDef *name, bool virtual);
-ExprDef *
-ActionCreate(xkb_atom_t name, ExprDef *args);
-
-ExprDef *
-CreateMultiKeysymList(ExprDef *list);
-
-ExprDef *
-CreateKeysymList(char *sym);
-
-ExprDef *
-AppendMultiKeysymList(ExprDef *list, ExprDef *append);
-
-ExprDef *
-AppendKeysymList(ExprDef *list, char *sym);
-
IncludeStmt *
IncludeCreate(struct xkb_context *ctx, char *str, enum merge_mode merge);
XkbFile *
XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
- ParseCommon *defs, unsigned flags);
+ ParseCommon *defs, enum xkb_map_flags flags);
void
FreeStmt(ParseCommon *stmt);
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h
index c430a772ae..489b33193c 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h
@@ -143,9 +143,11 @@ expr_op_type_to_string(enum expr_op_type type);
const char *
expr_value_type_to_string(enum expr_value_type type);
-typedef struct _ParseCommon {
- enum stmt_type type;
+/* This struct contains fields common to all other AST nodes. It is only
+ * ever embedded in other structs, so save some memory by packing it. */
+typedef struct ATTR_PACKED _ParseCommon {
struct _ParseCommon *next;
+ enum stmt_type type;
} ParseCommon;
typedef struct _IncludeStmt {
@@ -158,40 +160,92 @@ typedef struct _IncludeStmt {
struct _IncludeStmt *next_incl;
} IncludeStmt;
-typedef struct _Expr {
+typedef struct {
ParseCommon common;
enum expr_op_type op;
enum expr_value_type value_type;
- union {
- struct {
- struct _Expr *left;
- struct _Expr *right;
- } binary;
- struct {
- xkb_atom_t element;
- xkb_atom_t field;
- } field;
- struct {
- xkb_atom_t element;
- xkb_atom_t field;
- struct _Expr *entry;
- } array;
- struct {
- xkb_atom_t name;
- struct _Expr *args;
- } action;
- struct {
- darray(char *) syms;
- darray(int) symsMapIndex;
- darray(unsigned int) symsNumEntries;
- } list;
- struct _Expr *child;
- xkb_atom_t str;
- unsigned uval;
- int ival;
- xkb_atom_t keyName;
- } value;
-} ExprDef;
+} ExprCommon;
+
+typedef union ExprDef ExprDef;
+
+typedef struct {
+ ExprCommon expr;
+ xkb_atom_t ident;
+} ExprIdent;
+
+typedef struct {
+ ExprCommon expr;
+ xkb_atom_t str;
+} ExprString;
+
+typedef struct {
+ ExprCommon expr;
+ bool set;
+} ExprBoolean;
+
+typedef struct {
+ ExprCommon expr;
+ int ival;
+} ExprInteger;
+
+typedef struct {
+ ExprCommon expr;
+ xkb_atom_t key_name;
+} ExprKeyName;
+
+typedef struct {
+ ExprCommon expr;
+ ExprDef *left;
+ ExprDef *right;
+} ExprBinary;
+
+typedef struct {
+ ExprCommon expr;
+ ExprDef *child;
+} ExprUnary;
+
+typedef struct {
+ ExprCommon expr;
+ xkb_atom_t element;
+ xkb_atom_t field;
+} ExprFieldRef;
+
+typedef struct {
+ ExprCommon expr;
+ xkb_atom_t element;
+ xkb_atom_t field;
+ ExprDef *entry;
+} ExprArrayRef;
+
+typedef struct {
+ ExprCommon expr;
+ xkb_atom_t name;
+ ExprDef *args;
+} ExprAction;
+
+typedef struct {
+ ExprCommon expr;
+ darray(xkb_keysym_t) syms;
+ darray(int) symsMapIndex;
+ darray(unsigned int) symsNumEntries;
+} ExprKeysymList;
+
+union ExprDef {
+ ParseCommon common;
+ /* Maybe someday we can use C11 anonymous struct for ExprCommon here. */
+ ExprCommon expr;
+ ExprIdent ident;
+ ExprString string;
+ ExprBoolean boolean;
+ ExprInteger integer;
+ ExprKeyName key_name;
+ ExprBinary binary;
+ ExprUnary unary;
+ ExprFieldRef field_ref;
+ ExprArrayRef array_ref;
+ ExprAction action;
+ ExprKeysymList keysym_list;
+};
typedef struct {
ParseCommon common;
@@ -232,7 +286,7 @@ typedef struct {
ParseCommon common;
enum merge_mode merge;
xkb_atom_t keyName;
- ExprDef *symbols;
+ VarDef *symbols;
} SymbolsDef;
typedef struct {
@@ -252,7 +306,7 @@ typedef struct {
typedef struct {
ParseCommon common;
enum merge_mode merge;
- char *sym;
+ xkb_keysym_t sym;
ExprDef *match;
VarDef *def;
} InterpDef;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
index 5682895430..fffb2d34b2 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
@@ -432,19 +432,19 @@ ResolveStateAndPredicate(ExprDef *expr, enum xkb_match_operation *pred_rtrn,
}
*pred_rtrn = MATCH_EXACTLY;
- if (expr->op == EXPR_ACTION_DECL) {
+ if (expr->expr.op == EXPR_ACTION_DECL) {
const char *pred_txt = xkb_atom_text(info->keymap->ctx,
- expr->value.action.name);
+ expr->action.name);
if (!LookupString(symInterpretMatchMaskNames, pred_txt, pred_rtrn)) {
log_err(info->keymap->ctx,
"Illegal modifier predicate \"%s\"; Ignored\n", pred_txt);
return false;
}
- expr = expr->value.action.args;
+ expr = expr->action.args;
}
- else if (expr->op == EXPR_IDENT) {
+ else if (expr->expr.op == EXPR_IDENT) {
const char *pred_txt = xkb_atom_text(info->keymap->ctx,
- expr->value.str);
+ expr->ident.ident);
if (pred_txt && istreq(pred_txt, "any")) {
*pred_rtrn = MATCH_ANY;
*mods_rtrn = MOD_REAL_MASK_ALL;
@@ -805,7 +805,7 @@ HandleInterpBody(CompatInfo *info, VarDef *def, SymInterpInfo *si)
ExprDef *arrayNdx;
for (; def; def = (VarDef *) def->common.next) {
- if (def->name && def->name->op == EXPR_FIELD_REF) {
+ if (def->name && def->name->expr.op == EXPR_FIELD_REF) {
log_err(info->keymap->ctx,
"Cannot set a global default value from within an interpret statement; "
"Move statements to the global file scope\n");
@@ -840,15 +840,7 @@ HandleInterpDef(CompatInfo *info, InterpDef *def, enum merge_mode merge)
si = info->default_interp;
si.merge = merge = (def->merge == MERGE_DEFAULT ? merge : def->merge);
-
- if (!LookupKeysym(def->sym, &si.interp.sym)) {
- log_err(info->keymap->ctx,
- "Could not resolve keysym %s; "
- "Symbol interpretation ignored\n",
- def->sym);
- return false;
- }
-
+ si.interp.sym = def->sym;
si.interp.match = pred;
si.interp.mods = mods;
@@ -941,7 +933,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
break;
default:
log_err(info->keymap->ctx,
- "Interpretation files may not include other types; "
+ "Compat files may not include other types; "
"Ignoring %s\n", stmt_type_to_string(stmt->type));
ok = false;
break;
@@ -958,15 +950,21 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
}
}
+/* Temporary struct for CopyInterps. */
+struct collect {
+ darray(struct xkb_sym_interpret) sym_interprets;
+};
+
static void
-CopyInterps(CompatInfo *info, bool needSymbol, enum xkb_match_operation pred)
+CopyInterps(CompatInfo *info, bool needSymbol, enum xkb_match_operation pred,
+ struct collect *collect)
{
SymInterpInfo *si;
darray_foreach(si, info->interps)
if (si->interp.match == pred &&
(si->interp.sym != XKB_KEY_NoSymbol) == needSymbol)
- darray_append(info->keymap->sym_interprets, si->interp);
+ darray_append(collect->sym_interprets, si->interp);
}
static void
@@ -1025,19 +1023,26 @@ static bool
CopyCompatToKeymap(struct xkb_keymap *keymap, CompatInfo *info)
{
keymap->compat_section_name = strdup_safe(info->name);
+ XkbEscapeMapName(keymap->compat_section_name);
if (!darray_empty(info->interps)) {
+ struct collect collect;
+ darray_init(collect.sym_interprets);
+
/* Most specific to least specific. */
- CopyInterps(info, true, MATCH_EXACTLY);
- CopyInterps(info, true, MATCH_ALL);
- CopyInterps(info, true, MATCH_NONE);
- CopyInterps(info, true, MATCH_ANY);
- CopyInterps(info, true, MATCH_ANY_OR_NONE);
- CopyInterps(info, false, MATCH_EXACTLY);
- CopyInterps(info, false, MATCH_ALL);
- CopyInterps(info, false, MATCH_NONE);
- CopyInterps(info, false, MATCH_ANY);
- CopyInterps(info, false, MATCH_ANY_OR_NONE);
+ CopyInterps(info, true, MATCH_EXACTLY, &collect);
+ CopyInterps(info, true, MATCH_ALL, &collect);
+ CopyInterps(info, true, MATCH_NONE, &collect);
+ CopyInterps(info, true, MATCH_ANY, &collect);
+ CopyInterps(info, true, MATCH_ANY_OR_NONE, &collect);
+ CopyInterps(info, false, MATCH_EXACTLY, &collect);
+ CopyInterps(info, false, MATCH_ALL, &collect);
+ CopyInterps(info, false, MATCH_NONE, &collect);
+ CopyInterps(info, false, MATCH_ANY, &collect);
+ CopyInterps(info, false, MATCH_ANY_OR_NONE, &collect);
+
+ keymap->num_sym_interprets = darray_size(collect.sym_interprets);
+ keymap->sym_interprets = darray_mem(collect.sym_interprets, 0);
}
CopyLedMapDefs(info);
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
index dc64d7891f..ba71208f7e 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
@@ -37,26 +37,26 @@ ExprResolveLhs(struct xkb_context *ctx, const ExprDef *expr,
const char **elem_rtrn, const char **field_rtrn,
ExprDef **index_rtrn)
{
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_IDENT:
*elem_rtrn = NULL;
- *field_rtrn = xkb_atom_text(ctx, expr->value.str);
+ *field_rtrn = xkb_atom_text(ctx, expr->ident.ident);
*index_rtrn = NULL;
return true;
case EXPR_FIELD_REF:
- *elem_rtrn = xkb_atom_text(ctx, expr->value.field.element);
- *field_rtrn = xkb_atom_text(ctx, expr->value.field.field);
+ *elem_rtrn = xkb_atom_text(ctx, expr->field_ref.element);
+ *field_rtrn = xkb_atom_text(ctx, expr->field_ref.field);
*index_rtrn = NULL;
return true;
case EXPR_ARRAY_REF:
- *elem_rtrn = xkb_atom_text(ctx, expr->value.array.element);
- *field_rtrn = xkb_atom_text(ctx, expr->value.array.field);
- *index_rtrn = expr->value.array.entry;
+ *elem_rtrn = xkb_atom_text(ctx, expr->array_ref.element);
+ *field_rtrn = xkb_atom_text(ctx, expr->array_ref.field);
+ *index_rtrn = expr->array_ref.entry;
return true;
default:
break;
}
- log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->op);
+ log_wsgo(ctx, "Unexpected operator %d in ResolveLhs\n", expr->expr.op);
return false;
}
@@ -127,19 +127,19 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
bool ok = false;
const char *ident;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_VALUE:
- if (expr->value_type != EXPR_TYPE_BOOLEAN) {
+ if (expr->expr.value_type != EXPR_TYPE_BOOLEAN) {
log_err(ctx,
"Found constant of type %s where boolean was expected\n",
- expr_value_type_to_string(expr->value_type));
+ expr_value_type_to_string(expr->expr.value_type));
return false;
}
- *set_rtrn = !!expr->value.ival;
+ *set_rtrn = expr->boolean.set;
return true;
case EXPR_IDENT:
- ident = xkb_atom_text(ctx, expr->value.str);
+ ident = xkb_atom_text(ctx, expr->ident.ident);
if (ident) {
if (istreq(ident, "true") ||
istreq(ident, "yes") ||
@@ -154,14 +154,13 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
return true;
}
}
- log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n",
- xkb_atom_text(ctx, expr->value.str));
+ log_err(ctx, "Identifier \"%s\" of type boolean is unknown\n", ident);
return false;
case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type boolean is unknown\n",
- xkb_atom_text(ctx, expr->value.field.element),
- xkb_atom_text(ctx, expr->value.field.field));
+ xkb_atom_text(ctx, expr->field_ref.element),
+ xkb_atom_text(ctx, expr->field_ref.field));
return false;
case EXPR_INVERT:
@@ -178,11 +177,12 @@ ExprResolveBoolean(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_NEGATE:
case EXPR_UNARY_PLUS:
log_err(ctx, "%s of boolean values not permitted\n",
- expr_op_type_to_string(expr->op));
+ expr_op_type_to_string(expr->expr.op));
break;
default:
- log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n", expr->op);
+ log_wsgo(ctx, "Unknown operator %d in ResolveBoolean\n",
+ expr->expr.op);
break;
}
@@ -194,32 +194,28 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
xkb_keycode_t *kc)
{
xkb_keycode_t leftRtrn, rightRtrn;
- ExprDef *left, *right;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_VALUE:
- if (expr->value_type != EXPR_TYPE_INT) {
+ if (expr->expr.value_type != EXPR_TYPE_INT) {
log_err(ctx,
"Found constant of type %s where an int was expected\n",
- expr_value_type_to_string(expr->value_type));
+ expr_value_type_to_string(expr->expr.value_type));
return false;
}
- *kc = expr->value.uval;
+ *kc = (xkb_keycode_t) expr->integer.ival;
return true;
case EXPR_ADD:
case EXPR_SUBTRACT:
case EXPR_MULTIPLY:
case EXPR_DIVIDE:
- left = expr->value.binary.left;
- right = expr->value.binary.right;
-
- if (!ExprResolveKeyCode(ctx, left, &leftRtrn) ||
- !ExprResolveKeyCode(ctx, right, &rightRtrn))
+ if (!ExprResolveKeyCode(ctx, expr->binary.left, &leftRtrn) ||
+ !ExprResolveKeyCode(ctx, expr->binary.right, &rightRtrn))
return false;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_ADD:
*kc = leftRtrn + rightRtrn;
break;
@@ -245,19 +241,18 @@ ExprResolveKeyCode(struct xkb_context *ctx, const ExprDef *expr,
return true;
case EXPR_NEGATE:
- left = expr->value.child;
- if (!ExprResolveKeyCode(ctx, left, &leftRtrn))
+ if (!ExprResolveKeyCode(ctx, expr->unary.child, &leftRtrn))
return false;
*kc = ~leftRtrn;
return true;
case EXPR_UNARY_PLUS:
- left = expr->value.child;
- return ExprResolveKeyCode(ctx, left, kc);
+ return ExprResolveKeyCode(ctx, expr->unary.child, kc);
default:
- log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n", expr->op);
+ log_wsgo(ctx, "Unknown operator %d in ResolveKeyCode\n",
+ expr->expr.op);
break;
}
@@ -284,25 +279,25 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
unsigned u;
ExprDef *left, *right;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_VALUE:
- if (expr->value_type != EXPR_TYPE_INT) {
+ if (expr->expr.value_type != EXPR_TYPE_INT) {
log_err(ctx,
"Found constant of type %s where an int was expected\n",
- expr_value_type_to_string(expr->value_type));
+ expr_value_type_to_string(expr->expr.value_type));
return false;
}
- *val_rtrn = expr->value.ival;
+ *val_rtrn = expr->integer.ival;
return true;
case EXPR_IDENT:
if (lookup)
- ok = lookup(ctx, lookupPriv, expr->value.str, EXPR_TYPE_INT, &u);
+ ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT, &u);
if (!ok)
log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
- xkb_atom_text(ctx, expr->value.str));
+ xkb_atom_text(ctx, expr->ident.ident));
else
*val_rtrn = (int) u;
@@ -310,21 +305,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
- xkb_atom_text(ctx, expr->value.field.element),
- xkb_atom_text(ctx, expr->value.field.field));
+ xkb_atom_text(ctx, expr->field_ref.element),
+ xkb_atom_text(ctx, expr->field_ref.field));
return false;
case EXPR_ADD:
case EXPR_SUBTRACT:
case EXPR_MULTIPLY:
case EXPR_DIVIDE:
- left = expr->value.binary.left;
- right = expr->value.binary.right;
+ left = expr->binary.left;
+ right = expr->binary.right;
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv) ||
!ExprResolveIntegerLookup(ctx, right, &r, lookup, lookupPriv))
return false;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_ADD:
*val_rtrn = l + r;
break;
@@ -357,20 +352,21 @@ ExprResolveIntegerLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_INVERT:
case EXPR_NEGATE:
- left = expr->value.child;
+ left = expr->unary.child;
if (!ExprResolveIntegerLookup(ctx, left, &l, lookup, lookupPriv))
return false;
- *val_rtrn = (expr->op == EXPR_NEGATE ? -l : ~l);
+ *val_rtrn = (expr->expr.op == EXPR_NEGATE ? -l : ~l);
return true;
case EXPR_UNARY_PLUS:
- left = expr->value.child;
+ left = expr->unary.child;
return ExprResolveIntegerLookup(ctx, left, val_rtrn, lookup,
lookupPriv);
default:
- log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n", expr->op);
+ log_wsgo(ctx, "Unknown operator %d in ResolveInteger\n",
+ expr->expr.op);
break;
}
@@ -445,26 +441,26 @@ bool
ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
xkb_atom_t *val_rtrn)
{
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_VALUE:
- if (expr->value_type != EXPR_TYPE_STRING) {
+ if (expr->expr.value_type != EXPR_TYPE_STRING) {
log_err(ctx, "Found constant of type %s, expected a string\n",
- expr_value_type_to_string(expr->value_type));
+ expr_value_type_to_string(expr->expr.value_type));
return false;
}
- *val_rtrn = expr->value.str;
+ *val_rtrn = expr->string.str;
return true;
case EXPR_IDENT:
log_err(ctx, "Identifier \"%s\" of type string not found\n",
- xkb_atom_text(ctx, expr->value.str));
+ xkb_atom_text(ctx, expr->ident.ident));
return false;
case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type string not found\n",
- xkb_atom_text(ctx, expr->value.field.element),
- xkb_atom_text(ctx, expr->value.field.field));
+ xkb_atom_text(ctx, expr->field_ref.element),
+ xkb_atom_text(ctx, expr->field_ref.field));
return false;
case EXPR_ADD:
@@ -477,11 +473,12 @@ ExprResolveString(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_NOT:
case EXPR_UNARY_PLUS:
log_err(ctx, "%s of strings not permitted\n",
- expr_op_type_to_string(expr->op));
+ expr_op_type_to_string(expr->expr.op));
return false;
default:
- log_wsgo(ctx, "Unknown operator %d in ResolveString\n", expr->op);
+ log_wsgo(ctx, "Unknown operator %d in ResolveString\n",
+ expr->expr.op);
break;
}
return false;
@@ -491,16 +488,16 @@ bool
ExprResolveEnum(struct xkb_context *ctx, const ExprDef *expr,
unsigned int *val_rtrn, const LookupEntry *values)
{
- if (expr->op != EXPR_IDENT) {
+ if (expr->expr.op != EXPR_IDENT) {
log_err(ctx, "Found a %s where an enumerated value was expected\n",
- expr_op_type_to_string(expr->op));
+ expr_op_type_to_string(expr->expr.op));
return false;
}
- if (!SimpleLookup(ctx, values, expr->value.str, EXPR_TYPE_INT,
+ if (!SimpleLookup(ctx, values, expr->ident.ident, EXPR_TYPE_INT,
val_rtrn)) {
log_err(ctx, "Illegal identifier %s; expected one of:\n",
- xkb_atom_text(ctx, expr->value.str));
+ xkb_atom_text(ctx, expr->ident.ident));
while (values && values->name)
{
log_err(ctx, "\t%s\n", values->name);
@@ -523,29 +520,29 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
ExprDef *left, *right;
const char *bogus = NULL;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_VALUE:
- if (expr->value_type != EXPR_TYPE_INT) {
+ if (expr->expr.value_type != EXPR_TYPE_INT) {
log_err(ctx,
"Found constant of type %s where a mask was expected\n",
- expr_value_type_to_string(expr->value_type));
+ expr_value_type_to_string(expr->expr.value_type));
return false;
}
- *val_rtrn = (unsigned int) expr->value.ival;
+ *val_rtrn = (unsigned int) expr->integer.ival;
return true;
case EXPR_IDENT:
- ok = lookup(ctx, lookupPriv, expr->value.str, EXPR_TYPE_INT,
+ ok = lookup(ctx, lookupPriv, expr->ident.ident, EXPR_TYPE_INT,
val_rtrn);
if (!ok)
log_err(ctx, "Identifier \"%s\" of type int is unknown\n",
- xkb_atom_text(ctx, expr->value.str));
+ xkb_atom_text(ctx, expr->ident.ident));
return ok;
case EXPR_FIELD_REF:
log_err(ctx, "Default \"%s.%s\" of type int is unknown\n",
- xkb_atom_text(ctx, expr->value.field.element),
- xkb_atom_text(ctx, expr->value.field.field));
+ xkb_atom_text(ctx, expr->field_ref.element),
+ xkb_atom_text(ctx, expr->field_ref.field));
return false;
case EXPR_ARRAY_REF:
@@ -563,13 +560,13 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_SUBTRACT:
case EXPR_MULTIPLY:
case EXPR_DIVIDE:
- left = expr->value.binary.left;
- right = expr->value.binary.right;
+ left = expr->binary.left;
+ right = expr->binary.right;
if (!ExprResolveMaskLookup(ctx, left, &l, lookup, lookupPriv) ||
!ExprResolveMaskLookup(ctx, right, &r, lookup, lookupPriv))
return false;
- switch (expr->op) {
+ switch (expr->expr.op) {
case EXPR_ADD:
*val_rtrn = l | r;
break;
@@ -579,7 +576,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_MULTIPLY:
case EXPR_DIVIDE:
log_err(ctx, "Cannot %s masks; Illegal operation ignored\n",
- (expr->op == EXPR_DIVIDE ? "divide" : "multiply"));
+ (expr->expr.op == EXPR_DIVIDE ? "divide" : "multiply"));
return false;
default:
break;
@@ -592,7 +589,7 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
break;
case EXPR_INVERT:
- left = expr->value.child;
+ left = expr->unary.child;
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
return false;
@@ -602,14 +599,15 @@ ExprResolveMaskLookup(struct xkb_context *ctx, const ExprDef *expr,
case EXPR_UNARY_PLUS:
case EXPR_NEGATE:
case EXPR_NOT:
- left = expr->value.child;
+ left = expr->unary.child;
if (!ExprResolveIntegerLookup(ctx, left, &v, lookup, lookupPriv))
log_err(ctx, "The %s operator cannot be used with a mask\n",
- (expr->op == EXPR_NEGATE ? "-" : "!"));
+ (expr->expr.op == EXPR_NEGATE ? "-" : "!"));
return false;
default:
- log_wsgo(ctx, "Unknown operator %d in ResolveMask\n", expr->op);
+ log_wsgo(ctx, "Unknown operator %d in ResolveMask\n",
+ expr->expr.op);
break;
}
@@ -638,9 +636,8 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
{
int val;
- if (expr->op == EXPR_IDENT) {
- const char *str;
- str = xkb_atom_text(ctx, expr->value.str);
+ if (expr->expr.op == EXPR_IDENT) {
+ const char *str = xkb_atom_text(ctx, expr->ident.ident);
*sym_rtrn = xkb_keysym_from_name(str, 0);
if (*sym_rtrn != XKB_KEY_NoSymbol)
return true;
@@ -652,7 +649,7 @@ ExprResolveKeySym(struct xkb_context *ctx, const ExprDef *expr,
if (val < 0 || val >= 10)
return false;
- *sym_rtrn = ((xkb_keysym_t) val) + '0';
+ *sym_rtrn = XKB_KEY_0 + (xkb_keysym_t) val;
return true;
}
@@ -661,16 +658,17 @@ ExprResolveMod(struct xkb_keymap *keymap, const ExprDef *def,
enum mod_type mod_type, xkb_mod_index_t *ndx_rtrn)
{
xkb_mod_index_t ndx;
- xkb_atom_t name = def->value.str;
+ xkb_atom_t name;
- if (def->op != EXPR_IDENT) {
+ if (def->expr.op != EXPR_IDENT) {
log_err(keymap->ctx,
"Cannot resolve virtual modifier: "
"found %s where a virtual modifier name was expected\n",
- expr_op_type_to_string(def->op));
+ expr_op_type_to_string(def->expr.op));
return false;
}
+ name = def->ident.ident;
ndx = ModNameToIndex(keymap, name, mod_type);
if (ndx == XKB_MOD_INVALID) {
log_err(keymap->ctx,
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/include.c b/src/3rdparty/xkbcommon/src/xkbcomp/include.c
index b4a4014635..dc3f1e49bd 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/include.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/include.c
@@ -199,17 +199,34 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name,
{
unsigned int i;
FILE *file = NULL;
- char buf[PATH_MAX];
+ char *buf = NULL;
const char *typeDir;
+ size_t buf_size = 0, typeDirLen, name_len;
typeDir = DirectoryForInclude(type);
+ typeDirLen = strlen(typeDir);
+ name_len = strlen(name);
for (i = 0; i < xkb_context_num_include_paths(ctx); i++) {
- int ret = snprintf(buf, sizeof(buf), "%s/%s/%s",
- xkb_context_include_path_get(ctx, i),
- typeDir, name);
- if (ret >= (ssize_t) sizeof(buf)) {
- log_err(ctx, "File name (%s/%s/%s) too long\n",
+ size_t new_buf_size = strlen(xkb_context_include_path_get(ctx, i)) +
+ typeDirLen + name_len + 3;
+ int ret;
+ if (new_buf_size > buf_size) {
+ void *buf_new = realloc(buf, new_buf_size);
+ if (buf_new) {
+ buf_size = new_buf_size;
+ buf = buf_new;
+ } else {
+ log_err(ctx, "Cannot realloc for name (%s/%s/%s)\n",
+ xkb_context_include_path_get(ctx, i), typeDir, name);
+ continue;
+ }
+ }
+ ret = snprintf(buf, buf_size, "%s/%s/%s",
+ xkb_context_include_path_get(ctx, i),
+ typeDir, name);
+ if (ret < 0) {
+ log_err(ctx, "snprintf error (%s/%s/%s)\n",
xkb_context_include_path_get(ctx, i), typeDir, name);
continue;
}
@@ -242,11 +259,14 @@ FindFileInXkbPath(struct xkb_context *ctx, const char *name,
xkb_context_failed_include_path_get(ctx, i));
}
+ free(buf);
return NULL;
}
if (pathRtrn)
- *pathRtrn = strdup(buf);
+ *pathRtrn = buf;
+ else
+ free(buf);
return file;
}
@@ -275,7 +295,7 @@ ProcessIncludeFile(struct xkb_context *ctx, IncludeStmt *stmt,
if (xkb_file->file_type != file_type) {
log_err(ctx,
- "Include file wrong type (expected %s, got %s); "
+ "Include file of wrong type (expected %s, got %s); "
"Include file \"%s\" ignored\n",
xkb_file_type_to_string(file_type),
xkb_file_type_to_string(xkb_file->file_type), stmt->file);
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
index edc54c94f3..59916b7266 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
@@ -231,7 +231,10 @@ InitKeyNamesInfo(KeyNamesInfo *info, struct xkb_context *ctx)
{
memset(info, 0, sizeof(*info));
info->ctx = ctx;
- info->min_key_code = XKB_KEYCODE_MAX;
+ info->min_key_code = XKB_KEYCODE_INVALID;
+#if XKB_KEYCODE_INVALID < XKB_KEYCODE_MAX
+#error "Hey, you can't be changing stuff like that."
+#endif
}
static xkb_keycode_t
@@ -604,16 +607,28 @@ CopyKeyNamesToKeymap(struct xkb_keymap *keymap, KeyNamesInfo *info)
unsigned i;
keymap->keycodes_section_name = strdup_safe(info->name);
+ XkbEscapeMapName(keymap->keycodes_section_name);
- keymap->min_key_code = info->min_key_code;
- keymap->max_key_code = info->max_key_code;
+ if (info->min_key_code != XKB_KEYCODE_INVALID) {
+ keymap->min_key_code = info->min_key_code;
+ keymap->max_key_code = info->max_key_code;
+ }
+ else {
+ /*
+ * If the keymap has no keys, let's just use the safest pair
+ * we know.
+ */
+ keymap->min_key_code = 8;
+ keymap->max_key_code = 255;
+ }
- /* Copy key names. */
- keymap->keys = calloc(info->max_key_code + 1, sizeof(*keymap->keys));
- for (kc = info->min_key_code; kc <= info->max_key_code; kc++) {
+ keymap->keys = calloc(keymap->max_key_code + 1, sizeof(*keymap->keys));
+ for (kc = keymap->min_key_code; kc <= keymap->max_key_code; kc++)
keymap->keys[kc].keycode = kc;
+
+ /* Copy key names. */
+ for (kc = info->min_key_code; kc <= info->max_key_code; kc++)
keymap->keys[kc].name = darray_item(info->key_names, kc);
- }
/*
* Do some sanity checking on the aliases. We can't do it before
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
index 034a8c1af3..6b4c266ec0 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
@@ -157,17 +157,24 @@ write_keycodes(struct xkb_keymap *keymap, struct buf *buf)
else
write_buf(buf, "xkb_keycodes {\n");
+ /* xkbcomp and X11 really want to see keymaps with a minimum of 8, and
+ * a maximum of at least 255, else XWayland really starts hating life.
+ * If this is a problem and people really need strictly bounded keymaps,
+ * we should probably control this with a flag. */
+ write_buf(buf, "\tminimum = %u;\n", min(keymap->min_key_code, 8));
+ write_buf(buf, "\tmaximum = %u;\n", max(keymap->max_key_code, 255));
+
xkb_foreach_key(key, keymap) {
if (key->name == XKB_ATOM_NONE)
continue;
- write_buf(buf, "\t%-20s = %d;\n",
+ write_buf(buf, "\t%-20s = %u;\n",
KeyNameText(keymap->ctx, key->name), key->keycode);
}
darray_enumerate(idx, led, keymap->leds)
if (led->name != XKB_ATOM_NONE)
- write_buf(buf, "\tindicator %d = \"%s\";\n",
+ write_buf(buf, "\tindicator %u = \"%s\";\n",
idx + 1, xkb_atom_text(keymap->ctx, led->name));
@@ -212,7 +219,7 @@ write_types(struct xkb_keymap *keymap, struct buf *buf)
continue;
str = ModMaskText(keymap, entry->mods.mods);
- write_buf(buf, "\t\tmap[%s]= Level%d;\n",
+ write_buf(buf, "\t\tmap[%s]= Level%u;\n",
str, entry->level + 1);
if (entry->preserve.mods)
@@ -222,7 +229,7 @@ write_types(struct xkb_keymap *keymap, struct buf *buf)
for (xkb_level_index_t n = 0; n < type->num_levels; n++)
if (type->level_names[n])
- write_buf(buf, "\t\tlevel_name[Level%d]= \"%s\";\n", n + 1,
+ write_buf(buf, "\t\tlevel_name[Level%u]= \"%s\";\n", n + 1,
xkb_atom_text(keymap->ctx, type->level_names[n]));
write_buf(buf, "\t};\n");
@@ -409,7 +416,6 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
static bool
write_compat(struct xkb_keymap *keymap, struct buf *buf)
{
- const struct xkb_sym_interpret *si;
const struct xkb_led *led;
if (keymap->compat_section_name)
@@ -423,7 +429,9 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf)
write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n");
write_buf(buf, "\tinterpret.repeat= False;\n");
- darray_foreach(si, keymap->sym_interprets) {
+ for (int i = 0; i < keymap->num_sym_interprets; i++) {
+ const struct xkb_sym_interpret *si = &keymap->sym_interprets[i];
+
write_buf(buf, "\tinterpret %s+%s(%s) {\n",
si->sym ? KeysymText(keymap->ctx, si->sym) : "Any",
SIMatchText(si->match),
@@ -610,7 +618,7 @@ write_symbols(struct xkb_keymap *keymap, struct buf *buf)
for (group = 0; group < keymap->num_group_names; group++)
if (keymap->group_names[group])
write_buf(buf,
- "\tname[group%d]=\"%s\";\n", group + 1,
+ "\tname[group%u]=\"%s\";\n", group + 1,
xkb_atom_text(keymap->ctx, keymap->group_names[group]));
if (group > 0)
write_buf(buf, "\n");
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
index bed3930be9..549cf05da6 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
@@ -78,7 +78,6 @@ static const struct xkb_sym_interpret *
FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
xkb_layout_index_t group, xkb_level_index_t level)
{
- const struct xkb_sym_interpret *interp;
const xkb_keysym_t *syms;
int num_syms;
@@ -93,7 +92,9 @@ FindInterpForKey(struct xkb_keymap *keymap, const struct xkb_key *key,
* sym_interprets array from the most specific to the least specific,
* such that when we find a match we return immediately.
*/
- darray_foreach(interp, keymap->sym_interprets) {
+ for (int i = 0; i < keymap->num_sym_interprets; i++) {
+ const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i];
+
xkb_mod_mask_t mods;
bool found = false;
@@ -224,28 +225,6 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
return true;
}
-static bool
-UpdateBuiltinKeymapFields(struct xkb_keymap *keymap)
-{
- struct xkb_context *ctx = keymap->ctx;
-
- /*
- * Add predefined (AKA real, core, X11) modifiers.
- * The order is important!
- */
- darray_appends_t(keymap->mods, struct xkb_mod,
- { .name = xkb_atom_intern(ctx, "Shift"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Lock"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Control"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod1"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod2"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod3"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod4"), .type = MOD_REAL },
- { .name = xkb_atom_intern(ctx, "Mod5"), .type = MOD_REAL });
-
- return true;
-}
-
typedef bool (*compile_file_fn)(XkbFile *file,
struct xkb_keymap *keymap,
enum merge_mode merge);
@@ -311,9 +290,6 @@ CompileKeymap(XkbFile *file, struct xkb_keymap *keymap, enum merge_mode merge)
if (!ok)
return false;
- if (!UpdateBuiltinKeymapFields(keymap))
- return false;
-
/* Compile sections. */
for (type = FIRST_KEYMAP_FILE_TYPE;
type <= LAST_KEYMAP_FILE_TYPE;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c
new file mode 100644
index 0000000000..c19d66ffde
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c
@@ -0,0 +1,349 @@
+/* ANSI-C code produced by gperf version 3.0.4 */
+/* Command-line: gperf */
+/* Computed positions: -k'1-2,5' */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#endif
+
+
+#include "xkbcomp-priv.h"
+#include "parser-priv.h"
+
+static unsigned int
+keyword_gperf_hash(const char *str, unsigned int len);
+
+static const struct keyword_tok *
+keyword_gperf_lookup(const char *str, unsigned int len);
+struct keyword_tok { int name; int tok; };
+#include <string.h>
+/* maximum key range = 70, duplicates = 0 */
+
+#ifndef GPERF_DOWNCASE
+#define GPERF_DOWNCASE 1
+static unsigned char gperf_downcase[256] =
+ {
+ 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, 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, 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
+ };
+#endif
+
+#ifndef GPERF_CASE_STRCMP
+#define GPERF_CASE_STRCMP 1
+static int
+gperf_case_strcmp (register const char *s1, register const char *s2)
+{
+ for (;;)
+ {
+ unsigned char c1 = gperf_downcase[(unsigned char)*s1++];
+ unsigned char c2 = gperf_downcase[(unsigned char)*s2++];
+ if (c1 != 0 && c1 == c2)
+ continue;
+ return (int)c1 - (int)c2;
+ }
+}
+#endif
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static unsigned int
+keyword_gperf_hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 0, 73, 5, 36, 0,
+ 10, 1, 15, 15, 73, 0, 10, 20, 35, 20,
+ 50, 73, 10, 10, 5, 0, 15, 73, 0, 15,
+ 73, 73, 73, 73, 73, 73, 73, 0, 73, 5,
+ 36, 0, 10, 1, 15, 15, 73, 0, 10, 20,
+ 35, 20, 50, 73, 10, 10, 5, 0, 15, 73,
+ 0, 15, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73, 73, 73, 73, 73,
+ 73, 73, 73, 73, 73, 73
+ };
+ register int hval = len;
+
+ switch (hval)
+ {
+ default:
+ hval += asso_values[(unsigned char)str[4]];
+ /*FALLTHROUGH*/
+ case 4:
+ case 3:
+ case 2:
+ hval += asso_values[(unsigned char)str[1]];
+ /*FALLTHROUGH*/
+ case 1:
+ hval += asso_values[(unsigned char)str[0]];
+ break;
+ }
+ return hval;
+}
+
+struct stringpool_t
+ {
+ char stringpool_str3[sizeof("key")];
+ char stringpool_str4[sizeof("keys")];
+ char stringpool_str7[sizeof("augment")];
+ char stringpool_str9[sizeof("text")];
+ char stringpool_str10[sizeof("xkb_keymap")];
+ char stringpool_str11[sizeof("keypad_keys")];
+ char stringpool_str12[sizeof("xkb_keycodes")];
+ char stringpool_str13[sizeof("xkb_geometry")];
+ char stringpool_str14[sizeof("xkb_types")];
+ char stringpool_str15[sizeof("xkb_compat")];
+ char stringpool_str17[sizeof("replace")];
+ char stringpool_str19[sizeof("xkb_compat_map")];
+ char stringpool_str20[sizeof("xkb_layout")];
+ char stringpool_str21[sizeof("xkb_symbols")];
+ char stringpool_str22[sizeof("xkb_compatibility")];
+ char stringpool_str23[sizeof("xkb_semantics")];
+ char stringpool_str24[sizeof("type")];
+ char stringpool_str25[sizeof("alias")];
+ char stringpool_str26[sizeof("xkb_compatibility_map")];
+ char stringpool_str27[sizeof("alphanumeric_keys")];
+ char stringpool_str28[sizeof("function_keys")];
+ char stringpool_str29[sizeof("alternate")];
+ char stringpool_str30[sizeof("shape")];
+ char stringpool_str31[sizeof("action")];
+ char stringpool_str32[sizeof("section")];
+ char stringpool_str33[sizeof("row")];
+ char stringpool_str34[sizeof("logo")];
+ char stringpool_str35[sizeof("alternate_group")];
+ char stringpool_str36[sizeof("hidden")];
+ char stringpool_str37[sizeof("virtual")];
+ char stringpool_str42[sizeof("outline")];
+ char stringpool_str43[sizeof("default")];
+ char stringpool_str46[sizeof("modmap")];
+ char stringpool_str47[sizeof("virtual_modifiers")];
+ char stringpool_str52[sizeof("overlay")];
+ char stringpool_str53[sizeof("override")];
+ char stringpool_str57[sizeof("include")];
+ char stringpool_str62[sizeof("modifier_map")];
+ char stringpool_str63[sizeof("modifier_keys")];
+ char stringpool_str64[sizeof("indicator")];
+ char stringpool_str66[sizeof("group")];
+ char stringpool_str67[sizeof("mod_map")];
+ char stringpool_str69[sizeof("interpret")];
+ char stringpool_str71[sizeof("solid")];
+ char stringpool_str72[sizeof("partial")];
+ };
+static const struct stringpool_t stringpool_contents =
+ {
+ "key",
+ "keys",
+ "augment",
+ "text",
+ "xkb_keymap",
+ "keypad_keys",
+ "xkb_keycodes",
+ "xkb_geometry",
+ "xkb_types",
+ "xkb_compat",
+ "replace",
+ "xkb_compat_map",
+ "xkb_layout",
+ "xkb_symbols",
+ "xkb_compatibility",
+ "xkb_semantics",
+ "type",
+ "alias",
+ "xkb_compatibility_map",
+ "alphanumeric_keys",
+ "function_keys",
+ "alternate",
+ "shape",
+ "action",
+ "section",
+ "row",
+ "logo",
+ "alternate_group",
+ "hidden",
+ "virtual",
+ "outline",
+ "default",
+ "modmap",
+ "virtual_modifiers",
+ "overlay",
+ "override",
+ "include",
+ "modifier_map",
+ "modifier_keys",
+ "indicator",
+ "group",
+ "mod_map",
+ "interpret",
+ "solid",
+ "partial"
+ };
+#define stringpool ((const char *) &stringpool_contents)
+#ifdef __GNUC__
+__inline
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+const struct keyword_tok *
+keyword_gperf_lookup (register const char *str, register unsigned int len)
+{
+ enum
+ {
+ TOTAL_KEYWORDS = 45,
+ MIN_WORD_LENGTH = 3,
+ MAX_WORD_LENGTH = 21,
+ MIN_HASH_VALUE = 3,
+ MAX_HASH_VALUE = 72
+ };
+
+ static const struct keyword_tok wordlist[] =
+ {
+ {-1}, {-1}, {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str3, KEY},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str4, KEYS},
+ {-1}, {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, AUGMENT},
+ {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, TEXT},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str10, XKB_KEYMAP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, KEYPAD_KEYS},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, XKB_KEYCODES},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, XKB_GEOMETRY},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, XKB_TYPES},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, XKB_COMPATMAP},
+ {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, REPLACE},
+ {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, XKB_COMPATMAP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, XKB_LAYOUT},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, XKB_SYMBOLS},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, XKB_COMPATMAP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, XKB_SEMANTICS},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, TYPE},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str25, ALIAS},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, XKB_COMPATMAP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ALPHANUMERIC_KEYS},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, FUNCTION_KEYS},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, ALTERNATE},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, SHAPE},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str31, ACTION_TOK},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, SECTION},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, ROW},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, LOGO},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, ALTERNATE_GROUP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, HIDDEN},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, VIRTUAL},
+ {-1}, {-1}, {-1}, {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, OUTLINE},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, DEFAULT},
+ {-1}, {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, MODIFIER_MAP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str47, VIRTUAL_MODS},
+ {-1}, {-1}, {-1}, {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, OVERLAY},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, OVERRIDE},
+ {-1}, {-1}, {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str57, INCLUDE},
+ {-1}, {-1}, {-1}, {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, MODIFIER_MAP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str63, MODIFIER_KEYS},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, INDICATOR},
+ {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str66, GROUP},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str67, MODIFIER_MAP},
+ {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, INTERPRET},
+ {-1},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str71, SOLID},
+ {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, PARTIAL}
+ };
+
+ if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
+ {
+ register int key = keyword_gperf_hash (str, len);
+
+ if (key <= MAX_HASH_VALUE && key >= 0)
+ {
+ register int o = wordlist[key].name;
+ if (o >= 0)
+ {
+ register const char *s = o + stringpool;
+
+ if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strcmp (str, s))
+ return &wordlist[key];
+ }
+ }
+ }
+ return 0;
+}
+
+
+int
+keyword_to_token(const char *string)
+{
+ const struct keyword_tok *kt;
+ kt = keyword_gperf_lookup(string, strlen(string));
+ if (!kt)
+ return -1;
+ return kt->tok;
+}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
index 2e02db66a8..05e725eb00 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
@@ -27,21 +27,24 @@
#ifndef XKBCOMP_PARSER_PRIV_H
#define XKBCOMP_PARSER_PRIV_H
-struct scanner_extra;
+struct scanner;
struct parser_param;
-#pragma GCC diagnostic ignored "-Wredundant-decls"
-#pragma GCC diagnostic push
#include "parser.h"
-#pragma GCC diagnostic pop
+
+int
+scanner_error(struct scanner *scanner, const char *msg);
void
-scanner_error(YYLTYPE *loc, void *scanner, const char *msg);
+scanner_warn(struct scanner *s, const char *msg);
int
-_xkbcommon_lex(YYSTYPE *val, YYLTYPE *loc, void *scanner);
+_xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner);
XkbFile *
parse(struct xkb_context *ctx, void *scanner, const char *map);
+int
+keyword_to_token(const char *string);
+
#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
index e1280e9180..26bbf30be8 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
@@ -59,7 +59,7 @@
#define YYPULL 1
/* Using locations. */
-#define YYLSP_NEEDED 1
+#define YYLSP_NEEDED 0
/* Substitute the variable and function names. */
#define yyparse _xkbcommon_parse
@@ -69,12 +69,12 @@
#define yychar _xkbcommon_char
#define yydebug _xkbcommon_debug
#define yynerrs _xkbcommon_nerrs
-#define yylloc _xkbcommon_lloc
+
/* Copy the first part of user declarations. */
/* Line 268 of yacc.c */
-#line 27 "parser.y"
+#line 33 "parser.y"
#include "xkbcomp-priv.h"
#include "ast-build.h"
@@ -88,16 +88,52 @@ struct parser_param {
};
static void
-_xkbcommon_error(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
+parser_error(struct parser_param *param, const char *msg)
{
- scanner_error(loc, param->scanner, msg);
+ scanner_error(param->scanner, msg);
+}
+
+static void
+parser_warn(struct parser_param *param, const char *msg)
+{
+ scanner_warn(param->scanner, msg);
+}
+
+static void
+_xkbcommon_error(struct parser_param *param, const char *msg)
+{
+ parser_error(param, msg);
+}
+
+static bool
+resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn)
+{
+ xkb_keysym_t sym;
+
+ if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
+ *sym_rtrn = XKB_KEY_NoSymbol;
+ return true;
+ }
+
+ if (istreq(str, "none") || istreq(str, "voidsymbol")) {
+ *sym_rtrn = XKB_KEY_VoidSymbol;
+ return true;
+ }
+
+ sym = xkb_keysym_from_name(str, XKB_KEYSYM_NO_FLAGS);
+ if (sym != XKB_KEY_NoSymbol) {
+ *sym_rtrn = sym;
+ return true;
+ }
+
+ return false;
}
#define scanner param->scanner
/* Line 268 of yacc.c */
-#line 101 "src/xkbcomp/parser.c"
+#line 137 "src/xkbcomp/parser.c"
/* Enabling traces. */
#ifndef YYDEBUG
@@ -262,16 +298,16 @@ typedef union YYSTYPE
{
/* Line 293 of yacc.c */
-#line 127 "parser.y"
+#line 167 "parser.y"
int ival;
- unsigned uval;
int64_t num;
enum xkb_file_type file_type;
char *str;
xkb_atom_t sval;
enum merge_mode merge;
enum xkb_map_flags mapFlags;
+ xkb_keysym_t keysym;
ParseCommon *any;
ExprDef *expr;
VarDef *var;
@@ -291,32 +327,19 @@ typedef union YYSTYPE
/* Line 293 of yacc.c */
-#line 295 "src/xkbcomp/parser.c"
+#line 331 "src/xkbcomp/parser.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
/* Copy the second part of user declarations. */
/* Line 343 of yacc.c */
-#line 320 "src/xkbcomp/parser.c"
+#line 343 "src/xkbcomp/parser.c"
#ifdef short
# undef short
@@ -474,15 +497,13 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
#if (! defined yyoverflow \
&& (! defined __cplusplus \
- || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
- && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
/* A type that is properly aligned for any stack member. */
union yyalloc
{
yytype_int16 yyss_alloc;
YYSTYPE yyvs_alloc;
- YYLTYPE yyls_alloc;
};
/* The size of the maximum gap between one aligned stack and the next. */
@@ -491,8 +512,8 @@ union yyalloc
/* The size of an array large to enough to hold all stacks, each with
N elements. */
# define YYSTACK_BYTES(N) \
- ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
- + 2 * YYSTACK_GAP_MAXIMUM)
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
# define YYCOPY_NEEDED 1
@@ -677,25 +698,25 @@ static const yytype_int16 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 0, 198, 198, 200, 202, 206, 212, 213, 214, 217,
- 224, 228, 243, 244, 245, 246, 247, 250, 251, 254,
- 255, 258, 259, 260, 261, 262, 263, 264, 265, 268,
- 270, 273, 278, 283, 288, 293, 298, 303, 308, 313,
- 318, 323, 328, 329, 330, 331, 338, 340, 342, 346,
- 350, 354, 358, 360, 364, 366, 370, 376, 378, 382,
- 384, 388, 394, 400, 402, 404, 407, 408, 409, 410,
- 411, 414, 416, 420, 424, 428, 432, 434, 438, 440,
- 444, 448, 449, 452, 454, 456, 458, 460, 464, 465,
- 468, 469, 473, 474, 477, 479, 483, 487, 488, 491,
- 494, 496, 500, 502, 504, 508, 510, 514, 518, 522,
- 523, 524, 525, 528, 529, 532, 534, 536, 538, 540,
- 542, 544, 546, 548, 550, 552, 556, 557, 560, 561,
- 562, 563, 564, 574, 575, 578, 580, 584, 586, 588,
- 590, 592, 594, 598, 600, 602, 604, 606, 608, 610,
- 612, 616, 618, 622, 626, 633, 641, 650, 661, 668,
- 675, 679, 688, 689, 692, 694, 696, 698, 702, 706,
- 707, 708, 722, 723, 726, 727, 730, 733, 736, 739,
- 740, 743, 746, 747, 750
+ 0, 238, 238, 240, 242, 246, 252, 253, 254, 257,
+ 264, 268, 283, 284, 285, 286, 287, 290, 291, 294,
+ 295, 298, 299, 300, 301, 302, 303, 304, 305, 308,
+ 310, 313, 318, 323, 328, 333, 338, 343, 348, 353,
+ 358, 363, 368, 369, 370, 371, 378, 380, 382, 386,
+ 390, 394, 398, 400, 404, 406, 410, 416, 418, 422,
+ 424, 428, 434, 440, 442, 444, 447, 448, 449, 450,
+ 451, 454, 456, 460, 464, 468, 472, 474, 478, 480,
+ 484, 488, 489, 492, 494, 496, 498, 500, 504, 505,
+ 508, 509, 513, 514, 517, 519, 523, 527, 528, 531,
+ 534, 536, 540, 542, 544, 548, 550, 554, 558, 562,
+ 563, 564, 565, 568, 569, 572, 574, 576, 578, 580,
+ 582, 584, 586, 588, 590, 592, 596, 597, 600, 601,
+ 602, 603, 604, 614, 615, 618, 620, 624, 626, 628,
+ 630, 632, 634, 638, 640, 642, 644, 646, 648, 650,
+ 652, 656, 658, 662, 666, 668, 670, 672, 676, 678,
+ 680, 682, 686, 687, 690, 692, 694, 696, 700, 704,
+ 710, 711, 725, 726, 729, 730, 733, 736, 739, 742,
+ 743, 746, 749, 750, 753
};
#endif
@@ -1148,7 +1169,7 @@ do \
} \
else \
{ \
- yyerror (&yylloc, param, YY_("syntax error: cannot back up")); \
+ yyerror (param, YY_("syntax error: cannot back up")); \
YYERROR; \
} \
while (YYID (0))
@@ -1184,28 +1205,19 @@ while (YYID (0))
#endif
-/* YY_LOCATION_PRINT -- Print the location on the stream.
- This macro was not mandated originally: define only if we know
- we won't break user code: when these are the locations we know. */
+/* This macro is provided for backward compatibility. */
#ifndef YY_LOCATION_PRINT
-# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
-# define YY_LOCATION_PRINT(File, Loc) \
- fprintf (File, "%d.%d-%d.%d", \
- (Loc).first_line, (Loc).first_column, \
- (Loc).last_line, (Loc).last_column)
-# else
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
#endif
/* YYLEX -- calling `yylex' with the right arguments. */
#ifdef YYLEX_PARAM
-# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
#else
-# define YYLEX yylex (&yylval, &yylloc, scanner)
+# define YYLEX yylex (&yylval, scanner)
#endif
/* Enable debugging if requested. */
@@ -1228,7 +1240,7 @@ do { \
{ \
YYFPRINTF (stderr, "%s ", Title); \
yy_symbol_print (stderr, \
- Type, Value, Location, param); \
+ Type, Value, param); \
YYFPRINTF (stderr, "\n"); \
} \
} while (YYID (0))
@@ -1242,20 +1254,18 @@ do { \
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct parser_param *param)
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser_param *param)
#else
static void
-yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, param)
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, param)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
- YYLTYPE const * const yylocationp;
struct parser_param *param;
#endif
{
if (!yyvaluep)
return;
- YYUSE (yylocationp);
YYUSE (param);
# ifdef YYPRINT
if (yytype < YYNTOKENS)
@@ -1278,14 +1288,13 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, param)
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct parser_param *param)
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, struct parser_param *param)
#else
static void
-yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, param)
+yy_symbol_print (yyoutput, yytype, yyvaluep, param)
FILE *yyoutput;
int yytype;
YYSTYPE const * const yyvaluep;
- YYLTYPE const * const yylocationp;
struct parser_param *param;
#endif
{
@@ -1294,9 +1303,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, param)
else
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
- YY_LOCATION_PRINT (yyoutput, *yylocationp);
- YYFPRINTF (yyoutput, ": ");
- yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, param);
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, param);
YYFPRINTF (yyoutput, ")");
}
@@ -1339,12 +1346,11 @@ do { \
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct parser_param *param)
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule, struct parser_param *param)
#else
static void
-yy_reduce_print (yyvsp, yylsp, yyrule, param)
+yy_reduce_print (yyvsp, yyrule, param)
YYSTYPE *yyvsp;
- YYLTYPE *yylsp;
int yyrule;
struct parser_param *param;
#endif
@@ -1360,7 +1366,7 @@ yy_reduce_print (yyvsp, yylsp, yyrule, param)
YYFPRINTF (stderr, " $%d = ", yyi + 1);
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
&(yyvsp[(yyi + 1) - (yynrhs)])
- , &(yylsp[(yyi + 1) - (yynrhs)]) , param);
+ , param);
YYFPRINTF (stderr, "\n");
}
}
@@ -1368,7 +1374,7 @@ yy_reduce_print (yyvsp, yylsp, yyrule, param)
# define YY_REDUCE_PRINT(Rule) \
do { \
if (yydebug) \
- yy_reduce_print (yyvsp, yylsp, Rule, param); \
+ yy_reduce_print (yyvsp, Rule, param); \
} while (YYID (0))
/* Nonzero means print parse trace. It is left uninitialized so that
@@ -1645,19 +1651,17 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
static void
-yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct parser_param *param)
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, struct parser_param *param)
#else
static void
-yydestruct (yymsg, yytype, yyvaluep, yylocationp, param)
+yydestruct (yymsg, yytype, yyvaluep, param)
const char *yymsg;
int yytype;
YYSTYPE *yyvaluep;
- YYLTYPE *yylocationp;
struct parser_param *param;
#endif
{
YYUSE (yyvaluep);
- YYUSE (yylocationp);
YYUSE (param);
if (!yymsg)
@@ -1721,9 +1725,6 @@ int yychar;
/* The semantic value of the lookahead symbol. */
YYSTYPE yylval;
-/* Location data for the lookahead symbol. */
-YYLTYPE yylloc;
-
/* Number of syntax errors so far. */
int yynerrs;
@@ -1734,7 +1735,6 @@ YYLTYPE yylloc;
/* The stacks and their tools:
`yyss': related to states.
`yyvs': related to semantic values.
- `yyls': related to locations.
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
@@ -1749,14 +1749,6 @@ YYLTYPE yylloc;
YYSTYPE *yyvs;
YYSTYPE *yyvsp;
- /* The location stack. */
- YYLTYPE yylsa[YYINITDEPTH];
- YYLTYPE *yyls;
- YYLTYPE *yylsp;
-
- /* The locations where the error started and ended. */
- YYLTYPE yyerror_range[3];
-
YYSIZE_T yystacksize;
int yyn;
@@ -1766,7 +1758,6 @@ YYLTYPE yylloc;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
- YYLTYPE yyloc;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
@@ -1775,7 +1766,7 @@ YYLTYPE yylloc;
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
-#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
@@ -1784,7 +1775,6 @@ YYLTYPE yylloc;
yytoken = 0;
yyss = yyssa;
yyvs = yyvsa;
- yyls = yylsa;
yystacksize = YYINITDEPTH;
YYDPRINTF ((stderr, "Starting parse\n"));
@@ -1800,13 +1790,6 @@ YYLTYPE yylloc;
The wasted elements are never initialized. */
yyssp = yyss;
yyvsp = yyvs;
- yylsp = yyls;
-
-#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
- /* Initialize the default location before parsing starts. */
- yylloc.first_line = yylloc.last_line = 1;
- yylloc.first_column = yylloc.last_column = 1;
-#endif
goto yysetstate;
@@ -1833,7 +1816,6 @@ YYLTYPE yylloc;
memory. */
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
- YYLTYPE *yyls1 = yyls;
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
@@ -1842,10 +1824,8 @@ YYLTYPE yylloc;
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
- &yyls1, yysize * sizeof (*yylsp),
&yystacksize);
- yyls = yyls1;
yyss = yyss1;
yyvs = yyvs1;
}
@@ -1868,7 +1848,6 @@ YYLTYPE yylloc;
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, yyvs);
- YYSTACK_RELOCATE (yyls_alloc, yyls);
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
@@ -1878,7 +1857,6 @@ YYLTYPE yylloc;
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
- yylsp = yyls + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
@@ -1954,7 +1932,7 @@ yybackup:
yystate = yyn;
*++yyvsp = yylval;
- *++yylsp = yylloc;
+
goto yynewstate;
@@ -1985,64 +1963,63 @@ yyreduce:
GCC warning that YYVAL may be used uninitialized. */
yyval = yyvsp[1-yylen];
- /* Default location. */
- YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
case 2:
/* Line 1806 of yacc.c */
-#line 199 "parser.y"
+#line 239 "parser.y"
{ (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; }
break;
case 3:
/* Line 1806 of yacc.c */
-#line 201 "parser.y"
+#line 241 "parser.y"
{ (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; YYACCEPT; }
break;
case 4:
/* Line 1806 of yacc.c */
-#line 203 "parser.y"
+#line 243 "parser.y"
{ (yyval.file) = param->rtrn = NULL; param->more_maps = false; }
break;
case 5:
/* Line 1806 of yacc.c */
-#line 209 "parser.y"
+#line 249 "parser.y"
{ (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), &(yyvsp[(5) - (7)].file)->common, (yyvsp[(1) - (7)].mapFlags)); }
break;
case 6:
/* Line 1806 of yacc.c */
-#line 212 "parser.y"
+#line 252 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYMAP; }
break;
case 7:
/* Line 1806 of yacc.c */
-#line 213 "parser.y"
+#line 253 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYMAP; }
break;
case 8:
/* Line 1806 of yacc.c */
-#line 214 "parser.y"
+#line 254 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYMAP; }
break;
case 9:
/* Line 1806 of yacc.c */
-#line 218 "parser.y"
+#line 258 "parser.y"
{
if (!(yyvsp[(2) - (2)].file))
(yyval.file) = (yyvsp[(1) - (2)].file);
@@ -2054,14 +2031,14 @@ yyreduce:
case 10:
/* Line 1806 of yacc.c */
-#line 225 "parser.y"
+#line 265 "parser.y"
{ (yyval.file) = (yyvsp[(1) - (1)].file); }
break;
case 11:
/* Line 1806 of yacc.c */
-#line 231 "parser.y"
+#line 271 "parser.y"
{
if ((yyvsp[(2) - (7)].file_type) == FILE_TYPE_GEOMETRY) {
free((yyvsp[(3) - (7)].str));
@@ -2077,140 +2054,140 @@ yyreduce:
case 12:
/* Line 1806 of yacc.c */
-#line 243 "parser.y"
+#line 283 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYCODES; }
break;
case 13:
/* Line 1806 of yacc.c */
-#line 244 "parser.y"
+#line 284 "parser.y"
{ (yyval.file_type) = FILE_TYPE_TYPES; }
break;
case 14:
/* Line 1806 of yacc.c */
-#line 245 "parser.y"
+#line 285 "parser.y"
{ (yyval.file_type) = FILE_TYPE_COMPAT; }
break;
case 15:
/* Line 1806 of yacc.c */
-#line 246 "parser.y"
+#line 286 "parser.y"
{ (yyval.file_type) = FILE_TYPE_SYMBOLS; }
break;
case 16:
/* Line 1806 of yacc.c */
-#line 247 "parser.y"
+#line 287 "parser.y"
{ (yyval.file_type) = FILE_TYPE_GEOMETRY; }
break;
case 17:
/* Line 1806 of yacc.c */
-#line 250 "parser.y"
+#line 290 "parser.y"
{ (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); }
break;
case 18:
/* Line 1806 of yacc.c */
-#line 251 "parser.y"
+#line 291 "parser.y"
{ (yyval.mapFlags) = 0; }
break;
case 19:
/* Line 1806 of yacc.c */
-#line 254 "parser.y"
+#line 294 "parser.y"
{ (yyval.mapFlags) = ((yyvsp[(1) - (2)].mapFlags) | (yyvsp[(2) - (2)].mapFlags)); }
break;
case 20:
/* Line 1806 of yacc.c */
-#line 255 "parser.y"
+#line 295 "parser.y"
{ (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); }
break;
case 21:
/* Line 1806 of yacc.c */
-#line 258 "parser.y"
+#line 298 "parser.y"
{ (yyval.mapFlags) = MAP_IS_PARTIAL; }
break;
case 22:
/* Line 1806 of yacc.c */
-#line 259 "parser.y"
+#line 299 "parser.y"
{ (yyval.mapFlags) = MAP_IS_DEFAULT; }
break;
case 23:
/* Line 1806 of yacc.c */
-#line 260 "parser.y"
+#line 300 "parser.y"
{ (yyval.mapFlags) = MAP_IS_HIDDEN; }
break;
case 24:
/* Line 1806 of yacc.c */
-#line 261 "parser.y"
+#line 301 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_ALPHANUMERIC; }
break;
case 25:
/* Line 1806 of yacc.c */
-#line 262 "parser.y"
+#line 302 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_MODIFIER; }
break;
case 26:
/* Line 1806 of yacc.c */
-#line 263 "parser.y"
+#line 303 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_KEYPAD; }
break;
case 27:
/* Line 1806 of yacc.c */
-#line 264 "parser.y"
+#line 304 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_FN; }
break;
case 28:
/* Line 1806 of yacc.c */
-#line 265 "parser.y"
+#line 305 "parser.y"
{ (yyval.mapFlags) = MAP_IS_ALTGR; }
break;
case 29:
/* Line 1806 of yacc.c */
-#line 269 "parser.y"
+#line 309 "parser.y"
{ (yyval.any) = AppendStmt((yyvsp[(1) - (2)].any), (yyvsp[(2) - (2)].any)); }
break;
case 30:
/* Line 1806 of yacc.c */
-#line 270 "parser.y"
+#line 310 "parser.y"
{ (yyval.any) = NULL; }
break;
case 31:
/* Line 1806 of yacc.c */
-#line 274 "parser.y"
+#line 314 "parser.y"
{
(yyvsp[(2) - (2)].var)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].var)->common;
@@ -2220,7 +2197,7 @@ yyreduce:
case 32:
/* Line 1806 of yacc.c */
-#line 279 "parser.y"
+#line 319 "parser.y"
{
(yyvsp[(2) - (2)].vmod)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].vmod)->common;
@@ -2230,7 +2207,7 @@ yyreduce:
case 33:
/* Line 1806 of yacc.c */
-#line 284 "parser.y"
+#line 324 "parser.y"
{
(yyvsp[(2) - (2)].interp)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].interp)->common;
@@ -2240,7 +2217,7 @@ yyreduce:
case 34:
/* Line 1806 of yacc.c */
-#line 289 "parser.y"
+#line 329 "parser.y"
{
(yyvsp[(2) - (2)].keyCode)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].keyCode)->common;
@@ -2250,7 +2227,7 @@ yyreduce:
case 35:
/* Line 1806 of yacc.c */
-#line 294 "parser.y"
+#line 334 "parser.y"
{
(yyvsp[(2) - (2)].keyAlias)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].keyAlias)->common;
@@ -2260,7 +2237,7 @@ yyreduce:
case 36:
/* Line 1806 of yacc.c */
-#line 299 "parser.y"
+#line 339 "parser.y"
{
(yyvsp[(2) - (2)].keyType)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].keyType)->common;
@@ -2270,7 +2247,7 @@ yyreduce:
case 37:
/* Line 1806 of yacc.c */
-#line 304 "parser.y"
+#line 344 "parser.y"
{
(yyvsp[(2) - (2)].syms)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].syms)->common;
@@ -2280,7 +2257,7 @@ yyreduce:
case 38:
/* Line 1806 of yacc.c */
-#line 309 "parser.y"
+#line 349 "parser.y"
{
(yyvsp[(2) - (2)].modMask)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].modMask)->common;
@@ -2290,7 +2267,7 @@ yyreduce:
case 39:
/* Line 1806 of yacc.c */
-#line 314 "parser.y"
+#line 354 "parser.y"
{
(yyvsp[(2) - (2)].groupCompat)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].groupCompat)->common;
@@ -2300,7 +2277,7 @@ yyreduce:
case 40:
/* Line 1806 of yacc.c */
-#line 319 "parser.y"
+#line 359 "parser.y"
{
(yyvsp[(2) - (2)].ledMap)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].ledMap)->common;
@@ -2310,7 +2287,7 @@ yyreduce:
case 41:
/* Line 1806 of yacc.c */
-#line 324 "parser.y"
+#line 364 "parser.y"
{
(yyvsp[(2) - (2)].ledName)->merge = (yyvsp[(1) - (2)].merge);
(yyval.any) = &(yyvsp[(2) - (2)].ledName)->common;
@@ -2320,28 +2297,28 @@ yyreduce:
case 42:
/* Line 1806 of yacc.c */
-#line 328 "parser.y"
+#line 368 "parser.y"
{ (yyval.any) = NULL; }
break;
case 43:
/* Line 1806 of yacc.c */
-#line 329 "parser.y"
+#line 369 "parser.y"
{ (yyval.any) = NULL; }
break;
case 44:
/* Line 1806 of yacc.c */
-#line 330 "parser.y"
+#line 370 "parser.y"
{ (yyval.any) = NULL; }
break;
case 45:
/* Line 1806 of yacc.c */
-#line 332 "parser.y"
+#line 372 "parser.y"
{
(yyval.any) = &IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge))->common;
free((yyvsp[(2) - (2)].str));
@@ -2351,609 +2328,609 @@ yyreduce:
case 46:
/* Line 1806 of yacc.c */
-#line 339 "parser.y"
+#line 379 "parser.y"
{ (yyval.var) = VarCreate((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr)); }
break;
case 47:
/* Line 1806 of yacc.c */
-#line 341 "parser.y"
- { (yyval.var) = BoolVarCreate((yyvsp[(1) - (2)].sval), 1); }
+#line 381 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(1) - (2)].sval), true); }
break;
case 48:
/* Line 1806 of yacc.c */
-#line 343 "parser.y"
- { (yyval.var) = BoolVarCreate((yyvsp[(2) - (3)].sval), 0); }
+#line 383 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(2) - (3)].sval), false); }
break;
case 49:
/* Line 1806 of yacc.c */
-#line 347 "parser.y"
+#line 387 "parser.y"
{ (yyval.keyCode) = KeycodeCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].num)); }
break;
case 50:
/* Line 1806 of yacc.c */
-#line 351 "parser.y"
+#line 391 "parser.y"
{ (yyval.keyAlias) = KeyAliasCreate((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].sval)); }
break;
case 51:
/* Line 1806 of yacc.c */
-#line 355 "parser.y"
+#line 395 "parser.y"
{ (yyval.vmod) = (yyvsp[(2) - (3)].vmod); }
break;
case 52:
/* Line 1806 of yacc.c */
-#line 359 "parser.y"
+#line 399 "parser.y"
{ (yyval.vmod) = (VModDef *)AppendStmt(&(yyvsp[(1) - (3)].vmod)->common, &(yyvsp[(3) - (3)].vmod)->common); }
break;
case 53:
/* Line 1806 of yacc.c */
-#line 361 "parser.y"
+#line 401 "parser.y"
{ (yyval.vmod) = (yyvsp[(1) - (1)].vmod); }
break;
case 54:
/* Line 1806 of yacc.c */
-#line 365 "parser.y"
+#line 405 "parser.y"
{ (yyval.vmod) = VModCreate((yyvsp[(1) - (1)].sval), NULL); }
break;
case 55:
/* Line 1806 of yacc.c */
-#line 367 "parser.y"
+#line 407 "parser.y"
{ (yyval.vmod) = VModCreate((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr)); }
break;
case 56:
/* Line 1806 of yacc.c */
-#line 373 "parser.y"
+#line 413 "parser.y"
{ (yyvsp[(2) - (6)].interp)->def = (yyvsp[(4) - (6)].var); (yyval.interp) = (yyvsp[(2) - (6)].interp); }
break;
case 57:
/* Line 1806 of yacc.c */
-#line 377 "parser.y"
- { (yyval.interp) = InterpCreate((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].expr)); }
+#line 417 "parser.y"
+ { (yyval.interp) = InterpCreate((yyvsp[(1) - (3)].keysym), (yyvsp[(3) - (3)].expr)); }
break;
case 58:
/* Line 1806 of yacc.c */
-#line 379 "parser.y"
- { (yyval.interp) = InterpCreate((yyvsp[(1) - (1)].str), NULL); }
+#line 419 "parser.y"
+ { (yyval.interp) = InterpCreate((yyvsp[(1) - (1)].keysym), NULL); }
break;
case 59:
/* Line 1806 of yacc.c */
-#line 383 "parser.y"
+#line 423 "parser.y"
{ (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (2)].var)->common, &(yyvsp[(2) - (2)].var)->common); }
break;
case 60:
/* Line 1806 of yacc.c */
-#line 385 "parser.y"
+#line 425 "parser.y"
{ (yyval.var) = (yyvsp[(1) - (1)].var); }
break;
case 61:
/* Line 1806 of yacc.c */
-#line 391 "parser.y"
+#line 431 "parser.y"
{ (yyval.keyType) = KeyTypeCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
break;
case 62:
/* Line 1806 of yacc.c */
-#line 397 "parser.y"
- { (yyval.syms) = SymbolsCreate((yyvsp[(2) - (6)].sval), (ExprDef *)(yyvsp[(4) - (6)].var)); }
+#line 437 "parser.y"
+ { (yyval.syms) = SymbolsCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
break;
case 63:
/* Line 1806 of yacc.c */
-#line 401 "parser.y"
+#line 441 "parser.y"
{ (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (3)].var)->common, &(yyvsp[(3) - (3)].var)->common); }
break;
case 64:
/* Line 1806 of yacc.c */
-#line 403 "parser.y"
+#line 443 "parser.y"
{ (yyval.var) = (yyvsp[(1) - (1)].var); }
break;
case 65:
/* Line 1806 of yacc.c */
-#line 404 "parser.y"
+#line 444 "parser.y"
{ (yyval.var) = NULL; }
break;
case 66:
/* Line 1806 of yacc.c */
-#line 407 "parser.y"
+#line 447 "parser.y"
{ (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 67:
/* Line 1806 of yacc.c */
-#line 408 "parser.y"
+#line 448 "parser.y"
{ (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 68:
/* Line 1806 of yacc.c */
-#line 409 "parser.y"
- { (yyval.var) = BoolVarCreate((yyvsp[(1) - (1)].sval), 1); }
+#line 449 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(1) - (1)].sval), true); }
break;
case 69:
/* Line 1806 of yacc.c */
-#line 410 "parser.y"
- { (yyval.var) = BoolVarCreate((yyvsp[(2) - (2)].sval), 0); }
+#line 450 "parser.y"
+ { (yyval.var) = BoolVarCreate((yyvsp[(2) - (2)].sval), false); }
break;
case 70:
/* Line 1806 of yacc.c */
-#line 411 "parser.y"
+#line 451 "parser.y"
{ (yyval.var) = VarCreate(NULL, (yyvsp[(1) - (1)].expr)); }
break;
case 71:
/* Line 1806 of yacc.c */
-#line 415 "parser.y"
+#line 455 "parser.y"
{ (yyval.expr) = (yyvsp[(2) - (3)].expr); }
break;
case 72:
/* Line 1806 of yacc.c */
-#line 417 "parser.y"
+#line 457 "parser.y"
{ (yyval.expr) = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, (yyvsp[(2) - (3)].expr)); }
break;
case 73:
/* Line 1806 of yacc.c */
-#line 421 "parser.y"
+#line 461 "parser.y"
{ (yyval.groupCompat) = GroupCompatCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr)); }
break;
case 74:
/* Line 1806 of yacc.c */
-#line 425 "parser.y"
+#line 465 "parser.y"
{ (yyval.modMask) = ModMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].expr)); }
break;
case 75:
/* Line 1806 of yacc.c */
-#line 429 "parser.y"
+#line 469 "parser.y"
{ (yyval.ledMap) = LedMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
break;
case 76:
/* Line 1806 of yacc.c */
-#line 433 "parser.y"
+#line 473 "parser.y"
{ (yyval.ledName) = LedNameCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr), false); }
break;
case 77:
/* Line 1806 of yacc.c */
-#line 435 "parser.y"
+#line 475 "parser.y"
{ (yyval.ledName) = LedNameCreate((yyvsp[(3) - (6)].ival), (yyvsp[(5) - (6)].expr), true); }
break;
case 78:
/* Line 1806 of yacc.c */
-#line 439 "parser.y"
+#line 479 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 79:
/* Line 1806 of yacc.c */
-#line 441 "parser.y"
+#line 481 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 80:
/* Line 1806 of yacc.c */
-#line 445 "parser.y"
+#line 485 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 81:
/* Line 1806 of yacc.c */
-#line 448 "parser.y"
+#line 488 "parser.y"
{ (yyval.geom) = NULL;}
break;
case 82:
/* Line 1806 of yacc.c */
-#line 449 "parser.y"
+#line 489 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 83:
/* Line 1806 of yacc.c */
-#line 453 "parser.y"
+#line 493 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 84:
/* Line 1806 of yacc.c */
-#line 455 "parser.y"
+#line 495 "parser.y"
{ FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; }
break;
case 85:
/* Line 1806 of yacc.c */
-#line 457 "parser.y"
+#line 497 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 86:
/* Line 1806 of yacc.c */
-#line 459 "parser.y"
+#line 499 "parser.y"
{ FreeStmt(&(yyvsp[(1) - (1)].ledMap)->common); (yyval.geom) = NULL; }
break;
case 87:
/* Line 1806 of yacc.c */
-#line 461 "parser.y"
+#line 501 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 88:
/* Line 1806 of yacc.c */
-#line 464 "parser.y"
+#line 504 "parser.y"
{ (yyval.geom) = NULL;}
break;
case 89:
/* Line 1806 of yacc.c */
-#line 465 "parser.y"
+#line 505 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 90:
/* Line 1806 of yacc.c */
-#line 468 "parser.y"
+#line 508 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 91:
/* Line 1806 of yacc.c */
-#line 470 "parser.y"
+#line 510 "parser.y"
{ FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; }
break;
case 92:
/* Line 1806 of yacc.c */
-#line 473 "parser.y"
+#line 513 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 93:
/* Line 1806 of yacc.c */
-#line 474 "parser.y"
+#line 514 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 94:
/* Line 1806 of yacc.c */
-#line 478 "parser.y"
+#line 518 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 95:
/* Line 1806 of yacc.c */
-#line 480 "parser.y"
+#line 520 "parser.y"
{ FreeStmt(&(yyvsp[(2) - (3)].expr)->common); (yyval.geom) = NULL; }
break;
case 96:
/* Line 1806 of yacc.c */
-#line 484 "parser.y"
+#line 524 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 97:
/* Line 1806 of yacc.c */
-#line 487 "parser.y"
+#line 527 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 98:
/* Line 1806 of yacc.c */
-#line 488 "parser.y"
+#line 528 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 99:
/* Line 1806 of yacc.c */
-#line 491 "parser.y"
+#line 531 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 100:
/* Line 1806 of yacc.c */
-#line 495 "parser.y"
+#line 535 "parser.y"
{ (yyval.geom) = NULL;}
break;
case 101:
/* Line 1806 of yacc.c */
-#line 497 "parser.y"
+#line 537 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 102:
/* Line 1806 of yacc.c */
-#line 501 "parser.y"
+#line 541 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 103:
/* Line 1806 of yacc.c */
-#line 503 "parser.y"
+#line 543 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 104:
/* Line 1806 of yacc.c */
-#line 505 "parser.y"
+#line 545 "parser.y"
{ FreeStmt(&(yyvsp[(3) - (3)].expr)->common); (yyval.geom) = NULL; }
break;
case 105:
/* Line 1806 of yacc.c */
-#line 509 "parser.y"
+#line 549 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 106:
/* Line 1806 of yacc.c */
-#line 511 "parser.y"
+#line 551 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 107:
/* Line 1806 of yacc.c */
-#line 515 "parser.y"
+#line 555 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 108:
/* Line 1806 of yacc.c */
-#line 519 "parser.y"
+#line 559 "parser.y"
{ FreeStmt(&(yyvsp[(4) - (6)].var)->common); (yyval.geom) = NULL; }
break;
case 109:
/* Line 1806 of yacc.c */
-#line 522 "parser.y"
- { (yyval.uval) = 0; }
+#line 562 "parser.y"
+ { (yyval.ival) = 0; }
break;
case 110:
/* Line 1806 of yacc.c */
-#line 523 "parser.y"
- { (yyval.uval) = 0; }
+#line 563 "parser.y"
+ { (yyval.ival) = 0; }
break;
case 111:
/* Line 1806 of yacc.c */
-#line 524 "parser.y"
- { (yyval.uval) = 0; }
+#line 564 "parser.y"
+ { (yyval.ival) = 0; }
break;
case 112:
/* Line 1806 of yacc.c */
-#line 525 "parser.y"
- { (yyval.uval) = 0; }
+#line 565 "parser.y"
+ { (yyval.ival) = 0; }
break;
case 113:
/* Line 1806 of yacc.c */
-#line 528 "parser.y"
+#line 568 "parser.y"
{ (yyval.sval) = (yyvsp[(1) - (1)].sval); }
break;
case 114:
/* Line 1806 of yacc.c */
-#line 529 "parser.y"
+#line 569 "parser.y"
{ (yyval.sval) = (yyvsp[(1) - (1)].sval); }
break;
case 115:
/* Line 1806 of yacc.c */
-#line 533 "parser.y"
- { (yyval.sval) = xkb_atom_intern(param->ctx, "action"); }
+#line 573 "parser.y"
+ { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "action"); }
break;
case 116:
/* Line 1806 of yacc.c */
-#line 535 "parser.y"
- { (yyval.sval) = xkb_atom_intern(param->ctx, "interpret"); }
+#line 575 "parser.y"
+ { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "interpret"); }
break;
case 117:
/* Line 1806 of yacc.c */
-#line 537 "parser.y"
- { (yyval.sval) = xkb_atom_intern(param->ctx, "type"); }
+#line 577 "parser.y"
+ { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "type"); }
break;
case 118:
/* Line 1806 of yacc.c */
-#line 539 "parser.y"
- { (yyval.sval) = xkb_atom_intern(param->ctx, "key"); }
+#line 579 "parser.y"
+ { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "key"); }
break;
case 119:
/* Line 1806 of yacc.c */
-#line 541 "parser.y"
- { (yyval.sval) = xkb_atom_intern(param->ctx, "group"); }
+#line 581 "parser.y"
+ { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "group"); }
break;
case 120:
/* Line 1806 of yacc.c */
-#line 543 "parser.y"
- {(yyval.sval) = xkb_atom_intern(param->ctx, "modifier_map");}
+#line 583 "parser.y"
+ {(yyval.sval) = xkb_atom_intern_literal(param->ctx, "modifier_map");}
break;
case 121:
/* Line 1806 of yacc.c */
-#line 545 "parser.y"
- { (yyval.sval) = xkb_atom_intern(param->ctx, "indicator"); }
+#line 585 "parser.y"
+ { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "indicator"); }
break;
case 122:
/* Line 1806 of yacc.c */
-#line 547 "parser.y"
+#line 587 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 123:
/* Line 1806 of yacc.c */
-#line 549 "parser.y"
+#line 589 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 124:
/* Line 1806 of yacc.c */
-#line 551 "parser.y"
+#line 591 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 125:
/* Line 1806 of yacc.c */
-#line 553 "parser.y"
+#line 593 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 126:
/* Line 1806 of yacc.c */
-#line 556 "parser.y"
+#line 596 "parser.y"
{ (yyval.merge) = (yyvsp[(1) - (1)].merge); }
break;
case 127:
/* Line 1806 of yacc.c */
-#line 557 "parser.y"
+#line 597 "parser.y"
{ (yyval.merge) = MERGE_DEFAULT; }
break;
case 128:
/* Line 1806 of yacc.c */
-#line 560 "parser.y"
+#line 600 "parser.y"
{ (yyval.merge) = MERGE_DEFAULT; }
break;
case 129:
/* Line 1806 of yacc.c */
-#line 561 "parser.y"
+#line 601 "parser.y"
{ (yyval.merge) = MERGE_AUGMENT; }
break;
case 130:
/* Line 1806 of yacc.c */
-#line 562 "parser.y"
+#line 602 "parser.y"
{ (yyval.merge) = MERGE_OVERRIDE; }
break;
case 131:
/* Line 1806 of yacc.c */
-#line 563 "parser.y"
+#line 603 "parser.y"
{ (yyval.merge) = MERGE_REPLACE; }
break;
case 132:
/* Line 1806 of yacc.c */
-#line 565 "parser.y"
+#line 605 "parser.y"
{
/*
* This used to be MERGE_ALT_FORM. This functionality was
@@ -2966,324 +2943,286 @@ yyreduce:
case 133:
/* Line 1806 of yacc.c */
-#line 574 "parser.y"
+#line 614 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 134:
/* Line 1806 of yacc.c */
-#line 575 "parser.y"
+#line 615 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 135:
/* Line 1806 of yacc.c */
-#line 579 "parser.y"
+#line 619 "parser.y"
{ (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); }
break;
case 136:
/* Line 1806 of yacc.c */
-#line 581 "parser.y"
+#line 621 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 137:
/* Line 1806 of yacc.c */
-#line 585 "parser.y"
+#line 625 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_DIVIDE, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 138:
/* Line 1806 of yacc.c */
-#line 587 "parser.y"
+#line 627 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 139:
/* Line 1806 of yacc.c */
-#line 589 "parser.y"
+#line 629 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_SUBTRACT, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 140:
/* Line 1806 of yacc.c */
-#line 591 "parser.y"
+#line 631 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_MULTIPLY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 141:
/* Line 1806 of yacc.c */
-#line 593 "parser.y"
+#line 633 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_ASSIGN, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 142:
/* Line 1806 of yacc.c */
-#line 595 "parser.y"
+#line 635 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 143:
/* Line 1806 of yacc.c */
-#line 599 "parser.y"
- { (yyval.expr) = ExprCreateUnary(EXPR_NEGATE, (yyvsp[(2) - (2)].expr)->value_type, (yyvsp[(2) - (2)].expr)); }
+#line 639 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_NEGATE, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); }
break;
case 144:
/* Line 1806 of yacc.c */
-#line 601 "parser.y"
- { (yyval.expr) = ExprCreateUnary(EXPR_UNARY_PLUS, (yyvsp[(2) - (2)].expr)->value_type, (yyvsp[(2) - (2)].expr)); }
+#line 641 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_UNARY_PLUS, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); }
break;
case 145:
/* Line 1806 of yacc.c */
-#line 603 "parser.y"
+#line 643 "parser.y"
{ (yyval.expr) = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, (yyvsp[(2) - (2)].expr)); }
break;
case 146:
/* Line 1806 of yacc.c */
-#line 605 "parser.y"
- { (yyval.expr) = ExprCreateUnary(EXPR_INVERT, (yyvsp[(2) - (2)].expr)->value_type, (yyvsp[(2) - (2)].expr)); }
+#line 645 "parser.y"
+ { (yyval.expr) = ExprCreateUnary(EXPR_INVERT, (yyvsp[(2) - (2)].expr)->expr.value_type, (yyvsp[(2) - (2)].expr)); }
break;
case 147:
/* Line 1806 of yacc.c */
-#line 607 "parser.y"
+#line 647 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 148:
/* Line 1806 of yacc.c */
-#line 609 "parser.y"
- { (yyval.expr) = ActionCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
+#line 649 "parser.y"
+ { (yyval.expr) = ExprCreateAction((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
break;
case 149:
/* Line 1806 of yacc.c */
-#line 611 "parser.y"
+#line 651 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 150:
/* Line 1806 of yacc.c */
-#line 613 "parser.y"
+#line 653 "parser.y"
{ (yyval.expr) = (yyvsp[(2) - (3)].expr); }
break;
case 151:
/* Line 1806 of yacc.c */
-#line 617 "parser.y"
+#line 657 "parser.y"
{ (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); }
break;
case 152:
/* Line 1806 of yacc.c */
-#line 619 "parser.y"
+#line 659 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 153:
/* Line 1806 of yacc.c */
-#line 623 "parser.y"
- { (yyval.expr) = ActionCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
+#line 663 "parser.y"
+ { (yyval.expr) = ExprCreateAction((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
break;
case 154:
/* Line 1806 of yacc.c */
-#line 627 "parser.y"
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_IDENT, EXPR_TYPE_UNKNOWN);
- expr->value.str = (yyvsp[(1) - (1)].sval);
- (yyval.expr) = expr;
- }
+#line 667 "parser.y"
+ { (yyval.expr) = ExprCreateIdent((yyvsp[(1) - (1)].sval)); }
break;
case 155:
/* Line 1806 of yacc.c */
-#line 634 "parser.y"
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_FIELD_REF, EXPR_TYPE_UNKNOWN);
- expr->value.field.element = (yyvsp[(1) - (3)].sval);
- expr->value.field.field = (yyvsp[(3) - (3)].sval);
- (yyval.expr) = expr;
- }
+#line 669 "parser.y"
+ { (yyval.expr) = ExprCreateFieldRef((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].sval)); }
break;
case 156:
/* Line 1806 of yacc.c */
-#line 642 "parser.y"
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
- expr->value.array.element = XKB_ATOM_NONE;
- expr->value.array.field = (yyvsp[(1) - (4)].sval);
- expr->value.array.entry = (yyvsp[(3) - (4)].expr);
- (yyval.expr) = expr;
- }
+#line 671 "parser.y"
+ { (yyval.expr) = ExprCreateArrayRef(XKB_ATOM_NONE, (yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
break;
case 157:
/* Line 1806 of yacc.c */
-#line 651 "parser.y"
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_ARRAY_REF, EXPR_TYPE_UNKNOWN);
- expr->value.array.element = (yyvsp[(1) - (6)].sval);
- expr->value.array.field = (yyvsp[(3) - (6)].sval);
- expr->value.array.entry = (yyvsp[(5) - (6)].expr);
- (yyval.expr) = expr;
- }
+#line 673 "parser.y"
+ { (yyval.expr) = ExprCreateArrayRef((yyvsp[(1) - (6)].sval), (yyvsp[(3) - (6)].sval), (yyvsp[(5) - (6)].expr)); }
break;
case 158:
/* Line 1806 of yacc.c */
-#line 662 "parser.y"
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_STRING);
- expr->value.str = (yyvsp[(1) - (1)].sval);
- (yyval.expr) = expr;
- }
+#line 677 "parser.y"
+ { (yyval.expr) = ExprCreateString((yyvsp[(1) - (1)].sval)); }
break;
case 159:
/* Line 1806 of yacc.c */
-#line 669 "parser.y"
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_INT);
- expr->value.ival = (yyvsp[(1) - (1)].ival);
- (yyval.expr) = expr;
- }
+#line 679 "parser.y"
+ { (yyval.expr) = ExprCreateInteger((yyvsp[(1) - (1)].ival)); }
break;
case 160:
/* Line 1806 of yacc.c */
-#line 676 "parser.y"
- {
- (yyval.expr) = NULL;
- }
+#line 681 "parser.y"
+ { (yyval.expr) = NULL; }
break;
case 161:
/* Line 1806 of yacc.c */
-#line 680 "parser.y"
- {
- ExprDef *expr;
- expr = ExprCreate(EXPR_VALUE, EXPR_TYPE_KEYNAME);
- expr->value.keyName = (yyvsp[(1) - (1)].sval);
- (yyval.expr) = expr;
- }
+#line 683 "parser.y"
+ { (yyval.expr) = ExprCreateKeyName((yyvsp[(1) - (1)].sval)); }
break;
case 162:
/* Line 1806 of yacc.c */
-#line 688 "parser.y"
+#line 686 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 163:
/* Line 1806 of yacc.c */
-#line 689 "parser.y"
+#line 687 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 164:
/* Line 1806 of yacc.c */
-#line 693 "parser.y"
- { (yyval.expr) = AppendKeysymList((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].str)); }
+#line 691 "parser.y"
+ { (yyval.expr) = ExprAppendKeysymList((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].keysym)); }
break;
case 165:
/* Line 1806 of yacc.c */
-#line 695 "parser.y"
- { (yyval.expr) = AppendMultiKeysymList((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
+#line 693 "parser.y"
+ { (yyval.expr) = ExprAppendMultiKeysymList((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 166:
/* Line 1806 of yacc.c */
-#line 697 "parser.y"
- { (yyval.expr) = CreateKeysymList((yyvsp[(1) - (1)].str)); }
+#line 695 "parser.y"
+ { (yyval.expr) = ExprCreateKeysymList((yyvsp[(1) - (1)].keysym)); }
break;
case 167:
/* Line 1806 of yacc.c */
-#line 699 "parser.y"
- { (yyval.expr) = CreateMultiKeysymList((yyvsp[(1) - (1)].expr)); }
+#line 697 "parser.y"
+ { (yyval.expr) = ExprCreateMultiKeysymList((yyvsp[(1) - (1)].expr)); }
break;
case 168:
/* Line 1806 of yacc.c */
-#line 703 "parser.y"
+#line 701 "parser.y"
{ (yyval.expr) = (yyvsp[(2) - (3)].expr); }
break;
case 169:
/* Line 1806 of yacc.c */
-#line 706 "parser.y"
- { (yyval.str) = (yyvsp[(1) - (1)].str); }
+#line 705 "parser.y"
+ {
+ if (!resolve_keysym((yyvsp[(1) - (1)].str), &(yyval.keysym)))
+ parser_warn(param, "unrecognized keysym");
+ free((yyvsp[(1) - (1)].str));
+ }
break;
case 170:
/* Line 1806 of yacc.c */
-#line 707 "parser.y"
- { (yyval.str) = strdup("section"); }
+#line 710 "parser.y"
+ { (yyval.keysym) = XKB_KEY_section; }
break;
case 171:
/* Line 1806 of yacc.c */
-#line 709 "parser.y"
+#line 712 "parser.y"
{
- if ((yyvsp[(1) - (1)].ival) < 10) { /* XK_0 .. XK_9 */
- (yyval.str) = malloc(2);
- (yyval.str)[0] = (yyvsp[(1) - (1)].ival) + '0';
- (yyval.str)[1] = '\0';
+ if ((yyvsp[(1) - (1)].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */
+ (yyval.keysym) = XKB_KEY_0 + (yyvsp[(1) - (1)].ival);
}
else {
- (yyval.str) = malloc(17);
- snprintf((yyval.str), 17, "0x%x", (yyvsp[(1) - (1)].ival));
+ char buf[17];
+ snprintf(buf, sizeof(buf), "0x%x", (yyvsp[(1) - (1)].ival));
+ if (!resolve_keysym(buf, &(yyval.keysym)))
+ parser_warn(param, "unrecognized keysym");
}
}
break;
@@ -3291,98 +3230,98 @@ yyreduce:
case 172:
/* Line 1806 of yacc.c */
-#line 722 "parser.y"
+#line 725 "parser.y"
{ (yyval.ival) = -(yyvsp[(2) - (2)].ival); }
break;
case 173:
/* Line 1806 of yacc.c */
-#line 723 "parser.y"
+#line 726 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].ival); }
break;
case 174:
/* Line 1806 of yacc.c */
-#line 726 "parser.y"
+#line 729 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].num); }
break;
case 175:
/* Line 1806 of yacc.c */
-#line 727 "parser.y"
+#line 730 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].num); }
break;
case 176:
/* Line 1806 of yacc.c */
-#line 730 "parser.y"
+#line 733 "parser.y"
{ (yyval.ival) = 0; }
break;
case 177:
/* Line 1806 of yacc.c */
-#line 733 "parser.y"
+#line 736 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].num); }
break;
case 178:
/* Line 1806 of yacc.c */
-#line 736 "parser.y"
+#line 739 "parser.y"
{ (yyval.num) = (yyvsp[(1) - (1)].num); }
break;
case 179:
/* Line 1806 of yacc.c */
-#line 739 "parser.y"
+#line 742 "parser.y"
{ (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); }
break;
case 180:
/* Line 1806 of yacc.c */
-#line 740 "parser.y"
- { (yyval.sval) = xkb_atom_intern(param->ctx, "default"); }
+#line 743 "parser.y"
+ { (yyval.sval) = xkb_atom_intern_literal(param->ctx, "default"); }
break;
case 181:
/* Line 1806 of yacc.c */
-#line 743 "parser.y"
+#line 746 "parser.y"
{ (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); }
break;
case 182:
/* Line 1806 of yacc.c */
-#line 746 "parser.y"
+#line 749 "parser.y"
{ (yyval.str) = (yyvsp[(1) - (1)].str); }
break;
case 183:
/* Line 1806 of yacc.c */
-#line 747 "parser.y"
+#line 750 "parser.y"
{ (yyval.str) = NULL; }
break;
case 184:
/* Line 1806 of yacc.c */
-#line 750 "parser.y"
+#line 753 "parser.y"
{ (yyval.str) = (yyvsp[(1) - (1)].str); }
break;
/* Line 1806 of yacc.c */
-#line 3386 "src/xkbcomp/parser.c"
+#line 3325 "src/xkbcomp/parser.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -3403,7 +3342,6 @@ yyreduce:
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
- *++yylsp = yyloc;
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
@@ -3433,7 +3371,7 @@ yyerrlab:
{
++yynerrs;
#if ! YYERROR_VERBOSE
- yyerror (&yylloc, param, YY_("syntax error"));
+ yyerror (param, YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
@@ -3460,7 +3398,7 @@ yyerrlab:
yymsgp = yymsg;
}
}
- yyerror (&yylloc, param, yymsgp);
+ yyerror (param, yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
@@ -3468,7 +3406,7 @@ yyerrlab:
#endif
}
- yyerror_range[1] = yylloc;
+
if (yyerrstatus == 3)
{
@@ -3484,7 +3422,7 @@ yyerrlab:
else
{
yydestruct ("Error: discarding",
- yytoken, &yylval, &yylloc, param);
+ yytoken, &yylval, param);
yychar = YYEMPTY;
}
}
@@ -3505,7 +3443,6 @@ yyerrorlab:
if (/*CONSTCOND*/ 0)
goto yyerrorlab;
- yyerror_range[1] = yylsp[1-yylen];
/* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */
YYPOPSTACK (yylen);
@@ -3539,9 +3476,9 @@ yyerrlab1:
if (yyssp == yyss)
YYABORT;
- yyerror_range[1] = *yylsp;
+
yydestruct ("Error: popping",
- yystos[yystate], yyvsp, yylsp, param);
+ yystos[yystate], yyvsp, param);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
@@ -3549,11 +3486,6 @@ yyerrlab1:
*++yyvsp = yylval;
- yyerror_range[2] = yylloc;
- /* Using YYLLOC is tempting, but would change the location of
- the lookahead. YYLOC is available though. */
- YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
- *++yylsp = yyloc;
/* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
@@ -3581,7 +3513,7 @@ yyabortlab:
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
- yyerror (&yylloc, param, YY_("memory exhausted"));
+ yyerror (param, YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
@@ -3593,7 +3525,7 @@ yyreturn:
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
yydestruct ("Cleanup: discarding lookahead",
- yytoken, &yylval, &yylloc, param);
+ yytoken, &yylval, param);
}
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
@@ -3602,7 +3534,7 @@ yyreturn:
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
- yystos[*yyssp], yyvsp, yylsp, param);
+ yystos[*yyssp], yyvsp, param);
YYPOPSTACK (1);
}
#ifndef yyoverflow
@@ -3620,7 +3552,7 @@ yyreturn:
/* Line 2067 of yacc.c */
-#line 753 "parser.y"
+#line 756 "parser.y"
#undef scanner
@@ -3628,12 +3560,12 @@ yyreturn:
XkbFile *
parse(struct xkb_context *ctx, void *scanner, const char *map)
{
- struct parser_param param;
int ret;
XkbFile *first = NULL;
-
- param.scanner = scanner;
- param.ctx = ctx;
+ struct parser_param param = {
+ .scanner = scanner,
+ .ctx = ctx,
+ };
/*
* If we got a specific map, we look for it exclusively and return
@@ -3672,3 +3604,5 @@ parse(struct xkb_context *ctx, void *scanner, const char *map)
return first;
}
+#define scanner param->scanner
+
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h
index fba3f4ebd0..f85a2bad85 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h
@@ -175,16 +175,16 @@ typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
-#line 127 "parser.y"
+#line 167 "parser.y"
int ival;
- unsigned uval;
int64_t num;
enum xkb_file_type file_type;
char *str;
xkb_atom_t sval;
enum merge_mode merge;
enum xkb_map_flags mapFlags;
+ xkb_keysym_t keysym;
ParseCommon *any;
ExprDef *expr;
VarDef *var;
@@ -213,18 +213,4 @@ typedef union YYSTYPE
-#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
-typedef struct YYLTYPE
-{
- int first_line;
- int first_column;
- int last_line;
- int last_column;
-} YYLTYPE;
-# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
-# define YYLTYPE_IS_DECLARED 1
-# define YYLTYPE_IS_TRIVIAL 1
-#endif
-
-
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
index 3f717600fd..de82d96119 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
@@ -47,16 +47,10 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include <ctype.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
#include "xkbcomp-priv.h"
#include "rules.h"
#include "include.h"
+#include "scanner-utils.h"
/*
* The rules file
@@ -138,25 +132,6 @@
/* Scanner / Lexer */
-/* Point to some substring in the file; used to avoid copying. */
-struct sval {
- const char *start;
- unsigned int len;
-};
-typedef darray(struct sval) darray_sval;
-
-static inline bool
-svaleq(struct sval s1, struct sval s2)
-{
- return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
-}
-
-static inline bool
-svaleq_prefix(struct sval s1, struct sval s2)
-{
- return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
-}
-
/* Values returned with some tokens, like yylval. */
union lvalue {
struct sval string;
@@ -170,15 +145,6 @@ struct location {
int line, column;
};
-struct scanner {
- const char *s;
- size_t pos;
- size_t len;
- int line, column;
- const char *file_name;
- struct xkb_context *ctx;
-};
-
enum rules_token {
TOK_END_OF_FILE = 0,
TOK_END_OF_LINE,
@@ -190,81 +156,20 @@ enum rules_token {
TOK_ERROR
};
-static void
-scanner_init(struct scanner *s, struct xkb_context *ctx,
- const char *string, size_t len, const char *file_name)
-{
- s->s = string;
- s->len = len;
- s->pos = 0;
- s->line = s->column = 1;
- s->file_name = file_name;
- s->ctx = ctx;
-}
-
/* C99 is stupid. Just use the 1 variant when there are no args. */
#define scanner_error1(scanner, loc, msg) \
- log_warn(scanner->ctx, "rules/%s:%d:%d: " msg "\n", \
- scanner->file_name, loc->line, loc->column)
+ log_warn((scanner)->ctx, "rules/%s:%d:%d: %s\n", \
+ (scanner)->file_name, (loc)->line, (loc)->column, msg)
#define scanner_error(scanner, loc, fmt, ...) \
- log_warn(scanner->ctx, "rules/%s:%d:%d: " fmt "\n", \
- scanner->file_name, loc->line, loc->column, __VA_ARGS__)
-
-static char
-peek(struct scanner *s)
-{
- return s->pos < s->len ? s->s[s->pos] : '\0';
-}
-
-static bool
-eof(struct scanner *s)
-{
- return peek(s) == '\0';
-}
-
-static bool
-eol(struct scanner *s)
-{
- return peek(s) == '\n';
-}
+ log_warn((scanner)->ctx, "rules/%s:%d:%d: " fmt "\n", \
+ (scanner)->file_name, (loc)->line, (loc)->column, __VA_ARGS__)
-static char
-next(struct scanner *s)
+static inline bool
+is_ident(char ch)
{
- if (eof(s))
- return '\0';
- if (eol(s)) {
- s->line++;
- s->column = 1;
- }
- else {
- s->column++;
- }
- return s->s[s->pos++];
+ return is_graph(ch) && ch != '\\';
}
-static bool
-chr(struct scanner *s, char ch)
-{
- if (peek(s) != ch)
- return false;
- s->pos++; s->column++;
- return true;
-}
-
-static bool
-str(struct scanner *s, const char *string, size_t len)
-{
- if (s->len - s->pos < len)
- return false;
- if (strncasecmp(s->s + s->pos, string, len) != 0)
- return false;
- s->pos += len; s->column += len;
- return true;
-}
-
-#define lit(s, literal) str(s, literal, sizeof(literal) - 1)
-
static enum rules_token
lex(struct scanner *s, union lvalue *val, struct location *loc)
{
@@ -310,7 +215,7 @@ skip_more_whitespace_and_comments:
if (chr(s, '$')) {
val->string.start = s->s + s->pos;
val->string.len = 0;
- while (isgraph(peek(s))) {
+ while (is_ident(peek(s))) {
next(s);
val->string.len++;
}
@@ -323,10 +228,10 @@ skip_more_whitespace_and_comments:
}
/* Identifier. */
- if (isgraph(peek(s))) {
+ if (is_ident(peek(s))) {
val->string.start = s->s + s->pos;
val->string.len = 0;
- while (isgraph(peek(s))) {
+ while (is_ident(peek(s))) {
next(s);
val->string.len++;
}
@@ -440,8 +345,8 @@ struct matcher {
static struct sval
strip_spaces(struct sval v)
{
- while (v.len > 0 && isspace(v.start[0])) { v.len--; v.start++; }
- while (v.len > 0 && isspace(v.start[v.len - 1])) v.len--;
+ while (v.len > 0 && is_space(v.start[0])) { v.len--; v.start++; }
+ while (v.len > 0 && is_space(v.start[v.len - 1])) v.len--;
return v;
}
@@ -449,7 +354,6 @@ static darray_sval
split_comma_separated_string(const char *s)
{
darray_sval arr = darray_new();
- struct sval val = { NULL, 0 };
/*
* Make sure the array returned by this function always includes at
@@ -457,12 +361,13 @@ split_comma_separated_string(const char *s)
*/
if (!s) {
+ struct sval val = { NULL, 0 };
darray_append(arr, val);
return arr;
}
while (true) {
- val.start = s; val.len = 0;
+ struct sval val = { s, 0 };
while (*s != '\0' && *s != ',') { s++; val.len++; }
darray_append(arr, strip_spaces(val));
if (*s == '\0') break;
@@ -482,7 +387,7 @@ matcher_new(struct xkb_context *ctx,
m->ctx = ctx;
m->rmlvo.model.start = rmlvo->model;
- m->rmlvo.model.len = rmlvo->model ? strlen(rmlvo->model) : 0;
+ m->rmlvo.model.len = strlen_safe(rmlvo->model);
m->rmlvo.layouts = split_comma_separated_string(rmlvo->layout);
m->rmlvo.variants = split_comma_separated_string(rmlvo->variant);
m->rmlvo.options = split_comma_separated_string(rmlvo->options);
@@ -505,15 +410,10 @@ matcher_free(struct matcher *m)
free(m);
}
-/* C99 is stupid. Just use the 1 variant when there are no args. */
#define matcher_error1(matcher, msg) \
- log_warn(matcher->ctx, "rules/%s:%d:%d: " msg "\n", \
- matcher->scanner.file_name, matcher->loc.line, \
- matcher->loc.column)
+ scanner_error1(&(matcher)->scanner, &(matcher)->loc, msg)
#define matcher_error(matcher, fmt, ...) \
- log_warn(matcher->ctx, "rules/%s:%d:%d: " fmt "\n", \
- matcher->scanner.file_name, matcher->loc.line, \
- matcher->loc.column, __VA_ARGS__)
+ scanner_error(&(matcher)->scanner, &(matcher)->loc, fmt, __VA_ARGS__)
static void
matcher_group_start_new(struct matcher *m, struct sval name)
@@ -532,10 +432,9 @@ matcher_group_add_element(struct matcher *m, struct sval element)
static void
matcher_mapping_start_new(struct matcher *m)
{
- unsigned int i;
- for (i = 0; i < _MLVO_NUM_ENTRIES; i++)
+ for (unsigned i = 0; i < _MLVO_NUM_ENTRIES; i++)
m->mapping.mlvo_at_pos[i] = -1;
- for (i = 0; i < _KCCGST_NUM_ENTRIES; i++)
+ for (unsigned i = 0; i < _KCCGST_NUM_ENTRIES; i++)
m->mapping.kccgst_at_pos[i] = -1;
m->mapping.layout_idx = m->mapping.variant_idx = XKB_LAYOUT_INVALID;
m->mapping.num_mlvo = m->mapping.num_kccgst = 0;
@@ -551,7 +450,7 @@ extract_layout_index(const char *s, size_t max_len, xkb_layout_index_t *out)
*out = XKB_LAYOUT_INVALID;
if (max_len < 3)
return -1;
- if (s[0] != '[' || !isdigit(s[1]) || s[2] != ']')
+ if (s[0] != '[' || !is_digit(s[1]) || s[2] != ']')
return -1;
if (s[1] - '0' < 1 || s[1] - '0' > XKB_MAX_GROUPS)
return -1;
@@ -565,8 +464,6 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
{
enum rules_mlvo mlvo;
struct sval mlvo_sval;
- xkb_layout_index_t idx;
- int consumed;
for (mlvo = 0; mlvo < _MLVO_NUM_ENTRIES; mlvo++) {
mlvo_sval = rules_mlvo_svals[mlvo];
@@ -596,8 +493,9 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
/* If there are leftovers still, it must be an index. */
if (mlvo_sval.len < ident.len) {
- consumed = extract_layout_index(ident.start + mlvo_sval.len,
- ident.len - mlvo_sval.len, &idx);
+ xkb_layout_index_t idx;
+ int consumed = extract_layout_index(ident.start + mlvo_sval.len,
+ ident.len - mlvo_sval.len, &idx);
if ((int) (ident.len - mlvo_sval.len) != consumed) {
matcher_error(m,
"invalid mapping:\" %.*s\" may only be followed by a valid group index; "
@@ -822,14 +720,8 @@ static bool
append_expanded_kccgst_value(struct matcher *m, darray_char *to,
struct sval value)
{
- unsigned int i;
- size_t original_size = darray_size(*to);
+ const size_t original_size = darray_size(*to);
const char *s = value.start;
- xkb_layout_index_t idx;
- int consumed;
- enum rules_mlvo mlv;
- struct sval expanded;
- char pfx, sfx;
/*
* Appending bar to foo -> foo (not an error if this happens)
@@ -847,7 +739,12 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
* Some ugly hand-lexing here, but going through the scanner is more
* trouble than it's worth, and the format is ugly on its own merit.
*/
- for (i = 0; i < value.len; ) {
+ for (unsigned i = 0; i < value.len; ) {
+ enum rules_mlvo mlv;
+ xkb_layout_index_t idx;
+ char pfx, sfx;
+ struct sval expanded;
+
/* Check if that's a start of an expansion. */
if (s[i] != '%') {
/* Just a normal character. */
@@ -876,22 +773,19 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
/* Check for index. */
idx = XKB_LAYOUT_INVALID;
- if (i < value.len) {
- if (s[i] == '[') {
- if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) {
- matcher_error1(m,
- "invalid index in %%-expansion; "
- "may only index layout or variant");
- goto error;
- }
-
- consumed = extract_layout_index(s + i, value.len - i, &idx);
- if (consumed == -1) goto error;
- i += consumed;
- }
- else {
- idx = XKB_LAYOUT_INVALID;
+ if (i < value.len && s[i] == '[') {
+ int consumed;
+
+ if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) {
+ matcher_error1(m,
+ "invalid index in %%-expansion; "
+ "may only index layout or variant");
+ goto error;
}
+
+ consumed = extract_layout_index(s + i, value.len - i, &idx);
+ if (consumed == -1) goto error;
+ i += consumed;
}
/* Check for suffix, if there supposed to be one. */
@@ -959,37 +853,31 @@ matcher_rule_verify(struct matcher *m)
static void
matcher_rule_apply_if_matches(struct matcher *m)
{
- unsigned int i;
- enum rules_mlvo mlvo;
- enum rules_kccgst kccgst;
- struct sval value, *option;
- enum mlvo_match_type match_type;
- bool matched = false;
- xkb_layout_index_t idx;
-
- for (i = 0; i < m->mapping.num_mlvo; i++) {
- mlvo = m->mapping.mlvo_at_pos[i];
- value = m->rule.mlvo_value_at_pos[i];
- match_type = m->rule.match_type_at_pos[i];
+ for (unsigned i = 0; i < m->mapping.num_mlvo; i++) {
+ enum rules_mlvo mlvo = m->mapping.mlvo_at_pos[i];
+ struct sval value = m->rule.mlvo_value_at_pos[i];
+ enum mlvo_match_type match_type = m->rule.match_type_at_pos[i];
+ bool matched = false;
if (mlvo == MLVO_MODEL) {
matched = match_value(m, value, m->rmlvo.model, match_type);
}
else if (mlvo == MLVO_LAYOUT) {
- idx = m->mapping.layout_idx;
+ xkb_layout_index_t idx = m->mapping.layout_idx;
idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx);
matched = match_value(m, value,
darray_item(m->rmlvo.layouts, idx),
match_type);
}
else if (mlvo == MLVO_VARIANT) {
- idx = m->mapping.layout_idx;
+ xkb_layout_index_t idx = m->mapping.layout_idx;
idx = (idx == XKB_LAYOUT_INVALID ? 0 : idx);
matched = match_value(m, value,
darray_item(m->rmlvo.variants, idx),
match_type);
}
else if (mlvo == MLVO_OPTION) {
+ struct sval *option;
darray_foreach(option, m->rmlvo.options) {
matched = match_value(m, value, *option, match_type);
if (matched)
@@ -1001,9 +889,9 @@ matcher_rule_apply_if_matches(struct matcher *m)
return;
}
- for (i = 0; i < m->mapping.num_kccgst; i++) {
- kccgst = m->mapping.kccgst_at_pos[i];
- value = m->rule.kccgst_value_at_pos[i];
+ for (unsigned i = 0; i < m->mapping.num_kccgst; i++) {
+ enum rules_kccgst kccgst = m->mapping.kccgst_at_pos[i];
+ struct sval value = m->rule.kccgst_value_at_pos[i];
append_expanded_kccgst_value(m, &m->kccgst[kccgst], value);
}
@@ -1193,36 +1081,27 @@ xkb_components_from_rules(struct xkb_context *ctx,
bool ret = false;
FILE *file;
char *path;
- int fd;
- struct stat stat_buf;
- char *string;
+ const char *string;
+ size_t size;
struct matcher *matcher;
file = FindFileInXkbPath(ctx, rmlvo->rules, FILE_TYPE_RULES, &path);
if (!file)
goto err_out;
- fd = fileno(file);
-
- if (fstat(fd, &stat_buf) != 0) {
- log_err(ctx, "Couldn't stat rules file\n");
- goto err_file;
- }
-
- string = mmap(NULL, stat_buf.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (string == MAP_FAILED) {
- log_err(ctx, "Couldn't mmap rules file (%lld bytes)\n",
- (long long) stat_buf.st_size);
+ ret = map_file(file, &string, &size);
+ if (!ret) {
+ log_err(ctx, "Couldn't read rules file: %s\n", strerror(errno));
goto err_file;
}
matcher = matcher_new(ctx, rmlvo);
- ret = matcher_match(matcher, string, stat_buf.st_size, rmlvo->rules, out);
+ ret = matcher_match(matcher, string, size, rmlvo->rules, out);
if (!ret)
log_err(ctx, "No components returned from XKB rules \"%s\"\n", path);
matcher_free(matcher);
- munmap(string, stat_buf.st_size);
+ unmap_file(string, size);
err_file:
free(path);
fclose(file);
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h b/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h
new file mode 100644
index 0000000000..7e21b00662
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
+ *
+ * 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 (including the next
+ * paragraph) 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 XKBCOMP_SCANNER_UTILS_H
+#define XKBCOMP_SCANNER_UTILS_H
+
+/* Point to some substring in the file; used to avoid copying. */
+struct sval {
+ const char *start;
+ unsigned int len;
+};
+typedef darray(struct sval) darray_sval;
+
+static inline bool
+svaleq(struct sval s1, struct sval s2)
+{
+ return s1.len == s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
+}
+
+static inline bool
+svaleq_prefix(struct sval s1, struct sval s2)
+{
+ return s1.len <= s2.len && strncmp(s1.start, s2.start, s1.len) == 0;
+}
+
+struct scanner {
+ const char *s;
+ size_t pos;
+ size_t len;
+ char buf[1024];
+ size_t buf_pos;
+ int line, column;
+ /* The line/column of the start of the current token. */
+ int token_line, token_column;
+ const char *file_name;
+ struct xkb_context *ctx;
+};
+
+static inline void
+scanner_init(struct scanner *s, struct xkb_context *ctx,
+ const char *string, size_t len, const char *file_name)
+{
+ s->s = string;
+ s->len = len;
+ s->pos = 0;
+ s->line = s->column = 1;
+ s->token_line = s->token_column = 1;
+ s->file_name = file_name;
+ s->ctx = ctx;
+}
+
+static inline char
+peek(struct scanner *s)
+{
+ return s->pos < s->len ? s->s[s->pos] : '\0';
+}
+
+static inline bool
+eof(struct scanner *s)
+{
+ return s->pos >= s->len;
+}
+
+static inline bool
+eol(struct scanner *s)
+{
+ return peek(s) == '\n';
+}
+
+static inline char
+next(struct scanner *s)
+{
+ if (eof(s))
+ return '\0';
+ if (eol(s)) {
+ s->line++;
+ s->column = 1;
+ }
+ else {
+ s->column++;
+ }
+ return s->s[s->pos++];
+}
+
+static inline bool
+chr(struct scanner *s, char ch)
+{
+ if (peek(s) != ch)
+ return false;
+ s->pos++; s->column++;
+ return true;
+}
+
+static inline bool
+str(struct scanner *s, const char *string, size_t len)
+{
+ if (s->len - s->pos < len)
+ return false;
+ if (strncasecmp(s->s + s->pos, string, len) != 0)
+ return false;
+ s->pos += len; s->column += len;
+ return true;
+}
+
+#define lit(s, literal) str(s, literal, sizeof(literal) - 1)
+
+static inline bool
+buf_append(struct scanner *s, char ch)
+{
+ if (s->buf_pos + 1 >= sizeof(s->buf))
+ return false;
+ s->buf[s->buf_pos++] = ch;
+ return true;
+}
+
+static inline bool
+oct(struct scanner *s, uint8_t *out)
+{
+ int i;
+ for (i = 0, *out = 0; peek(s) >= '0' && peek(s) <= '7' && i < 3; i++)
+ *out = *out * 8 + next(s) - '0';
+ return i > 0;
+}
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
index 4731107b85..48df488547 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
@@ -1,2861 +1,219 @@
-#line 2 "src/xkbcomp/scanner.c"
-
-#line 4 "src/xkbcomp/scanner.c"
-
-#define YY_INT_ALIGNED short int
-
-/* A lexical scanner generated by flex */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 35
-#if YY_FLEX_SUBMINOR_VERSION > 0
-#define FLEX_BETA
-#endif
-
-/* First, we deal with platform-specific or compiler-specific issues. */
-
-/* begin standard C headers. */
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-
-/* end standard C headers. */
-
-/* flex integer type definitions */
-
-#ifndef FLEXINT_H
-#define FLEXINT_H
-
-/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
-
-#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-
-/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
- * if you want the limit (max/min) macros for int types.
- */
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS 1
-#endif
-
-#include <inttypes.h>
-typedef int8_t flex_int8_t;
-typedef uint8_t flex_uint8_t;
-typedef int16_t flex_int16_t;
-typedef uint16_t flex_uint16_t;
-typedef int32_t flex_int32_t;
-typedef uint32_t flex_uint32_t;
-#else
-typedef signed char flex_int8_t;
-typedef short int flex_int16_t;
-typedef int flex_int32_t;
-typedef unsigned char flex_uint8_t;
-typedef unsigned short int flex_uint16_t;
-typedef unsigned int flex_uint32_t;
-
-/* Limits of integral types. */
-#ifndef INT8_MIN
-#define INT8_MIN (-128)
-#endif
-#ifndef INT16_MIN
-#define INT16_MIN (-32767-1)
-#endif
-#ifndef INT32_MIN
-#define INT32_MIN (-2147483647-1)
-#endif
-#ifndef INT8_MAX
-#define INT8_MAX (127)
-#endif
-#ifndef INT16_MAX
-#define INT16_MAX (32767)
-#endif
-#ifndef INT32_MAX
-#define INT32_MAX (2147483647)
-#endif
-#ifndef UINT8_MAX
-#define UINT8_MAX (255U)
-#endif
-#ifndef UINT16_MAX
-#define UINT16_MAX (65535U)
-#endif
-#ifndef UINT32_MAX
-#define UINT32_MAX (4294967295U)
-#endif
-
-#endif /* ! C99 */
-
-#endif /* ! FLEXINT_H */
-
-#ifdef __cplusplus
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-/* C99 requires __STDC__ to be defined as 1. */
-#if defined (__STDC__)
-
-#define YY_USE_CONST
-
-#endif /* defined (__STDC__) */
-#endif /* ! __cplusplus */
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* An opaque pointer. */
-#ifndef YY_TYPEDEF_YY_SCANNER_T
-#define YY_TYPEDEF_YY_SCANNER_T
-typedef void* yyscan_t;
-#endif
-
-/* For convenience, these vars (plus the bison vars far below)
- are macros in the reentrant scanner. */
-#define yyin yyg->yyin_r
-#define yyout yyg->yyout_r
-#define yyextra yyg->yyextra_r
-#define yyleng yyg->yyleng_r
-#define yytext yyg->yytext_r
-#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
-#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
-#define yy_flex_debug yyg->yy_flex_debug_r
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yyg->yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yyg->yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE _xkbcommon_restart(yyin ,yyscanner )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#ifndef YY_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k.
- * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
- * Ditto for the __ia64__ case accordingly.
- */
-#define YY_BUF_SIZE 32768
-#else
-#define YY_BUF_SIZE 16384
-#endif /* __ia64__ */
-#endif
-
-/* The state buf must be large enough to hold one state per character in the main buffer.
- */
-#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
-
-#ifndef YY_TYPEDEF_YY_BUFFER_STATE
-#define YY_TYPEDEF_YY_BUFFER_STATE
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-#endif
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
- /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
- * access to the local variable yy_act. Since yyless() is a macro, it would break
- * existing scanners that call yyless() from OUTSIDE _xkbcommon_lex.
- * One obvious solution it to make yy_act a global. I tried that, and saw
- * a 5% performance hit in a non-yylineno scanner, because yy_act is
- * normally declared as a register variable-- so it is not worth it.
- */
- #define YY_LESS_LINENO(n) \
- do { \
- int yyl;\
- for ( yyl = n; yyl < yyleng; ++yyl )\
- if ( yytext[yyl] == '\n' )\
- --yylineno;\
- }while(0)
-
-/* Return all but the first "n" matched characters back to the input stream. */
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- *yy_cp = yyg->yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
-
-#ifndef YY_TYPEDEF_YY_SIZE_T
-#define YY_TYPEDEF_YY_SIZE_T
-typedef size_t yy_size_t;
-#endif
-
-#ifndef YY_STRUCT_YY_BUFFER_STATE
-#define YY_STRUCT_YY_BUFFER_STATE
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- int yy_bs_lineno; /**< The line count. */
- int yy_bs_column; /**< The column count. */
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via _xkbcommon_restart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
-
- };
-#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
+/*
+ * Copyright © 2012 Ran Benita <ran234@gmail.com>
*
- * Returns the top of the stack, or NULL.
- */
-#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
- ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
- : NULL)
-
-/* Same as previous macro, but useful when we know that the buffer stack is not
- * NULL or when we need an lvalue. For internal use only.
- */
-#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
-
-void _xkbcommon_restart (FILE *input_file ,yyscan_t yyscanner );
-void _xkbcommon__switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-YY_BUFFER_STATE _xkbcommon__create_buffer (FILE *file,int size ,yyscan_t yyscanner );
-void _xkbcommon__delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void _xkbcommon__flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
-void _xkbcommon_push_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
-void _xkbcommon_pop_buffer_state (yyscan_t yyscanner );
-
-static void _xkbcommon_ensure_buffer_stack (yyscan_t yyscanner );
-static void _xkbcommon__load_buffer_state (yyscan_t yyscanner );
-static void _xkbcommon__init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
-
-#define YY_FLUSH_BUFFER _xkbcommon__flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
-
-YY_BUFFER_STATE _xkbcommon__scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
-YY_BUFFER_STATE _xkbcommon__scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
-YY_BUFFER_STATE _xkbcommon__scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
-
-void *_xkbcommon_alloc (yy_size_t ,yyscan_t yyscanner );
-void *_xkbcommon_realloc (void *,yy_size_t ,yyscan_t yyscanner );
-void _xkbcommon_free (void * ,yyscan_t yyscanner );
-
-#define yy_new_buffer _xkbcommon__create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! YY_CURRENT_BUFFER ){ \
- _xkbcommon_ensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! YY_CURRENT_BUFFER ){\
- _xkbcommon_ensure_buffer_stack (yyscanner); \
- YY_CURRENT_BUFFER_LVALUE = \
- _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
- } \
- YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
-
-/* Begin user sect3 */
-
-#define _xkbcommon_wrap(n) 1
-#define YY_SKIP_YYWRAP
-
-typedef unsigned char YY_CHAR;
-
-typedef int yy_state_type;
-
-#define yytext_ptr yytext_r
-
-static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
-static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
-static int yy_get_next_buffer (yyscan_t yyscanner );
-static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yyg->yytext_ptr = yy_bp; \
- yyleng = (size_t) (yy_cp - yy_bp); \
- yyg->yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yyg->yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 83
-#define YY_END_OF_BUFFER 84
-/* This struct is not used in this scanner,
- but its presence is necessary. */
-struct yy_trans_info
- {
- flex_int32_t yy_verify;
- flex_int32_t yy_nxt;
- };
-static yyconst flex_int16_t yy_accept[336] =
- { 0,
- 0, 0, 0, 0, 84, 82, 81, 81, 79, 3,
- 2, 72, 73, 69, 66, 77, 67, 76, 68, 63,
- 63, 78, 82, 65, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 74, 75, 70, 71, 80, 14, 83, 4, 14,
- 81, 2, 1, 0, 63, 0, 0, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 5, 6, 10, 13, 11, 7, 9, 8, 12,
- 1, 64, 62, 15, 61, 61, 61, 61, 61, 61,
-
- 61, 61, 61, 61, 61, 61, 39, 61, 61, 61,
- 61, 61, 61, 47, 61, 61, 61, 61, 61, 61,
- 61, 5, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 61, 48, 54, 61, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 51, 36, 61,
- 61, 5, 61, 40, 61, 61, 61, 61, 61, 41,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 46, 53, 61, 61, 61, 61,
- 61, 61, 61, 38, 61, 61, 61, 61, 61, 34,
- 61, 61, 61, 61, 61, 42, 61, 61, 61, 61,
-
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 29, 33, 61, 27, 61, 61, 61,
- 61, 43, 52, 50, 61, 32, 30, 49, 55, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 28, 61, 61, 61, 61, 61, 61,
- 61, 61, 61, 61, 31, 61, 45, 37, 61, 61,
- 61, 61, 61, 61, 61, 61, 61, 61, 18, 61,
- 61, 61, 61, 61, 61, 61, 20, 61, 61, 16,
- 26, 61, 61, 61, 61, 61, 58, 61, 61, 61,
- 61, 61, 61, 61, 61, 19, 61, 61, 61, 61,
-
- 44, 61, 61, 61, 24, 17, 61, 61, 61, 59,
- 57, 61, 61, 61, 25, 61, 61, 61, 61, 21,
- 61, 60, 61, 61, 61, 61, 61, 56, 35, 22,
- 61, 61, 61, 23, 0
- } ;
-
-static yyconst flex_int32_t yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 2, 1, 2, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 4, 5, 6, 1, 1, 1, 1, 7,
- 8, 9, 10, 11, 12, 13, 14, 15, 16, 16,
- 16, 16, 16, 16, 16, 17, 17, 1, 18, 19,
- 20, 21, 1, 1, 22, 23, 24, 25, 26, 27,
- 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
- 31, 38, 39, 40, 41, 42, 43, 44, 45, 31,
- 46, 47, 48, 1, 49, 1, 50, 51, 52, 53,
-
- 54, 55, 56, 57, 58, 31, 59, 60, 61, 62,
- 63, 64, 31, 65, 66, 67, 68, 69, 70, 71,
- 72, 31, 73, 1, 74, 75, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst flex_int32_t yy_meta[76] =
- { 0,
- 1, 1, 2, 1, 1, 1, 1, 1, 1, 3,
- 1, 3, 1, 1, 4, 4, 4, 1, 1, 1,
- 1, 4, 4, 4, 4, 4, 4, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 1, 1, 1, 5, 4,
- 4, 4, 4, 4, 4, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 1, 1, 1
- } ;
-
-static yyconst flex_int16_t yy_base[342] =
- { 0,
- 0, 0, 73, 74, 263, 695, 78, 80, 695, 695,
- 0, 695, 695, 695, 695, 695, 695, 695, 203, 71,
- 76, 695, 0, 695, 66, 0, 59, 54, 58, 67,
- 65, 75, 67, 68, 64, 86, 83, 109, 98, 81,
- 82, 695, 695, 695, 695, 695, 695, 695, 695, 158,
- 114, 0, 0, 132, 138, 0, 158, 0, 100, 128,
- 100, 123, 109, 124, 136, 166, 131, 141, 152, 140,
- 156, 150, 157, 156, 159, 179, 171, 164, 177, 178,
- 179, 221, 229, 695, 695, 695, 695, 695, 695, 695,
- 0, 232, 0, 695, 192, 202, 199, 206, 200, 217,
-
- 216, 201, 226, 220, 224, 229, 220, 222, 232, 231,
- 227, 230, 238, 0, 232, 236, 244, 236, 251, 247,
- 115, 279, 252, 250, 256, 263, 278, 266, 268, 272,
- 284, 271, 289, 279, 296, 0, 0, 292, 298, 288,
- 293, 292, 296, 305, 301, 307, 312, 0, 0, 288,
- 342, 347, 305, 0, 307, 310, 315, 320, 313, 0,
- 323, 335, 346, 336, 351, 348, 346, 357, 349, 364,
- 357, 367, 366, 356, 0, 0, 371, 359, 371, 373,
- 381, 379, 367, 0, 372, 394, 380, 383, 390, 0,
- 402, 390, 394, 113, 408, 0, 399, 411, 396, 413,
-
- 409, 417, 410, 413, 414, 413, 407, 409, 421, 424,
- 423, 427, 424, 0, 0, 432, 0, 434, 448, 445,
- 440, 0, 0, 0, 454, 0, 0, 0, 110, 446,
- 450, 462, 453, 468, 469, 467, 472, 473, 108, 457,
- 461, 477, 63, 0, 472, 485, 483, 476, 491, 474,
- 482, 483, 485, 487, 61, 497, 0, 0, 485, 500,
- 500, 498, 500, 518, 508, 507, 508, 516, 0, 520,
- 525, 528, 519, 529, 538, 537, 538, 526, 540, 0,
- 0, 539, 534, 546, 539, 534, 0, 535, 547, 556,
- 566, 558, 548, 556, 575, 0, 53, 565, 563, 564,
-
- 0, 578, 578, 587, 0, 0, 573, 581, 574, 0,
- 0, 580, 583, 581, 0, 595, 586, 598, 595, 0,
- 586, 0, 594, 594, 596, 602, 599, 0, 0, 49,
- 612, 604, 610, 0, 695, 674, 679, 682, 684, 689,
- 90
- } ;
-
-static yyconst flex_int16_t yy_def[342] =
- { 0,
- 335, 1, 336, 336, 335, 335, 335, 335, 335, 335,
- 337, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 338, 335, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 337, 340, 335, 335, 341, 338, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 340, 335, 341, 335, 339, 339, 339, 339, 339, 339,
-
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 335, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 335, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
-
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
-
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 339, 339, 339, 339, 339, 339,
- 339, 339, 339, 339, 0, 335, 335, 335, 335, 335,
- 335
- } ;
-
-static yyconst flex_int16_t yy_nxt[771] =
- { 0,
- 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 21, 22, 23, 24,
- 6, 25, 26, 26, 27, 26, 28, 29, 30, 31,
- 26, 32, 33, 34, 26, 35, 36, 37, 38, 39,
- 26, 40, 26, 41, 26, 42, 6, 43, 26, 25,
- 26, 26, 27, 26, 28, 29, 30, 31, 32, 33,
- 34, 26, 35, 36, 37, 38, 39, 26, 40, 26,
- 41, 26, 44, 45, 46, 48, 48, 49, 49, 51,
- 51, 51, 51, 54, 62, 55, 55, 55, 54, 59,
- 55, 55, 55, 93, 63, 64, 65, 331, 60, 66,
-
- 67, 308, 68, 69, 70, 71, 61, 72, 73, 271,
- 80, 260, 62, 81, 56, 51, 51, 59, 74, 50,
- 50, 63, 64, 78, 65, 60, 66, 99, 67, 68,
- 69, 70, 71, 61, 75, 72, 73, 76, 80, 95,
- 81, 56, 79, 101, 77, 74, 92, 92, 92, 100,
- 54, 78, 55, 55, 55, 99, 256, 96, 245, 102,
- 103, 220, 75, 151, 97, 76, 95, 98, 108, 79,
- 101, 77, 82, 82, 83, 107, 109, 100, 94, 110,
- 84, 111, 115, 85, 86, 96, 102, 112, 103, 104,
- 105, 97, 87, 113, 98, 88, 108, 89, 114, 90,
-
- 116, 121, 107, 117, 109, 106, 110, 118, 84, 111,
- 115, 85, 86, 119, 112, 120, 53, 104, 105, 87,
- 113, 123, 88, 124, 89, 114, 90, 125, 116, 121,
- 117, 126, 106, 127, 118, 122, 122, 83, 128, 129,
- 119, 130, 120, 83, 83, 83, 92, 92, 92, 123,
- 131, 124, 132, 133, 134, 125, 135, 137, 136, 126,
- 127, 138, 335, 141, 142, 139, 128, 129, 130, 143,
- 144, 145, 146, 147, 335, 148, 149, 155, 131, 132,
- 140, 133, 134, 135, 137, 136, 150, 153, 154, 138,
- 141, 142, 139, 152, 152, 83, 143, 144, 145, 146,
-
- 156, 147, 148, 157, 149, 155, 158, 159, 160, 161,
- 335, 162, 163, 150, 153, 154, 164, 165, 166, 167,
- 335, 168, 169, 335, 170, 172, 173, 156, 177, 171,
- 174, 157, 175, 158, 159, 160, 176, 161, 162, 184,
- 163, 185, 189, 164, 186, 165, 166, 167, 168, 187,
- 169, 170, 188, 172, 173, 177, 171, 190, 174, 191,
- 175, 83, 83, 83, 176, 178, 184, 192, 185, 179,
- 189, 186, 193, 180, 181, 194, 187, 195, 197, 188,
- 182, 183, 196, 198, 190, 199, 200, 191, 201, 202,
- 335, 203, 204, 178, 205, 192, 206, 179, 207, 193,
-
- 180, 181, 208, 194, 209, 195, 197, 182, 183, 196,
- 198, 211, 212, 199, 200, 213, 201, 202, 203, 214,
- 204, 205, 215, 210, 206, 216, 207, 217, 335, 218,
- 208, 219, 209, 221, 335, 222, 223, 225, 211, 212,
- 224, 226, 227, 213, 228, 229, 214, 230, 231, 215,
- 210, 232, 216, 233, 234, 217, 218, 235, 219, 236,
- 237, 221, 222, 238, 223, 225, 239, 224, 226, 240,
- 227, 228, 229, 241, 230, 231, 242, 243, 232, 244,
- 233, 234, 246, 247, 235, 248, 236, 237, 250, 251,
- 238, 252, 253, 239, 257, 249, 240, 254, 255, 335,
-
- 258, 241, 259, 242, 243, 261, 262, 244, 263, 246,
- 247, 264, 265, 248, 266, 250, 267, 251, 268, 252,
- 253, 257, 249, 269, 270, 254, 255, 258, 272, 273,
- 259, 274, 261, 275, 262, 276, 263, 277, 264, 278,
- 265, 266, 279, 267, 280, 268, 281, 282, 283, 284,
- 269, 270, 285, 286, 288, 272, 273, 287, 274, 289,
- 275, 290, 276, 293, 277, 294, 278, 291, 295, 297,
- 279, 280, 296, 281, 282, 283, 298, 284, 299, 300,
- 285, 286, 288, 301, 287, 302, 292, 289, 303, 290,
- 293, 304, 305, 294, 306, 291, 295, 297, 307, 296,
-
- 309, 310, 311, 298, 312, 299, 300, 313, 314, 318,
- 301, 315, 316, 302, 317, 319, 303, 320, 304, 305,
- 321, 306, 322, 323, 324, 333, 307, 309, 310, 311,
- 325, 326, 312, 327, 328, 313, 314, 318, 315, 316,
- 329, 317, 319, 330, 320, 332, 334, 335, 321, 322,
- 335, 323, 324, 333, 335, 335, 335, 325, 326, 335,
- 327, 328, 335, 335, 335, 335, 335, 329, 335, 335,
- 330, 335, 332, 334, 47, 47, 47, 47, 47, 52,
- 335, 52, 52, 52, 57, 57, 57, 58, 58, 91,
- 335, 91, 91, 91, 5, 335, 335, 335, 335, 335,
-
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335
- } ;
-
-static yyconst flex_int16_t yy_chk[771] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 3, 4, 3, 4, 7,
- 7, 8, 8, 20, 27, 20, 20, 20, 21, 25,
- 21, 21, 21, 341, 28, 29, 30, 330, 25, 31,
-
- 32, 297, 33, 34, 35, 35, 25, 36, 37, 255,
- 40, 243, 27, 41, 20, 51, 51, 25, 37, 3,
- 4, 28, 29, 39, 30, 25, 31, 61, 32, 33,
- 34, 35, 35, 25, 38, 36, 37, 38, 40, 59,
- 41, 20, 39, 63, 38, 37, 54, 54, 54, 62,
- 55, 39, 55, 55, 55, 61, 239, 60, 229, 64,
- 65, 194, 38, 121, 60, 38, 59, 60, 68, 39,
- 63, 38, 50, 50, 50, 67, 69, 62, 57, 70,
- 50, 71, 75, 50, 50, 60, 64, 72, 65, 66,
- 66, 60, 50, 73, 60, 50, 68, 50, 74, 50,
-
- 76, 81, 67, 77, 69, 66, 70, 78, 50, 71,
- 75, 50, 50, 79, 72, 80, 19, 66, 66, 50,
- 73, 95, 50, 96, 50, 74, 50, 97, 76, 81,
- 77, 98, 66, 99, 78, 82, 82, 82, 100, 101,
- 79, 102, 80, 83, 83, 83, 92, 92, 92, 95,
- 103, 96, 104, 105, 106, 97, 107, 108, 107, 98,
- 99, 109, 5, 110, 111, 109, 100, 101, 102, 112,
- 113, 115, 116, 117, 0, 118, 119, 125, 103, 104,
- 109, 105, 106, 107, 108, 107, 120, 123, 124, 109,
- 110, 111, 109, 122, 122, 122, 112, 113, 115, 116,
-
- 126, 117, 118, 127, 119, 125, 128, 129, 130, 131,
- 0, 132, 133, 120, 123, 124, 134, 135, 138, 139,
- 0, 140, 141, 0, 142, 143, 144, 126, 150, 142,
- 145, 127, 146, 128, 129, 130, 147, 131, 132, 153,
- 133, 155, 159, 134, 156, 135, 138, 139, 140, 157,
- 141, 142, 158, 143, 144, 150, 142, 161, 145, 162,
- 146, 152, 152, 152, 147, 151, 153, 163, 155, 151,
- 159, 156, 164, 151, 151, 165, 157, 166, 168, 158,
- 151, 151, 167, 169, 161, 170, 171, 162, 172, 173,
- 0, 174, 177, 151, 178, 163, 179, 151, 180, 164,
-
- 151, 151, 181, 165, 182, 166, 168, 151, 151, 167,
- 169, 183, 185, 170, 171, 186, 172, 173, 174, 187,
- 177, 178, 188, 182, 179, 189, 180, 191, 0, 192,
- 181, 193, 182, 195, 0, 197, 198, 200, 183, 185,
- 199, 201, 202, 186, 203, 204, 187, 205, 206, 188,
- 182, 207, 189, 208, 209, 191, 192, 210, 193, 211,
- 212, 195, 197, 213, 198, 200, 216, 199, 201, 218,
- 202, 203, 204, 219, 205, 206, 220, 221, 207, 225,
- 208, 209, 230, 231, 210, 232, 211, 212, 233, 234,
- 213, 235, 236, 216, 240, 232, 218, 237, 238, 0,
-
- 241, 219, 242, 220, 221, 245, 246, 225, 247, 230,
- 231, 248, 249, 232, 250, 233, 251, 234, 252, 235,
- 236, 240, 232, 253, 254, 237, 238, 241, 256, 259,
- 242, 260, 245, 260, 246, 261, 247, 262, 248, 263,
- 249, 250, 264, 251, 265, 252, 266, 267, 268, 270,
- 253, 254, 271, 272, 274, 256, 259, 273, 260, 275,
- 260, 276, 261, 278, 262, 279, 263, 277, 282, 284,
- 264, 265, 283, 266, 267, 268, 285, 270, 286, 288,
- 271, 272, 274, 289, 273, 290, 277, 275, 291, 276,
- 278, 292, 293, 279, 294, 277, 282, 284, 295, 283,
-
- 298, 299, 300, 285, 302, 286, 288, 303, 304, 312,
- 289, 307, 308, 290, 309, 313, 291, 314, 292, 293,
- 316, 294, 317, 318, 319, 332, 295, 298, 299, 300,
- 321, 323, 302, 324, 325, 303, 304, 312, 307, 308,
- 326, 309, 313, 327, 314, 331, 333, 0, 316, 317,
- 0, 318, 319, 332, 0, 0, 0, 321, 323, 0,
- 324, 325, 0, 0, 0, 0, 0, 326, 0, 0,
- 327, 0, 331, 333, 336, 336, 336, 336, 336, 337,
- 0, 337, 337, 337, 338, 338, 338, 339, 339, 340,
- 0, 340, 340, 340, 335, 335, 335, 335, 335, 335,
-
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335,
- 335, 335, 335, 335, 335, 335, 335, 335, 335, 335
- } ;
-
-/* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[84] =
- { 0,
-0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, };
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
+ * 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 (including the next
+ * paragraph) 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 REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-#line 1 "scanner.l"
-/************************************************************
- Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc.
-
- Permission to use, copy, modify, and distribute this
- software and its documentation for any purpose and without
- fee is hereby granted, provided that the above copyright
- notice appear in all copies and that both that copyright
- notice and this permission notice appear in supporting
- documentation, and that the name of Silicon Graphics not be
- used in advertising or publicity pertaining to distribution
- of the software without specific prior written permission.
- Silicon Graphics makes no representation about the suitability
- of this software for any purpose. It is provided "as is"
- without any express or implied warranty.
-
- SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
- GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
- THE USE OR PERFORMANCE OF THIS SOFTWARE.
- ********************************************************/
-#line 28 "scanner.l"
#include "xkbcomp-priv.h"
#include "parser-priv.h"
-
-#pragma GCC diagnostic ignored "-Wmissing-noreturn"
-#pragma GCC diagnostic ignored "-Wredundant-decls"
-#pragma GCC diagnostic push
-
-struct scanner_extra {
- struct xkb_context *ctx;
- const char *file_name;
- char scanBuf[1024];
- char *s;
-};
+#include "scanner-utils.h"
static void
-scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
- const char *msg);
-
-#define YY_USER_ACTION { \
- yylloc->first_line = yylineno; \
- yylloc->last_line = yylineno; \
-}
-
-#define APPEND_S(ch) do { \
- if (yyextra->s - yyextra->scanBuf >= sizeof(yyextra->scanBuf) - 1) \
- return ERROR_TOK; \
- *yyextra->s++ = ch; \
-} while (0)
-#define YY_NO_UNISTD_H 1
-#define YY_NO_INPUT 1
-
-#line 803 "src/xkbcomp/scanner.c"
-
-#define INITIAL 0
-#define S_STR 1
-
-#ifndef YY_NO_UNISTD_H
-/* Special case for "unistd.h", since it is non-ANSI. We include it way
- * down here because we want the user's section 1 to have been scanned first.
- * The user has a chance to override it with an option.
- */
-#include <unistd.h>
-#endif
-
-#define YY_EXTRA_TYPE struct scanner_extra *
-
-/* Holds the entire state of the reentrant scanner. */
-struct yyguts_t
- {
-
- /* User-defined. Not touched by flex. */
- YY_EXTRA_TYPE yyextra_r;
-
- /* The rest are the same as the globals declared in the non-reentrant scanner. */
- FILE *yyin_r, *yyout_r;
- size_t yy_buffer_stack_top; /**< index of top of stack. */
- size_t yy_buffer_stack_max; /**< capacity of stack. */
- YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
- char yy_hold_char;
- int yy_n_chars;
- int yyleng_r;
- char *yy_c_buf_p;
- int yy_init;
- int yy_start;
- int yy_did_buffer_switch_on_eof;
- int yy_start_stack_ptr;
- int yy_start_stack_depth;
- int *yy_start_stack;
- yy_state_type yy_last_accepting_state;
- char* yy_last_accepting_cpos;
-
- int yylineno_r;
- int yy_flex_debug_r;
-
- char *yytext_r;
- int yy_more_flag;
- int yy_more_len;
-
- YYSTYPE * yylval_r;
-
- YYLTYPE * yylloc_r;
-
- }; /* end struct yyguts_t */
-
-static int yy_init_globals (yyscan_t yyscanner );
-
- /* This must go here because YYSTYPE and YYLTYPE are included
- * from bison output in section 1.*/
- # define yylval yyg->yylval_r
-
- # define yylloc yyg->yylloc_r
-
-int _xkbcommon_lex_init (yyscan_t* scanner);
-
-int _xkbcommon_lex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
-
-/* Accessor methods to globals.
- These are made visible to non-reentrant scanners for convenience. */
-
-int _xkbcommon_lex_destroy (yyscan_t yyscanner );
-
-int _xkbcommon_get_debug (yyscan_t yyscanner );
-
-void _xkbcommon_set_debug (int debug_flag ,yyscan_t yyscanner );
-
-YY_EXTRA_TYPE _xkbcommon_get_extra (yyscan_t yyscanner );
-
-void _xkbcommon_set_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
-
-FILE *_xkbcommon_get_in (yyscan_t yyscanner );
-
-void _xkbcommon_set_in (FILE * in_str ,yyscan_t yyscanner );
-
-FILE *_xkbcommon_get_out (yyscan_t yyscanner );
-
-void _xkbcommon_set_out (FILE * out_str ,yyscan_t yyscanner );
-
-int _xkbcommon_get_leng (yyscan_t yyscanner );
-
-char *_xkbcommon_get_text (yyscan_t yyscanner );
-
-int _xkbcommon_get_lineno (yyscan_t yyscanner );
-
-void _xkbcommon_set_lineno (int line_number ,yyscan_t yyscanner );
-
-YYSTYPE * _xkbcommon_get_lval (yyscan_t yyscanner );
-
-void _xkbcommon_set_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
-
- YYLTYPE *_xkbcommon_get_lloc (yyscan_t yyscanner );
-
- void _xkbcommon_set_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int _xkbcommon_wrap (yyscan_t yyscanner );
-#else
-extern int _xkbcommon_wrap (yyscan_t yyscanner );
-#endif
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
-#endif
-
-#ifndef YY_NO_INPUT
-
-#ifdef __cplusplus
-static int yyinput (yyscan_t yyscanner );
-#else
-static int input (yyscan_t yyscanner );
-#endif
-
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#ifdef __ia64__
-/* On IA-64, the buffer size is 16k, not 8k */
-#define YY_READ_BUF_SIZE 16384
-#else
-#define YY_READ_BUF_SIZE 8192
-#endif /* __ia64__ */
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
- { \
- int c = '*'; \
- size_t n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else \
- { \
- errno=0; \
- while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
- { \
- if( errno != EINTR) \
- { \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- break; \
- } \
- errno=0; \
- clearerr(yyin); \
- } \
- }\
-\
-
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
-#endif
-
-/* end tables serialization structures and prototypes */
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL_IS_OURS 1
-
-extern int _xkbcommon_lex \
- (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
-
-#define YY_DECL int _xkbcommon_lex \
- (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
-#endif /* !YY_DECL */
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-/** The main scanner function which does all the work.
- */
-YY_DECL
-{
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
-#line 69 "scanner.l"
-
-
-#line 1049 "src/xkbcomp/scanner.c"
-
- yylval = yylval_param;
-
- yylloc = yylloc_param;
-
- if ( !yyg->yy_init )
- {
- yyg->yy_init = 1;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yyg->yy_start )
- yyg->yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! YY_CURRENT_BUFFER ) {
- _xkbcommon_ensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- _xkbcommon__load_buffer_state(yyscanner );
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = yyg->yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yyg->yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yyg->yy_start;
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 336 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_current_state != 335 );
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
-
- YY_DO_BEFORE_ACTION;
-
- if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
- {
- int yyl;
- for ( yyl = 0; yyl < yyleng; ++yyl )
- if ( yytext[yyl] == '\n' )
-
- do{ yylineno++;
- yycolumn=0;
- }while(0)
-;
- }
-
-do_action: /* This label is used only to access EOF actions. */
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yyg->yy_hold_char;
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 71 "scanner.l"
-
- YY_BREAK
-case 2:
-YY_RULE_SETUP
-#line 72 "scanner.l"
-
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 74 "scanner.l"
-yyextra->s = yyextra->scanBuf; BEGIN(S_STR);
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 76 "scanner.l"
-{
- BEGIN(INITIAL);
- *yyextra->s = '\0';
- yylval->str = strdup(yyextra->scanBuf);
- return STRING;
- }
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 83 "scanner.l"
-{
- /* octal escape sequence */
- unsigned int result;
-
- (void) sscanf( yytext + 1, "%o", &result );
-
- if (result > 0xff) {
- scanner_error_extra(yylloc, yyextra,
- "Illegal octal escape");
- return ERROR_TOK;
- }
-
- APPEND_S(result);
- }
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 98 "scanner.l"
-{
- scanner_error_extra(yylloc, yyextra,
- "Illegal octal escape");
- return ERROR_TOK;
- }
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 104 "scanner.l"
-APPEND_S('\n');
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 105 "scanner.l"
-APPEND_S('\t');
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 106 "scanner.l"
-APPEND_S('\r');
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 107 "scanner.l"
-APPEND_S('\b');
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 108 "scanner.l"
-APPEND_S('\f');
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 109 "scanner.l"
-APPEND_S('\v');
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 110 "scanner.l"
-APPEND_S('\033');
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 112 "scanner.l"
-APPEND_S(yytext[0]);
- YY_BREAK
-case 15:
-YY_RULE_SETUP
-#line 114 "scanner.l"
-{
- /* We don't want the brackets. */
- yytext[yyleng - 1] = '\0';
- yytext++;
- yylval->sval = xkb_atom_intern(yyextra->ctx, yytext);
- return KEYNAME;
- }
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 122 "scanner.l"
-return XKB_KEYMAP;
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 123 "scanner.l"
-return XKB_KEYCODES;
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 124 "scanner.l"
-return XKB_TYPES;
- YY_BREAK
-case 19:
-YY_RULE_SETUP
-#line 125 "scanner.l"
-return XKB_SYMBOLS;
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 126 "scanner.l"
-return XKB_COMPATMAP;
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 127 "scanner.l"
-return XKB_COMPATMAP;
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 128 "scanner.l"
-return XKB_COMPATMAP;
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 129 "scanner.l"
-return XKB_COMPATMAP;
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 130 "scanner.l"
-return XKB_GEOMETRY;
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 131 "scanner.l"
-return XKB_SEMANTICS;
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 132 "scanner.l"
-return XKB_LAYOUT;
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 133 "scanner.l"
-return INCLUDE;
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 134 "scanner.l"
-return OVERRIDE;
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 135 "scanner.l"
-return AUGMENT;
- YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 136 "scanner.l"
-return REPLACE;
- YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 137 "scanner.l"
-return ALTERNATE;
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 138 "scanner.l"
-return PARTIAL;
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-#line 139 "scanner.l"
-return DEFAULT;
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 140 "scanner.l"
-return HIDDEN;
- YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 141 "scanner.l"
-return VIRTUAL_MODS;
- YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 142 "scanner.l"
-return TYPE;
- YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 143 "scanner.l"
-return INTERPRET;
- YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 144 "scanner.l"
-return ACTION_TOK;
- YY_BREAK
-case 39:
-YY_RULE_SETUP
-#line 145 "scanner.l"
-return KEY;
- YY_BREAK
-case 40:
-YY_RULE_SETUP
-#line 146 "scanner.l"
-return ALIAS;
- YY_BREAK
-case 41:
-YY_RULE_SETUP
-#line 147 "scanner.l"
-return GROUP;
- YY_BREAK
-case 42:
-YY_RULE_SETUP
-#line 148 "scanner.l"
-return MODIFIER_MAP;
- YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 149 "scanner.l"
-return MODIFIER_MAP;
- YY_BREAK
-case 44:
-YY_RULE_SETUP
-#line 150 "scanner.l"
-return MODIFIER_MAP;
- YY_BREAK
-case 45:
-YY_RULE_SETUP
-#line 151 "scanner.l"
-return INDICATOR;
- YY_BREAK
-case 46:
-YY_RULE_SETUP
-#line 152 "scanner.l"
-return SHAPE;
- YY_BREAK
-case 47:
-YY_RULE_SETUP
-#line 153 "scanner.l"
-return ROW;
- YY_BREAK
-case 48:
-YY_RULE_SETUP
-#line 154 "scanner.l"
-return KEYS;
- YY_BREAK
-case 49:
-YY_RULE_SETUP
-#line 155 "scanner.l"
-return SECTION;
- YY_BREAK
-case 50:
-YY_RULE_SETUP
-#line 156 "scanner.l"
-return OVERLAY;
- YY_BREAK
-case 51:
-YY_RULE_SETUP
-#line 157 "scanner.l"
-return TEXT;
- YY_BREAK
-case 52:
-YY_RULE_SETUP
-#line 158 "scanner.l"
-return OUTLINE;
- YY_BREAK
-case 53:
-YY_RULE_SETUP
-#line 159 "scanner.l"
-return SOLID;
- YY_BREAK
-case 54:
-YY_RULE_SETUP
-#line 160 "scanner.l"
-return LOGO;
- YY_BREAK
-case 55:
-YY_RULE_SETUP
-#line 161 "scanner.l"
-return VIRTUAL;
- YY_BREAK
-case 56:
-YY_RULE_SETUP
-#line 162 "scanner.l"
-return ALPHANUMERIC_KEYS;
- YY_BREAK
-case 57:
-YY_RULE_SETUP
-#line 163 "scanner.l"
-return MODIFIER_KEYS;
- YY_BREAK
-case 58:
-YY_RULE_SETUP
-#line 164 "scanner.l"
-return KEYPAD_KEYS;
- YY_BREAK
-case 59:
-YY_RULE_SETUP
-#line 165 "scanner.l"
-return FUNCTION_KEYS;
- YY_BREAK
-case 60:
-YY_RULE_SETUP
-#line 166 "scanner.l"
-return ALTERNATE_GROUP;
- YY_BREAK
-case 61:
-YY_RULE_SETUP
-#line 168 "scanner.l"
-yylval->str = strdup(yytext); return IDENT;
- YY_BREAK
-case 62:
-#line 171 "scanner.l"
-case 63:
-YY_RULE_SETUP
-#line 171 "scanner.l"
-{
- char *end;
- yylval->num = strtoul(yytext, &end, 0);
-
- return INTEGER;
- }
- YY_BREAK
-case 64:
-YY_RULE_SETUP
-#line 177 "scanner.l"
-{
- char *end;
- yylval->num = strtod(yytext, &end);
-
- return FLOAT;
- }
- YY_BREAK
-case 65:
-YY_RULE_SETUP
-#line 184 "scanner.l"
-return EQUALS;
- YY_BREAK
-case 66:
-YY_RULE_SETUP
-#line 185 "scanner.l"
-return PLUS;
- YY_BREAK
-case 67:
-YY_RULE_SETUP
-#line 186 "scanner.l"
-return MINUS;
- YY_BREAK
-case 68:
-YY_RULE_SETUP
-#line 187 "scanner.l"
-return DIVIDE;
- YY_BREAK
-case 69:
-YY_RULE_SETUP
-#line 188 "scanner.l"
-return TIMES;
- YY_BREAK
-case 70:
-YY_RULE_SETUP
-#line 189 "scanner.l"
-return OBRACE;
- YY_BREAK
-case 71:
-YY_RULE_SETUP
-#line 190 "scanner.l"
-return CBRACE;
- YY_BREAK
-case 72:
-YY_RULE_SETUP
-#line 191 "scanner.l"
-return OPAREN;
- YY_BREAK
-case 73:
-YY_RULE_SETUP
-#line 192 "scanner.l"
-return CPAREN;
- YY_BREAK
-case 74:
-YY_RULE_SETUP
-#line 193 "scanner.l"
-return OBRACKET;
- YY_BREAK
-case 75:
-YY_RULE_SETUP
-#line 194 "scanner.l"
-return CBRACKET;
- YY_BREAK
-case 76:
-YY_RULE_SETUP
-#line 195 "scanner.l"
-return DOT;
- YY_BREAK
-case 77:
-YY_RULE_SETUP
-#line 196 "scanner.l"
-return COMMA;
- YY_BREAK
-case 78:
-YY_RULE_SETUP
-#line 197 "scanner.l"
-return SEMI;
- YY_BREAK
-case 79:
-YY_RULE_SETUP
-#line 198 "scanner.l"
-return EXCLAM;
- YY_BREAK
-case 80:
-YY_RULE_SETUP
-#line 199 "scanner.l"
-return INVERT;
- YY_BREAK
-case 81:
-/* rule 81 can match eol */
-YY_RULE_SETUP
-#line 201 "scanner.l"
-
- YY_BREAK
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(S_STR):
-#line 203 "scanner.l"
-return END_OF_FILE;
- YY_BREAK
-case 82:
-YY_RULE_SETUP
-#line 205 "scanner.l"
-return ERROR_TOK;
- YY_BREAK
-case 83:
-YY_RULE_SETUP
-#line 207 "scanner.l"
-ECHO;
- YY_BREAK
-#line 1600 "src/xkbcomp/scanner.c"
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yyg->yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * _xkbcommon_lex(). If so, then we have to assure
- * consistency between YY_CURRENT_BUFFER and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
-
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yyg->yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yyg->yy_last_accepting_cpos;
- yy_current_state = yyg->yy_last_accepting_state;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yyg->yy_did_buffer_switch_on_eof = 0;
-
- if ( _xkbcommon_wrap(yyscanner ) )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p =
- yyg->yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yyg->yy_c_buf_p =
- &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
-
- yy_current_state = yy_get_previous_state( yyscanner );
-
- yy_cp = yyg->yy_c_buf_p;
- yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
-} /* end of _xkbcommon_lex */
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-static int yy_get_next_buffer (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
- register char *source = yyg->yytext_ptr;
- register int number_to_move, i;
- int ret_val;
-
- if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
-
- int yy_c_buf_p_offset =
- (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- _xkbcommon_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
- number_to_move - 1;
-
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
- yyg->yy_n_chars, (size_t) num_to_read );
-
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- if ( yyg->yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- _xkbcommon_restart(yyin ,yyscanner);
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
- /* Extend the array by 50%, plus the number we really need. */
- yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) _xkbcommon_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
- if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
- }
-
- yyg->yy_n_chars += number_to_move;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
-
- return ret_val;
-}
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
- static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
-{
- register yy_state_type yy_current_state;
- register char *yy_cp;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- yy_current_state = yyg->yy_start;
-
- for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 336 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
-}
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
- static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
-{
- register int yy_is_jam;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
- register char *yy_cp = yyg->yy_c_buf_p;
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- yyg->yy_last_accepting_state = yy_current_state;
- yyg->yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 336 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 335);
-
- return yy_is_jam ? 0 : yy_current_state;
-}
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
- static int yyinput (yyscan_t yyscanner)
-#else
- static int input (yyscan_t yyscanner)
-#endif
-
-{
- int c;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
-
- if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
- /* This was really a NUL. */
- *yyg->yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
- ++yyg->yy_c_buf_p;
-
- switch ( yy_get_next_buffer( yyscanner ) )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- _xkbcommon_restart(yyin ,yyscanner);
-
- /*FALLTHROUGH*/
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( _xkbcommon_wrap(yyscanner ) )
- return EOF;
-
- if ( ! yyg->yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput(yyscanner);
-#else
- return input(yyscanner);
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
- *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
- yyg->yy_hold_char = *++yyg->yy_c_buf_p;
-
- if ( c == '\n' )
-
- do{ yylineno++;
- yycolumn=0;
- }while(0)
-;
-
- return c;
-}
-#endif /* ifndef YY_NO_INPUT */
-
-/** Immediately switch to a different input stream.
- * @param input_file A readable stream.
- * @param yyscanner The scanner object.
- * @note This function does not reset the start condition to @c INITIAL .
- */
- void _xkbcommon_restart (FILE * input_file , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! YY_CURRENT_BUFFER ){
- _xkbcommon_ensure_buffer_stack (yyscanner);
- YY_CURRENT_BUFFER_LVALUE =
- _xkbcommon__create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
- }
-
- _xkbcommon__init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
- _xkbcommon__load_buffer_state(yyscanner );
-}
-
-/** Switch to a different input buffer.
- * @param new_buffer The new input buffer.
- * @param yyscanner The scanner object.
- */
- void _xkbcommon__switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+scanner_log(enum xkb_log_level level, struct scanner *s, const char *msg)
{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* TODO. We should be able to replace this entire function body
- * with
- * _xkbcommon_pop_buffer_state();
- * _xkbcommon_push_buffer_state(new_buffer);
- */
- _xkbcommon_ensure_buffer_stack (yyscanner);
- if ( YY_CURRENT_BUFFER == new_buffer )
- return;
-
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
- _xkbcommon__load_buffer_state(yyscanner );
-
- /* We don't actually know whether we did this switch during
- * EOF (_xkbcommon_wrap()) processing, but the only time this flag
- * is looked at is after _xkbcommon_wrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yyg->yy_did_buffer_switch_on_eof = 1;
+ xkb_log(s->ctx, level, 0, "%s:%d:%d: %s\n", s->file_name,
+ s->token_line, s->token_column, msg);
}
-static void _xkbcommon__load_buffer_state (yyscan_t yyscanner)
+int
+scanner_error(struct scanner *s, const char *msg)
{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
- yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
- yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
- yyg->yy_hold_char = *yyg->yy_c_buf_p;
+ scanner_log(XKB_LOG_LEVEL_ERROR, s, msg);
+ return ERROR_TOK;
}
-/** Allocate and initialize an input buffer state.
- * @param file A readable stream.
- * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
- * @param yyscanner The scanner object.
- * @return the allocated buffer state.
- */
- YY_BUFFER_STATE _xkbcommon__create_buffer (FILE * file, int size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) _xkbcommon_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) _xkbcommon_alloc(b->yy_buf_size + 2 ,yyscanner );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- _xkbcommon__init_buffer(b,file ,yyscanner);
-
- return b;
-}
-
-/** Destroy the buffer.
- * @param b a buffer created with _xkbcommon__create_buffer()
- * @param yyscanner The scanner object.
- */
- void _xkbcommon__delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+void
+scanner_warn(struct scanner *s, const char *msg)
{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if ( ! b )
- return;
-
- if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
- YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- _xkbcommon_free((void *) b->yy_ch_buf ,yyscanner );
-
- _xkbcommon_free((void *) b ,yyscanner );
+ scanner_log(XKB_LOG_LEVEL_WARNING, s, msg);
}
-/* Initializes or reinitializes a buffer.
- * This function is sometimes called more than once on the same buffer,
- * such as during a _xkbcommon_restart() or at EOF.
- */
- static void _xkbcommon__init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
-
+static bool
+number(struct scanner *s, int64_t *out, int *out_tok)
{
- int oerrno = errno;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- _xkbcommon__flush_buffer(b ,yyscanner);
+ bool is_float = false, is_hex = false;
+ const char *start = s->s + s->pos;
+ char *end;
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
- /* If b is the current buffer, then _xkbcommon__init_buffer was _probably_
- * called from _xkbcommon_restart() or through yy_get_next_buffer.
- * In that case, we don't want to reset the lineno or column.
- */
- if (b != YY_CURRENT_BUFFER){
- b->yy_bs_lineno = 1;
- b->yy_bs_column = 0;
+ if (lit(s, "0x")) {
+ while (is_xdigit(peek(s))) next(s);
+ is_hex = true;
}
+ else {
+ while (is_digit(peek(s))) next(s);
+ is_float = chr(s, '.');
+ while (is_digit(peek(s))) next(s);
+ }
+ if (s->s + s->pos == start)
+ return false;
- b->yy_is_interactive = 0;
-
- errno = oerrno;
-}
-
-/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
- * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
- * @param yyscanner The scanner object.
- */
- void _xkbcommon__flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == YY_CURRENT_BUFFER )
- _xkbcommon__load_buffer_state(yyscanner );
-}
-
-/** Pushes the new state onto the stack. The new state becomes
- * the current state. This function will allocate the stack
- * if necessary.
- * @param new_buffer The new state.
- * @param yyscanner The scanner object.
- */
-void _xkbcommon_push_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (new_buffer == NULL)
- return;
-
- _xkbcommon_ensure_buffer_stack(yyscanner);
-
- /* This block is copied from _xkbcommon__switch_to_buffer. */
- if ( YY_CURRENT_BUFFER )
- {
- /* Flush out information for old buffer. */
- *yyg->yy_c_buf_p = yyg->yy_hold_char;
- YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
- YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
- }
-
- /* Only push if top exists. Otherwise, replace top. */
- if (YY_CURRENT_BUFFER)
- yyg->yy_buffer_stack_top++;
- YY_CURRENT_BUFFER_LVALUE = new_buffer;
-
- /* copied from _xkbcommon__switch_to_buffer. */
- _xkbcommon__load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
-}
-
-/** Removes and deletes the top of the stack, if present.
- * The next element becomes the new top.
- * @param yyscanner The scanner object.
- */
-void _xkbcommon_pop_buffer_state (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- if (!YY_CURRENT_BUFFER)
- return;
-
- _xkbcommon__delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
- YY_CURRENT_BUFFER_LVALUE = NULL;
- if (yyg->yy_buffer_stack_top > 0)
- --yyg->yy_buffer_stack_top;
-
- if (YY_CURRENT_BUFFER) {
- _xkbcommon__load_buffer_state(yyscanner );
- yyg->yy_did_buffer_switch_on_eof = 1;
- }
-}
-
-/* Allocates the stack if it does not exist.
- * Guarantees space for at least one push.
- */
-static void _xkbcommon_ensure_buffer_stack (yyscan_t yyscanner)
-{
- int num_to_alloc;
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (!yyg->yy_buffer_stack) {
-
- /* First allocation is just for 2 elements, since we don't know if this
- * scanner will even need a stack. We use 2 instead of 1 to avoid an
- * immediate realloc on the next call.
- */
- num_to_alloc = 1;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)_xkbcommon_alloc
- (num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
- if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon_ensure_buffer_stack()" );
-
- memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
-
- yyg->yy_buffer_stack_max = num_to_alloc;
- yyg->yy_buffer_stack_top = 0;
- return;
- }
-
- if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
-
- /* Increase the buffer to prepare for a possible push. */
- int grow_size = 8 /* arbitrary grow size */;
-
- num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
- yyg->yy_buffer_stack = (struct yy_buffer_state**)_xkbcommon_realloc
- (yyg->yy_buffer_stack,
- num_to_alloc * sizeof(struct yy_buffer_state*)
- , yyscanner);
- if ( ! yyg->yy_buffer_stack )
- YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon_ensure_buffer_stack()" );
-
- /* zero only the new slots.*/
- memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
- yyg->yy_buffer_stack_max = num_to_alloc;
- }
-}
-
-/** Setup the input buffer state to scan directly from a user-specified character buffer.
- * @param base the character buffer
- * @param size the size in bytes of the character buffer
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE _xkbcommon__scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) _xkbcommon_alloc(sizeof( struct yy_buffer_state ) ,yyscanner );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- _xkbcommon__switch_to_buffer(b ,yyscanner );
-
- return b;
-}
-
-/** Setup the input buffer state to scan a string. The next call to _xkbcommon_lex() will
- * scan from a @e copy of @a str.
- * @param yystr a NUL-terminated string to scan
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- * @note If you want to scan bytes that may contain NUL values, then use
- * _xkbcommon__scan_bytes() instead.
- */
-YY_BUFFER_STATE _xkbcommon__scan_string (yyconst char * yystr , yyscan_t yyscanner)
-{
-
- return _xkbcommon__scan_bytes(yystr,strlen(yystr) ,yyscanner);
-}
-
-/** Setup the input buffer state to scan the given bytes. The next call to _xkbcommon_lex() will
- * scan from a @e copy of @a bytes.
- * @param yybytes the byte buffer to scan
- * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
- * @param yyscanner The scanner object.
- * @return the newly allocated buffer state object.
- */
-YY_BUFFER_STATE _xkbcommon__scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
-{
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = _yybytes_len + 2;
- buf = (char *) _xkbcommon_alloc(n ,yyscanner );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in _xkbcommon__scan_bytes()" );
-
- for ( i = 0; i < _yybytes_len; ++i )
- buf[i] = yybytes[i];
-
- buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = _xkbcommon__scan_buffer(buf,n ,yyscanner);
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in _xkbcommon__scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
-}
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
-{
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
-}
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- int yyless_macro_arg = (n); \
- YY_LESS_LINENO(yyless_macro_arg);\
- yytext[yyleng] = yyg->yy_hold_char; \
- yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
- yyg->yy_hold_char = *yyg->yy_c_buf_p; \
- *yyg->yy_c_buf_p = '\0'; \
- yyleng = yyless_macro_arg; \
- } \
- while ( 0 )
-
-/* Accessor methods (get/set functions) to struct members. */
-
-/** Get the user-defined data for this scanner.
- * @param yyscanner The scanner object.
- */
-YY_EXTRA_TYPE _xkbcommon_get_extra (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyextra;
-}
-
-/** Get the current line number.
- * @param yyscanner The scanner object.
- */
-int _xkbcommon_get_lineno (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yylineno;
-}
-
-/** Get the current column number.
- * @param yyscanner The scanner object.
- */
-int _xkbcommon_get_column (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- if (! YY_CURRENT_BUFFER)
- return 0;
-
- return yycolumn;
-}
-
-/** Get the input stream.
- * @param yyscanner The scanner object.
- */
-FILE *_xkbcommon_get_in (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyin;
-}
-
-/** Get the output stream.
- * @param yyscanner The scanner object.
- */
-FILE *_xkbcommon_get_out (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyout;
-}
-
-/** Get the length of the current token.
- * @param yyscanner The scanner object.
- */
-int _xkbcommon_get_leng (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yyleng;
-}
-
-/** Get the current token.
- * @param yyscanner The scanner object.
- */
-
-char *_xkbcommon_get_text (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yytext;
-}
-
-/** Set the user-defined data. This data is never touched by the scanner.
- * @param user_defined The data to be associated with this scanner.
- * @param yyscanner The scanner object.
- */
-void _xkbcommon_set_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyextra = user_defined ;
-}
-
-/** Set the current line number.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void _xkbcommon_set_lineno (int line_number , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* lineno is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "_xkbcommon_set_lineno called with no buffer" , yyscanner);
-
- yylineno = line_number;
-}
-
-/** Set the current column.
- * @param line_number
- * @param yyscanner The scanner object.
- */
-void _xkbcommon_set_column (int column_no , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* column is only valid if an input buffer exists. */
- if (! YY_CURRENT_BUFFER )
- yy_fatal_error( "_xkbcommon_set_column called with no buffer" , yyscanner);
-
- yycolumn = column_no;
-}
-
-/** Set the input stream. This does not discard the current
- * input buffer.
- * @param in_str A readable stream.
- * @param yyscanner The scanner object.
- * @see _xkbcommon__switch_to_buffer
- */
-void _xkbcommon_set_in (FILE * in_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyin = in_str ;
-}
-
-void _xkbcommon_set_out (FILE * out_str , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yyout = out_str ;
-}
-
-int _xkbcommon_get_debug (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yy_flex_debug;
-}
-
-void _xkbcommon_set_debug (int bdebug , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yy_flex_debug = bdebug ;
-}
-
-/* Accessor methods for yylval and yylloc */
-
-YYSTYPE * _xkbcommon_get_lval (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yylval;
-}
-
-void _xkbcommon_set_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yylval = yylval_param;
+ errno = 0;
+ if (is_hex)
+ *out = strtoul(start, &end, 16);
+ else if (is_float)
+ *out = strtod(start, &end);
+ else
+ *out = strtoul(start, &end, 10);
+ if (errno != 0 || s->s + s->pos != end)
+ *out_tok = ERROR_TOK;
+ else
+ *out_tok = (is_float ? FLOAT : INTEGER);
+ return true;
}
-YYLTYPE *_xkbcommon_get_lloc (yyscan_t yyscanner)
+int
+_xkbcommon_lex(YYSTYPE *yylval, struct scanner *s)
{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- return yylloc;
-}
-
-void _xkbcommon_set_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- yylloc = yylloc_param;
-}
-
-/* User-visible API */
+ int tok;
-/* _xkbcommon_lex_init is special because it creates the scanner itself, so it is
- * the ONLY reentrant function that doesn't take the scanner as the last argument.
- * That's why we explicitly handle the declaration, instead of using our macros.
- */
-
-int _xkbcommon_lex_init(yyscan_t* ptr_yy_globals)
+skip_more_whitespace_and_comments:
+ /* Skip spaces. */
+ while (is_space(peek(s))) next(s);
-{
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
+ /* Skip comments. */
+ if (lit(s, "//") || chr(s, '#')) {
+ while (!eof(s) && !eol(s)) next(s);
+ goto skip_more_whitespace_and_comments;
}
- *ptr_yy_globals = (yyscan_t) _xkbcommon_alloc ( sizeof( struct yyguts_t ), NULL );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
+ /* See if we're done. */
+ if (eof(s)) return END_OF_FILE;
+
+ /* New token. */
+ s->token_line = s->line;
+ s->token_column = s->column;
+ s->buf_pos = 0;
+
+ /* String literal. */
+ if (chr(s, '\"')) {
+ while (!eof(s) && !eol(s) && peek(s) != '\"') {
+ if (chr(s, '\\')) {
+ uint8_t o;
+ if (chr(s, '\\')) buf_append(s, '\\');
+ else if (chr(s, 'n')) buf_append(s, '\n');
+ else if (chr(s, 't')) buf_append(s, '\t');
+ else if (chr(s, 'r')) buf_append(s, '\r');
+ else if (chr(s, 'b')) buf_append(s, '\b');
+ else if (chr(s, 'f')) buf_append(s, '\f');
+ else if (chr(s, 'v')) buf_append(s, '\v');
+ else if (chr(s, 'e')) buf_append(s, '\033');
+ else if (oct(s, &o)) buf_append(s, (char) o);
+ else {
+ scanner_warn(s, "unknown escape sequence in string literal");
+ /* Ignore. */
+ }
+ } else {
+ buf_append(s, next(s));
+ }
+ }
+ if (!buf_append(s, '\0') || !chr(s, '\"'))
+ return scanner_error(s, "unterminated string literal");
+ yylval->str = strdup(s->buf);
+ if (!yylval->str)
+ return scanner_error(s, "scanner out of memory");
+ return STRING;
}
- /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-/* _xkbcommon_lex_init_extra has the same functionality as _xkbcommon_lex_init, but follows the
- * convention of taking the scanner as the last argument. Note however, that
- * this is a *pointer* to a scanner, as it will be allocated by this call (and
- * is the reason, too, why this function also must handle its own declaration).
- * The user defined value in the first argument will be available to _xkbcommon_alloc in
- * the yyextra field.
- */
-
-int _xkbcommon_lex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
-
-{
- struct yyguts_t dummy_yyguts;
-
- _xkbcommon_set_extra (yy_user_defined, &dummy_yyguts);
-
- if (ptr_yy_globals == NULL){
- errno = EINVAL;
- return 1;
+ /* Key name literal. */
+ if (chr(s, '<')) {
+ while (is_graph(peek(s)) && peek(s) != '>')
+ buf_append(s, next(s));
+ if (!buf_append(s, '\0') || !chr(s, '>'))
+ return scanner_error(s, "unterminated key name literal");
+ /* Empty key name literals are allowed. */
+ yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1);
+ return KEYNAME;
}
-
- *ptr_yy_globals = (yyscan_t) _xkbcommon_alloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
-
- if (*ptr_yy_globals == NULL){
- errno = ENOMEM;
- return 1;
- }
-
- /* By setting to 0xAA, we expose bugs in
- yy_init_globals. Leave at 0x00 for releases. */
- memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
-
- _xkbcommon_set_extra (yy_user_defined, *ptr_yy_globals);
-
- return yy_init_globals ( *ptr_yy_globals );
-}
-
-static int yy_init_globals (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
- /* Initialization is the same as for the non-reentrant scanner.
- * This function is called from _xkbcommon_lex_destroy(), so don't allocate here.
- */
-
- yyg->yy_buffer_stack = 0;
- yyg->yy_buffer_stack_top = 0;
- yyg->yy_buffer_stack_max = 0;
- yyg->yy_c_buf_p = (char *) 0;
- yyg->yy_init = 0;
- yyg->yy_start = 0;
-
- yyg->yy_start_stack_ptr = 0;
- yyg->yy_start_stack_depth = 0;
- yyg->yy_start_stack = NULL;
-
-/* Defined in main.c */
-#ifdef YY_STDINIT
- yyin = stdin;
- yyout = stdout;
-#else
- yyin = (FILE *) 0;
- yyout = (FILE *) 0;
-#endif
-
- /* For future reference: Set errno on error, since we are called by
- * _xkbcommon_lex_init()
- */
- return 0;
-}
-
-/* _xkbcommon_lex_destroy is for both reentrant and non-reentrant scanners. */
-int _xkbcommon_lex_destroy (yyscan_t yyscanner)
-{
- struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
-
- /* Pop the buffer stack, destroying each element. */
- while(YY_CURRENT_BUFFER){
- _xkbcommon__delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
- YY_CURRENT_BUFFER_LVALUE = NULL;
- _xkbcommon_pop_buffer_state(yyscanner);
- }
-
- /* Destroy the stack itself. */
- _xkbcommon_free(yyg->yy_buffer_stack ,yyscanner);
- yyg->yy_buffer_stack = NULL;
-
- /* Destroy the start condition stack. */
- _xkbcommon_free(yyg->yy_start_stack ,yyscanner );
- yyg->yy_start_stack = NULL;
-
- /* Reset the globals. This is important in a non-reentrant scanner so the next time
- * _xkbcommon_lex() is called, initialization will occur. */
- yy_init_globals( yyscanner);
-
- /* Destroy the main struct (reentrant only). */
- _xkbcommon_free ( yyscanner , yyscanner );
- yyscanner = NULL;
- return 0;
-}
-/*
- * Internal utility routines.
- */
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
-{
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
-}
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
-{
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
-}
-#endif
-
-void *_xkbcommon_alloc (yy_size_t size , yyscan_t yyscanner)
-{
- return (void *) malloc( size );
-}
-
-void *_xkbcommon_realloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
-{
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
-}
-
-void _xkbcommon_free (void * ptr , yyscan_t yyscanner)
-{
- free( (char *) ptr ); /* see _xkbcommon_realloc() for (char *) cast */
-}
-
-#define YYTABLES_NAME "yytables"
-
-#line 207 "scanner.l"
-
-
-
-#pragma GCC diagnostic pop
-
-static void
-scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
- const char *msg)
-{
- log_err(extra->ctx, "%s: line %d of %s\n", msg,
- loc->first_line,
- extra->file_name ? extra->file_name : "(unknown)");
-}
-
-void
-scanner_error(struct YYLTYPE *loc, void *scanner, const char *msg)
-{
- struct scanner_extra *extra = _xkbcommon_get_extra(scanner);
- scanner_error_extra(loc, extra, msg);
-}
-
-static bool
-init_scanner(yyscan_t *scanner, struct scanner_extra *extra,
- struct xkb_context *ctx, const char *file_name)
-{
- memset(extra, 0, sizeof(*extra));
-
- if (_xkbcommon_lex_init_extra(extra,scanner) != 0)
- return false;
-
- extra->ctx = ctx;
- extra->file_name = file_name;
-
- return true;
-}
-
-static void
-clear_scanner(yyscan_t scanner)
-{
- _xkbcommon_lex_destroy(scanner);
-}
-
-XkbFile *
-XkbParseString(struct xkb_context *ctx, const char *string,
- const char *file_name)
-{
- yyscan_t scanner;
- struct scanner_extra extra;
- YY_BUFFER_STATE state;
- XkbFile *xkb_file;
-
- if (!init_scanner(&scanner, &extra, ctx, file_name))
- return NULL;
-
- state = _xkbcommon__scan_string(string,scanner);
-
- xkb_file = parse(ctx, scanner, NULL);
+ /* Operators and punctuation. */
+ if (chr(s, ';')) return SEMI;
+ if (chr(s, '{')) return OBRACE;
+ if (chr(s, '}')) return CBRACE;
+ if (chr(s, '=')) return EQUALS;
+ if (chr(s, '[')) return OBRACKET;
+ if (chr(s, ']')) return CBRACKET;
+ if (chr(s, '(')) return OPAREN;
+ if (chr(s, ')')) return CPAREN;
+ if (chr(s, '.')) return DOT;
+ if (chr(s, ',')) return COMMA;
+ if (chr(s, '+')) return PLUS;
+ if (chr(s, '-')) return MINUS;
+ if (chr(s, '*')) return TIMES;
+ if (chr(s, '/')) return DIVIDE;
+ if (chr(s, '!')) return EXCLAM;
+ if (chr(s, '~')) return INVERT;
+
+ /* Identifier. */
+ if (is_alpha(peek(s)) || peek(s) == '_') {
+ s->buf_pos = 0;
+ while (is_alnum(peek(s)) || peek(s) == '_')
+ buf_append(s, next(s));
+ if (!buf_append(s, '\0'))
+ return scanner_error(s, "identifier too long");
+
+ /* Keyword. */
+ tok = keyword_to_token(s->buf);
+ if (tok != -1) return tok;
+
+ yylval->str = strdup(s->buf);
+ if (!yylval->str)
+ return scanner_error(s, "scanner out of memory");
+ return IDENT;
+ }
- _xkbcommon__delete_buffer(state,scanner);
- clear_scanner(scanner);
+ /* Number literal (hexadecimal / decimal / float). */
+ if (number(s, &yylval->num, &tok)) {
+ if (tok == ERROR_TOK)
+ return scanner_error(s, "malformed number literal");
+ return tok;
+ }
- return xkb_file;
+ return scanner_error(s, "unrecognized token");
}
-/*
- * _xkbcommon__scan_buffer() requires the last two bytes of \buf to be 0. These two bytes
- * are not scanned. Other zero bytes in the buffer are scanned normally, though.
- * Due to these terminating zeroes, \length must be greater than 2.
- * Furthermore, the buffer must be writable and you cannot make any assumptions
- * about it after the scanner finished.
- * All this must be guaranteed by the caller of this function!
- */
XkbFile *
-XkbParseBuffer(struct xkb_context *ctx, char *buf, size_t length,
- const char *file_name)
+XkbParseString(struct xkb_context *ctx, const char *string, size_t len,
+ const char *file_name, const char *map)
{
- yyscan_t scanner;
- struct scanner_extra extra;
- YY_BUFFER_STATE state;
- XkbFile *xkb_file;
-
- if (!init_scanner(&scanner, &extra, ctx, file_name))
- return NULL;
-
- xkb_file = NULL;
- state = _xkbcommon__scan_buffer(buf,length,scanner);
- if (state) {
- xkb_file = parse(ctx, scanner, NULL);
- _xkbcommon__delete_buffer(state,scanner);
- }
-
- clear_scanner(scanner);
-
- return xkb_file;
+ struct scanner scanner;
+ scanner_init(&scanner, ctx, string, len, file_name);
+ return parse(ctx, &scanner, map);
}
XkbFile *
XkbParseFile(struct xkb_context *ctx, FILE *file,
const char *file_name, const char *map)
{
- yyscan_t scanner;
- struct scanner_extra extra;
- YY_BUFFER_STATE state;
+ bool ok;
XkbFile *xkb_file;
+ const char *string;
+ size_t size;
- if (!init_scanner(&scanner, &extra, ctx, file_name))
+ ok = map_file(file, &string, &size);
+ if (!ok) {
+ log_err(ctx, "Couldn't read XKB file %s: %s\n",
+ file_name, strerror(errno));
return NULL;
+ }
- state = _xkbcommon__create_buffer(file,YY_BUF_SIZE,scanner);
- _xkbcommon__switch_to_buffer(state,scanner);
-
- xkb_file = parse(ctx, scanner, map);
-
- _xkbcommon__delete_buffer(state,scanner);
- clear_scanner(scanner);
-
+ xkb_file = XkbParseString(ctx, string, size, file_name, map);
+ unmap_file(string, size);
return xkb_file;
}
-
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
index a2970f5004..56cce431da 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
@@ -143,7 +143,7 @@ InitKeyInfo(struct xkb_context *ctx, KeyInfo *keyi)
{
memset(keyi, 0, sizeof(*keyi));
keyi->merge = MERGE_OVERRIDE;
- keyi->name = xkb_atom_intern(ctx, "*");
+ keyi->name = xkb_atom_intern_literal(ctx, "*");
keyi->out_of_range_group_action = RANGE_WRAP;
}
@@ -177,7 +177,7 @@ typedef struct {
KeyInfo default_key;
ActionsInfo *actions;
darray(xkb_atom_t) group_names;
- darray(ModMapEntry) modMaps;
+ darray(ModMapEntry) modmaps;
struct xkb_keymap *keymap;
} SymbolsInfo;
@@ -203,7 +203,7 @@ ClearSymbolsInfo(SymbolsInfo *info)
ClearKeyInfo(keyi);
darray_free(info->keys);
darray_free(info->group_names);
- darray_free(info->modMaps);
+ darray_free(info->modmaps);
ClearKeyInfo(&info->default_key);
}
@@ -437,7 +437,7 @@ AddModMapEntry(SymbolsInfo *info, ModMapEntry *new)
ModMapEntry *old;
bool clobber = (new->merge != MERGE_AUGMENT);
- darray_foreach(old, info->modMaps) {
+ darray_foreach(old, info->modmaps) {
xkb_mod_index_t use, ignore;
if ((new->haveSymbol != old->haveSymbol) ||
@@ -470,7 +470,7 @@ AddModMapEntry(SymbolsInfo *info, ModMapEntry *new)
return true;
}
- darray_append(info->modMaps, *new);
+ darray_append(info->modmaps, *new);
return true;
}
@@ -517,7 +517,7 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
into->errorCount++;
}
- darray_foreach(mm, from->modMaps) {
+ darray_foreach(mm, from->modmaps) {
mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge);
if (!AddModMapEntry(into, mm))
into->errorCount++;
@@ -626,30 +626,6 @@ GetGroupIndex(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
return true;
}
-bool
-LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn)
-{
- xkb_keysym_t sym;
-
- if (!str || istreq(str, "any") || istreq(str, "nosymbol")) {
- *sym_rtrn = XKB_KEY_NoSymbol;
- return 1;
- }
-
- if (istreq(str, "none") || istreq(str, "voidsymbol")) {
- *sym_rtrn = XKB_KEY_VoidSymbol;
- return 1;
- }
-
- sym = xkb_keysym_from_name(str, 0);
- if (sym != XKB_KEY_NoSymbol) {
- *sym_rtrn = sym;
- return 1;
- }
-
- return 0;
-}
-
static bool
AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
ExprDef *value)
@@ -670,11 +646,11 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
return true;
}
- if (value->op != EXPR_KEYSYM_LIST) {
+ if (value->expr.op != EXPR_KEYSYM_LIST) {
log_err(info->keymap->ctx,
"Expected a list of symbols, found %s; "
"Ignoring symbols for group %u of %s\n",
- expr_op_type_to_string(value->op), ndx + 1,
+ expr_op_type_to_string(value->expr.op), ndx + 1,
KeyInfoText(info, keyi));
return false;
}
@@ -687,7 +663,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
return false;
}
- nLevels = darray_size(value->value.list.symsMapIndex);
+ nLevels = darray_size(value->keysym_list.symsMapIndex);
if (darray_size(groupi->levels) < nLevels)
darray_resize0(groupi->levels, nLevels);
@@ -697,34 +673,14 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
unsigned int sym_index;
struct xkb_level *leveli = &darray_item(groupi->levels, i);
- sym_index = darray_item(value->value.list.symsMapIndex, i);
- leveli->num_syms = darray_item(value->value.list.symsNumEntries, i);
+ sym_index = darray_item(value->keysym_list.symsMapIndex, i);
+ leveli->num_syms = darray_item(value->keysym_list.symsNumEntries, i);
if (leveli->num_syms > 1)
leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms));
for (j = 0; j < leveli->num_syms; j++) {
- char *sym_name = darray_item(value->value.list.syms,
- sym_index + j);
- xkb_keysym_t keysym;
-
- if (!LookupKeysym(sym_name, &keysym)) {
- const char *group_name = "unnamed";
-
- if (ndx < darray_size(info->group_names) &&
- darray_item(info->group_names, ndx))
- group_name = xkb_atom_text(info->keymap->ctx,
- darray_item(info->group_names,
- ndx));
-
- log_warn(info->keymap->ctx,
- "Could not resolve keysym %s for key %s, group %u (%s), level %u\n",
- sym_name, KeyInfoText(info, keyi), ndx + 1,
- group_name, i);
-
- ClearLevelInfo(leveli);
- leveli->num_syms = 0;
- break;
- }
+ xkb_keysym_t keysym = darray_item(value->keysym_list.syms,
+ sym_index + j);
if (leveli->num_syms == 1) {
if (keysym == XKB_KEY_NoSymbol)
@@ -750,7 +706,6 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
GroupInfo *groupi;
unsigned int nActs;
ExprDef *act;
- union xkb_action *toAct;
if (!GetGroupIndex(info, keyi, arrayNdx, ACTIONS, &ndx))
return false;
@@ -762,11 +717,11 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
return true;
}
- if (value->op != EXPR_ACTION_LIST) {
+ if (value->expr.op != EXPR_ACTION_LIST) {
log_wsgo(info->keymap->ctx,
"Bad expression type (%d) for action list value; "
"Ignoring actions for group %u of %s\n",
- value->op, ndx, KeyInfoText(info, keyi));
+ value->expr.op, ndx, KeyInfoText(info, keyi));
return false;
}
@@ -778,7 +733,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
}
nActs = 0;
- for (act = value->value.child; act; act = (ExprDef *) act->common.next)
+ for (act = value->unary.child; act; act = (ExprDef *) act->common.next)
nActs++;
if (darray_size(groupi->levels) < nActs)
@@ -786,9 +741,9 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
groupi->defined |= GROUP_FIELD_ACTS;
- act = value->value.child;
+ act = value->unary.child;
for (i = 0; i < nActs; i++) {
- toAct = &darray_item(groupi->levels, i).action;
+ union xkb_action *toAct = &darray_item(groupi->levels, i).action;
if (!HandleActionDef(act, info->keymap, toAct, info->actions))
log_err(info->keymap->ctx,
@@ -866,7 +821,7 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
log_err(info->keymap->ctx,
"Expected a virtual modifier mask, found %s; "
"Ignoring virtual modifiers definition for key %s\n",
- expr_op_type_to_string(value->op),
+ expr_op_type_to_string(value->expr.op),
KeyInfoText(info, keyi));
}
}
@@ -1082,7 +1037,7 @@ HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi)
ExprDef *arrayNdx;
for (; def; def = (VarDef *) def->common.next) {
- if (def->name && def->name->op == EXPR_FIELD_REF) {
+ if (def->name && def->name->expr.op == EXPR_FIELD_REF) {
log_err(info->keymap->ctx,
"Cannot set a global default value from within a key statement; "
"Move statements to the global file scope\n");
@@ -1090,7 +1045,7 @@ HandleSymbolsBody(SymbolsInfo *info, VarDef *def, KeyInfo *keyi)
}
if (!def->name) {
- if (!def->value || def->value->op == EXPR_KEYSYM_LIST)
+ if (!def->value || def->value->expr.op == EXPR_KEYSYM_LIST)
field = "symbols";
else
field = "actions";
@@ -1158,7 +1113,7 @@ HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt)
keyi.merge = stmt->merge;
keyi.name = stmt->keyName;
- if (!HandleSymbolsBody(info, (VarDef *) stmt->symbols, &keyi)) {
+ if (!HandleSymbolsBody(info, stmt->symbols, &keyi)) {
info->errorCount++;
return false;
}
@@ -1196,13 +1151,15 @@ HandleModMapDef(SymbolsInfo *info, ModMapDef *def)
ok = true;
tmp.modifier = ndx;
+ tmp.merge = def->merge;
for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) {
xkb_keysym_t sym;
- if (key->op == EXPR_VALUE && key->value_type == EXPR_TYPE_KEYNAME) {
+ if (key->expr.op == EXPR_VALUE &&
+ key->expr.value_type == EXPR_TYPE_KEYNAME) {
tmp.haveSymbol = false;
- tmp.u.keyName = key->value.keyName;
+ tmp.u.keyName = key->key_name.key_name;
}
else if (ExprResolveKeySym(ctx, key, &sym)) {
tmp.haveSymbol = true;
@@ -1248,7 +1205,7 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge)
break;
default:
log_err(info->keymap->ctx,
- "Interpretation files may not include other types; "
+ "Symbols files may not include other types; "
"Ignoring %s\n", stmt_type_to_string(stmt->type));
ok = false;
break;
@@ -1339,19 +1296,19 @@ FindAutomaticType(struct xkb_context *ctx, GroupInfo *groupi)
darray_item(groupi->levels, level).u.syms[0])
if (width == 1 || width <= 0)
- return xkb_atom_intern(ctx, "ONE_LEVEL");
+ return xkb_atom_intern_literal(ctx, "ONE_LEVEL");
sym0 = GET_SYM(0);
sym1 = GET_SYM(1);
if (width == 2) {
if (xkb_keysym_is_lower(sym0) && xkb_keysym_is_upper(sym1))
- return xkb_atom_intern(ctx, "ALPHABETIC");
+ return xkb_atom_intern_literal(ctx, "ALPHABETIC");
if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1))
- return xkb_atom_intern(ctx, "KEYPAD");
+ return xkb_atom_intern_literal(ctx, "KEYPAD");
- return xkb_atom_intern(ctx, "TWO_LEVEL");
+ return xkb_atom_intern_literal(ctx, "TWO_LEVEL");
}
if (width <= 4) {
@@ -1360,15 +1317,15 @@ FindAutomaticType(struct xkb_context *ctx, GroupInfo *groupi)
sym3 = (width == 4 ? GET_SYM(3) : XKB_KEY_NoSymbol);
if (xkb_keysym_is_lower(sym2) && xkb_keysym_is_upper(sym3))
- return xkb_atom_intern(ctx, "FOUR_LEVEL_ALPHABETIC");
+ return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_ALPHABETIC");
- return xkb_atom_intern(ctx, "FOUR_LEVEL_SEMIALPHABETIC");
+ return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_SEMIALPHABETIC");
}
if (xkb_keysym_is_keypad(sym0) || xkb_keysym_is_keypad(sym1))
- return xkb_atom_intern(ctx, "FOUR_LEVEL_KEYPAD");
+ return xkb_atom_intern_literal(ctx, "FOUR_LEVEL_KEYPAD");
- return xkb_atom_intern(ctx, "FOUR_LEVEL");
+ return xkb_atom_intern_literal(ctx, "FOUR_LEVEL");
}
return XKB_ATOM_NONE;
@@ -1570,9 +1527,9 @@ CopySymbolsToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info)
{
KeyInfo *keyi;
ModMapEntry *mm;
- struct xkb_key *key;
keymap->symbols_section_name = strdup_safe(info->name);
+ XkbEscapeMapName(keymap->symbols_section_name);
keymap->num_group_names = darray_size(info->group_names);
keymap->group_names = darray_mem(info->group_names, 0);
@@ -1583,6 +1540,8 @@ CopySymbolsToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info)
info->errorCount++;
if (xkb_context_get_log_verbosity(keymap->ctx) > 3) {
+ struct xkb_key *key;
+
xkb_foreach_key(key, keymap) {
if (key->name == XKB_ATOM_NONE)
continue;
@@ -1594,7 +1553,7 @@ CopySymbolsToKeymap(struct xkb_keymap *keymap, SymbolsInfo *info)
}
}
- darray_foreach(mm, info->modMaps)
+ darray_foreach(mm, info->modmaps)
if (!CopyModMapDef(info, mm))
info->errorCount++;
@@ -1618,9 +1577,6 @@ CompileSymbols(XkbFile *file, struct xkb_keymap *keymap,
HandleSymbolsFile(&info, file, merge);
- if (darray_empty(info.keys))
- goto err_info;
-
if (info.errorCount != 0)
goto err_info;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/types.c b/src/3rdparty/xkbcommon/src/xkbcomp/types.c
index 1eb1b73205..5b7ccbb4db 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/types.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/types.c
@@ -197,16 +197,6 @@ ReportTypeBadType(KeyTypesInfo *info, KeyTypeInfo *type,
TypeTxt(info, type), wanted);
}
-static inline bool
-ReportTypeBadWidth(KeyTypesInfo *info, const char *type, int has, int needs)
-{
- log_err(info->keymap->ctx,
- "Key type \"%s\" has %d levels, must have %d; "
- "Illegal type definition ignored\n",
- type, has, needs);
- return false;
-}
-
/***====================================================================***/
static void
@@ -775,6 +765,7 @@ static bool
CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
{
keymap->types_section_name = strdup_safe(info->name);
+ XkbEscapeMapName(keymap->types_section_name);
keymap->num_types = darray_size(info->types);
if (keymap->num_types == 0)
@@ -793,7 +784,7 @@ CopyKeyTypesToKeymap(struct xkb_keymap *keymap, KeyTypesInfo *info)
type->num_levels = 1;
type->entries = NULL;
type->num_entries = 0;
- type->name = xkb_atom_intern(keymap->ctx, "default");
+ type->name = xkb_atom_intern_literal(keymap->ctx, "default");
type->level_names = NULL;
return true;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h
index 4d421b5f2f..6cb774da17 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp-priv.h
@@ -45,12 +45,9 @@ XkbParseFile(struct xkb_context *ctx, FILE *file,
const char *file_name, const char *map);
XkbFile *
-XkbParseString(struct xkb_context *ctx, const char *string,
- const char *file_name);
-
-XkbFile *
-XkbParseBuffer(struct xkb_context *ctx, char *buf, size_t length,
- const char *file_name);
+XkbParseString(struct xkb_context *ctx,
+ const char *string, size_t len,
+ const char *file_name, const char *map);
void
FreeXkbFile(XkbFile *file);
@@ -79,9 +76,6 @@ bool
CompileKeymap(XkbFile *file, struct xkb_keymap *keymap,
enum merge_mode merge);
-bool
-LookupKeysym(const char *str, xkb_keysym_t *sym_rtrn);
-
/***====================================================================***/
static inline bool
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
index b9a1b5ffa6..007e3f73e8 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/xkbcomp.c
@@ -97,12 +97,13 @@ text_v1_keymap_new_from_names(struct xkb_keymap *keymap,
}
static bool
-text_v1_keymap_new_from_string(struct xkb_keymap *keymap, const char *string)
+text_v1_keymap_new_from_string(struct xkb_keymap *keymap,
+ const char *string, size_t len)
{
bool ok;
XkbFile *xkb_file;
- xkb_file = XkbParseString(keymap->ctx, string, "(input string)");
+ xkb_file = XkbParseString(keymap->ctx, string, len, "(input string)", NULL);
if (!xkb_file) {
log_err(keymap->ctx, "Failed to parse input xkb string\n");
return NULL;
@@ -114,38 +115,6 @@ text_v1_keymap_new_from_string(struct xkb_keymap *keymap, const char *string)
}
static bool
-text_v1_keymap_new_from_buffer(struct xkb_keymap *keymap,
- const char *buffer, size_t length)
-{
- bool ok;
- XkbFile *xkb_file;
- char *buf;
-
- buf = malloc(length + 2);
- if (!buf) {
- log_err(keymap->ctx, "Cannot allocate memory for keymap\n");
- return NULL;
- }
-
- /* yy_scan_buffer requires two terminating zero bytes */
- memcpy(buf, buffer, length);
- buf[length] = 0;
- buf[length + 1] = 0;
-
- xkb_file = XkbParseBuffer(keymap->ctx, buf, length + 2, "input");
- if (!xkb_file) {
- log_err(keymap->ctx, "Failed to parse input xkb file\n");
- free(buf);
- return NULL;
- }
-
- ok = compile_keymap_file(keymap, xkb_file);
- FreeXkbFile(xkb_file);
- free(buf);
- return ok;
-}
-
-static bool
text_v1_keymap_new_from_file(struct xkb_keymap *keymap, FILE *file)
{
bool ok;
@@ -165,7 +134,6 @@ text_v1_keymap_new_from_file(struct xkb_keymap *keymap, FILE *file)
const struct xkb_keymap_format_ops text_v1_keymap_format_ops = {
.keymap_new_from_names = text_v1_keymap_new_from_names,
.keymap_new_from_string = text_v1_keymap_new_from_string,
- .keymap_new_from_buffer = text_v1_keymap_new_from_buffer,
.keymap_new_from_file = text_v1_keymap_new_from_file,
.keymap_get_as_string = text_v1_keymap_get_as_string,
};
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h
index 253ea59ceb..69c582e45f 100644
--- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h
+++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-keysyms.h
@@ -418,6 +418,12 @@ SOFTWARE.
#define XKB_KEY_dead_belowcomma 0xfe6e
#define XKB_KEY_dead_currency 0xfe6f
+/* extra dead elements for German T3 layout */
+#define XKB_KEY_dead_lowline 0xfe90
+#define XKB_KEY_dead_aboveverticalline 0xfe91
+#define XKB_KEY_dead_belowverticalline 0xfe92
+#define XKB_KEY_dead_longsolidusoverlay 0xfe93
+
/* dead vowels for universal syllable entry */
#define XKB_KEY_dead_a 0xfe80
#define XKB_KEY_dead_A 0xfe81
@@ -2652,6 +2658,8 @@ SOFTWARE.
#define XKB_KEY_XF86TouchpadOn 0x1008FFB0 /* The touchpad got switched on */
#define XKB_KEY_XF86TouchpadOff 0x1008FFB1 /* The touchpad got switched off */
+#define XKB_KEY_XF86AudioMicMute 0x1008FFB2 /* Mute the Mic from the system */
+
/* Keys for special action keys (hot keys) */
/* Virtual terminals on some operating systems */
#define XKB_KEY_XF86Switch_VT_1 0x1008FE01
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h
index db071d8a2a..ecb551ff10 100644
--- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h
+++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-names.h
@@ -35,6 +35,7 @@
#define XKB_MOD_NAME_CAPS "Lock"
#define XKB_MOD_NAME_CTRL "Control"
#define XKB_MOD_NAME_ALT "Mod1"
+#define XKB_MOD_NAME_NUM "Mod2"
#define XKB_MOD_NAME_LOGO "Mod4"
#define XKB_LED_NAME_CAPS "Caps Lock"
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h
new file mode 100644
index 0000000000..4ec9b649c7
--- /dev/null
+++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright © 2013 Ran Benita
+ *
+ * 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 (including the next
+ * paragraph) 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 _XKBCOMMON_X11_H
+#define _XKBCOMMON_X11_H
+
+#include <xcb/xcb.h>
+#include <xkbcommon/xkbcommon.h>
+
+/**
+ * @file
+ * libxkbcommon-x11 API - Additional X11 support for xkbcommon.
+ */
+
+/**
+ * @defgroup x11 X11 support
+ * Additional X11 support for xkbcommon.
+ *
+ * @{
+ */
+
+/**
+ * The minimal compatible major version of the XKB X11 extension which
+ * this library can use.
+ */
+#define XKB_X11_MIN_MAJOR_XKB_VERSION 1
+/**
+ * The minimal compatible minor version of the XKB X11 extension which
+ * this library can use (for the minimal major version).
+ */
+#define XKB_X11_MIN_MINOR_XKB_VERSION 0
+
+/** Flags for the xkb_x11_setup_xkb_extension() function. */
+enum xkb_x11_setup_xkb_extension_flags {
+ /** Do not apply any flags. */
+ XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS = 0
+};
+
+/**
+ * Setup the XKB X11 extension for this X client.
+ *
+ * The xkbcommon-x11 library uses various XKB requests. Before doing so,
+ * an X client must notify the server that it will be using the extension.
+ * This function (or an XCB equivalent) must be called before any other
+ * function in this library is used.
+ *
+ * Some X servers may not support or disable the XKB extension. If you
+ * want to support such servers, you need to use a different fallback.
+ *
+ * You may call this function several times; it is idempotent.
+ *
+ * @param connection
+ * An XCB connection to the X server.
+ * @param major_xkb_version, minor_xkb_version
+ * The XKB extension version to request. To operate correctly, you
+ * must have (major_xkb_version, minor_xkb_version) >=
+ * (XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION),
+ * though this is not enforced.
+ * @param flags
+ * Optional flags, or 0.
+ * @param[out] major_xkb_version_out, minor_xkb_version_out
+ * Backfilled with the compatible XKB extension version numbers picked
+ * by the server. Can be NULL.
+ * @param[out] base_event_out
+ * Backfilled with the XKB base (also known as first) event code, needed
+ * to distinguish XKB events. Can be NULL.
+ * @param[out] base_error_out
+ * Backfilled with the XKB base (also known as first) error code, needed
+ * to distinguish XKB errors. Can be NULL.
+ *
+ * @returns 1 on success, or 0 on failure.
+ */
+int
+xkb_x11_setup_xkb_extension(xcb_connection_t *connection,
+ uint16_t major_xkb_version,
+ uint16_t minor_xkb_version,
+ enum xkb_x11_setup_xkb_extension_flags flags,
+ uint16_t *major_xkb_version_out,
+ uint16_t *minor_xkb_version_out,
+ uint8_t *base_event_out,
+ uint8_t *base_error_out);
+
+/**
+ * Get the keyboard device ID of the core X11 keyboard.
+ *
+ * @param connection An XCB connection to the X server.
+ *
+ * @returns A device ID which may be used with other xkb_x11_* functions,
+ * or -1 on failure.
+ */
+int32_t
+xkb_x11_get_core_keyboard_device_id(xcb_connection_t *connection);
+
+/**
+ * Create a keymap from an X11 keyboard device.
+ *
+ * This function queries the X server with various requests, fetches the
+ * details of the active keymap on a keyboard device, and creates an
+ * xkb_keymap from these details.
+ *
+ * @param context
+ * The context in which to create the keymap.
+ * @param connection
+ * An XCB connection to the X server.
+ * @param device_id
+ * An XInput 1 device ID (in the range 0-255) with input class KEY.
+ * Passing values outside of this range is an error.
+ * @param flags
+ * Optional flags for the keymap, or 0.
+ *
+ * @returns A keymap retrieved from the X server, or NULL on failure.
+ *
+ * @memberof xkb_keymap
+ */
+struct xkb_keymap *
+xkb_x11_keymap_new_from_device(struct xkb_context *context,
+ xcb_connection_t *connection,
+ int32_t device_id,
+ enum xkb_keymap_compile_flags flags);
+
+/**
+ * Create a new keyboard state object from an X11 keyboard device.
+ *
+ * This function is the same as xkb_state_new(), only pre-initialized
+ * with the state of the device at the time this function is called.
+ *
+ * @param keymap
+ * The keymap for which to create the state.
+ * @param connection
+ * An XCB connection to the X server.
+ * @param device_id
+ * An XInput 1 device ID (in the range 0-255) with input class KEY.
+ * Passing values outside of this range is an error.
+ *
+ * @returns A new keyboard state object, or NULL on failure.
+ *
+ * @memberof xkb_state
+ */
+struct xkb_state *
+xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
+ xcb_connection_t *connection,
+ int32_t device_id);
+
+/** @} */
+
+#endif
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
index a2aecfbb2a..cc9262ff89 100644
--- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
+++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
@@ -197,7 +197,7 @@ typedef uint32_t xkb_keysym_t;
* layout</em> is active. These may be different alphabets, different key
* arrangements, etc.
*
- * Layout indexes are consecutive. The first layout has index 0.
+ * Layout indices are consecutive. The first layout has index 0.
*
* Each layout is not required to have a name, and the names are not
* guaranteed to be unique (though they are usually provided and unique).
@@ -209,13 +209,20 @@ typedef uint32_t xkb_keysym_t;
* @sa xkb_keymap_num_layouts() xkb_keymap_num_layouts_for_key()
*/
typedef uint32_t xkb_layout_index_t;
-/** A mask of layout indexes. */
+/** A mask of layout indices. */
typedef uint32_t xkb_layout_mask_t;
/**
* Index of a shift level.
*
- * @todo Explain what are shift levels.
+ * Any key, in any layout, can have several <em>shift levels</em>. Each
+ * shift level can assign different keysyms to the key. The shift level
+ * to use is chosen according to the current keyboard state; for example,
+ * if no keys are pressed, the first level may be used; if the Left Shift
+ * key is pressed, the second; if Num Lock is pressed, the third; and
+ * many such combinations are possible (see xkb_mod_index_t).
+ *
+ * Level indices are consecutive. The first level has index 0.
*/
typedef uint32_t xkb_level_index_t;
@@ -233,7 +240,7 @@ typedef uint32_t xkb_level_index_t;
* consulted; this detemines the correct shift level to use within the
* currently active layout (see xkb_level_index_t).
*
- * Modifier indexes are consecutive. The first modifier has index 0.
+ * Modifier indices are consecutive. The first modifier has index 0.
*
* Each modifier must have a name, and the names are unique. Therefore, it
* is safe to use the name as a unique identifier for a modifier. The names
@@ -243,15 +250,17 @@ typedef uint32_t xkb_level_index_t;
* @sa xkb_keymap_num_mods()
*/
typedef uint32_t xkb_mod_index_t;
-/** A mask of modifier indexes. */
+/** A mask of modifier indices. */
typedef uint32_t xkb_mod_mask_t;
/**
* Index of a keyboard LED.
*
- * @todo Explain what are LEDs.
+ * LEDs are logical objects which may be @e active or @e inactive. They
+ * typically correspond to the lights on the keyboard. Their state is
+ * determined by the current keyboard state.
*
- * LED indexes are non-consecutive. The first LED has index 0.
+ * LED indices are non-consecutive. The first LED has index 0.
*
* Each LED must have a name, and the names are unique. Therefore,
* it is safe to use the name as a unique identifier for a LED. The names
@@ -261,7 +270,7 @@ typedef uint32_t xkb_mod_mask_t;
* @warning A given keymap may specify an exact index for a given LED.
* Therefore, LED indexing is not necessarily sequential, as opposed to
* modifiers and layouts. This means that when iterating over the LEDs
- * in a keymap using e.g. xkb_keymap_num_leds(), some indexes might be
+ * in a keymap using e.g. xkb_keymap_num_leds(), some indices might be
* invalid. Given such an index, functions like xkb_keymap_led_get_name()
* will return NULL, and xkb_state_led_index_is_active() will return -1.
*
@@ -270,7 +279,7 @@ typedef uint32_t xkb_mod_mask_t;
* @sa xkb_keymap_num_leds()
*/
typedef uint32_t xkb_led_index_t;
-/** A mask of LED indexes. */
+/** A mask of LED indices. */
typedef uint32_t xkb_led_mask_t;
#define XKB_KEYCODE_INVALID (0xffffffff)
@@ -351,6 +360,8 @@ xkb_keysym_get_name(xkb_keysym_t keysym, char *buffer, size_t size);
/** Flags for xkb_keysym_from_name(). */
enum xkb_keysym_flags {
+ /** Do not apply any flags. */
+ XKB_KEYSYM_NO_FLAGS = 0,
/** Find keysym by case-insensitive search. */
XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0)
};
@@ -416,6 +427,8 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym);
/** Flags for context creation. */
enum xkb_context_flags {
+ /** Do not apply any context flags. */
+ XKB_CONTEXT_NO_FLAGS = 0,
/** Create this context with an empty include path. */
XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
/** Don't take RMLVO names from the environment. */
@@ -667,6 +680,8 @@ xkb_context_set_log_fn(struct xkb_context *context,
/** Flags for keymap compilation. */
enum xkb_keymap_compile_flags {
+ /** Do not apply any flags. */
+ XKB_MAP_COMPILE_NO_FLAGS = 0,
/** Apparently you can't have empty enums. What a drag. */
XKB_MAP_COMPILE_PLACEHOLDER = 0
};
@@ -812,6 +827,46 @@ xkb_keymap_get_as_string(struct xkb_keymap *keymap,
*/
/**
+ * Get the minimum keycode in the keymap.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ */
+xkb_keycode_t
+xkb_keymap_min_keycode(struct xkb_keymap *keymap);
+
+/**
+ * Get the maximum keycode in the keymap.
+ *
+ * @sa xkb_keycode_t
+ * @memberof xkb_keymap
+ */
+xkb_keycode_t
+xkb_keymap_max_keycode(struct xkb_keymap *keymap);
+
+/**
+ * The iterator used by xkb_keymap_key_for_each().
+ *
+ * @sa xkb_keymap_key_for_each
+ * @memberof xkb_keymap
+ */
+typedef void
+(*xkb_keymap_key_iter_t)(struct xkb_keymap *keymap, xkb_keycode_t key,
+ void *data);
+
+/**
+ * Run a specified function for every valid keycode in the keymap. If a
+ * keymap is sparse, this function may be called fewer than
+ * (max_keycode - min_keycode + 1) times.
+ *
+ * @sa xkb_keymap_min_keycode() xkb_keymap_max_keycode() xkb_keycode_t
+ * @memberof xkb_keymap
+ */
+void
+xkb_keymap_key_for_each(struct xkb_keymap *keymap, xkb_keymap_key_iter_t iter,
+ void *data);
+
+/**
* Get the number of modifiers in the keymap.
*
* @sa xkb_mod_index_t
@@ -1001,9 +1056,9 @@ xkb_keymap_key_repeats(struct xkb_keymap *keymap, xkb_keycode_t key);
*/
/**
- * Create a new keyboard state object for a keymap.
+ * Create a new keyboard state object.
*
- * @param keymap The keymap for which to create the state.
+ * @param keymap The keymap which the state will use.
*
* @returns A new keyboard state object, or NULL on failure.
*
@@ -1033,10 +1088,10 @@ void
xkb_state_unref(struct xkb_state *state);
/**
- * Get the keymap from which a keyboard state object was created.
+ * Get the keymap which a keyboard state object is using.
*
- * @returns The keymap which was used in xkb_state_new() to create this
- * state object.
+ * @returns The keymap which was passed to xkb_state_new() when creating
+ * this state object.
*
* This function does not take a new reference on the keymap; you must
* explicitly reference it yourself if you plan to use it beyond the
@@ -1070,7 +1125,8 @@ enum xkb_state_component {
* lock has been pressed again. */
XKB_STATE_MODS_LOCKED = (1 << 2),
/** Effective modifiers, i.e. currently active and affect key
- * processing (derived from the other state components). */
+ * processing (derived from the other state components).
+ * Use this unless you explictly care how the state came about. */
XKB_STATE_MODS_EFFECTIVE = (1 << 3),
/** Depressed layout, i.e. a key is physically holding it. */
XKB_STATE_LAYOUT_DEPRESSED = (1 << 4),
@@ -1081,7 +1137,8 @@ enum xkb_state_component {
* has been pressed again. */
XKB_STATE_LAYOUT_LOCKED = (1 << 6),
/** Effective layout, i.e. currently active and affects key processing
- * (derived from the other state components). */
+ * (derived from the other state components).
+ * Use this unless you explictly care how the state came about. */
XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7),
/** LEDs (derived from the other state components). */
XKB_STATE_LEDS = (1 << 8)
@@ -1091,16 +1148,65 @@ enum xkb_state_component {
* Update the keyboard state to reflect a given key being pressed or
* released.
*
+ * This entry point is intended for programs which track the keyboard state
+ * explictly (like an evdev client). If the state is serialized to you by
+ * a master process (like a Wayland compositor) using functions like
+ * xkb_state_serialize_mods(), you should use xkb_state_update_mask() instead.
+ * The two functins should not generally be used together.
+ *
+ * A series of calls to this function should be consistent; that is, a call
+ * with XKB_KEY_DOWN for a key should be matched by an XKB_KEY_UP; if a key
+ * is pressed twice, it should be released twice; etc. Otherwise (e.g. due
+ * to missed input events), situations like "stuck modifiers" may occur.
+ *
* @returns A mask of state components that have changed as a result of
* the update. If nothing in the state has changed, returns 0.
*
* @memberof xkb_state
+ *
+ * @sa xkb_state_update_mask()
*/
enum xkb_state_component
xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
enum xkb_key_direction direction);
/**
+ * Update a keyboard state from a set of explicit masks.
+ *
+ * This entry point is intended for window systems and the like, where a
+ * master process holds an xkb_state, then serializes it over a wire
+ * protocol, and clients then use the serialization to feed in to their own
+ * xkb_state.
+ *
+ * All parameters must always be passed, or the resulting state may be
+ * incoherent.
+ *
+ * The serialization is lossy and will not survive round trips; it must only
+ * be used to feed slave state objects, and must not be used to update the
+ * master state.
+ *
+ * If you do not fit the description above, you should use
+ * xkb_state_update_key() instead. The two functions should not generally be
+ * used together.
+ *
+ * @returns A mask of state components that have changed as a result of
+ * the update. If nothing in the state has changed, returns 0.
+ *
+ * @memberof xkb_state
+ *
+ * @sa xkb_state_component
+ * @sa xkb_state_update_key
+ */
+enum xkb_state_component
+xkb_state_update_mask(struct xkb_state *state,
+ xkb_mod_mask_t depressed_mods,
+ xkb_mod_mask_t latched_mods,
+ xkb_mod_mask_t locked_mods,
+ xkb_layout_index_t depressed_layout,
+ xkb_layout_index_t latched_layout,
+ xkb_layout_index_t locked_layout);
+
+/**
* Get the keysyms obtained from pressing a particular key in a given
* keyboard state.
*
@@ -1114,8 +1220,9 @@ xkb_state_update_key(struct xkb_state *state, xkb_keycode_t key,
* key in the given keyboard state.
*
* As an extension to XKB, this function can return more than one keysym.
- * If you do not want to handle this case, you can use
- * xkb_state_key_get_one_sym().
+ * If you do not want to handle this case, you should use
+ * xkb_state_key_get_one_sym(), which additionally performs transformations
+ * which are specific to the one-keysym case.
*
* @returns The number of keysyms in the syms_out array. If no keysyms
* are produced by the key in the given keyboard state, returns 0 and sets
@@ -1131,9 +1238,10 @@ xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key,
* Get the single keysym obtained from pressing a particular key in a
* given keyboard state.
*
- * This function is similar to xkb_state_key_get_syms(), but with a
- * simplified interface for users which cannot or do not want to handle
- * the case where multiple keysyms are returned.
+ * This function is similar to xkb_state_key_get_syms(), but intended
+ * for users which cannot or do not want to handle the case where
+ * multiple keysyms are returned (in which case this function is
+ * preferred).
*
* @returns The keysym. If the key does not have exactly one keysym,
* returns XKB_KEY_NoSymbol
@@ -1204,39 +1312,6 @@ enum xkb_state_match {
};
/**
- * Update a keyboard state from a set of explicit masks.
- *
- * This entry point is really only for window systems and the like, where a
- * master process holds an xkb_state, then serializes it over a wire
- * protocol, and clients then use the serialization to feed in to their own
- * xkb_state.
- *
- * All parameters must always be passed, or the resulting state may be
- * incoherent.
- *
- * The serialization is lossy and will not survive round trips; it must only
- * be used to feed slave state objects, and must not be used to update the
- * master state.
- *
- * Please do not use this unless you fit the description above.
- *
- * @returns A mask of state components that have changed as a result of
- * the update. If nothing in the state has changed, returns 0.
- *
- * @memberof xkb_state
- *
- * @sa xkb_state_component
- */
-enum xkb_state_component
-xkb_state_update_mask(struct xkb_state *state,
- xkb_mod_mask_t depressed_mods,
- xkb_mod_mask_t latched_mods,
- xkb_mod_mask_t locked_mods,
- xkb_layout_index_t depressed_layout,
- xkb_layout_index_t latched_layout,
- xkb_layout_index_t locked_layout);
-
-/**
* The counterpart to xkb_state_update_mask for modifiers, to be used on
* the server side of serialization.
*
@@ -1336,11 +1411,11 @@ xkb_state_mod_index_is_active(struct xkb_state *state, xkb_mod_index_t idx,
* given modifiers.
* @param match The manner by which to match the state against the
* given modifiers.
- * @param ... The set of of modifier indexes to test, terminated by a
+ * @param ... The set of of modifier indices to test, terminated by a
* XKB_MOD_INVALID argument (sentinel).
*
* @returns 1 if the modifiers are active, 0 if they are not. If any of
- * the modifier indexes are invalid in the keymap, returns -1.
+ * the modifier indices are invalid in the keymap, returns -1.
*
* @memberof xkb_state
*/
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon_workaround.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon_workaround.h
deleted file mode 100644
index 58ce143978..0000000000
--- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon_workaround.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef XKBCOMMON_WORKAROUND_H
-#define XKBCOMMON_WORKAROUND_H
-
-// Function utf32_to_utf8() is borrowed from the libxkbcommon library,
-// file keysym-utf.c. The workaround should be removed once the fix from
-// https://bugs.freedesktop.org/show_bug.cgi?id=56780 gets released.
-static int utf32_to_utf8(uint32_t unichar, char *buffer)
-{
- int count, shift, length;
- uint8_t head;
-
- if (unichar <= 0x007f) {
- buffer[0] = unichar;
- buffer[1] = '\0';
- return 2;
- }
- else if (unichar <= 0x07FF) {
- length = 2;
- head = 0xc0;
- }
- else if (unichar <= 0xffff) {
- length = 3;
- head = 0xe0;
- }
- else if (unichar <= 0x1fffff) {
- length = 4;
- head = 0xf0;
- }
- else if (unichar <= 0x3ffffff) {
- length = 5;
- head = 0xf8;
- }
- else {
- length = 6;
- head = 0xfc;
- }
-
- for (count = length - 1, shift = 0; count > 0; count--, shift += 6)
- buffer[count] = 0x80 | ((unichar >> shift) & 0x3f);
-
- buffer[0] = head | ((unichar >> shift) & 0x3f);
- buffer[length] = '\0';
-
- return length + 1;
-}
-
-static bool needWorkaround(uint32_t sym)
-{
- /* patch encoding botch */
- if (sym == XKB_KEY_KP_Space)
- return true;
-
- /* special keysyms */
- if ((sym >= XKB_KEY_BackSpace && sym <= XKB_KEY_Clear) ||
- (sym >= XKB_KEY_KP_Multiply && sym <= XKB_KEY_KP_9) ||
- sym == XKB_KEY_Return || sym == XKB_KEY_Escape ||
- sym == XKB_KEY_Delete || sym == XKB_KEY_KP_Tab ||
- sym == XKB_KEY_KP_Enter || sym == XKB_KEY_KP_Equal)
- return true;
-
- return false;
-}
-
-#endif // XKBCOMMON_WORKAROUND_H
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 aa18dfc2d1..ea8e5cd44c 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -301,6 +301,8 @@ public class QtActivityDelegate
protected void onReceiveResult(int resultCode, Bundle resultData) {
switch (resultCode) {
case InputMethodManager.RESULT_SHOWN:
+ QtNativeInputConnection.updateCursorPosition();
+ //FALLTHROUGH
case InputMethodManager.RESULT_UNCHANGED_SHOWN:
setKeyboardVisibility(true);
break;
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java b/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java
index 4b2d50ca1f..5e6e227c2b 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java
@@ -78,6 +78,7 @@ class QtNativeInputConnection
static native boolean copy();
static native boolean copyURL();
static native boolean paste();
+ static native boolean updateCursorPosition();
}
class HideKeyboardRunnable implements Runnable {
@@ -127,7 +128,7 @@ public class QtInputConnection extends BaseInputConnection
if (closing && m_inputState == InputStates.Hiding)
return;
- if (closing && m_inputState == InputStates.FinishComposing && m_view.getActivityDelegate().isSoftwareKeyboardVisible()) {
+ if (closing && m_view.getActivityDelegate().isSoftwareKeyboardVisible()) {
m_view.postDelayed(new HideKeyboardRunnable(this), 100);
m_inputState = InputStates.Hiding;
} else {
diff --git a/src/android/java/java.pro b/src/android/java/java.pro
index 9d682e4f23..cff2d55d86 100644
--- a/src/android/java/java.pro
+++ b/src/android/java/java.pro
@@ -9,3 +9,17 @@ javaresources.files = \
javaresources.path = $$[QT_INSTALL_PREFIX]/src/android/java
INSTALLS += javaresources
+
+!prefix_build:!equals(OUT_PWD, $$PWD) {
+ RETURN = $$escape_expand(\\n\\t)
+ equals(QMAKE_HOST.os, Windows) {
+ RETURN = $$escape_expand(\\r\\n\\t)
+ }
+ OUT_PATH = $$shell_path($$OUT_PWD)
+
+ QMAKE_POST_LINK += \
+ $${QMAKE_COPY} $$shell_path($$PWD/AndroidManifest.xml) $$OUT_PATH $$RETURN \
+ $${QMAKE_COPY} $$shell_path($$PWD/version.xml) $$OUT_PATH $$RETURN \
+ $${QMAKE_COPY_DIR} $$shell_path($$PWD/res) $$OUT_PATH $$RETURN \
+ $${QMAKE_COPY_DIR} $$shell_path($$PWD/src) $$OUT_PATH
+}
diff --git a/src/android/java/res/layout/splash.xml b/src/android/java/res/layout/splash.xml
new file mode 100644
index 0000000000..6875521a12
--- /dev/null
+++ b/src/android/java/res/layout/splash.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/src/angle/patches/0014-ANGLE-D3D11-Fix-internal-index-buffer-for-level-9-ha.patch b/src/angle/patches/0014-ANGLE-D3D11-Fix-internal-index-buffer-for-level-9-ha.patch
new file mode 100644
index 0000000000..52dfcd6da2
--- /dev/null
+++ b/src/angle/patches/0014-ANGLE-D3D11-Fix-internal-index-buffer-for-level-9-ha.patch
@@ -0,0 +1,256 @@
+From d7eb7ea643f00d47447d755b4a2125922d69a3b3 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Thu, 20 Mar 2014 13:21:29 +0200
+Subject: [PATCH] ANGLE D3D11: Fix internal index buffer for level 9 hardware
+
+Some level 9 hardware does not support 32-bit indices, and in most
+places this is already checked. It would appear that most phone
+hardware actually does support 32-bit indices, and so this bug wasn't
+caught until testing on the Surface RT. This is not surprising, as some
+level 9 resources are only a minimum for the hardware spec, not the
+true limit of the device/driver.
+
+This patch provides the general fix to use 16-bit indices on such
+hardware, but a whitelist of known good GPUs should be added to enable
+32-bit indices where available.
+
+Change-Id: I282ede5dd4a323037ade6c44b7cfac2c6445b491
+---
+ .../src/libGLESv2/renderer/d3d11/Renderer11.cpp | 169 ++++++++++++---------
+ 1 file changed, 94 insertions(+), 75 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+index 31d976d..2de477b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp
+@@ -1137,6 +1137,84 @@ void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLv
+ }
+ }
+
++template<typename T>
++static void fillLineLoopIndices(GLenum type, GLsizei count, const GLvoid *indices, T *data)
++{
++ switch (type)
++ {
++ case GL_NONE: // Non-indexed draw
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = i;
++ }
++ data[count] = 0;
++ break;
++ case GL_UNSIGNED_BYTE:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLubyte*>(indices)[i];
++ }
++ data[count] = static_cast<const GLubyte*>(indices)[0];
++ break;
++ case GL_UNSIGNED_SHORT:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLushort*>(indices)[i];
++ }
++ data[count] = static_cast<const GLushort*>(indices)[0];
++ break;
++ case GL_UNSIGNED_INT:
++ for (int i = 0; i < count; i++)
++ {
++ data[i] = static_cast<const GLuint*>(indices)[i];
++ }
++ data[count] = static_cast<const GLuint*>(indices)[0];
++ break;
++ default: UNREACHABLE();
++ }
++}
++
++template<typename T>
++static void fillTriangleFanIndices(GLenum type, unsigned int numTris, const GLvoid *indices, T *data)
++{
++ switch (type)
++ {
++ case GL_NONE: // Non-indexed draw
++ for (unsigned int i = 0; i < numTris; i++)
++ {
++ data[i*3 + 0] = 0;
++ data[i*3 + 1] = i + 1;
++ data[i*3 + 2] = i + 2;
++ }
++ break;
++ case GL_UNSIGNED_BYTE:
++ for (unsigned int i = 0; i < numTris; i++)
++ {
++ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
++ }
++ break;
++ case GL_UNSIGNED_SHORT:
++ for (unsigned int i = 0; i < numTris; i++)
++ {
++ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
++ }
++ break;
++ case GL_UNSIGNED_INT:
++ for (unsigned int i = 0; i < numTris; i++)
++ {
++ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
++ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
++ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
++ }
++ break;
++ default: UNREACHABLE();
++ }
++}
++
+ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+ {
+ // Get the raw indices for an indexed draw
+@@ -1148,10 +1226,12 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
+ indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ }
+
++ const int indexType = get32BitIndexSupport() ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
++
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+- if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
++ if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType))
+ {
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+@@ -1171,7 +1251,7 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
+ }
+
+ const unsigned int spaceNeeded = (static_cast<unsigned int>(count) + 1) * sizeof(unsigned int);
+- if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
++ if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, indexType))
+ {
+ ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+@@ -1185,42 +1265,12 @@ void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices,
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
++ if (indexType == GL_UNSIGNED_SHORT)
++ fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned short*>(mappedMemory));
++ else
++ fillLineLoopIndices(type, count, indices, reinterpret_cast<unsigned int*>(mappedMemory));
+ unsigned int indexBufferOffset = offset;
+
+- switch (type)
+- {
+- case GL_NONE: // Non-indexed draw
+- for (int i = 0; i < count; i++)
+- {
+- data[i] = i;
+- }
+- data[count] = 0;
+- break;
+- case GL_UNSIGNED_BYTE:
+- for (int i = 0; i < count; i++)
+- {
+- data[i] = static_cast<const GLubyte*>(indices)[i];
+- }
+- data[count] = static_cast<const GLubyte*>(indices)[0];
+- break;
+- case GL_UNSIGNED_SHORT:
+- for (int i = 0; i < count; i++)
+- {
+- data[i] = static_cast<const GLushort*>(indices)[i];
+- }
+- data[count] = static_cast<const GLushort*>(indices)[0];
+- break;
+- case GL_UNSIGNED_INT:
+- for (int i = 0; i < count; i++)
+- {
+- data[i] = static_cast<const GLuint*>(indices)[i];
+- }
+- data[count] = static_cast<const GLuint*>(indices)[0];
+- break;
+- default: UNREACHABLE();
+- }
+-
+ if (!mLineLoopIB->unmapBuffer())
+ {
+ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+@@ -1251,10 +1301,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
+ indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ }
+
++ const int indexType = get32BitIndexSupport() ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
++
+ if (!mTriangleFanIB)
+ {
+ mTriangleFanIB = new StreamingIndexBufferInterface(this);
+- if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
++ if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, indexType))
+ {
+ delete mTriangleFanIB;
+ mTriangleFanIB = NULL;
+@@ -1276,7 +1328,7 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
+ }
+
+ const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
+- if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
++ if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, indexType))
+ {
+ ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
+ return gl::error(GL_OUT_OF_MEMORY);
+@@ -1290,45 +1342,12 @@ void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indic
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+- unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
++ if (indexType == GL_UNSIGNED_SHORT)
++ fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned short*>(mappedMemory));
++ else
++ fillTriangleFanIndices(type, numTris, indices, reinterpret_cast<unsigned int*>(mappedMemory));
+ unsigned int indexBufferOffset = offset;
+
+- switch (type)
+- {
+- case GL_NONE: // Non-indexed draw
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = 0;
+- data[i*3 + 1] = i + 1;
+- data[i*3 + 2] = i + 2;
+- }
+- break;
+- case GL_UNSIGNED_BYTE:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+- }
+- break;
+- case GL_UNSIGNED_SHORT:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+- }
+- break;
+- case GL_UNSIGNED_INT:
+- for (unsigned int i = 0; i < numTris; i++)
+- {
+- data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
+- data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
+- data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+- }
+- break;
+- default: UNREACHABLE();
+- }
+
+ if (!mTriangleFanIB->unmapBuffer())
+ {
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/src/d3dcompiler/main.cpp b/src/angle/src/d3dcompiler/main.cpp
index d2bb43ea9f..7742596226 100644
--- a/src/angle/src/d3dcompiler/main.cpp
+++ b/src/angle/src/d3dcompiler/main.cpp
@@ -180,22 +180,32 @@ HRESULT WINAPI D3DCompile(
const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint,
const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **errorMsgs)
{
+ // Shortcut to compile using the runtime compiler if it is available
+ static bool compilerAvailable =
+ !qgetenv("QT_D3DCOMPILER_DISABLE_DLL").toInt() && D3DCompiler::loadCompiler();
+ if (compilerAvailable) {
+ HRESULT hr = D3DCompiler::compile(data, data_size, filename, defines, include, entrypoint,
+ target, sflags, eflags, shader, errorMsgs);
+ return hr;
+ }
+
static bool initialized = false;
- static bool serviceAvailable = false;
static QString binaryPath;
static QString sourcePath;
if (!initialized) {
QString base;
- if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR")) {
+ if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR"));
- } else {
+
+ if (base.isEmpty()) {
const QString location = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
if (!location.isEmpty())
base = location + QStringLiteral("/d3dcompiler");
}
+ // Unless the service has run, this directory won't exist.
QDir baseDir(base);
- if (!base.isEmpty() && baseDir.exists()) {
+ if (baseDir.exists()) {
// Check if we have can read/write blobs
if (baseDir.exists(QStringLiteral("binary"))) {
binaryPath = baseDir.absoluteFilePath(QStringLiteral("binary/"));
@@ -211,14 +221,10 @@ HRESULT WINAPI D3DCompile(
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the source directory does not.\n"
"Check the compiler service.";
}
-
- // Look for a file, "control", and check if it has been touched in the last 60 seconds
- QFileInfo control(baseDir.absoluteFilePath(QStringLiteral("control")));
- serviceAvailable = control.exists() && control.lastModified().secsTo(QDateTime::currentDateTime()) < 60;
} else {
qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist:"
<< QDir::toNativeSeparators(base)
- << "\nThe compiler service won't be used.";
+ << "\nCheck that the compiler service is running.";
}
initialized = true;
@@ -259,8 +265,8 @@ HRESULT WINAPI D3DCompile(
}
}
- // Shader blob is not available, compile with compilation service if possible
- if (!sourcePath.isEmpty() && serviceAvailable) {
+ // Shader blob is not available; write out shader source
+ if (!sourcePath.isEmpty()) {
// Dump source to source path; wait for blob to appear
QFile source(sourcePath + fileName);
if (!source.open(QFile::WriteOnly)) {
@@ -292,24 +298,6 @@ HRESULT WINAPI D3DCompile(
return E_ABORT;
}
- // Fall back to compiler DLL
- if (D3DCompiler::loadCompiler()) {
- HRESULT hr = D3DCompiler::compile(data, data_size, filename, defines, include, entrypoint,
- target, sflags, eflags, shader, errorMsgs);
- // Cache shader
- if (SUCCEEDED(hr) && !binaryPath.isEmpty()) {
- const QByteArray blobContents = QByteArray::fromRawData(
- reinterpret_cast<const char *>((*shader)->GetBufferPointer()), (*shader)->GetBufferSize());
-
- QFile blob(binaryPath + fileName);
- if (blob.open(QFile::WriteOnly) && blob.write(blobContents))
- qCDebug(QT_D3DCOMPILER) << "Cached shader blob at" << blob.fileName();
- else
- qCDebug(QT_D3DCOMPILER) << "Unable to write shader blob at" << blob.fileName();
- }
- return hr;
- }
-
- *errorMsgs = new D3DCompiler::Blob("Unable to load D3D compiler DLL.");
+ *errorMsgs = new D3DCompiler::Blob("No shader compiler or service could be found.");
return E_FAIL;
}
diff --git a/src/concurrent/doc/src/qtconcurrent-module.qdoc b/src/concurrent/doc/src/qtconcurrent-module.qdoc
index 37298017c7..d9cc953a05 100644
--- a/src/concurrent/doc/src/qtconcurrent-module.qdoc
+++ b/src/concurrent/doc/src/qtconcurrent-module.qdoc
@@ -36,3 +36,17 @@
The Qt Concurrent module extends the basic threading support found in \l{Qt Core} module and
simplifies the development of code that can be executed in parallel on all available CPU cores.
*/
+
+/*!
+ \typedef QtConcurrent::Exception
+ \obsolete
+
+ Use QException from \l{Qt Core} instead.
+*/
+
+/*!
+ \typedef QtConcurrent::UnhandledException
+ \obsolete
+
+ Use QUnhandledException from \l{Qt Core} instead.
+*/
diff --git a/src/concurrent/qtconcurrentiteratekernel.h b/src/concurrent/qtconcurrentiteratekernel.h
index b47c30aef6..0969029e37 100644
--- a/src/concurrent/qtconcurrentiteratekernel.h
+++ b/src/concurrent/qtconcurrentiteratekernel.h
@@ -86,6 +86,8 @@ private:
Median<double> controlPartElapsed;
Median<double> userPartElapsed;
int m_blockSize;
+
+ Q_DISABLE_COPY(BlockSizeManager)
};
template <typename T>
diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h
index 31a06541ed..3fd07e0813 100644
--- a/src/corelib/arch/qatomic_armv6.h
+++ b/src/corelib/arch/qatomic_armv6.h
@@ -171,8 +171,8 @@ bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
template<> template <typename T> inline
bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
- register T tempValue;
- register int result;
+ T tempValue;
+ int result;
asm volatile("0:\n"
"ldrex %[tempValue], [%[_q_value]]\n"
"eors %[result], %[tempValue], %[expectedValue]\n"
@@ -352,8 +352,8 @@ bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
template<> template <typename T> inline
bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
- register T tempValue;
- register T result;
+ T tempValue;
+ T result;
asm volatile("0:\n"
"ldrexb %[tempValue], [%[_q_value]]\n"
"eors %[result], %[tempValue], %[expectedValue]\n"
@@ -474,8 +474,8 @@ bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
template<> template <typename T> inline
bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
- register T tempValue;
- register T result;
+ T tempValue;
+ T result;
asm volatile("0:\n"
"ldrexh %[tempValue], [%[_q_value]]\n"
"eors %[result], %[tempValue], %[expectedValue]\n"
@@ -608,8 +608,8 @@ bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newVa
template<> template <typename T> inline
bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue) Q_DECL_NOTHROW
{
- register T tempValue;
- register T result;
+ T tempValue;
+ T result;
asm volatile("0:\n"
"ldrexd %[tempValue], %H[tempValue], [%[_q_value]]\n"
"eor %[result], %[tempValue], %[expectedValue]\n"
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 18fdfb18f3..2ad24d33b1 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -37,7 +37,8 @@ exampledirs += \
snippets \
../../../examples/threads/ \
../../../examples/tools/ \
- ../../../examples/json/
+ ../../../examples/json/ \
+ ../../../examples/network/dnslookup
imagedirs += images
diff --git a/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp b/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp
index fde37bb549..5c6055defe 100644
--- a/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_thread_qthread.cpp
@@ -47,7 +47,7 @@ class WorkerThread : public QThread
Q_OBJECT
void run() Q_DECL_OVERRIDE {
QString result;
- /* expensive or blocking operation */
+ /* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
@@ -71,7 +71,8 @@ class Worker : public QObject
public slots:
void doWork(const QString &parameter) {
- // ...
+ QString result;
+ /* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
@@ -87,7 +88,7 @@ public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
- connect(workerThread, &QThread::finished, worker, &QObject::deleteLater);
+ connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index c15305322b..66664f0f2a 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -3258,7 +3258,7 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
On Blackberry the message is sent to slogger2. This
function does nothing if \c QT_NO_WARNING_OUTPUT was defined
during compilation; it exits if the environment variable \c
- QT_FATAL_WARNINGS is defined.
+ QT_FATAL_WARNINGS is not empty.
This function takes a format string and a list of arguments,
similar to the C printf() function. The format should be a Latin-1
@@ -3291,6 +3291,8 @@ bool QInternal::activateCallbacks(Callback cb, void **parameters)
stderr. Under Windows, the message is sent to the debugger.
On Blackberry the message is sent to slogger2.
+ It exits if the environment variable QT_FATAL_CRITICALS is not empty.
+
This function takes a format string and a list of arguments,
similar to the C printf() function. The format should be a Latin-1
string.
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 7789461a1c..cd422dfd87 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -534,8 +534,8 @@ Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max
#ifdef Q_OS_DARWIN
# define QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(osx, ios) \
- ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= osx) || \
- (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios))
+ ((defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MAX_ALLOWED >= osx) || \
+ (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && ios != __IPHONE_NA && __IPHONE_OS_VERSION_MAX_ALLOWED >= ios))
# define QT_MAC_DEPLOYMENT_TARGET_BELOW(osx, ios) \
((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && osx != __MAC_NA && __MAC_OS_X_VERSION_MIN_REQUIRED < osx) || \
@@ -896,8 +896,11 @@ struct QForeachContainerBase {};
template <typename T>
class QForeachContainer : public QForeachContainerBase {
+ QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE;
public:
inline QForeachContainer(const T& t): c(t), brk(0), i(c.begin()), e(c.end()){}
+ QForeachContainer(const QForeachContainer &other)
+ : c(other.c), brk(other.brk), i(other.i), e(other.e) {}
const T c;
mutable int brk;
mutable typename T::const_iterator i, e;
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 689de48e26..39bfd339c3 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -257,9 +257,9 @@ QLibraryInfo::buildDate()
#if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too
# ifdef __apple_build_version__ // Apple clang has other version numbers
-# define COMPILER_STRING __clang_version__ " (Apple)"
+# define COMPILER_STRING "Clang " __clang_version__ " (Apple)"
# else
-# define COMPILER_STRING __clang_version__
+# define COMPILER_STRING "Clang " __clang_version__
# endif
#elif defined(Q_CC_GNU)
# define COMPILER_STRING "GCC " __VERSION__
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 64dd544cf0..8c1d8b867d 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -83,6 +83,11 @@ static bool isFatal(QtMsgType msgType)
if (msgType == QtFatalMsg)
return true;
+ if (msgType == QtCriticalMsg) {
+ static bool fatalCriticals = !qEnvironmentVariableIsEmpty("QT_FATAL_CRITICALS");
+ return fatalCriticals;
+ }
+
if (msgType == QtWarningMsg || msgType == QtCriticalMsg) {
static bool fatalWarnings = !qEnvironmentVariableIsEmpty("QT_FATAL_WARNINGS");
return fatalWarnings;
@@ -1220,7 +1225,7 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
logMessage.chop(1);
systemd_default_message_handler(type, context, logMessage);
} else {
- fprintf(stderr, "%s", logMessage.toUtf8().constData());
+ fprintf(stderr, "%s", logMessage.toLocal8Bit().constData());
fflush(stderr);
}
#elif defined(Q_OS_ANDROID)
@@ -1479,12 +1484,15 @@ void qErrnoWarning(int code, const char *msg, ...)
\c %{if-warning}, \c %{if-critical} or \c %{if-fatal} followed by an \c %{endif}.
What is inside the \c %{if-*} and \c %{endif} will only be printed if the type matches.
+ Finally, text inside \c %{if-category} ... \c %{endif} is only printed if the category
+ is not the default one.
+
Example:
\code
QT_MESSAGE_PATTERN="[%{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}"
\endcode
- The default \a pattern is "%{message}".
+ The default \a pattern is "%{if-category}%{category}: %{endif}%{message}".
The \a pattern can also be changed at runtime by setting the QT_MESSAGE_PATTERN
environment variable; if both qSetMessagePattern() is called and QT_MESSAGE_PATTERN is
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index d7ae97e911..839d352d36 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -267,6 +267,8 @@ public:
TextJustificationForced = 0x10000,
TextForceLeftToRight = 0x20000,
TextForceRightToLeft = 0x40000,
+ // Ensures that the longest variant is always used when computing the
+ // size of a multi-variant string.
TextLongestVariant = 0x80000,
TextBypassShaping = 0x100000
};
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 31bc18749b..8ade3f86d6 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -493,8 +493,7 @@
text; otherwise this width is excluded.
\value TextJustificationForced Ensures that text lines are justified.
- \omitvalue TextLongestVariant Ensures that the longest variant is always used
- when computing the size of a multi-variant string. (Internal)
+ \omitvalue TextLongestVariant
\omitvalue TextBypassShaping
\omitvalue TextForceLeftToRight
\omitvalue TextForceRightToLeft
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 989e4644c7..f651860e08 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -148,7 +148,7 @@ win32 {
}
} else:blackberry {
SOURCES += io/qstandardpaths_blackberry.cpp
- } else:android {
+ } else:android:!android-no-sdk {
SOURCES += io/qstandardpaths_android.cpp
} else {
SOURCES += io/qstandardpaths_unix.cpp
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index ea3a3ca13d..6c0f31fb55 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>>
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -89,35 +89,23 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e
QFileInfo info(entry.filePath());
QString suffix = info.suffix();
- // First step: is the extenstion known ?
- if (suffix == QLatin1String("app")
- || suffix == QLatin1String("debug")
- || suffix == QLatin1String("profile")
- || suffix == QLatin1String("bundle")
- || suffix == QLatin1String("pkg")) {
- return true;
- }
-
- // Second step: check if an application knows the package type
- const QByteArray &native = entry.nativeFilePath();
- const char *nativeFilePath = native.constData();
- int nativeFilePathLength = native.size();
-
- QCFType<CFStringRef> path = CFStringCreateWithBytes(0,
- reinterpret_cast<const UInt8*>(nativeFilePath),
- nativeFilePathLength,
- kCFStringEncodingUTF8,
- false);
-
- QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, true);
-
- UInt32 type, creator;
- // Well created packages have the PkgInfo file
- if (CFBundleGetPackageInfoInDirectory(url, &type, &creator))
- return true;
-
- // Find if an application other than Finder claims to know how to handle the package
if (suffix.length() > 0) {
+ // First step: is the extension known ?
+ CFStringRef extensionRef = QCFString::toCFStringRef(suffix);
+ CFStringRef uniformTypeIdentifier = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extensionRef, NULL);
+ if (UTTypeConformsTo(uniformTypeIdentifier, kUTTypeBundle))
+ return true;
+
+ // Second step: check if an application knows the package type
+ CFStringRef path = QCFString::toCFStringRef(entry.filePath());
+ QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0, path, kCFURLPOSIXPathStyle, true);
+
+ UInt32 type, creator;
+ // Well created packages have the PkgInfo file
+ if (CFBundleGetPackageInfoInDirectory(url, &type, &creator))
+ return true;
+
+ // Find if an application other than Finder claims to know how to handle the package
QCFType<CFURLRef> application;
LSGetApplicationForURL(url,
kLSRolesEditor|kLSRolesViewer|kLSRolesViewer,
@@ -134,7 +122,7 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e
// Third step: check if the directory has the package bit set
FSRef packageRef;
- FSPathMakeRef((UInt8 *)nativeFilePath, &packageRef, NULL);
+ FSPathMakeRef((UInt8 *)entry.nativeFilePath().constData(), &packageRef, NULL);
FSCatalogInfo catalogInfo;
FSGetCatalogInfo(&packageRef,
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index dbc6d28846..7741eb4c1e 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -74,6 +74,8 @@
# define SECURITY_WIN32
# include <security.h>
#else // !Q_OS_WINRT
+# include "qstandardpaths.h"
+# include "qthreadstorage.h"
# include <wrl.h>
# include <windows.foundation.h>
# include <windows.storage.h>
@@ -1151,6 +1153,18 @@ bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool crea
bool existed = false;
if (isDirPath(chunk, &existed) && existed)
continue;
+#ifdef Q_OS_WINRT
+ static QThreadStorage<QString> dataLocation;
+ if (!dataLocation.hasLocalData())
+ dataLocation.setLocalData(QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation)));
+ static QThreadStorage<QString> tempLocation;
+ if (!tempLocation.hasLocalData())
+ tempLocation.setLocalData(QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::TempLocation)));
+ // We try to create something outside the sandbox, which is forbidden
+ // However we could still try to pass into the sandbox
+ if (dataLocation.localData().startsWith(chunk) || tempLocation.localData().startsWith(chunk))
+ continue;
+#endif
}
return false;
}
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index 5fd20c6d74..3031c7a27e 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -138,6 +138,11 @@
# define __NR_inotify_add_watch 285
# define __NR_inotify_rm_watch 286
# define __NR_inotify_init1 328
+#elif defined (__aarch64__)
+# define __NR_inotify_init1 26
+# define __NR_inotify_add_watch 27
+# define __NR_inotify_rm_watch 28
+// no inotify_init for aarch64
#else
# error "This architecture is not supported. Please see http://www.qt-project.org/"
#endif
@@ -155,7 +160,11 @@ static inline int syscall(...) { return -1; }
static inline int inotify_init()
{
+#ifdef __NR_inotify_init
return syscall(__NR_inotify_init);
+#else
+ return syscall(__NR_inotify_init1, 0);
+#endif
}
static inline int inotify_add_watch(int fd, const char *name, __u32 mask)
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 23f1ffbd16..7e6883fd14 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -62,7 +62,6 @@ Q_GLOBAL_STATIC(QLoggingRegistry, qtLoggingRegistry)
Constructs a logging rule with default values.
*/
QLoggingRule::QLoggingRule() :
- flags(Invalid),
enabled(false)
{
}
@@ -73,7 +72,6 @@ QLoggingRule::QLoggingRule() :
*/
QLoggingRule::QLoggingRule(const QStringRef &pattern, bool enabled) :
messageType(-1),
- flags(Invalid),
enabled(enabled)
{
parse(pattern);
@@ -147,7 +145,6 @@ void QLoggingRule::parse(const QStringRef &pattern)
p = pattern;
}
- flags = Invalid;
if (!p.contains(QLatin1Char('*'))) {
flags = FullText;
} else {
@@ -160,7 +157,7 @@ void QLoggingRule::parse(const QStringRef &pattern)
p = QStringRef(p.string(), p.position() + 1, p.length() - 1);
}
if (p.contains(QLatin1Char('*'))) // '*' only supported at start/end
- flags = Invalid;
+ flags = 0;
}
category = p.toString();
@@ -224,7 +221,11 @@ void QLoggingSettingsParser::setContent(QTextStream &stream)
const QStringRef value = line.midRef(equalPos + 1);
bool enabled = (value.compare(QLatin1String("true"),
Qt::CaseInsensitive) == 0);
- _rules.append(QLoggingRule(pattern, enabled));
+ QLoggingRule rule(pattern, enabled);
+ if (rule.flags != 0)
+ _rules.append(rule);
+ else
+ warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData());
}
}
}
diff --git a/src/corelib/io/qloggingregistry_p.h b/src/corelib/io/qloggingregistry_p.h
index 21896bb268..48804cfc2b 100644
--- a/src/corelib/io/qloggingregistry_p.h
+++ b/src/corelib/io/qloggingregistry_p.h
@@ -72,7 +72,6 @@ public:
int pass(const QString &categoryName, QtMsgType type) const;
enum PatternFlag {
- Invalid = 0x0,
FullText = 0x1,
LeftFilter = 0x2,
RightFilter = 0x4,
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 3b78351809..18391703da 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -165,7 +165,7 @@ QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list
QStringList::ConstIterator it = list.constBegin(),
end = list.constEnd();
for ( ; it != end; ++it) {
- int pos = it->indexOf(QLatin1Char('='));
+ int pos = it->indexOf(QLatin1Char('='), 1);
if (pos < 1)
continue;
@@ -2227,6 +2227,8 @@ void QProcess::start(const QString &command, OpenMode mode)
}
/*!
+ \since 5.0
+
Returns the program the process was last started with.
\sa start()
@@ -2256,6 +2258,8 @@ void QProcess::setProgram(const QString &program)
}
/*!
+ \since 5.0
+
Returns the command line arguments the process was last started with.
\sa start()
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 219bdf8200..5d65b2a068 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -390,6 +390,11 @@ public:
qint64 writeToStdin(const char *data, qint64 maxlen);
void cleanup();
+
+#ifdef Q_OS_BLACKBERRY
+ QList<QSocketNotifier *> defaultNotifiers() const;
+#endif // Q_OS_BLACKBERRY
+
#ifdef Q_OS_UNIX
static void initializeProcessManager();
#endif
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 0e917ef438..8674371baa 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -1042,17 +1042,6 @@ void QProcessPrivate::killProcess()
::kill(pid_t(pid), SIGKILL);
}
-static int select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
-{
- if (timeout < 0)
- return qt_safe_select(nfds, fdread, fdwrite, 0, 0);
-
- struct timespec tv;
- tv.tv_sec = timeout / 1000;
- tv.tv_nsec = (timeout % 1000) * 1000 * 1000;
- return qt_safe_select(nfds, fdread, fdwrite, 0, &tv);
-}
-
/*
Returns the difference between msecs and elapsed. If msecs is -1,
however, -1 is returned.
@@ -1066,41 +1055,6 @@ static int qt_timeout_value(int msecs, int elapsed)
return timeout < 0 ? 0 : timeout;
}
-#ifdef Q_OS_BLACKBERRY
-// The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered
-// socket notifiers are disabled by a call to select. This is to rearm the standard streams.
-static int bb_select(QProcessPrivate *process, int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
-{
- bool stdoutEnabled = false;
- bool stderrEnabled = false;
- bool stdinEnabled = false;
-
- if (process->stdoutChannel.notifier && process->stdoutChannel.notifier->isEnabled()) {
- stdoutEnabled = true;
- process->stdoutChannel.notifier->setEnabled(false);
- }
- if (process->stderrChannel.notifier && process->stderrChannel.notifier->isEnabled()) {
- stderrEnabled = true;
- process->stderrChannel.notifier->setEnabled(false);
- }
- if (process->stdinChannel.notifier && process->stdinChannel.notifier->isEnabled()) {
- stdinEnabled = true;
- process->stdinChannel.notifier->setEnabled(false);
- }
-
- const int ret = select_msecs(nfds, fdread, fdwrite, timeout);
-
- if (stdoutEnabled)
- process->stdoutChannel.notifier->setEnabled(true);
- if (stderrEnabled)
- process->stderrChannel.notifier->setEnabled(true);
- if (stdinEnabled)
- process->stdinChannel.notifier->setEnabled(true);
-
- return ret;
-}
-#endif // Q_OS_BLACKBERRY
-
bool QProcessPrivate::waitForStarted(int msecs)
{
Q_Q(QProcess);
@@ -1113,7 +1067,7 @@ bool QProcessPrivate::waitForStarted(int msecs)
fd_set fds;
FD_ZERO(&fds);
FD_SET(childStartedPipe[0], &fds);
- if (select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) {
+ if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) {
processError = QProcess::Timedout;
q->setErrorString(QProcess::tr("Process operation timed out"));
#if defined (QPROCESS_DEBUG)
@@ -1129,6 +1083,17 @@ bool QProcessPrivate::waitForStarted(int msecs)
return startedEmitted;
}
+#ifdef Q_OS_BLACKBERRY
+QList<QSocketNotifier *> QProcessPrivate::defaultNotifiers() const
+{
+ QList<QSocketNotifier *> notifiers;
+ notifiers << stdoutChannel.notifier
+ << stderrChannel.notifier
+ << stdinChannel.notifier;
+ return notifiers;
+}
+#endif // Q_OS_BLACKBERRY
+
bool QProcessPrivate::waitForReadyRead(int msecs)
{
Q_Q(QProcess);
@@ -1139,6 +1104,10 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
QElapsedTimer stopWatch;
stopWatch.start();
+#ifdef Q_OS_BLACKBERRY
+ QList<QSocketNotifier *> notifiers = defaultNotifiers();
+#endif
+
forever {
fd_set fdread;
fd_set fdwrite;
@@ -1162,9 +1131,9 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
#ifdef Q_OS_BLACKBERRY
- int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+ int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
#else
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
#endif
if (ret < 0) {
break;
@@ -1215,6 +1184,10 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
QElapsedTimer stopWatch;
stopWatch.start();
+#ifdef Q_OS_BLACKBERRY
+ QList<QSocketNotifier *> notifiers = defaultNotifiers();
+#endif
+
while (!writeBuffer.isEmpty()) {
fd_set fdread;
fd_set fdwrite;
@@ -1239,9 +1212,9 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
#ifdef Q_OS_BLACKBERRY
- int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+ int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
#else
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
#endif
if (ret < 0) {
break;
@@ -1286,6 +1259,10 @@ bool QProcessPrivate::waitForFinished(int msecs)
QElapsedTimer stopWatch;
stopWatch.start();
+#ifdef Q_OS_BLACKBERRY
+ QList<QSocketNotifier *> notifiers = defaultNotifiers();
+#endif
+
forever {
fd_set fdread;
fd_set fdwrite;
@@ -1310,9 +1287,9 @@ bool QProcessPrivate::waitForFinished(int msecs)
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
#ifdef Q_OS_BLACKBERRY
- int ret = bb_select(this, nfds + 1, &fdread, &fdwrite, timeout);
+ int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout);
#else
- int ret = select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
+ int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout);
#endif
if (ret < 0) {
break;
@@ -1349,7 +1326,7 @@ bool QProcessPrivate::waitForWrite(int msecs)
fd_set fdwrite;
FD_ZERO(&fdwrite);
FD_SET(stdinChannel.pipe[1], &fdwrite);
- return select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1;
+ return qt_select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1;
}
void QProcessPrivate::findExitCode()
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index a3727a6a4b..0406aeb501 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -2369,6 +2369,10 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
stored in the following registry path:
\c{HKEY_LOCAL_MACHINE\Software\WOW6432node}.
+ On BlackBerry only a single file is used (see \l{Platform Limitations}).
+ If the file format is NativeFormat, this is "Settings/MySoft/Star Runner.conf"
+ in the application's home directory.
+
If the file format is IniFormat, the following files are
used on Unix and Mac OS X:
@@ -2393,8 +2397,12 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
%COMMON_APPDATA% path is usually \tt{C:\\Documents and
Settings\\All Users\\Application Data}.
+ On BlackBerry only a single file is used (see \l{Platform Limitations}).
+ If the file format is IniFormat, this is "Settings/MySoft/Star Runner.ini"
+ in the application's home directory.
+
The paths for the \c .ini and \c .conf files can be changed using
- setPath(). On Unix and Mac OS X, the user can override them by by
+ setPath(). On Unix and Mac OS X, the user can override them by
setting the \c XDG_CONFIG_HOME environment variable; see
setPath() for details.
@@ -2498,7 +2506,8 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
allowed to read or write outside of this sandbox. This involves the
following limitations:
\list
- \li As there is only a single scope the scope is simply ignored.
+ \li As there is only a single scope the scope is simply ignored,
+ i.e. there is no difference between SystemScope and UserScope.
\li The \l{Fallback Mechanism} is not applied, i.e. only a single
location is considered.
\li It is advised against setting and using custom file paths.
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
index 9b6a088a30..bd72de11bb 100644
--- a/src/corelib/io/qstandardpaths_winrt.cpp
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -74,6 +74,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
switch (type) {
case ConfigLocation: // same as DataLocation, on Windows
+ case GenericConfigLocation: // same as GenericDataLocation, on Windows
case DataLocation:
case GenericDataLocation: {
ComPtr<IApplicationDataStatics> applicationDataStatics;
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index e4181b5c86..568453ec07 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -58,6 +58,10 @@
#include <mach/mach_time.h>
#endif
+#ifdef Q_OS_BLACKBERRY
+#include <qsocketnotifier.h>
+#endif // Q_OS_BLACKBERRY
+
QT_BEGIN_NAMESPACE
static inline bool time_update(struct timespec *tv, const struct timespec &start,
@@ -106,4 +110,43 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
}
}
+int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout)
+{
+ if (timeout < 0)
+ return qt_safe_select(nfds, fdread, fdwrite, 0, 0);
+
+ struct timespec tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_nsec = (timeout % 1000) * 1000 * 1000;
+ return qt_safe_select(nfds, fdread, fdwrite, 0, &tv);
+}
+
+#ifdef Q_OS_BLACKBERRY
+// The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered
+// socket notifiers are disabled by a call to select. This is to rearm the standard streams.
+int bb_select(QList<QSocketNotifier *> socketNotifiers, int nfds, fd_set *fdread, fd_set *fdwrite,
+ int timeout)
+{
+ QList<bool> socketNotifiersEnabled;
+ socketNotifiersEnabled.reserve(socketNotifiers.count());
+ for (int a = 0; a < socketNotifiers.count(); ++a) {
+ if (socketNotifiers.at(a) && socketNotifiers.at(a)->isEnabled()) {
+ socketNotifiersEnabled.append(true);
+ socketNotifiers.at(a)->setEnabled(false);
+ } else {
+ socketNotifiersEnabled.append(false);
+ }
+ }
+
+ const int ret = qt_select_msecs(nfds, fdread, fdwrite, timeout);
+
+ for (int a = 0; a < socketNotifiers.count(); ++a) {
+ if (socketNotifiersEnabled.at(a) == true)
+ socketNotifiers.at(a)->setEnabled(true);
+ }
+
+ return ret;
+}
+#endif // Q_OS_BLACKBERRY
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index 7ab632d7a0..df78ef6692 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -343,6 +343,14 @@ void qt_nanosleep(timespec amount);
Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept,
const struct timespec *tv);
+int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout);
+
+#ifdef Q_OS_BLACKBERRY
+class QSocketNotifier;
+Q_CORE_EXPORT int bb_select(QList<QSocketNotifier *> socketNotifiers, int nfds, fd_set *fdread,
+ fd_set *fdwrite, int timeout);
+#endif // Q_OS_BLACKBERRY
+
// according to X/OPEN we have to define semun ourselves
// we use prefix as on some systems sem.h will have it
struct semid_ds;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index e8bcc449e9..6868eb6a1e 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -506,7 +506,6 @@ QThread *QCoreApplicationPrivate::mainThread()
return theMainThread;
}
-#if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
{
QThread *currentThread = QThread::currentThread();
@@ -523,7 +522,6 @@ void QCoreApplicationPrivate::checkReceiverThread(QObject *receiver)
Q_UNUSED(currentThread);
Q_UNUSED(thr);
}
-#endif
#endif // QT_NO_QOBJECT
@@ -2217,6 +2215,9 @@ QStringList QCoreApplication::arguments()
organizationName(). On all other platforms, QSettings uses
organizationName() as the organization.
+ On BlackBerry this property is read-only. It is obtained from the
+ BAR application descriptor file.
+
\sa organizationDomain, applicationName
*/
@@ -2294,6 +2295,9 @@ QString QCoreApplication::organizationDomain()
If not set, the application name defaults to the executable name (since 5.0).
+ On BlackBerry this property is read-only. It is obtained from the
+ BAR application descriptor file.
+
\sa organizationName, organizationDomain, applicationVersion, applicationFilePath()
*/
/*!
@@ -2335,6 +2339,9 @@ Q_CORE_EXPORT QString qt_applicationName_noFallback()
\since 4.4
\brief the version of this application
+ On BlackBerry this property is read-only. It is obtained from the
+ BAR application descriptor file.
+
\sa applicationName, organizationName, organizationDomain
*/
/*!
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index c3d83112ae..d784267a65 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -116,9 +116,7 @@ public:
static QThread *mainThread();
static void sendPostedEvents(QObject *receiver, int event_type, QThreadData *data);
-#if !defined (QT_NO_DEBUG) || defined (QT_MAC_FRAMEWORK_BUILD)
void checkReceiverThread(QObject *receiver);
-#endif
void cleanupThreadData();
#endif // QT_NO_QOBJECT
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index aaa75c0fb8..623662a628 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -1264,6 +1264,8 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig);
if (id) {
res = env->CallObjectMethodV(d->m_jobject, id, args);
+ if (res && env->ExceptionCheck())
+ res = 0;
}
QJNIObjectPrivate obj(res);
@@ -1342,6 +1344,8 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *classNam
jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true);
if (id) {
res = env->CallStaticObjectMethodV(clazz, id, args);
+ if (res && env->ExceptionCheck())
+ res = 0;
}
}
@@ -1372,6 +1376,8 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true);
if (id) {
res = env->CallStaticObjectMethodV(clazz, id, args);
+ if (res && env->ExceptionCheck())
+ res = 0;
}
QJNIObjectPrivate obj(res);
@@ -1685,8 +1691,11 @@ QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName,
QJNIEnvironmentPrivate env;
jobject res = 0;
jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig);
- if (id)
+ if (id) {
res = env->GetObjectField(d->m_jobject, id);
+ if (res && env->ExceptionCheck())
+ res = 0;
+ }
QJNIObjectPrivate obj(res);
env->DeleteLocalRef(res);
@@ -1713,8 +1722,11 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz,
QJNIEnvironmentPrivate env;
jobject res = 0;
jfieldID id = getCachedFieldID(env, clazz, fieldName, sig, true);
- if (id)
+ if (id) {
res = env->GetStaticObjectField(clazz, id);
+ if (res && env->ExceptionCheck())
+ res = 0;
+ }
QJNIObjectPrivate obj(res);
env->DeleteLocalRef(res);
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index a2f203bf7a..7679258a98 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -771,9 +771,13 @@ struct VariantData
, flags(flags_)
{
}
+ VariantData(const VariantData &other)
+ : metaTypeId(other.metaTypeId), data(other.data), flags(other.flags){}
const int metaTypeId;
const void *data;
const uint flags;
+private:
+ VariantData &operator=(const VariantData &) Q_DECL_EQ_DELETE;
};
template<typename const_iterator>
@@ -1702,7 +1706,8 @@ inline int qRegisterMetaTypeStreamOperators()
} QT_END_NAMESPACE \
/**/
-#define Q_DECLARE_METATYPE(TYPE) \
+#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
+#define Q_DECLARE_METATYPE_IMPL(TYPE) \
QT_BEGIN_NAMESPACE \
template <> \
struct QMetaTypeId< TYPE > \
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index d2996e6e4d..aea9d41c67 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -132,6 +132,8 @@ namespace QtPrivate {
inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, 0); }
protected:
~QSlotObjectBase() {}
+ private:
+ Q_DISABLE_COPY(QSlotObjectBase)
};
// implementation of QSlotObjectBase for which the slot is a pointer to member function of a QObject
// Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp
index 59656883f1..40c1157fb4 100644
--- a/src/corelib/kernel/qtcore_eval.cpp
+++ b/src/corelib/kernel/qtcore_eval.cpp
@@ -529,8 +529,6 @@ void qt_gui_eval_init(QCoreApplicationPrivate::Type type)
box.exec();
::exit(0);
} else {
- EvalMessageBox *box = new EvalMessageBox(false);
- box->show();
Q_UNUSED(new QGuiFuriCuri());
}
}
diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp
index 0f5d9a6827..168701d13c 100644
--- a/src/corelib/tools/qcommandlineparser.cpp
+++ b/src/corelib/tools/qcommandlineparser.cpp
@@ -187,6 +187,78 @@ QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const
QCoreApplication::arguments() before QCommandLineParser defines the \c{profile}
option and parses the command line.
+ \section2 How to Use QCommandLineParser in Complex Applications
+
+ In practice, additional error checking needs to be performed on the positional
+ arguments and option values. For example, ranges of numbers should be checked.
+
+ It is then advisable to introduce a function to do the command line parsing
+ which takes a struct or class receiving the option values returning an
+ enumeration representing the result. The dnslookup example of the QtNetwork
+ module illustrates this:
+
+ \snippet dnslookup.h 0
+
+ \snippet dnslookup.cpp 0
+
+ In the main function, help should be printed to the standard output if the help option
+ was passed and the application should return the exit code 0.
+
+ If an error was detected, the error message should be printed to the standard
+ error output and the application should return an exit code other than 0.
+
+ \snippet dnslookup.cpp 1
+
+ A special case to consider here are GUI applications on Windows and mobile
+ platforms. These applications may not use the standard output or error channels
+ since the output is either discarded or not accessible.
+
+ For such GUI applications, it is recommended to display help texts and error messages
+ using a QMessageBox. To preserve the formatting of the help text, rich text
+ with \c <pre> elements should be used:
+
+ \code
+
+ switch (parseCommandLine(parser, &query, &errorMessage)) {
+ case CommandLineOk:
+ break;
+ case CommandLineError:
+#ifdef Q_OS_WIN
+ QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
+ "<html><head/><body><h2>" + errorMessage + "</h2><pre>"
+ + parser.helpText() + "</pre></body></html>");
+#else
+ fputs(qPrintable(errorMessage), stderr);
+ fputs("\n\n", stderr);
+ fputs(qPrintable(parser.helpText()), stderr);
+#endif
+ return 1;
+ case CommandLineVersionRequested:
+#ifdef Q_OS_WIN
+ QMessageBox::information(0, QGuiApplication::applicationDisplayName(),
+ QGuiApplication::applicationDisplayName() + ' '
+ + QCoreApplication::applicationVersion());
+#else
+ printf("%s %s\n", QGuiApplication::applicationDisplayName(),
+ qPrintable(QCoreApplication::applicationVersion()));
+#endif
+ return 0;
+ case CommandLineHelpRequested:
+#ifdef Q_OS_WIN
+ QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
+ "<html><head/><body><pre>"
+ + parser.helpText() + "</pre></body></html>");
+ return 0;
+#else
+ parser.showHelp();
+ Q_UNREACHABLE();
+#endif
+ }
+ \endcode
+
+ However, this does not apply to the dnslookup example, because it is a
+ console application.
+
\sa QCommandLineOption, QCoreApplication
*/
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 7a421a4586..67924c0888 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -52,6 +52,12 @@
#include <initializer_list>
#endif
+#if defined(Q_CC_MSVC)
+#pragma warning( push )
+#pragma warning( disable : 4311 ) // disable pointer truncation warning
+#pragma warning( disable : 4127 ) // conditional expression is constant
+#endif
+
QT_BEGIN_NAMESPACE
class QBitArray;
@@ -95,18 +101,10 @@ Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QString &key) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(const QStringRef &key) Q_DECL_NOTHROW;
-#if defined(Q_CC_MSVC)
-#pragma warning( push )
-#pragma warning( disable : 4311 ) // disable pointer truncation warning
-#endif
template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
{
return qHash(reinterpret_cast<quintptr>(key), seed);
}
-#if defined(Q_CC_MSVC)
-#pragma warning( pop )
-#endif
-
template<typename T> inline uint qHash(const T &t, uint seed)
Q_DECL_NOEXCEPT_EXPR(noexcept(qHash(t)))
{ return (qHash(t) ^ seed); }
@@ -214,6 +212,9 @@ struct QHashNode
inline QHashNode(const Key &key0, const T &value0, uint hash, QHashNode *n)
: next(n), h(hash), key(key0), value(value0) {}
inline bool same_key(uint h0, const Key &key0) const { return h0 == h && key0 == key; }
+
+private:
+ Q_DISABLE_COPY(QHashNode)
};
template <class Key, class T>
@@ -224,6 +225,9 @@ struct QHashDummyNode
const Key key;
inline QHashDummyNode(const Key &key0, uint hash, QHashNode<Key, T> *n) : next(n), h(hash), key(key0) {}
+
+private:
+ Q_DISABLE_COPY(QHashDummyNode)
};
@@ -1087,4 +1091,8 @@ Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(Hash)
QT_END_NAMESPACE
+#if defined(Q_CC_MSVC)
+#pragma warning( pop )
+#endif
+
#endif // QHASH_H
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 16f058b001..3a0d01aa8d 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -58,6 +58,11 @@
#include <limits.h>
#include <string.h>
+#ifdef Q_CC_MSVC
+#pragma warning( push )
+#pragma warning( disable : 4127 ) // "conditional expression is constant"
+#endif
+
QT_BEGIN_NAMESPACE
@@ -937,4 +942,8 @@ Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List)
QT_END_NAMESPACE
+#ifdef Q_CC_MSVC
+#pragma warning( pop )
+#endif
+
#endif // QLIST_H
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index db0cd6a2d6..487039ccfb 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -260,6 +260,11 @@ QMapNode<Key, T> *QMapNode<Key, T>::copy(QMapData<Key, T> *d) const
return n;
}
+#if defined(Q_CC_MSVC)
+#pragma warning( push )
+#pragma warning( disable : 4127 ) // conditional expression is constant
+#endif
+
template <class Key, class T>
void QMapNode<Key, T>::destroySubTree()
{
@@ -275,6 +280,10 @@ void QMapNode<Key, T>::destroySubTree()
}
}
+#if defined(Q_CC_MSVC)
+#pragma warning( pop )
+#endif
+
template <class Key, class T>
void QMapData<Key, T>::deleteNode(QMapNode<Key, T> *z)
{
diff --git a/src/corelib/tools/qmargins.cpp b/src/corelib/tools/qmargins.cpp
index 088f0dc083..03993f05a9 100644
--- a/src/corelib/tools/qmargins.cpp
+++ b/src/corelib/tools/qmargins.cpp
@@ -312,7 +312,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QMargins &operator+=(const QMargins &margins)
+ \fn QMargins &QMargins::operator+=(const QMargins &margins)
Add each component of \a margins to the respective component of this object
and returns a reference to it.
@@ -323,7 +323,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QMargins &operator-=(const QMargins &margins)
+ \fn QMargins &QMargins::operator-=(const QMargins &margins)
Subtract each component of \a margins from the respective component of this object
and returns a reference to it.
@@ -334,7 +334,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QMargins &operator*=(int factor)
+ \fn QMargins &QMargins::operator*=(int factor)
Multiplies each component of this object by \a factor
and returns a reference to it.
@@ -345,7 +345,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QMargins &operator*=(qreal factor)
+ \fn QMargins &QMargins::operator*=(qreal factor)
\overload
Multiplies each component of this object by \a factor
@@ -357,7 +357,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QMargins &operator/=(int divisor)
+ \fn QMargins &QMargins::operator/=(int divisor)
Divides each component of this object by \a divisor
and returns a reference to it.
@@ -368,7 +368,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QMargins &operator/=(qreal divisor)
+ \fn QMargins &QMargins::operator/=(qreal divisor)
\overload
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
index 1b3a28839c..35c7d1cd3c 100644
--- a/src/corelib/tools/qrect.cpp
+++ b/src/corelib/tools/qrect.cpp
@@ -1201,7 +1201,7 @@ bool QRect::intersects(const QRect &r) const
*/
/*!
- \fn QRect QRect::operator+=(const QMargins &margins) const
+ \fn QRect QRect::operator+=(const QMargins &margins)
Adds the \a margins to the rectangle, growing it.
@@ -1221,7 +1221,7 @@ bool QRect::intersects(const QRect &r) const
*/
/*!
- \fn QRect QRect::operator -=(const QMargins &margins) const
+ \fn QRect QRect::operator -=(const QMargins &margins)
Returns a rectangle shrunk by the \a margins.
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index d2b5adc974..cadf2da019 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -133,8 +133,8 @@ int qFindString(const QChar *haystack, int haystackLen, int from,
or \b{5}. An expression can also be a set of characters
enclosed in square brackets. \b{[ABCD]} will match an \b{A}
or a \b{B} or a \b{C} or a \b{D}. We can write this same
- expression as \b{[A-D]}, and an experession to match any
- captital letter in the English alphabet is written as
+ expression as \b{[A-D]}, and an expression to match any
+ capital letter in the English alphabet is written as
\b{[A-Z]}.
A quantifier specifies the number of occurrences of an expression
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index 77409f5c71..a610fc46e5 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -478,6 +478,14 @@
*/
/*!
+ \fn void QSharedPointer::swap(QSharedPointer<T> &other);
+ \since 5.3
+
+ Swaps this shared pointer instance with \a other. This function is
+ very fast and never fails.
+*/
+
+/*!
\fn T *QSharedPointer::data() const
Returns the value of the pointer referenced by this object.
diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h
index 7d1f00814d..34b4bfbb12 100644
--- a/src/corelib/tools/qsharedpointer.h
+++ b/src/corelib/tools/qsharedpointer.h
@@ -79,6 +79,8 @@ public:
QSharedPointer<T> &operator=(const QSharedPointer<T> &other);
QSharedPointer<T> &operator=(const QWeakPointer<T> &other);
+ void swap(QSharedPointer<T> &other);
+
QWeakPointer<T> toWeakRef() const;
void clear();
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 9063f59171..cf0726d831 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -870,6 +870,12 @@ inline QString QString::arg(const QString &a1, const QString &a2, const QString
inline QString QString::section(QChar asep, int astart, int aend, SectionFlags aflags) const
{ return section(QString(asep), astart, aend, aflags); }
+#ifdef Q_CC_MSVC
+// "conditional expression is constant"
+#pragma warning(push)
+#pragma warning(disable : 4127)
+#endif
+
inline int QString::toWCharArray(wchar_t *array) const
{
if (sizeof(wchar_t) == sizeof(QChar)) {
@@ -878,6 +884,11 @@ inline int QString::toWCharArray(wchar_t *array) const
}
return toUcs4_helper(d->data(), size(), reinterpret_cast<uint *>(array));
}
+
+#ifdef Q_CC_MSVC
+#pragma warning(pop)
+#endif
+
inline QString QString::fromWCharArray(const wchar_t *string, int size)
{
return sizeof(wchar_t) == sizeof(QChar) ? fromUtf16(reinterpret_cast<const ushort *>(string), size)
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index f0670999d7..befa40081c 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -143,12 +143,16 @@ class QStringBuilder <QString, QString> : public QStringBuilderBase<QStringBuild
{
public:
QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
+ QStringBuilder(const QStringBuilder &other) : a(other.a), b(other.b) {}
operator QString() const
{ QString r(a); r += b; return r; }
const QString &a;
const QString &b;
+
+ private:
+ QStringBuilder &operator=(const QStringBuilder &) Q_DECL_EQ_DELETE;
};
template <>
@@ -156,12 +160,16 @@ class QStringBuilder <QByteArray, QByteArray> : public QStringBuilderBase<QStrin
{
public:
QStringBuilder(const QByteArray &a_, const QByteArray &b_) : a(a_), b(b_) {}
+ QStringBuilder(const QStringBuilder &other) : a(other.a), b(other.b) {}
operator QByteArray() const
{ QByteArray r(a); r += b; return r; }
const QByteArray &a;
const QByteArray &b;
+
+ private:
+ QStringBuilder &operator=(const QStringBuilder &) Q_DECL_EQ_DELETE;
};
diff --git a/src/corelib/tools/qtimezoneprivate_mac.mm b/src/corelib/tools/qtimezoneprivate_mac.mm
index 3d95377850..49930490ff 100644
--- a/src/corelib/tools/qtimezoneprivate_mac.mm
+++ b/src/corelib/tools/qtimezoneprivate_mac.mm
@@ -272,7 +272,6 @@ QSet<QByteArray> QMacTimeZonePrivate::availableTimeZoneIds() const
tzid = QCFString::toQString([enumerator nextObject]).toUtf8();
}
- [enumerator release];
return set;
}
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 075e8e83e8..b0be98c296 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -287,6 +287,11 @@ void QVector<T>::copyConstruct(const T *srcFrom, const T *srcTo, T *dstFrom)
}
}
+#if defined(Q_CC_MSVC)
+#pragma warning( push )
+#pragma warning( disable : 4127 ) // conditional expression is constant
+#endif
+
template <typename T>
void QVector<T>::destruct(T *from, T *to)
{
@@ -297,6 +302,10 @@ void QVector<T>::destruct(T *from, T *to)
}
}
+#if defined(Q_CC_MSVC)
+#pragma warning( pop )
+#endif
+
template <typename T>
inline QVector<T>::QVector(const QVector<T> &v)
{
diff --git a/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp b/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp
index 6a012879d4..144858816b 100644
--- a/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp
+++ b/src/gui/doc/snippets/code/src_gui_painting_qpainter.cpp
@@ -207,7 +207,7 @@ QRectF source(0.0, 0.0, 70.0, 40.0);
QPixmap pixmap(":myPixmap.png");
QPainter(this);
-painter.drawPixmap(target, image, source);
+painter.drawPixmap(target, pixmap, source);
//! [16]
diff --git a/src/gui/image/qjpeghandler.cpp b/src/gui/image/qjpeghandler.cpp
index 22d82ba894..dfacf34097 100644
--- a/src/gui/image/qjpeghandler.cpp
+++ b/src/gui/image/qjpeghandler.cpp
@@ -856,7 +856,6 @@ bool QJpegHandlerPrivate::read(QImage *image)
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len);
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_ssse3(quint32 *dst, const uchar *src, int len);
-Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_avx(quint32 *dst, const uchar *src, int len);
extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uchar *src, int len);
QJpegHandler::QJpegHandler()
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 295380a93c..92d9871dc5 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -4361,13 +4361,13 @@ void QTouchEvent::TouchPoint::setFlags(InfoFlags flags)
\ingroup events
\inmodule QtGui
- \brief The QScrollPrepareEvent class is send in preparation of a scrolling.
+ \brief The QScrollPrepareEvent class is sent in preparation of scrolling.
- The scroll prepare event is send before scrolling (usually by QScroller) is started.
+ The scroll prepare event is sent before scrolling (usually by QScroller) is started.
The object receiving this event should set viewportSize, maxContentPos and contentPos.
It also should accept this event to indicate that scrolling should be started.
- It is not guaranteed that a QScrollEvent will be send after an acceepted
+ It is not guaranteed that a QScrollEvent will be sent after an acceepted
QScrollPrepareEvent, e.g. in a case where the maximum content position is (0,0).
\sa QScrollEvent, QScroller
@@ -4462,9 +4462,9 @@ void QScrollPrepareEvent::setContentPos(const QPointF &pos)
\ingroup events
\inmodule QtGui
- \brief The QScrollEvent class is send when scrolling.
+ \brief The QScrollEvent class is sent when scrolling.
- The scroll event is send to indicate that the receiver should be scrolled.
+ The scroll event is sent to indicate that the receiver should be scrolled.
Usually the receiver should be something visual like QWidget or QGraphicsObject.
Some care should be taken that no conflicting QScrollEvents are sent from two
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index c6376b2647..a19eebfb7c 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2294,6 +2294,18 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To
if (w->d_func()->blockedByModalWindow) {
// a modal window is blocking this window, don't allow touch events through
+
+ // QTBUG-37371 temporary fix; TODO: revisit in 5.4 when we have a forwarding solution
+ if (eventType == QEvent::TouchEnd) {
+ // but don't leave dangling state: e.g.
+ // QQuickWindowPrivate::itemForTouchPointId needs to be cleared.
+ QTouchEvent touchEvent(QEvent::TouchCancel,
+ e->device,
+ e->modifiers);
+ touchEvent.setTimestamp(e->timestamp);
+ touchEvent.setWindow(w);
+ QGuiApplication::sendSpontaneousEvent(w, &touchEvent);
+ }
continue;
}
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index fb7d15c160..5087e33b47 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -247,8 +247,8 @@ QMutex QOpenGLContextPrivate::makeCurrentTrackerMutex;
To set up a context, set its screen and format such that they match those
of the surface or surfaces with which the context is meant to be used, if
necessary make it share resources with other contexts with
- setShareContext(), and finally call create(). Use isValid() to check if the
- context was successfully initialized.
+ setShareContext(), and finally call create(). Use the return value or isValid()
+ to check if the context was successfully initialized.
A context can be made current against a given surface by calling
makeCurrent(). When OpenGL rendering is done, call swapBuffers() to swap
@@ -491,7 +491,7 @@ bool QOpenGLContext::create()
d->shareContext = 0;
d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup;
d->shareGroup->d_func()->addContext(this);
- return d->platformGLContext;
+ return isValid();
}
/*!
@@ -578,6 +578,9 @@ bool QOpenGLContext::isValid() const
without having to manage it manually.
The context or a sharing context must be current.
+
+ The returned QOpenGLFunctions instance is ready to be used and it
+ does not need initializeOpenGLFunctions() to be called.
*/
QOpenGLFunctions *QOpenGLContext::functions() const
{
diff --git a/src/gui/kernel/qplatformtheme.h b/src/gui/kernel/qplatformtheme.h
index 073eda8d07..a2d14be0fb 100644
--- a/src/gui/kernel/qplatformtheme.h
+++ b/src/gui/kernel/qplatformtheme.h
@@ -130,6 +130,7 @@ public:
ComboBoxPalette,
ItemViewPalette,
MessageBoxLabelPelette,
+ MessageBoxLabelPalette = MessageBoxLabelPelette,
TabBarPalette,
LabelPalette,
GroupBoxPalette,
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index 2b6cb2d949..23c0e59779 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -522,6 +522,10 @@ int QSurfaceFormat::alphaBufferSize() const
/*!
Set the desired \a size in bits of the red channel of the color buffer.
+
+ \note On Mac OSX, be sure to set the buffer size of all color channels,
+ otherwise this setting will have no effect. If one of the buffer sizes is not set,
+ the current bit-depth of the screen is used.
*/
void QSurfaceFormat::setRedBufferSize(int size)
{
@@ -533,6 +537,10 @@ void QSurfaceFormat::setRedBufferSize(int size)
/*!
Set the desired \a size in bits of the green channel of the color buffer.
+
+ \note On Mac OSX, be sure to set the buffer size of all color channels,
+ otherwise this setting will have no effect. If one of the buffer sizes is not set,
+ the current bit-depth of the screen is used.
*/
void QSurfaceFormat::setGreenBufferSize(int size)
{
@@ -544,6 +552,10 @@ void QSurfaceFormat::setGreenBufferSize(int size)
/*!
Set the desired \a size in bits of the blue channel of the color buffer.
+
+ \note On Mac OSX, be sure to set the buffer size of all color channels,
+ otherwise this setting will have no effect. If one of the buffer sizes is not set,
+ the current bit-depth of the screen is used.
*/
void QSurfaceFormat::setBlueBufferSize(int size)
{
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 84c70606b1..ef0ef6d103 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -51,12 +51,12 @@ QT_BEGIN_NAMESPACE
/*!
\class QOpenGLFunctions
- \brief The QOpenGLFunctions class provides cross-platform access to the OpenGL/ES 2.0 API.
+ \brief The QOpenGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
\since 5.0
\ingroup painting-3D
\inmodule QtGui
- OpenGL/ES 2.0 defines a subset of the OpenGL specification that is
+ OpenGL ES 2.0 defines a subset of the OpenGL specification that is
common across many desktop and embedded OpenGL implementations.
However, it can be difficult to use the functions from that subset
because they need to be resolved manually on desktop systems.
@@ -102,7 +102,7 @@ QT_BEGIN_NAMESPACE
}
\endcode
- The \c{paintGL()} function can then use any of the OpenGL/ES 2.0
+ The \c{paintGL()} function can then use any of the OpenGL ES 2.0
functions without explicit resolution, such as glActiveTexture()
in the following example:
@@ -119,14 +119,14 @@ QT_BEGIN_NAMESPACE
\endcode
QOpenGLFunctions can also be used directly for ad-hoc invocation
- of OpenGL/ES 2.0 functions on all platforms:
+ of OpenGL ES 2.0 functions on all platforms:
\code
QOpenGLFunctions glFuncs(QOpenGLContext::currentContext());
glFuncs.glActiveTexture(GL_TEXTURE1);
\endcode
- QOpenGLFunctions provides wrappers for all OpenGL/ES 2.0
+ QOpenGLFunctions provides wrappers for all OpenGL ES 2.0
functions, including the common subset of OpenGL 1.x and ES
2.0. While such functions, for example glClear() or
glDrawArrays(), can be called also directly, as long as the
@@ -135,7 +135,7 @@ QT_BEGIN_NAMESPACE
loading the OpenGL implementation.
The hasOpenGLFeature() and openGLFeatures() functions can be used
- to determine if the OpenGL implementation has a major OpenGL/ES 2.0
+ to determine if the OpenGL implementation has a major OpenGL ES 2.0
feature. For example, the following checks if non power of two
textures are available:
@@ -359,10 +359,37 @@ static int qt_gl_resolve_extensions()
{
int extensions = 0;
QOpenGLExtensionMatcher extensionMatcher;
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ QSurfaceFormat format = ctx->format();
+
if (extensionMatcher.match("GL_EXT_bgra"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
-
- if (QOpenGLContext::currentContext()->isES()) {
+ if (extensionMatcher.match("GL_ARB_texture_rectangle"))
+ extensions |= QOpenGLExtensions::TextureRectangle;
+ if (extensionMatcher.match("GL_SGIS_generate_mipmap"))
+ extensions |= QOpenGLExtensions::GenerateMipmap;
+ if (extensionMatcher.match("GL_ARB_texture_compression"))
+ extensions |= QOpenGLExtensions::TextureCompression;
+ if (extensionMatcher.match("GL_EXT_texture_compression_s3tc"))
+ extensions |= QOpenGLExtensions::DDSTextureCompression;
+ if (extensionMatcher.match("GL_OES_compressed_ETC1_RGB8_texture"))
+ extensions |= QOpenGLExtensions::ETC1TextureCompression;
+ if (extensionMatcher.match("GL_IMG_texture_compression_pvrtc"))
+ extensions |= QOpenGLExtensions::PVRTCTextureCompression;
+ if (extensionMatcher.match("GL_ARB_texture_mirrored_repeat"))
+ extensions |= QOpenGLExtensions::MirroredRepeat;
+ if (extensionMatcher.match("GL_EXT_stencil_two_side"))
+ extensions |= QOpenGLExtensions::StencilTwoSide;
+ if (extensionMatcher.match("GL_EXT_stencil_wrap"))
+ extensions |= QOpenGLExtensions::StencilWrap;
+ if (extensionMatcher.match("GL_NV_float_buffer"))
+ extensions |= QOpenGLExtensions::NVFloatBuffer;
+ if (extensionMatcher.match("GL_ARB_pixel_buffer_object"))
+ extensions |= QOpenGLExtensions::PixelBufferObject;
+
+ if (ctx->isES()) {
+ if (format.majorVersion() >= 2)
+ extensions |= QOpenGLExtensions::GenerateMipmap;
if (extensionMatcher.match("GL_OES_mapbuffer"))
extensions |= QOpenGLExtensions::MapBuffer;
if (extensionMatcher.match("GL_OES_packed_depth_stencil"))
@@ -375,7 +402,6 @@ static int qt_gl_resolve_extensions()
if (extensionMatcher.match("GL_IMG_texture_format_BGRA8888") || extensionMatcher.match("GL_EXT_texture_format_BGRA8888"))
extensions |= QOpenGLExtensions::BGRATextureFormat;
} else {
- QSurfaceFormat format = QOpenGLContext::currentContext()->format();
extensions |= QOpenGLExtensions::ElementIndexUint | QOpenGLExtensions::MapBuffer;
// Recognize features by extension name.
@@ -394,6 +420,19 @@ static int qt_gl_resolve_extensions()
extensions |= QOpenGLExtensions::PackedDepthStencil;
}
}
+
+ if (format.renderableType() == QSurfaceFormat::OpenGL && format.version() >= qMakePair(3, 2))
+ extensions |= QOpenGLExtensions::GeometryShaders;
+
+#ifndef QT_OPENGL_ES
+ if (extensionMatcher.match("GL_EXT_framebuffer_sRGB")) {
+ GLboolean srgbCapableFramebuffers = false;
+ ctx->functions()->glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgbCapableFramebuffers);
+ if (srgbCapableFramebuffers)
+ extensions |= QOpenGLExtensions::SRGBFrameBuffer;
+ }
+#endif
+
return extensions;
}
@@ -498,7 +537,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBindTexture(\a target, \a texture).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindTexture.xml}{glBindTexture()}.
\since 5.3
@@ -509,7 +548,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBlendFunc(\a sfactor, \a dfactor).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendFunc.xml}{glBlendFunc()}.
\since 5.3
@@ -520,7 +559,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glClear(\a mask).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glClear.xml}{glClear()}.
\since 5.3
@@ -531,7 +570,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glClearColor(\a red, \a green, \a blue, \a alpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glClearColor.xml}{glClearColor()}.
\since 5.3
@@ -542,7 +581,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glClearStencil(\a s).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glClearStencil.xml}{glClearStencil()}.
\since 5.3
@@ -553,7 +592,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glColorMask(\a red, \a green, \a blue, \a alpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glColorMask.xml}{glColorMask()}.
\since 5.3
@@ -564,7 +603,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCopyTexImage2D(\a target, \a level, \a internalformat, \a x, \a y, \a width, \a height, \a border).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCopyTexImage2D.xml}{glCopyTexImage2D()}.
\since 5.3
@@ -575,7 +614,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCopyTexSubImage2D(\a target, \a level, \a xoffset, \a yoffset, \a x, \a y, \a width, \a height).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCopyTexSubImage2D.xml}{glCopyTexSubImage2D()}.
\since 5.3
@@ -586,7 +625,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCullFace(\a mode).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCullFace.xml}{glCullFace()}.
\since 5.3
@@ -597,7 +636,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDeleteTextures(\a n, \a textures).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteTextures.xml}{glDeleteTextures()}.
\since 5.3
@@ -608,7 +647,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDepthFunc(\a func).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDepthFunc.xml}{glDepthFunc()}.
\since 5.3
@@ -619,7 +658,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDepthMask(\a flag).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDepthMask.xml}{glDepthMask()}.
\since 5.3
@@ -630,7 +669,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDisable(\a cap).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDisable.xml}{glDisable()}.
\since 5.3
@@ -641,7 +680,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDrawArrays(\a mode, \a first, \a count).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDrawArrays.xml}{glDrawArrays()}.
\since 5.3
@@ -652,7 +691,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDrawElements(\a mode, \a count, \a type, \a indices).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDrawElements.xml}{glDrawElements()}.
\since 5.3
@@ -663,7 +702,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glEnable(\a cap).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glEnable.xml}{glEnable()}.
\since 5.3
@@ -674,7 +713,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glFinish().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glFinish.xml}{glFinish()}.
\since 5.3
@@ -685,7 +724,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glFlush().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glFlush.xml}{glFlush()}.
\since 5.3
@@ -696,7 +735,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glFrontFace(\a mode).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glFrontFace.xml}{glFrontFace()}.
\since 5.3
@@ -707,7 +746,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGenTextures(\a n, \a textures).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenTextures.xml}{glGenTextures()}.
\since 5.3
@@ -718,7 +757,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetBooleanv(\a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetBooleanv.xml}{glGetBooleanv()}.
\since 5.3
@@ -729,7 +768,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetError().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetError.xml}{glGetError()}.
\since 5.3
@@ -740,7 +779,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetFloatv(\a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetFloatv.xml}{glGetFloatv()}.
\since 5.3
@@ -751,7 +790,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetIntegerv(\a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetIntegerv.xml}{glGetIntegerv()}.
\since 5.3
@@ -762,7 +801,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetString(\a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetString.xml}{glGetString()}.
\since 5.3
@@ -773,7 +812,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetTexParameterfv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetTexParameterfv.xml}{glGetTexParameterfv()}.
\since 5.3
@@ -784,7 +823,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetTexParameteriv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetTexParameteriv.xml}{glGetTexParameteriv()}.
\since 5.3
@@ -795,7 +834,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glHint(\a target, \a mode).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glHint.xml}{glHint()}.
\since 5.3
@@ -806,7 +845,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glIsEnabled(\a cap).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsEnabled.xml}{glIsEnabled()}.
\since 5.3
@@ -817,7 +856,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glIsTexture(\a texture).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsTexture.xml}{glIsTexture()}.
\since 5.3
@@ -828,7 +867,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glLineWidth(\a width).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glLineWidth.xml}{glLineWidth()}.
\since 5.3
@@ -839,7 +878,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glPixelStorei(\a pname, \a param).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glPixelStorei.xml}{glPixelStorei()}.
\since 5.3
@@ -850,7 +889,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glPolygonOffset(\a factor, \a units).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glPolygonOffset.xml}{glPolygonOffset()}.
\since 5.3
@@ -861,7 +900,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glReadPixels(\a x, \a y, \a width, \a height, \a format, \a type, \a pixels).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glReadPixels.xml}{glReadPixels()}.
\since 5.3
@@ -872,7 +911,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glScissor(\a x, \a y, \a width, \a height).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glScissor.xml}{glScissor()}.
\since 5.3
@@ -883,7 +922,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glStencilFunc(\a func, \a ref, \a mask).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilFunc.xml}{glStencilFunc()}.
\since 5.3
@@ -894,7 +933,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glStencilMask(\a mask).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilMask.xml}{glStencilMask()}.
\since 5.3
@@ -905,7 +944,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glStencilOp(\a fail, \a zfail, \a zpass).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilOp.xml}{glStencilOp()}.
\since 5.3
@@ -916,7 +955,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glTexImage2D(\a target, \a level, \a internalformat, \a width, \a height, \a border, \a format, \a type, \a pixels).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glTexImage2D.xml}{glTexImage2D()}.
\since 5.3
@@ -927,7 +966,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glTexParameterf(\a target, \a pname, \a param).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glTexParameterf.xml}{glTexParameterf()}.
\since 5.3
@@ -938,7 +977,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glTexParameterfv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glTexParameterfv.xml}{glTexParameterfv()}.
\since 5.3
@@ -949,7 +988,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glTexParameteri(\a target, \a pname, \a param).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glTexParameteri.xml}{glTexParameteri()}.
\since 5.3
@@ -960,7 +999,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glTexParameteriv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glTexParameteriv.xml}{glTexParameteriv()}.
\since 5.3
@@ -971,7 +1010,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glTexSubImage2D(\a target, \a level, \a xoffset, \a yoffset, \a width, \a height, \a format, \a type, \a pixels).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glTexSubImage2D.xml}{glTexSubImage2D()}.
\since 5.3
@@ -982,7 +1021,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glViewport(\a x, \a y, \a width, \a height).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glViewport.xml}{glViewport()}.
\since 5.3
@@ -993,7 +1032,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glActiveTexture(\a texture).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glActiveTexture.xml}{glActiveTexture()}.
*/
@@ -1002,10 +1041,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glAttachShader(\a program, \a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glAttachShader.xml}{glAttachShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1013,10 +1052,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBindAttribLocation(\a program, \a index, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindAttribLocation.xml}{glBindAttribLocation()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1024,7 +1063,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBindBuffer(\a target, \a buffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindBuffer.xml}{glBindBuffer()}.
*/
@@ -1036,7 +1075,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Note that Qt will translate a \a framebuffer argument of 0 to the currently
bound QOpenGLContext's defaultFramebufferObject().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindFramebuffer.xml}{glBindFramebuffer()}.
*/
@@ -1045,7 +1084,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBindRenderbuffer(\a target, \a renderbuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindRenderbuffer.xml}{glBindRenderbuffer()}.
*/
@@ -1054,7 +1093,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBlendColor(\a red, \a green, \a blue, \a alpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendColor.xml}{glBlendColor()}.
*/
@@ -1063,7 +1102,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBlendEquation(\a mode).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquation.xml}{glBlendEquation()}.
*/
@@ -1072,7 +1111,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBlendEquationSeparate(\a modeRGB, \a modeAlpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquationSeparate.xml}{glBlendEquationSeparate()}.
*/
@@ -1081,7 +1120,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBlendFuncSeparate(\a srcRGB, \a dstRGB, \a srcAlpha, \a dstAlpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendFuncSeparate.xml}{glBlendFuncSeparate()}.
*/
@@ -1090,7 +1129,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBufferData.xml}{glBufferData()}.
*/
@@ -1099,7 +1138,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBufferSubData.xml}{glBufferSubData()}.
*/
@@ -1108,7 +1147,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCheckFramebufferStatus(\a target).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCheckFramebufferStatus.xml}{glCheckFramebufferStatus()}.
*/
@@ -1117,9 +1156,9 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glClearDepth(\a depth) on
desktop OpenGL systems and glClearDepthf(\a depth) on
- embedded OpenGL/ES systems.
+ embedded OpenGL ES systems.
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glClearDepthf.xml}{glClearDepthf()}.
*/
@@ -1128,10 +1167,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCompileShader(\a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCompileShader.xml}{glCompileShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1139,7 +1178,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCompressedTexImage2D(\a target, \a level, \a internalformat, \a width, \a height, \a border, \a imageSize, \a data).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexImage2D.xml}{glCompressedTexImage2D()}.
*/
@@ -1148,7 +1187,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCompressedTexSubImage2D(\a target, \a level, \a xoffset, \a yoffset, \a width, \a height, \a format, \a imageSize, \a data).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexSubImage2D.xml}{glCompressedTexSubImage2D()}.
*/
@@ -1157,10 +1196,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCreateProgram().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCreateProgram.xml}{glCreateProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1168,10 +1207,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glCreateShader(\a type).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCreateShader.xml}{glCreateShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1179,7 +1218,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDeleteBuffers(\a n, \a buffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteBuffers.xml}{glDeleteBuffers()}.
*/
@@ -1188,7 +1227,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDeleteFramebuffers(\a n, \a framebuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteFramebuffers.xml}{glDeleteFramebuffers()}.
*/
@@ -1197,10 +1236,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDeleteProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteProgram.xml}{glDeleteProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1208,7 +1247,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDeleteRenderbuffers(\a n, \a renderbuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteRenderbuffers.xml}{glDeleteRenderbuffers()}.
*/
@@ -1217,10 +1256,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDeleteShader(\a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteShader.xml}{glDeleteShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1228,9 +1267,9 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDepthRange(\a zNear, \a zFar) on
desktop OpenGL systems and glDepthRangef(\a zNear, \a zFar) on
- embedded OpenGL/ES systems.
+ embedded OpenGL ES systems.
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDepthRangef.xml}{glDepthRangef()}.
*/
@@ -1239,10 +1278,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDetachShader(\a program, \a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDetachShader.xml}{glDetachShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1250,10 +1289,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glDisableVertexAttribArray(\a index).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDisableVertexAttribArray.xml}{glDisableVertexAttribArray()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1261,10 +1300,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glEnableVertexAttribArray(\a index).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glEnableVertexAttribArray.xml}{glEnableVertexAttribArray()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1272,7 +1311,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glFramebufferRenderbuffer(\a target, \a attachment, \a renderbuffertarget, \a renderbuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferRenderbuffer.xml}{glFramebufferRenderbuffer()}.
*/
@@ -1281,7 +1320,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glFramebufferTexture2D(\a target, \a attachment, \a textarget, \a texture, \a level).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferTexture2D.xml}{glFramebufferTexture2D()}.
*/
@@ -1290,7 +1329,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGenBuffers(\a n, \a buffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenBuffers.xml}{glGenBuffers()}.
*/
@@ -1299,7 +1338,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGenerateMipmap(\a target).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenerateMipmap.xml}{glGenerateMipmap()}.
*/
@@ -1308,7 +1347,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGenFramebuffers(\a n, \a framebuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenFramebuffers.xml}{glGenFramebuffers()}.
*/
@@ -1317,7 +1356,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGenRenderbuffers(\a n, \a renderbuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenRenderbuffers.xml}{glGenRenderbuffers()}.
*/
@@ -1326,10 +1365,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetActiveAttrib(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveAttrib.xml}{glGetActiveAttrib()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1337,10 +1376,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetActiveUniform(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveUniform.xml}{glGetActiveUniform()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1348,10 +1387,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetAttachedShaders(\a program, \a maxcount, \a count, \a shaders).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttachedShaders.xml}{glGetAttachedShaders()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1359,10 +1398,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetAttribLocation(\a program, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttribLocation.xml}{glGetAttribLocation()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1370,7 +1409,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetBufferParameteriv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetBufferParameteriv.xml}{glGetBufferParameteriv()}.
*/
@@ -1379,7 +1418,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetFramebufferAttachmentParameteriv(\a target, \a attachment, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetFramebufferAttachmentParameteriv.xml}{glGetFramebufferAttachmentParameteriv()}.
*/
@@ -1388,10 +1427,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetProgramiv(\a program, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramiv.xml}{glGetProgramiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1399,10 +1438,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetProgramInfoLog(\a program, \a bufsize, \a length, \a infolog).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramInfoLog.xml}{glGetProgramInfoLog()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1410,7 +1449,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetRenderbufferParameteriv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetRenderbufferParameteriv.xml}{glGetRenderbufferParameteriv()}.
*/
@@ -1419,10 +1458,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetShaderiv(\a shader, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderiv.xml}{glGetShaderiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1430,10 +1469,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetShaderInfoLog(\a shader, \a bufsize, \a length, \a infolog).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderInfoLog.xml}{glGetShaderInfoLog()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1441,10 +1480,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetShaderPrecisionFormat(\a shadertype, \a precisiontype, \a range, \a precision).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderPrecisionFormat.xml}{glGetShaderPrecisionFormat()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1452,10 +1491,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetShaderSource(\a shader, \a bufsize, \a length, \a source).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderSource.xml}{glGetShaderSource()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1463,10 +1502,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetUniformfv(\a program, \a location, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformfv.xml}{glGetUniformfv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1474,10 +1513,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetUniformiv(\a program, \a location, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformiv.xml}{glGetUniformiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1485,10 +1524,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetUniformLocation(\a program, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformLocation.xml}{glGetUniformLocation()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1496,10 +1535,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetVertexAttribfv(\a index, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribfv.xml}{glGetVertexAttribfv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1507,10 +1546,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetVertexAttribiv(\a index, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribiv.xml}{glGetVertexAttribiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1518,10 +1557,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glGetVertexAttribPointerv(\a index, \a pname, \a pointer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribPointerv.xml}{glGetVertexAttribPointerv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1529,7 +1568,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glIsBuffer(\a buffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsBuffer.xml}{glIsBuffer()}.
*/
@@ -1538,7 +1577,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glIsFramebuffer(\a framebuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsFramebuffer.xml}{glIsFramebuffer()}.
*/
@@ -1547,10 +1586,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glIsProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsProgram.xml}{glIsProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1558,7 +1597,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glIsRenderbuffer(\a renderbuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsRenderbuffer.xml}{glIsRenderbuffer()}.
*/
@@ -1567,10 +1606,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glIsShader(\a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsShader.xml}{glIsShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1578,10 +1617,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glLinkProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glLinkProgram.xml}{glLinkProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1589,10 +1628,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glReleaseShaderCompiler().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glReleaseShaderCompiler.xml}{glReleaseShaderCompiler()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1600,7 +1639,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glRenderbufferStorage(\a target, \a internalformat, \a width, \a height).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glRenderbufferStorage.xml}{glRenderbufferStorage()}.
*/
@@ -1609,7 +1648,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glSampleCoverage(\a value, \a invert).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glSampleCoverage.xml}{glSampleCoverage()}.
*/
@@ -1618,10 +1657,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glShaderBinary(\a n, \a shaders, \a binaryformat, \a binary, \a length).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glShaderBinary.xml}{glShaderBinary()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1629,10 +1668,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glShaderSource(\a shader, \a count, \a string, \a length).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glShaderSource.xml}{glShaderSource()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1640,7 +1679,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glStencilFuncSeparate(\a face, \a func, \a ref, \a mask).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilFuncSeparate.xml}{glStencilFuncSeparate()}.
*/
@@ -1649,7 +1688,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glStencilMaskSeparate(\a face, \a mask).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilMaskSeparate.xml}{glStencilMaskSeparate()}.
*/
@@ -1658,7 +1697,7 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glStencilOpSeparate(\a face, \a fail, \a zfail, \a zpass).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilOpSeparate.xml}{glStencilOpSeparate()}.
*/
@@ -1667,10 +1706,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform1f(\a location, \a x).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1f.xml}{glUniform1f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1678,10 +1717,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform1fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1fv.xml}{glUniform1fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1689,10 +1728,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform1i(\a location, \a x).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1i.xml}{glUniform1i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1700,10 +1739,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform1iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1iv.xml}{glUniform1iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1711,10 +1750,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform2f(\a location, \a x, \a y).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2f.xml}{glUniform2f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1722,10 +1761,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform2fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2fv.xml}{glUniform2fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1733,10 +1772,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform2i(\a location, \a x, \a y).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2i.xml}{glUniform2i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1744,10 +1783,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform2iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2iv.xml}{glUniform2iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1755,10 +1794,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform3f(\a location, \a x, \a y, \a z).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3f.xml}{glUniform3f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1766,10 +1805,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform3fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3fv.xml}{glUniform3fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1777,10 +1816,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform3i(\a location, \a x, \a y, \a z).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3i.xml}{glUniform3i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1788,10 +1827,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform3iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3iv.xml}{glUniform3iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1799,10 +1838,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform4f(\a location, \a x, \a y, \a z, \a w).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4f.xml}{glUniform4f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1810,10 +1849,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform4fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4fv.xml}{glUniform4fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1821,10 +1860,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform4i(\a location, \a x, \a y, \a z, \a w).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4i.xml}{glUniform4i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1832,10 +1871,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniform4iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4iv.xml}{glUniform4iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1843,10 +1882,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniformMatrix2fv(\a location, \a count, \a transpose, \a value).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix2fv.xml}{glUniformMatrix2fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1854,10 +1893,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniformMatrix3fv(\a location, \a count, \a transpose, \a value).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix3fv.xml}{glUniformMatrix3fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1865,10 +1904,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUniformMatrix4fv(\a location, \a count, \a transpose, \a value).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix4fv.xml}{glUniformMatrix4fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1876,10 +1915,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glUseProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUseProgram.xml}{glUseProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1887,10 +1926,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glValidateProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glValidateProgram.xml}{glValidateProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1898,10 +1937,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib1f(\a indx, \a x).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1f.xml}{glVertexAttrib1f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1909,10 +1948,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib1fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1fv.xml}{glVertexAttrib1fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1920,10 +1959,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib2f(\a indx, \a x, \a y).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2f.xml}{glVertexAttrib2f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1931,10 +1970,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib2fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2fv.xml}{glVertexAttrib2fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1942,10 +1981,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib3f(\a indx, \a x, \a y, \a z).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3f.xml}{glVertexAttrib3f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1953,10 +1992,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib3fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3fv.xml}{glVertexAttrib3fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1964,10 +2003,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib4f(\a indx, \a x, \a y, \a z, \a w).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4f.xml}{glVertexAttrib4f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1975,10 +2014,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttrib4fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4fv.xml}{glVertexAttrib4fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1986,10 +2025,10 @@ void QOpenGLFunctions::initializeOpenGLFunctions()
Convenience function that calls glVertexAttribPointer(\a indx, \a size, \a type, \a normalized, \a stride, \a ptr).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttribPointer.xml}{glVertexAttribPointer()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -3155,8 +3194,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qop
(target, offset, size, data);
}
-#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC)
-
+#ifndef QT_OPENGL_ES_2
// Desktop only
static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
@@ -3164,6 +3202,7 @@ static void QOPENGLF_APIENTRY qopenglfResolveGetTexLevelParameteriv(GLenum targe
RESOLVE_FUNC_VOID(0, GetTexLevelParameteriv)(target, level, pname, params);
}
+#ifndef QT_OPENGL_DYNAMIC
// Special translation functions for ES-specific calls on desktop GL
static void QOPENGLF_APIENTRY qopenglfTranslateClearDepthf(GLclampf depth)
@@ -3176,7 +3215,9 @@ static void QOPENGLF_APIENTRY qopenglfTranslateDepthRangef(GLclampf zNear, GLcla
::glDepthRange(zNear, zFar);
}
-#endif // !ES2 && !DYNAMIC
+#endif // QT_OPENGL_DYNAMIC
+
+#endif // QT_OPENGL_ES2
QOpenGLFunctionsPrivate::QOpenGLFunctionsPrivate(QOpenGLContext *)
{
diff --git a/src/gui/opengl/qopenglshaderprogram.cpp b/src/gui/opengl/qopenglshaderprogram.cpp
index d2429cdd23..bfde270446 100644
--- a/src/gui/opengl/qopenglshaderprogram.cpp
+++ b/src/gui/opengl/qopenglshaderprogram.cpp
@@ -1516,6 +1516,9 @@ void QOpenGLShaderProgram::setAttributeArray
The setAttributeBuffer() function can be used to set the attribute
array to an offset within a vertex buffer.
+ \note Normalization will be enabled. If this is not desired, call
+ glVertexAttribPointer directly through QOpenGLFunctions.
+
\sa setAttributeValue(), setUniformValue(), enableAttributeArray()
\sa disableAttributeArray(), setAttributeBuffer()
*/
@@ -1659,6 +1662,9 @@ void QOpenGLShaderProgram::setAttributeArray
on the \a location. Otherwise the value specified with
setAttributeValue() for \a location will be used.
+ \note Normalization will be enabled. If this is not desired, call
+ glVertexAttribPointer directly through QOpenGLFunctions.
+
\sa setAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeBuffer
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index d52517add2..9710f1677c 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -68,11 +68,8 @@ static const char fragment_shader150[] =
"uniform sampler2D textureSampler;"
"uniform bool swizzle;"
"void main() {"
- " if (swizzle) {"
- " fragcolor = texture(textureSampler, uv).bgra;"
- " } else {"
- " fragcolor = texture(textureSampler,uv);"
- " }"
+ " vec4 tmpFragColor = texture(textureSampler, uv);"
+ " fragcolor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
"}";
static const char vertex_shader[] =
@@ -91,11 +88,8 @@ static const char fragment_shader[] =
"uniform sampler2D textureSampler;"
"uniform bool swizzle;"
"void main() {"
- " if (swizzle) {"
- " gl_FragColor = texture2D(textureSampler, uv).bgra;"
- " } else {"
- " gl_FragColor = texture2D(textureSampler,uv);"
- " }"
+ " highp vec4 tmpFragColor = texture2D(textureSampler,uv);"
+ " gl_FragColor = swizzle ? tmpFragColor.bgra : tmpFragColor;"
"}";
static const GLfloat vertex_buffer_data[] = {
diff --git a/src/gui/opengl/qopengltextureglyphcache.cpp b/src/gui/opengl/qopengltextureglyphcache.cpp
index 5844bf639c..3287bbb972 100644
--- a/src/gui/opengl/qopengltextureglyphcache.cpp
+++ b/src/gui/opengl/qopengltextureglyphcache.cpp
@@ -350,17 +350,7 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed
return;
}
- QImage mask;
-
- if (m_current_fontengine->hasInternalCaching()) {
- QImage *alphaMap = m_current_fontengine->lockedAlphaMapForGlyph(glyph, subPixelPosition, QFontEngine::Format_None);
- if (!alphaMap || alphaMap->isNull())
- return;
- mask = alphaMap->copy();
- m_current_fontengine->unlockAlphaMapForGlyph();
- } else {
- mask = textureMapForGlyph(glyph, subPixelPosition);
- }
+ QImage mask = textureMapForGlyph(glyph, subPixelPosition);
const int maskWidth = mask.width();
const int maskHeight = mask.height();
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 6bf80eddbd..ed45b8ea17 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -19,6 +19,8 @@ HEADERS += \
painting/qoutlinemapper_p.h \
painting/qpagedpaintdevice.h \
painting/qpagedpaintdevice_p.h \
+ painting/qpagelayout.h \
+ painting/qpagesize.h \
painting/qpaintdevice.h \
painting/qpaintengine.h \
painting/qpaintengine_p.h \
@@ -66,6 +68,8 @@ SOURCES += \
painting/qmemrotate.cpp \
painting/qoutlinemapper.cpp \
painting/qpagedpaintdevice.cpp \
+ painting/qpagelayout.cpp \
+ painting/qpagesize.cpp \
painting/qpaintdevice.cpp \
painting/qpaintengine.cpp \
painting/qpaintengineex.cpp \
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 3f598cd3a7..c7472cca29 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -5937,7 +5937,7 @@ static void qt_gradient_quint16(int count, const QSpan *spans, void *userData)
}
}
-inline static void qt_bitmapblit_quint32(QRasterBuffer *rasterBuffer,
+inline static void qt_bitmapblit_argb32(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
const uchar *map,
int mapWidth, int mapHeight, int mapStride)
@@ -5946,6 +5946,15 @@ inline static void qt_bitmapblit_quint32(QRasterBuffer *rasterBuffer,
map, mapWidth, mapHeight, mapStride);
}
+inline static void qt_bitmapblit_rgba8888(QRasterBuffer *rasterBuffer,
+ int x, int y, quint32 color,
+ const uchar *map,
+ int mapWidth, int mapHeight, int mapStride)
+{
+ qt_bitmapblit_template<quint32>(rasterBuffer, x, y, ARGB2RGBA(color),
+ map, mapWidth, mapHeight, mapStride);
+}
+
inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
const uchar *map,
@@ -6057,11 +6066,11 @@ static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, in
}
#endif
-static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
- const uchar *map,
- int mapWidth, int mapHeight, int mapStride,
- const QClipData *clip)
+static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
+ int x, int y, quint32 color,
+ const uchar *map,
+ int mapWidth, int mapHeight, int mapStride,
+ const QClipData *clip)
{
const quint32 c = color;
const int destStride = rasterBuffer->bytesPerLine() / sizeof(quint32);
@@ -6152,10 +6161,19 @@ static void qt_alphamapblit_quint32(QRasterBuffer *rasterBuffer,
}
}
-static void qt_alphargbblit_quint32(QRasterBuffer *rasterBuffer,
- int x, int y, quint32 color,
- const uint *src, int mapWidth, int mapHeight, int srcStride,
- const QClipData *clip)
+static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer,
+ int x, int y, quint32 color,
+ const uchar *map,
+ int mapWidth, int mapHeight, int mapStride,
+ const QClipData *clip)
+{
+ qt_alphamapblit_argb32(rasterBuffer, x, y, ARGB2RGBA(color), map, mapWidth, mapHeight, mapStride, clip);
+}
+
+static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
+ int x, int y, quint32 color,
+ const uint *src, int mapWidth, int mapHeight, int srcStride,
+ const QClipData *clip)
{
const quint32 c = color;
@@ -6297,27 +6315,27 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
{
blend_color_argb,
qt_gradient_argb32,
- qt_bitmapblit_quint32,
- qt_alphamapblit_quint32,
- qt_alphargbblit_quint32,
+ qt_bitmapblit_argb32,
+ qt_alphamapblit_argb32,
+ qt_alphargbblit_argb32,
qt_rectfill_argb32
},
// Format_ARGB32,
{
blend_color_generic,
qt_gradient_argb32,
- qt_bitmapblit_quint32,
- qt_alphamapblit_quint32,
- qt_alphargbblit_quint32,
+ qt_bitmapblit_argb32,
+ qt_alphamapblit_argb32,
+ qt_alphargbblit_argb32,
qt_rectfill_nonpremul_argb32
},
// Format_ARGB32_Premultiplied
{
blend_color_argb,
qt_gradient_argb32,
- qt_bitmapblit_quint32,
- qt_alphamapblit_quint32,
- qt_alphargbblit_quint32,
+ qt_bitmapblit_argb32,
+ qt_alphamapblit_argb32,
+ qt_alphargbblit_argb32,
qt_rectfill_argb32
},
// Format_RGB16
@@ -6381,42 +6399,39 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
{
blend_color_generic,
blend_src_generic,
- qt_bitmapblit_quint32,
+ qt_bitmapblit_rgba8888,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qt_alphamapblit_quint32,
- qt_alphargbblit_quint32,
+ qt_alphamapblit_rgba8888,
#else
0,
- 0,
#endif
+ 0,
qt_rectfill_rgba
},
// Format_RGBA8888
{
blend_color_generic,
blend_src_generic,
- qt_bitmapblit_quint32,
+ qt_bitmapblit_rgba8888,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qt_alphamapblit_quint32,
- qt_alphargbblit_quint32,
+ qt_alphamapblit_rgba8888,
#else
0,
- 0,
#endif
+ 0,
qt_rectfill_nonpremul_rgba
},
// Format_RGB8888_Premultiplied
{
blend_color_generic,
blend_src_generic,
- qt_bitmapblit_quint32,
+ qt_bitmapblit_rgba8888,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- qt_alphamapblit_quint32,
- qt_alphargbblit_quint32,
+ qt_alphamapblit_rgba8888,
#else
0,
- 0,
#endif
+ 0,
qt_rectfill_rgba
}
};
@@ -6502,9 +6517,9 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_ARGB32].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_ARGB32_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
qDrawHelper[QImage::Format_RGB16].bitmapBlit = qt_bitmapblit16_sse2;
- qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit32_sse2;
- qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit32_sse2;
+ qDrawHelper[QImage::Format_RGBX8888].bitmapBlit = qt_bitmapblit8888_sse2;
+ qDrawHelper[QImage::Format_RGBA8888].bitmapBlit = qt_bitmapblit8888_sse2;
+ qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2;
extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const uchar *srcPixels, int sbpl,
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index f5523f7113..c37858d679 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -476,6 +476,13 @@ void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
}
}
+void qt_bitmapblit8888_sse2(QRasterBuffer *rasterBuffer, int x, int y,
+ quint32 color,
+ const uchar *src, int width, int height, int stride)
+{
+ qt_bitmapblit32_sse2(rasterBuffer, x, y, ARGB2RGBA(color), src, width, height, stride);
+}
+
void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride)
diff --git a/src/gui/painting/qdrawhelper_x86_p.h b/src/gui/painting/qdrawhelper_x86_p.h
index 699c586cb0..97c1f87c2a 100644
--- a/src/gui/painting/qdrawhelper_x86_p.h
+++ b/src/gui/painting/qdrawhelper_x86_p.h
@@ -63,6 +63,9 @@ void qt_memfill16(quint16 *dest, quint16 value, int count);
void qt_bitmapblit32_sse2(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride);
+void qt_bitmapblit8888_sse2(QRasterBuffer *rasterBuffer, int x, int y,
+ quint32 color,
+ const uchar *src, int width, int height, int stride);
void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y,
quint32 color,
const uchar *src, int width, int height, int stride);
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
index b95b3e3503..18ba964a26 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -44,42 +44,6 @@
QT_BEGIN_NAMESPACE
-static const struct {
- float width;
- float height;
-} pageSizes[] = {
- {210, 297}, // A4
- {176, 250}, // B5
- {215.9f, 279.4f}, // Letter
- {215.9f, 355.6f}, // Legal
- {190.5f, 254}, // Executive
- {841, 1189}, // A0
- {594, 841}, // A1
- {420, 594}, // A2
- {297, 420}, // A3
- {148, 210}, // A5
- {105, 148}, // A6
- {74, 105}, // A7
- {52, 74}, // A8
- {37, 52}, // A8
- {1000, 1414}, // B0
- {707, 1000}, // B1
- {31, 44}, // B10
- {500, 707}, // B2
- {353, 500}, // B3
- {250, 353}, // B4
- {125, 176}, // B6
- {88, 125}, // B7
- {62, 88}, // B8
- {44, 62}, // B9
- {163, 229}, // C5E
- {105, 241}, // US Common
- {110, 220}, // DLE
- {210, 330}, // Folio
- {431.8f, 279.4f}, // Ledger
- {279.4f, 431.8f} // Tabloid
-};
-
/*!
\class QPagedPaintDevice
\inmodule QtGui
@@ -110,46 +74,147 @@ QPagedPaintDevice::~QPagedPaintDevice()
}
/*!
- \enum QPagedPaintDevice::PageSize
-
- This enum type specifies the page size of the paint device.
-
- \value A0 841 x 1189 mm
- \value A1 594 x 841 mm
- \value A2 420 x 594 mm
- \value A3 297 x 420 mm
- \value A4 210 x 297 mm, 8.26 x 11.69 inches
- \value A5 148 x 210 mm
- \value A6 105 x 148 mm
- \value A7 74 x 105 mm
- \value A8 52 x 74 mm
- \value A9 37 x 52 mm
- \value B0 1000 x 1414 mm
- \value B1 707 x 1000 mm
- \value B2 500 x 707 mm
- \value B3 353 x 500 mm
- \value B4 250 x 353 mm
- \value B5 176 x 250 mm, 6.93 x 9.84 inches
- \value B6 125 x 176 mm
- \value B7 88 x 125 mm
- \value B8 62 x 88 mm
- \value B9 44 x 62 mm
- \value B10 31 x 44 mm
- \value C5E 163 x 229 mm
- \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
- \value DLE 110 x 220 mm
- \value Executive 7.5 x 10 inches, 190.5 x 254 mm
- \value Folio 210 x 330 mm
- \value Ledger 431.8 x 279.4 mm
- \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
- \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
- \value Tabloid 279.4 x 431.8 mm
- \value Custom Unknown, or a user defined size.
-
- \omitvalue NPageSize
-
- The page size can also be specified in millimeters using setPageSizeMM(). In this case the
- page size enum is set to Custom.
+ \enum QPagedPaintDevice::PageSize
+
+ This enum type lists the available page sizes as defined in the Postscript
+ PPD standard. These values are duplicated in QPageSize and QPrinter.
+
+ The defined sizes are:
+
+ \value A0 841 x 1189 mm
+ \value A1 594 x 841 mm
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.69 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1000 x 1414 mm
+ \value B1 707 x 1000 mm
+ \value B2 500 x 707 mm
+ \value B3 353 x 500 mm
+ \value B4 250 x 353 mm
+ \value B5 176 x 250 mm, 6.93 x 9.84 inches
+ \value B6 125 x 176 mm
+ \value B7 88 x 125 mm
+ \value B8 62 x 88 mm
+ \value B9 33 x 62 mm
+ \value B10 31 x 44 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 190.5 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 431.8 x 279.4 mm
+ \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
+ \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
+ \value Tabloid 279.4 x 431.8 mm
+ \value Custom Unknown, or a user defined size.
+ \value A10
+ \value A3Extra
+ \value A4Extra
+ \value A4Plus
+ \value A4Small
+ \value A5Extra
+ \value B5Extra
+ \value JisB0
+ \value JisB1
+ \value JisB2
+ \value JisB3
+ \value JisB4
+ \value JisB5
+ \value JisB6,
+ \value JisB7
+ \value JisB8
+ \value JisB9
+ \value JisB10
+ \value AnsiA = Letter
+ \value AnsiB = Ledger
+ \value AnsiC
+ \value AnsiD
+ \value AnsiE
+ \value LegalExtra
+ \value LetterExtra
+ \value LetterPlus
+ \value LetterSmall
+ \value TabloidExtra
+ \value ArchA
+ \value ArchB
+ \value ArchC
+ \value ArchD
+ \value ArchE
+ \value Imperial7x9
+ \value Imperial8x10
+ \value Imperial9x11
+ \value Imperial9x12
+ \value Imperial10x11
+ \value Imperial10x13
+ \value Imperial10x14
+ \value Imperial12x11
+ \value Imperial15x11
+ \value ExecutiveStandard
+ \value Note
+ \value Quarto
+ \value Statement
+ \value SuperA
+ \value SuperB
+ \value Postcard
+ \value DoublePostcard
+ \value Prc16K
+ \value Prc32K
+ \value Prc32KBig
+ \value FanFoldUS
+ \value FanFoldGerman
+ \value FanFoldGermanLegal
+ \value EnvelopeB4
+ \value EnvelopeB5
+ \value EnvelopeB6
+ \value EnvelopeC0
+ \value EnvelopeC1
+ \value EnvelopeC2
+ \value EnvelopeC3
+ \value EnvelopeC4
+ \value EnvelopeC5 = C5E
+ \value EnvelopeC6
+ \value EnvelopeC65
+ \value EnvelopeC7
+ \value EnvelopeDL = DLE
+ \value Envelope9
+ \value Envelope10 = Comm10E
+ \value Envelope11
+ \value Envelope12
+ \value Envelope14
+ \value EnvelopeMonarch
+ \value EnvelopePersonal
+ \value EnvelopeChou3
+ \value EnvelopeChou4
+ \value EnvelopeInvite
+ \value EnvelopeItalian
+ \value EnvelopeKaku2
+ \value EnvelopeKaku3
+ \value EnvelopePrc1
+ \value EnvelopePrc2
+ \value EnvelopePrc3
+ \value EnvelopePrc4
+ \value EnvelopePrc5
+ \value EnvelopePrc6
+ \value EnvelopePrc7
+ \value EnvelopePrc8
+ \value EnvelopePrc9
+ \value EnvelopePrc10
+ \value EnvelopeYou4
+ \value LastPageSize = EnvelopeYou4
+ \omitvalue NPageSize
+ \omitvalue NPaperSize
+
+ Due to historic reasons QPageSize::Executive is not the same as the standard
+ Postscript and Windows Executive size, use QPageSize::ExecutiveStandard instead.
+
+ The Postscript standard size QPageSize::Folio is different to the Windows
+ DMPAPER_FOLIO size, use the Postscript standard size QPageSize::FanFoldGermanLegal
+ if needed.
*/
/*!
@@ -166,10 +231,7 @@ QPagedPaintDevice::~QPagedPaintDevice()
*/
void QPagedPaintDevice::setPageSize(PageSize size)
{
- if (size >= Custom)
- return;
- d->pageSize = size;
- d->pageSizeMM = QSizeF(pageSizes[size].width, pageSizes[size].height);
+ d->m_pageLayout.setPageSize(QPageSize(QPageSize::PageSizeId(size)));
}
/*!
@@ -177,16 +239,18 @@ void QPagedPaintDevice::setPageSize(PageSize size)
*/
QPagedPaintDevice::PageSize QPagedPaintDevice::pageSize() const
{
- return d->pageSize;
+ return PageSize(d->m_pageLayout.pageSize().id());
}
/*!
- Sets the page size to \a size. \a size is specified in millimeters.
- */
+ Sets the page size to \a size. \a size is specified in millimeters.
+
+ If the size matches a standard QPagedPaintDevice::PageSize then that page
+ size will be used, otherwise QPagedPaintDevice::Custom will be set.
+*/
void QPagedPaintDevice::setPageSizeMM(const QSizeF &size)
{
- d->pageSize = Custom;
- d->pageSizeMM = size;
+ d->m_pageLayout.setPageSize(QPageSize(size, QPageSize::Millimeter));
}
/*!
@@ -194,7 +258,7 @@ void QPagedPaintDevice::setPageSizeMM(const QSizeF &size)
*/
QSizeF QPagedPaintDevice::pageSizeMM() const
{
- return d->pageSizeMM;
+ return d->m_pageLayout.pageSize().size(QPageSize::Millimeter);
}
/*!
@@ -209,17 +273,48 @@ QSizeF QPagedPaintDevice::pageSizeMM() const
*/
void QPagedPaintDevice::setMargins(const Margins &margins)
{
- d->margins = margins;
+ d->m_pageLayout.setUnits(QPageLayout::Millimeter);
+ d->m_pageLayout.setMargins(QMarginsF(margins.left, margins.top, margins.right, margins.bottom));
}
/*!
- returns the current margins of the paint device. The default is 0.
+ Returns the current margins of the paint device. The default is 0.
+
+ Margins are specified in millimeters.
\sa setMargins()
*/
QPagedPaintDevice::Margins QPagedPaintDevice::margins() const
{
- return d->margins;
+ QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Millimeter);
+ Margins result;
+ result.left = margins.left();
+ result.top = margins.top();
+ result.right = margins.right();
+ result.bottom = margins.bottom();
+ return result;
+}
+
+/*!
+ \internal
+
+ Returns the internal device page layout.
+*/
+
+QPageLayout QPagedPaintDevice::devicePageLayout() const
+{
+ return d->m_pageLayout;
+}
+
+/*!
+ \internal
+
+ Returns the internal device page layout.
+*/
+
+QPageLayout &QPagedPaintDevice::devicePageLayout()
+{
+ return d->m_pageLayout;
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h
index d44a401184..6d4c422a95 100644
--- a/src/gui/painting/qpagedpaintdevice.h
+++ b/src/gui/painting/qpagedpaintdevice.h
@@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE
#endif
class QPagedPaintDevicePrivate;
+class QPageLayout;
class Q_GUI_EXPORT QPagedPaintDevice : public QPaintDevice
{
@@ -60,10 +61,158 @@ public:
virtual bool newPage() = 0;
- enum PageSize { A4, B5, Letter, Legal, Executive,
- A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
- B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
- DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom };
+ // ### Qt6 Remove in favor of QPage::PageSize
+ // NOTE: Must keep in sync with QPageSize and QPrinter
+ enum PageSize {
+ // Existing Qt sizes
+ A4,
+ B5,
+ Letter,
+ Legal,
+ Executive,
+ A0,
+ A1,
+ A2,
+ A3,
+ A5,
+ A6,
+ A7,
+ A8,
+ A9,
+ B0,
+ B1,
+ B10,
+ B2,
+ B3,
+ B4,
+ B6,
+ B7,
+ B8,
+ B9,
+ C5E,
+ Comm10E,
+ DLE,
+ Folio,
+ Ledger,
+ Tabloid,
+ Custom,
+
+ // New values derived from PPD standard
+ A10,
+ A3Extra,
+ A4Extra,
+ A4Plus,
+ A4Small,
+ A5Extra,
+ B5Extra,
+
+ JisB0,
+ JisB1,
+ JisB2,
+ JisB3,
+ JisB4,
+ JisB5,
+ JisB6,
+ JisB7,
+ JisB8,
+ JisB9,
+ JisB10,
+
+ // AnsiA = Letter,
+ // AnsiB = Ledger,
+ AnsiC,
+ AnsiD,
+ AnsiE,
+ LegalExtra,
+ LetterExtra,
+ LetterPlus,
+ LetterSmall,
+ TabloidExtra,
+
+ ArchA,
+ ArchB,
+ ArchC,
+ ArchD,
+ ArchE,
+
+ Imperial7x9,
+ Imperial8x10,
+ Imperial9x11,
+ Imperial9x12,
+ Imperial10x11,
+ Imperial10x13,
+ Imperial10x14,
+ Imperial12x11,
+ Imperial15x11,
+
+ ExecutiveStandard,
+ Note,
+ Quarto,
+ Statement,
+ SuperA,
+ SuperB,
+ Postcard,
+ DoublePostcard,
+ Prc16K,
+ Prc32K,
+ Prc32KBig,
+
+ FanFoldUS,
+ FanFoldGerman,
+ FanFoldGermanLegal,
+
+ EnvelopeB4,
+ EnvelopeB5,
+ EnvelopeB6,
+ EnvelopeC0,
+ EnvelopeC1,
+ EnvelopeC2,
+ EnvelopeC3,
+ EnvelopeC4,
+ // EnvelopeC5 = C5E,
+ EnvelopeC6,
+ EnvelopeC65,
+ EnvelopeC7,
+ // EnvelopeDL = DLE,
+
+ Envelope9,
+ // Envelope10 = Comm10E,
+ Envelope11,
+ Envelope12,
+ Envelope14,
+ EnvelopeMonarch,
+ EnvelopePersonal,
+
+ EnvelopeChou3,
+ EnvelopeChou4,
+ EnvelopeInvite,
+ EnvelopeItalian,
+ EnvelopeKaku2,
+ EnvelopeKaku3,
+ EnvelopePrc1,
+ EnvelopePrc2,
+ EnvelopePrc3,
+ EnvelopePrc4,
+ EnvelopePrc5,
+ EnvelopePrc6,
+ EnvelopePrc7,
+ EnvelopePrc8,
+ EnvelopePrc9,
+ EnvelopePrc10,
+ EnvelopeYou4,
+
+ // Last item, with commonly used synynoms from QPagedPrintEngine / QPrinter
+ LastPageSize = EnvelopeYou4,
+ NPageSize = LastPageSize,
+ NPaperSize = LastPageSize,
+
+ // Convenience overloads for naming consistency
+ AnsiA = Letter,
+ AnsiB = Ledger,
+ EnvelopeC5 = C5E,
+ EnvelopeDL = DLE,
+ Envelope10 = Comm10E
+ };
virtual void setPageSize(PageSize size);
PageSize pageSize() const;
@@ -71,6 +220,7 @@ public:
virtual void setPageSizeMM(const QSizeF &size);
QSizeF pageSizeMM() const;
+ // ### Qt6 Remove in favor of QMarginsF
struct Margins {
qreal left;
qreal right;
@@ -82,6 +232,8 @@ public:
Margins margins() const;
protected:
+ QPageLayout devicePageLayout() const;
+ QPageLayout &devicePageLayout();
friend class QPagedPaintDevicePrivate;
QPagedPaintDevicePrivate *d;
};
diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h
index d9e5d43903..da58951dc7 100644
--- a/src/gui/painting/qpagedpaintdevice_p.h
+++ b/src/gui/painting/qpagedpaintdevice_p.h
@@ -55,27 +55,25 @@
#include <qpagedpaintdevice.h>
+#include "qpagelayout.h"
+
QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QPagedPaintDevicePrivate
{
public:
QPagedPaintDevicePrivate()
- : pageSize(QPagedPaintDevice::A4),
- pageSizeMM(210, 297),
+ : m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0)),
fromPage(0),
toPage(0),
pageOrderAscending(true),
printSelectionOnly(false)
{
- margins.left = margins.right = margins.top = margins.bottom = 0;
}
static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; }
- QPagedPaintDevice::PageSize pageSize;
- QSizeF pageSizeMM;
- QPagedPaintDevice::Margins margins;
+ QPageLayout m_pageLayout;
// These are currently required to keep QPrinter functionality working in QTextDocument::print()
int fromPage;
diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp
new file mode 100644
index 0000000000..7ae117e423
--- /dev/null
+++ b/src/gui/painting/qpagelayout.cpp
@@ -0,0 +1,971 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qpagelayout.h"
+
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qsize.h>
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static qreal qt_clamp(qreal value, qreal min, qreal max)
+{
+ return qMin(qMax(value, min), max);
+}
+
+// Multiplier for converting units to points.
+Q_GUI_EXPORT qreal qt_pointMultiplier(QPageLayout::Unit unit)
+{
+ switch (unit) {
+ case QPageLayout::Millimeter:
+ return 2.83464566929;
+ case QPageLayout::Point:
+ return 1.0;
+ case QPageLayout::Inch:
+ return 72.0;
+ case QPageLayout::Pica:
+ return 12;
+ case QPageLayout::Didot:
+ return 1.065826771;
+ case QPageLayout::Cicero:
+ return 12.789921252;
+ }
+ return 1.0;
+}
+
+// Multiplier for converting pixels to points.
+extern qreal qt_pixelMultiplier(int resolution);
+
+QPointF qt_convertPoint(const QPointF &xy, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
+{
+ // If the size have the same units, or are all 0, then don't need to convert
+ if (fromUnits == toUnits || xy.isNull())
+ return xy;
+
+ // If converting to points then convert and round to 0 decimal places
+ if (toUnits == QPageLayout::Point) {
+ const qreal multiplier = qt_pointMultiplier(fromUnits);
+ return QPointF(qRound(xy.x() * multiplier),
+ qRound(xy.y() * multiplier));
+ }
+
+ // If converting to other units, need to convert to unrounded points first
+ QPointF pointXy = (fromUnits == QPageLayout::Point) ? xy : xy * qt_pointMultiplier(fromUnits);
+
+ // Then convert from points to required units rounded to 2 decimal places
+ const qreal multiplier = qt_pointMultiplier(toUnits);
+ return QPointF(qRound(pointXy.x() * 100 / multiplier) / 100.0,
+ qRound(pointXy.y() * 100 / multiplier) / 100.0);
+}
+
+Q_GUI_EXPORT QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits)
+{
+ // If the margins have the same units, or are all 0, then don't need to convert
+ if (fromUnits == toUnits || margins.isNull())
+ return margins;
+
+ // If converting to points then convert and round to 0 decimal places
+ if (toUnits == QPageLayout::Point) {
+ const qreal multiplier = qt_pointMultiplier(fromUnits);
+ return QMarginsF(qRound(margins.left() * multiplier),
+ qRound(margins.top() * multiplier),
+ qRound(margins.right() * multiplier),
+ qRound(margins.bottom() * multiplier));
+ }
+
+ // If converting to other units, need to convert to unrounded points first
+ QMarginsF pointMargins = fromUnits == QPageLayout::Point ? margins : margins * qt_pointMultiplier(fromUnits);
+
+ // Then convert from points to required units rounded to 2 decimal places
+ const qreal multiplier = qt_pointMultiplier(toUnits);
+ return QMarginsF(qRound(pointMargins.left() * 100 / multiplier) / 100.0,
+ qRound(pointMargins.top() * 100 / multiplier) / 100.0,
+ qRound(pointMargins.right() * 100 / multiplier) / 100.0,
+ qRound(pointMargins.bottom() * 100 / multiplier) / 100.0);
+}
+
+class QPageLayoutPrivate : public QSharedData
+{
+public:
+
+ QPageLayoutPrivate();
+ QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ const QMarginsF &margins, QPageLayout::Unit units,
+ const QMarginsF &minMargins);
+ ~QPageLayoutPrivate();
+
+ bool operator==(const QPageLayoutPrivate &other) const;
+ bool isEquivalentTo(const QPageLayoutPrivate &other) const;
+
+ bool isValid() const;
+
+ void clampMargins(const QMarginsF &margins);
+
+ QMarginsF margins(QPageLayout::Unit units) const;
+ QMargins marginsPoints() const;
+ QMargins marginsPixels(int resolution) const;
+
+ void setDefaultMargins(const QMarginsF &minMargins);
+
+ QSizeF paintSize() const;
+
+ QRectF fullRect() const;
+ QRectF fullRect(QPageLayout::Unit units) const;
+ QRect fullRectPoints() const;
+ QRect fullRectPixels(int resolution) const;
+
+ QRectF paintRect() const;
+
+private:
+ friend class QPageLayout;
+
+ QSizeF fullSizeUnits(QPageLayout::Unit units) const;
+
+ QPageSize m_pageSize;
+ QPageLayout::Orientation m_orientation;
+ QPageLayout::Mode m_mode;
+ QPageLayout::Unit m_units;
+ QSizeF m_fullSize;
+ QMarginsF m_margins;
+ QMarginsF m_minMargins;
+ QMarginsF m_maxMargins;
+};
+
+QPageLayoutPrivate::QPageLayoutPrivate()
+ : m_orientation(QPageLayout::Landscape),
+ m_mode(QPageLayout::StandardMode)
+{
+}
+
+QPageLayoutPrivate::QPageLayoutPrivate(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ const QMarginsF &margins, QPageLayout::Unit units,
+ const QMarginsF &minMargins)
+ : m_pageSize(pageSize),
+ m_orientation(orientation),
+ m_mode(QPageLayout::StandardMode),
+ m_units(units),
+ m_margins(margins)
+{
+ m_fullSize = fullSizeUnits(m_units);
+ setDefaultMargins(minMargins);
+}
+
+QPageLayoutPrivate::~QPageLayoutPrivate()
+{
+}
+
+bool QPageLayoutPrivate::operator==(const QPageLayoutPrivate &other) const
+{
+ return m_pageSize == other.m_pageSize
+ && m_orientation == other.m_orientation
+ && m_units == other.m_units
+ && m_margins == other.m_margins
+ && m_minMargins == other.m_minMargins
+ && m_maxMargins == other.m_maxMargins;
+}
+
+bool QPageLayoutPrivate::isEquivalentTo(const QPageLayoutPrivate &other) const
+{
+ return m_pageSize.isEquivalentTo(other.m_pageSize)
+ && m_orientation == other.m_orientation
+ && qt_convertMargins(m_margins, m_units, QPageLayout::Point)
+ == qt_convertMargins(other.m_margins, other.m_units, QPageLayout::Point);
+}
+
+bool QPageLayoutPrivate::isValid() const
+{
+ return m_pageSize.isValid();
+}
+
+void QPageLayoutPrivate::clampMargins(const QMarginsF &margins)
+{
+ m_margins = QMarginsF(qt_clamp(margins.left(), m_minMargins.left(), m_maxMargins.left()),
+ qt_clamp(margins.top(), m_minMargins.top(), m_maxMargins.top()),
+ qt_clamp(margins.right(), m_minMargins.right(), m_maxMargins.right()),
+ qt_clamp(margins.bottom(), m_minMargins.bottom(), m_maxMargins.bottom()));
+}
+
+QMarginsF QPageLayoutPrivate::margins(QPageLayout::Unit units) const
+{
+ return qt_convertMargins(m_margins, m_units, units);
+}
+
+QMargins QPageLayoutPrivate::marginsPoints() const
+{
+ return qt_convertMargins(m_margins, m_units, QPageLayout::Point).toMargins();
+}
+
+QMargins QPageLayoutPrivate::marginsPixels(int resolution) const
+{
+ return marginsPoints() / qt_pixelMultiplier(resolution);
+}
+
+void QPageLayoutPrivate::setDefaultMargins(const QMarginsF &minMargins)
+{
+ m_minMargins = minMargins;
+ m_maxMargins = QMarginsF(m_fullSize.width() - m_minMargins.right(),
+ m_fullSize.height() - m_minMargins.bottom(),
+ m_fullSize.width() - m_minMargins.left(),
+ m_fullSize.height() - m_minMargins.top());
+ if (m_mode == QPageLayout::StandardMode)
+ clampMargins(m_margins);
+}
+
+QSizeF QPageLayoutPrivate::fullSizeUnits(QPageLayout::Unit units) const
+{
+ QSizeF fullPageSize = m_pageSize.size(QPageSize::Unit(units));
+ return m_orientation == QPageLayout::Landscape ? fullPageSize.transposed() : fullPageSize;
+}
+
+QRectF QPageLayoutPrivate::fullRect() const
+{
+ return QRectF(QPointF(0, 0), m_fullSize);
+}
+
+QRectF QPageLayoutPrivate::fullRect(QPageLayout::Unit units) const
+{
+ return units == m_units ? fullRect() : QRectF(QPointF(0, 0), fullSizeUnits(units));
+}
+
+QRect QPageLayoutPrivate::fullRectPoints() const
+{
+ if (m_orientation == QPageLayout::Landscape)
+ return QRect(QPoint(0, 0), m_pageSize.sizePoints().transposed());
+ else
+ return QRect(QPoint(0, 0), m_pageSize.sizePoints());
+}
+
+QRect QPageLayoutPrivate::fullRectPixels(int resolution) const
+{
+ if (m_orientation == QPageLayout::Landscape)
+ return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution).transposed());
+ else
+ return QRect(QPoint(0, 0), m_pageSize.sizePixels(resolution));
+}
+
+QRectF QPageLayoutPrivate::paintRect() const
+{
+ return m_mode == QPageLayout::FullPageMode ? fullRect() : fullRect() - m_margins;
+}
+
+
+/*!
+ \class QPageLayout
+ \inmodule QtGui
+ \since 5.3
+ \brief Describes the size, orientation and margins of a page.
+
+ The QPageLayout class defines the layout of a page in a paged document, with the
+ page size, orientation and margins able to be set and the full page and paintable
+ page rectangles defined by those attributes able to be queried in a variety of units.
+
+ The page size is defined by the QPageSize class which can be queried for page size
+ attributes. Note that the QPageSize itself is always defined in a Portrait
+ orientation.
+
+ The minimum margins can be defined for the layout but normally default to 0.
+ When used in conjunction with Qt's printing support the minimum margins
+ will reflect the minimum printable area defined by the printer.
+
+ In the default StandardMode the current margins and minimum margins are
+ always taken into account. The paintable rectangle is the full page
+ rectangle less the current margins, and the current margins can only be set
+ to values between the minimum margins and the maximum margins allowed by
+ the full page size.
+
+ In FullPageMode the current margins and minimum margins are not taken
+ into account. The paintable rectangle is the full page rectangle, and the
+ current margins can be set to any values regardless of the minimum margins
+ and page size.
+
+ \sa QPageSize
+*/
+
+/*!
+ \enum QPageLayout::Unit
+
+ This enum type is used to specify the measurement unit for page layout and margins.
+
+ \value Millimeter
+ \value Point 1/72th of an inch
+ \value Inch
+ \value Pica 1/72th of a foot, 1/6th of an inch, 12 Points
+ \value Didot 1/72th of a French inch, 0.375 mm
+ \value Cicero 1/6th of a French inch, 12 Didot, 4.5mm
+*/
+
+/*!
+ \enum QPageLayout::Orientation
+
+ This enum type defines the page orientation
+
+ \value Portrait The page size is used in its default orientation
+ \value Landscape The page size is rotated through 90 degrees
+
+ Note that some standard page sizes are defined with a width larger than
+ their height, hence the orientation is defined relative to the standard
+ page size and not using the relative page dimensions.
+*/
+
+/*!
+ \enum QPageLayout::Mode
+
+ Defines the page layout mode
+
+ \value StandardMode Paint Rect includes margins, margins must fall between the minimum and maximum.
+ \value FullPageMode Paint Rect excludes margins, margins can be any value and must be managed manually.
+*/
+
+/*!
+ Creates an invalid QPageLayout.
+*/
+
+QPageLayout::QPageLayout()
+ : d(new QPageLayoutPrivate())
+{
+}
+
+/*!
+ Creates a QPageLayout with the given \a pageSize, \a orientation and
+ \a margins in the given \a units.
+
+ Optionally define the minimum allowed margins \a minMargins, e.g. the minimum
+ margins able to be printed by a physical print device.
+
+ The constructed QPageLayout will be in StandardMode.
+
+ The \a margins given will be clamped to the minimum margins and the maximum
+ margins allowed by the page size.
+*/
+
+QPageLayout::QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ const QMarginsF &margins, QPageLayout::Unit units,
+ const QMarginsF &minMargins)
+ : d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins))
+{
+}
+
+/*!
+ Copy constructor, copies \a other to this.
+*/
+
+QPageLayout::QPageLayout(const QPageLayout &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Destroys the page layout.
+*/
+
+QPageLayout::~QPageLayout()
+{
+}
+
+/*!
+ Assignment operator, assigns \a other to this.
+*/
+
+QPageLayout &QPageLayout::operator=(const QPageLayout &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn void QPageLayout::swap(QPageLayout &other)
+
+ Swaps this page layout with \a other. This function is very fast and
+ never fails.
+*/
+
+/*!
+ \fn QPageLayout &QPageLayout::operator=(QPageLayout &&other)
+
+ Move-assigns \a other to this QPageLayout instance, transferring the
+ ownership of the managed pointer to this instance.
+*/
+
+/*!
+ Returns \c true if this page layout is equal to the \a other page layout,
+ i.e. if all the attributes are exactly equal.
+
+ Note that this is a strict equality, especially for page size where the
+ QPageSize ID, name and size must exactly match, and the margins where the
+ units must match.
+
+ \sa isEquivalentTo()
+*/
+
+bool QPageLayout::operator==(const QPageLayout &other) const
+{
+ if (d && other.d)
+ return (*d == *other.d);
+ return (d == other.d);
+}
+
+/*!
+ Returns \c true if this page layout is equivalent to the \a other page layout,
+ i.e. if the page has the same size, margins and orientation.
+*/
+
+bool QPageLayout::isEquivalentTo(const QPageLayout &other) const
+{
+ return d && other.d && d->isEquivalentTo(*other.d);
+}
+
+/*!
+ Returns \c true if this page layout is valid.
+*/
+
+bool QPageLayout::isValid() const
+{
+ return d->isValid();
+}
+
+/*!
+ Sets a page layout mode to \a mode.
+*/
+
+void QPageLayout::setMode(QPageLayout::Mode mode)
+{
+ d->m_mode = mode;
+}
+
+/*!
+ Returns the page layout mode.
+*/
+
+QPageLayout::Mode QPageLayout::mode() const
+{
+ return d->m_mode;
+}
+
+/*!
+ Sets the page size of the page layout to \a pageSize.
+
+ Optionally define the minimum allowed margins \a minMargins, e.g. the minimum
+ margins able to be printed by a physical print device, otherwise the
+ minimum margins will default to 0.
+
+ If StandardMode is set then the existing margins will be clamped
+ to the new minimum margins and the maximum margins allowed by the page size.
+ If FullPageMode is set then the existing margins will be unchanged.
+*/
+
+void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMargins)
+{
+ if (!pageSize.isValid())
+ return;
+ d->m_pageSize = pageSize;
+ d->m_fullSize = d->fullSizeUnits(d->m_units);
+ d->setDefaultMargins(minMargins);
+}
+
+/*!
+ Returns the page size of the page layout.
+
+ Note that the QPageSize is always defined in a Portrait orientation. To
+ obtain a size that takes the set orientation into account you must use
+ fullRect().
+*/
+
+QPageSize QPageLayout::pageSize() const
+{
+ return d->m_pageSize;
+}
+
+/*!
+ Sets the page orientation of the page layout to \a orientation.
+
+ Changing the orientation does not affect the current margins or
+ the minimum margins.
+*/
+
+void QPageLayout::setOrientation(QPageLayout::Orientation orientation)
+{
+ if (orientation != d->m_orientation) {
+ d->m_orientation = orientation;
+ d->m_fullSize = d->fullSizeUnits(d->m_units);
+ // Adust the max margins to reflect change in max page size
+ const qreal change = d->m_fullSize.width() - d->m_fullSize.height();
+ d->m_maxMargins.setLeft(d->m_maxMargins.left() + change);
+ d->m_maxMargins.setRight(d->m_maxMargins.right() + change);
+ d->m_maxMargins.setTop(d->m_maxMargins.top() - change);
+ d->m_maxMargins.setBottom(d->m_maxMargins.bottom() - change);
+ }
+}
+
+/*!
+ Returns the page orientation of the page layout.
+*/
+
+QPageLayout::Orientation QPageLayout::orientation() const
+{
+ return d->m_orientation;
+}
+
+/*!
+ Sets the \a units used to define the page layout.
+*/
+
+void QPageLayout::setUnits(QPageLayout::Unit units)
+{
+ if (units != d->m_units) {
+ d->m_margins = qt_convertMargins(d->m_margins, d->m_units, units);
+ d->m_minMargins = qt_convertMargins(d->m_minMargins, d->m_units, units);
+ d->m_maxMargins = qt_convertMargins(d->m_maxMargins, d->m_units, units);
+ d->m_units = units;
+ d->m_fullSize = d->fullSizeUnits(d->m_units);
+ }
+}
+
+/*!
+ Returns the units the page layout is currently defined in.
+*/
+
+QPageLayout::Unit QPageLayout::units() const
+{
+ return d->m_units;
+}
+
+/*!
+ Sets the page margins of the page layout to \a margins
+ Returns true if the margins were successfully set.
+
+ The units used are those currently defined for the layout. To use different
+ units then call setUnits() first.
+
+ If in the default StandardMode then all the new margins must fall between the
+ minimum margins set and the maximum margins allowed by the page size,
+ otherwise the margins will not be set.
+
+ If in FullPageMode then any margin values will be accepted.
+
+ \sa margins(), units()
+*/
+
+bool QPageLayout::setMargins(const QMarginsF &margins)
+{
+ if (d->m_mode == QPageLayout::FullPageMode) {
+ d->m_margins = margins;
+ return true;
+ } else if (margins.left() >= d->m_minMargins.left()
+ && margins.right() >= d->m_minMargins.right()
+ && margins.top() >= d->m_minMargins.top()
+ && margins.bottom() >= d->m_minMargins.bottom()
+ && margins.left() <= d->m_maxMargins.left()
+ && margins.right() <= d->m_maxMargins.right()
+ && margins.top() <= d->m_maxMargins.top()
+ && margins.bottom() <= d->m_maxMargins.bottom()) {
+ d->m_margins = margins;
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Sets the left page margin of the page layout to \a leftMargin.
+ Returns true if the margin was successfully set.
+
+ The units used are those currently defined for the layout. To use different
+ units call setUnits() first.
+
+ If in the default StandardMode then the new margin must fall between the
+ minimum margin set and the maximum margin allowed by the page size,
+ otherwise the margin will not be set.
+
+ If in FullPageMode then any margin values will be accepted.
+
+ \sa setMargins(), margins()
+*/
+
+bool QPageLayout::setLeftMargin(qreal leftMargin)
+{
+ if (d->m_mode == QPageLayout::FullPageMode
+ || (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) {
+ d->m_margins.setLeft(leftMargin);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Sets the right page margin of the page layout to \a rightMargin.
+ Returns true if the margin was successfully set.
+
+ The units used are those currently defined for the layout. To use different
+ units call setUnits() first.
+
+ If in the default StandardMode then the new margin must fall between the
+ minimum margin set and the maximum margin allowed by the page size,
+ otherwise the margin will not be set.
+
+ If in FullPageMode then any margin values will be accepted.
+
+ \sa setMargins(), margins()
+*/
+
+bool QPageLayout::setRightMargin(qreal rightMargin)
+{
+ if (d->m_mode == QPageLayout::FullPageMode
+ || (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) {
+ d->m_margins.setRight(rightMargin);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Sets the top page margin of the page layout to \a topMargin.
+ Returns true if the margin was successfully set.
+
+ The units used are those currently defined for the layout. To use different
+ units call setUnits() first.
+
+ If in the default StandardMode then the new margin must fall between the
+ minimum margin set and the maximum margin allowed by the page size,
+ otherwise the margin will not be set.
+
+ If in FullPageMode then any margin values will be accepted.
+
+ \sa setMargins(), margins()
+*/
+
+bool QPageLayout::setTopMargin(qreal topMargin)
+{
+ if (d->m_mode == QPageLayout::FullPageMode
+ || (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) {
+ d->m_margins.setTop(topMargin);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Sets the bottom page margin of the page layout to \a bottomMargin.
+ Returns true if the margin was successfully set.
+
+ The units used are those currently defined for the layout. To use different
+ units call setUnits() first.
+
+ If in the default StandardMode then the new margin must fall between the
+ minimum margin set and the maximum margin allowed by the page size,
+ otherwise the margin will not be set.
+
+ If in FullPageMode then any margin values will be accepted.
+
+ \sa setMargins(), margins()
+*/
+
+bool QPageLayout::setBottomMargin(qreal bottomMargin)
+{
+ if (d->m_mode == QPageLayout::FullPageMode
+ || (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) {
+ d->m_margins.setBottom(bottomMargin);
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns the margins of the page layout using the currently set units.
+
+ \sa setMargins(), units()
+*/
+
+QMarginsF QPageLayout::margins() const
+{
+ return d->m_margins;
+}
+
+/*!
+ Returns the margins of the page layout using the requested \a units.
+
+ \sa setMargins(), margins()
+*/
+
+QMarginsF QPageLayout::margins(QPageLayout::Unit units) const
+{
+ return d->margins(units);
+}
+
+/*!
+ Returns the margins of the page layout in Postscript Points (1/72 of an inch).
+
+ \sa setMargins(), margins()
+*/
+
+QMargins QPageLayout::marginsPoints() const
+{
+ return d->marginsPoints();
+}
+
+/*!
+ Returns the margins of the page layout in device pixels for the given \a resolution.
+
+ \sa setMargins()
+*/
+
+QMargins QPageLayout::marginsPixels(int resolution) const
+{
+ return d->marginsPixels(resolution);
+}
+
+/*!
+ Sets the minimum page margins of the page layout to \a minMargins.
+
+ It is not recommended to override the default values set for a page size
+ as this may be the minimum printable area for a physical print device.
+
+ If the StandardMode mode is set then the existing margins will be clamped
+ to the new \a minMargins and the maximum allowed by the page size. If the
+ FullPageMode is set then the existing margins will be unchanged.
+
+ \sa minimumMargins(), setMargins()
+*/
+
+void QPageLayout::setMinimumMargins(const QMarginsF &minMargins)
+{
+ d->setDefaultMargins(minMargins);
+}
+
+/*!
+ Returns the minimum margins of the page layout.
+
+ \sa setMinimumMargins(), maximumMargins()
+*/
+
+QMarginsF QPageLayout::minimumMargins() const
+{
+ return d->m_minMargins;
+}
+
+/*!
+ Returns the maximum margins that would be applied if the page layout was
+ in StandardMode.
+
+ The maximum margins allowed are calculated as the full size of the page
+ minus the minimum margins set. For example, if the page width is 100 points
+ and the minimum right margin is 10 points, then the maximum left margin
+ will be 90 points.
+
+ \sa setMinimumMargins(), minimumMargins()
+*/
+
+QMarginsF QPageLayout::maximumMargins() const
+{
+ return d->m_maxMargins;
+}
+
+/*!
+ Returns the full page rectangle in the current layout units.
+
+ The page rectangle takes into account the page size and page orientation,
+ but not the page margins.
+
+ \sa paintRect(), units()
+*/
+
+QRectF QPageLayout::fullRect() const
+{
+ return isValid() ? d->fullRect() : QRect();
+}
+
+/*!
+ Returns the full page rectangle in the required \a units.
+
+ The page rectangle takes into account the page size and page orientation,
+ but not the page margins.
+
+ \sa paintRect()
+*/
+
+QRectF QPageLayout::fullRect(QPageLayout::Unit units) const
+{
+ return isValid() ? d->fullRect(units) : QRect();
+}
+
+/*!
+ Returns the full page rectangle in Postscript Points (1/72 of an inch).
+
+ The page rectangle takes into account the page size and page orientation,
+ but not the page margins.
+
+ \sa paintRect()
+*/
+
+QRect QPageLayout::fullRectPoints() const
+{
+ return isValid() ? d->fullRectPoints() : QRect();
+}
+
+/*!
+ Returns the full page rectangle in device pixels for the given \a resolution.
+
+ The page rectangle takes into account the page size and page orientation,
+ but not the page margins.
+
+ \sa paintRect()
+*/
+
+QRect QPageLayout::fullRectPixels(int resolution) const
+{
+ return isValid() ? d->fullRectPixels(resolution) : QRect();
+}
+
+/*!
+ Returns the page rectangle in the current layout units.
+
+ The paintable rectangle takes into account the page size, orientation
+ and margins.
+
+ If the FullPageMode mode is set then the fullRect() is returned and
+ the margins must be manually managed.
+*/
+
+QRectF QPageLayout::paintRect() const
+{
+ return isValid() ? d->paintRect() : QRectF();
+}
+
+/*!
+ Returns the page rectangle in the required \a units.
+
+ The paintable rectangle takes into account the page size, orientation
+ and margins.
+
+ If the FullPageMode mode is set then the fullRect() is returned and
+ the margins must be manually managed.
+*/
+
+QRectF QPageLayout::paintRect(QPageLayout::Unit units) const
+{
+ if (!isValid())
+ return QRectF();
+ if (units == d->m_units)
+ return d->paintRect();
+ return d->m_mode == QPageLayout::FullPageMode ? d->fullRect(units)
+ : d->fullRect(units) - d->margins(units);
+}
+
+/*!
+ Returns the paintable rectangle in rounded Postscript Points (1/72 of an inch).
+
+ The paintable rectangle takes into account the page size, orientation
+ and margins.
+
+ If the FullPageMode mode is set then the fullRect() is returned and
+ the margins must be manually managed.
+*/
+
+QRect QPageLayout::paintRectPoints() const
+{
+ if (!isValid())
+ return QRect();
+ return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPoints()
+ : d->fullRectPoints() - d->marginsPoints();
+}
+
+/*!
+ Returns the paintable rectangle in rounded device pixels for the given \a resolution.
+
+ The paintable rectangle takes into account the page size, orientation
+ and margins.
+
+ If the FullPageMode mode is set then the fullRect() is returned and
+ the margins must be manually managed.
+*/
+
+QRect QPageLayout::paintRectPixels(int resolution) const
+{
+ if (!isValid())
+ return QRect();
+ return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPixels(resolution)
+ : d->fullRectPixels(resolution) - d->marginsPixels(resolution);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QPageLayout &layout)
+{
+ if (layout.isValid()) {
+ QString output = QStringLiteral("QPageLayout(%1, %2, l:%3 r:%4 t:%5 b:%6 %7)");
+ QString units;
+ switch (layout.units()) {
+ case QPageLayout::Millimeter:
+ units = QStringLiteral("mm");
+ break;
+ case QPageLayout::Point:
+ units = QStringLiteral("pt");
+ break;
+ case QPageLayout::Inch:
+ units = QStringLiteral("in");
+ break;
+ case QPageLayout::Pica:
+ units = QStringLiteral("pc");
+ break;
+ case QPageLayout::Didot:
+ units = QStringLiteral("DD");
+ break;
+ case QPageLayout::Cicero:
+ units = QStringLiteral("CC");
+ break;
+ }
+ output = output.arg(layout.pageSize().name())
+ .arg(layout.orientation() == QPageLayout::Portrait ? QStringLiteral("Portrait") : QStringLiteral("Landscape"))
+ .arg(layout.margins().left())
+ .arg(layout.margins().right())
+ .arg(layout.margins().top())
+ .arg(layout.margins().bottom())
+ .arg(units);
+ dbg.nospace() << output;
+ } else {
+ dbg.nospace() << QStringLiteral("QPageLayout()");
+ }
+ return dbg.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h
new file mode 100644
index 0000000000..86e430e311
--- /dev/null
+++ b/src/gui/painting/qpagelayout.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAGELAYOUT_H
+#define QPAGELAYOUT_H
+
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qmargins.h>
+
+#include <QtGui/qpagesize.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPageLayoutPrivate;
+class QMarginsF;
+
+class Q_GUI_EXPORT QPageLayout
+{
+public:
+
+ // NOTE: Must keep in sync with QPageSize::Unit and QPrinter::Unit
+ enum Unit {
+ Millimeter,
+ Point,
+ Inch,
+ Pica,
+ Didot,
+ Cicero
+ };
+
+ // NOTE: Must keep in sync with QPrinter::Orientation
+ enum Orientation {
+ Portrait,
+ Landscape
+ };
+
+ enum Mode {
+ StandardMode, // Paint Rect includes margins
+ FullPageMode // Paint Rect excludes margins
+ };
+
+ QPageLayout();
+ QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ const QMarginsF &margins, QPageLayout::Unit units = QPageLayout::Point,
+ const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0));
+ QPageLayout(const QPageLayout &other);
+ ~QPageLayout();
+
+ QPageLayout &operator=(const QPageLayout &other);
+ #ifdef Q_COMPILER_RVALUE_REFS
+ QPageLayout &operator=(QPageLayout &&other) { swap(other); return *this; }
+#endif
+
+ void swap(QPageLayout &other) { d.swap(other.d); }
+
+ bool operator==(const QPageLayout &other) const;
+ bool isEquivalentTo(const QPageLayout &other) const;
+
+ bool isValid() const;
+
+ void setMode(QPageLayout::Mode mode);
+ QPageLayout::Mode mode() const;
+
+ void setPageSize(const QPageSize &pageSize,
+ const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0));
+ QPageSize pageSize() const;
+
+ void setOrientation(QPageLayout::Orientation orientation);
+ QPageLayout::Orientation orientation() const;
+
+ void setUnits(QPageLayout::Unit units);
+ QPageLayout::Unit units() const;
+
+ bool setMargins(const QMarginsF &margins);
+ bool setLeftMargin(qreal leftMargin);
+ bool setRightMargin(qreal rightMargin);
+ bool setTopMargin(qreal topMargin);
+ bool setBottomMargin(qreal bottomMargin);
+
+ QMarginsF margins() const;
+ QMarginsF margins(QPageLayout::Unit units) const;
+ QMargins marginsPoints() const;
+ QMargins marginsPixels(int resolution) const;
+
+ void setMinimumMargins(const QMarginsF &minMargins);
+ QMarginsF minimumMargins() const;
+ QMarginsF maximumMargins() const;
+
+ QRectF fullRect() const;
+ QRectF fullRect(QPageLayout::Unit units) const;
+ QRect fullRectPoints() const;
+ QRect fullRectPixels(int resolution) const;
+
+ QRectF paintRect() const;
+ QRectF paintRect(QPageLayout::Unit units) const;
+ QRect paintRectPoints() const;
+ QRect paintRectPixels(int resolution) const;
+
+private:
+ friend class QPageLayoutPrivate;
+ QSharedDataPointer<QPageLayoutPrivate> d;
+};
+
+Q_DECLARE_SHARED(QPageLayout)
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageLayout &pageLayout);
+#endif
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPageLayout)
+Q_DECLARE_METATYPE(QPageLayout::Unit)
+Q_DECLARE_METATYPE(QPageLayout::Orientation)
+
+#endif // QPAGELAYOUT_H
diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp
new file mode 100644
index 0000000000..6698d77bbd
--- /dev/null
+++ b/src/gui/painting/qpagesize.cpp
@@ -0,0 +1,1882 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpagesize.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qpoint.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qsize.h>
+#include <QtCore/qstring.h>
+
+QT_BEGIN_NAMESPACE
+
+// Define the Windows DMPAPER sizes for use in the look-up table
+// See http://msdn.microsoft.com/en-us/library/windows/desktop/dd319099.aspx
+
+enum WindowsDmPaper {
+ DMPAPER_NONE = 0, // Not a DMPAPER, use for sizes without a DMPAPER value
+ DMPAPER_LETTER = 1,
+ DMPAPER_LETTERSMALL = 2,
+ DMPAPER_TABLOID = 3,
+ DMPAPER_LEDGER = 4,
+ DMPAPER_LEGAL = 5,
+ DMPAPER_STATEMENT = 6,
+ DMPAPER_EXECUTIVE = 7,
+ DMPAPER_A3 = 8,
+ DMPAPER_A4 = 9,
+ DMPAPER_A4SMALL = 10,
+ DMPAPER_A5 = 11,
+ DMPAPER_B4 = 12,
+ DMPAPER_B5 = 13,
+ DMPAPER_FOLIO = 14,
+ DMPAPER_QUARTO = 15,
+ DMPAPER_10X14 = 16,
+ DMPAPER_11X17 = 17,
+ DMPAPER_NOTE = 18,
+ DMPAPER_ENV_9 = 19,
+ DMPAPER_ENV_10 = 20,
+ DMPAPER_ENV_11 = 21,
+ DMPAPER_ENV_12 = 22,
+ DMPAPER_ENV_14 = 23,
+ DMPAPER_CSHEET = 24,
+ DMPAPER_DSHEET = 25,
+ DMPAPER_ESHEET = 26,
+ DMPAPER_ENV_DL = 27,
+ DMPAPER_ENV_C5 = 28,
+ DMPAPER_ENV_C3 = 29,
+ DMPAPER_ENV_C4 = 30,
+ DMPAPER_ENV_C6 = 31,
+ DMPAPER_ENV_C65 = 32,
+ DMPAPER_ENV_B4 = 33,
+ DMPAPER_ENV_B5 = 34,
+ DMPAPER_ENV_B6 = 35,
+ DMPAPER_ENV_ITALY = 36,
+ DMPAPER_ENV_MONARCH = 37,
+ DMPAPER_ENV_PERSONAL = 38,
+ DMPAPER_FANFOLD_US = 39,
+ DMPAPER_FANFOLD_STD_GERMAN = 40,
+ DMPAPER_FANFOLD_LGL_GERMAN = 41,
+ DMPAPER_ISO_B4 = 42,
+ DMPAPER_JAPANESE_POSTCARD = 43,
+ DMPAPER_9X11 = 44,
+ DMPAPER_10X11 = 45,
+ DMPAPER_15X11 = 46,
+ DMPAPER_ENV_INVITE = 47,
+ DMPAPER_RESERVED_48 = 48,
+ DMPAPER_RESERVED_49 = 49,
+ DMPAPER_LETTER_EXTRA = 50,
+ DMPAPER_LEGAL_EXTRA = 51,
+ DMPAPER_TABLOID_EXTRA = 52,
+ DMPAPER_A4_EXTRA = 53,
+ DMPAPER_LETTER_TRANSVERSE = 54,
+ DMPAPER_A4_TRANSVERSE = 55,
+ DMPAPER_LETTER_EXTRA_TRANSVERSE = 56,
+ DMPAPER_A_PLUS = 57,
+ DMPAPER_B_PLUS = 58,
+ DMPAPER_LETTER_PLUS = 59,
+ DMPAPER_A4_PLUS = 60,
+ DMPAPER_A5_TRANSVERSE = 61,
+ DMPAPER_B5_TRANSVERSE = 62,
+ DMPAPER_A3_EXTRA = 63,
+ DMPAPER_A5_EXTRA = 64,
+ DMPAPER_B5_EXTRA = 65,
+ DMPAPER_A2 = 66,
+ DMPAPER_A3_TRANSVERSE = 67,
+ DMPAPER_A3_EXTRA_TRANSVERSE = 68,
+ DMPAPER_DBL_JAPANESE_POSTCARD = 69,
+ DMPAPER_A6 = 70,
+ DMPAPER_JENV_KAKU2 = 71,
+ DMPAPER_JENV_KAKU3 = 72,
+ DMPAPER_JENV_CHOU3 = 73,
+ DMPAPER_JENV_CHOU4 = 74,
+ DMPAPER_LETTER_ROTATED = 75,
+ DMPAPER_A3_ROTATED = 76,
+ DMPAPER_A4_ROTATED = 77,
+ DMPAPER_A5_ROTATED = 78,
+ DMPAPER_B4_JIS_ROTATED = 79,
+ DMPAPER_B5_JIS_ROTATED = 80,
+ DMPAPER_JAPANESE_POSTCARD_ROTATED = 81,
+ DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED = 82,
+ DMPAPER_A6_ROTATED = 83,
+ DMPAPER_JENV_KAKU2_ROTATED = 84,
+ DMPAPER_JENV_KAKU3_ROTATED = 85,
+ DMPAPER_JENV_CHOU3_ROTATED = 86,
+ DMPAPER_JENV_CHOU4_ROTATED = 87,
+ DMPAPER_B6_JIS = 88,
+ DMPAPER_B6_JIS_ROTATED = 89,
+ DMPAPER_12X11 = 90,
+ DMPAPER_JENV_YOU4 = 91,
+ DMPAPER_JENV_YOU4_ROTATED = 92,
+ DMPAPER_P16K = 93,
+ DMPAPER_P32K = 94,
+ DMPAPER_P32KBIG = 95,
+ DMPAPER_PENV_1 = 96,
+ DMPAPER_PENV_2 = 97,
+ DMPAPER_PENV_3 = 98,
+ DMPAPER_PENV_4 = 99,
+ DMPAPER_PENV_5 = 100,
+ DMPAPER_PENV_6 = 101,
+ DMPAPER_PENV_7 = 102,
+ DMPAPER_PENV_8 = 103,
+ DMPAPER_PENV_9 = 104,
+ DMPAPER_PENV_10 = 105,
+ DMPAPER_P16K_ROTATED = 106,
+ DMPAPER_P32K_ROTATED = 107,
+ DMPAPER_P32KBIG_ROTATED = 108,
+ DMPAPER_PENV_1_ROTATED = 109,
+ DMPAPER_PENV_2_ROTATED = 110,
+ DMPAPER_PENV_3_ROTATED = 111,
+ DMPAPER_PENV_4_ROTATED = 112,
+ DMPAPER_PENV_5_ROTATED = 113,
+ DMPAPER_PENV_6_ROTATED = 114,
+ DMPAPER_PENV_7_ROTATED = 115,
+ DMPAPER_PENV_8_ROTATED = 116,
+ DMPAPER_PENV_9_ROTATED = 117,
+ DMPAPER_PENV_10_ROTATED = 118,
+ DMPAPER_LAST = DMPAPER_PENV_10_ROTATED,
+ DMPAPER_USER = 256
+};
+
+// Conversion table for historic page size values that we don't support.
+// These are deprecated in PPD and strongly discouraged from being used,
+// so convert them to usable page sizes to support older print devices.
+// The paper source orientation will be handled in the QPrintMedia class,
+// we're only concerned about the standard size in QPageSize.
+// _ROTATED = 90 degrees or QPageLayout::Landscape
+// _TRANSVERSE = 180 degrees or QPageLayout::ReversePortrait
+
+static const int qt_windowsConversion[][2] = {
+ {DMPAPER_11X17, DMPAPER_TABLOID}, // = DMPAPER_LEDGER rotated
+ {DMPAPER_A3_EXTRA_TRANSVERSE, DMPAPER_A3_EXTRA},
+ {DMPAPER_A3_ROTATED, DMPAPER_A3},
+ {DMPAPER_A3_TRANSVERSE, DMPAPER_A3},
+ {DMPAPER_A4_ROTATED, DMPAPER_A4},
+ {DMPAPER_A4_TRANSVERSE, DMPAPER_A4},
+ {DMPAPER_A5_ROTATED, DMPAPER_A5},
+ {DMPAPER_A5_TRANSVERSE, DMPAPER_A5},
+ {DMPAPER_A6_ROTATED, DMPAPER_A6},
+ {DMPAPER_B4_JIS_ROTATED, DMPAPER_B4},
+ {DMPAPER_B5_JIS_ROTATED, DMPAPER_B5},
+ {DMPAPER_B5_TRANSVERSE, DMPAPER_B5},
+ {DMPAPER_B6_JIS_ROTATED, DMPAPER_B6_JIS},
+ {DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED, DMPAPER_DBL_JAPANESE_POSTCARD},
+ {DMPAPER_JAPANESE_POSTCARD_ROTATED, DMPAPER_JAPANESE_POSTCARD},
+ {DMPAPER_JENV_CHOU3_ROTATED, DMPAPER_JENV_CHOU3},
+ {DMPAPER_JENV_CHOU4_ROTATED, DMPAPER_JENV_CHOU4},
+ {DMPAPER_JENV_KAKU2_ROTATED, DMPAPER_JENV_KAKU2},
+ {DMPAPER_JENV_KAKU3_ROTATED, DMPAPER_JENV_KAKU3},
+ {DMPAPER_JENV_YOU4_ROTATED, DMPAPER_JENV_YOU4},
+ {DMPAPER_LETTER_EXTRA_TRANSVERSE, DMPAPER_LETTER_EXTRA},
+ {DMPAPER_LETTER_ROTATED, DMPAPER_LETTER},
+ {DMPAPER_LETTER_TRANSVERSE, DMPAPER_LETTER},
+ {DMPAPER_P16K_ROTATED, DMPAPER_P16K},
+ {DMPAPER_P32K_ROTATED, DMPAPER_P32K},
+ {DMPAPER_P32KBIG_ROTATED, DMPAPER_P32KBIG},
+ {DMPAPER_PENV_1_ROTATED, DMPAPER_PENV_1},
+ {DMPAPER_PENV_2_ROTATED, DMPAPER_PENV_2},
+ {DMPAPER_PENV_3_ROTATED, DMPAPER_PENV_3},
+ {DMPAPER_PENV_4_ROTATED, DMPAPER_PENV_4},
+ {DMPAPER_PENV_5_ROTATED, DMPAPER_PENV_5},
+ {DMPAPER_PENV_6_ROTATED, DMPAPER_PENV_6},
+ {DMPAPER_PENV_7_ROTATED, DMPAPER_PENV_7},
+ {DMPAPER_PENV_8_ROTATED, DMPAPER_PENV_8},
+ {DMPAPER_PENV_9_ROTATED, DMPAPER_PENV_9},
+ {DMPAPER_PENV_10_ROTATED, DMPAPER_PENV_10} // Is = DMPAPER_LAST, use as loop terminator
+};
+
+static const int windowsConversionCount = int(sizeof(qt_windowsConversion) / sizeof(qt_windowsConversion[0]));
+
+// Standard sizes data
+struct StandardPageSize {
+ QPageSize::PageSizeId id;
+ int windowsId; // Windows DMPAPER value
+ QPageSize::Unit definitionUnits; // Standard definition size, e.g. ISO uses mm, ANSI uses inches
+ int widthPoints;
+ int heightPoints;
+ qreal widthMillimeters;
+ qreal heightMillimeters;
+ qreal widthInches;
+ qreal heightInches;
+ const char *mediaOption; // PPD standard mediaOption ID
+};
+
+// Standard page sizes taken from the Postscript PPD Standard v4.3
+// See http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf
+// Excludes all Transverse and Rotated sizes
+// NB! This table needs to be in sync with QPageSize::PageSizeId
+static const StandardPageSize qt_pageSizes[] = {
+
+ // Existing Qt sizes including ISO, US, ANSI and other standards
+ {QPageSize::A4 , DMPAPER_A4 , QPageSize::Millimeter, 595, 842, 210 , 297 , 8.27, 11.69, "A4"},
+ {QPageSize::B5 , DMPAPER_NONE , QPageSize::Millimeter, 499, 709, 176 , 250 , 6.9 , 9.8 , "ISOB5"},
+ {QPageSize::Letter , DMPAPER_LETTER , QPageSize::Inch , 612, 792, 215.9, 279.4, 8.5 , 11 , "Letter"},
+ {QPageSize::Legal , DMPAPER_LEGAL , QPageSize::Inch , 612, 1008, 215.9, 355.6, 8.5 , 14 , "Legal"},
+ {QPageSize::Executive , DMPAPER_NONE , QPageSize::Inch , 540, 720, 190.5, 254 , 7.5 , 10 , "Executive.7.5x10in"}, // Qt size differs from Postscript / Windows
+ {QPageSize::A0 , DMPAPER_NONE , QPageSize::Millimeter, 2384, 3370, 841 , 1189 , 33.11, 46.81, "A0"},
+ {QPageSize::A1 , DMPAPER_NONE , QPageSize::Millimeter, 1684, 2384, 594 , 841 , 23.39, 33.11, "A1"},
+ {QPageSize::A2 , DMPAPER_A2 , QPageSize::Millimeter, 1191, 1684, 420 , 594 , 16.54, 23.39, "A2"},
+ {QPageSize::A3 , DMPAPER_A3 , QPageSize::Millimeter, 842, 1191, 297 , 420 , 11.69, 16.54, "A3"},
+ {QPageSize::A5 , DMPAPER_A5 , QPageSize::Millimeter, 420, 595, 148 , 210 , 5.83, 8.27, "A5"},
+ {QPageSize::A6 , DMPAPER_A6 , QPageSize::Millimeter, 297, 420, 105 , 148 , 4.13, 5.83, "A6"},
+ {QPageSize::A7 , DMPAPER_NONE , QPageSize::Millimeter, 210, 297, 74 , 105 , 2.91, 4.13, "A7"},
+ {QPageSize::A8 , DMPAPER_NONE , QPageSize::Millimeter, 148, 210, 52 , 74 , 2.05, 2.91, "A8"},
+ {QPageSize::A9 , DMPAPER_NONE , QPageSize::Millimeter, 105, 148, 37 , 52 , 1.46, 2.05, "A9"},
+ {QPageSize::B0 , DMPAPER_NONE , QPageSize::Millimeter, 2835, 4008, 1000 , 1414 , 39.37, 55.67, "ISOB0"},
+ {QPageSize::B1 , DMPAPER_NONE , QPageSize::Millimeter, 2004, 2835, 707 , 1000 , 27.83, 39.37, "ISOB1"},
+ {QPageSize::B10 , DMPAPER_NONE , QPageSize::Millimeter, 88, 125, 31 , 44 , 1.22, 1.73, "ISOB10"},
+ {QPageSize::B2 , DMPAPER_NONE , QPageSize::Millimeter, 1417, 2004, 500 , 707 , 19.68, 27.83, "ISOB2"},
+ {QPageSize::B3 , DMPAPER_NONE , QPageSize::Millimeter, 1001, 1417, 353 , 500 , 13.9 , 19.68, "ISOB3"},
+ {QPageSize::B4 , DMPAPER_ISO_B4 , QPageSize::Millimeter, 709, 1001, 250 , 353 , 9.84, 13.9 , "ISOB4"},
+ {QPageSize::B6 , DMPAPER_NONE , QPageSize::Millimeter, 354, 499, 125 , 176 , 4.92, 6.93, "ISOB6"},
+ {QPageSize::B7 , DMPAPER_NONE , QPageSize::Millimeter, 249, 354, 88 , 125 , 3.46, 4.92, "ISOB7"},
+ {QPageSize::B8 , DMPAPER_NONE , QPageSize::Millimeter, 176, 249, 62 , 88 , 2.44, 3.46, "ISOB8"},
+ {QPageSize::B9 , DMPAPER_NONE , QPageSize::Millimeter, 125, 176, 44 , 62 , 1.73, 2.44, "ISOB9"},
+ {QPageSize::C5E , DMPAPER_ENV_C5 , QPageSize::Millimeter, 459, 649, 162 , 229 , 6.38, 9.02, "EnvC5"},
+ {QPageSize::Comm10E , DMPAPER_ENV_10 , QPageSize::Inch , 297, 684, 104.8, 241.3, 4.12, 9.5 , "Env10"},
+ {QPageSize::DLE , DMPAPER_ENV_DL , QPageSize::Millimeter, 312, 624, 110 , 220 , 4.33, 8.66, "EnvDL"},
+ {QPageSize::Folio , DMPAPER_NONE , QPageSize::Millimeter, 595, 935, 210 , 330 , 8.27, 13 , "Folio"},
+ {QPageSize::Ledger , DMPAPER_LEDGER , QPageSize::Inch , 1224, 792, 431.8, 279.4, 17 , 11 , "Ledger"},
+ {QPageSize::Tabloid , DMPAPER_TABLOID , QPageSize::Inch , 792, 1224, 279.4, 431.8, 11 , 17 , "Tabloid"},
+ {QPageSize::Custom , DMPAPER_USER , QPageSize::Millimeter, -1, -1, -1. , -1 , -1 , -1 , "Custom"}, // Special case to keep in sync with QPageSize::PageSizeId
+
+ // ISO Standard Sizes
+ {QPageSize::A10 , DMPAPER_NONE , QPageSize::Millimeter, 73, 105, 26 , 37 , 1.02, 1.46, "A10"},
+ {QPageSize::A3Extra , DMPAPER_A3_EXTRA , QPageSize::Millimeter, 913, 1262, 322 , 445 , 12.67, 17.52, "A3Extra"},
+ {QPageSize::A4Extra , DMPAPER_A4_EXTRA , QPageSize::Millimeter, 667, 914, 235.5, 322.3, 9.27, 12.69, "A4Extra"},
+ {QPageSize::A4Plus , DMPAPER_A4_PLUS , QPageSize::Millimeter, 595, 936, 210 , 330 , 8.27, 13 , "A4Plus"},
+ {QPageSize::A4Small , DMPAPER_A4SMALL , QPageSize::Millimeter, 595, 842, 210 , 297 , 8.27, 11.69, "A4Small"},
+ {QPageSize::A5Extra , DMPAPER_A5_EXTRA , QPageSize::Millimeter, 492, 668, 174 , 235 , 6.85, 9.25, "A5Extra"},
+ {QPageSize::B5Extra , DMPAPER_B5_EXTRA , QPageSize::Millimeter, 570, 782, 201 , 276 , 7.9 , 10.8 , "ISOB5Extra"},
+
+ // JIS Standard Sizes
+ {QPageSize::JisB0 , DMPAPER_NONE , QPageSize::Millimeter, 2920, 4127, 1030 , 1456 , 40.55, 57.32, "B0"},
+ {QPageSize::JisB1 , DMPAPER_NONE , QPageSize::Millimeter, 2064, 2920, 728 , 1030 , 28.66, 40.55, "B1"},
+ {QPageSize::JisB2 , DMPAPER_NONE , QPageSize::Millimeter, 1460, 2064, 515 , 728 , 20.28, 28.66, "B2"},
+ {QPageSize::JisB3 , DMPAPER_NONE , QPageSize::Millimeter, 1032, 1460, 364 , 515 , 14.33, 20.28, "B3"},
+ {QPageSize::JisB4 , DMPAPER_B4 , QPageSize::Millimeter, 729, 1032, 257 , 364 , 10.12, 14.33, "B4"},
+ {QPageSize::JisB5 , DMPAPER_B5 , QPageSize::Millimeter, 516, 729, 182 , 257 , 7.17, 10.12, "B5"},
+ {QPageSize::JisB6 , DMPAPER_B6_JIS , QPageSize::Millimeter, 363, 516, 128 , 182 , 5.04, 7.17, "B6"},
+ {QPageSize::JisB7 , DMPAPER_NONE , QPageSize::Millimeter, 258, 363, 91 , 128 , 3.58, 5.04, "B7"},
+ {QPageSize::JisB8 , DMPAPER_NONE , QPageSize::Millimeter, 181, 258, 64 , 91 , 2.52, 3.58, "B8"},
+ {QPageSize::JisB9 , DMPAPER_NONE , QPageSize::Millimeter, 127, 181, 45 , 64 , 1.77, 2.52, "B9"},
+ {QPageSize::JisB10 , DMPAPER_NONE , QPageSize::Millimeter, 91, 127, 32 , 45 , 1.26, 1.77, "B10"},
+
+ // ANSI / US Standard sizes
+ {QPageSize::AnsiC , DMPAPER_NONE , QPageSize::Inch , 1224, 1584, 431.8, 558.8, 17 , 22 , "AnsiC"},
+ {QPageSize::AnsiD , DMPAPER_NONE , QPageSize::Inch , 1584, 2448, 558.8, 863.6, 22 , 34 , "AnsiD"},
+ {QPageSize::AnsiE , DMPAPER_NONE , QPageSize::Inch , 2448, 3168, 863.6, 1118 , 34 , 44 , "AnsiE"},
+ {QPageSize::LegalExtra , DMPAPER_LEGAL_EXTRA , QPageSize::Inch , 684, 1080, 241.3, 381 , 9.5 , 15 , "LegalExtra"},
+ {QPageSize::LetterExtra , DMPAPER_LETTER_EXTRA , QPageSize::Inch , 684, 864, 241.3, 304.8, 9.5 , 12 , "LetterExtra"},
+ {QPageSize::LetterPlus , DMPAPER_LETTER_PLUS , QPageSize::Inch , 612, 914, 215.9, 322.3, 8.5 , 12.69, "LetterPlus"},
+ {QPageSize::LetterSmall , DMPAPER_LETTERSMALL , QPageSize::Inch , 612, 792, 215.9, 279.4, 8.5 , 11 , "LetterSmall"},
+ {QPageSize::TabloidExtra , DMPAPER_TABLOID_EXTRA , QPageSize::Inch , 864, 1296, 304.8, 457.2, 12 , 18 , "TabloidExtra"},
+
+ // Architectural sizes
+ {QPageSize::ArchA , DMPAPER_NONE , QPageSize::Inch , 648, 864, 228.6, 304.8, 9 , 12 , "ARCHA"},
+ {QPageSize::ArchB , DMPAPER_NONE , QPageSize::Inch , 864, 1296, 304.8, 457.2, 12 , 18 , "ARCHB"},
+ {QPageSize::ArchC , DMPAPER_CSHEET , QPageSize::Inch , 1296, 1728, 457.2, 609.6, 18 , 24 , "ARCHC"},
+ {QPageSize::ArchD , DMPAPER_DSHEET , QPageSize::Inch , 1728, 2592, 609.6, 914.4, 24 , 36 , "ARCHD"},
+ {QPageSize::ArchE , DMPAPER_ESHEET , QPageSize::Inch , 2592, 3456, 914.4, 1219 , 36 , 48 , "ARCHE"},
+
+ // Inch-based Sizes
+ {QPageSize::Imperial7x9 , DMPAPER_NONE , QPageSize::Inch , 504, 648, 177.8, 228.6, 7 , 9 , "7x9"},
+ {QPageSize::Imperial8x10 , DMPAPER_NONE , QPageSize::Inch , 576, 720, 203.2, 254 , 8 , 10 , "8x10"},
+ {QPageSize::Imperial9x11 , DMPAPER_9X11 , QPageSize::Inch , 648, 792, 228.6, 279.4, 9 , 11 , "9x11"},
+ {QPageSize::Imperial9x12 , DMPAPER_NONE , QPageSize::Inch , 648, 864, 228.6, 304.8, 9 , 12 , "9x12"},
+ {QPageSize::Imperial10x11 , DMPAPER_10X11 , QPageSize::Inch , 720, 792, 254 , 279.4, 10 , 11 , "10x11"},
+ {QPageSize::Imperial10x13 , DMPAPER_NONE , QPageSize::Inch , 720, 936, 254 , 330.2, 10 , 13 , "10x13"},
+ {QPageSize::Imperial10x14 , DMPAPER_10X14 , QPageSize::Inch , 720, 1008, 254 , 355.6, 10 , 14 , "10x14"},
+ {QPageSize::Imperial12x11 , DMPAPER_12X11 , QPageSize::Inch , 864, 792, 304.8, 279.4, 12 , 11 , "12x11"},
+ {QPageSize::Imperial15x11 , DMPAPER_15X11 , QPageSize::Inch , 1080, 792, 381 , 279.4, 15 , 11 , "15x11"},
+
+ // Other Page Sizes
+ {QPageSize::ExecutiveStandard , DMPAPER_EXECUTIVE , QPageSize::Inch , 522, 756, 184.2, 266.7, 7.25, 10.5 , "Executive"}, // Qt size differs from Postscript / Windows
+ {QPageSize::Note , DMPAPER_NOTE , QPageSize::Inch , 612, 792, 215.9, 279.4, 8.5 , 11 , "Note"},
+ {QPageSize::Quarto , DMPAPER_QUARTO , QPageSize::Inch , 610, 780, 215.9, 275.1, 8.5 , 10.83, "Quarto"},
+ {QPageSize::Statement , DMPAPER_STATEMENT , QPageSize::Inch , 396, 612, 139.7, 215.9, 5.5 , 8.5 , "Statement"},
+ {QPageSize::SuperA , DMPAPER_A_PLUS , QPageSize::Millimeter, 643, 1009, 227 , 356 , 8.94, 14 , "SuperA"},
+ {QPageSize::SuperB , DMPAPER_B_PLUS , QPageSize::Millimeter, 864, 1380, 305 , 487 , 12 , 19.17, "SuperB"},
+ {QPageSize::Postcard , DMPAPER_JAPANESE_POSTCARD , QPageSize::Millimeter, 284, 419, 100 , 148 , 3.94, 5.83, "Postcard"},
+ {QPageSize::DoublePostcard , DMPAPER_DBL_JAPANESE_POSTCARD, QPageSize::Millimeter, 567, 419, 200 , 148 , 7.87, 5.83, "DoublePostcard"},
+ {QPageSize::Prc16K , DMPAPER_P16K , QPageSize::Millimeter, 414, 610, 146 , 215 , 5.75, 8.5 , "PRC16K"},
+ {QPageSize::Prc32K , DMPAPER_P32K , QPageSize::Millimeter, 275, 428, 97 , 151 , 3.82, 5.95, "PRC32K"},
+ {QPageSize::Prc32KBig , DMPAPER_P32KBIG , QPageSize::Millimeter, 275, 428, 97 , 151 , 3.82, 5.95, "PRC32KBig"},
+
+ // Fan Fold Sizes
+ {QPageSize::FanFoldUS , DMPAPER_FANFOLD_US , QPageSize::Inch , 1071, 792, 377.8, 279.4, 14.875, 11 , "FanFoldUS"},
+ {QPageSize::FanFoldGerman , DMPAPER_FANFOLD_STD_GERMAN , QPageSize::Inch , 612, 864, 215.9, 304.8, 8.5 , 12 , "FanFoldGerman"},
+ {QPageSize::FanFoldGermanLegal, DMPAPER_FANFOLD_LGL_GERMAN , QPageSize::Inch , 612, 936, 215.9, 330 , 8.5 , 13 , "FanFoldGermanLegal"},
+
+ // ISO Envelopes
+ {QPageSize::EnvelopeB4 , DMPAPER_ENV_B4 , QPageSize::Millimeter, 708, 1001, 250 , 353 , 9.84, 13.9 , "EnvISOB4"},
+ {QPageSize::EnvelopeB5 , DMPAPER_ENV_B5 , QPageSize::Millimeter, 499, 709, 176 , 250 , 6.9 , 9.8 , "EnvISOB5"},
+ {QPageSize::EnvelopeB6 , DMPAPER_ENV_B6 , QPageSize::Millimeter, 499, 354, 176 , 125 , 6.9 , 4.9 , "EnvISOB6"},
+ {QPageSize::EnvelopeC0 , DMPAPER_NONE , QPageSize::Millimeter, 2599, 3676, 917 , 1297 , 36.1 , 51.06, "EnvC0"},
+ {QPageSize::EnvelopeC1 , DMPAPER_NONE , QPageSize::Millimeter, 1837, 2599, 648 , 917 , 25.51, 36.1 , "EnvC1"},
+ {QPageSize::EnvelopeC2 , DMPAPER_NONE , QPageSize::Millimeter, 1298, 1837, 458 , 648 , 18.03, 25.51, "EnvC2"},
+ {QPageSize::EnvelopeC3 , DMPAPER_ENV_C3 , QPageSize::Millimeter, 918, 1296, 324 , 458 , 12.75, 18.03, "EnvC3"},
+ {QPageSize::EnvelopeC4 , DMPAPER_ENV_C4 , QPageSize::Millimeter, 649, 918, 229 , 324 , 9.02, 12.75, "EnvC4"},
+ {QPageSize::EnvelopeC6 , DMPAPER_ENV_C6 , QPageSize::Millimeter, 323, 459, 114 , 162 , 4.49, 6.38, "EnvC6"},
+ {QPageSize::EnvelopeC65 , DMPAPER_ENV_C65 , QPageSize::Millimeter, 324, 648, 114 , 229 , 4.5 , 9 , "EnvC65"},
+ {QPageSize::EnvelopeC7 , DMPAPER_NONE , QPageSize::Millimeter, 230, 323, 81 , 114 , 3.19, 4.49, "EnvC7"},
+
+ // US Envelopes
+ {QPageSize::Envelope9 , DMPAPER_ENV_9 , QPageSize::Inch , 279, 639, 98.4, 225.4, 3.875, 8.875, "Env9"},
+ {QPageSize::Envelope11 , DMPAPER_ENV_11 , QPageSize::Inch , 324, 747, 114.3, 263.5, 4.5 , 10.375, "Env11"},
+ {QPageSize::Envelope12 , DMPAPER_ENV_12 , QPageSize::Inch , 342, 792, 120.7, 279.4, 4.75, 11 , "Env12"},
+ {QPageSize::Envelope14 , DMPAPER_ENV_14 , QPageSize::Inch , 360, 828, 127 , 292.1, 5 , 11.5 , "Env14"},
+ {QPageSize::EnvelopeMonarch , DMPAPER_ENV_MONARCH , QPageSize::Inch , 279, 540, 98.43, 190.5, 3.875, 7.5 , "EnvMonarch"},
+ {QPageSize::EnvelopePersonal , DMPAPER_ENV_PERSONAL , QPageSize::Inch , 261, 468, 92.08, 165.1, 3.625, 6.5 , "EnvPersonal"},
+
+ // Other Envelopes
+ {QPageSize::EnvelopeChou3 , DMPAPER_JENV_CHOU3 , QPageSize::Millimeter, 340, 666, 120 , 235 , 4.72, 9.25, "EnvChou3"},
+ {QPageSize::EnvelopeChou4 , DMPAPER_JENV_CHOU4 , QPageSize::Millimeter, 255, 581, 90 , 205 , 3.54, 8 , "EnvChou4"},
+ {QPageSize::EnvelopeInvite , DMPAPER_ENV_INVITE , QPageSize::Millimeter, 624, 624, 220 , 220 , 8.66, 8.66, "EnvInvite"},
+ {QPageSize::EnvelopeItalian , DMPAPER_ENV_ITALY , QPageSize::Millimeter, 312, 652, 110 , 230 , 4.33, 9 , "EnvItalian"},
+ {QPageSize::EnvelopeKaku2 , DMPAPER_JENV_KAKU2 , QPageSize::Millimeter, 680, 941, 240 , 332 , 9.45, 13 , "EnvKaku2"},
+ {QPageSize::EnvelopeKaku3 , DMPAPER_JENV_KAKU3 , QPageSize::Millimeter, 612, 785, 216 , 277 , 8.5 , 10.9 , "EnvKaku3"},
+ {QPageSize::EnvelopePrc1 , DMPAPER_PENV_1 , QPageSize::Millimeter, 289, 468, 102 , 165 , 4 , 6.5 , "EnvPRC1"},
+ {QPageSize::EnvelopePrc2 , DMPAPER_PENV_2 , QPageSize::Millimeter, 289, 499, 102 , 176 , 4 , 6.9 , "EnvPRC2"},
+ {QPageSize::EnvelopePrc3 , DMPAPER_PENV_3 , QPageSize::Millimeter, 354, 499, 125 , 176 , 4.9 , 6.9 , "EnvPRC3"},
+ {QPageSize::EnvelopePrc4 , DMPAPER_PENV_4 , QPageSize::Millimeter, 312, 590, 110 , 208 , 4.33, 8.2 , "EnvPRC4"},
+ {QPageSize::EnvelopePrc5 , DMPAPER_PENV_5 , QPageSize::Millimeter, 312, 624, 110 , 220 , 4.33, 8.66, "EnvPRC5"},
+ {QPageSize::EnvelopePrc6 , DMPAPER_PENV_6 , QPageSize::Millimeter, 340, 652, 120 , 230 , 4.7 , 9 , "EnvPRC6"},
+ {QPageSize::EnvelopePrc7 , DMPAPER_PENV_7 , QPageSize::Millimeter, 454, 652, 160 , 230 , 6.3 , 9 , "EnvPRC7"},
+ {QPageSize::EnvelopePrc8 , DMPAPER_PENV_8 , QPageSize::Millimeter, 340, 876, 120 , 309 , 4.7 , 12.2 , "EnvPRC8"},
+ {QPageSize::EnvelopePrc9 , DMPAPER_PENV_9 , QPageSize::Millimeter, 649, 918, 229 , 324 , 9 , 12.75, "EnvPRC9"},
+ {QPageSize::EnvelopePrc10 , DMPAPER_PENV_10 , QPageSize::Millimeter, 918, 1298, 324 , 458 , 12.75, 18 , "EnvPRC10"},
+ {QPageSize::EnvelopeYou4 , DMPAPER_JENV_YOU4 , QPageSize::Millimeter, 298, 666, 105 , 235 , 4.13, 9.25, "EnvYou4"}
+};
+
+static const int pageSizesCount = int(sizeof(qt_pageSizes) / sizeof(qt_pageSizes[0]));
+
+// Return key name for PageSize
+static QString qt_keyForPageSizeId(QPageSize::PageSizeId id)
+{
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ return QString::fromLatin1(qt_pageSizes[id].mediaOption);
+}
+
+// Return id name for PPD Key
+static QPageSize::PageSizeId qt_idForPpdKey(const QString &ppdKey, QSize *match = 0)
+{
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ if (ppdKey.isEmpty())
+ return QPageSize::Custom;
+ QString key = ppdKey;
+ // Remove any Rotated or Tranverse modifiers
+ if (key.endsWith(QStringLiteral("Rotated")))
+ key.chop(7);
+ else if (key.endsWith(QStringLiteral(".Transverse")))
+ key.chop(11);
+ for (int i = 0; i <= int(QPageSize::LastPageSize); ++i) {
+ if (QLatin1String(qt_pageSizes[i].mediaOption) == key) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+ return QPageSize::Custom;
+}
+
+// Return id name for Windows ID
+static QPageSize::PageSizeId qt_idForWindowsID(int windowsId, QSize *match = 0)
+{
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ // If outside known values then is Custom
+ if (windowsId <= DMPAPER_NONE || windowsId > DMPAPER_LAST)
+ return QPageSize::Custom;
+ // Check if one of the unsupported values, convert to valid value if is
+ for (int i = 0; i < windowsConversionCount; ++i) {
+ if (qt_windowsConversion[i][0] == windowsId) {
+ windowsId = qt_windowsConversion[i][1];
+ break;
+ }
+ }
+ // Look for the value in our supported size table
+ for (int i = 0; i <= int(QPageSize::LastPageSize); ++i) {
+ if (qt_pageSizes[i].windowsId == windowsId) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+ // Otherwise is Custom
+ return QPageSize::Custom;
+}
+
+// Return key name for custom size
+static QString qt_keyForCustomSize(const QSizeF &size, QPageSize::Unit units)
+{
+ // PPD custom format
+ QString key = QStringLiteral("Custom.%1x%2%3");
+ QString abbrev;
+ switch (units) {
+ case QPageSize::Millimeter:
+ abbrev = QStringLiteral("mm");
+ break;
+ case QPageSize::Point:
+ break;
+ case QPageSize::Inch:
+ abbrev = QStringLiteral("in");
+ break;
+ case QPageSize::Pica:
+ abbrev = QStringLiteral("pc");
+ break;
+ case QPageSize::Didot:
+ abbrev = QStringLiteral("DD");
+ break;
+ case QPageSize::Cicero:
+ abbrev = QStringLiteral("CC");
+ break;
+ }
+ // Assumes size is already max 2 decimal places
+ return key.arg(size.width()).arg(size.height()).arg(abbrev);
+}
+
+// Return localized name for custom size
+static QString qt_nameForCustomSize(const QSizeF &size, QPageSize::Unit units)
+{
+ QString name;
+ switch (units) {
+ case QPageSize::Millimeter:
+ //: Custom size name in millimeters
+ name = QCoreApplication::translate("QPageSize", "Custom (%1mm x %2mm)");
+ break;
+ case QPageSize::Point:
+ //: Custom size name in points
+ name = QCoreApplication::translate("QPageSize", "Custom (%1pt x %2pt)");
+ break;
+ case QPageSize::Inch:
+ //: Custom size name in inches
+ name = QCoreApplication::translate("QPageSize", "Custom (%1in x %2in)");
+ break;
+ case QPageSize::Pica:
+ //: Custom size name in picas
+ name = QCoreApplication::translate("QPageSize", "Custom (%1pc x %2pc)");
+ break;
+ case QPageSize::Didot:
+ //: Custom size name in didots
+ name = QCoreApplication::translate("QPageSize", "Custom (%1DD x %2DD)");
+ break;
+ case QPageSize::Cicero:
+ //: Custom size name in ciceros
+ name = QCoreApplication::translate("QPageSize", "Custom (%1CC x %2CC)");
+ break;
+ }
+ // Assumes size is already max 2 decimal places
+ return name.arg(size.width()).arg(size.height());
+}
+
+// Multiplier for converting units to points.
+static qreal qt_pointMultiplier(QPageSize::Unit unit)
+{
+ switch (unit) {
+ case QPageSize::Millimeter:
+ return 2.83464566929;
+ case QPageSize::Point:
+ return 1.0;
+ case QPageSize::Inch:
+ return 72.0;
+ case QPageSize::Pica:
+ return 12;
+ case QPageSize::Didot:
+ return 1.065826771;
+ case QPageSize::Cicero:
+ return 12.789921252;
+ }
+ return 1.0;
+}
+
+// Multiplier for converting pixels to points.
+Q_GUI_EXPORT qreal qt_pixelMultiplier(int resolution)
+{
+ return resolution <= 0 ? 1.0 : 72.0 / resolution;
+}
+
+static QSizeF qt_definitionSize(QPageSize::PageSizeId pageSizeId)
+{
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ QPageSize::Unit units = qt_pageSizes[pageSizeId].definitionUnits;
+ if (units == QPageSize::Millimeter)
+ return QSizeF(qt_pageSizes[pageSizeId].widthMillimeters, qt_pageSizes[pageSizeId].heightMillimeters);
+ Q_ASSERT(units == QPageSize::Inch); // We currently only support definitions in mm or inches
+ return QSizeF(qt_pageSizes[pageSizeId].widthInches, qt_pageSizes[pageSizeId].heightInches);
+}
+
+static QSizeF qt_convertUnits(const QSizeF &size, QPageSize::Unit fromUnits, QPageSize::Unit toUnits)
+{
+ if (!size.isValid())
+ return QSizeF();
+
+ // If the units are the same or the size is 0, then don't need to convert
+ if (fromUnits == toUnits || (qFuzzyIsNull(size.width()) && qFuzzyIsNull(size.height())))
+ return size;
+
+ QSizeF newSize = size;
+ // First convert to points
+ if (fromUnits != QPageSize::Point) {
+ const qreal multiplier = qt_pointMultiplier(fromUnits);
+ newSize = newSize * multiplier;
+ }
+ // Then convert from points to required units
+ const qreal multiplier = qt_pointMultiplier(toUnits);
+ // Try force to 2 decimal places for consistency
+ const int width = qRound(newSize.width() * 100 / multiplier);
+ const int height = qRound(newSize.height() * 100 / multiplier);
+ return QSizeF(width / 100.0, height / 100.0);
+}
+
+static QSize qt_convertUnitsToPoints(const QSizeF &size, QPageSize::Unit units)
+{
+ if (!size.isValid())
+ return QSize();
+ return QSizeF(size * qt_pointMultiplier(units)).toSize();
+}
+
+static QSize qt_convertPointsToPixels(const QSize &size, int resolution)
+{
+ if (!size.isValid() || resolution <= 0)
+ return QSize();
+ const qreal multiplier = qt_pixelMultiplier(resolution);
+ return QSize(qRound(size.width() / multiplier), qRound(size.height() / multiplier));
+}
+
+static QSizeF qt_convertPointsToUnits(const QSize &size, QPageSize::Unit units)
+{
+ if (!size.isValid())
+ return QSizeF();
+ const qreal multiplier = qt_pointMultiplier(units);
+ // Try force to 2 decimal places for consistency
+ const int width = qRound(size.width() * 100 / multiplier);
+ const int height = qRound(size.height() * 100 / multiplier);
+ return QSizeF(width / 100.0, height / 100.0);
+}
+
+static QSizeF qt_unitSize(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units)
+{
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ switch (units) {
+ case QPageSize::Millimeter:
+ return QSizeF(qt_pageSizes[pageSizeId].widthMillimeters, qt_pageSizes[pageSizeId].heightMillimeters);
+ case QPageSize::Point:
+ return QSizeF(qt_pageSizes[pageSizeId].widthPoints, qt_pageSizes[pageSizeId].heightPoints);
+ case QPageSize::Inch:
+ return QSizeF(qt_pageSizes[pageSizeId].widthInches, qt_pageSizes[pageSizeId].heightInches);
+ case QPageSize::Pica:
+ case QPageSize::Didot:
+ case QPageSize::Cicero:
+ return qt_convertPointsToUnits(QSize(qt_pageSizes[pageSizeId].widthPoints,
+ qt_pageSizes[pageSizeId].heightPoints), units);
+ }
+ return QSizeF();
+}
+
+// Find matching standard page size for point size
+static QPageSize::PageSizeId qt_idForPointSize(const QSize &size, QPageSize::SizeMatchPolicy matchPolicy, QSize *match)
+{
+ if (!size.isValid())
+ return QPageSize::Custom;
+
+ // Try exact match in portrait layout
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ for (int i = 0; i <= int(QPageSize::LastPageSize); ++i) {
+ if (size.width() == qt_pageSizes[i].widthPoints && size.height() == qt_pageSizes[i].heightPoints) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+
+ // If no exact match only try fuzzy if asked
+ if (matchPolicy != QPageSize::ExactMatch) {
+ // Set up the fuzzy tolerance
+ // TODO Use ISO standard tolerance based on page size?
+ const int tolerance = 3; // = approx 1mm
+ const int minWidth = size.width() - tolerance;
+ const int maxWidth = size.width() + tolerance;
+ const int minHeight = size.height() - tolerance;
+ const int maxHeight = size.height() + tolerance;
+
+ // First try fuzzy match in portrait layout
+ for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
+ const int width = qt_pageSizes[i].widthPoints;
+ const int height = qt_pageSizes[i].heightPoints;
+ if (width >= minWidth && width <= maxWidth && height >= minHeight && height <= maxHeight) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+
+ // If FuzzyOrientationMatch then try rotated sizes
+ if (matchPolicy == QPageSize::FuzzyOrientationMatch) {
+ // First try exact match in landscape layout
+ for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
+ if (size.width() == qt_pageSizes[i].heightPoints && size.height() == qt_pageSizes[i].widthPoints) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+
+ // Then try fuzzy match in landscape layout
+ for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
+ const int width = qt_pageSizes[i].heightPoints;
+ const int height = qt_pageSizes[i].widthPoints;
+ if (width >= minWidth && width <= maxWidth && height >= minHeight && height <= maxHeight) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+ }
+ }
+
+ if (match)
+ *match = size;
+ // Otherwise no match so Custom
+ return QPageSize::Custom;
+}
+
+// Find matching standard page size for point size
+static QPageSize::PageSizeId qt_idForSize(const QSizeF &size, QPageSize::Unit units,
+ QPageSize::SizeMatchPolicy matchPolicy, QSize *match)
+{
+ if (!size.isValid())
+ return QPageSize::Custom;
+
+ // Try exact match if units are the same
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ if (units == QPageSize::Millimeter) {
+ for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
+ if (size.width() == qt_pageSizes[i].widthMillimeters && size.height() == qt_pageSizes[i].heightMillimeters) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+ } else if (units == QPageSize::Inch) {
+ for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
+ if (size.width() == qt_pageSizes[i].widthInches && size.height() == qt_pageSizes[i].heightInches) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+ } else if (units == QPageSize::Point) {
+ for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
+ if (size.width() == qt_pageSizes[i].widthPoints && size.height() == qt_pageSizes[i].heightPoints) {
+ if (match)
+ *match = QSize(qt_pageSizes[i].widthPoints, qt_pageSizes[i].heightPoints);
+ return qt_pageSizes[i].id;
+ }
+ }
+ }
+
+ // If no exact match then convert to points and try match those
+ QSize points = qt_convertUnitsToPoints(size, units);
+ return qt_idForPointSize(points, matchPolicy, match);
+}
+
+class QPageSizePrivate : public QSharedData
+{
+public:
+ QPageSizePrivate();
+ explicit QPageSizePrivate(QPageSize::PageSizeId pageSizeId);
+ QPageSizePrivate(const QSize &pointSize,
+ const QString &name,
+ QPageSize::SizeMatchPolicy matchPolicy);
+ QPageSizePrivate(const QSizeF &size, QPageSize::Unit units,
+ const QString &name,
+ QPageSize::SizeMatchPolicy matchPolicy);
+ QPageSizePrivate(const QString &key, const QSize &size, const QString &name);
+ QPageSizePrivate(int windowsId, const QSize &pointSize, const QString &name);
+ ~QPageSizePrivate();
+
+ bool operator==(const QPageSizePrivate &other) const;
+ bool isEquivalentTo(const QPageSizePrivate &other) const;
+
+ bool isValid() const;
+
+ QSizeF size(QPageSize::Unit units) const;
+ QSize sizePixels(int resolution) const;
+
+private:
+ friend class QPageSize;
+
+ void init(QPageSize::PageSizeId id, const QString &name);
+ void init(const QSize &size, const QString &name);
+ void init(const QSizeF &size, QPageSize::Unit units, const QString &name);
+
+ QString m_key;
+ QPageSize::PageSizeId m_id;
+ QSize m_pointSize;
+ QString m_name;
+ int m_windowsId;
+ QSizeF m_size;
+ QPageSize::Unit m_units;
+};
+
+QPageSizePrivate::QPageSizePrivate()
+ : m_id(QPageSize::Custom),
+ m_windowsId(0),
+ m_units(QPageSize::Point)
+{
+}
+
+QPageSizePrivate::QPageSizePrivate(QPageSize::PageSizeId pageSizeId)
+ : m_id(QPageSize::Custom),
+ m_windowsId(0),
+ m_units(QPageSize::Point)
+{
+ if (pageSizeId >= QPageSize::PageSizeId(0) && pageSizeId <= QPageSize::LastPageSize)
+ init(pageSizeId, QString());
+}
+
+QPageSizePrivate::QPageSizePrivate(const QSize &pointSize, const QString &name, QPageSize::SizeMatchPolicy matchPolicy)
+ : m_id(QPageSize::Custom),
+ m_windowsId(0),
+ m_units(QPageSize::Point)
+{
+ if (pointSize.isValid()) {
+ QPageSize::PageSizeId id = qt_idForPointSize(pointSize, matchPolicy, 0);
+ id == QPageSize::Custom ? init(pointSize, name) : init(id, name);
+ }
+}
+
+QPageSizePrivate::QPageSizePrivate(const QSizeF &size, QPageSize::Unit units,
+ const QString &name, QPageSize::SizeMatchPolicy matchPolicy)
+ : m_id(QPageSize::Custom),
+ m_windowsId(0),
+ m_units(QPageSize::Point)
+{
+ if (size.isValid()) {
+ QPageSize::PageSizeId id = qt_idForSize(size, units, matchPolicy, 0);
+ id == QPageSize::Custom ? init(size, units, name) : init(id, name);
+ }
+}
+
+QPageSizePrivate::QPageSizePrivate(const QString &key, const QSize &pointSize, const QString &name)
+ : m_id(QPageSize::Custom),
+ m_windowsId(0),
+ m_units(QPageSize::Point)
+{
+ if (!key.isEmpty() && pointSize.isValid()) {
+ QPageSize::PageSizeId id = qt_idForPpdKey(key, 0);
+ // If not a known PPD key, check if size is a standard PPD size
+ if (id == QPageSize::Custom)
+ id = qt_idForPointSize(pointSize, QPageSize::FuzzyMatch, 0);
+ id == QPageSize::Custom ? init(pointSize, name) : init(id, name);
+ m_key = key;
+ }
+}
+
+QPageSizePrivate::QPageSizePrivate(int windowsId, const QSize &pointSize, const QString &name)
+ : m_id(QPageSize::Custom),
+ m_windowsId(0),
+ m_units(QPageSize::Point)
+{
+ if (windowsId > 0 && pointSize.isValid()) {
+ QPageSize::PageSizeId id = qt_idForWindowsID(windowsId, 0);
+ // If not a known Windows ID, check if size is a standard PPD size
+ if (id == QPageSize::Custom)
+ id = qt_idForPointSize(pointSize, QPageSize::FuzzyMatch, 0);
+ id == QPageSize::Custom ? init(pointSize, name) : init(id, name);
+ m_windowsId = windowsId;
+ }
+}
+
+QPageSizePrivate::~QPageSizePrivate()
+{
+}
+
+// Init a standard PageSizeId
+void QPageSizePrivate::init(QPageSize::PageSizeId id, const QString &name)
+{
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ m_id = id;
+ m_size = qt_definitionSize(id);
+ m_units = qt_pageSizes[id].definitionUnits;
+ m_key = qt_keyForPageSizeId(id);
+ m_name = name.isEmpty() ? QPageSize::name(id) : name;
+ m_windowsId = qt_pageSizes[id].windowsId;
+ m_pointSize = QSize(qt_pageSizes[id].widthPoints, qt_pageSizes[id].heightPoints);
+}
+
+// Init a point size
+void QPageSizePrivate::init(const QSize &size, const QString &name)
+{
+ m_id = QPageSize::Custom;
+ m_size = size;
+ m_units = QPageSize::Point;
+ m_key = qt_keyForCustomSize(m_size, m_units);
+ m_name = name.isEmpty() ? qt_nameForCustomSize(m_size, m_units) : name;
+ m_windowsId = 0;
+ m_pointSize = size;
+}
+
+// Init a unit size
+void QPageSizePrivate::init(const QSizeF &size, QPageSize::Unit units, const QString &name)
+{
+ m_id = QPageSize::Custom;
+ m_size = size;
+ m_units = units;
+ m_key = qt_keyForCustomSize(m_size, m_units);
+ if (name.isEmpty())
+ m_name = qt_nameForCustomSize(m_size, m_units);
+ else
+ m_name = name;
+ m_windowsId = 0;
+ m_pointSize = qt_convertUnitsToPoints(m_size, m_units);
+}
+
+bool QPageSizePrivate::operator==(const QPageSizePrivate &other) const
+{
+ return m_size == other.m_size
+ && m_units == other.m_units
+ && m_key == other.m_key
+ && m_name == other.m_name;
+}
+
+bool QPageSizePrivate::isEquivalentTo(const QPageSizePrivate &other) const
+{
+ return m_pointSize == other.m_pointSize;
+}
+
+bool QPageSizePrivate::isValid() const
+{
+ return m_pointSize.isValid() && !m_key.isEmpty() && !m_name.isEmpty();
+}
+
+QSizeF QPageSizePrivate::size(QPageSize::Unit units) const
+{
+ // If want units we've stored in, we already have them
+ if (units == m_units)
+ return m_size;
+
+ // If want points we already have them
+ if (units == QPageSize::Point)
+ return QSizeF(m_pointSize.width(), m_pointSize.height());
+
+ // If a custom size do a conversion
+ if (m_id == QPageSize::Custom)
+ return qt_convertUnits(m_size, m_units, units);
+
+ // Otherwise use the standard sizes
+ return qt_unitSize(m_id, units);
+}
+
+QSize QPageSizePrivate::sizePixels(int resolution) const
+{
+ return qt_convertPointsToPixels(m_pointSize, resolution);;
+}
+
+
+/*!
+ \class QPageSize
+ \inmodule QtGui
+ \since 5.3
+ \brief The QPageSize class describes the size and name of a defined page size
+
+ This class implements support for the set of standard page sizes as defined
+ in the Adobe Postscript PPD Standard v4.3. It defines the standard set of
+ page sizes in points, millimeters and inches and ensures these sizes are
+ consistently used. Other size units can be used but will be calculated
+ results and so may not always be consistent. The defined point sizes are
+ always a integer, all other sizes can be fractions of a unit.
+
+ The defined size is always in width x height order with no implied page
+ orientation. Note that it is possible for page sizes to be defined where the
+ width is greater than the height, such as QPageSize::Ledger, so you cannot
+ rely on comparing the width and height values to determine page orientation.
+
+ For example, A4 is defined by the standard as 210mm x 297mm, 8.27in x 11.69in,
+ or 595pt x 842pt.
+
+ You can also define custom page sizes with custom names in any units you want
+ and this unit size will be preserved and used as the base for all other unit
+ size calculations.
+
+ When creating a QPageSize using a custom QSize you can choose if you want
+ QPageSize to try match the size to a standard page size. By default
+ QPaperSize uses a FuzzyMatch mode where it will match a given page size to
+ a standard page size if it falls within 3 postscript points of a defined
+ standard size. You can override this to request only an exact match but this
+ is not recommended as conversions between units can easily lose 3 points and
+ result in incorrect page sizes.
+
+ A QPageSize instance may also be obtained by querying the supported page sizes
+ for a print device. In this case the localized name returned is that defined
+ by the printer itself. Note that the print device may not support the current
+ default locale language.
+
+ The class also provides convenience methods for converting page size IDs to and from
+ various unit sizes.
+
+ \sa QPagedPaintDevice, QPdfWriter
+*/
+
+/*!
+ \enum QPageSize::PageSizeId
+
+ This enum type lists the available page sizes as defined in the Postscript
+ PPD standard. These values are duplicated in QPagedPaintDevice and QPrinter.
+
+ The defined sizes are:
+
+ \value A0 841 x 1189 mm
+ \value A1 594 x 841 mm
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.69 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1000 x 1414 mm
+ \value B1 707 x 1000 mm
+ \value B2 500 x 707 mm
+ \value B3 353 x 500 mm
+ \value B4 250 x 353 mm
+ \value B5 176 x 250 mm, 6.93 x 9.84 inches
+ \value B6 125 x 176 mm
+ \value B7 88 x 125 mm
+ \value B8 62 x 88 mm
+ \value B9 44 x 62 mm
+ \value B10 31 x 44 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 190.5 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 431.8 x 279.4 mm
+ \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
+ \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
+ \value Tabloid 279.4 x 431.8 mm
+ \value Custom Unknown, or a user defined size.
+ \value A10
+ \value A3Extra
+ \value A4Extra
+ \value A4Plus
+ \value A4Small
+ \value A5Extra
+ \value B5Extra
+ \value JisB0
+ \value JisB1
+ \value JisB2
+ \value JisB3
+ \value JisB4
+ \value JisB5
+ \value JisB6,
+ \value JisB7
+ \value JisB8
+ \value JisB9
+ \value JisB10
+ \value AnsiA = Letter
+ \value AnsiB = Ledger
+ \value AnsiC
+ \value AnsiD
+ \value AnsiE
+ \value LegalExtra
+ \value LetterExtra
+ \value LetterPlus
+ \value LetterSmall
+ \value TabloidExtra
+ \value ArchA
+ \value ArchB
+ \value ArchC
+ \value ArchD
+ \value ArchE
+ \value Imperial7x9
+ \value Imperial8x10
+ \value Imperial9x11
+ \value Imperial9x12
+ \value Imperial10x11
+ \value Imperial10x13
+ \value Imperial10x14
+ \value Imperial12x11
+ \value Imperial15x11
+ \value ExecutiveStandard
+ \value Note
+ \value Quarto
+ \value Statement
+ \value SuperA
+ \value SuperB
+ \value Postcard
+ \value DoublePostcard
+ \value Prc16K
+ \value Prc32K
+ \value Prc32KBig
+ \value FanFoldUS
+ \value FanFoldGerman
+ \value FanFoldGermanLegal
+ \value EnvelopeB4
+ \value EnvelopeB5
+ \value EnvelopeB6
+ \value EnvelopeC0
+ \value EnvelopeC1
+ \value EnvelopeC2
+ \value EnvelopeC3
+ \value EnvelopeC4
+ \value EnvelopeC5 = C5E
+ \value EnvelopeC6
+ \value EnvelopeC65
+ \value EnvelopeC7
+ \value EnvelopeDL = DLE
+ \value Envelope9
+ \value Envelope10 = Comm10E
+ \value Envelope11
+ \value Envelope12
+ \value Envelope14
+ \value EnvelopeMonarch
+ \value EnvelopePersonal
+ \value EnvelopeChou3
+ \value EnvelopeChou4
+ \value EnvelopeInvite
+ \value EnvelopeItalian
+ \value EnvelopeKaku2
+ \value EnvelopeKaku3
+ \value EnvelopePrc1
+ \value EnvelopePrc2
+ \value EnvelopePrc3
+ \value EnvelopePrc4
+ \value EnvelopePrc5
+ \value EnvelopePrc6
+ \value EnvelopePrc7
+ \value EnvelopePrc8
+ \value EnvelopePrc9
+ \value EnvelopePrc10
+ \value EnvelopeYou4
+ \value LastPageSize = EnvelopeYou4
+ \omitvalue NPageSize
+ \omitvalue NPaperSize
+
+ Due to historic reasons QPageSize::Executive is not the same as the standard
+ Postscript and Windows Executive size, use QPageSize::ExecutiveStandard instead.
+
+ The Postscript standard size QPageSize::Folio is different to the Windows
+ DMPAPER_FOLIO size, use the Postscript standard size QPageSize::FanFoldGermanLegal
+ if needed.
+*/
+
+/*!
+ \enum QPageSize::Unit
+
+ This enum type is used to specify the measurement unit for page sizes.
+
+ \value Millimeter
+ \value Point 1/72th of an inch
+ \value Inch
+ \value Pica 1/72th of a foot, 1/6th of an inch, 12 Points
+ \value Didot 1/72th of a French inch, 0.375 mm
+ \value Cicero 1/6th of a French inch, 12 Didot, 4.5mm
+*/
+
+/*!
+ \enum QPageSize::SizeMatchPolicy
+
+ \value FuzzyMatch Match to a standard page size if within the margin of tolerance.
+ \value FuzzyOrientationMatch Match to a standard page size if within the margin of tolerance regardless of orientation.
+ \value ExactMatch Only match to a standard page size if the sizes match exactly.
+*/
+
+/*!
+ Creates a null QPageSize.
+*/
+
+QPageSize::QPageSize()
+ : d(new QPageSizePrivate())
+{
+}
+
+/*!
+ Creates a QPageSize of the standard \a pageSize.
+
+ If \a pageSize is QPageSize::Custom then the resulting QPageSize will not
+ be valid. Use the custom size constructor instead.
+*/
+
+QPageSize::QPageSize(QPageSize::PageSizeId pageSize)
+ : d(new QPageSizePrivate(pageSize))
+{
+}
+
+/*!
+ Creates a QPageSize of the given \a pointSize in Points using the matching \a matchPolicy.
+
+ If the given \a pointSize matches a standard QPageSize::PageSizeId, then that page
+ size will be used. Note that if the \a matchPolicy is FuzzyMatch this may result
+ in the \a pointSize being adjusted to the standard size. To prevent this happening
+ use a \a matchPolicy of ExactMatch instead.
+
+ If the given \a pointSize is not a standard QPageSize::PageSizeId then a QPageSize::Custom
+ size will be created.
+
+ If \a name is null then the standard localized name will be used. If a custom page
+ size then a custom name in the format "Custom (width x height)" will be created.
+
+ The \a matchPolicy defaults to FuzzyMatch.
+*/
+
+QPageSize::QPageSize(const QSize &pointSize, const QString &name, SizeMatchPolicy matchPolicy)
+ : d(new QPageSizePrivate(pointSize, name, matchPolicy))
+{
+}
+
+/*!
+ Creates a custom page of the given \a size in \a units.
+
+ If the given \a size matches a standard QPageSize::PageSizeId, then that page
+ size will be used. Note that if the \a matchPolicy is FuzzyMatch this may result
+ in the \a size being adjusted to the standard size. To prevent this happening
+ use a \a matchPolicy of ExactMatch instead.
+
+ If the given \a size is not a standard QPageSize::PageSizeId then a QPageSize::Custom
+ size will be created. The original unit size will be preserved and used as the
+ base for all other unit size calculations.
+
+ If \a name is null then a custom name will be created in the form
+ "Custom (width x height)" where the size is expressed in units provided.
+*/
+
+QPageSize::QPageSize(const QSizeF &size, QPageSize::Unit units,
+ const QString &name, SizeMatchPolicy matchPolicy)
+ : d(new QPageSizePrivate(size, units, name, matchPolicy))
+{
+}
+
+/*!
+ \internal
+
+ Create page with given key, size and name, for use by printer plugin.
+*/
+
+QPageSize::QPageSize(const QString &key, const QSize &pointSize, const QString &name)
+ : d(new QPageSizePrivate(key, pointSize, name))
+{
+}
+
+/*!
+ \internal
+
+ Create page with given windows ID, size and name, for use by printer plugin.
+*/
+
+QPageSize::QPageSize(int windowsId, const QSize &pointSize, const QString &name)
+ : d(new QPageSizePrivate(windowsId, pointSize, name))
+{
+}
+
+/*!
+ \internal
+
+ Create page with given private backend
+*/
+
+QPageSize::QPageSize(QPageSizePrivate &dd)
+ : d(&dd)
+{
+}
+
+/*!
+ Copy constructor, copies \a other to this.
+*/
+
+QPageSize::QPageSize(const QPageSize &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Destroys the page.
+*/
+
+QPageSize::~QPageSize()
+{
+}
+
+/*!
+ Assignment operator, assigns \a other to this.
+*/
+
+QPageSize &QPageSize::operator=(const QPageSize &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \fn void QPageSize::swap(QPageSize &other)
+
+ Swaps this QPageSize with \a other. This function is very fast and
+ never fails.
+*/
+
+/*!
+ \fn QPageSize &QPageSize::operator=(QPageSize &&other)
+
+ Move-assigns \a other to this QPageSize instance, transferring the
+ ownership of the managed pointer to this instance.
+*/
+
+/*!
+ Returns \c true if this page is equal to the \a other page, i.e. if the
+ page has the same attributes. Current attributes are size and name.
+*/
+
+bool QPageSize::operator==(const QPageSize &other) const
+{
+ if (d == other.d)
+ return true;
+ return d && other.d && *d == *other.d;
+}
+
+/*!
+ Returns \c true if this page is equivalent to the \a other page, i.e. if the
+ page has the same size regardless of other attributes like name.
+*/
+
+bool QPageSize::isEquivalentTo(const QPageSize &other) const
+{
+ if (d == other.d)
+ return true;
+ return d && other.d && d->isEquivalentTo(*other.d);
+}
+
+/*!
+ Returns \c true if this page size is valid.
+
+ The page size may be invalid if created with an invalid PageSizeId, or a
+ negative or invalid QSize or QSizeF, or the null constructor.
+*/
+
+bool QPageSize::isValid() const
+{
+ return d && d->isValid();
+}
+
+/*!
+ Returns the unique key of the page size.
+
+ By default this is the PPD standard mediaOption keyword for the page size,
+ or the PPD custom format key. If the QPageSize instance was obtained from
+ a print device then this will be the key provided by the print device and
+ may differ from the standard key.
+
+ If the QPageSize is invalid then the key will be an empty string.
+
+ This key should never be shown to end users, it is an internal key only.
+ For a human-readable name use name().
+
+ \sa name()
+*/
+
+QString QPageSize::key() const
+{
+ return isValid() ? d->m_key : QString();
+}
+
+/*!
+ Returns a localized human-readable name for the page size.
+
+ If the QPageSize instance was obtained from a print device then the name
+ used is that provided by the print device. Note that a print device may
+ not support the current default locale language.
+
+ If the QPageSize is invalid then the name will be an empty string.
+*/
+
+QString QPageSize::name() const
+{
+ return isValid() ? d->m_name : QString();
+}
+
+/*!
+ Returns the standard QPageSize::PageSizeId of the page, or QPageSize::Custom.
+
+ If the QPageSize is invalid then the ID will be QPageSize::Custom.
+*/
+
+QPageSize::PageSizeId QPageSize::id() const
+{
+ return isValid() ? d->m_id : QPageSize::Custom;
+}
+
+/*!
+ Returns the Windows DMPAPER enum value for the page size.
+
+ Not all valid PPD page sizes have a Windows equivalent, in which case 0
+ will be returned.
+
+ If the QPageSize is invalid then the Windows ID will be 0.
+
+ \sa id()
+*/
+
+int QPageSize::windowsId() const
+{
+ if (!isValid())
+ return 0;
+ return d->m_windowsId > 0 ? d->m_windowsId : QPageSize::windowsId(d->m_id);
+}
+
+/*!
+ Returns the definition size of the page size.
+
+ For a standard page size this will be the size as defined in the relevant
+ standard, i.e. ISO A4 will be defined in millimeters while ANSI Letter will
+ be defined in inches.
+
+ For a custom page size this will be the original size used to create the
+ page size object.
+
+ If the QPageSize is invalid then the QSizeF will be invalid.
+
+ \sa definitionUnits()
+*/
+
+QSizeF QPageSize::definitionSize() const
+{
+ return isValid() ? d->m_size : QSizeF();
+}
+
+/*!
+ Returns the definition units of the page size.
+
+ For a standard page size this will be the units as defined in the relevant
+ standard, i.e. ISO A4 will be defined in millimeters while ANSI Letter will
+ be defined in inches.
+
+ For a custom page size this will be the original units used to create the
+ page size object.
+
+ If the QPageSize is invalid then the QPageSize::Unit will be invalid.
+
+ \sa definitionSize()
+*/
+
+QPageSize::Unit QPageSize::definitionUnits() const
+{
+ return isValid() ? d->m_units : QPageSize::Unit(-1);
+}
+
+/*!
+ Returns the size of the page in the required \a units.
+
+ If the QPageSize is invalid then the QSizeF will be invalid.
+*/
+
+QSizeF QPageSize::size(QPageSize::Unit units) const
+{
+ return isValid() ? d->size(units) : QSize();
+}
+
+/*!
+ Returns the size of the page in Postscript Points (1/72 of an inch).
+
+ If the QPageSize is invalid then the QSize will be invalid.
+*/
+
+QSize QPageSize::sizePoints() const
+{
+ return isValid() ? d->m_pointSize : QSize();
+}
+
+/*!
+ Returns the size of the page in Device Pixels at the given \a resolution.
+
+ If the QPageSize is invalid then the QSize will be invalid.
+*/
+
+QSize QPageSize::sizePixels(int resolution) const
+{
+ return isValid() ? d->sizePixels(resolution) : QSize();
+}
+
+/*!
+ Returns the page rectangle in the required \a units.
+
+ If the QPageSize is invalid then the QRect will be invalid.
+*/
+
+QRectF QPageSize::rect(QPageSize::Unit units) const
+{
+ return isValid() ? QRectF(QPointF(0, 0), d->size(units)) : QRectF();
+}
+
+/*!
+ Returns the page rectangle in Postscript Points (1/72 of an inch).
+
+ If the QPageSize is invalid then the QRect will be invalid.
+*/
+
+QRect QPageSize::rectPoints() const
+{
+ return isValid() ? QRect(QPoint(0, 0), d->m_pointSize) : QRect();
+}
+
+/*!
+ Returns the page rectangle in Device Pixels at the given \a resolution.
+
+ If the QPageSize is invalid then the QRect will be invalid.
+*/
+
+QRect QPageSize::rectPixels(int resolution) const
+{
+ return isValid() ? QRect(QPoint(0, 0), d->sizePixels(resolution)) : QRect();
+}
+
+// Statics
+
+/*!
+ Returns the PPD mediaOption keyword of the standard \a pageSizeId.
+
+ If the QPageSize is invalid then the key will be empty.
+*/
+
+QString QPageSize::key(QPageSize::PageSizeId pageSizeId)
+{
+ if (pageSizeId < QPageSize::PageSizeId(0) || pageSizeId > QPageSize::LastPageSize)
+ return QString();
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ return QString::fromUtf8(qt_pageSizes[pageSizeId].mediaOption);
+}
+
+static QString msgImperialPageSizeInch(int width, int height)
+{
+ //: Page size in 'Inch'.
+ return QCoreApplication::translate("QPageSize", "%1 x %2 in").arg(width).arg(height);
+}
+
+/*!
+ Returns the localized name of the standard \a pageSizeId.
+
+ If the QPageSize is invalid then the name will be empty.
+*/
+
+QString QPageSize::name(QPageSize::PageSizeId pageSizeId)
+{
+ if (pageSizeId < QPageSize::PageSizeId(0) || pageSizeId > QPageSize::LastPageSize)
+ return QString();
+
+ switch (pageSizeId) {
+ case QPageSize::A0:
+ return QCoreApplication::translate("QPageSize", "A0");
+ case QPageSize::A1:
+ return QCoreApplication::translate("QPageSize", "A1");
+ case QPageSize::A2:
+ return QCoreApplication::translate("QPageSize", "A2");
+ case QPageSize::A3:
+ return QCoreApplication::translate("QPageSize", "A3");
+ case QPageSize::A4:
+ return QCoreApplication::translate("QPageSize", "A4");
+ case QPageSize::A5:
+ return QCoreApplication::translate("QPageSize", "A5");
+ case QPageSize::A6:
+ return QCoreApplication::translate("QPageSize", "A6");
+ case QPageSize::A7:
+ return QCoreApplication::translate("QPageSize", "A7");
+ case QPageSize::A8:
+ return QCoreApplication::translate("QPageSize", "A8");
+ case QPageSize::A9:
+ return QCoreApplication::translate("QPageSize", "A9");
+ case QPageSize::A10:
+ return QCoreApplication::translate("QPageSize", "A10");
+ case QPageSize::B0:
+ return QCoreApplication::translate("QPageSize", "B0");
+ case QPageSize::B1:
+ return QCoreApplication::translate("QPageSize", "B1");
+ case QPageSize::B2:
+ return QCoreApplication::translate("QPageSize", "B2");
+ case QPageSize::B3:
+ return QCoreApplication::translate("QPageSize", "B3");
+ case QPageSize::B4:
+ return QCoreApplication::translate("QPageSize", "B4");
+ case QPageSize::B5:
+ return QCoreApplication::translate("QPageSize", "B5");
+ case QPageSize::B6:
+ return QCoreApplication::translate("QPageSize", "B6");
+ case QPageSize::B7:
+ return QCoreApplication::translate("QPageSize", "B7");
+ case QPageSize::B8:
+ return QCoreApplication::translate("QPageSize", "B8");
+ case QPageSize::B9:
+ return QCoreApplication::translate("QPageSize", "B9");
+ case QPageSize::B10:
+ return QCoreApplication::translate("QPageSize", "B10");
+ case QPageSize::Executive:
+ return QCoreApplication::translate("QPageSize", "Executive (7.5 x 10 in)");
+ case QPageSize::ExecutiveStandard:
+ return QCoreApplication::translate("QPageSize", "Executive (7.25 x 10.5 in)");
+ case QPageSize::Folio:
+ return QCoreApplication::translate("QPageSize", "Folio (8.27 x 13 in)");
+ case QPageSize::Legal:
+ return QCoreApplication::translate("QPageSize", "Legal");
+ case QPageSize::Letter:
+ return QCoreApplication::translate("QPageSize", "Letter / ANSI A");
+ case QPageSize::Tabloid:
+ return QCoreApplication::translate("QPageSize", "Tabloid / ANSI B");
+ case QPageSize::Ledger:
+ return QCoreApplication::translate("QPageSize", "Ledger / ANSI B");
+ case QPageSize::Custom:
+ return QCoreApplication::translate("QPageSize", "Custom");
+ case QPageSize::A3Extra:
+ return QCoreApplication::translate("QPageSize", "A3 Extra");
+ case QPageSize::A4Extra:
+ return QCoreApplication::translate("QPageSize", "A4 Extra");
+ case QPageSize::A4Plus:
+ return QCoreApplication::translate("QPageSize", "A4 Plus");
+ case QPageSize::A4Small:
+ return QCoreApplication::translate("QPageSize", "A4 Small");
+ case QPageSize::A5Extra:
+ return QCoreApplication::translate("QPageSize", "A5 Extra");
+ case QPageSize::B5Extra:
+ return QCoreApplication::translate("QPageSize", "B5 Extra");
+ case QPageSize::JisB0:
+ return QCoreApplication::translate("QPageSize", "JIS B0");
+ case QPageSize::JisB1:
+ return QCoreApplication::translate("QPageSize", "JIS B1");
+ case QPageSize::JisB2:
+ return QCoreApplication::translate("QPageSize", "JIS B2");
+ case QPageSize::JisB3:
+ return QCoreApplication::translate("QPageSize", "JIS B3");
+ case QPageSize::JisB4:
+ return QCoreApplication::translate("QPageSize", "JIS B4");
+ case QPageSize::JisB5:
+ return QCoreApplication::translate("QPageSize", "JIS B5");
+ case QPageSize::JisB6:
+ return QCoreApplication::translate("QPageSize", "JIS B6");
+ case QPageSize::JisB7:
+ return QCoreApplication::translate("QPageSize", "JIS B7");
+ case QPageSize::JisB8:
+ return QCoreApplication::translate("QPageSize", "JIS B8");
+ case QPageSize::JisB9:
+ return QCoreApplication::translate("QPageSize", "JIS B9");
+ case QPageSize::JisB10:
+ return QCoreApplication::translate("QPageSize", "JIS B10");
+ case QPageSize::AnsiC:
+ return QCoreApplication::translate("QPageSize", "ANSI C");
+ case QPageSize::AnsiD:
+ return QCoreApplication::translate("QPageSize", "ANSI D");
+ case QPageSize::AnsiE:
+ return QCoreApplication::translate("QPageSize", "ANSI E");
+ case QPageSize::LegalExtra:
+ return QCoreApplication::translate("QPageSize", "Legal Extra");
+ case QPageSize::LetterExtra:
+ return QCoreApplication::translate("QPageSize", "Letter Extra");
+ case QPageSize::LetterPlus:
+ return QCoreApplication::translate("QPageSize", "Letter Plus");
+ case QPageSize::LetterSmall:
+ return QCoreApplication::translate("QPageSize", "Letter Small");
+ case QPageSize::TabloidExtra:
+ return QCoreApplication::translate("QPageSize", "Tabloid Extra");
+ case QPageSize::ArchA:
+ return QCoreApplication::translate("QPageSize", "Architect A");
+ case QPageSize::ArchB:
+ return QCoreApplication::translate("QPageSize", "Architect B");
+ case QPageSize::ArchC:
+ return QCoreApplication::translate("QPageSize", "Architect C");
+ case QPageSize::ArchD:
+ return QCoreApplication::translate("QPageSize", "Architect D");
+ case QPageSize::ArchE:
+ return QCoreApplication::translate("QPageSize", "Architect E");
+ case QPageSize::Imperial7x9:
+ return msgImperialPageSizeInch(7, 9);
+ case QPageSize::Imperial8x10:
+ return msgImperialPageSizeInch(8, 10);
+ case QPageSize::Imperial9x11:
+ return msgImperialPageSizeInch(9, 11);
+ case QPageSize::Imperial9x12:
+ return msgImperialPageSizeInch(9, 12);
+ case QPageSize::Imperial10x11:
+ return msgImperialPageSizeInch(10, 11);
+ case QPageSize::Imperial10x13:
+ return msgImperialPageSizeInch(10, 13);
+ case QPageSize::Imperial10x14:
+ return msgImperialPageSizeInch(10, 14);
+ case QPageSize::Imperial12x11:
+ return msgImperialPageSizeInch(12, 11);
+ case QPageSize::Imperial15x11:
+ return msgImperialPageSizeInch(15, 11);
+ case QPageSize::Note:
+ return QCoreApplication::translate("QPageSize", "Note");
+ case QPageSize::Quarto:
+ return QCoreApplication::translate("QPageSize", "Quarto");
+ case QPageSize::Statement:
+ return QCoreApplication::translate("QPageSize", "Statement");
+ case QPageSize::SuperA:
+ return QCoreApplication::translate("QPageSize", "Super A");
+ case QPageSize::SuperB:
+ return QCoreApplication::translate("QPageSize", "Super B");
+ case QPageSize::Postcard:
+ return QCoreApplication::translate("QPageSize", "Postcard");
+ case QPageSize::DoublePostcard:
+ return QCoreApplication::translate("QPageSize", "Double Postcard");
+ case QPageSize::Prc16K:
+ return QCoreApplication::translate("QPageSize", "PRC 16K");
+ case QPageSize::Prc32K:
+ return QCoreApplication::translate("QPageSize", "PRC 32K");
+ case QPageSize::Prc32KBig:
+ return QCoreApplication::translate("QPageSize", "PRC 32K Big");
+ case QPageSize::FanFoldUS:
+ return QCoreApplication::translate("QPageSize", "Fan-fold US (14.875 x 11 in)");
+ case QPageSize::FanFoldGerman:
+ return QCoreApplication::translate("QPageSize", "Fan-fold German (8.5 x 12 in)");
+ case QPageSize::FanFoldGermanLegal:
+ return QCoreApplication::translate("QPageSize", "Fan-fold German Legal (8.5 x 13 in)");
+ case QPageSize::EnvelopeB4:
+ return QCoreApplication::translate("QPageSize", "Envelope B4");
+ case QPageSize::EnvelopeB5:
+ return QCoreApplication::translate("QPageSize", "Envelope B5");
+ case QPageSize::EnvelopeB6:
+ return QCoreApplication::translate("QPageSize", "Envelope B6");
+ case QPageSize::EnvelopeC0:
+ return QCoreApplication::translate("QPageSize", "Envelope C0");
+ case QPageSize::EnvelopeC1:
+ return QCoreApplication::translate("QPageSize", "Envelope C1");
+ case QPageSize::EnvelopeC2:
+ return QCoreApplication::translate("QPageSize", "Envelope C2");
+ case QPageSize::EnvelopeC3:
+ return QCoreApplication::translate("QPageSize", "Envelope C3");
+ case QPageSize::EnvelopeC4:
+ return QCoreApplication::translate("QPageSize", "Envelope C4");
+ case QPageSize::EnvelopeC5: // C5E
+ return QCoreApplication::translate("QPageSize", "Envelope C5");
+ case QPageSize::EnvelopeC6:
+ return QCoreApplication::translate("QPageSize", "Envelope C6");
+ case QPageSize::EnvelopeC65:
+ return QCoreApplication::translate("QPageSize", "Envelope C65");
+ case QPageSize::EnvelopeC7:
+ return QCoreApplication::translate("QPageSize", "Envelope C7");
+ case QPageSize::EnvelopeDL: // DLE:
+ return QCoreApplication::translate("QPageSize", "Envelope DL");
+ case QPageSize::Envelope9:
+ return QCoreApplication::translate("QPageSize", "Envelope US 9");
+ case QPageSize::Envelope10: // Comm10E
+ return QCoreApplication::translate("QPageSize", "Envelope US 10");
+ case QPageSize::Envelope11:
+ return QCoreApplication::translate("QPageSize", "Envelope US 11");
+ case QPageSize::Envelope12:
+ return QCoreApplication::translate("QPageSize", "Envelope US 12");
+ case QPageSize::Envelope14:
+ return QCoreApplication::translate("QPageSize", "Envelope US 14");
+ case QPageSize::EnvelopeMonarch:
+ return QCoreApplication::translate("QPageSize", "Envelope Monarch");
+ case QPageSize::EnvelopePersonal:
+ return QCoreApplication::translate("QPageSize", "Envelope Personal");
+ case QPageSize::EnvelopeChou3:
+ return QCoreApplication::translate("QPageSize", "Envelope Chou 3");
+ case QPageSize::EnvelopeChou4:
+ return QCoreApplication::translate("QPageSize", "Envelope Chou 4");
+ case QPageSize::EnvelopeInvite:
+ return QCoreApplication::translate("QPageSize", "Envelope Invite");
+ case QPageSize::EnvelopeItalian:
+ return QCoreApplication::translate("QPageSize", "Envelope Italian");
+ case QPageSize::EnvelopeKaku2:
+ return QCoreApplication::translate("QPageSize", "Envelope Kaku 2");
+ case QPageSize::EnvelopeKaku3:
+ return QCoreApplication::translate("QPageSize", "Envelope Kaku 3");
+ case QPageSize::EnvelopePrc1:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 1");
+ case QPageSize::EnvelopePrc2:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 2");
+ case QPageSize::EnvelopePrc3:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 3");
+ case QPageSize::EnvelopePrc4:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 4");
+ case QPageSize::EnvelopePrc5:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 5");
+ case QPageSize::EnvelopePrc6:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 6");
+ case QPageSize::EnvelopePrc7:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 7");
+ case QPageSize::EnvelopePrc8:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 8");
+ case QPageSize::EnvelopePrc9:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 9");
+ case QPageSize::EnvelopePrc10:
+ return QCoreApplication::translate("QPageSize", "Envelope PRC 10");
+ case QPageSize::EnvelopeYou4:
+ return QCoreApplication::translate("QPageSize", "Envelope You 4");
+ }
+ return QString();
+}
+
+/*!
+ Returns the standard QPageSize::PageSizeId of the given \a pointSize in
+ points using the given \a matchPolicy.
+
+ If using FuzzyMatch then the point size of the PageSizeId returned may not
+ exactly match the \a pointSize you passed in. You should call
+ QPageSize::sizePoints() using the returned PageSizeId to find out the actual
+ point size of the PageSizeId before using it in any calculations.
+*/
+
+QPageSize::PageSizeId QPageSize::id(const QSize &pointSize, QPageSize::SizeMatchPolicy matchPolicy)
+{
+ return qt_idForPointSize(pointSize, matchPolicy, 0);
+}
+
+/*!
+ Returns the standard QPageSize::PageSizeId of the given \a size in \a units
+ using the given \a matchPolicy.
+
+ If using FuzzyMatch then the unit size of the PageSizeId returned may not
+ exactly match the \a size you passed in. You should call
+ QPageSize::size() using the returned PageSizeId to find out the actual
+ unit size of the PageSizeId before using it in any calculations.
+*/
+
+QPageSize::PageSizeId QPageSize::id(const QSizeF &size, QPageSize::Unit units,
+ QPageSize::SizeMatchPolicy matchPolicy)
+{
+ return qt_idForSize(size, units, matchPolicy, 0);
+}
+
+/*!
+ Returns the PageSizeId for the given Windows DMPAPER enum value \a windowsId.
+
+ If there is no matching PageSizeId then QPageSize::Custom is returned.
+*/
+
+QPageSize::PageSizeId QPageSize::id(int windowsId)
+{
+ return qt_idForWindowsID(windowsId);
+}
+
+/*!
+ Returns the Windows DMPAPER enum value of the standard \a pageSizeId.
+
+ Not all valid PPD page sizes have a Windows equivalent, in which case 0
+ will be returned.
+*/
+
+int QPageSize::windowsId(QPageSize::PageSizeId pageSizeId)
+{
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ return qt_pageSizes[pageSizeId].windowsId;
+}
+
+/*!
+ Returns the definition size of the standard \a pageSizeId.
+
+ To obtain the definition units, call QPageSize::definitionUnits().
+*/
+
+QSizeF QPageSize::definitionSize(QPageSize::PageSizeId pageSizeId)
+{
+ if (pageSizeId == QPageSize::Custom)
+ return QSizeF();
+ return qt_definitionSize(pageSizeId);
+}
+
+/*!
+ Returns the definition units of the standard \a pageSizeId.
+
+ To obtain the definition size, call QPageSize::definitionSize().
+*/
+
+QPageSize::Unit QPageSize::definitionUnits(QPageSize::PageSizeId pageSizeId)
+{
+ if (pageSizeId == QPageSize::Custom)
+ return QPageSize::Unit(-1);
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ return qt_pageSizes[pageSizeId].definitionUnits;
+}
+
+/*!
+ Returns the size of the standard \a pageSizeId in the requested \a units.
+*/
+
+QSizeF QPageSize::size(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units)
+{
+ if (pageSizeId == QPageSize::Custom)
+ return QSizeF();
+ return qt_unitSize(pageSizeId, units);
+}
+
+/*!
+ Returns the size of the standard \a pageSizeId in Points.
+*/
+
+QSize QPageSize::sizePoints(QPageSize::PageSizeId pageSizeId)
+{
+ if (pageSizeId == QPageSize::Custom)
+ return QSize();
+ Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ return QSize(qt_pageSizes[pageSizeId].widthPoints, qt_pageSizes[pageSizeId].heightPoints);
+}
+
+/*!
+ Returns the size of the standard \a pageSizeId in Device Pixels
+ for the given \a resolution.
+*/
+
+QSize QPageSize::sizePixels(QPageSize::PageSizeId pageSizeId, int resolution)
+{
+ if (pageSizeId == QPageSize::Custom)
+ return QSize();
+ return qt_convertPointsToPixels(QPageSize::sizePoints(pageSizeId), resolution);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QPageSize &pageSize)
+{
+ if (pageSize.isValid()) {
+ QString output = QStringLiteral("QPageSize(\"%1\", \"%2\", %3x%4pt, %5)");
+ output = output.arg(pageSize.name())
+ .arg(pageSize.key())
+ .arg(pageSize.sizePoints().width())
+ .arg(pageSize.sizePoints().height())
+ .arg(pageSize.id());
+ dbg.nospace() << output;
+ } else {
+ dbg.nospace() << QStringLiteral("QPageSize()");
+ }
+ return dbg.space();
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h
new file mode 100644
index 0000000000..c8a472747d
--- /dev/null
+++ b/src/gui/painting/qpagesize.h
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAGESIZE_H
+#define QPAGESIZE_H
+
+#include <QtCore/qsharedpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(B0)
+#undef B0 // Terminal hang-up. We assume that you do not want that.
+#endif
+
+class QPageSizePrivate;
+class QString;
+class QSize;
+class QSizeF;
+
+class Q_GUI_EXPORT QPageSize
+{
+public:
+
+ // ### Qt6 Re-order and remove duplicates
+ // NOTE: Must keep in sync with QPagedPrintEngine and QPrinter
+ enum PageSizeId {
+ // Existing Qt sizes
+ A4,
+ B5,
+ Letter,
+ Legal,
+ Executive,
+ A0,
+ A1,
+ A2,
+ A3,
+ A5,
+ A6,
+ A7,
+ A8,
+ A9,
+ B0,
+ B1,
+ B10,
+ B2,
+ B3,
+ B4,
+ B6,
+ B7,
+ B8,
+ B9,
+ C5E,
+ Comm10E,
+ DLE,
+ Folio,
+ Ledger,
+ Tabloid,
+ Custom,
+
+ // New values derived from PPD standard
+ A10,
+ A3Extra,
+ A4Extra,
+ A4Plus,
+ A4Small,
+ A5Extra,
+ B5Extra,
+
+ JisB0,
+ JisB1,
+ JisB2,
+ JisB3,
+ JisB4,
+ JisB5,
+ JisB6,
+ JisB7,
+ JisB8,
+ JisB9,
+ JisB10,
+
+ // AnsiA = Letter,
+ // AnsiB = Ledger,
+ AnsiC,
+ AnsiD,
+ AnsiE,
+ LegalExtra,
+ LetterExtra,
+ LetterPlus,
+ LetterSmall,
+ TabloidExtra,
+
+ ArchA,
+ ArchB,
+ ArchC,
+ ArchD,
+ ArchE,
+
+ Imperial7x9,
+ Imperial8x10,
+ Imperial9x11,
+ Imperial9x12,
+ Imperial10x11,
+ Imperial10x13,
+ Imperial10x14,
+ Imperial12x11,
+ Imperial15x11,
+
+ ExecutiveStandard,
+ Note,
+ Quarto,
+ Statement,
+ SuperA,
+ SuperB,
+ Postcard,
+ DoublePostcard,
+ Prc16K,
+ Prc32K,
+ Prc32KBig,
+
+ FanFoldUS,
+ FanFoldGerman,
+ FanFoldGermanLegal,
+
+ EnvelopeB4,
+ EnvelopeB5,
+ EnvelopeB6,
+ EnvelopeC0,
+ EnvelopeC1,
+ EnvelopeC2,
+ EnvelopeC3,
+ EnvelopeC4,
+ // EnvelopeC5 = C5E,
+ EnvelopeC6,
+ EnvelopeC65,
+ EnvelopeC7,
+ // EnvelopeDL = DLE,
+
+ Envelope9,
+ // Envelope10 = Comm10E,
+ Envelope11,
+ Envelope12,
+ Envelope14,
+ EnvelopeMonarch,
+ EnvelopePersonal,
+
+ EnvelopeChou3,
+ EnvelopeChou4,
+ EnvelopeInvite,
+ EnvelopeItalian,
+ EnvelopeKaku2,
+ EnvelopeKaku3,
+ EnvelopePrc1,
+ EnvelopePrc2,
+ EnvelopePrc3,
+ EnvelopePrc4,
+ EnvelopePrc5,
+ EnvelopePrc6,
+ EnvelopePrc7,
+ EnvelopePrc8,
+ EnvelopePrc9,
+ EnvelopePrc10,
+ EnvelopeYou4,
+
+ // Last item, with commonly used synynoms from QPagedPrintEngine / QPrinter
+ LastPageSize = EnvelopeYou4,
+ NPageSize = LastPageSize,
+ NPaperSize = LastPageSize,
+
+ // Convenience overloads for naming consistency
+ AnsiA = Letter,
+ AnsiB = Ledger,
+ EnvelopeC5 = C5E,
+ EnvelopeDL = DLE,
+ Envelope10 = Comm10E
+ };
+
+ // NOTE: Must keep in sync with QPageLayout::Unit and QPrinter::Unit
+ enum Unit {
+ Millimeter,
+ Point,
+ Inch,
+ Pica,
+ Didot,
+ Cicero
+ };
+
+ enum SizeMatchPolicy {
+ FuzzyMatch,
+ FuzzyOrientationMatch,
+ ExactMatch
+ };
+
+ QPageSize();
+ explicit QPageSize(QPageSize::PageSizeId pageSizeId);
+ QPageSize(const QSize &pointSize,
+ const QString &name = QString(),
+ QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch);
+ QPageSize(const QSizeF &size, QPageSize::Unit units,
+ const QString &name = QString(),
+ QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch);
+ QPageSize(const QPageSize &other);
+ ~QPageSize();
+
+ QPageSize &operator=(const QPageSize &other);
+#ifdef Q_COMPILER_RVALUE_REFS
+ QPageSize &operator=(QPageSize &&other) { swap(other); return *this; }
+#endif
+
+ void swap(QPageSize &other) { d.swap(other.d); }
+
+ bool operator==(const QPageSize &other) const;
+ bool isEquivalentTo(const QPageSize &other) const;
+
+ bool isValid() const;
+
+ QString key() const;
+ QString name() const;
+
+ QPageSize::PageSizeId id() const;
+
+ int windowsId() const;
+
+ QSizeF definitionSize() const;
+ QPageSize::Unit definitionUnits() const;
+
+ QSizeF size(QPageSize::Unit units) const;
+ QSize sizePoints() const;
+ QSize sizePixels(int resolution) const;
+
+ QRectF rect(QPageSize::Unit units) const;
+ QRect rectPoints() const;
+ QRect rectPixels(int resolution) const;
+
+ static QString key(QPageSize::PageSizeId pageSizeId);
+ static QString name(QPageSize::PageSizeId pageSizeId);
+
+ static QPageSize::PageSizeId id(const QSize &pointSize,
+ QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch);
+ static QPageSize::PageSizeId id(const QSizeF &size, QPageSize::Unit units,
+ QPageSize::SizeMatchPolicy matchPolicy = QPageSize::FuzzyMatch);
+
+ static QPageSize::PageSizeId id(int windowsId);
+ static int windowsId(QPageSize::PageSizeId pageSizeId);
+
+ static QSizeF definitionSize(QPageSize::PageSizeId pageSizeId);
+ static QPageSize::Unit definitionUnits(QPageSize::PageSizeId pageSizeId);
+
+ static QSizeF size(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units);
+ static QSize sizePoints(QPageSize::PageSizeId pageSizeId);
+ static QSize sizePixels(QPageSize::PageSizeId pageSizeId, int resolution);
+
+private:
+ friend class QPageSizePrivate;
+ friend class QPlatformPrintDevice;
+ QPageSize(const QString &key, const QSize &pointSize, const QString &name);
+ QPageSize(int windowsId, const QSize &pointSize, const QString &name);
+ QPageSize(QPageSizePrivate &dd);
+ QSharedDataPointer<QPageSizePrivate> d;
+};
+
+Q_DECLARE_SHARED(QPageSize)
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageSize &pageSize);
+#endif
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(QPageSize)
+Q_DECLARE_METATYPE(QPageSize::PageSizeId)
+Q_DECLARE_METATYPE(QPageSize::Unit)
+
+#endif // QPAGESIZE_H
diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp
index e356a3a36a..26eacacd49 100644
--- a/src/gui/painting/qpaintengine_blitter.cpp
+++ b/src/gui/painting/qpaintengine_blitter.cpp
@@ -494,11 +494,12 @@ void QBlitterPaintEngine::clipEnabledChanged()
bool QBlitterPaintEngine::begin(QPaintDevice *pdev)
{
+ Q_D(QBlitterPaintEngine);
bool ok = QRasterPaintEngine::begin(pdev);
#ifdef QT_BLITTER_RASTEROVERLAY
- Q_D(QBlitterPaintEngine);
d->pmData->unmergeOverlay();
#endif
+ d->pdev = pdev;
return ok;
}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index e35cdd370e..fe5fc051df 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -3828,7 +3828,7 @@ Qt::BGMode QPainter::backgroundMode() const
/*!
\overload
- Sets the painter's pen to have style Qt::SolidLine, width 0 and the
+ Sets the painter's pen to have style Qt::SolidLine, width 1 and the
specified \a color.
*/
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 147fa3f561..56cfc0f707 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1425,19 +1425,60 @@ QPaintEngine::Type QPdfEngine::type() const
return QPaintEngine::Pdf;
}
+void QPdfEngine::setResolution(int resolution)
+{
+ Q_D(QPdfEngine);
+ d->resolution = resolution;
+}
+
+int QPdfEngine::resolution() const
+{
+ Q_D(const QPdfEngine);
+ return d->resolution;
+}
+
+void QPdfEngine::setPageLayout(const QPageLayout &pageLayout)
+{
+ Q_D(QPdfEngine);
+ d->m_pageLayout = pageLayout;
+}
+void QPdfEngine::setPageSize(const QPageSize &pageSize)
+{
+ Q_D(QPdfEngine);
+ d->m_pageLayout.setPageSize(pageSize);
+}
+
+void QPdfEngine::setPageOrientation(QPageLayout::Orientation orientation)
+{
+ Q_D(QPdfEngine);
+ d->m_pageLayout.setOrientation(orientation);
+}
+
+void QPdfEngine::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
+{
+ Q_D(QPdfEngine);
+ d->m_pageLayout.setUnits(units);
+ d->m_pageLayout.setMargins(margins);
+}
+QPageLayout QPdfEngine::pageLayout() const
+{
+ Q_D(const QPdfEngine);
+ return d->m_pageLayout;
+}
+
+// Metrics are in Device Pixels
int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
{
Q_D(const QPdfEngine);
int val;
- QRect r = d->pageRect();
switch (metricType) {
case QPaintDevice::PdmWidth:
- val = r.width();
+ val = d->m_pageLayout.paintRectPixels(d->resolution).width();
break;
case QPaintDevice::PdmHeight:
- val = r.height();
+ val = d->m_pageLayout.paintRectPixels(d->resolution).height();
break;
case QPaintDevice::PdmDpiX:
case QPaintDevice::PdmDpiY:
@@ -1448,10 +1489,10 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
val = 1200;
break;
case QPaintDevice::PdmWidthMM:
- val = qRound(r.width()*25.4/d->resolution);
+ val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).width());
break;
case QPaintDevice::PdmHeightMM:
- val = qRound(r.height()*25.4/d->resolution);
+ val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).height());
break;
case QPaintDevice::PdmNumColors:
val = INT_MAX;
@@ -1469,21 +1510,12 @@ int QPdfEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const
return val;
}
-static inline QSizeF pageSizeToPostScriptPoints(const QSizeF &pageSizeMM)
-{
-#define Q_MM(n) int((n * 720 + 127) / 254)
- return QSizeF(Q_MM(pageSizeMM.width()), Q_MM(pageSizeMM.height()));
-#undef Q_MM
-}
-
QPdfEnginePrivate::QPdfEnginePrivate()
: clipEnabled(false), allClipped(false), hasPen(true), hasBrush(false), simplePen(false),
outDevice(0), ownsDevice(false),
- fullPage(false), embedFonts(true),
- landscape(false),
+ embedFonts(true),
grayscale(false),
- paperSize(pageSizeToPostScriptPoints(QSizeF(210, 297))), // A4
- leftMargin(10), topMargin(10), rightMargin(10), bottomMargin(10) // ~3.5 mm
+ m_pageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(10, 10, 10, 10))
{
resolution = 1200;
currentObject = 1;
@@ -1495,11 +1527,6 @@ QPdfEnginePrivate::QPdfEnginePrivate()
stream = new QDataStream;
}
-void QPdfEnginePrivate::setPaperSize(const QSizeF &pageSizeMM)
-{
- paperSize = pageSizeToPostScriptPoints(pageSizeMM);
-}
-
bool QPdfEngine::begin(QPaintDevice *pdev)
{
Q_D(QPdfEngine);
@@ -1581,31 +1608,6 @@ QPdfEnginePrivate::~QPdfEnginePrivate()
delete stream;
}
-QRect QPdfEnginePrivate::paperRect() const
-{
- int w = qRound(paperSize.width()*resolution/72.);
- int h = qRound(paperSize.height()*resolution/72.);
-
- if (!landscape)
- return QRect(0, 0, w, h);
- else
- return QRect(0, 0, h, w);
-}
-
-QRect QPdfEnginePrivate::pageRect() const
-{
- QRect r = paperRect();
-
- if(!fullPage)
- r.adjust(qRound(leftMargin*(resolution/72.)),
- qRound(topMargin*(resolution/72.)),
- -qRound(rightMargin*(resolution/72.)),
- -qRound(bottomMargin*(resolution/72.)));
-
- return r;
-}
-
-
void QPdfEnginePrivate::writeHeader()
{
addXrefEntry(0,false);
@@ -2615,9 +2617,9 @@ void QPdfEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti)
QTransform QPdfEnginePrivate::pageMatrix() const
{
qreal scale = 72./resolution;
- QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, height());
- if (!fullPage) {
- QRect r = pageRect();
+ QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, m_pageLayout.fullRectPoints().height());
+ if (m_pageLayout.mode() != QPageLayout::FullPageMode) {
+ QRect r = m_pageLayout.paintRectPixels(resolution);
tmp.translate(r.left(), r.top());
}
return tmp;
@@ -2626,12 +2628,12 @@ QTransform QPdfEnginePrivate::pageMatrix() const
void QPdfEnginePrivate::newPage()
{
if (currentPage && currentPage->pageSize.isEmpty())
- currentPage->pageSize = QSize(width(), height());
+ currentPage->pageSize = m_pageLayout.fullRectPoints().size();
writePage();
delete currentPage;
currentPage = new QPdfPage;
- currentPage->pageSize = QSize(width(), height());
+ currentPage->pageSize = m_pageLayout.fullRectPoints().size();
stroker.stream = currentPage;
pages.append(requestObject());
diff --git a/src/gui/painting/qpdf_p.h b/src/gui/painting/qpdf_p.h
index ae2d4b00ac..e9459eff83 100644
--- a/src/gui/painting/qpdf_p.h
+++ b/src/gui/painting/qpdf_p.h
@@ -64,6 +64,7 @@
#include "private/qpaintengine_p.h"
#include "private/qfontengine_p.h"
#include "private/qfontsubset_p.h"
+#include "qpagelayout.h"
// #define USE_NATIVE_GRADIENTS
@@ -179,7 +180,9 @@ public:
~QPdfEngine() {}
void setOutputFilename(const QString &filename);
- inline void setResolution(int resolution);
+
+ void setResolution(int resolution);
+ int resolution() const;
// reimplementations QPaintEngine
bool begin(QPaintDevice *pdev);
@@ -207,6 +210,14 @@ public:
// Printer stuff...
bool newPage();
+ // Page layout stuff
+ void setPageLayout(const QPageLayout &pageLayout);
+ void setPageSize(const QPageSize &pageSize);
+ void setPageOrientation(QPageLayout::Orientation orientation);
+ void setPageMargins(const QMarginsF &margins, QPageLayout::Unit units = QPageLayout::Point);
+
+ QPageLayout pageLayout() const;
+
void setPen();
void setBrush();
void setupGraphicsState(QPaintEngine::DirtyFlags flags);
@@ -224,19 +235,6 @@ public:
inline uint requestObject() { return currentObject++; }
- QRect paperRect() const;
- QRect pageRect() const;
- void setPaperSize(const QSizeF &pageSizeMM);
-
- int width() const {
- QRect r = paperRect();
- return qRound(r.width()*72./resolution);
- }
- int height() const {
- QRect r = paperRect();
- return qRound(r.height()*72./resolution);
- }
-
void writeHeader();
void writeTail();
@@ -278,15 +276,12 @@ public:
QString outputFileName;
QString title;
QString creator;
- bool fullPage;
bool embedFonts;
int resolution;
- bool landscape;
bool grayscale;
- // in postscript points
- QSizeF paperSize;
- qreal leftMargin, topMargin, rightMargin, bottomMargin;
+ // Page layout: size, orientation and margins
+ QPageLayout m_pageLayout;
private:
#ifdef USE_NATIVE_GRADIENTS
@@ -325,12 +320,6 @@ private:
QHash<QPair<uint, uint>, uint > alphaCache;
};
-void QPdfEngine::setResolution(int resolution)
-{
- Q_D(QPdfEngine);
- d->resolution = resolution;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_PDF
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index 27fb8b1646..08c8f42fd9 100644
--- a/src/gui/painting/qpdfwriter.cpp
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -90,6 +90,9 @@ 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();
}
/*!
@@ -101,6 +104,9 @@ 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();
}
/*!
@@ -147,7 +153,6 @@ void QPdfWriter::setCreator(const QString &creator)
d->engine->d_func()->creator = creator;
}
-
/*!
\reimp
*/
@@ -159,25 +164,213 @@ QPaintEngine *QPdfWriter::paintEngine() const
}
/*!
- \reimp
- */
-void QPdfWriter::setPageSize(PageSize size)
+ \since 5.3
+
+ Sets the PDF \a resolution in DPI.
+
+ This setting affects the coordinate system as returned by, for
+ example QPainter::viewport().
+
+ \sa resolution()
+*/
+
+void QPdfWriter::setResolution(int resolution)
{
Q_D(const QPdfWriter);
+ if (resolution > 0)
+ d->engine->setResolution(resolution);
+}
+
+/*!
+ \since 5.3
- QPagedPaintDevice::setPageSize(size);
- d->engine->d_func()->setPaperSize(pageSizeMM());
+ Returns the resolution of the PDF in DPI.
+
+ \sa setResolution()
+*/
+
+int QPdfWriter::resolution() const
+{
+ Q_D(const QPdfWriter);
+ return d->engine->resolution();
}
/*!
- \reimp
- */
-void QPdfWriter::setPageSizeMM(const QSizeF &size)
+ \since 5.3
+
+ Sets the PDF page layout to \a newPageLayout.
+
+ You should call this before calling QPainter::begin(), or immediately
+ before calling newPage() to apply the new page layout to a new page.
+ You should not call any painting methods between a call to setPageLayout()
+ and newPage() as the wrong paint metrics may be used.
+
+ Returns true if the page layout was successfully set to \a newPageLayout.
+
+ \sa pageLayout()
+*/
+
+bool QPdfWriter::setPageLayout(const QPageLayout &newPageLayout)
{
Q_D(const QPdfWriter);
+ // Try to set the paint engine page layout
+ d->engine->setPageLayout(newPageLayout);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ devicePageLayout() = d->engine->pageLayout();
+ return pageLayout().isEquivalentTo(newPageLayout);
+}
+
+/*!
+ \since 5.3
+
+ Sets the PDF page size to \a pageSize.
+
+ To get the current QPageSize use pageLayout().pageSize().
+
+ You should call this before calling QPainter::begin(), or immediately
+ before calling newPage() to apply the new page size to a new page.
+ You should not call any painting methods between a call to setPageSize()
+ and newPage() as the wrong paint metrics may be used.
+
+ Returns true if the page size was successfully set to \a pageSize.
- QPagedPaintDevice::setPageSizeMM(size);
- d->engine->d_func()->setPaperSize(pageSizeMM());
+ \sa pageLayout()
+*/
+
+bool QPdfWriter::setPageSize(const QPageSize &pageSize)
+{
+ Q_D(const QPdfWriter);
+ // Try to set the paint engine page size
+ d->engine->setPageSize(pageSize);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ devicePageLayout() = d->engine->pageLayout();
+ return pageLayout().pageSize().isEquivalentTo(pageSize);
+}
+
+/*!
+ \since 5.3
+
+ Sets the PDF page \a orientation.
+
+ The page orientation is used to define the orientation of the
+ page size when obtaining the page rect.
+
+ You should call this before calling QPainter::begin(), or immediately
+ before calling newPage() to apply the new orientation to a new page.
+ You should not call any painting methods between a call to setPageOrientation()
+ and newPage() as the wrong paint metrics may be used.
+
+ To get the current QPageLayout::Orientation use pageLayout().pageOrientation().
+
+ Returns true if the page orientation was successfully set to \a orientation.
+
+ \sa pageLayout()
+*/
+
+bool QPdfWriter::setPageOrientation(QPageLayout::Orientation orientation)
+{
+ Q_D(const QPdfWriter);
+ // Set the print engine value
+ d->engine->setPageOrientation(orientation);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ devicePageLayout() = d->engine->pageLayout();
+ return pageLayout().orientation() == orientation;
+}
+
+/*!
+ \since 5.3
+
+ Set the PDF page \a margins in the current page layout units.
+
+ You should call this before calling QPainter::begin(), or immediately
+ before calling newPage() to apply the new margins to a new page.
+ You should not call any painting methods between a call to setPageMargins()
+ and newPage() as the wrong paint metrics may be used.
+
+ To get the current page margins use pageLayout().pageMargins().
+
+ Returns true if the page margins were successfully set to \a margins.
+
+ \sa pageLayout()
+*/
+
+bool QPdfWriter::setPageMargins(const QMarginsF &margins)
+{
+ Q_D(const QPdfWriter);
+ // Try to set engine margins
+ d->engine->setPageMargins(margins, pageLayout().units());
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ devicePageLayout() = d->engine->pageLayout();
+ return pageLayout().margins() == margins;
+}
+
+/*!
+ \since 5.3
+
+ Set the PDF page \a margins defined in the given \a units.
+
+ You should call this before calling QPainter::begin(), or immediately
+ before calling newPage() to apply the new margins to a new page.
+ You should not call any painting methods between a call to setPageMargins()
+ and newPage() as the wrong paint metrics may be used.
+
+ To get the current page margins use pageLayout().pageMargins().
+
+ Returns true if the page margins were successfully set to \a margins.
+
+ \sa pageLayout()
+*/
+
+bool QPdfWriter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
+{
+ Q_D(const QPdfWriter);
+ // Try to set engine margins
+ d->engine->setPageMargins(margins, units);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ devicePageLayout() = d->engine->pageLayout();
+ return pageLayout().margins() == margins && pageLayout().units() == units;
+}
+
+/*!
+ Returns the current page layout. Use this method to access the current
+ QPageSize, QPageLayout::Orientation, QMarginsF, fullRect() and paintRect().
+
+ Note that you cannot use the setters on the returned object, you must either
+ call the individual QPdfWriter methods or use setPageLayout().
+
+ \sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins()
+*/
+
+QPageLayout QPdfWriter::pageLayout() const
+{
+ Q_D(const QPdfWriter);
+ return d->engine->pageLayout();
+}
+
+/*!
+ \reimp
+
+ \obsolete Use setPageSize(QPageSize(id)) instead
+
+ \sa setPageSize()
+*/
+
+void QPdfWriter::setPageSize(PageSize size)
+{
+ setPageSize(QPageSize(QPageSize::PageSizeId(size)));
+}
+
+/*!
+ \reimp
+
+ \obsolete Use setPageSize(QPageSize(size, QPageSize::Millimeter)) instead
+
+ \sa setPageSize()
+*/
+
+void QPdfWriter::setPageSizeMM(const QSizeF &size)
+{
+ setPageSize(QPageSize(size, QPageSize::Millimeter));
}
/*!
@@ -203,19 +396,15 @@ bool QPdfWriter::newPage()
/*!
- \reimp
+ \reimp
+
+ \obsolete Use setPageMargins(QMarginsF(l, t, r, b), QPageLayout::Millimeter) instead
+
+ \sa setPageMargins()
*/
void QPdfWriter::setMargins(const Margins &m)
{
- Q_D(QPdfWriter);
-
- QPagedPaintDevice::setMargins(m);
-
- const qreal multiplier = 72./25.4;
- d->engine->d_func()->leftMargin = m.left*multiplier;
- d->engine->d_func()->rightMargin = m.right*multiplier;
- d->engine->d_func()->topMargin = m.top*multiplier;
- d->engine->d_func()->bottomMargin = m.bottom*multiplier;
+ setPageMargins(QMarginsF(m.left, m.top, m.right, m.bottom), QPageLayout::Millimeter);
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h
index f5c25de5e9..fce0b88ea8 100644
--- a/src/gui/painting/qpdfwriter.h
+++ b/src/gui/painting/qpdfwriter.h
@@ -48,6 +48,7 @@
#include <QtCore/qobject.h>
#include <QtGui/qpagedpaintdevice.h>
+#include <QtGui/qpagelayout.h>
QT_BEGIN_NAMESPACE
@@ -70,6 +71,17 @@ public:
bool newPage();
+ void setResolution(int resolution);
+ int resolution() const;
+
+ bool setPageLayout(const QPageLayout &pageLayout);
+ bool setPageSize(const QPageSize &pageSize);
+ bool setPageOrientation(QPageLayout::Orientation orientation);
+ bool setPageMargins(const QMarginsF &margins);
+ bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units);
+
+ QPageLayout pageLayout() const;
+
void setPageSize(PageSize size);
void setPageSizeMM(const QSizeF &size);
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index 4843e93858..710d84e3aa 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -186,6 +186,28 @@ void QPlatformTextureList::clear()
*/
#ifndef QT_NO_OPENGL
+
+static QRect deviceRect(const QRect &rect, QWindow *window)
+{
+ QRect deviceRect(rect.topLeft() * window->devicePixelRatio(),
+ rect.size() * window->devicePixelRatio());
+ return deviceRect;
+}
+
+static QRegion deviceRegion(const QRegion &region, QWindow *window)
+{
+ if (!(window->devicePixelRatio() > 1))
+ return region;
+
+ QVector<QRect> rects;
+ foreach (QRect rect, region.rects())
+ rects.append(deviceRect(rect, window));
+
+ QRegion deviceRegion;
+ deviceRegion.setRects(rects.constData(), rects.count());
+ return deviceRegion;
+}
+
/*!
Flushes the given \a region from the specified \a window onto the
screen, and composes it with the specified \a textures.
@@ -205,7 +227,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
context->makeCurrent(window);
QOpenGLFunctions *funcs = context->functions();
- funcs->glViewport(0, 0, window->width(), window->height());
+ funcs->glViewport(0, 0, window->width() * window->devicePixelRatio(), window->height() * window->devicePixelRatio());
if (!d_ptr->blitter) {
d_ptr->blitter = new QOpenGLTextureBlitter;
@@ -214,16 +236,18 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->bind();
- QRect windowRect(QPoint(), window->size());
+ QRect windowRect(QPoint(), window->size() * window->devicePixelRatio());
+
for (int i = 0; i < textures->count(); ++i) {
GLuint textureId = textures->textureId(i);
funcs->glBindTexture(GL_TEXTURE_2D, textureId);
- QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), windowRect);
+ QRect targetRect = deviceRect(textures->geometry(i), window);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect);
d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
}
- GLuint textureId = toTexture(region);
+ GLuint textureId = toTexture(deviceRegion(region, window));
if (!textureId)
return;
@@ -306,6 +330,13 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QRect imageRect = image.rect();
QRect rect = dirtyRegion.boundingRect() & imageRect;
+
+#ifndef QT_OPENGL_ES_2
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, image.width());
+ funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ image.constScanLine(rect.y()) + rect.x() * 4);
+ funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+#else
// if the rect is wide enough it's cheaper to just
// extend it instead of doing an image copy
if (rect.width() >= imageRect.width() / 2) {
@@ -323,6 +354,7 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const
funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
image.copy(rect).constBits());
}
+#endif
}
return d_ptr->textureId;
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index beeac6bd43..20c62fdd9d 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -1713,7 +1713,7 @@ QT_END_INCLUDE_NAMESPACE
* the buffers together
*/
typedef struct _POINTBLOCK {
- int data[NUMPTSTOBUFFER * sizeof(QPoint)];
+ char data[NUMPTSTOBUFFER * sizeof(QPoint)];
QPoint *pts;
struct _POINTBLOCK *next;
} POINTBLOCK;
diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h
index b087a2384a..123a53c5cc 100644
--- a/src/gui/text/qcssparser_p.h
+++ b/src/gui/text/qcssparser_p.h
@@ -508,7 +508,7 @@ const quint64 PseudoClass_EditFocus = Q_UINT64_C(0x0000080000000000);
const quint64 PseudoClass_Alternate = Q_UINT64_C(0x0000100000000000);
// The Any specifier is never generated, but can be used as a wildcard in searches.
const quint64 PseudoClass_Any = Q_UINT64_C(0x0000ffffffffffff);
-const int NumPseudos = 46;
+const int NumPseudos = 45;
struct Pseudo
{
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 02b9e6d25c..ae7b6c1c0d 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -317,6 +317,7 @@ struct QtFontFamily
QtFontFamily(const QString &n)
:
+ populated(false),
fixedPitch(false),
name(n), count(0), foundries(0)
, bogusWritingSystems(false)
@@ -330,6 +331,7 @@ struct QtFontFamily
free(foundries);
}
+ bool populated : 1;
bool fixedPitch : 1;
QString name;
@@ -344,6 +346,8 @@ struct QtFontFamily
bool matchesFamilyName(const QString &familyName) const;
QtFontFoundry *foundry(const QString &f, bool = false);
+
+ void ensurePopulated();
};
QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create)
@@ -375,6 +379,14 @@ bool QtFontFamily::matchesFamilyName(const QString &familyName) const
return name.compare(familyName, Qt::CaseInsensitive) == 0 || aliases.contains(familyName, Qt::CaseInsensitive);
}
+void QtFontFamily::ensurePopulated()
+{
+ if (populated)
+ return;
+
+ QGuiApplicationPrivate::platformIntegration()->fontDatabase()->populateFamily(name);
+ Q_ASSERT(populated);
+}
class QFontDatabasePrivate
{
@@ -386,7 +398,14 @@ public:
~QFontDatabasePrivate() {
free();
}
- QtFontFamily *family(const QString &f, bool = false);
+
+ enum FamilyRequestFlags {
+ RequestFamily = 0,
+ EnsureCreated,
+ EnsurePopulated
+ };
+
+ QtFontFamily *family(const QString &f, FamilyRequestFlags flags = EnsurePopulated);
void free() {
while (count--)
delete families[count];
@@ -424,8 +443,10 @@ void QFontDatabasePrivate::invalidate()
emit static_cast<QGuiApplication *>(QCoreApplication::instance())->fontDatabaseChanged();
}
-QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
+QtFontFamily *QFontDatabasePrivate::family(const QString &f, FamilyRequestFlags flags)
{
+ QtFontFamily *fam = 0;
+
int low = 0;
int high = count;
int pos = count / 2;
@@ -439,28 +460,34 @@ QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create)
pos = (high + low) / 2;
}
if (!res)
- return families[pos];
+ fam = families[pos];
}
- if (!create)
- return 0;
- if (res < 0)
- pos++;
+ if (!fam && (flags & EnsureCreated)) {
+ if (res < 0)
+ pos++;
+
+ // qDebug() << "adding family " << f.toLatin1() << " at " << pos << " total=" << count;
+ if (!(count % 8)) {
+ QtFontFamily **newFamilies = (QtFontFamily **)
+ realloc(families,
+ (((count+8) >> 3) << 3) * sizeof(QtFontFamily *));
+ Q_CHECK_PTR(newFamilies);
+ families = newFamilies;
+ }
+
+ QtFontFamily *family = new QtFontFamily(f);
+ memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *));
+ families[pos] = family;
+ count++;
- // qDebug() << "adding family " << f.toLatin1() << " at " << pos << " total=" << count;
- if (!(count % 8)) {
- QtFontFamily **newFamilies = (QtFontFamily **)
- realloc(families,
- (((count+8) >> 3) << 3) * sizeof(QtFontFamily *));
- Q_CHECK_PTR(newFamilies);
- families = newFamilies;
+ fam = families[pos];
}
- QtFontFamily *family = new QtFontFamily(f);
- memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *));
- families[pos] = family;
- count++;
- return families[pos];
+ if (fam && (flags & EnsurePopulated))
+ fam->ensurePopulated();
+
+ return fam;
}
@@ -670,7 +697,7 @@ void qt_registerFont(const QString &familyName, const QString &stylename,
styleKey.style = style;
styleKey.weight = weight;
styleKey.stretch = stretch;
- QtFontFamily *f = d->family(familyName, true);
+ QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::EnsureCreated);
f->fixedPitch = fixedPitch;
for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
@@ -689,6 +716,13 @@ void qt_registerFont(const QString &familyName, const QString &stylename,
integration->fontDatabase()->releaseHandle(size->handle);
}
size->handle = handle;
+ f->populated = true;
+}
+
+void qt_registerFontFamily(const QString &familyName)
+{
+ // Create uninitialized/unpopulated family
+ privateDb()->family(familyName, QFontDatabasePrivate::EnsureCreated);
}
void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias)
@@ -697,7 +731,7 @@ void qt_registerAliasToFontFamily(const QString &familyName, const QString &alia
return;
QFontDatabasePrivate *d = privateDb();
- QtFontFamily *f = d->family(familyName, false);
+ QtFontFamily *f = d->family(familyName, QFontDatabasePrivate::RequestFamily);
if (!f)
return;
@@ -1092,6 +1126,8 @@ static int match(int script, const QFontDef &request,
if (!matchFamilyName(family_name, test.family))
continue;
+ test.family->ensurePopulated();
+
if (family_name.isEmpty())
load(test.family->name, script);
@@ -1304,6 +1340,8 @@ QList<QFontDatabase::WritingSystem> QFontDatabase::writingSystems() const
QList<WritingSystem> list;
for (int i = 0; i < d->count; ++i) {
QtFontFamily *family = d->families[i];
+ family->ensurePopulated();
+
if (family->count == 0)
continue;
for (int x = Latin; x < WritingSystemsCount; ++x) {
@@ -1367,11 +1405,14 @@ QStringList QFontDatabase::families(WritingSystem writingSystem) const
QStringList flist;
for (int i = 0; i < d->count; i++) {
QtFontFamily *f = d->families[i];
- if (f->count == 0)
+ if (f->populated && f->count == 0)
continue;
- if (writingSystem != Any && (f->writingSystems[writingSystem] != QtFontFamily::Supported))
- continue;
- if (f->count == 1) {
+ if (writingSystem != Any) {
+ f->ensurePopulated();
+ if (f->writingSystems[writingSystem] != QtFontFamily::Supported)
+ continue;
+ }
+ if (!f->populated || f->count == 1) {
flist.append(f->name);
} else {
for (int j = 0; j < f->count; j++) {
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index 11e9ce6c02..fe38755ffd 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -1934,8 +1934,6 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
lockFace();
QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, antialias ? Format_A8 : Format_Mono));
- if (cacheEnabled)
- glyph.take();
if (!glyph || !glyph->data) {
unlockFace();
return QFontEngine::alphaMapForGlyph(g);
@@ -1960,6 +1958,8 @@ QImage QFontEngineFT::alphaMapForGlyph(glyph_t g, QFixed subPixelPosition)
for (int y = 0; y < glyph->height; ++y)
memcpy(img.scanLine(y), &glyph->data[y * pitch], pitch);
}
+ if (cacheEnabled)
+ glyph.take();
unlockFace();
return img;
@@ -1973,8 +1973,6 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co
lockFace();
QScopedPointer<Glyph> glyph(loadGlyphFor(g, subPixelPosition, Format_A32));
- if (cacheEnabled)
- glyph.take();
if (!glyph || !glyph->data) {
unlockFace();
return QFontEngine::alphaRGBMapForGlyph(g, subPixelPosition, t);
@@ -1982,6 +1980,9 @@ QImage QFontEngineFT::alphaRGBMapForGlyph(glyph_t g, QFixed subPixelPosition, co
QImage img(glyph->width, glyph->height, QImage::Format_RGB32);
memcpy(img.bits(), glyph->data, 4 * glyph->width * glyph->height);
+
+ if (cacheEnabled)
+ glyph.take();
unlockFace();
return img;
diff --git a/src/gui/text/qplatformfontdatabase.cpp b/src/gui/text/qplatformfontdatabase.cpp
index 5f277c878a..33301005c6 100644
--- a/src/gui/text/qplatformfontdatabase.cpp
+++ b/src/gui/text/qplatformfontdatabase.cpp
@@ -53,6 +53,7 @@ void qt_registerFont(const QString &familyname, const QString &stylename,
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *hanlde);
+void qt_registerFontFamily(const QString &familyName);
void qt_registerAliasToFontFamily(const QString &familyName, const QString &alias);
/*!
@@ -118,7 +119,7 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *
The writing systems supported by the font are specified by the
\a writingSystems argument.
- \sa registerQPF2Font()
+ \sa registerQPF2Font(), registerFontFamily()
*/
void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &stylename,
const QString &foundryname, QFont::Weight weight,
@@ -134,6 +135,18 @@ void QPlatformFontDatabase::registerFont(const QString &familyname, const QStrin
fixedPitch, writingSystems, usrPtr);
}
+/*!
+ Registers a font family with the font database. The font will be
+ lazily populated by a callback to populateFamily() when the font
+ database determines that the family needs population.
+
+ \sa populateFamily(), registerFont()
+*/
+void QPlatformFontDatabase::registerFontFamily(const QString &familyName)
+{
+ qt_registerFontFamily(familyName);
+}
+
class QWritingSystemsPrivate
{
public:
@@ -249,6 +262,11 @@ QPlatformFontDatabase::~QPlatformFontDatabase()
Reimplement this function in a subclass for a convenient place to initialize
the internal font database.
+ You may lazily populate the database by calling registerFontFamily() instead
+ of registerFont(), in which case you'll get a callback to populateFamily()
+ when the required family needs population. You then call registerFont() to
+ finish population of the family.
+
The default implementation looks in the fontDir() location and registers all
QPF2 fonts.
*/
@@ -276,6 +294,18 @@ void QPlatformFontDatabase::populateFontDatabase()
}
/*!
+ This function is called whenever a lazily populated family, populated
+ through registerFontFamily(), needs full population.
+
+ You are expected to fully populate the family by calling registerFont()
+ for each font that matches the family name.
+*/
+void QPlatformFontDatabase::populateFamily(const QString &familyName)
+{
+ Q_UNUSED(familyName);
+}
+
+/*!
This function is called whenever the font database is invalidated.
Reimplement this function to clear any internal data structures that
diff --git a/src/gui/text/qplatformfontdatabase.h b/src/gui/text/qplatformfontdatabase.h
index 870480809b..b200cf0e58 100644
--- a/src/gui/text/qplatformfontdatabase.h
+++ b/src/gui/text/qplatformfontdatabase.h
@@ -96,6 +96,7 @@ class Q_GUI_EXPORT QPlatformFontDatabase
public:
virtual ~QPlatformFontDatabase();
virtual void populateFontDatabase();
+ virtual void populateFamily(const QString &familyName);
virtual void invalidate();
virtual QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
@@ -125,6 +126,7 @@ public:
bool scalable, int pixelSize, bool fixedPitch,
const QSupportedWritingSystems &writingSystems, void *handle);
+ static void registerFontFamily(const QString &familyName);
static void registerAliasToFontFamily(const QString &familyName, const QString &alias);
};
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index b153219136..0afc6f9259 100644
--- a/src/gui/text/qstatictext.cpp
+++ b/src/gui/text/qstatictext.cpp
@@ -573,6 +573,9 @@ namespace {
case PdmDepth:
val = 24;
break;
+ case PdmDevicePixelRatio:
+ val = 1;
+ break;
default:
val = 0;
qWarning("DrawTextItemDevice::metric: Invalid metric command");
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 0298adde7a..3b079b7ee3 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -2374,6 +2374,7 @@ void QTextEngine::freeMemory()
layoutData->hasBidi = false;
layoutData->layoutState = LayoutEmpty;
layoutData->haveCharAttributes = false;
+ layoutData->items.clear();
}
for (int i = 0; i < lines.size(); ++i) {
lines[i].justified = 0;
@@ -2520,7 +2521,8 @@ void QTextEngine::setAdditionalFormats(const QList<QTextLayout::FormatRange> &fo
specialData->addFormats = formatList;
indexAdditionalFormats();
}
- resetFontEngineCache();
+ invalidate();
+ clearLineData();
}
void QTextEngine::indexAdditionalFormats()
diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri
index 2a0e4eff32..c67769ad48 100644
--- a/src/gui/text/text.pri
+++ b/src/gui/text/text.pri
@@ -88,7 +88,7 @@ HEADERS += \
contains(QT_CONFIG, harfbuzz)|contains(QT_CONFIG, system-harfbuzz) {
DEFINES += QT_ENABLE_HARFBUZZ_NG
- include($$PWD/../../3rdparty/harfbuzz.pri)
+ include($$PWD/../../3rdparty/harfbuzzng.pri)
SOURCES += text/qharfbuzzng.cpp
HEADERS += text/qharfbuzzng_p.h
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index cf786e37c6..accad6e4c0 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -377,6 +377,8 @@ void QHttpNetworkConnectionPrivate::emitReplyError(QAbstractSocket *socket,
// Clean the channel
channels[i].close();
channels[i].reply = 0;
+ if (channels[i].protocolHandler)
+ channels[i].protocolHandler->setReply(0);
channels[i].request = QHttpNetworkRequest();
if (socket)
channels[i].requeueCurrentlyPipelinedRequests();
@@ -826,6 +828,8 @@ void QHttpNetworkConnectionPrivate::removeReply(QHttpNetworkReply *reply)
// is the reply associated the currently processing of this channel?
if (channels[i].reply == reply) {
channels[i].reply = 0;
+ if (channels[i].protocolHandler)
+ channels[i].protocolHandler->setReply(0);
channels[i].request = QHttpNetworkRequest();
channels[i].resendCurrent = false;
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index 2a7e6ed638..b057fee144 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -363,7 +363,7 @@ bool QHttpNetworkReplyPrivate::isCompressed()
void QHttpNetworkReplyPrivate::removeAutoDecompressHeader()
{
// The header "Content-Encoding = gzip" is retained.
- // Content-Length is removed since the actual one send by the server is for compressed data
+ // Content-Length is removed since the actual one sent by the server is for compressed data
QByteArray name("content-length");
QList<QPair<QByteArray, QByteArray> >::Iterator it = fields.begin(),
end = fields.end();
@@ -921,7 +921,7 @@ qint64 QHttpNetworkReplyPrivate::getChunkSize(QAbstractSocket *socket, qint64 *c
bool QHttpNetworkReplyPrivate::shouldEmitSignals()
{
// for 401 & 407 don't emit the data signals. Content along with these
- // responses are send only if the authentication fails.
+ // responses are sent only if the authentication fails.
return (statusCode != 401 && statusCode != 407);
}
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 6e9f1216c3..8ad04c9885 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -120,7 +120,7 @@ QByteArray QHttpNetworkRequest::uri(bool throughProxy) const
{
QUrl::FormattingOptions format(QUrl::RemoveFragment | QUrl::RemoveUserInfo | QUrl::FullyEncoded);
- // for POST, query data is send as content
+ // for POST, query data is sent as content
if (d->operation == QHttpNetworkRequest::Post && !d->uploadByteDevice)
format |= QUrl::RemoveQuery;
// for requests through proxy, the Request-URI contains full url
diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl.mm b/src/network/access/qnetworkreplynsurlconnectionimpl.mm
index 293a505912..d49324918e 100644
--- a/src/network/access/qnetworkreplynsurlconnectionimpl.mm
+++ b/src/network/access/qnetworkreplynsurlconnectionimpl.mm
@@ -128,6 +128,7 @@ QNetworkReplyNSURLConnectionImplPrivate::QNetworkReplyNSURLConnectionImplPrivate
QNetworkReplyNSURLConnectionImplPrivate::~QNetworkReplyNSURLConnectionImplPrivate()
{
+ [urlConnection cancel];
[urlConnection release];
[urlConnectionDelegate release];
if (readStream)
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index edbbbf5a75..f7b956651f 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -981,7 +981,7 @@ public:
QNtlmPhase1Block() {
qstrncpy(magic, "NTLMSSP", 8);
type = 1;
- flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET;
+ flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_NTLM2;
}
// extracted
@@ -1423,9 +1423,16 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
ds.setByteOrder(QDataStream::LittleEndian);
QNtlmPhase3Block pb;
+ // set NTLMv2
+ if (ch.flags & NTLMSSP_NEGOTIATE_NTLM2)
+ pb.flags |= NTLMSSP_NEGOTIATE_NTLM2;
+
+ // set Always Sign
+ if (ch.flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
+ pb.flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+
bool unicode = ch.flags & NTLMSSP_NEGOTIATE_UNICODE;
- pb.flags = NTLMSSP_NEGOTIATE_NTLM;
if (unicode)
pb.flags |= NTLMSSP_NEGOTIATE_UNICODE;
else
diff --git a/src/network/socket/qlocalserver_tcp.cpp b/src/network/socket/qlocalserver_tcp.cpp
index 39e7babf71..de4acd9111 100644
--- a/src/network/socket/qlocalserver_tcp.cpp
+++ b/src/network/socket/qlocalserver_tcp.cpp
@@ -80,8 +80,6 @@ bool QLocalServerPrivate::listen(const QString &requestedServerName)
bool QLocalServerPrivate::listen(qintptr socketDescriptor)
{
- Q_Q(QLocalServer);
-
return tcpServer.setSocketDescriptor(socketDescriptor);
}
diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp
index 11a14359d7..0181b9965a 100644
--- a/src/network/socket/qnativesocketengine_unix.cpp
+++ b/src/network/socket/qnativesocketengine_unix.cpp
@@ -363,7 +363,7 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt
bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port)
{
#ifdef QNATIVESOCKETENGINE_DEBUG
- qDebug("QNativeSocketEnginePrivate::nativeConnect() : %d ", socketDescriptor);
+ qDebug("QNativeSocketEnginePrivate::nativeConnect() : %lli", socketDescriptor);
#endif
struct sockaddr_in sockAddrIPv4;
@@ -856,7 +856,7 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
}
#if defined (QNATIVESOCKETENGINE_DEBUG)
- qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %i", recvResult);
+ qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %zd", recvResult);
#endif
return qint64(recvResult);
@@ -1021,13 +1021,13 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
socketType = QAbstractSocket::UnknownSocketType;
}
#if defined (QNATIVESOCKETENGINE_DEBUG)
- QString socketProtocolStr = "UnknownProtocol";
- if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = "IPv4Protocol";
- else if (socketProtocol == QAbstractSocket::IPv6Protocol) socketProtocolStr = "IPv6Protocol";
+ QString socketProtocolStr = QStringLiteral("UnknownProtocol");
+ if (socketProtocol == QAbstractSocket::IPv4Protocol) socketProtocolStr = QStringLiteral("IPv4Protocol");
+ else if (socketProtocol == QAbstractSocket::IPv6Protocol) socketProtocolStr = QStringLiteral("IPv6Protocol");
- QString socketTypeStr = "UnknownSocketType";
- if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = "TcpSocket";
- else if (socketType == QAbstractSocket::UdpSocket) socketTypeStr = "UdpSocket";
+ QString socketTypeStr = QStringLiteral("UnknownSocketType");
+ if (socketType == QAbstractSocket::TcpSocket) socketTypeStr = QStringLiteral("TcpSocket");
+ else if (socketType == QAbstractSocket::UdpSocket) socketTypeStr = QStringLiteral("UdpSocket");
qDebug("QNativeSocketEnginePrivate::fetchConnectionParameters() local == %s:%i,"
" peer == %s:%i, socket == %s - %s",
@@ -1121,7 +1121,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize)
}
#if defined (QNATIVESOCKETENGINE_DEBUG)
- qDebug("QNativeSocketEnginePrivate::nativeRead(%p \"%s\", %llu) == %i",
+ qDebug("QNativeSocketEnginePrivate::nativeRead(%p \"%s\", %llu) == %zd",
data, qt_prettyDebug(data, qMin(r, ssize_t(16)), r).data(),
maxSize, r);
#endif
@@ -1129,6 +1129,53 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize)
return qint64(r);
}
+#ifdef Q_OS_BLACKBERRY
+int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
+{
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(socketDescriptor, &fds);
+
+ int retval;
+ QList<QSocketNotifier *> notifiers;
+ if (selectForRead) {
+ notifiers << readNotifier;
+ retval = bb_select(notifiers, socketDescriptor + 1, &fds, 0, timeout);
+ } else {
+ notifiers << writeNotifier;
+ retval = bb_select(notifiers, socketDescriptor + 1, 0, &fds, timeout);
+ }
+
+ return retval;
+}
+
+int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite,
+ bool *selectForRead, bool *selectForWrite) const
+{
+ fd_set fdread;
+ FD_ZERO(&fdread);
+ if (checkRead)
+ FD_SET(socketDescriptor, &fdread);
+
+ fd_set fdwrite;
+ FD_ZERO(&fdwrite);
+ if (checkWrite)
+ FD_SET(socketDescriptor, &fdwrite);
+
+ QList<QSocketNotifier *> notifiers;
+ notifiers << readNotifier << writeNotifier;
+ int ret = bb_select(notifiers, socketDescriptor + 1, &fdread, &fdwrite, timeout);
+
+ if (ret <= 0)
+ return ret;
+ *selectForRead = FD_ISSET(socketDescriptor, &fdread);
+ *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite);
+
+ return ret;
+}
+
+#else // not Q_OS_BLACKBERRY:
+
int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const
{
fd_set fds;
@@ -1175,5 +1222,6 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c
return ret;
}
+#endif // Q_OS_BLACKBERRY
QT_END_NAMESPACE
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index 2a61325471..4b2d1c372e 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -549,9 +549,9 @@ qint64 QNativeSocketEngine::write(const char *data, qint64 len)
Q_D(QNativeSocketEngine);
qint64 bytesWritten = -1;
if (d->socketType == QAbstractSocket::TcpSocket)
- bytesWritten = ::nativeWrite(d->tcp, data, len);
+ bytesWritten = nativeWrite(d->tcp, data, len);
else if (d->socketType == QAbstractSocket::UdpSocket)
- bytesWritten = ::nativeWrite(d->udp, data, len);
+ bytesWritten = nativeWrite(d->udp, data, len);
if (bytesWritten != -1 && d->notifyOnWrite)
writeNotification();
return bytesWritten;
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 4360a13b51..cd64b9ec43 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -1519,11 +1519,13 @@ void QSslSocketBackendPrivate::continueHandshake()
}
#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
- const unsigned char *proto;
- unsigned int proto_len;
+ const unsigned char *proto = 0;
+ unsigned int proto_len = 0;
q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
- QByteArray nextProtocol(reinterpret_cast<const char *>(proto), proto_len);
- configuration.nextNegotiatedProtocol = nextProtocol;
+ if (proto_len)
+ configuration.nextNegotiatedProtocol = QByteArray(reinterpret_cast<const char *>(proto), proto_len);
+ else
+ configuration.nextNegotiatedProtocol.clear();
configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
index 56f3f5ad0a..f266318ba6 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp
@@ -534,7 +534,8 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id)
"invertedTextureSize",
"brushTransform",
"brushTexture",
- "matrix"
+ "matrix",
+ "translateZ"
};
if (uniformLocations.at(id) == GLuint(-1))
diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
index bbd9d86773..166d9a0593 100644
--- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h
@@ -444,6 +444,7 @@ public:
BrushTransform,
BrushTexture,
Matrix,
+ TranslateZ,
NumUniforms
};
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index 90bd7edf54..aad2c1f7db 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -106,10 +106,13 @@ static const char* const qglslPositionOnlyVertexShader = "\n\
static const char* const qglslComplexGeometryPositionOnlyVertexShader = "\n\
uniform highp mat3 matrix; \n\
+ uniform highp float translateZ; \n\
attribute highp vec2 vertexCoordsArray; \n\
void setPosition(void) \n\
{ \n\
- gl_Position = vec4(matrix * vec3(vertexCoordsArray, 1), 1);\n\
+ vec3 v = matrix * vec3(vertexCoordsArray, 1.0); \n\
+ vec4 vz = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, translateZ, 1) * vec4(v, 1.0); \n\
+ gl_Position = vec4(vz.xyz, 1.0);\n\
} \n";
static const char* const qglslUntransformedPositionVertexShader = "\n\
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index fd64a4a71f..2b49e4d2d1 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1158,6 +1158,7 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
brushUniformsDirty = true;
opacityUniformDirty = true;
matrixUniformDirty = true;
+ translateZUniformDirty = true;
}
if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode)
@@ -1174,6 +1175,12 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque)
matrixUniformDirty = false;
}
+ if (translateZUniformDirty && shaderManager->hasComplexGeometry()) {
+ shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::TranslateZ),
+ translateZ);
+ translateZUniformDirty = false;
+ }
+
return changed;
}
@@ -2011,6 +2018,7 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev)
d->matrixDirty = true;
d->compositionModeDirty = true;
d->opacityUniformDirty = true;
+ d->translateZUniformDirty = true;
d->needsSync = true;
d->useSystemClip = !systemClip().isEmpty();
d->currentBrush = QBrush();
@@ -2375,6 +2383,15 @@ void QGL2PaintEngineExPrivate::systemStateChanged()
}
}
+void QGL2PaintEngineEx::setTranslateZ(GLfloat z)
+{
+ Q_D(QGL2PaintEngineEx);
+ if (d->translateZ != z) {
+ d->translateZ = z;
+ d->translateZUniformDirty = true;
+ }
+}
+
void QGL2PaintEngineEx::setState(QPainterState *new_state)
{
// qDebug("QGL2PaintEngineEx::setState()");
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 33a8869ecf..15ed5bc57d 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -158,6 +158,9 @@ public:
bool isNativePaintingActive() const;
bool requiresPretransformedGlyphPositions(QFontEngine *, const QTransform &) const { return false; }
bool shouldDrawCachedGlyphs(QFontEngine *, const QTransform &) const;
+
+ void setTranslateZ(GLfloat z);
+
private:
Q_DISABLE_COPY(QGL2PaintEngineEx)
};
@@ -183,7 +186,8 @@ public:
snapToPixelGrid(false),
nativePaintingActive(false),
inverseScale(1),
- lastMaskTextureUsed(0)
+ lastMaskTextureUsed(0),
+ translateZ(0)
{ }
~QGL2PaintEngineExPrivate();
@@ -266,6 +270,7 @@ public:
bool brushUniformsDirty;
bool opacityUniformDirty;
bool matrixUniformDirty;
+ bool translateZUniformDirty;
bool stencilClean; // Has the stencil not been used for clipping so far?
bool useSystemClip;
@@ -309,6 +314,8 @@ public:
QVector<GLuint> unusedIBOSToClean;
const GLfloat *vertexAttribPointers[3];
+
+ GLfloat translateZ;
};
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 1fbff0f0fe..de1de476b8 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2441,7 +2441,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
if (genMipmap && ctx->isES())
- functions->glGenerateMipmap(target);
+ q->functions()->glGenerateMipmap(target);
#ifndef QT_NO_DEBUG
GLenum error = glGetError();
if (error != GL_NO_ERROR) {
@@ -4451,12 +4451,6 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font)
glDisable(GL_DEPTH_TEST);
glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, width, height, 0, 0, 1);
- glMatrixMode(GL_MODELVIEW);
-
- glLoadIdentity();
} else {
setAutoBufferSwap(false);
// disable glClear() as a result of QPainter::begin()
@@ -4567,19 +4561,21 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con
} else if (use_scissor_testing) {
glEnable(GL_SCISSOR_TEST);
}
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
glViewport(0, 0, width, height);
- glOrtho(0, width, height, 0, 0, 1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
glAlphaFunc(GL_GREATER, 0.0);
glEnable(GL_ALPHA_TEST);
if (use_depth_testing)
glEnable(GL_DEPTH_TEST);
- glTranslated(0, 0, -win_z);
+
+ // The only option in Qt 5 is the shader-based OpenGL 2 paint engine.
+ // Setting fixed pipeline transformations is futile. Instead, pass the
+ // extra values directly and let the engine figure the matrices out.
+ static_cast<QGL2PaintEngineEx *>(p->paintEngine())->setTranslateZ(-win_z);
+
qt_gl_draw_text(p, qRound(win_x), qRound(win_y), str, font);
+ static_cast<QGL2PaintEngineEx *>(p->paintEngine())->setTranslateZ(0);
+
if (!reuse_painter) {
p->end();
delete p;
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
index d82e55eba1..450f17b171 100644
--- a/src/opengl/qglfunctions.cpp
+++ b/src/opengl/qglfunctions.cpp
@@ -49,12 +49,12 @@ QT_BEGIN_NAMESPACE
/*!
\class QGLFunctions
\inmodule QtOpenGL
- \brief The QGLFunctions class provides cross-platform access to the OpenGL/ES 2.0 API.
+ \brief The QGLFunctions class provides cross-platform access to the OpenGL ES 2.0 API.
\since 4.8
\obsolete
\ingroup painting-3D
- OpenGL/ES 2.0 defines a subset of the OpenGL specification that is
+ OpenGL ES 2.0 defines a subset of the OpenGL specification that is
common across many desktop and embedded OpenGL implementations.
However, it can be difficult to use the functions from that subset
because they need to be resolved manually on desktop systems.
@@ -82,7 +82,7 @@ QT_BEGIN_NAMESPACE
}
\endcode
- The \c{paintGL()} function can then use any of the OpenGL/ES 2.0
+ The \c{paintGL()} function can then use any of the OpenGL ES 2.0
functions without explicit resolution, such as glActiveTexture()
in the following example:
@@ -96,23 +96,23 @@ QT_BEGIN_NAMESPACE
\endcode
QGLFunctions can also be used directly for ad-hoc invocation
- of OpenGL/ES 2.0 functions on all platforms:
+ of OpenGL ES 2.0 functions on all platforms:
\code
QGLFunctions glFuncs(QGLContext::currentContext());
glFuncs.glActiveTexture(GL_TEXTURE1);
\endcode
- QGLFunctions provides wrappers for all OpenGL/ES 2.0 functions,
+ QGLFunctions provides wrappers for all OpenGL ES 2.0 functions,
except those like \c{glDrawArrays()}, \c{glViewport()}, and
\c{glBindTexture()} that don't have portability issues.
Including the header for QGLFunctions will also define all of
- the OpenGL/ES 2.0 macro constants that are not already defined by
+ the OpenGL ES 2.0 macro constants that are not already defined by
the system's OpenGL headers, such as \c{GL_TEXTURE1} above.
The hasOpenGLFeature() and openGLFeatures() functions can be used
- to determine if the OpenGL implementation has a major OpenGL/ES 2.0
+ to determine if the OpenGL implementation has a major OpenGL ES 2.0
feature. For example, the following checks if non power of two
textures are available:
@@ -126,7 +126,7 @@ QT_BEGIN_NAMESPACE
/*!
\enum QGLFunctions::OpenGLFeature
- This enum defines OpenGL/ES 2.0 features that may be optional
+ This enum defines OpenGL ES 2.0 features that may be optional
on other platforms.
\value Multitexture glActiveTexture() function is available.
@@ -373,7 +373,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glActiveTexture(\a texture).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glActiveTexture.xml}{glActiveTexture()}.
*/
@@ -382,10 +382,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glAttachShader(\a program, \a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glAttachShader.xml}{glAttachShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -393,10 +393,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBindAttribLocation(\a program, \a index, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindAttribLocation.xml}{glBindAttribLocation()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -404,7 +404,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBindBuffer(\a target, \a buffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindBuffer.xml}{glBindBuffer()}.
*/
@@ -416,7 +416,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Note that Qt will translate a \a framebuffer argument of 0 to the currently
bound QOpenGLContext's defaultFramebufferObject().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindFramebuffer.xml}{glBindFramebuffer()}.
*/
@@ -425,7 +425,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBindRenderbuffer(\a target, \a renderbuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBindRenderbuffer.xml}{glBindRenderbuffer()}.
*/
@@ -434,7 +434,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBlendColor(\a red, \a green, \a blue, \a alpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendColor.xml}{glBlendColor()}.
*/
@@ -443,7 +443,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBlendEquation(\a mode).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquation.xml}{glBlendEquation()}.
*/
@@ -452,7 +452,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBlendEquationSeparate(\a modeRGB, \a modeAlpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendEquationSeparate.xml}{glBlendEquationSeparate()}.
*/
@@ -461,7 +461,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBlendFuncSeparate(\a srcRGB, \a dstRGB, \a srcAlpha, \a dstAlpha).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBlendFuncSeparate.xml}{glBlendFuncSeparate()}.
*/
@@ -470,7 +470,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBufferData.xml}{glBufferData()}.
*/
@@ -479,7 +479,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glBufferSubData.xml}{glBufferSubData()}.
*/
@@ -488,7 +488,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glCheckFramebufferStatus(\a target).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCheckFramebufferStatus.xml}{glCheckFramebufferStatus()}.
*/
@@ -497,9 +497,9 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glClearDepth(\a depth) on
desktop OpenGL systems and glClearDepthf(\a depth) on
- embedded OpenGL/ES systems.
+ embedded OpenGL ES systems.
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glClearDepthf.xml}{glClearDepthf()}.
*/
@@ -508,10 +508,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glCompileShader(\a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCompileShader.xml}{glCompileShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -519,7 +519,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glCompressedTexImage2D(\a target, \a level, \a internalformat, \a width, \a height, \a border, \a imageSize, \a data).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexImage2D.xml}{glCompressedTexImage2D()}.
*/
@@ -528,7 +528,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glCompressedTexSubImage2D(\a target, \a level, \a xoffset, \a yoffset, \a width, \a height, \a format, \a imageSize, \a data).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCompressedTexSubImage2D.xml}{glCompressedTexSubImage2D()}.
*/
@@ -537,10 +537,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glCreateProgram().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCreateProgram.xml}{glCreateProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -548,10 +548,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glCreateShader(\a type).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glCreateShader.xml}{glCreateShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -559,7 +559,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDeleteBuffers(\a n, \a buffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteBuffers.xml}{glDeleteBuffers()}.
*/
@@ -568,7 +568,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDeleteFramebuffers(\a n, \a framebuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteFramebuffers.xml}{glDeleteFramebuffers()}.
*/
@@ -577,10 +577,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDeleteProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteProgram.xml}{glDeleteProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -588,7 +588,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDeleteRenderbuffers(\a n, \a renderbuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteRenderbuffers.xml}{glDeleteRenderbuffers()}.
*/
@@ -597,10 +597,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDeleteShader(\a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDeleteShader.xml}{glDeleteShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -608,9 +608,9 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDepthRange(\a zNear, \a zFar) on
desktop OpenGL systems and glDepthRangef(\a zNear, \a zFar) on
- embedded OpenGL/ES systems.
+ embedded OpenGL ES systems.
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDepthRangef.xml}{glDepthRangef()}.
*/
@@ -619,10 +619,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDetachShader(\a program, \a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDetachShader.xml}{glDetachShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -630,10 +630,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glDisableVertexAttribArray(\a index).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glDisableVertexAttribArray.xml}{glDisableVertexAttribArray()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -641,10 +641,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glEnableVertexAttribArray(\a index).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glEnableVertexAttribArray.xml}{glEnableVertexAttribArray()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -652,7 +652,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glFramebufferRenderbuffer(\a target, \a attachment, \a renderbuffertarget, \a renderbuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferRenderbuffer.xml}{glFramebufferRenderbuffer()}.
*/
@@ -661,7 +661,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glFramebufferTexture2D(\a target, \a attachment, \a textarget, \a texture, \a level).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glFramebufferTexture2D.xml}{glFramebufferTexture2D()}.
*/
@@ -670,7 +670,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGenBuffers(\a n, \a buffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenBuffers.xml}{glGenBuffers()}.
*/
@@ -679,7 +679,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGenerateMipmap(\a target).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenerateMipmap.xml}{glGenerateMipmap()}.
*/
@@ -688,7 +688,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGenFramebuffers(\a n, \a framebuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenFramebuffers.xml}{glGenFramebuffers()}.
*/
@@ -697,7 +697,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGenRenderbuffers(\a n, \a renderbuffers).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGenRenderbuffers.xml}{glGenRenderbuffers()}.
*/
@@ -706,10 +706,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetActiveAttrib(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveAttrib.xml}{glGetActiveAttrib()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -717,10 +717,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetActiveUniform(\a program, \a index, \a bufsize, \a length, \a size, \a type, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetActiveUniform.xml}{glGetActiveUniform()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -728,10 +728,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetAttachedShaders(\a program, \a maxcount, \a count, \a shaders).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttachedShaders.xml}{glGetAttachedShaders()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -739,10 +739,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetAttribLocation(\a program, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetAttribLocation.xml}{glGetAttribLocation()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -750,7 +750,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetBufferParameteriv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetBufferParameteriv.xml}{glGetBufferParameteriv()}.
*/
@@ -759,7 +759,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetFramebufferAttachmentParameteriv(\a target, \a attachment, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetFramebufferAttachmentParameteriv.xml}{glGetFramebufferAttachmentParameteriv()}.
*/
@@ -768,10 +768,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetProgramiv(\a program, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramiv.xml}{glGetProgramiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -779,10 +779,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetProgramInfoLog(\a program, \a bufsize, \a length, \a infolog).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetProgramInfoLog.xml}{glGetProgramInfoLog()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -790,7 +790,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetRenderbufferParameteriv(\a target, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetRenderbufferParameteriv.xml}{glGetRenderbufferParameteriv()}.
*/
@@ -799,10 +799,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetShaderiv(\a shader, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderiv.xml}{glGetShaderiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -810,10 +810,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetShaderInfoLog(\a shader, \a bufsize, \a length, \a infolog).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderInfoLog.xml}{glGetShaderInfoLog()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -821,10 +821,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetShaderPrecisionFormat(\a shadertype, \a precisiontype, \a range, \a precision).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderPrecisionFormat.xml}{glGetShaderPrecisionFormat()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -832,10 +832,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetShaderSource(\a shader, \a bufsize, \a length, \a source).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetShaderSource.xml}{glGetShaderSource()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -843,10 +843,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetUniformfv(\a program, \a location, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformfv.xml}{glGetUniformfv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -854,10 +854,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetUniformiv(\a program, \a location, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformiv.xml}{glGetUniformiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -865,10 +865,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetUniformLocation(\a program, \a name).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetUniformLocation.xml}{glGetUniformLocation()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -876,10 +876,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetVertexAttribfv(\a index, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribfv.xml}{glGetVertexAttribfv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -887,10 +887,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetVertexAttribiv(\a index, \a pname, \a params).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribiv.xml}{glGetVertexAttribiv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -898,10 +898,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glGetVertexAttribPointerv(\a index, \a pname, \a pointer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glGetVertexAttribPointerv.xml}{glGetVertexAttribPointerv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -909,7 +909,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glIsBuffer(\a buffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsBuffer.xml}{glIsBuffer()}.
*/
@@ -918,7 +918,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glIsFramebuffer(\a framebuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsFramebuffer.xml}{glIsFramebuffer()}.
*/
@@ -927,10 +927,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glIsProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsProgram.xml}{glIsProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -938,7 +938,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glIsRenderbuffer(\a renderbuffer).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsRenderbuffer.xml}{glIsRenderbuffer()}.
*/
@@ -947,10 +947,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glIsShader(\a shader).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glIsShader.xml}{glIsShader()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -958,10 +958,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glLinkProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glLinkProgram.xml}{glLinkProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -969,10 +969,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glReleaseShaderCompiler().
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glReleaseShaderCompiler.xml}{glReleaseShaderCompiler()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -980,7 +980,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glRenderbufferStorage(\a target, \a internalformat, \a width, \a height).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glRenderbufferStorage.xml}{glRenderbufferStorage()}.
*/
@@ -989,7 +989,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glSampleCoverage(\a value, \a invert).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glSampleCoverage.xml}{glSampleCoverage()}.
*/
@@ -998,10 +998,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glShaderBinary(\a n, \a shaders, \a binaryformat, \a binary, \a length).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glShaderBinary.xml}{glShaderBinary()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1009,10 +1009,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glShaderSource(\a shader, \a count, \a string, \a length).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glShaderSource.xml}{glShaderSource()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1020,7 +1020,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glStencilFuncSeparate(\a face, \a func, \a ref, \a mask).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilFuncSeparate.xml}{glStencilFuncSeparate()}.
*/
@@ -1029,7 +1029,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glStencilMaskSeparate(\a face, \a mask).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilMaskSeparate.xml}{glStencilMaskSeparate()}.
*/
@@ -1038,7 +1038,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glStencilOpSeparate(\a face, \a fail, \a zfail, \a zpass).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glStencilOpSeparate.xml}{glStencilOpSeparate()}.
*/
@@ -1047,10 +1047,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform1f(\a location, \a x).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1f.xml}{glUniform1f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1058,10 +1058,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform1fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1fv.xml}{glUniform1fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1069,10 +1069,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform1i(\a location, \a x).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1i.xml}{glUniform1i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1080,10 +1080,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform1iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform1iv.xml}{glUniform1iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1091,10 +1091,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform2f(\a location, \a x, \a y).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2f.xml}{glUniform2f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1102,10 +1102,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform2fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2fv.xml}{glUniform2fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1113,10 +1113,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform2i(\a location, \a x, \a y).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2i.xml}{glUniform2i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1124,10 +1124,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform2iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform2iv.xml}{glUniform2iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1135,10 +1135,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform3f(\a location, \a x, \a y, \a z).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3f.xml}{glUniform3f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1146,10 +1146,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform3fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3fv.xml}{glUniform3fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1157,10 +1157,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform3i(\a location, \a x, \a y, \a z).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3i.xml}{glUniform3i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1168,10 +1168,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform3iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform3iv.xml}{glUniform3iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1179,10 +1179,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform4f(\a location, \a x, \a y, \a z, \a w).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4f.xml}{glUniform4f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1190,10 +1190,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform4fv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4fv.xml}{glUniform4fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1201,10 +1201,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform4i(\a location, \a x, \a y, \a z, \a w).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4i.xml}{glUniform4i()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1212,10 +1212,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniform4iv(\a location, \a count, \a v).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniform4iv.xml}{glUniform4iv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1223,10 +1223,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniformMatrix2fv(\a location, \a count, \a transpose, \a value).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix2fv.xml}{glUniformMatrix2fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1234,10 +1234,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniformMatrix3fv(\a location, \a count, \a transpose, \a value).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix3fv.xml}{glUniformMatrix3fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1245,10 +1245,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUniformMatrix4fv(\a location, \a count, \a transpose, \a value).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUniformMatrix4fv.xml}{glUniformMatrix4fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1256,10 +1256,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glUseProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glUseProgram.xml}{glUseProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1267,10 +1267,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glValidateProgram(\a program).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glValidateProgram.xml}{glValidateProgram()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1278,10 +1278,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib1f(\a indx, \a x).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1f.xml}{glVertexAttrib1f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1289,10 +1289,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib1fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib1fv.xml}{glVertexAttrib1fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1300,10 +1300,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib2f(\a indx, \a x, \a y).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2f.xml}{glVertexAttrib2f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1311,10 +1311,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib2fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib2fv.xml}{glVertexAttrib2fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1322,10 +1322,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib3f(\a indx, \a x, \a y, \a z).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3f.xml}{glVertexAttrib3f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1333,10 +1333,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib3fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib3fv.xml}{glVertexAttrib3fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1344,10 +1344,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib4f(\a indx, \a x, \a y, \a z, \a w).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4f.xml}{glVertexAttrib4f()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1355,10 +1355,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttrib4fv(\a indx, \a values).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttrib4fv.xml}{glVertexAttrib4fv()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
/*!
@@ -1366,10 +1366,10 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
Convenience function that calls glVertexAttribPointer(\a indx, \a size, \a type, \a normalized, \a stride, \a ptr).
- For more information, see the OpenGL/ES 2.0 documentation for
+ For more information, see the OpenGL ES 2.0 documentation for
\l{http://www.khronos.org/opengles/sdk/docs/man/glVertexAttribPointer.xml}{glVertexAttribPointer()}.
- This convenience function will do nothing on OpenGL/ES 1.x systems.
+ This convenience function will do nothing on OpenGL ES 1.x systems.
*/
QGLFunctionsPrivate::QGLFunctionsPrivate(const QGLContext *)
diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp
index 7261b68a88..65f217edf2 100644
--- a/src/opengl/qglshaderprogram.cpp
+++ b/src/opengl/qglshaderprogram.cpp
@@ -1553,6 +1553,9 @@ void QGLShaderProgram::setAttributeArray
The setAttributeBuffer() function can be used to set the attribute
array to an offset within a vertex buffer.
+ \note Normalization will be enabled. If this is not desired, call
+ glVertexAttribPointer directly through QGLFunctions.
+
\sa setAttributeValue(), setUniformValue(), enableAttributeArray()
\sa disableAttributeArray(), setAttributeBuffer()
\since 4.7
@@ -1698,6 +1701,9 @@ void QGLShaderProgram::setAttributeArray
on the \a location. Otherwise the value specified with
setAttributeValue() for \a location will be used.
+ \note Normalization will be enabled. If this is not desired, call
+ glVertexAttribPointer directly though QGLFunctions.
+
\sa setAttributeArray()
\since 4.7
*/
diff --git a/src/platformsupport/cglconvenience/cglconvenience.mm b/src/platformsupport/cglconvenience/cglconvenience.mm
index 50c39a12e0..d0b0de8ae8 100644
--- a/src/platformsupport/cglconvenience/cglconvenience.mm
+++ b/src/platformsupport/cglconvenience/cglconvenience.mm
@@ -114,6 +114,14 @@ void *qcgl_createNSOpenGLPixelFormat(const QSurfaceFormat &format)
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 (format.samples() > 0) {
attrs << NSOpenGLPFAMultisample
@@ -121,6 +129,9 @@ void *qcgl_createNSOpenGLPixelFormat(const QSurfaceFormat &format)
<< NSOpenGLPFASamples << (NSOpenGLPixelFormatAttribute) format.samples();
}
+ if (format.stereo())
+ attrs << NSOpenGLPFAStereo;
+
attrs << NSOpenGLPFAAllowOfflineRenderers;
attrs << 0;
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index c026ff5a4b..7600cc952b 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -1,30 +1,33 @@
contains(QT_CONFIG,egl) {
HEADERS += \
$$PWD/qeglconvenience_p.h \
- $$PWD/qeglplatformcontext_p.h \
$$PWD/qeglpbuffer_p.h
SOURCES += \
$$PWD/qeglconvenience.cpp \
- $$PWD/qeglplatformcontext.cpp \
$$PWD/qeglpbuffer.cpp
- unix {
- HEADERS += \
- $$PWD/qeglplatformcursor_p.h \
- $$PWD/qeglplatformwindow_p.h \
- $$PWD/qeglplatformscreen_p.h \
- $$PWD/qeglcompositor_p.h \
- $$PWD/qeglplatformbackingstore_p.h \
- $$PWD/qeglplatformintegration_p.h
+ contains(QT_CONFIG,opengl) {
+ HEADERS += $$PWD/qeglplatformcontext_p.h
+ SOURCES += $$PWD/qeglplatformcontext.cpp
- SOURCES += \
- $$PWD/qeglplatformcursor.cpp \
- $$PWD/qeglplatformwindow.cpp \
- $$PWD/qeglplatformscreen.cpp \
- $$PWD/qeglcompositor.cpp \
- $$PWD/qeglplatformbackingstore.cpp \
- $$PWD/qeglplatformintegration.cpp
+ unix {
+ HEADERS += \
+ $$PWD/qeglplatformcursor_p.h \
+ $$PWD/qeglplatformwindow_p.h \
+ $$PWD/qeglplatformscreen_p.h \
+ $$PWD/qeglcompositor_p.h \
+ $$PWD/qeglplatformbackingstore_p.h \
+ $$PWD/qeglplatformintegration_p.h
+
+ SOURCES += \
+ $$PWD/qeglplatformcursor.cpp \
+ $$PWD/qeglplatformwindow.cpp \
+ $$PWD/qeglplatformscreen.cpp \
+ $$PWD/qeglcompositor.cpp \
+ $$PWD/qeglplatformbackingstore.cpp \
+ $$PWD/qeglplatformintegration.cpp
+ }
}
# Avoid X11 header collision
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 1ed5ede3e8..88814151b6 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -170,6 +170,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi
{
QFontDef fontDef;
fontDef.pixelSize = pixelSize;
+ fontDef.hintingPreference = hintingPreference;
QFontEngineFTRawData *fe = new QFontEngineFTRawData(fontDef);
if (!fe->initFromData(fontData)) {
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index a9a85f1316..1a31400ea5 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -509,6 +509,74 @@ QFontEngineMulti *QFontconfigDatabase::fontEngineMulti(QFontEngine *fontEngine,
return new QFontEngineMultiFontConfig(fontEngine, script);
}
+namespace {
+QFontEngineFT::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintingPreference, FcPattern *match)
+{
+ switch (hintingPreference) {
+ case QFont::PreferNoHinting:
+ return QFontEngineFT::HintNone;
+ case QFont::PreferVerticalHinting:
+ return QFontEngineFT::HintLight;
+ case QFont::PreferFullHinting:
+ return QFontEngineFT::HintFull;
+ case QFont::PreferDefaultHinting:
+ break;
+ }
+
+ const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
+ if (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")) {
+ void *hintStyleResource =
+ QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
+ QGuiApplication::primaryScreen());
+ int hintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
+ if (hintStyle > 0)
+ return QFontEngine::HintStyle(hintStyle - 1);
+ }
+
+ int hint_style = 0;
+ if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
+ hint_style = FC_HINT_FULL;
+ switch (hint_style) {
+ case FC_HINT_NONE:
+ return QFontEngineFT::HintNone;
+ case FC_HINT_SLIGHT:
+ return QFontEngineFT::HintLight;
+ case FC_HINT_MEDIUM:
+ return QFontEngineFT::HintMedium;
+ case FC_HINT_FULL:
+ return QFontEngineFT::HintFull;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ return QFontEngineFT::HintFull;
+}
+
+QFontEngineFT::SubpixelAntialiasingType subpixelTypeFromMatch(FcPattern *match)
+{
+ int subpixel = FC_RGBA_UNKNOWN;
+ FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
+
+ switch (subpixel) {
+ case FC_RGBA_UNKNOWN:
+ case FC_RGBA_NONE:
+ return QFontEngineFT::Subpixel_None;
+ case FC_RGBA_RGB:
+ return QFontEngineFT::Subpixel_RGB;
+ case FC_RGBA_BGR:
+ return QFontEngineFT::Subpixel_BGR;
+ case FC_RGBA_VRGB:
+ return QFontEngineFT::Subpixel_VRGB;
+ case FC_RGBA_VBGR:
+ return QFontEngineFT::Subpixel_VBGR;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ return QFontEngineFT::Subpixel_None;
+}
+} // namespace
+
QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
if (!usrPtr)
@@ -548,39 +616,7 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
FcPattern *match = FcFontMatch(0, pattern, &result);
if (match) {
- QFontEngineFT::HintStyle default_hint_style;
- if (f.hintingPreference != QFont::PreferDefaultHinting) {
- switch (f.hintingPreference) {
- case QFont::PreferNoHinting:
- default_hint_style = QFontEngineFT::HintNone;
- break;
- case QFont::PreferVerticalHinting:
- default_hint_style = QFontEngineFT::HintLight;
- break;
- case QFont::PreferFullHinting:
- default:
- default_hint_style = QFontEngineFT::HintFull;
- break;
- }
- } else {
- int hint_style = 0;
- if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultNoMatch)
- hint_style = QFontEngineFT::HintFull;
- switch (hint_style) {
- case FC_HINT_NONE:
- default_hint_style = QFontEngineFT::HintNone;
- break;
- case FC_HINT_SLIGHT:
- default_hint_style = QFontEngineFT::HintLight;
- break;
- case FC_HINT_MEDIUM:
- default_hint_style = QFontEngineFT::HintMedium;
- break;
- default:
- default_hint_style = QFontEngineFT::HintFull;
- break;
- }
- }
+ engine->setDefaultHintStyle(defaultHintStyleFromMatch((QFont::HintingPreference)f.hintingPreference, match));
if (antialias) {
// If antialiasing is not fully disabled, fontconfig may still disable it on a font match basis.
@@ -590,40 +626,13 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
antialias = fc_antialias;
}
- if (f.hintingPreference == QFont::PreferDefaultHinting) {
- const QPlatformServices *services = QGuiApplicationPrivate::platformIntegration()->services();
- if (services && (services->desktopEnvironment() == "GNOME" || services->desktopEnvironment() == "UNITY")) {
- void *hintStyleResource =
- QGuiApplication::platformNativeInterface()->nativeResourceForScreen("hintstyle",
- QGuiApplication::primaryScreen());
- int hintStyle = int(reinterpret_cast<qintptr>(hintStyleResource));
- if (hintStyle > 0)
- default_hint_style = QFontEngine::HintStyle(hintStyle - 1);
- }
- }
-
- engine->setDefaultHintStyle(default_hint_style);
-
if (antialias) {
- QFontEngineFT::SubpixelAntialiasingType subpixelType = QFontEngineFT::Subpixel_None;
- int subpixel = FC_RGBA_NONE;
-
- FcPatternGetInteger(match, FC_RGBA, 0, &subpixel);
- if (subpixel == FC_RGBA_UNKNOWN)
- subpixel = FC_RGBA_NONE;
-
- switch (subpixel) {
- case FC_RGBA_NONE: subpixelType = QFontEngineFT::Subpixel_None; break;
- case FC_RGBA_RGB: subpixelType = QFontEngineFT::Subpixel_RGB; break;
- case FC_RGBA_BGR: subpixelType = QFontEngineFT::Subpixel_BGR; break;
- case FC_RGBA_VRGB: subpixelType = QFontEngineFT::Subpixel_VRGB; break;
- case FC_RGBA_VBGR: subpixelType = QFontEngineFT::Subpixel_VBGR; break;
- default: break;
- }
-
- format = subpixelType == QFontEngineFT::Subpixel_None
- ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_A32;
+ QFontEngineFT::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match);
engine->subpixelType = subpixelType;
+
+ format = (subpixelType == QFontEngineFT::Subpixel_None)
+ ? QFontEngineFT::Format_A8
+ : QFontEngineFT::Format_A32;
} else
format = QFontEngineFT::Format_Mono;
@@ -641,6 +650,56 @@ QFontEngine *QFontconfigDatabase::fontEngine(const QFontDef &f, void *usrPtr)
return engine;
}
+QFontEngine *QFontconfigDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
+{
+ QFontEngineFT *engine = static_cast<QFontEngineFT*>(QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference));
+ QFontDef fontDef = engine->fontDef;
+
+ QFontEngineFT::GlyphFormat format;
+ // try and get the pattern
+ FcPattern *pattern = FcPatternCreate();
+
+ FcValue value;
+ value.type = FcTypeString;
+ QByteArray cs = fontDef.family.toUtf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAdd(pattern,FC_FAMILY,value,true);
+
+ FcResult result;
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
+ FcPattern *match = FcFontMatch(0, pattern, &result);
+ if (match) {
+ engine->setDefaultHintStyle(defaultHintStyleFromMatch(hintingPreference, match));
+
+ FcBool fc_antialias;
+ if (FcPatternGetBool(match, FC_ANTIALIAS,0, &fc_antialias) != FcResultMatch)
+ fc_antialias = true;
+ engine->antialias = fc_antialias;
+
+ if (engine->antialias) {
+ QFontEngineFT::SubpixelAntialiasingType subpixelType = subpixelTypeFromMatch(match);
+ engine->subpixelType = subpixelType;
+
+ format = subpixelType == QFontEngineFT::Subpixel_None
+ ? QFontEngineFT::Format_A8
+ : QFontEngineFT::Format_A32;
+ } else
+ format = QFontEngineFT::Format_Mono;
+ FcPatternDestroy(match);
+ } else
+ format = QFontEngineFT::Format_A8;
+
+ FcPatternDestroy(pattern);
+
+ engine->defaultFormat = format;
+ engine->glyphFormat = format;
+
+ return engine;
+}
+
QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
QStringList fallbackFamilies;
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
index 9f1fd28144..ba706dc59e 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase_p.h
@@ -53,6 +53,7 @@ public:
void populateFontDatabase();
QFontEngineMulti *fontEngineMulti(QFontEngine *fontEngine, QChar::Script script);
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
+ QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
QString resolveFontFamilyAlias(const QString &family) const;
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index afee68ebed..1c0e888758 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -41,9 +41,11 @@
#include "qglobal.h"
-#ifdef Q_OS_MACX
+#if defined(Q_OS_MACX)
#import <Cocoa/Cocoa.h>
#import <IOKit/graphics/IOGraphicsLib.h>
+#elif defined(Q_OS_IOS)
+#import <UIKit/UIFont.h>
#endif
#include "qcoretextfontdatabase_p.h"
@@ -176,29 +178,50 @@ QCoreTextFontDatabase::~QCoreTextFontDatabase()
{
}
+static CFArrayRef availableFamilyNames()
+{
+#if defined(Q_OS_OSX)
+ return CTFontManagerCopyAvailableFontFamilyNames();
+#elif defined(Q_OS_IOS)
+ return (CFArrayRef) [[UIFont familyNames] retain];
+#endif
+}
+
void QCoreTextFontDatabase::populateFontDatabase()
{
// The caller (QFontDB) expects the db to be populate only with system fonts, so we need
// to make sure that any previously registered app fonts become invisible.
removeApplicationFonts();
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ QCFType<CFArrayRef> familyNames = availableFamilyNames();
+ const int numberOfFamilies = CFArrayGetCount(familyNames);
+ for (int i = 0; i < numberOfFamilies; ++i) {
+ QString familyName = QCFString::toQString((CFStringRef) CFArrayGetValueAtIndex(familyNames, i));
- QCFType<CTFontCollectionRef> collection = CTFontCollectionCreateFromAvailableFonts(0);
- if (! collection)
- return;
+ // Don't populate internal fonts
+ if (familyName.startsWith(QLatin1Char('.')) || familyName == QStringLiteral("LastResort"))
+ continue;
- QCFType<CFArrayRef> fonts = CTFontCollectionCreateMatchingFontDescriptors(collection);
- if (! fonts)
- return;
+ QPlatformFontDatabase::registerFontFamily(familyName);
+ }
+}
- const int numFonts = CFArrayGetCount(fonts);
- for (int i = 0; i < numFonts; ++i) {
- CTFontDescriptorRef font = (CTFontDescriptorRef) CFArrayGetValueAtIndex(fonts, i);
- populateFromDescriptor(font);
+void QCoreTextFontDatabase::populateFamily(const QString &familyName)
+{
+ CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, QCFString(familyName));
+ CTFontDescriptorRef nameOnlyDescriptor = CTFontDescriptorCreateWithAttributes(attributes);
+
+ // A single family might match several different fonts with different styles eg.
+ QCFType<CFArrayRef> matchingFonts = (CFArrayRef) CTFontDescriptorCreateMatchingFontDescriptors(nameOnlyDescriptor, 0);
+ if (!matchingFonts) {
+ qWarning() << "QCoreTextFontDatabase: Found no matching fonts for family" << familyName;
+ return;
}
- [pool release];
+ const int numFonts = CFArrayGetCount(matchingFonts);
+ for (int i = 0; i < numFonts; ++i)
+ populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)));
}
void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index c6fc791503..c73f4a32ca 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -72,6 +72,7 @@ public:
QCoreTextFontDatabase();
~QCoreTextFontDatabase();
void populateFontDatabase();
+ void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle);
QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 3c30df6efb..0460f11139 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -50,6 +50,22 @@ QT_BEGIN_NAMESPACE
static float SYNTHETIC_ITALIC_SKEW = tanf(14 * acosf(0) / 90);
+static bool ct_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *length)
+{
+ CTFontRef ctfont = *(CTFontRef *)user_data;
+
+ QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
+ if (!table)
+ return false;
+
+ CFIndex tableLength = CFDataGetLength(table);
+ if (buffer && int(*length) >= tableLength)
+ CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
+ *length = tableLength;
+ Q_ASSERT(int(*length) > 0);
+ return true;
+}
+
static void loadAdvancesForGlyphs(CTFontRef ctfont,
QVarLengthArray<CGGlyph> &cgGlyphs,
QGlyphLayout *glyphs, int len,
@@ -191,7 +207,10 @@ void QCoreTextFontEngine::init()
cache_cost = (CTFontGetAscent(ctfont) + CTFontGetDescent(ctfont)) * avgCharWidth.toInt() * 2000;
- setUserData(QVariant::fromValue((void *)cgFont));
+ // HACK hb_coretext requires both CTFont and CGFont but user_data is only void*
+ Q_ASSERT((void *)(&ctfont + 1) == (void *)&cgFont);
+ faceData.user_data = &ctfont;
+ faceData.get_font_table = ct_getSfntTable;
}
glyph_t QCoreTextFontEngine::glyphIndex(uint ucs4) const
@@ -683,15 +702,7 @@ bool QCoreTextFontEngine::canRender(const QChar *string, int len) const
bool QCoreTextFontEngine::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
- QCFType<CFDataRef> table = CTFontCopyTable(ctfont, tag, 0);
- if (!table)
- return false;
- CFIndex tableLength = CFDataGetLength(table);
- if (buffer && int(*length) >= tableLength)
- CFDataGetBytes(table, CFRangeMake(0, tableLength), buffer);
- *length = tableLength;
- Q_ASSERT(int(*length) > 0);
- return true;
+ return ct_getSfntTable((void *)&ctfont, tag, buffer, length);
}
void QCoreTextFontEngine::getUnscaledGlyph(glyph_t, QPainterPath *, glyph_metrics_t *)
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
index dc2920360d..2d8b9be092 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -573,6 +573,8 @@ void QCoreWlanEngine::doRequestUpdate()
scanThread->start();
}
locker.unlock();
+ if ([wifiInterfaces count] == 0)
+ networksChanged();
[autoreleasepool release];
}
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm b/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm
index 7044e9696b..057aec5487 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine_10_6.mm
@@ -631,6 +631,8 @@ void QCoreWlanEngine::doRequestUpdate()
scanThread->start();
}
locker.unlock();
+ if ([wifiInterfaces count] == 0)
+ networksChanged();
[autoreleasepool release];
}
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index 546a0a2af7..7182c458fc 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -6,8 +6,6 @@ load(qt_plugin)
QT += gui-private
-LIBS += $$QMAKE_LIBS_XKBCOMMON
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
DEFINES += X11_PREFIX='\\"$$QMAKE_X11_PREFIX\\"'
SOURCES += $$PWD/main.cpp \
@@ -19,14 +17,12 @@ HEADERS += $$PWD/qcomposeplatforminputcontext.h \
# libxkbcommon
contains(QT_CONFIG, xkbcommon-qt): {
+ # dont't need x11 dependency for compose key plugin
+ QT_CONFIG -= use-xkbcommon-x11support
include(../../../3rdparty/xkbcommon.pri)
} else {
LIBS += $$QMAKE_LIBS_XKBCOMMON
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
- equals(QMAKE_VERSION_XKBCOMMON, "0.2.0") {
- DEFINES += XKBCOMMON_0_2_0
- INCLUDEPATH += ../../../3rdparty/xkbcommon/xkbcommon/
- }
}
OTHER_FILES += $$PWD/compose.json
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index ca61b0e495..8bbb490022 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -51,10 +51,6 @@
#include <xkbcommon/xkbcommon.h>
-#ifdef XKBCOMMON_0_2_0
-#include <xkbcommon_workaround.h>
-#endif
-
#include <locale.h> // LC_CTYPE
#include <string.h> // strchr, strncmp, etc.
#include <strings.h> // strncasecmp
@@ -326,23 +322,7 @@ ushort TableGenerator::keysymToUtf8(quint32 sym)
QByteArray chars;
int bytes;
chars.resize(8);
-
-#ifdef XKBCOMMON_0_2_0
- if (needWorkaround(sym)) {
- quint32 codepoint;
- if (sym == XKB_KEY_KP_Space)
- codepoint = XKB_KEY_space & 0x7f;
- else
- codepoint = sym & 0x7f;
-
- bytes = utf32_to_utf8(codepoint, chars.data());
- } else {
- bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
- }
-#else
bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
-#endif
-
if (bytes == -1)
qWarning("TableGenerator::keysymToUtf8 - buffer too small");
diff --git a/src/plugins/platforminputcontexts/platforminputcontexts.pro b/src/plugins/platforminputcontexts/platforminputcontexts.pro
index 60b66bfb35..faea54b874 100644
--- a/src/plugins/platforminputcontexts/platforminputcontexts.pro
+++ b/src/plugins/platforminputcontexts/platforminputcontexts.pro
@@ -4,7 +4,6 @@ qtHaveModule(dbus) {
!mac:!win32:SUBDIRS += ibus
}
-unix:!macx:!contains(DEFINES, QT_NO_XKBCOMMON): {
- SUBDIRS += compose
-}
+contains(QT_CONFIG, xcb-plugin): SUBDIRS += compose
+
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 55d44b7377..9efdcad158 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -67,8 +67,6 @@ namespace QtAndroidInput
static QPointer<QWindow> m_mouseGrabber;
- static int m_lastCursorPos = -1;
-
void updateSelection(int selStart, int selEnd, int candidatesStart, int candidatesEnd)
{
AttachedJNIEnv env;
@@ -78,21 +76,6 @@ namespace QtAndroidInput
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
#endif
- if (candidatesStart == -1 && candidatesEnd == -1 && selStart == selEnd) {
- // Qt only gives us position inside the block, so if we move to the
- // same position in another block, the Android keyboard will believe
- // we have not changed position, and be terribly confused.
- if (selStart == m_lastCursorPos) {
-#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << ">>> FAKEUPDATESELECTION" << selStart+1;
-#endif
- env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID,
- selStart+1, selEnd+1, candidatesStart, candidatesEnd);
- }
- m_lastCursorPos = selStart;
- } else {
- m_lastCursorPos = -1;
- }
env.jniEnv->CallStaticVoidMethod(applicationClass(), m_updateSelectionMethodID,
selStart, selEnd, candidatesStart, candidatesEnd);
}
@@ -517,6 +500,12 @@ namespace QtAndroidInput
}
}
+ // maps 0 to the empty string, and anything else to a single-character string
+ static inline QString toString(jint unicode)
+ {
+ return unicode ? QString(QChar(unicode)) : QString();
+ }
+
static void keyDown(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier)
{
Qt::KeyboardModifiers modifiers;
@@ -533,7 +522,7 @@ namespace QtAndroidInput
QEvent::KeyPress,
mapAndroidKey(key),
modifiers,
- QChar(unicode),
+ toString(unicode),
false);
}
@@ -553,7 +542,7 @@ namespace QtAndroidInput
QEvent::KeyRelease,
mapAndroidKey(key),
modifiers,
- QChar(unicode),
+ toString(unicode),
false);
}
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
index b112e265a5..224a8ca9f7 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
@@ -262,18 +262,20 @@ private:
AndroidAssetsFileEngineHandler::AndroidAssetsFileEngineHandler()
: m_assetsCache(std::max(5, qgetenv("QT_ANDROID_MAX_ASSETS_CACHE_SIZE").toInt()))
, m_hasPrepopulatedCache(false)
+ , m_hasTriedPrepopulatingCache(false)
{
m_assetManager = QtAndroid::assetManager();
- prepopulateCache();
}
AndroidAssetsFileEngineHandler::~AndroidAssetsFileEngineHandler()
{
}
-void AndroidAssetsFileEngineHandler::prepopulateCache()
+void AndroidAssetsFileEngineHandler::prepopulateCache() const
{
- QMutexLocker locker(&m_assetsCacheMutext);
+ Q_ASSERT(!m_hasTriedPrepopulatingCache);
+ m_hasTriedPrepopulatingCache = true;
+
Q_ASSERT(m_assetsCache.isEmpty());
// Failsafe: Don't read cache files that are larger than 1MB
@@ -364,7 +366,11 @@ QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &file
if (!path.size())
path = fileName.left(fileName.length() - 1).toUtf8();
+
m_assetsCacheMutext.lock();
+ if (!m_hasTriedPrepopulatingCache)
+ prepopulateCache();
+
QSharedPointer<AndroidAssetDir> *aad = m_assetsCache.object(path);
m_assetsCacheMutext.unlock();
if (!aad) {
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
index d56367d4d8..ac16ad7b79 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
@@ -58,12 +58,13 @@ public:
QAbstractFileEngine *create(const QString &fileName) const;
private:
- void prepopulateCache();
+ void prepopulateCache() const;
AAssetManager *m_assetManager;
mutable QCache<QByteArray, QSharedPointer<AndroidAssetDir>> m_assetsCache;
mutable QMutex m_assetsCacheMutext;
- bool m_hasPrepopulatedCache;
+ mutable bool m_hasPrepopulatedCache;
+ mutable bool m_hasTriedPrepopulatingCache;
};
#endif // QANDROIDASSETSFILEENGINEHANDLER_H
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index 326972e71e..bfb13811e3 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -81,7 +81,7 @@ static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint new
env->ReleaseStringChars(text, jstr);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << "@@@ COMMIT" << str;
+ qDebug() << "@@@ COMMIT" << str << newCursorPosition;
#endif
return m_androidInputContext->commitText(str, newCursorPosition);
}
@@ -160,7 +160,7 @@ static jstring getTextAfterCursor(JNIEnv *env, jobject /*thiz*/, jint length, ji
const QString &text = m_androidInputContext->getTextAfterCursor(length, flags);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << "@@@ GET" << length << text;
+ qDebug() << "@@@ GETA" << length << text;
#endif
return env->NewString(reinterpret_cast<const jchar *>(text.constData()), jsize(text.length()));
}
@@ -172,7 +172,7 @@ static jstring getTextBeforeCursor(JNIEnv *env, jobject /*thiz*/, jint length, j
const QString &text = m_androidInputContext->getTextBeforeCursor(length, flags);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << "@@@ GET" << length << text;
+ qDebug() << "@@@ GETB" << length << text;
#endif
return env->NewString(reinterpret_cast<const jchar *>(text.constData()), jsize(text.length()));
}
@@ -188,7 +188,7 @@ static jboolean setComposingText(JNIEnv *env, jobject /*thiz*/, jstring text, ji
env->ReleaseStringChars(text, jstr);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << "@@@ SET" << str;
+ qDebug() << "@@@ SET" << str << newCursorPosition;
#endif
return m_androidInputContext->setComposingText(str, newCursorPosition);
}
@@ -271,6 +271,18 @@ static jboolean paste(JNIEnv */*env*/, jobject /*thiz*/)
return m_androidInputContext->paste();
}
+static jboolean updateCursorPosition(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ UPDATECURSORPOS";
+#endif
+ m_androidInputContext->updateCursorPosition();
+ return true;
+}
+
static JNINativeMethod methods[] = {
{"commitText", "(Ljava/lang/String;I)Z", (void *)commitText},
@@ -288,7 +300,8 @@ static JNINativeMethod methods[] = {
{"cut", "()Z", (void *)cut},
{"copy", "()Z", (void *)copy},
{"copyURL", "()Z", (void *)copyURL},
- {"paste", "()Z", (void *)paste}
+ {"paste", "()Z", (void *)paste},
+ {"updateCursorPosition", "()Z", (void *)updateCursorPosition}
};
@@ -404,7 +417,9 @@ void QAndroidInputContext::updateCursorPosition()
{
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (!query.isNull() && !m_blockUpdateSelection) {
- const int cursorPos = query->value(Qt::ImCursorPosition).toInt();
+ // make sure it also works with editors that have not been updated to the new API
+ QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
+ const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt();
QtAndroidInput::updateSelection(cursorPos, cursorPos, -1, -1); //selection empty and no pre-edit text
}
}
@@ -422,9 +437,9 @@ void QAndroidInputContext::invokeAction(QInputMethod::Action action, int cursorP
#warning TODO Handle at least QInputMethod::ContextMenu action
Q_UNUSED(action)
Q_UNUSED(cursorPosition)
-
- if (action == QInputMethod::Click)
- commit();
+ //### click should be passed to the IM, but in the meantime it's better to ignore it than to do something wrong
+ // if (action == QInputMethod::Click)
+ // commit();
}
QRectF QAndroidInputContext::keyboardRect() const
@@ -573,6 +588,12 @@ QString QAndroidInputContext::getSelectedText(jint /*flags*/)
QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
{
+ QVariant textAfter = queryFocusObjectThreadSafe(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 = focusObjectInputMethodQuery();
if (query.isNull())
return QString();
@@ -587,15 +608,21 @@ QString QAndroidInputContext::getTextAfterCursor(jint length, jint /*flags*/)
QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{
+ QVariant textBefore = queryFocusObjectThreadSafe(Qt::ImTextBeforeCursor, QVariant(length));
+ if (textBefore.isValid()) {
+ return textBefore.toString().left(length);
+ }
+
+ //compatibility code for old controls that do not implement the new API
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return QString();
+ int cursorPos = query->value(Qt::ImCursorPosition).toInt();
QString text = query->value(Qt::ImSurroundingText).toString();
if (!text.length())
return text;
- int cursorPos = query->value(Qt::ImCursorPosition).toInt();
const int wordLeftPos = cursorPos - length;
return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos);
}
@@ -621,8 +648,9 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (!query.isNull() && !m_blockUpdateSelection) {
- int cursorPos = query->value(Qt::ImCursorPosition).toInt();
- int preeditLength = text.length();
+ QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
+ const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt();
+ const int preeditLength = text.length();
QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, cursorPos, cursorPos+preeditLength);
}
@@ -650,16 +678,19 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
Therefore, the length of the region is end - start
*/
int length = end - start;
+ int localPos = query->value(Qt::ImCursorPosition).toInt();
+ QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
+ int blockPosition = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0;
+ int localStart = start - blockPosition; // Qt uses position inside block
bool updateSelectionWasBlocked = m_blockUpdateSelection;
m_blockUpdateSelection = true;
QString text = query->value(Qt::ImSurroundingText).toString();
- m_composingText = text.mid(start, length);
+ m_composingText = text.mid(localStart, length);
- //in the Qt text controls, cursor pos is the start of the preedit
- int cursorPos = query->value(Qt::ImCursorPosition).toInt();
- int relativeStart = start - cursorPos;
+ //in the Qt text controls, the cursor position is the start of the preedit
+ int relativeStart = localStart - localPos;
QList<QInputMethodEvent::Attribute> attributes;
@@ -669,6 +700,9 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,0, length,
QVariant(underlined)));
+ // Keep the cursor position unchanged (don't move to end of preedit)
+ attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, localPos - localStart, length, QVariant()));
+
QInputMethodEvent event(m_composingText, attributes);
event.setCommitString(QString(), relativeStart, length);
sendInputMethodEvent(&event);
@@ -720,6 +754,26 @@ jboolean QAndroidInputContext::paste()
return JNI_FALSE;
}
+
+Q_INVOKABLE QVariant QAndroidInputContext::queryFocusObjectUnsafe(Qt::InputMethodQuery query, QVariant argument)
+{
+ return QInputMethod::queryFocusObject(query, argument);
+}
+
+QVariant QAndroidInputContext::queryFocusObjectThreadSafe(Qt::InputMethodQuery query, QVariant argument)
+{
+ bool inMainThread = qGuiApp->thread() == QThread::currentThread();
+ QVariant 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 retval;
+}
+
QSharedPointer<QInputMethodQueryEvent> QAndroidInputContext::focusObjectInputMethodQuery(Qt::InputMethodQueries queries)
{
#warning TODO make qGuiApp->focusObject() thread safe !!!
diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index 041bd0dc49..2fb54a97c4 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
@@ -114,14 +114,19 @@ public:
jboolean copyURL();
jboolean paste();
+public slots:
+ void updateCursorPosition();
+
private:
QSharedPointer<QInputMethodQueryEvent> focusObjectInputMethodQuery(Qt::InputMethodQueries queries = Qt::ImQueryAll);
void sendInputMethodEvent(QInputMethodEvent *event);
+ Q_INVOKABLE QVariant queryFocusObjectUnsafe(Qt::InputMethodQuery query, QVariant argument);
+ QVariant queryFocusObjectThreadSafe(Qt::InputMethodQuery query, QVariant argument);
+
private slots:
virtual void sendEvent(QObject *receiver, QInputMethodEvent *event);
virtual void sendEvent(QObject *receiver, QInputMethodQueryEvent *event);
- void updateCursorPosition();
private:
ExtractedText m_extractedText;
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
index b85b1157a8..ff49f59076 100644
--- a/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
+++ b/src/plugins/platforms/android/qandroidplatformbackingstore.cpp
@@ -50,11 +50,8 @@ QT_BEGIN_NAMESPACE
QAndroidPlatformBackingStore::QAndroidPlatformBackingStore(QWindow *window)
: QPlatformBackingStore(window)
{
- Q_ASSERT(window->handle());
- if (window->surfaceType() == QSurface::RasterSurface)
- (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->setBackingStore(this);
- else
- qWarning("QAndroidPlatformBackingStore does not support GL windows.");
+ if (window->handle())
+ setBackingStore(window);
}
QPaintDevice *QAndroidPlatformBackingStore::paintDevice()
@@ -64,9 +61,11 @@ QPaintDevice *QAndroidPlatformBackingStore::paintDevice()
void QAndroidPlatformBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
- Q_UNUSED(window);
Q_UNUSED(offset);
+ if (!m_backingStoreSet)
+ setBackingStore(window);
+
(static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->repaint(region);
}
@@ -78,4 +77,14 @@ void QAndroidPlatformBackingStore::resize(const QSize &size, const QRegion &stat
m_image = QImage(size, window()->screen()->handle()->format());
}
+void QAndroidPlatformBackingStore::setBackingStore(QWindow *window)
+{
+ if (window->surfaceType() == QSurface::RasterSurface) {
+ (static_cast<QAndroidPlatformRasterWindow *>(window->handle()))->setBackingStore(this);
+ m_backingStoreSet = true;
+ } else {
+ qWarning("QAndroidPlatformBackingStore does not support GL windows.");
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.h b/src/plugins/platforms/android/qandroidplatformbackingstore.h
index e6ea3dcce0..4c24e129c3 100644
--- a/src/plugins/platforms/android/qandroidplatformbackingstore.h
+++ b/src/plugins/platforms/android/qandroidplatformbackingstore.h
@@ -56,9 +56,10 @@ public:
virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset);
virtual void resize(const QSize &size, const QRegion &staticContents);
const QImage image() { return m_image; }
-
+ void setBackingStore(QWindow *window);
protected:
QImage m_image;
+ bool m_backingStoreSet = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 2cca974b41..9adefd5b2c 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -152,7 +152,8 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
case ThreadedOpenGL:
if (needsWorkaround())
return false;
- // fall through
+ else
+ return true;
default:
return QPlatformIntegration::hasCapability(cap);
}
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index d8cd32255c..a60f4adc28 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -81,7 +81,7 @@ HEADERS += qcocoaintegration.h \
RESOURCES += qcocoaresources.qrc
-LIBS += -framework Cocoa -framework Carbon -framework IOKit
+LIBS += -framework Cocoa -framework Carbon -framework IOKit -lcups
QT += core-private gui-private platformsupport-private
@@ -90,11 +90,13 @@ qtHaveModule(widgets) {
qpaintengine_mac.mm \
qprintengine_mac.mm \
qcocoaprintersupport.mm \
+ qcocoaprintdevice.mm \
HEADERS += \
qpaintengine_mac_p.h \
qprintengine_mac_p.h \
qcocoaprintersupport.h \
+ qcocoaprintdevice.h \
QT += widgets-private printsupport-private
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 1371eb3658..0f99a414a0 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -130,7 +130,7 @@ static void populateRoleMap()
roleMap[QAccessible::Cell] = NSAccessibilityTextFieldRole;
roleMap[QAccessible::PushButton] = NSAccessibilityButtonRole;
roleMap[QAccessible::EditableText] = NSAccessibilityTextFieldRole;
- roleMap[QAccessible::Link] = NSAccessibilityTextFieldRole;
+ roleMap[QAccessible::Link] = NSAccessibilityLinkRole;
roleMap[QAccessible::Indicator] = NSAccessibilityValueIndicatorRole;
roleMap[QAccessible::Splitter] = NSAccessibilitySplitGroupRole;
roleMap[QAccessible::List] = NSAccessibilityListRole;
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 66c7727f15..bc98d002f0 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -91,6 +91,13 @@
// attributes
++ (id) lineNumberForIndex: (int)index forText:(const QString &)text
+{
+ QStringRef textBefore = QStringRef(&text, 0, index);
+ int newlines = textBefore.count(QLatin1Char('\n'));
+ return [NSNumber numberWithInt: newlines];
+}
+
- (NSArray *)accessibilityAttributeNames {
static NSArray *defaultAttributes = nil;
@@ -121,6 +128,19 @@
[attributes addObject : NSAccessibilityValueAttribute];
}
+ if (iface->textInterface()) {
+ [attributes addObjectsFromArray: [[NSArray alloc] initWithObjects:
+ NSAccessibilityNumberOfCharactersAttribute,
+ NSAccessibilitySelectedTextAttribute,
+ NSAccessibilitySelectedTextRangeAttribute,
+ NSAccessibilityVisibleCharacterRangeAttribute,
+ NSAccessibilityInsertionPointLineNumberAttribute,
+ nil
+ ]];
+
+// TODO: multi-selection: NSAccessibilitySelectedTextRangesAttribute,
+ }
+
return [attributes autorelease];
}
@@ -167,23 +187,150 @@
return nil;
return QCocoaAccessible::getValueAttribute(iface);
+
+ } else if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute]) {
+ if (QAccessibleTextInterface *text = iface->textInterface())
+ return [NSNumber numberWithInt: text->characterCount()];
+ return nil;
+ } else if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
+ if (QAccessibleTextInterface *text = iface->textInterface()) {
+ int start = 0;
+ int end = 0;
+ text->selection(0, &start, &end);
+ return text->text(start, end).toNSString();
+ }
+ return nil;
+ } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
+ if (QAccessibleTextInterface *text = iface->textInterface()) {
+ int start = 0;
+ int end = 0;
+ if (text->selectionCount() > 0) {
+ text->selection(0, &start, &end);
+ } else {
+ start = text->cursorPosition();
+ end = start;
+ }
+ return [NSValue valueWithRange:NSMakeRange(quint32(start), quint32(end - start))];
+ }
+ return [NSValue valueWithRange: NSMakeRange(0, 0)];
+ } else if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
+ // FIXME This is not correct and may impact performance for big texts
+ return [NSValue valueWithRange: NSMakeRange(0, iface->textInterface()->characterCount())];
+
+ } else if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute]) {
+ if (QAccessibleTextInterface *text = iface->textInterface()) {
+ QString textBeforeCursor = text->text(0, text->cursorPosition());
+ return [NSNumber numberWithInt: textBeforeCursor.count(QLatin1Char('\n'))];
+ }
+ return nil;
+ }
+
+ return nil;
+}
+
+- (NSArray *)accessibilityParameterizedAttributeNames {
+
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface) {
+ qWarning() << "Called attribute on invalid object: " << axid;
+ return nil;
+ }
+
+ if (iface->textInterface()) {
+ return [[NSArray alloc] initWithObjects:
+ NSAccessibilityStringForRangeParameterizedAttribute,
+ NSAccessibilityLineForIndexParameterizedAttribute,
+ NSAccessibilityRangeForLineParameterizedAttribute,
+ NSAccessibilityRangeForPositionParameterizedAttribute,
+// NSAccessibilityRangeForIndexParameterizedAttribute,
+ NSAccessibilityBoundsForRangeParameterizedAttribute,
+// NSAccessibilityRTFForRangeParameterizedAttribute,
+// NSAccessibilityStyleRangeForIndexParameterizedAttribute,
+ NSAccessibilityAttributedStringForRangeParameterizedAttribute,
+ nil
+ ];
+ }
+
+ return nil;
+}
+
+- (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface) {
+ qWarning() << "Called attribute on invalid object: " << axid;
+ return nil;
}
+ if (!iface->textInterface())
+ return nil;
+
+ if ([attribute isEqualToString: NSAccessibilityStringForRangeParameterizedAttribute]) {
+ NSRange range = [parameter rangeValue];
+ QString text = iface->textInterface()->text(range.location, range.location + range.length);
+ return text.toNSString();
+ }
+ if ([attribute isEqualToString: NSAccessibilityLineForIndexParameterizedAttribute]) {
+ int index = [parameter intValue];
+ NSNumber *ln = [QCocoaAccessibleElement lineNumberForIndex: index forText: iface->text(QAccessible::Value)];
+ return ln;
+ }
+ if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) {
+ int lineNumber = [parameter intValue];
+ QString text = iface->text(QAccessible::Value);
+ int startOffset = 0;
+ // skip newlines until we have the one we look for
+ for (int i = 0; i < lineNumber; ++i)
+ startOffset = text.indexOf(QLatin1Char('\n'), startOffset) + 1;
+ if (startOffset < 0) // invalid line number, return the first line
+ startOffset = 0;
+ int endOffset = text.indexOf(QLatin1Char('\n'), startOffset + 1);
+ if (endOffset == -1)
+ endOffset = text.length();
+ return [NSValue valueWithRange:NSMakeRange(quint32(startOffset), quint32(endOffset - startOffset))];
+ }
+ if ([attribute isEqualToString: NSAccessibilityBoundsForRangeParameterizedAttribute]) {
+ NSRange range = [parameter rangeValue];
+ QRect firstRect = iface->textInterface()->characterRect(range.location);
+ QRect lastRect = iface->textInterface()->characterRect(range.location + range.length);
+ QRect rect = firstRect.united(lastRect); // This is off quite often, but at least a rough approximation
+ return [NSValue valueWithRect: NSMakeRect((CGFloat) rect.x(),(CGFloat) qt_mac_flipYCoordinate(rect.y() + rect.height()), rect.width(), rect.height())];
+ }
+ if ([attribute isEqualToString: NSAccessibilityAttributedStringForRangeParameterizedAttribute]) {
+ NSRange range = [parameter rangeValue];
+ QString text = iface->textInterface()->text(range.location, range.location + range.length);
+ return [[NSAttributedString alloc] initWithString: text.toNSString()];
+ }
return nil;
}
- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface)
+ return nil;
+
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
- return NO; // YES to handle keyboard input
- } else {
- return NO;
+ return iface->state().focusable ? YES : NO;
+ } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
+ return iface->textInterface() ? YES : NO;
}
+ return NO;
}
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute {
- Q_UNUSED(value);
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface)
+ return;
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
-
+ if (QAccessibleActionInterface *action = iface->actionInterface())
+ action->doAction(QAccessibleActionInterface::setFocusAction());
+ } else if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
+ if (QAccessibleTextInterface *text = iface->textInterface()) {
+ NSRange range = [value rangeValue];
+ if (range.length > 0)
+ text->setSelection(0, range.location, range.location + range.length);
+ else
+ text->setCursorPosition(range.location);
+ }
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 327ca00ad6..f8411845dc 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -223,8 +223,9 @@ static void cleanupCocoaApplicationDelegate()
// events while the event loop is still running.
const QWindowList topLevels = QGuiApplication::topLevelWindows();
for (int i = 0; i < topLevels.size(); ++i) {
- topLevels.at(i)->close();
+ QWindowSystemInterface::handleCloseEvent(topLevels.at(i));
}
+ QWindowSystemInterface::flushWindowSystemEvents();
QGuiApplication::exit(0);
startedQuit = false;
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h
index ce8ebbc79e..a33373c4c1 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.h
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h
@@ -59,6 +59,7 @@ public:
QPaintDevice *paintDevice();
void flush(QWindow *widget, const QRegion &region, const QPoint &offset);
+ QImage toImage() const Q_DECL_OVERRIDE;
void resize (const QSize &size, const QRegion &);
bool scroll(const QRegion &area, int dx, int dy);
CGImageRef getBackingStoreCGImage();
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index 3ca611b537..d76645c668 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -59,25 +59,20 @@ QCocoaBackingStore::~QCocoaBackingStore()
QPaintDevice *QCocoaBackingStore::paintDevice()
{
- if (m_qImage.size() / m_qImage.devicePixelRatio() != m_requestedSize) {
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
+ int windowDevicePixelRatio = int(cocoaWindow->devicePixelRatio());
+
+ // Receate the backing store buffer if the effective buffer size has changed,
+ // either due to a window resize or devicePixelRatio change.
+ QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio;
+ if (m_qImage.size() != effectiveBufferSize) {
CGImageRelease(m_cgImage);
m_cgImage = 0;
- int scaleFactor = 1;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
- if (cocoaWindow && cocoaWindow->m_contentView && [cocoaWindow->m_contentView window]) {
- scaleFactor = int([[cocoaWindow->m_contentView window] backingScaleFactor]);
- }
- }
-#endif
-
- QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient)
? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32;
- m_qImage = QImage(m_requestedSize * scaleFactor, format);
- m_qImage.setDevicePixelRatio(scaleFactor);
+ m_qImage = QImage(effectiveBufferSize, format);
+ m_qImage.setDevicePixelRatio(windowDevicePixelRatio);
if (format == QImage::Format_ARGB32_Premultiplied)
m_qImage.fill(Qt::transparent);
}
@@ -101,6 +96,11 @@ void QCocoaBackingStore::flush(QWindow *win, const QRegion &region, const QPoint
}
}
+QImage QCocoaBackingStore::toImage() const
+{
+ return m_qImage;
+}
+
void QCocoaBackingStore::resize(const QSize &size, const QRegion &)
{
m_requestedSize = size;
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index 13f6423701..592bfc8e50 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -308,8 +308,22 @@ NSCursor *QCocoaCursor::createCursorFromBitmap(const QBitmap *bitmap, const QBit
NSCursor *QCocoaCursor::createCursorFromPixmap(const QPixmap pixmap, const QPoint hotspot)
{
- NSPoint hotSpot = NSMakePoint(hotspot.x(), hotspot.y());
- NSImage *nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
+ NSPoint hotSpot = NSMakePoint(hotspot.x() / pixmap.devicePixelRatio(),
+ hotspot.y() / pixmap.devicePixelRatio());
+ NSImage *nsimage;
+ if (pixmap.devicePixelRatio() > 1.0) {
+ QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio();
+ QPixmap scaledPixmap = pixmap.scaled(layoutSize);
+ nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(scaledPixmap));
+ CGImageRef cgImage = qt_mac_toCGImage(pixmap.toImage());
+ NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithCGImage:cgImage];
+ [nsimage addRepresentation:imageRep];
+ [imageRep release];
+ CGImageRelease(cgImage);
+ } else {
+ nsimage = static_cast<NSImage *>(qt_mac_create_nsimage(pixmap));
+ }
+
NSCursor *nsCursor = [[NSCursor alloc] initWithImage:nsimage hotSpot: hotSpot];
[nsimage release];
return nsCursor;
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 9b4d8fd96f..3f61bd81ee 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -194,7 +194,7 @@ void QCocoaGLContext::swapBuffers(QPlatformSurface *surface)
bool QCocoaGLContext::makeCurrent(QPlatformSurface *surface)
{
- Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
+ Q_ASSERT(surface->surface()->supportsOpenGL());
QCocoaAutoReleasePool pool;
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 8975605e5c..a73944c07c 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -102,21 +102,31 @@ CGImageRef qt_mac_toCGImage(const QImage &inImage)
uint cgflags = kCGImageAlphaNone;
switch (image.format()) {
case QImage::Format_ARGB32_Premultiplied:
- cgflags = kCGImageAlphaPremultipliedFirst;
+ cgflags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_ARGB32:
- cgflags = kCGImageAlphaFirst;
+ cgflags = kCGImageAlphaFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB32:
- cgflags = kCGImageAlphaNoneSkipFirst;
+ cgflags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host;
break;
case QImage::Format_RGB888:
- cgflags |= kCGImageAlphaNone;
- break;
+ cgflags = kCGImageAlphaNone | kCGBitmapByteOrder32Big;
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ cgflags = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
+ break;
+ case QImage::Format_RGBA8888:
+ cgflags = kCGImageAlphaLast | kCGBitmapByteOrder32Big;
+ break;
+ case QImage::Format_RGBX8888:
+ cgflags = kCGImageAlphaNoneSkipLast | kCGBitmapByteOrder32Big;
+ break;
default:
+ Q_ASSERT(false); // Should never be reached.
break;
}
- cgflags |= kCGBitmapByteOrder32Host;
+
QCFType<CGDataProviderRef> dataProvider = qt_mac_CGDataProvider(image);
return CGImageCreate(image.width(), image.height(), 8, 32,
image.bytesPerLine(),
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index b1b73e5f08..24adc7a95b 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -129,6 +129,7 @@ public:
QCocoaServices *services() const;
QVariant styleHint(StyleHint hint) const;
+ Qt::KeyboardModifiers queryKeyboardModifiers() const;
QList<int> possibleKeys(const QKeyEvent *event) const;
void updateScreens();
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 1892a5b6bf..65a9f87e2d 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -375,6 +375,7 @@ bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
case WindowMasks:
case MultipleWindows:
case ForeignWindows:
+ case RasterGLSurface:
return true;
default:
return QPlatformIntegration::hasCapability(cap);
@@ -464,6 +465,11 @@ QVariant QCocoaIntegration::styleHint(StyleHint hint) const
return QPlatformIntegration::styleHint(hint);
}
+Qt::KeyboardModifiers QCocoaIntegration::queryKeyboardModifiers() const
+{
+ return QCocoaKeyMapper::queryKeyboardModifiers();
+}
+
QList<int> QCocoaIntegration::possibleKeys(const QKeyEvent *event) const
{
return mKeyboardMapper->possibleKeys(event);
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.h b/src/plugins/platforms/cocoa/qcocoakeymapper.h
index 0629de9317..4f419b3651 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.h
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.h
@@ -83,6 +83,7 @@ class QCocoaKeyMapper
public:
QCocoaKeyMapper();
~QCocoaKeyMapper();
+ static Qt::KeyboardModifiers queryKeyboardModifiers();
QList<int> possibleKeys(const QKeyEvent *event) const;
bool updateKeyboard();
void deleteLayouts();
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
index 0745cc2254..e46eaff6be 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
@@ -346,6 +346,11 @@ QCocoaKeyMapper::~QCocoaKeyMapper()
deleteLayouts();
}
+Qt::KeyboardModifiers QCocoaKeyMapper::queryKeyboardModifiers()
+{
+ return qt_mac_get_modifiers(GetCurrentEventKeyModifiers());
+}
+
bool QCocoaKeyMapper::updateKeyboard()
{
const UCKeyboardLayout *uchrData = 0;
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 329c7a264a..35e8fdebb4 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -127,6 +127,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
{
QCocoaMenuItem *cocoaItem = reinterpret_cast<QCocoaMenuItem *>([item tag]);
QScopedLoopLevelCounter loopLevelCounter(QGuiApplicationPrivate::instance()->threadData);
+ QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers:[NSEvent modifierFlags]];
cocoaItem->activated();
}
@@ -268,7 +269,7 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before);
- menuItem->setParent(this);
+ SET_COCOA_MENU_ANCESTOR(menuItem, this);
cocoaItem->sync();
if (beforeItem) {
int index = m_menuItems.indexOf(beforeItem);
@@ -325,8 +326,8 @@ void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
return;
}
- if (menuItem->parent() == this)
- menuItem->setParent(0);
+ if (COCOA_MENU_ANCESTOR(menuItem) == this)
+ SET_COCOA_MENU_ANCESTOR(menuItem, 0);
m_menuItems.removeOne(cocoaItem);
if (!cocoaItem->isMerged()) {
@@ -550,7 +551,7 @@ void QCocoaMenu::syncModalState(bool modal)
void QCocoaMenu::setMenuBar(QCocoaMenuBar *menuBar)
{
m_menuBar = menuBar;
- setParent(menuBar);
+ SET_COCOA_MENU_ANCESTOR(this, menuBar);
}
QCocoaMenuBar *QCocoaMenu::menuBar() const
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index 1e69ed5a4b..b0169b9746 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -118,6 +118,9 @@ private:
quintptr m_tag;
};
+#define COCOA_MENU_ANCESTOR(m) ((m)->property("_qCocoaMenuAncestor").value<QObject *>())
+#define SET_COCOA_MENU_ANCESTOR(m, ancestor) (m)->setProperty("_qCocoaMenuAncestor", QVariant::fromValue<QObject *>(ancestor))
+
QT_END_NAMESPACE
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 3bba1ee1d5..2246d2ce46 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -126,13 +126,13 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
{
if (menu == m_menu)
return;
- if (m_menu && m_menu->parent() == this)
- m_menu->setParent(0);
+ if (m_menu && COCOA_MENU_ANCESTOR(m_menu) == this)
+ SET_COCOA_MENU_ANCESTOR(m_menu, 0);
QCocoaAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) {
- m_menu->setParent(this);
+ SET_COCOA_MENU_ANCESTOR(m_menu, this);
} else {
// we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one
@@ -217,12 +217,12 @@ NSMenuItem *QCocoaMenuItem::sync()
mergeItem = [loader preferencesMenuItem];
break;
case TextHeuristicRole: {
- QObject *p = parent();
+ QObject *p = COCOA_MENU_ANCESTOR(this);
int depth = 1;
QCocoaMenuBar *menubar = 0;
while (depth < 3 && p && !(menubar = qobject_cast<QCocoaMenuBar *>(p))) {
++depth;
- p = p->parent();
+ p = COCOA_MENU_ANCESTOR(p);
}
if (depth == 3 || !menubar)
break; // Menu item too deep in the hierarchy, or not connected to any menubar
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index bf7e85619a..efdd433d8f 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -136,10 +136,19 @@ private:
// Request a unified title and toolbar look for the window.
static void setContentBorderThickness(QWindow *window, int topThickness, int bottomThickness);
+ // Request a unified title and toolbar look for the window by registering
+ // an area. Multiple callers can register areas and the platform plugin
+ // will extend the "unified" area to cover them.
+ static void registerContentBorderArea(QWindow *window, quintptr identifer, int upper, int lower);
+
+ // Enable the unified title and toolbar area.
+ static void enableContentBorderArea(QWindow *window, bool enable);
+
// Sets a NSToolbar instance for the given QWindow. The
// toolbar will be attached to the native NSWindow when
// that is created;
static void setNSToolbar(QWindow *window, void *nsToolbar);
+
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 5e57200ebc..d6a5be8d52 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -125,6 +125,10 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setEmbeddedInForeignView);
if (resource.toLower() == "setcontentborderthickness")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness);
+ if (resource.toLower() == "registercontentborderarea")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerContentBorderArea);
+ if (resource.toLower() == "enablecontentborderarea")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::enableContentBorderArea);
if (resource.toLower() == "setnstoolbar")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar);
@@ -287,11 +291,28 @@ void QCocoaNativeInterface::setContentBorderThickness(QWindow *window, int topTh
cocoaWindow->setContentBorderThickness(topThickness, bottomThickness);
}
-void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
+void QCocoaNativeInterface::registerContentBorderArea(QWindow *window, quintptr identifier, int upper, int lower)
{
if (!window)
return;
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->registerContentBorderArea(identifier, upper, lower);
+}
+
+void QCocoaNativeInterface::enableContentBorderArea(QWindow *window, bool enable)
+{
+ if (!window)
+ return;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->enableContentBorderArea(enable);
+}
+
+void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
+{
QCocoaIntegration::instance()->setToolbar(window, static_cast<NSToolbar *>(nsToolbar));
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.h b/src/plugins/platforms/cocoa/qcocoaprintdevice.h
new file mode 100644
index 0000000000..30a2155bc7
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOCOAPRINTDEVICE_H
+#define QCOCOAPRINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpa/qplatformprintdevice.h>
+
+#ifndef QT_NO_PRINTER
+
+#include "qt_mac_p.h"
+
+#include <cups/ppd.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCocoaPrintDevice : public QPlatformPrintDevice
+{
+public:
+ QCocoaPrintDevice();
+ explicit QCocoaPrintDevice(const QString &id);
+ QCocoaPrintDevice(const QCocoaPrintDevice &other);
+ virtual ~QCocoaPrintDevice();
+
+ QCocoaPrintDevice *clone();
+
+ bool operator==(const QCocoaPrintDevice &other) const;
+
+ bool isValid() const Q_DECL_OVERRIDE;
+ bool isDefault() const Q_DECL_OVERRIDE;
+
+ QPrint::DeviceState state() const Q_DECL_OVERRIDE;
+
+ QPageSize defaultPageSize() const Q_DECL_OVERRIDE;
+
+ QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ int resolution) const Q_DECL_OVERRIDE;
+
+ int defaultResolution() const Q_DECL_OVERRIDE;
+
+ QPrint::InputSlot defaultInputSlot() const Q_DECL_OVERRIDE;
+
+ QPrint::OutputBin defaultOutputBin() const Q_DECL_OVERRIDE;
+
+ QPrint::DuplexMode defaultDuplexMode() const Q_DECL_OVERRIDE;
+
+ QPrint::ColorMode defaultColorMode() const Q_DECL_OVERRIDE;
+
+ PMPrinter macPrinter() const;
+ PMPaper macPaper(const QPageSize &pageSize) const;
+
+protected:
+ void loadPageSizes() const Q_DECL_OVERRIDE;
+ void loadResolutions() const Q_DECL_OVERRIDE;
+ void loadInputSlots() const Q_DECL_OVERRIDE;
+ void loadOutputBins() const Q_DECL_OVERRIDE;
+ void loadDuplexModes() const Q_DECL_OVERRIDE;
+ void loadColorModes() const Q_DECL_OVERRIDE;
+ void loadMimeTypes() const Q_DECL_OVERRIDE;
+
+private:
+ QPageSize createPageSize(const PMPaper &paper) const;
+ bool openPpdFile();
+
+ // Mac Core Printing
+ PMPrinter m_printer;
+ PMPrintSession m_session;
+ mutable QHash<QString, PMPaper> m_macPapers;
+
+ // PPD File
+ ppd_file_t *m_ppd;
+
+ QMarginsF m_customMargins;
+ mutable QHash<QString, QMarginsF> m_printableMargins;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+#endif // QCOCOAPRINTDEVICE_H
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
new file mode 100644
index 0000000000..3061e84470
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
@@ -0,0 +1,502 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoaprintdevice.h"
+
+#include <QtCore/qmimedatabase.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+static QPrint::DuplexMode macToDuplexMode(const PMDuplexMode &mode)
+{
+ if (mode == kPMDuplexTumble)
+ return QPrint::DuplexShortSide;
+ else if (mode == kPMDuplexNoTumble)
+ return QPrint::DuplexLongSide;
+ else // kPMDuplexNone or kPMSimplexTumble
+ return QPrint::DuplexNone;
+}
+
+QCocoaPrintDevice::QCocoaPrintDevice()
+ : QPlatformPrintDevice(),
+ m_printer(0),
+ m_session(0),
+ m_ppd(0)
+{
+}
+
+QCocoaPrintDevice::QCocoaPrintDevice(const QString &id)
+ : QPlatformPrintDevice(id),
+ m_printer(0),
+ m_session(0),
+ m_ppd(0)
+{
+ if (!id.isEmpty()) {
+ m_printer = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(id));
+ if (m_printer) {
+ m_name = QCFString::toQString(PMPrinterGetName(m_printer));
+ m_location = QCFString::toQString(PMPrinterGetLocation(m_printer));
+ CFStringRef cfMakeAndModel;
+ if (PMPrinterGetMakeAndModelName(m_printer, &cfMakeAndModel) == noErr)
+ m_makeAndModel = QCFString::toQString(cfMakeAndModel);
+ Boolean isRemote;
+ if (PMPrinterIsRemote(m_printer, &isRemote) == noErr)
+ m_isRemote = isRemote;
+ if (PMCreateSession(&m_session) == noErr)
+ PMSessionSetCurrentPMPrinter(m_session, m_printer);
+
+ // No native api to query these options, need to use PPD directly, note is deprecated from 1.6 onwards
+ if (openPpdFile()) {
+ // Note this is if the hardware does multiple copies, not if Cups can
+ m_supportsMultipleCopies = !m_ppd->manual_copies;
+ // Note this is if the hardware does collation, not if Cups can
+ ppd_option_t *collate = ppdFindOption(m_ppd, "Collate");
+ if (collate)
+ m_supportsCollateCopies = true;
+ m_supportsCustomPageSizes = m_ppd->custom_max[0] > 0 && m_ppd->custom_max[1] > 0;
+ 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]);
+ }
+ }
+ }
+}
+
+QCocoaPrintDevice::QCocoaPrintDevice(const QCocoaPrintDevice &other)
+ : QPlatformPrintDevice(other),
+ m_printer(0),
+ m_session(0),
+ m_ppd(0)
+{
+ m_printer = other.m_printer;
+ PMRetain(m_printer);
+ m_session = other.m_session;
+ PMRetain(m_session);
+ m_macPapers = other.m_macPapers;
+ foreach (PMPaper paper, m_macPapers.values())
+ PMRetain(paper);
+ openPpdFile();
+ m_customMargins = other.m_customMargins;
+ m_printableMargins = other.m_printableMargins;
+}
+
+QCocoaPrintDevice::~QCocoaPrintDevice()
+{
+ if (m_ppd)
+ ppdClose(m_ppd);
+ foreach (PMPaper paper, m_macPapers.values())
+ PMRelease(paper);
+ // Releasing the session appears to also release the printer
+ if (m_session)
+ PMRelease(m_session);
+ else if (m_printer)
+ PMRelease(m_printer);
+}
+
+QCocoaPrintDevice *QCocoaPrintDevice::clone()
+{
+ return new QCocoaPrintDevice(*this);
+}
+
+bool QCocoaPrintDevice::operator==(const QCocoaPrintDevice &other) const
+{
+ return (m_id == other.m_id);
+}
+
+bool QCocoaPrintDevice::isValid() const
+{
+ return m_printer ? true : false;
+}
+
+bool QCocoaPrintDevice::isDefault() const
+{
+ return PMPrinterIsDefault(m_printer);
+}
+
+QPrint::DeviceState QCocoaPrintDevice::state() const
+{
+ PMPrinterState state;
+ if (PMPrinterGetState(m_printer, &state) == noErr) {
+ if (state == kPMPrinterIdle)
+ return QPrint::Idle;
+ else if (state == kPMPrinterProcessing)
+ return QPrint::Active;
+ else if (state == kPMPrinterStopped)
+ return QPrint::Error;
+ }
+ return QPrint::Error;
+}
+
+QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const
+{
+ QCFString key;
+ double width;
+ double height;
+ QCFString localizedName;
+ if (PMPaperGetPPDPaperName(paper, &key) == noErr
+ && PMPaperGetWidth(paper, &width) == noErr
+ && PMPaperGetHeight(paper, &height) == noErr
+ && PMPaperCreateLocalizedName(paper, m_printer, &localizedName) == noErr) {
+ return(QPlatformPrintDevice::createPageSize(key, QSize(width, height), localizedName));
+ }
+ return QPageSize();
+}
+
+void QCocoaPrintDevice::loadPageSizes() const
+{
+ m_pageSizes.clear();
+ foreach (PMPaper paper, m_macPapers.values())
+ PMRelease(paper);
+ m_macPapers.clear();
+ m_printableMargins.clear();
+ CFArrayRef paperSizes;
+ if (PMPrinterGetPaperList(m_printer, &paperSizes) == noErr) {
+ int count = CFArrayGetCount(paperSizes);
+ for (int i = 0; i < count; ++i) {
+ PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(paperSizes, i)));
+ QPageSize pageSize = createPageSize(paper);
+ if (pageSize.isValid()) {
+ m_pageSizes.append(pageSize);
+ PMRetain(paper);
+ m_macPapers.insert(pageSize.key(), paper);
+ PMPaperMargins printMargins;
+ PMPaperGetMargins(paper, &printMargins);
+ m_printableMargins.insert(pageSize.key(), QMarginsF(printMargins.left, printMargins.top,
+ printMargins.right, printMargins.bottom));
+ }
+ }
+ }
+ m_havePageSizes = true;
+}
+
+QPageSize QCocoaPrintDevice::defaultPageSize() const
+{
+ QPageSize pageSize;
+ PMPageFormat pageFormat;
+ PMPaper paper;
+ if (PMCreatePageFormat(&pageFormat) == noErr
+ && PMSessionDefaultPageFormat(m_session, pageFormat) == noErr
+ && PMGetPageFormatPaper(pageFormat, &paper) == noErr) {
+ pageSize = createPageSize(paper);
+ PMRelease(pageFormat);
+ }
+ return pageSize;
+}
+
+QMarginsF QCocoaPrintDevice::printableMargins(const QPageSize &pageSize,
+ QPageLayout::Orientation orientation,
+ int resolution) const
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(resolution)
+ if (!m_havePageSizes)
+ loadPageSizes();
+ if (m_printableMargins.contains(pageSize.key()))
+ return m_printableMargins.value(pageSize.key());
+ return m_customMargins;
+}
+
+void QCocoaPrintDevice::loadResolutions() const
+{
+ m_resolutions.clear();
+ UInt32 count;
+ if (PMPrinterGetPrinterResolutionCount(m_printer, &count) == noErr) {
+ // 1-based index
+ for (UInt32 i = 1; i <= count; ++i) {
+ PMResolution resolution;
+ if (PMPrinterGetIndexedPrinterResolution(m_printer, i, &resolution) == noErr)
+ m_resolutions.append(int(resolution.hRes));
+ }
+ }
+ m_haveResolutions = true;
+}
+
+int QCocoaPrintDevice::defaultResolution() const
+{
+ int defaultResolution = 72;
+ PMPrintSettings settings;
+ if (PMCreatePrintSettings(&settings) == noErr) {
+ PMResolution resolution;
+ if (PMSessionDefaultPrintSettings(m_session, settings) == noErr
+ && PMPrinterGetOutputResolution(m_printer, settings, &resolution) == noErr) {
+ // PMPrinterGetOutputResolution usually fails with -9589 kPMKeyNotFound as not set in PPD
+ defaultResolution = int(resolution.hRes);
+ }
+ PMRelease(settings);
+ }
+ // If no value returned (usually means not set in PPD) then use supported resolutions which
+ // OSX will have populated with at least one default value (but why not returned by call?)
+ if (defaultResolution <= 0) {
+ if (!m_haveResolutions)
+ loadResolutions();
+ if (m_resolutions.count() > 0)
+ return m_resolutions.at(0); // First value or highest? Only likely to be one anyway.
+ return 72; // TDOD More sensible default value???
+ }
+ return defaultResolution;
+}
+
+void QCocoaPrintDevice::loadInputSlots() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // TODO Deal with concatenated names like Tray1Manual or Tray1_Man,
+ // will currently show as CustomInputSlot
+ // TODO Deal with separate ManualFeed key
+ // Try load standard PPD options first
+ m_inputSlots.clear();
+ if (m_ppd) {
+ ppd_option_t *inputSlots = ppdFindOption(m_ppd, "InputSlot");
+ if (inputSlots) {
+ for (int i = 0; i < inputSlots->num_choices; ++i)
+ m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i]));
+ }
+ // If no result, try just the default
+ if (m_inputSlots.size() == 0) {
+ inputSlots = ppdFindOption(m_ppd, "DefaultInputSlot");
+ if (inputSlots)
+ m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[0]));
+ }
+ }
+ // If still no result, just use Auto
+ if (m_inputSlots.size() == 0)
+ m_inputSlots.append(QPlatformPrintDevice::defaultInputSlot());
+ m_haveInputSlots = true;
+}
+
+QPrint::InputSlot QCocoaPrintDevice::defaultInputSlot() const
+{
+ // No native api to query, use PPD directly
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *inputSlot = ppdFindOption(m_ppd, "DefaultInputSlot");
+ if (inputSlot)
+ return QPrintUtils::ppdChoiceToInputSlot(inputSlot->choices[0]);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "InputSlot");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToInputSlot(*defaultChoice);
+ }
+ // Otherwise return Auto
+ return QPlatformPrintDevice::defaultInputSlot();
+}
+
+void QCocoaPrintDevice::loadOutputBins() const
+{
+ // No native api to query, use PPD directly
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ m_outputBins.clear();
+ if (m_ppd) {
+ ppd_option_t *outputBins = ppdFindOption(m_ppd, "OutputBin");
+ if (outputBins) {
+ for (int i = 0; i < outputBins->num_choices; ++i)
+ m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i]));
+ }
+ // If no result, try just the default
+ if (m_outputBins.size() == 0) {
+ outputBins = ppdFindOption(m_ppd, "DefaultOutputBin");
+ if (outputBins)
+ m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[0]));
+ }
+ }
+ // If still no result, just use Auto
+ if (m_outputBins.size() == 0)
+ m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
+ m_haveOutputBins = true;
+}
+
+QPrint::OutputBin QCocoaPrintDevice::defaultOutputBin() const
+{
+ // No native api to query, use PPD directly
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *outputBin = ppdFindOption(m_ppd, "DefaultOutputBin");
+ if (outputBin)
+ return QPrintUtils::ppdChoiceToOutputBin(outputBin->choices[0]);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "OutputBin");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToOutputBin(*defaultChoice);
+ }
+ // Otherwise return AutoBin
+ return QPlatformPrintDevice::defaultOutputBin();
+}
+
+void QCocoaPrintDevice::loadDuplexModes() const
+{
+ // No native api to query, use PPD directly
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD options first
+ m_duplexModes.clear();
+ if (m_ppd) {
+ ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex");
+ if (duplexModes) {
+ for (int i = 0; i < duplexModes->num_choices; ++i)
+ 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)
+ m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice));
+ }
+ }
+ // If still no result, or not added in PPD, then add None
+ if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone))
+ m_duplexModes.append(QPrint::DuplexNone);
+ m_haveDuplexModes = true;
+}
+
+QPrint::DuplexMode QCocoaPrintDevice::defaultDuplexMode() const
+{
+ QPrint::DuplexMode defaultMode = QPrint::DuplexNone;
+ PMPrintSettings settings;
+ if (PMCreatePrintSettings(&settings) == noErr) {
+ PMDuplexMode duplexMode;
+ if (PMSessionDefaultPrintSettings(m_session, settings) == noErr
+ && PMGetDuplex(settings, &duplexMode) == noErr) {
+ defaultMode = macToDuplexMode(duplexMode);
+ }
+ PMRelease(settings);
+ }
+ return defaultMode;
+}
+
+void QCocoaPrintDevice::loadColorModes() const
+{
+ // No native api to query, use PPD directly
+ m_colorModes.clear();
+ m_colorModes.append(QPrint::GrayScale);
+ if (!m_ppd || (m_ppd && m_ppd->color_device))
+ m_colorModes.append(QPrint::Color);
+ m_haveColorModes = true;
+}
+
+QPrint::ColorMode QCocoaPrintDevice::defaultColorMode() const
+{
+ // No native api to query, use PPD directly
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Not a proper option, usually only know if supports color or not, but some
+ // users known to abuse ColorModel to always force GrayScale.
+ if (m_ppd && supportedColorModes().contains(QPrint::Color)) {
+ ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel");
+ if (!colorModel)
+ colorModel = ppdFindOption(m_ppd, "ColorModel");
+ if (!colorModel || (colorModel && !qstrcmp(colorModel->defchoice, "Gray")))
+ return QPrint::Color;
+ }
+ return QPrint::GrayScale;
+}
+
+void QCocoaPrintDevice::loadMimeTypes() const
+{
+ // TODO Check how settings affect returned list
+ m_mimeTypes.clear();
+ QMimeDatabase db;
+ PMPrintSettings settings;
+ if (PMCreatePrintSettings(&settings) == noErr) {
+ CFArrayRef mimeTypes;
+ if (PMPrinterGetMimeTypes(m_printer, settings, &mimeTypes) == noErr) {
+ int count = CFArrayGetCount(mimeTypes);
+ for (int i = 0; i < count; ++i) {
+ CFStringRef mimeName = static_cast<CFStringRef>(const_cast<void *>(CFArrayGetValueAtIndex(mimeTypes, i)));
+ QMimeType mimeType = db.mimeTypeForName(QCFString::toQString(mimeName));
+ if (mimeType.isValid())
+ m_mimeTypes.append(mimeType);
+ }
+ }
+ PMRelease(settings);
+ }
+ m_haveMimeTypes = true;
+}
+
+bool QCocoaPrintDevice::openPpdFile()
+{
+ if (m_ppd)
+ ppdClose(m_ppd);
+ m_ppd = 0;
+ CFURLRef ppdURL = NULL;
+ char ppdPath[MAXPATHLEN];
+ if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr
+ && ppdURL != NULL
+ && CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath))) {
+ m_ppd = ppdOpenFile(ppdPath);
+ }
+ CFRelease(ppdURL);
+ return m_ppd ? true : false;
+}
+
+PMPrinter QCocoaPrintDevice::macPrinter() const
+{
+ return m_printer;
+}
+
+// Returns a cached printer PMPaper, or creates and caches a new custom PMPaper
+// Caller should never release a cached PMPaper!
+PMPaper QCocoaPrintDevice::macPaper(const QPageSize &pageSize) const
+{
+ if (!m_havePageSizes)
+ loadPageSizes();
+ // If keys match, then is a supported size or an existing custom size
+ 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;
+ PMPaperMargins paperMargins;
+ paperMargins.left = m_customMargins.left();
+ paperMargins.right = m_customMargins.right();
+ paperMargins.top = m_customMargins.top();
+ paperMargins.bottom = m_customMargins.bottom();
+ PMPaperCreateCustom(m_printer, QCFString(pageSize.key()), QCFString(pageSize.name()),
+ pageSize.sizePoints().width(), pageSize.sizePoints().height(),
+ &paperMargins, &paper);
+ m_macPapers.insert(pageSize.key(), paper);
+ return paper;
+}
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaprintersupport.h b/src/plugins/platforms/cocoa/qcocoaprintersupport.h
index a48790ef34..61c1bfd3ec 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintersupport.h
+++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.h
@@ -55,14 +55,10 @@ public:
QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE;
QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE;
- QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const Q_DECL_OVERRIDE;
- QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &) const Q_DECL_OVERRIDE;
- QList<QPrinterInfo> availablePrinters() Q_DECL_OVERRIDE;
- QPrinterInfo printerInfo(const QString &printerName) Q_DECL_OVERRIDE;
-
-private:
- QPrinterInfo printerInfoFromPMPrinter(const PMPrinter &printer);
+ QPrintDevice createPrintDevice(const QString &id) Q_DECL_OVERRIDE;
+ QStringList availablePrintDeviceIds() const Q_DECL_OVERRIDE;
+ QString defaultPrintDeviceId() const Q_DECL_OVERRIDE;
};
#endif // QT_NO_PRINTER
diff --git a/src/plugins/platforms/cocoa/qcocoaprintersupport.mm b/src/plugins/platforms/cocoa/qcocoaprintersupport.mm
index cb2aa7132b..5853135dfb 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintersupport.mm
+++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.mm
@@ -42,10 +42,10 @@
#include "qcocoaprintersupport.h"
#ifndef QT_NO_PRINTER
+
+#include "qcocoaprintdevice.h"
#include "qprintengine_mac_p.h"
-#include <QtPrintSupport/QPrinter>
-#include <QtPrintSupport/QPrinterInfo>
#include <private/qprinterinfo_p.h>
QCocoaPrinterSupport::QCocoaPrinterSupport()
@@ -69,107 +69,37 @@ QPaintEngine *QCocoaPrinterSupport::createPaintEngine(QPrintEngine *printEngine,
return static_cast<QMacPrintEngine *>(printEngine);
}
-QList<QPrinter::PaperSize> QCocoaPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const
+QPrintDevice QCocoaPrinterSupport::createPrintDevice(const QString &id)
{
- QList<QPrinter::PaperSize> returnValue;
- if (printerInfo.isNull())
- return returnValue;
-
- PMPrinter printer = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(printerInfo.printerName()));
- if (!printer)
- return returnValue;
-
- CFArrayRef array;
- if (PMPrinterGetPaperList(printer, &array) != noErr) {
- PMRelease(printer);
- return returnValue;
- }
-
- CFIndex count = CFArrayGetCount(array);
- for (CFIndex i = 0; i < count; ++i) {
- PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(array, i)));
- double width, height;
- if (PMPaperGetWidth(paper, &width) == noErr
- && PMPaperGetHeight(paper, &height) == noErr) {
- // width and height are in points, convertQSizeFToPaperSize() expects millimeters
- static const double OnePointInMillimeters = 1.0 / 72.0 * 25.4;
- QSizeF size(width * OnePointInMillimeters, height * OnePointInMillimeters);
- returnValue += QPlatformPrinterSupport::convertQSizeFToPaperSize(size);
- }
- }
-
- PMRelease(printer);
-
- return returnValue;
+ return QPlatformPrinterSupport::createPrintDevice(new QCocoaPrintDevice(id));
}
-QList<QPrinterInfo> QCocoaPrinterSupport::availablePrinters()
+QStringList QCocoaPrinterSupport::availablePrintDeviceIds() const
{
- QList<QPrinterInfo> returnValue;
+ QStringList list;
QCFType<CFArrayRef> printerList;
if (PMServerCreatePrinterList(kPMServerLocal, &printerList) == noErr) {
CFIndex count = CFArrayGetCount(printerList);
for (CFIndex i = 0; i < count; ++i) {
PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i)));
- returnValue += printerInfoFromPMPrinter(printer);
+ list.append(QCFString::toQString(PMPrinterGetID(printer)));
}
}
- return returnValue;
-}
-
-QPrinterInfo QCocoaPrinterSupport::printerInfo(const QString &printerName)
-{
- PMPrinter printer = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(printerName));
- QPrinterInfo pi = printerInfoFromPMPrinter(printer);
- PMRelease(printer);
- return pi;
-}
-
-QPrinterInfo QCocoaPrinterSupport::printerInfoFromPMPrinter(const PMPrinter &printer)
-{
- if (!printer)
- return QPrinterInfo();
-
- QString name = QCFString::toQString(PMPrinterGetID(printer));
- QString description = QCFString::toQString(PMPrinterGetName(printer));
- QString location = QCFString::toQString(PMPrinterGetLocation(printer));
- CFStringRef cfMakeAndModel;
- PMPrinterGetMakeAndModelName(printer, &cfMakeAndModel);
- QString makeAndModel = QCFString::toQString(cfMakeAndModel);
- bool isDefault = PMPrinterIsDefault(printer);
-
- return createPrinterInfo(name, description, location, makeAndModel, isDefault, 0);
+ return list;
}
-QList<QPair<QString, QSizeF> > QCocoaPrinterSupport::supportedSizesWithNames(const QPrinterInfo &printerInfo) const
+QString QCocoaPrinterSupport::defaultPrintDeviceId() const
{
- QList<QPair<QString, QSizeF> > returnValue;
- if (printerInfo.isNull())
- return returnValue;
-
- PMPrinter printer = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(printerInfo.printerName()));
- if (!printer)
- return returnValue;
-
- CFArrayRef array;
- if (PMPrinterGetPaperList(printer, &array) != noErr) {
- PMRelease(printer);
- return returnValue;
- }
-
- int count = CFArrayGetCount(array);
- for (int i = 0; i < count; ++i) {
- PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(array, i)));
- double width, height;
- if (PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr) {
- static const double OnePointInMillimeters = 1.0 / 72.0 * 25.4;
- QCFString paperName;
- if (PMPaperCreateLocalizedName(paper, printer, &paperName) == noErr)
- returnValue.append(qMakePair(QString(paperName), QSizeF(width * OnePointInMillimeters, height * OnePointInMillimeters)));
+ QCFType<CFArrayRef> printerList;
+ if (PMServerCreatePrinterList(kPMServerLocal, &printerList) == noErr) {
+ CFIndex count = CFArrayGetCount(printerList);
+ for (CFIndex i = 0; i < count; ++i) {
+ PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i)));
+ if (PMPrinterIsDefault(printer))
+ return QCFString::toQString(PMPrinterGetID(printer));
}
}
- PMRelease(printer);
- return returnValue;
+ return QString();
}
#endif //QT_NO_PRINTER
diff --git a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
index 1c08d4bcb7..f18be8b69c 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemsettings.mm
@@ -161,7 +161,7 @@ static QMacPaletteMap mac_widget_colors[] = {
QMacPaletteMap(QPlatformTheme::HeaderPalette, kThemeTextColorPushButtonActive, kThemeTextColorPushButtonInactive),
QMacPaletteMap(QPlatformTheme::ComboBoxPalette, kThemeTextColorPopupButtonActive, kThemeTextColorPopupButtonInactive),
QMacPaletteMap(QPlatformTheme::ItemViewPalette, kThemeTextColorListView, kThemeTextColorDialogInactive),
- QMacPaletteMap(QPlatformTheme::MessageBoxLabelPelette, kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
+ QMacPaletteMap(QPlatformTheme::MessageBoxLabelPalette, kThemeTextColorAlertActive, kThemeTextColorAlertInactive),
QMacPaletteMap(QPlatformTheme::TabBarPalette, kThemeTextColorTabFrontActive, kThemeTextColorTabFrontInactive),
QMacPaletteMap(QPlatformTheme::LabelPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
QMacPaletteMap(QPlatformTheme::GroupBoxPalette, kThemeTextColorPlacardActive, kThemeTextColorPlacardInactive),
@@ -191,6 +191,8 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
pal.setColor(QPalette::Disabled, QPalette::HighlightedText, qc);
}
if (mac_widget_colors[i].paletteRole == QPlatformTheme::MenuPalette) {
+ qc = qt_mac_colorForTheme(kThemeBrushMenuBackground);
+ pal.setBrush(QPalette::Background, qc);
qc = qt_mac_colorForThemeTextColor(kThemeTextColorMenuItemActive);
pal.setBrush(QPalette::ButtonText, qc);
qc = qt_mac_colorForThemeTextColor(kThemeTextColorMenuItemSelected);
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 67cac41383..6e1f00eebe 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -80,6 +80,7 @@ typedef NSWindow<QNSWindowProtocol> QCocoaNSWindow;
- (id)initWithNSWindow:(QCocoaNSWindow *)window platformWindow:(QCocoaWindow *)platformWindow;
- (void)handleWindowEvent:(NSEvent *)theEvent;
+- (void) clearWindow;
@end
@@ -141,6 +142,7 @@ public:
~QCocoaWindow();
void setGeometry(const QRect &rect);
+ QRect geometry() const;
void setCocoaGeometry(const QRect &rect);
void clipChildWindows();
void clipWindow(const NSRect &clipRect);
@@ -189,6 +191,7 @@ public:
NSInteger windowLevel(Qt::WindowFlags flags);
NSUInteger windowStyleMask(Qt::WindowFlags flags);
void setWindowShadow(Qt::WindowFlags flags);
+ void setWindowZoomButton(Qt::WindowFlags flags);
void setCurrentContext(QCocoaGLContext *context);
QCocoaGLContext *currentContext() const;
@@ -206,6 +209,8 @@ public:
void registerTouch(bool enable);
void setContentBorderThickness(int topThickness, int bottomThickness);
+ void registerContentBorderArea(quintptr identifier, int upper, int lower);
+ void enableContentBorderArea(bool enable);
void applyContentBorderThickness(NSWindow *window);
void updateNSToolbar();
@@ -280,6 +285,16 @@ public: // for QNSView
QRect m_normalGeometry;
Qt::WindowFlags m_oldWindowFlags;
NSApplicationPresentationOptions m_presentationOptions;
+
+ struct BorderRange {
+ BorderRange(int u, int l) : upper(u), lower(l) { }
+ int upper;
+ int lower;
+ bool operator<(BorderRange const& right) const {
+ return upper < right.upper;
+ }
+ };
+ QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index f1f88a13dd..c7fba4eef0 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -155,7 +155,14 @@ static bool isMouseEvent(NSEvent *ev)
}
}
+ // The call to -[NSWindow sendEvent] may result in the window being deleted
+ // (e.g., when closing the window by pressing the title bar close button).
+ [self retain];
[self.window superSendEvent:theEvent];
+ bool windowStillAlive = self.window != nil; // We need to read before releasing
+ [self release];
+ if (!windowStillAlive)
+ return;
if (!self.window.delegate)
return; // Already detached, pending NSAppKitDefined event
@@ -179,6 +186,11 @@ static bool isMouseEvent(NSEvent *ev)
self.window.delegate = nil;
}
+- (void)clearWindow
+{
+ _window = nil;
+}
+
- (void)dealloc
{
_window = nil;
@@ -259,6 +271,7 @@ static bool isMouseEvent(NSEvent *ev)
- (void)dealloc
{
+ [_helper clearWindow];
[_helper release];
_helper = nil;
[super dealloc];
@@ -319,6 +332,7 @@ static bool isMouseEvent(NSEvent *ev)
- (void)dealloc
{
+ [_helper clearWindow];
[_helper release];
_helper = nil;
[super dealloc];
@@ -378,7 +392,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
// problem, except if the appilcation wants to have a "custom" viewport.
// (like the hellogl example)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7
- && tlw->surfaceType() == QSurface::OpenGLSurface) {
+ && tlw->supportsOpenGL()) {
BOOL enable = qt_mac_resolveOption(YES, tlw, "_q_mac_wantsBestResolutionOpenGLSurface",
"QT_MAC_WANTS_BEST_RESOLUTION_OPENGL_SURFACE");
[m_contentView setWantsBestResolutionOpenGLSurface:enable];
@@ -448,6 +462,22 @@ void QCocoaWindow::setGeometry(const QRect &rectIn)
setCocoaGeometry(rect);
}
+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_contentViewIsEmbedded) {
+ NSPoint windowPoint = [m_contentView convertPoint:NSMakePoint(0, 0) toView:nil];
+ NSPoint screenPoint = [[m_contentView window] convertBaseToScreen:windowPoint]; // ### use convertRectToScreen after 10.6 removal
+ QPoint position = qt_mac_flipPoint(screenPoint).toPoint();
+ QSize size = qt_mac_toQRect([m_contentView bounds]).size();
+ return QRect(position, size);
+ }
+
+ return QPlatformWindow::geometry();
+}
+
void QCocoaWindow::setCocoaGeometry(const QRect &rect)
{
QCocoaAutoReleasePool pool;
@@ -791,6 +821,18 @@ void QCocoaWindow::setWindowShadow(Qt::WindowFlags flags)
[m_nsWindow setHasShadow:(keepShadow ? YES : NO)];
}
+void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags)
+{
+ // Disable the zoom (maximize) button for fixed-sized windows and customized
+ // no-WindowMaximizeButtonHint windows. From a Qt perspective it migth be expected
+ // that the button would be removed in the latter case, but disabling it is more
+ // in line with the platform style guidelines.
+ bool fixedSizeNoZoom = (window()->minimumSize().isValid() && window()->maximumSize().isValid()
+ && window()->minimumSize() == window()->maximumSize());
+ bool customizeNoZoom = ((flags & Qt::CustomizeWindowHint) && !(flags & Qt::WindowMaximizeButtonHint));
+ [[m_nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:!(fixedSizeNoZoom || customizeNoZoom)];
+}
+
void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
if (m_nsWindow && !m_isNSWindowChild) {
@@ -816,6 +858,7 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
}
}
#endif
+ setWindowZoomButton(flags);
}
m_windowFlags = flags;
@@ -908,6 +951,9 @@ void QCocoaWindow::raise()
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} else {
[m_nsWindow orderFront: m_nsWindow];
+ ProcessSerialNumber psn;
+ GetCurrentProcess(&psn);
+ SetFrontProcessWithOptions(&psn, kSetFrontProcessFrontWindowOnly);
}
}
}
@@ -979,6 +1025,9 @@ void QCocoaWindow::propagateSizeHints()
const QSize maximumSize = window()->maximumSize();
[m_nsWindow setContentMaxSize : NSMakeSize(maximumSize.width(), maximumSize.height())];
+ // The window may end up with a fixed size; in this case the zoom button should be disabled.
+ setWindowZoomButton(m_windowFlags);
+
// 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.
if (!window()->sizeIncrement().isEmpty())
@@ -1080,7 +1129,9 @@ NSWindow *QCocoaWindow::nativeWindow() const
void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
{
m_contentViewIsToBeEmbedded = embedded;
- recreateWindow(0); // destroy what was already created
+ // Release any previosly created NSWindow.
+ [m_nsWindow closeAndRelease];
+ m_nsWindow = 0;
}
void QCocoaWindow::windowWillMove()
@@ -1505,15 +1556,46 @@ void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickne
applyContentBorderThickness(m_nsWindow);
}
+void QCocoaWindow::registerContentBorderArea(quintptr identifier, int upper, int lower)
+{
+ m_contentBorderAreas.insert(identifier, BorderRange(upper, lower));
+
+ // Find consecutive registered border areas, starting from the top.
+ QList<BorderRange> ranges = m_contentBorderAreas.values();
+ std::sort(ranges.begin(), ranges.end());
+ m_topContentBorderThickness = 0;
+ foreach (BorderRange range, ranges) {
+ // Is this sub-range adjacent to or overlaping the
+ // existing total border area range? If so merge
+ // it into the total range,
+ if (range.upper <= (m_topContentBorderThickness + 1))
+ m_topContentBorderThickness = qMax(m_topContentBorderThickness, range.lower);
+ else
+ break;
+ }
+
+ m_bottomContentBorderThickness = 0; // (not supported)
+ if (m_drawContentBorderGradient)
+ applyContentBorderThickness(m_nsWindow);
+}
+
+void QCocoaWindow::enableContentBorderArea(bool enable)
+{
+ m_drawContentBorderGradient = enable;
+ applyContentBorderThickness(m_nsWindow);
+}
+
void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
{
if (!window)
return;
- if (m_drawContentBorderGradient)
- [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
- else
+ if (!m_drawContentBorderGradient) {
[window setStyleMask:[window styleMask] & ~NSTexturedBackgroundWindowMask];
+ return;
+ }
+
+ [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
if (m_topContentBorderThickness > 0) {
[window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMaxYEdge];
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 90d56bc3f3..47081ab890 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -562,9 +562,11 @@ static QTouchDevice *touchDevice = 0;
QPointF qtWindowPoint;
QPointF qtScreenPoint;
QNSView *targetView = self;
- if (m_platformWindow && m_platformWindow->m_forwardWindow
- && (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)) {
- targetView = m_platformWindow->m_forwardWindow->m_qtView;
+ if (m_platformWindow && m_platformWindow->m_forwardWindow) {
+ if (theEvent.type == NSLeftMouseDragged || theEvent.type == NSLeftMouseUp)
+ targetView = m_platformWindow->m_forwardWindow->m_qtView;
+ else
+ m_platformWindow->m_forwardWindow = 0;
}
[targetView convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&qtWindowPoint andScreenPoint:&qtScreenPoint];
@@ -650,7 +652,7 @@ static QTouchDevice *touchDevice = 0;
{
if (m_window->flags() & Qt::WindowTransparentForInput)
return [super mouseDragged:theEvent];
- if (!(m_buttons & Qt::LeftButton))
+ if (!(m_buttons & (m_sendUpAsRightButton ? Qt::RightButton : Qt::LeftButton)))
qWarning("QNSView mouseDragged: Internal mouse button tracking invalid (missing Qt::LeftButton)");
[self handleMouseEvent:theEvent];
}
@@ -1719,7 +1721,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
// keep our state, and QGuiApplication state (buttons member) in-sync,
// or future mouse events will be processed incorrectly
- m_buttons &= ~Qt::LeftButton;
+ m_buttons &= ~(m_sendUpAsRightButton ? Qt::RightButton : Qt::LeftButton);
NSPoint windowPoint = [self convertPoint: point fromView: nil];
QPoint qtWindowPoint(windowPoint.x, windowPoint.y);
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
index 61fbe3a61f..ef67d1166f 100644
--- a/src/plugins/platforms/cocoa/qpaintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -979,43 +979,6 @@ static void drawImageReleaseData (void *info, const void *, size_t)
delete static_cast<QImage *>(info);
}
-CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0)
-{
- QImage *image;
- if (img.depth() != 32)
- image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied));
- else
- image = new QImage(img);
-
- uint cgflags = kCGImageAlphaNone;
- switch (image->format()) {
- case QImage::Format_ARGB32_Premultiplied:
- cgflags = kCGImageAlphaPremultipliedFirst;
- break;
- case QImage::Format_ARGB32:
- cgflags = kCGImageAlphaFirst;
- break;
- case QImage::Format_RGB32:
- cgflags = kCGImageAlphaNoneSkipFirst;
- default:
- break;
- }
-#if defined(kCGBitmapByteOrder32Host) //only needed because CGImage.h added symbols in the minor version
- cgflags |= kCGBitmapByteOrder32Host;
-#endif
- QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image,
- static_cast<const QImage *>(image)->bits(),
- image->byteCount(),
- drawImageReleaseData);
- if (imagePtr)
- *imagePtr = image;
- return CGImageCreate(image->width(), image->height(), 8, 32,
- image->bytesPerLine(),
- QCoreGraphicsPaintEngine::macGenericColorSpace(),
- cgflags, dataProvider, 0, false, kCGRenderingIntentDefault);
-
-}
-
void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
Qt::ImageConversionFlags flags)
{
@@ -1026,8 +989,7 @@ void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, con
if (img.isNull() || state->compositionMode() == QPainter::CompositionMode_Destination)
return;
- const QImage *image;
- QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img, &image);
+ QCFType<CGImageRef> cgimage = qt_mac_toCGImage(img);
CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
if (QRectF(0, 0, img.width(), img.height()) != sr)
cgimage = CGImageCreateWithImageInRect(cgimage, CGRectMake(sr.x(), sr.y(),
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
index 3e92a45a62..fb968f31e9 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac.mm
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -40,9 +40,11 @@
****************************************************************************/
#include "qprintengine_mac_p.h"
+#include "qcocoaprintersupport.h"
#include <quuid.h>
+#include <QtGui/qpagelayout.h>
#include <QtCore/qcoreapplication.h>
-#include <qpa/qplatformprintersupport.h>
+#include <QtCore/qdebug.h>
#include "qcocoaautoreleasepool.h"
@@ -50,10 +52,14 @@
QT_BEGIN_NAMESPACE
+extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits);
+
QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode) : QPaintEngine(*(new QMacPrintEnginePrivate))
{
Q_D(QMacPrintEngine);
d->mode = mode;
+ d->m_printDevice = new QCocoaPrintDevice(QCocoaPrinterSupport().defaultPrintDeviceId());
+ d->m_pageLayout.setPageSize(d->m_printDevice->defaultPageSize());
d->initialize();
}
@@ -137,126 +143,6 @@ QMacPrintEnginePrivate::~QMacPrintEnginePrivate()
delete paintEngine;
}
-void QMacPrintEnginePrivate::setPaperSize(QPrinter::PaperSize ps)
-{
- Q_Q(QMacPrintEngine);
- if (hasCustomPaperSize) {
- PMRelease(customPaper);
- customPaper = 0;
- }
- hasCustomPaperSize = (ps == QPrinter::Custom);
- PMPrinter printer;
- if (PMSessionGetCurrentPrinter(session(), &printer) == noErr) {
- if (ps != QPrinter::Custom) {
- QSizeF newSize = QPlatformPrinterSupport::convertPaperSizeToQSizeF(ps);
- QCFType<CFArrayRef> formats;
- if (PMSessionCreatePageFormatList(session(), printer, &formats) == noErr) {
- CFIndex total = CFArrayGetCount(formats);
- PMPageFormat tmp;
- PMRect paper;
- for (CFIndex idx = 0; idx < total; ++idx) {
- tmp = static_cast<PMPageFormat>(const_cast<void *>(CFArrayGetValueAtIndex(formats, idx)));
- PMGetUnadjustedPaperRect(tmp, &paper);
- int wMM = int((paper.right - paper.left) / 72 * 25.4 + 0.5);
- int hMM = int((paper.bottom - paper.top) / 72 * 25.4 + 0.5);
- if (newSize.width() == wMM && newSize.height() == hMM) {
- PMCopyPageFormat(tmp, format());
- // reset the orientation and resolution as they are lost in the copy.
- q->setProperty(QPrintEngine::PPK_Orientation, orient);
- if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr) {
- // Don't know, warn for the moment.
- qWarning("QMacPrintEngine, problem setting format and resolution for this page size");
- }
- break;
- }
- }
- }
- } else {
- QCFString paperId = QCFString::toCFStringRef(QUuid::createUuid().toString());
- PMPaperMargins paperMargins;
- paperMargins.left = leftMargin;
- paperMargins.top = topMargin;
- paperMargins.right = rightMargin;
- paperMargins.bottom = bottomMargin;
- PMPaperCreateCustom(printer, paperId, QCFString("Custom size"), customSize.width(), customSize.height(), &paperMargins, &customPaper);
- PMPageFormat tmp;
- PMCreatePageFormatWithPMPaper(&tmp, customPaper);
- PMCopyPageFormat(tmp, format());
- if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr) {
- // Don't know, warn for the moment.
- qWarning("QMacPrintEngine, problem setting paper name");
- }
- }
- }
-}
-
-QPrinter::PaperSize QMacPrintEnginePrivate::paperSize() const
-{
- if (hasCustomPaperSize)
- return QPrinter::Custom;
- PMRect paper;
- PMGetUnadjustedPaperRect(format(), &paper);
- QSizeF sizef((paper.right - paper.left) / 72.0 * 25.4, (paper.bottom - paper.top) / 72.0 * 25.4);
- return QPlatformPrinterSupport::convertQSizeFToPaperSize(sizef);
-}
-
-void QMacPrintEnginePrivate::setPaperName(const QString &name)
-{
- Q_Q(QMacPrintEngine);
- if (hasCustomPaperSize) {
- PMRelease(customPaper);
- customPaper = 0;
- hasCustomPaperSize = false;
- }
- PMPrinter printer;
-
- if (PMSessionGetCurrentPrinter(session(), &printer) == noErr) {
- CFArrayRef array;
- if (PMPrinterGetPaperList(printer, &array) != noErr)
- return;
- int count = CFArrayGetCount(array);
- for (int i = 0; i < count; ++i) {
- PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(array, i)));
- QCFString paperName;
- if (PMPaperCreateLocalizedName(paper, printer, &paperName) == noErr) {
- if (QString(paperName) == name) {
- PMPageFormat tmp;
- PMCreatePageFormatWithPMPaper(&tmp, paper);
- PMCopyPageFormat(tmp, format());
- q->setProperty(QPrintEngine::PPK_Orientation, orient);
- if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr) {
- // Don't know, warn for the moment.
- qWarning("QMacPrintEngine, problem setting paper name");
- }
- }
- }
- }
- }
-}
-
-QList<QVariant> QMacPrintEnginePrivate::supportedResolutions() const
-{
- Q_ASSERT_X(printInfo, "QMacPrinterEngine::supportedResolutions",
- "must have a valid printer session");
- UInt32 resCount;
- QList<QVariant> resolutions;
- PMPrinter printer;
- if (PMSessionGetCurrentPrinter(session(), &printer) == noErr) {
- PMResolution res;
- OSStatus status = PMPrinterGetPrinterResolutionCount(printer, &resCount);
- if (status == noErr) {
- // According to the docs, index start at 1.
- for (UInt32 i = 1; i <= resCount; ++i) {
- if (PMPrinterGetIndexedPrinterResolution(printer, i, &res) == noErr)
- resolutions.append(QVariant(int(res.hRes)));
- }
- } else {
- qWarning("QMacPrintEngine::supportedResolutions: Unexpected error: %ld", long(status));
- }
- }
- return resolutions;
-}
-
QPrinter::PrinterState QMacPrintEngine::printerState() const
{
return d_func()->state;
@@ -291,77 +177,22 @@ bool QMacPrintEngine::abort()
return ret;
}
-static inline int qt_get_PDMWidth(PMPageFormat pformat, bool fullPage,
- const PMResolution &resolution)
-{
- int val = 0;
- PMRect r;
- qreal hRatio = resolution.hRes / 72;
- if (fullPage) {
- if (PMGetAdjustedPaperRect(pformat, &r) == noErr)
- val = qRound((r.right - r.left) * hRatio);
- } else {
- if (PMGetAdjustedPageRect(pformat, &r) == noErr)
- val = qRound((r.right - r.left) * hRatio);
- }
- return val;
-}
-
-static inline int qt_get_PDMHeight(PMPageFormat pformat, bool fullPage,
- const PMResolution &resolution)
-{
- int val = 0;
- PMRect r;
- qreal vRatio = resolution.vRes / 72;
- if (fullPage) {
- if (PMGetAdjustedPaperRect(pformat, &r) == noErr)
- val = qRound((r.bottom - r.top) * vRatio);
- } else {
- if (PMGetAdjustedPageRect(pformat, &r) == noErr)
- val = qRound((r.bottom - r.top) * vRatio);
- }
- return val;
-}
-
-
int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
{
Q_D(const QMacPrintEngine);
int val = 1;
switch (m) {
case QPaintDevice::PdmWidth:
- if (d->hasCustomPaperSize) {
- val = qRound(d->customSize.width());
- if (d->hasCustomPageMargins) {
- val -= qRound(d->leftMargin + d->rightMargin);
- } else {
- QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList();
- val -= qRound(margins.at(0).toDouble() + margins.at(2).toDouble());
- }
- } else {
- val = qt_get_PDMWidth(d->format(), property(PPK_FullPage).toBool(), d->resolution);
- }
+ val = d->m_pageLayout.paintRectPixels(d->resolution.hRes).width();
break;
case QPaintDevice::PdmHeight:
- if (d->hasCustomPaperSize) {
- val = qRound(d->customSize.height());
- if (d->hasCustomPageMargins) {
- val -= qRound(d->topMargin + d->bottomMargin);
- } else {
- QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList();
- val -= qRound(margins.at(1).toDouble() + margins.at(3).toDouble());
- }
- } else {
- val = qt_get_PDMHeight(d->format(), property(PPK_FullPage).toBool(), d->resolution);
- }
+ val = d->m_pageLayout.paintRectPixels(d->resolution.hRes).height();
break;
case QPaintDevice::PdmWidthMM:
- val = metric(QPaintDevice::PdmWidth);
- val = int((val * 254 + 5 * d->resolution.hRes) / (10 * d->resolution.hRes));
+ val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).width());
break;
case QPaintDevice::PdmHeightMM:
- val = metric(QPaintDevice::PdmHeight);
- val = int((val * 254 + 5 * d->resolution.vRes) / (10 * d->resolution.vRes));
+ val = qRound(d->m_pageLayout.paintRect(QPageLayout::Millimeter).height());
break;
case QPaintDevice::PdmPhysicalDpiX:
case QPaintDevice::PdmPhysicalDpiY: {
@@ -407,33 +238,24 @@ void QMacPrintEnginePrivate::initialize()
q->gccaps = paintEngine->gccaps;
- fullPage = false;
-
QCocoaAutoReleasePool pool;
printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]];
- PMPrinter printer;
- if (printInfo && PMSessionGetCurrentPrinter(session(), &printer) == noErr) {
- QList<QVariant> resolutions = supportedResolutions();
- if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) {
- if (resolutions.count() > 1 && mode == QPrinter::HighResolution) {
- int max = 0;
- for (int i = 0; i < resolutions.count(); ++i) {
- int value = resolutions.at(i).toInt();
- if (value > max)
- max = value;
- }
- resolution.hRes = resolution.vRes = max;
- } else {
- resolution.hRes = resolution.vRes = resolutions.at(0).toInt();
- }
- if (resolution.hRes == 0)
- resolution.hRes = resolution.vRes = 600;
- } else {
- resolution.hRes = resolution.vRes = qt_defaultDpi();
- }
+ QList<int> resolutions = m_printDevice->supportedResolutions();
+ if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) {
+ qSort(resolutions);
+ if (resolutions.count() > 1 && mode == QPrinter::HighResolution)
+ resolution.hRes = resolution.vRes = resolutions.last();
+ else
+ resolution.hRes = resolution.vRes = resolutions.first();
+ if (resolution.hRes == 0)
+ resolution.hRes = resolution.vRes = 600;
+ } else {
+ resolution.hRes = resolution.vRes = qt_defaultDpi();
}
+ setPageSize(m_pageLayout.pageSize());
+
QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant>::const_iterator propC;
for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); propC++) {
q->setProperty(propC.key(), propC.value());
@@ -444,8 +266,6 @@ void QMacPrintEnginePrivate::releaseSession()
{
PMSessionEndPageNoDialog(session());
PMSessionEndDocumentNoDialog(session());
- if (hasCustomPaperSize)
- PMRelease(customPaper);
[printInfo release];
printInfo = 0;
}
@@ -473,8 +293,8 @@ bool QMacPrintEnginePrivate::newPage_helper()
return false;
}
- QRect page = q->property(QPrintEngine::PPK_PageRect).toRect();
- QRect paper = q->property(QPrintEngine::PPK_PaperRect).toRect();
+ QRect page = m_pageLayout.paintRectPixels(resolution.hRes);
+ QRect paper = m_pageLayout.fullRectPixels(resolution.hRes);
CGContextRef cgContext;
OSStatus err = noErr;
@@ -491,7 +311,7 @@ bool QMacPrintEnginePrivate::newPage_helper()
CGContextScaleCTM(cgContext, 1, -1);
CGContextTranslateCTM(cgContext, 0, -paper.height());
- if (!fullPage)
+ 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);
@@ -505,6 +325,34 @@ bool QMacPrintEnginePrivate::newPage_helper()
return true;
}
+void QMacPrintEnginePrivate::setPageSize(const QPageSize &pageSize)
+{
+ if (!pageSize.isValid())
+ return;
+
+ // Get the matching printer paper
+ QPageSize printerPageSize = m_printDevice->supportedPageSize(pageSize);
+ QPageSize usePageSize = printerPageSize.isValid() ? printerPageSize : pageSize;
+
+ // Get the PMPaper and check it is valid
+ PMPaper macPaper = m_printDevice->macPaper(usePageSize);
+ if (macPaper == 0) {
+ qWarning() << "QMacPrintEngine: Invalid PMPaper returned for " << pageSize;
+ return;
+ }
+
+ QMarginsF printable = m_printDevice->printableMargins(usePageSize, m_pageLayout.orientation(), resolution.hRes);
+ m_pageLayout.setPageSize(usePageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units()));
+
+ // You cannot set the page size on a PMPageFormat, you must create a new PMPageFormat
+ PMPageFormat pageFormat;
+ PMCreatePageFormatWithPMPaper(&pageFormat, macPaper);
+ PMSetOrientation(pageFormat, m_pageLayout.orientation() == QPageLayout::Landscape ? kPMLandscape : kPMPortrait, kPMUnlocked);
+ PMCopyPageFormat(pageFormat, format());
+ if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr)
+ qWarning("QMacPrintEngine: Invalid page format");
+ PMRelease(pageFormat);
+}
void QMacPrintEngine::updateState(const QPaintEngineState &state)
{
@@ -624,32 +472,22 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
break;
case PPK_SelectionOption:
break;
- case PPK_WindowsPageSize:
- break;
// The following keys are properties and settings that are supported by the Mac PrintEngine
case PPK_Resolution: {
- PMPrinter printer;
- UInt32 count;
- if (PMSessionGetCurrentPrinter(d->session(), &printer) != noErr)
- break;
- if (PMPrinterGetPrinterResolutionCount(printer, &count) != noErr)
- break;
- PMResolution resolution = { 0.0, 0.0 };
- PMResolution bestResolution = { 0.0, 0.0 };
+ // TODO It appears the old code didn't actually set the resolution??? Can we delete all this???
+ int bestResolution = 0;
int dpi = value.toInt();
int bestDistance = INT_MAX;
- for (UInt32 i = 1; i <= count; ++i) { // Yes, it starts at 1
- if (PMPrinterGetIndexedPrinterResolution(printer, i, &resolution) == noErr) {
- if (dpi == int(resolution.hRes)) {
+ foreach (int resolution, d->m_printDevice->supportedResolutions()) {
+ if (dpi == resolution) {
+ bestResolution = resolution;
+ break;
+ } else {
+ int distance = qAbs(dpi - resolution);
+ if (distance < bestDistance) {
+ bestDistance = distance;
bestResolution = resolution;
- break;
- } else {
- int distance = qAbs(dpi - int(resolution.hRes));
- if (distance < bestDistance) {
- bestDistance = distance;
- bestResolution = resolution;
- }
}
}
}
@@ -666,75 +504,80 @@ void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
PMPrintSettingsSetJobName(d->settings(), QCFString(value.toString()));
break;
case PPK_FullPage:
- d->fullPage = value.toBool();
+ if (value.toBool())
+ d->m_pageLayout.setMode(QPageLayout::FullPageMode);
+ else
+ d->m_pageLayout.setMode(QPageLayout::StandardMode);
break;
case PPK_CopyCount: // fallthrough
case PPK_NumberOfCopies:
PMSetCopies(d->settings(), value.toInt(), false);
break;
case PPK_Orientation: {
- QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
- if (d->hasCustomPaperSize && (d->orient != newOrientation))
- d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
- d->orient = newOrientation;
- PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
- PMSetOrientation(d->format(), o, false);
+ // First try set the Mac format orientation, then set our orientation to match result
+ QPageLayout::Orientation newOrientation = QPageLayout::Orientation(value.toInt());
+ PMOrientation macOrientation = (newOrientation == QPageLayout::Landscape) ? kPMLandscape : kPMPortrait;
+ PMSetOrientation(d->format(), macOrientation, kPMUnlocked);
PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
+ PMGetOrientation(d->format(), &macOrientation);
+ d->m_pageLayout.setOrientation(macOrientation == kPMLandscape ? QPageLayout::Landscape : QPageLayout::Portrait);
break;
}
case PPK_OutputFileName:
d->outputFilename = value.toString();
break;
- case PPK_PaperSize:
- d->setPaperSize(QPrinter::PaperSize(value.toInt()));
+ case PPK_PageSize:
+ d->setPageSize(QPageSize(QPageSize::PageSizeId(value.toInt())));
break;
case PPK_PaperName:
- d->setPaperName(value.toString());
+ // Get the named page size from the printer if supported
+ d->setPageSize(d->m_printDevice->supportedPageSize(value.toString()));
+ break;
+ case PPK_WindowsPageSize:
+ d->setPageSize(QPageSize(QPageSize::id(value.toInt())));
break;
case PPK_PrinterName: {
- bool printerNameSet = false;
- OSStatus status = noErr;
- QCFType<CFArrayRef> printerList;
- status = PMServerCreatePrinterList(kPMServerLocal, &printerList);
- if (status == noErr) {
- CFIndex count = CFArrayGetCount(printerList);
- for (CFIndex i=0; i<count; ++i) {
- PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i)));
- QString name = QCFString::toQString(PMPrinterGetID(printer));
- if (name == value.toString()) {
- status = PMSessionSetCurrentPMPrinter(d->session(), printer);
- printerNameSet = true;
- break;
- }
- }
- }
- if (status != noErr)
- qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status));
- if (!printerNameSet) {
- qWarning("QMacPrintEngine::setPrinterName: Failed to set printer named '%s'.", qPrintable(value.toString()));
- d->releaseSession();
- d->state = QPrinter::Idle;
- }
- break; }
- case PPK_CustomPaperSize:
- {
- PMOrientation orientation;
- PMGetOrientation(d->format(), &orientation);
- d->customSize = value.toSizeF();
- if (orientation != kPMPortrait)
- d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
- d->setPaperSize(QPrinter::Custom);
+ QString id = value.toString();
+ if (id.isEmpty())
+ id = QCocoaPrinterSupport().defaultPrintDeviceId();
+ else if (!QCocoaPrinterSupport().availablePrintDeviceIds().contains(id))
+ break;
+ d->m_printDevice = new QCocoaPrintDevice(id);
+ PMPrinter printer = d->m_printDevice->macPrinter();
+ PMRetain(printer);
+ PMSessionSetCurrentPMPrinter(d->session(), printer);
+ // TODO Do we need to check if the page size, etc, are valid on new printer?
break;
}
+ case PPK_CustomPaperSize:
+ d->setPageSize(QPageSize(value.toSizeF(), QPageSize::Point));
+ break;
case PPK_PageMargins:
{
QList<QVariant> margins(value.toList());
Q_ASSERT(margins.size() == 4);
- d->leftMargin = margins.at(0).toDouble();
- d->topMargin = margins.at(1).toDouble();
- d->rightMargin = margins.at(2).toDouble();
- d->bottomMargin = margins.at(3).toDouble();
- d->hasCustomPageMargins = true;
+ d->m_pageLayout.setMargins(QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(),
+ margins.at(2).toReal(), margins.at(3).toReal()));
+ break;
+ }
+ case PPK_QPageSize:
+ d->setPageSize(value.value<QPageSize>());
+ break;
+ case PPK_QPageMargins: {
+ QPair<QMarginsF, QPageLayout::Unit> pair = value.value<QPair<QMarginsF, QPageLayout::Unit> >();
+ d->m_pageLayout.setUnits(pair.second);
+ d->m_pageLayout.setMargins(pair.first);
+ break;
+ }
+ case PPK_QPageLayout: {
+ QPageLayout pageLayout = value.value<QPageLayout>();
+ if (pageLayout.isValid() && d->m_printDevice->isValidPageLayout(pageLayout, d->resolution.hRes)) {
+ setProperty(PPK_QPageSize, QVariant::fromValue(pageLayout.pageSize()));
+ setProperty(PPK_FullPage, pageLayout.mode() == QPageLayout::FullPageMode);
+ setProperty(PPK_Orientation, QVariant::fromValue(pageLayout.orientation()));
+ d->m_pageLayout.setUnits(pageLayout.units());
+ d->m_pageLayout.setMargins(pageLayout.margins());
+ }
break;
}
// No default so that compiler will complain if new keys added and not handled in this engine
@@ -787,9 +630,6 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_SelectionOption:
ret = QString();
break;
- case PPK_WindowsPageSize:
- // Special case, leave null
- break;
// The following keys are properties and settings that are supported by the Mac PrintEngine
case PPK_CollateCopies: {
@@ -808,7 +648,7 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
break;
}
case PPK_FullPage:
- ret = d->fullPage;
+ ret = d->m_pageLayout.mode() == QPageLayout::FullPageMode;
break;
case PPK_NumberOfCopies:
ret = 1;
@@ -823,107 +663,62 @@ QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
ret = true;
break;
case PPK_Orientation:
- PMOrientation orientation;
- PMGetOrientation(d->format(), &orientation);
- ret = orientation == kPMPortrait ? QPrinter::Portrait : QPrinter::Landscape;
+ ret = d->m_pageLayout.orientation();
break;
case PPK_OutputFileName:
ret = d->outputFilename;
break;
- case PPK_PageRect: {
+ case PPK_PageRect:
// PageRect is returned in device pixels
- QRect r;
- PMRect macrect, macpaper;
- qreal hRatio = d->resolution.hRes / 72;
- qreal vRatio = d->resolution.vRes / 72;
- if (d->hasCustomPaperSize) {
- r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio));
- if (d->hasCustomPageMargins) {
- r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio),
- -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
- } else {
- QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList();
- r.adjust(qRound(margins.at(0).toDouble() * hRatio),
- qRound(margins.at(1).toDouble() * vRatio),
- -qRound(margins.at(2).toDouble() * hRatio),
- -qRound(margins.at(3).toDouble()) * vRatio);
- }
- } else if (PMGetAdjustedPageRect(d->format(), &macrect) == noErr
- && PMGetAdjustedPaperRect(d->format(), &macpaper) == noErr)
- {
- if (d->fullPage || d->hasCustomPageMargins) {
- r.setCoords(int(macpaper.left * hRatio), int(macpaper.top * vRatio),
- int(macpaper.right * hRatio), int(macpaper.bottom * vRatio));
- r.translate(-r.x(), -r.y());
- if (d->hasCustomPageMargins) {
- r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio),
- -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
- }
- } else {
- r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
- int(macrect.right * hRatio), int(macrect.bottom * vRatio));
- r.translate(int(-macpaper.left * hRatio), int(-macpaper.top * vRatio));
- }
- }
- ret = r;
- break; }
- case PPK_PaperSize:
- ret = d->paperSize();
+ ret = d->m_pageLayout.paintRectPixels(d->resolution.hRes);
+ break;
+ case PPK_PageSize:
+ ret = d->m_pageLayout.pageSize().id();
break;
case PPK_PaperName:
- ret = QCFString::toQString([d->printInfo localizedPaperName]);
- break;
- case PPK_PaperRect: {
- QRect r;
- PMRect macrect;
- qreal hRatio = d->resolution.hRes / 72;
- qreal vRatio = d->resolution.vRes / 72;
- if (d->hasCustomPaperSize) {
- r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio));
- } else if (PMGetAdjustedPaperRect(d->format(), &macrect) == noErr) {
- r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
- int(macrect.right * hRatio), int(macrect.bottom * vRatio));
- r.translate(-r.x(), -r.y());
- }
- ret = r;
- break; }
- case PPK_PrinterName: {
- PMPrinter printer;
- OSStatus status = PMSessionGetCurrentPrinter(d->session(), &printer);
- if (status != noErr)
- qWarning("QMacPrintEngine::printerName: Failed getting current PMPrinter: %ld", long(status));
- if (printer)
- ret = QCFString::toQString(PMPrinterGetID(printer));
- break; }
+ ret = d->m_pageLayout.pageSize().name();
+ break;
+ case PPK_WindowsPageSize:
+ ret = d->m_pageLayout.pageSize().windowsId();
+ break;
+ case PPK_PaperRect:
+ // PaperRect is returned in device pixels
+ ret = d->m_pageLayout.fullRectPixels(d->resolution.hRes);
+ break;
+ case PPK_PrinterName:
+ return d->m_printDevice->id();
+ break;
case PPK_Resolution: {
ret = d->resolution.hRes;
break;
}
- case PPK_SupportedResolutions:
- ret = d->supportedResolutions();
+ case PPK_SupportedResolutions: {
+ QList<QVariant> list;
+ foreach (int resolution, d->m_printDevice->supportedResolutions())
+ list << resolution;
+ ret = list;
break;
+ }
case PPK_CustomPaperSize:
- ret = d->customSize;
+ ret = d->m_pageLayout.fullRectPoints().size();
break;
- case PPK_PageMargins:
- {
- QList<QVariant> margins;
- if (d->hasCustomPageMargins) {
- margins << d->leftMargin << d->topMargin
- << d->rightMargin << d->bottomMargin;
- } else if (!d->hasCustomPaperSize) {
- PMPaperMargins paperMargins;
- PMPaper paper;
- PMGetPageFormatPaper(d->format(), &paper);
- PMPaperGetMargins(paper, &paperMargins);
- margins << paperMargins.left << paperMargins.top
- << paperMargins.right << paperMargins.bottom;
- } else {
- margins << 0 << 0 << 0 << 0;
- }
- ret = margins;
+ case PPK_PageMargins: {
+ QList<QVariant> list;
+ QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Point);
+ list << margins.left() << margins.top() << margins.right() << margins.bottom();
+ ret = list;
+ break;
+ }
+ case PPK_QPageSize:
+ ret.setValue(d->m_pageLayout.pageSize());
+ break;
+ case PPK_QPageMargins: {
+ QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(d->m_pageLayout.margins(), d->m_pageLayout.units());
+ ret.setValue(pair);
break;
}
+ case PPK_QPageLayout:
+ ret.setValue(d->m_pageLayout);
// No default so that compiler will complain if new keys added and not handled in this engine
}
return ret;
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
index e3a8520811..12a87b35e9 100644
--- a/src/plugins/platforms/cocoa/qprintengine_mac_p.h
+++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
@@ -60,6 +60,9 @@
#include <QtPrintSupport/qprinter.h>
#include <QtPrintSupport/qprintengine.h>
#include <QtGui/private/qpainter_p.h>
+#include <QtGui/qpagelayout.h>
+
+#include "qcocoaprintdevice.h"
#include "qpaintengine_mac_p.h"
@@ -121,33 +124,24 @@ class QMacPrintEnginePrivate : public QPaintEnginePrivate
public:
QPrinter::PrinterMode mode;
QPrinter::PrinterState state;
- QPrinter::Orientation orient;
+ QSharedDataPointer<QCocoaPrintDevice> m_printDevice;
+ QPageLayout m_pageLayout;
NSPrintInfo *printInfo;
PMResolution resolution;
QString outputFilename;
QString m_creator;
- bool fullPage;
QPaintEngine *paintEngine;
- bool hasCustomPaperSize;
- QSizeF customSize;
- bool hasCustomPageMargins;
- qreal leftMargin;
- qreal topMargin;
- qreal rightMargin;
- qreal bottomMargin;
QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant> valueCache;
- PMPaper customPaper;
+
QMacPrintEnginePrivate() : mode(QPrinter::ScreenResolution), state(QPrinter::Idle),
- orient(QPrinter::Portrait), printInfo(0), paintEngine(0),
- hasCustomPaperSize(false), hasCustomPageMargins(false) {}
+ m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))),
+ printInfo(0), paintEngine(0) {}
~QMacPrintEnginePrivate();
+
void initialize();
void releaseSession();
bool newPage_helper();
- void setPaperSize(QPrinter::PaperSize ps);
- QPrinter::PaperSize paperSize() const;
- void setPaperName(const QString &name);
- QList<QVariant> supportedResolutions() const;
+ void setPageSize(const QPageSize &pageSize);
inline bool isPrintSessionInitialized() const
{
return printInfo != 0;
diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h
index 581157c2e1..7d38b08d84 100644
--- a/src/plugins/platforms/cocoa/qt_mac_p.h
+++ b/src/plugins/platforms/cocoa/qt_mac_p.h
@@ -194,8 +194,6 @@ extern QPoint qt_mac_nativeMapFromParent(const QWidget *child, const QPoint &pt)
QFont qfontForThemeFont(ThemeFontID themeID);
-QColor qcolorForTheme(ThemeBrush brush);
-
QColor qcolorForThemeTextColor(ThemeTextColor themeColor);
struct QMacDndAnswerRecord {
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index e19a6be47b..d8f34fc3ed 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -77,6 +77,12 @@ enum {
D2DDebugDrawStaticTextItemTag,
D2DDebugDrawTextItemTag
};
+
+//Clipping flags
+enum {
+ UserClip = 0x1,
+ SimpleSystemClip = 0x2
+};
#define D2D_TAG(tag) d->dc()->SetTags(tag, tag)
Q_GUI_EXPORT QImage qt_imageForBrush(int brushStyle, bool invert);
@@ -286,7 +292,7 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
public:
QWindowsDirect2DPaintEnginePrivate(QWindowsDirect2DBitmap *bm)
: bitmap(bm)
- , clipPushed(false)
+ , clipFlags(0)
{
pen.reset();
brush.reset();
@@ -297,7 +303,7 @@ public:
QWindowsDirect2DBitmap *bitmap;
QPainterPath clipPath;
- bool clipPushed;
+ unsigned int clipFlags;
QPointF currentBrushOrigin;
@@ -381,14 +387,14 @@ public:
NULL,
D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND),
NULL);
- clipPushed = true;
+ clipFlags |= UserClip;
}
void popClip()
{
- if (clipPushed) {
+ if (clipFlags & UserClip) {
dc()->PopLayer();
- clipPushed = false;
+ clipFlags &= ~UserClip;
}
}
@@ -397,7 +403,7 @@ public:
Q_Q(const QWindowsDirect2DPaintEngine);
if (!q->state()->clipEnabled)
popClip();
- else if (!clipPushed)
+ else if (!(clipFlags & UserClip))
pushClip();
}
@@ -729,11 +735,29 @@ bool QWindowsDirect2DPaintEngine::begin(QPaintDevice * pdev)
d->bitmap->deviceContext()->begin();
d->dc()->SetTransform(D2D1::Matrix3x2F::Identity());
- QRect clip(0, 0, pdev->width(), pdev->height());
- if (!systemClip().isEmpty())
- clip &= systemClip().boundingRect();
+ if (systemClip().rectCount() > 1) {
+ QPainterPath p;
+ p.addRegion(systemClip());
- d->dc()->PushAxisAlignedClip(to_d2d_rect_f(clip), D2D1_ANTIALIAS_MODE_ALIASED);
+ ComPtr<ID2D1PathGeometry1> geometry = painterPathToPathGeometry(p);
+ if (!geometry)
+ return false;
+
+ d->dc()->PushLayer(D2D1::LayerParameters1(D2D1::InfiniteRect(),
+ geometry.Get(),
+ d->antialiasMode(),
+ D2D1::IdentityMatrix(),
+ 1.0,
+ NULL,
+ D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND),
+ NULL);
+ } else {
+ QRect clip(0, 0, pdev->width(), pdev->height());
+ if (!systemClip().isEmpty())
+ clip &= systemClip().boundingRect();
+ d->dc()->PushAxisAlignedClip(to_d2d_rect_f(clip), D2D1_ANTIALIAS_MODE_ALIASED);
+ d->clipFlags |= SimpleSystemClip;
+ }
D2D_TAG(D2DDebugDrawInitialStateTag);
@@ -746,7 +770,12 @@ bool QWindowsDirect2DPaintEngine::end()
// First pop any user-applied clipping
d->popClip();
// Now the system clip from begin() above
- d->dc()->PopAxisAlignedClip();
+ if (d->clipFlags & SimpleSystemClip) {
+ d->dc()->PopAxisAlignedClip();
+ d->clipFlags &= ~SimpleSystemClip;
+ } else {
+ d->dc()->PopLayer();
+ }
return d->bitmap->deviceContext()->end();
}
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 4fe2cae15e..13a0b46745 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -39,13 +39,16 @@
**
****************************************************************************/
-#include "qiosglobal.h"
#include "qiosinputcontext.h"
+
+#import <UIKit/UIGestureRecognizerSubclass.h>
+
+#include "qiosglobal.h"
#include "qioswindow.h"
#include "quiview.h"
#include <QGuiApplication>
-@interface QIOSKeyboardListener : NSObject {
+@interface QIOSKeyboardListener : UIGestureRecognizer {
@public
QIOSInputContext *m_context;
BOOL m_keyboardVisible;
@@ -63,7 +66,7 @@
- (id)initWithQIOSInputContext:(QIOSInputContext *)context
{
- self = [super init];
+ self = [super initWithTarget:self action:@selector(gestureTriggered)];
if (self) {
m_context = context;
m_keyboardVisible = NO;
@@ -82,6 +85,14 @@
}
}
Q_ASSERT(m_viewController);
+
+ // Attach 'hide keyboard' gesture to the window, but keep it disabled when the
+ // keyboard is not visible. Note that we never trigger the gesture the way it is intended
+ // since we don't want to cancel touch events and interrupt flicking etc. Instead we use
+ // the gesture framework more as an event filter and hide the keyboard silently.
+ self.enabled = NO;
+ self.delaysTouchesEnded = NO;
+ [m_viewController.view.window addGestureRecognizer:self];
}
[[NSNotificationCenter defaultCenter]
@@ -102,7 +113,9 @@
- (void) dealloc
{
+ [m_viewController.view.window removeGestureRecognizer:self];
[m_viewController release];
+
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:@"UIKeyboardWillShowNotification" object:nil];
@@ -131,16 +144,11 @@
- (void) keyboardDidChangeFrame:(NSNotification *)notification
{
+ Q_UNUSED(notification);
if (m_ignoreKeyboardChanges)
return;
- m_keyboardRect = [self getKeyboardRect:notification];
- m_context->emitKeyboardRectChanged();
- BOOL visible = m_keyboardRect.intersects(fromCGRect([UIScreen mainScreen].bounds));
- if (m_keyboardVisible != visible) {
- m_keyboardVisible = visible;
- m_context->emitInputPanelVisibleChanged();
- }
+ [self handleKeyboardRectChanged];
// If the keyboard was visible and docked from before, this is just a geometry
// change (normally caused by an orientation change). In that case, update scroll:
@@ -155,6 +163,7 @@
// Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked.
m_keyboardVisibleAndDocked = YES;
m_keyboardEndRect = [self getKeyboardRect:notification];
+ self.enabled = YES;
if (!m_duration) {
m_duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
m_curve = UIViewAnimationCurve([[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16);
@@ -169,9 +178,35 @@
// Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
m_keyboardVisibleAndDocked = NO;
m_keyboardEndRect = [self getKeyboardRect:notification];
+ self.enabled = NO;
m_context->scroll(0);
}
+- (void) handleKeyboardRectChanged
+{
+ QRectF rect = m_keyboardEndRect;
+ rect.moveTop(rect.y() + m_viewController.view.bounds.origin.y);
+ if (m_keyboardRect != rect) {
+ m_keyboardRect = rect;
+ m_context->emitKeyboardRectChanged();
+ }
+
+ BOOL visible = m_keyboardEndRect.intersects(fromCGRect([UIScreen mainScreen].bounds));
+ if (m_keyboardVisible != visible) {
+ m_keyboardVisible = visible;
+ m_context->emitInputPanelVisibleChanged();
+ }
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ QPointF p = fromCGPoint([[touches anyObject] locationInView:m_viewController.view]);
+ if (m_keyboardRect.contains(p))
+ m_context->hideInputPanel();
+
+ [super touchesMoved:touches withEvent:event];
+}
+
@end
QIOSInputContext::QIOSInputContext()
@@ -295,10 +330,15 @@ void QIOSInputContext::scroll(int y)
CGRect newBounds = view.bounds;
newBounds.origin.y = y;
+ QPointer<QIOSInputContext> self = this;
[UIView animateWithDuration:m_keyboardListener->m_duration delay:0
options:m_keyboardListener->m_curve
animations:^{ view.bounds = newBounds; }
- completion:0];
+ completion:^(BOOL){
+ if (self)
+ [m_keyboardListener handleKeyboardRectChanged];
+ }
+ ];
}
void QIOSInputContext::update(Qt::InputMethodQueries query)
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 96410952f9..5331d05ae9 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -120,7 +120,9 @@ static QString deviceModelIdentifier()
QIOSScreen::QIOSScreen(unsigned int screenIndex)
: QPlatformScreen()
- , m_uiScreen([[UIScreen screens] objectAtIndex:qMin(NSUInteger(screenIndex), [[UIScreen screens] count] - 1)])
+ , m_uiScreen([[UIScreen screens] count] > screenIndex
+ ? [[UIScreen screens] objectAtIndex:screenIndex]
+ : [UIScreen mainScreen])
, m_orientationListener(0)
{
QString deviceIdentifier = deviceModelIdentifier();
diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm
index d0088d415a..28fb23d57b 100644
--- a/src/plugins/platforms/ios/quiview_textinput.mm
+++ b/src/plugins/platforms/ios/quiview_textinput.mm
@@ -492,8 +492,17 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
if (!focusObject)
return;
- if ([text isEqualToString:@"\n"] && self.returnKeyType == UIReturnKeyDone)
- [self resignFirstResponder];
+ if ([text isEqualToString:@"\n"]) {
+ QKeyEvent press(QEvent::KeyPress, Qt::Key_Return, Qt::NoModifier);
+ QKeyEvent release(QEvent::KeyRelease, Qt::Key_Return, Qt::NoModifier);
+ [self sendEventToFocusObject:press];
+ [self sendEventToFocusObject:release];
+
+ if (self.returnKeyType == UIReturnKeyDone)
+ [self resignFirstResponder];
+
+ return;
+ }
QInputMethodEvent e;
e.setCommitString(QString::fromNSString(text));
diff --git a/src/plugins/platforms/qnx/qblackberrytheme.cpp b/src/plugins/platforms/qnx/qblackberrytheme.cpp
index a0f334d909..46ab4d7033 100644
--- a/src/plugins/platforms/qnx/qblackberrytheme.cpp
+++ b/src/plugins/platforms/qnx/qblackberrytheme.cpp
@@ -60,9 +60,11 @@ QBlackberryTheme::QBlackberryTheme(const QQnxIntegration *integration) : m_integ
m_defaultPalette.setBrush(QPalette::Disabled, QPalette::WindowText, color);
m_defaultPalette.setBrush(QPalette::Disabled, QPalette::Text, color);
- m_defaultPalette.setColor(QPalette::Window, QColor(18, 18, 18));
- m_defaultPalette.setColor(QPalette::Base, QColor(18, 18, 18));
+ color.setRgb(18, 18, 18);
+ m_defaultPalette.setColor(QPalette::Window, color);
+ m_defaultPalette.setColor(QPalette::Base, color);
m_defaultPalette.setColor(QPalette::AlternateBase, QColor(50, 50, 50));
+ m_defaultPalette.setColor(QPalette::Button, color);
m_defaultPalette.setBrush(QPalette::Highlight, QColor(0, 168, 223));
m_defaultPalette.setBrush(QPalette::HighlightedText, QColor(250, 250,250));
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index 3c08cc9f82..f1f9f5469c 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -70,8 +70,7 @@ QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool nee
if (result != 0)
qFatal("QQnxEglWindow: failed to set window alpha usage, errno=%d", errno);
- m_requestedBufferSize = screen()->rootWindow() == this ?
- screen()->geometry().size() : window->geometry().size();
+ m_requestedBufferSize = shouldMakeFullScreen() ? screen()->geometry().size() : window->geometry().size();
}
QQnxEglWindow::~QQnxEglWindow()
@@ -156,7 +155,7 @@ EGLSurface QQnxEglWindow::getSurface()
void QQnxEglWindow::setGeometry(const QRect &rect)
{
//If this is the root window, it has to be shown fullscreen
- const QRect &newGeometry = screen()->rootWindow() == this ? screen()->geometry() : rect;
+ const QRect &newGeometry = shouldMakeFullScreen() ? screen()->geometry() : rect;
//We need to request that the GL context updates
// the EGLsurface on which it is rendering.
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index 178ea121e6..5724fbd92a 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -457,7 +457,7 @@ void QQnxScreenEventHandler::handleTouchEvent(screen_event_t event, int qnxType)
m_touchPoints[touchId].area = QRectF(w->geometry().left() + windowPos[0] - (touchArea[0]>>1),
w->geometry().top() + windowPos[1] - (touchArea[1]>>1),
- 0.0, 0.0);
+ (touchArea[0]>>1), (touchArea[1]>>1));
QWindow *parent = w->parent();
while (parent) {
m_touchPoints[touchId].area.translate(parent->geometry().topLeft());
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
index 156ba8a780..b66de3cac5 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventthread.cpp
@@ -103,10 +103,10 @@ void QQnxScreenEventThread::run()
Q_SCREEN_CHECKERROR(screen_create_event(&event), "Failed to create screen event");
// block until screen event is available
- const int result = screen_get_event(m_screenContext, event, -1);
- Q_SCREEN_CRITICALERROR(result, "Failed to get screen event");
+ 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 (!result) {
+ if (error) {
errorCounter++;
if (errorCounter > 50)
m_quit = true;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 9ae2d01ab4..f11a009bca 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -242,19 +242,14 @@ QQnxWindow::~QQnxWindow()
void QQnxWindow::setGeometry(const QRect &rect)
{
QRect newGeometry = rect;
- if (screen()->rootWindow() == this) //If this is the root window, it has to be shown fullscreen
+ if (shouldMakeFullScreen())
newGeometry = screen()->geometry();
setGeometryHelper(newGeometry);
- // Send a geometry change event to Qt (triggers resizeEvent() in QWindow/QWidget).
-
- // Calling flushWindowSystemEvents() here would flush input events which
- // could result in re-entering QQnxWindow::setGeometry() again.
- QWindowSystemInterface::setSynchronousWindowsSystemEvents(true);
QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
- QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
- QWindowSystemInterface::setSynchronousWindowsSystemEvents(false);
+ if (isExposed())
+ QWindowSystemInterface::handleExposeEvent(window(), newGeometry);
}
void QQnxWindow::setGeometryHelper(const QRect &rect)
@@ -714,7 +709,7 @@ void QQnxWindow::initWindow()
if (window()->parent() && window()->parent()->handle())
setParent(window()->parent()->handle());
- if (screen()->rootWindow() == this) {
+ if (shouldMakeFullScreen()) {
setGeometryHelper(screen()->geometry());
QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry());
} else {
@@ -817,4 +812,9 @@ void QQnxWindow::windowPosted()
qqnxLgmonFramePosted(m_cover); // for performance measurements
}
+bool QQnxWindow::shouldMakeFullScreen() const
+{
+ return ((screen()->rootWindow() == this) && (QQnxIntegration::options() & QQnxIntegration::FullScreenApplication));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index e97e941a08..9a2006396f 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -112,6 +112,8 @@ public:
QByteArray groupName() const { return m_windowGroupName; }
void joinWindowGroup(const QByteArray &groupName);
+ bool shouldMakeFullScreen() const;
+
protected:
virtual int pixelFormat() const = 0;
virtual void resetBuffers() = 0;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index b6ff3dc3ce..f70b5b4e2b 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -1195,7 +1195,7 @@ static QList<FilterSpec> filterSpecs(const QStringList &filters,
const QRegExp filterSeparatorRE(QStringLiteral("[;\\s]+"));
const QString separator = QStringLiteral(";");
Q_ASSERT(filterSeparatorRE.isValid());
- // Split filter specification as 'Texts (*.txt[;] *.doc)'
+ // Split filter specification as 'Texts (*.txt[;] *.doc)', '*.txt[;] *.doc'
// into description and filters specification as '*.txt;*.doc'
foreach (const QString &filterString, filters) {
const int openingParenPos = filterString.lastIndexOf(QLatin1Char('('));
@@ -1203,8 +1203,10 @@ static QList<FilterSpec> filterSpecs(const QStringList &filters,
filterString.indexOf(QLatin1Char(')'), openingParenPos + 1) : -1;
FilterSpec filterSpec;
filterSpec.filter = closingParenPos == -1 ?
- QString(QLatin1Char('*')) :
+ filterString :
filterString.mid(openingParenPos + 1, closingParenPos - openingParenPos - 1).trimmed();
+ if (filterSpec.filter.isEmpty())
+ filterSpec.filter += QLatin1Char('*');
filterSpec.filter.replace(filterSeparatorRE, separator);
filterSpec.description = filterString;
if (hideFilterDetails && openingParenPos != -1) { // Do not show pattern in description
@@ -1559,7 +1561,7 @@ public:
QWindowsFileDialogHelper() {}
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
- { return true; }
+ { return false; }
virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
virtual QUrl directory() const Q_DECL_OVERRIDE;
virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index c45c34ae4d..e7e4028079 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -387,7 +387,12 @@ static int choosePixelFormat(HDC hdc,
iAttributes[i++] = WGL_DRAW_TO_WINDOW_ARB;
iAttributes[i++] = TRUE;
iAttributes[i++] = WGL_COLOR_BITS_ARB;
- iAttributes[i++] = 24;
+
+ iAttributes[i++] = (format.redBufferSize() > 0)
+ && (format.greenBufferSize() > 0)
+ && (format.blueBufferSize() > 0) ?
+ format.redBufferSize() + format.greenBufferSize() + format.blueBufferSize() :
+ 24;
switch (format.swapBehavior()) {
case QSurfaceFormat::SingleBuffer:
iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index e0e8753e14..de34663286 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -83,6 +83,7 @@
# include "qwindowssessionmanager.h"
#endif
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatforminputcontextfactory_p.h>
#include <QtCore/private/qeventdispatcher_win_p.h>
#include <QtCore/QDebug>
@@ -158,7 +159,7 @@ struct QWindowsIntegrationPrivate
#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
QOpenGLStaticContextPtr m_staticOpenGLContext;
#endif
- QWindowsInputContext m_inputContext;
+ QScopedPointer<QPlatformInputContext> m_inputContext;
#ifndef QT_NO_ACCESSIBILITY
QWindowsAccessibility m_accessibility;
#endif
@@ -224,6 +225,14 @@ QWindowsIntegration::~QWindowsIntegration()
{
}
+void QWindowsIntegration::initialize()
+{
+ if (QPlatformInputContext *pluginContext = QPlatformInputContextFactory::create())
+ d->m_inputContext.reset(pluginContext);
+ else
+ d->m_inputContext.reset(new QWindowsInputContext);
+}
+
bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
@@ -441,7 +450,7 @@ QPlatformDrag *QWindowsIntegration::drag() const
QPlatformInputContext * QWindowsIntegration::inputContext() const
{
- return &d->m_inputContext;
+ return d->m_inputContext.data();
}
#ifndef QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 2202ebd39e..0f417c8239 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -76,6 +76,7 @@ public:
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
#endif
virtual QAbstractEventDispatcher *createEventDispatcher() const;
+ void initialize() Q_DECL_OVERRIDE;
#ifndef QT_NO_CLIPBOARD
virtual QPlatformClipboard *clipboard() const;
# ifndef QT_NO_DRAGANDDROP
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
index 10136dbead..9b623048af 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.cpp
@@ -207,14 +207,24 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
, m_fbo(0)
, m_texture(0)
, m_screen(static_cast<QWinRTScreen*>(window->screen()->handle()))
+ , m_initialized(false)
{
window->setSurfaceType(QSurface::OpenGLSurface); // Required for flipping, but could be done in the swap
+}
- m_context->setFormat(window->requestedFormat());
- m_context->setScreen(window->screen());
- m_context->create();
+bool QWinRTBackingStore::initialize()
+{
+ if (m_initialized)
+ return true;
+
+ m_context->setFormat(window()->requestedFormat());
+ m_context->setScreen(window()->screen());
+ if (!m_context->create())
+ return false;
+
+ if (!m_context->makeCurrent(window()))
+ return false;
- m_context->makeCurrent(window);
glGenFramebuffers(1, &m_fbo);
glGenRenderbuffers(1, &m_rbo);
glGenTextures(1, &m_texture);
@@ -258,11 +268,14 @@ QWinRTBackingStore::QWinRTBackingStore(QWindow *window)
glProgramBinaryOES(m_shaderProgram, GL_PROGRAM_BINARY_ANGLE, binary.constData(), binary.size());
#endif
m_context->doneCurrent();
- resize(window->size(), QRegion());
+ m_initialized = true;
+ return true;
}
QWinRTBackingStore::~QWinRTBackingStore()
{
+ if (!m_initialized)
+ return;
glDeleteBuffers(1, &m_fbo);
glDeleteRenderbuffers(1, &m_rbo);
glDeleteTextures(1, &m_texture);
@@ -277,6 +290,8 @@ QPaintDevice *QWinRTBackingStore::paintDevice()
void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
Q_UNUSED(offset)
+ if (m_size.isEmpty())
+ return;
const QImage *image = static_cast<QImage *>(m_paintDevice.data());
@@ -334,10 +349,16 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents)
{
Q_UNUSED(staticContents)
+ if (!initialize())
+ return;
+
if (m_size == size)
return;
m_size = size;
+ if (m_size.isEmpty())
+ return;
+
m_paintDevice.reset(new QImage(m_size, QImage::Format_ARGB32_Premultiplied));
m_context->makeCurrent(window());
@@ -360,6 +381,7 @@ void QWinRTBackingStore::resize(const QSize &size, const QRegion &staticContents
void QWinRTBackingStore::beginPaint(const QRegion &region)
{
Q_UNUSED(region)
+ resize(window()->size(), QRegion());
}
void QWinRTBackingStore::endPaint()
diff --git a/src/plugins/platforms/winrt/qwinrtbackingstore.h b/src/plugins/platforms/winrt/qwinrtbackingstore.h
index 8be549b441..726f7c838f 100644
--- a/src/plugins/platforms/winrt/qwinrtbackingstore.h
+++ b/src/plugins/platforms/winrt/qwinrtbackingstore.h
@@ -62,6 +62,8 @@ public:
void resize(const QSize &size, const QRegion &staticContents);
private:
+ bool initialize();
+ bool m_initialized;
QSize m_size;
QScopedPointer<QPaintDevice> m_paintDevice;
QScopedPointer<QOpenGLContext> m_context;
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
index c7fa339fad..3da87de708 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -44,6 +44,14 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QFile>
+#ifndef Q_OS_WINPHONE
+#include <QtCore/QUuid>
+#include <QtGui/private/qfontengine_ft_p.h>
+#include <dwrite_1.h>
+#include <wrl.h>
+using namespace Microsoft::WRL;
+#endif // !Q_OS_WINPHONE
+
QT_BEGIN_NAMESPACE
QString QWinRTFontDatabase::fontDir() const
@@ -54,11 +62,315 @@ QString QWinRTFontDatabase::fontDir() const
const QString applicationDirPath = QCoreApplication::applicationDirPath();
fontDirectory = applicationDirPath + QLatin1String("/fonts");
if (!QFile::exists(fontDirectory)) {
- qWarning("No fonts directory found in application package.");
+#ifndef Q_OS_WINPHONE
+ if (m_fonts.isEmpty())
+#endif
+ qWarning("No fonts directory found in application package.");
fontDirectory = applicationDirPath;
}
}
return fontDirectory;
}
+#ifndef Q_OS_WINPHONE
+
+QWinRTFontDatabase::~QWinRTFontDatabase()
+{
+ foreach (IDWriteFontFile *fontFile, m_fonts.keys())
+ fontFile->Release();
+}
+
+QFont QWinRTFontDatabase::defaultFont() const
+{
+ return QFont(QStringLiteral("Segoe UI"));
+}
+
+void QWinRTFontDatabase::populateFontDatabase()
+{
+ ComPtr<IDWriteFactory1> factory;
+ HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_ISOLATED, __uuidof(IDWriteFactory1), &factory);
+ if (FAILED(hr)) {
+ qWarning("Failed to create DirectWrite factory: %s", qPrintable(qt_error_string(hr)));
+ QBasicFontDatabase::populateFontDatabase();
+ return;
+ }
+
+ ComPtr<IDWriteFontCollection> fontCollection;
+ hr = factory->GetSystemFontCollection(&fontCollection);
+ if (FAILED(hr)) {
+ qWarning("Failed to open system font collection: %s", qPrintable(qt_error_string(hr)));
+ QBasicFontDatabase::populateFontDatabase();
+ return;
+ }
+
+ int fontFamilyCount = fontCollection->GetFontFamilyCount();
+ for (int i = 0; i < fontFamilyCount; ++i) {
+ ComPtr<IDWriteFontFamily> fontFamily;
+ hr = fontCollection->GetFontFamily(i, &fontFamily);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font family: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ ComPtr<IDWriteLocalizedStrings> names;
+ hr = fontFamily->GetFamilyNames(&names);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font family names: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ quint32 familyNameLength;
+ hr = names->GetStringLength(0, &familyNameLength);
+ if (FAILED(hr)) {
+ qWarning("Unable to get family name length: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QVector<wchar_t> familyBuffer(familyNameLength + 1);
+ hr = names->GetString(0, familyBuffer.data(), familyBuffer.size());
+ if (FAILED(hr)) {
+ qWarning("Unable to create font family name: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength);
+
+ int fontCount = fontFamily->GetFontCount();
+ for (int j = 0; j < fontCount; ++j) {
+ ComPtr<IDWriteFont> font;
+ hr = fontFamily->GetFont(j, &font);
+ if (FAILED(hr)) {
+ qWarning("Unable to get base font: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ ComPtr<IDWriteFontFace> baseFontFace;
+ hr = font->CreateFontFace(&baseFontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ ComPtr<IDWriteFontFace1> fontFace;
+ hr = baseFontFace.As(&fontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ // Only try to load true-type fonts
+ DWRITE_FONT_FACE_TYPE type = fontFace->GetType();
+ if (!(type == DWRITE_FONT_FACE_TYPE_TRUETYPE
+ || type == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)) {
+ continue;
+ }
+
+ // We can't deal with multi-file fonts
+ quint32 fileCount;
+ hr = fontFace->GetFiles(&fileCount, NULL);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ if (fileCount != 1) // Should not happen as we only look at TT fonts
+ continue;
+
+ ComPtr<IDWriteLocalizedStrings> informationalStrings;
+ BOOL exists;
+ hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
+ &informationalStrings, &exists);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QString foundryName;
+ if (exists) {
+ quint32 length;
+ hr = informationalStrings->GetStringLength(0, &length);
+ if (FAILED(hr))
+ qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr)) {
+ QVector<wchar_t> buffer(length + 1);
+ hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
+ if (FAILED(hr))
+ qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr))
+ foundryName = QString::fromWCharArray(buffer.data(), length);
+ }
+ }
+
+ QFont::Weight weight;
+ switch (font->GetWeight()) {
+ case DWRITE_FONT_WEIGHT_THIN:
+ case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
+ case DWRITE_FONT_WEIGHT_LIGHT:
+ case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
+ weight = QFont::Light;
+ break;
+ default:
+ case DWRITE_FONT_WEIGHT_NORMAL:
+ case DWRITE_FONT_WEIGHT_MEDIUM:
+ weight = QFont::Normal;
+ break;
+ case DWRITE_FONT_WEIGHT_DEMI_BOLD:
+ weight = QFont::DemiBold;
+ break;
+ case DWRITE_FONT_WEIGHT_BOLD:
+ case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
+ weight = QFont::Bold;
+ break;
+ case DWRITE_FONT_WEIGHT_BLACK:
+ case DWRITE_FONT_WEIGHT_EXTRA_BLACK:
+ weight = QFont::Black;
+ break;
+ }
+
+ QFont::Style style;
+ switch (font->GetStyle()) {
+ default:
+ case DWRITE_FONT_STYLE_NORMAL:
+ style = QFont::StyleNormal;
+ break;
+ case DWRITE_FONT_STYLE_OBLIQUE:
+ style = QFont::StyleOblique;
+ break;
+ case DWRITE_FONT_STYLE_ITALIC:
+ style = QFont::StyleItalic;
+ break;
+ }
+
+ QFont::Stretch stretch;
+ switch (font->GetStretch()) {
+ default:
+ case DWRITE_FONT_STRETCH_UNDEFINED:
+ case DWRITE_FONT_STRETCH_NORMAL:
+ stretch = QFont::Unstretched;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
+ stretch = QFont::UltraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
+ stretch = QFont::ExtraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_CONDENSED:
+ stretch = QFont::Condensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
+ stretch = QFont::SemiCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
+ stretch = QFont::SemiExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXPANDED:
+ stretch = QFont::Expanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
+ stretch = QFont::ExtraExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
+ stretch = QFont::UltraExpanded;
+ break;
+ }
+
+ const bool fixedPitch = fontFace->IsMonospacedFont();
+
+ quint32 unicodeRange[4];
+ quint32 actualRangeCount;
+ hr = fontFace->GetUnicodeRanges(
+ 2, reinterpret_cast<DWRITE_UNICODE_RANGE *>(unicodeRange), &actualRangeCount);
+ if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices
+ qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ quint32 codePageRange[2] = { 0, 0 };
+ QSupportedWritingSystems writingSystems =
+ QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+
+ IDWriteFontFile *fontFile;
+ hr = fontFace->GetFiles(&fileCount, &fontFile);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
+ m_fonts.insert(fontFile, description);
+ registerFont(familyName, QString(), foundryName, weight, style, stretch,
+ true, true, 0, fixedPitch, writingSystems, fontFile);
+ }
+ }
+
+ QBasicFontDatabase::populateFontDatabase();
+}
+
+QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
+{
+ IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
+ if (!m_fonts.contains(fontFile))
+ return QBasicFontDatabase::fontEngine(fontDef, handle);
+
+ const void *referenceKey;
+ quint32 referenceKeySize;
+ HRESULT hr = fontFile->GetReferenceKey(&referenceKey, &referenceKeySize);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file reference key: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ ComPtr<IDWriteFontFileLoader> loader;
+ hr = fontFile->GetLoader(&loader);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file loader: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ ComPtr<IDWriteFontFileStream> stream;
+ hr =loader->CreateStreamFromKey(referenceKey, referenceKeySize, &stream);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file stream: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ quint64 fileSize;
+ hr = stream->GetFileSize(&fileSize);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file size: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+
+ const void *data;
+ void *context;
+ hr = stream->ReadFileFragment(&data, 0, fileSize, &context);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file data: %s", qPrintable(qt_error_string(hr)));
+ return 0;
+ }
+ const QByteArray fontData((const char *)data, fileSize);
+ stream->ReleaseFileFragment(context);
+
+ QFontEngine::FaceId faceId;
+ const FontDescription description = m_fonts.value(fontFile);
+ faceId.uuid = description.uuid;
+ faceId.index = description.index;
+ const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+ QFontEngineFT::GlyphFormat format = antialias ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono;
+ QFontEngineFT *engine = new QFontEngineFT(fontDef);
+ if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) {
+ delete engine;
+ return 0;
+ }
+
+ return engine;
+}
+
+void QWinRTFontDatabase::releaseHandle(void *handle)
+{
+ IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
+ if (m_fonts.contains(fontFile)) {
+ m_fonts.remove(fontFile);
+ fontFile->Release();
+ return;
+ }
+
+ QBasicFontDatabase::releaseHandle(handle);
+}
+
+#endif // !Q_OS_WINPHONE
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index 49e32470c2..6f194a10cc 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -46,10 +46,29 @@
QT_BEGIN_NAMESPACE
+#ifndef Q_OS_WINPHONE
+struct IDWriteFontFile;
+
+struct FontDescription
+{
+ quint32 index;
+ QByteArray uuid;
+};
+#endif
+
class QWinRTFontDatabase : public QBasicFontDatabase
{
public:
QString fontDir() const;
+#ifndef Q_OS_WINPHONE
+ ~QWinRTFontDatabase();
+ QFont defaultFont() const Q_DECL_OVERRIDE;
+ void populateFontDatabase() Q_DECL_OVERRIDE;
+ QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
+ void releaseHandle(void *handle) Q_DECL_OVERRIDE;
+private:
+ QHash<IDWriteFontFile *, FontDescription> m_fonts;
+#endif // !Q_OS_WINPHONE
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/winrt/qwinrtservices.cpp b/src/plugins/platforms/winrt/qwinrtservices.cpp
index 8f0a1d55bb..73c090351b 100644
--- a/src/plugins/platforms/winrt/qwinrtservices.cpp
+++ b/src/plugins/platforms/winrt/qwinrtservices.cpp
@@ -106,8 +106,7 @@ bool QWinRTServices::openDocument(const QUrl &url)
if (!(m_fileFactory && m_launcher))
return QPlatformServices::openDocument(url);
- QString pathString = QDir::toNativeSeparators(
- QDir::cleanPath(qApp->applicationDirPath().append(url.toString(QUrl::RemoveScheme))));
+ const QString pathString = QDir::toNativeSeparators(url.toLocalFile());
HSTRING_HEADER header; HSTRING path;
WindowsCreateStringReference((const wchar_t*)pathString.utf16(), pathString.length(), &header, &path);
IAsyncOperation<StorageFile*> *fileOp;
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 6e3cfb1d20..306bbc8174 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -11,6 +11,11 @@ DEFINES *= QT_NO_CAST_FROM_ASCII __WRL_NO_DEFAULT_LIB__ GL_GLEXT_PROTOTYPES
LIBS += $$QMAKE_LIBS_CORE
+!winphone {
+ LIBS += -ldwrite
+ INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/freetype/include
+}
+
SOURCES = \
main.cpp \
qwinrtbackingstore.cpp \
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index eaa4d05311..c183deb3b8 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -130,7 +130,7 @@ static void updateFormatFromContext(QSurfaceFormat &format)
}
format.setProfile(QSurfaceFormat::NoProfile);
- format.setOption(QSurfaceFormat::FormatOptions());
+ format.setOptions(QSurfaceFormat::FormatOptions());
if (format.renderableType() == QSurfaceFormat::OpenGL) {
if (format.version() < qMakePair(3, 0)) {
@@ -211,7 +211,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
// Don't bother with versions below ES 2.0
glVersions << 30 << 20;
// ES does not support any format option
- m_format.setOption(QSurfaceFormat::FormatOptions());
+ m_format.setOptions(QSurfaceFormat::FormatOptions());
}
Q_ASSERT(glVersions.count() > 0);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 030090d98d..a68ae8cf71 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -144,23 +144,23 @@ void QXcbConnection::updateScreens()
xcb_generic_error_t *error = NULL;
xcb_randr_get_output_primary_cookie_t primaryCookie =
xcb_randr_get_output_primary(xcb_connection(), xcbScreen->root);
- xcb_randr_get_screen_resources_current_cookie_t resourcesCookie =
- xcb_randr_get_screen_resources_current(xcb_connection(), xcbScreen->root);
+ xcb_randr_get_screen_resources_cookie_t resourcesCookie =
+ xcb_randr_get_screen_resources(xcb_connection(), xcbScreen->root);
xcb_randr_get_output_primary_reply_t *primary =
xcb_randr_get_output_primary_reply(xcb_connection(), primaryCookie, &error);
if (!primary || error) {
qWarning("QXcbConnection: Failed to get the primary output of the screen");
free(error);
} else {
- xcb_randr_get_screen_resources_current_reply_t *resources =
- xcb_randr_get_screen_resources_current_reply(xcb_connection(), resourcesCookie, &error);
+ xcb_randr_get_screen_resources_reply_t *resources =
+ xcb_randr_get_screen_resources_reply(xcb_connection(), resourcesCookie, &error);
if (!resources || error) {
qWarning("QXcbConnection: Failed to get the screen resources");
free(error);
} else {
xcb_timestamp_t timestamp = resources->config_timestamp;
- outputCount = xcb_randr_get_screen_resources_current_outputs_length(resources);
- xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_current_outputs(resources);
+ outputCount = xcb_randr_get_screen_resources_outputs_length(resources);
+ xcb_randr_output_t *outputs = xcb_randr_get_screen_resources_outputs(resources);
for (int i = 0; i < outputCount; i++) {
xcb_randr_get_output_info_reply_t *output =
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 6042ec0f87..bcadcd1f02 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -872,7 +872,6 @@ void QXcbDrag::handleLeave(QWindow *w, const xcb_client_message_event_t *event)
}
QWindowSystemInterface::handleDrag(w,0,QPoint(),Qt::IgnoreAction);
- updateAction(Qt::IgnoreAction);
xdnd_dragsource = 0;
xdnd_types.clear();
@@ -1045,7 +1044,8 @@ void QXcbDrag::timerEvent(QTimerEvent* e)
- showing dialog box on drop event where user's response takes more time than XdndDropTransactionTimeout (QTBUG-14493)
- dnd takes unusually long time to process data
*/
- t.drag->deleteLater();
+ if (t.drag)
+ t.drag->deleteLater();
transactions.removeAt(i--);
} else {
stopTimer = false;
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index 537898db48..7b0d337e7c 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -156,7 +156,7 @@ private:
xcb_window_t proxy_target;
QWindow *targetWindow;
// QWidget *embedding_widget;
- QDrag *drag;
+ QPointer<QDrag> drag;
QTime time;
};
QVector<Transaction> transactions;
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index aaa2e81c40..0bab341914 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -396,7 +396,6 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
case QPlatformIntegration::CursorFlashTime:
case QPlatformIntegration::KeyboardInputInterval:
case QPlatformIntegration::MouseDoubleClickInterval:
- case QPlatformIntegration::StartDragDistance:
case QPlatformIntegration::StartDragTime:
case QPlatformIntegration::KeyboardAutoRepeatRate:
case QPlatformIntegration::PasswordMaskDelay:
@@ -406,6 +405,20 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
case QPlatformIntegration::PasswordMaskCharacter:
// TODO using various xcb, gnome or KDE settings
break; // Not implemented, use defaults
+ case QPlatformIntegration::StartDragDistance: {
+ // The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but
+ // on a high-resolution screen it makes sense to increase it.
+ const QList<QXcbScreen *> &screens = defaultConnection()->screens();
+ qreal dpi = 100.0;
+ if (screens.length() > 0) {
+ const QXcbScreen *screen = screens.at(defaultConnection()->primaryScreen());
+ if (screen->logicalDpi().first > dpi)
+ dpi = screen->logicalDpi().first;
+ if (screen->logicalDpi().second > dpi)
+ dpi = screen->logicalDpi().second;
+ }
+ return 10.0 * dpi / 100.0;
+ }
case QPlatformIntegration::ShowIsFullScreen:
// X11 always has support for windows, but the
// window manager could prevent it (e.g. matchbox)
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 966090dbd5..0a52640c9a 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -53,10 +53,6 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformcursor.h>
-#ifdef XKBCOMMON_0_2_0
-#include <xkbcommon_workaround.h>
-#endif
-
#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
#endif
@@ -1398,23 +1394,7 @@ QString QXcbKeyboard::keysymToUnicode(xcb_keysym_t sym) const
QByteArray chars;
int bytes;
chars.resize(7);
-
-#ifdef XKBCOMMON_0_2_0
- if (needWorkaround(sym)) {
- quint32 codepoint;
- if (sym == XKB_KEY_KP_Space)
- codepoint = XKB_KEY_space & 0x7f;
- else
- codepoint = sym & 0x7f;
-
- bytes = utf32_to_utf8(codepoint, chars.data());
- } else {
- bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
- }
-#else
bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
-#endif
-
if (bytes == -1)
qWarning("QXcbKeyboard::handleKeyEvent - buffer too small");
chars.resize(bytes-1);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index b1ef3182ba..9f19841437 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -371,7 +371,6 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan
}
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
- QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
QDpi ldpi = logicalDpi();
@@ -409,6 +408,8 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
m_availableGeometry = m_geometry & virtualAvailableGeometry;
}
free(workArea);
+
+ QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), m_availableGeometry);
}
void QXcbScreen::updateRefreshRate()
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index aabcb84a08..d890398416 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1823,23 +1823,21 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
connection()->setTime(event->time);
const bool propertyDeleted = event->state == XCB_PROPERTY_DELETE;
- const xcb_atom_t netWmStateAtom = atom(QXcbAtom::_NET_WM_STATE);
- const xcb_atom_t wmStateAtom = atom(QXcbAtom::WM_STATE);
- if (event->atom == netWmStateAtom || event->atom == wmStateAtom) {
+ if (event->atom == atom(QXcbAtom::_NET_WM_STATE) || event->atom == atom(QXcbAtom::WM_STATE)) {
if (propertyDeleted)
return;
Qt::WindowState newState = Qt::WindowNoState;
- if (event->atom == wmStateAtom) { // WM_STATE: Quick check for 'Minimize'.
+ if (event->atom == atom(QXcbAtom::_NET_WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
const xcb_get_property_cookie_t get_cookie =
- xcb_get_property(xcb_connection(), 0, m_window, wmStateAtom,
+ xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
XCB_ATOM_ANY, 0, 1024);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
- if (reply && reply->format == 32 && reply->type == wmStateAtom) {
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::_NET_WM_STATE)) {
const quint32 *data = (const quint32 *)xcb_get_property_value(reply);
if (reply->length != 0 && XCB_WM_STATE_ICONIC == data[0])
newState = Qt::WindowMinimized;
@@ -1860,6 +1858,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
m_windowState = newState;
}
return;
+ } else if (event->atom == atom(QXcbAtom::_NET_WORKAREA) && event->window == m_screen->root()) {
+ m_screen->updateGeometry(event->time);
}
}
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index bfbec91e3c..e19bb921e1 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -131,12 +131,9 @@ contains(QT_CONFIG, xcb-qt) {
# libxkbcommon
contains(QT_CONFIG, xkbcommon-qt): {
+ QT_CONFIG += use-xkbcommon-x11support
include(../../../3rdparty/xkbcommon.pri)
} else {
LIBS += $$QMAKE_LIBS_XKBCOMMON
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XKBCOMMON
- equals(QMAKE_VERSION_XKBCOMMON, "0.2.0") {
- DEFINES += XKBCOMMON_0_2_0
- INCLUDEPATH += ../../../3rdparty/xkbcommon/xkbcommon/
- }
}
diff --git a/src/plugins/printsupport/cups/cups.pro b/src/plugins/printsupport/cups/cups.pro
index f617738a94..cdbb08b10a 100644
--- a/src/plugins/printsupport/cups/cups.pro
+++ b/src/plugins/printsupport/cups/cups.pro
@@ -6,13 +6,17 @@ load(qt_plugin)
QT += core-private gui-private printsupport printsupport-private
+LIBS_PRIVATE += -lcups
+
INCLUDEPATH += ../../../printsupport/kernel
SOURCES += main.cpp \
+ qppdprintdevice.cpp \
qcupsprintersupport.cpp \
qcupsprintengine.cpp
HEADERS += qcupsprintersupport_p.h \
+ qppdprintdevice.h \
qcupsprintengine_p.h
OTHER_FILES += cups.json
diff --git a/src/plugins/printsupport/cups/qcupsprintengine.cpp b/src/plugins/printsupport/cups/qcupsprintengine.cpp
index 2fecdc00e9..ec9963197c 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintengine.cpp
@@ -43,13 +43,17 @@
#ifndef QT_NO_PRINTER
+#include <qpa/qplatformprintplugin.h>
+#include <qpa/qplatformprintersupport.h>
+
#include <qiodevice.h>
#include <qfile.h>
#include <qdebug.h>
#include <qbuffer.h>
-#include "private/qcups_p.h"
-#include "qprinterinfo.h"
+#include "private/qcups_p.h" // Only needed for PPK_CupsOptions
+#include <QtGui/qpagelayout.h>
+#include <cups/cups.h>
#include <limits.h>
#include <math.h>
@@ -57,26 +61,13 @@
QT_BEGIN_NAMESPACE
+extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits);
+
QCupsPrintEngine::QCupsPrintEngine(QPrinter::PrinterMode m)
: QPdfPrintEngine(*new QCupsPrintEnginePrivate(m))
{
Q_D(QCupsPrintEngine);
-
- if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- const cups_dest_t* printers = cups.availablePrinters();
- int prnCount = cups.availablePrintersCount();
-
- for (int i = 0; i < prnCount; ++i) {
- if (printers[i].is_default) {
- d->printerName = QString::fromLocal8Bit(printers[i].name);
- d->setCupsDefaults();
- break;
- }
- }
-
- }
-
+ d->setupDefaultPrinter();
state = QPrinter::Idle;
}
@@ -89,31 +80,37 @@ void QCupsPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &v
Q_D(QCupsPrintEngine);
switch (int(key)) {
- case PPK_PaperSize:
- d->printerPaperSize = QPrinter::PaperSize(value.toInt());
- d->setPaperSize();
+ case PPK_PageSize:
+ d->setPageSize(QPageSize(QPageSize::PageSizeId(value.toInt())));
+ break;
+ case PPK_WindowsPageSize:
+ d->setPageSize(QPageSize(QPageSize::id(value.toInt())));
break;
- case PPK_CupsPageRect:
- d->cupsPageRect = value.toRect();
+ case PPK_CustomPaperSize:
+ d->setPageSize(QPageSize(value.toSizeF(), QPageSize::Point));
+ break;
+ case PPK_PaperName:
+ // Get the named page size from the printer if supported
+ d->setPageSize(d->m_printDevice.supportedPageSize(value.toString()));
break;
- case PPK_CupsPaperRect:
- d->cupsPaperRect = value.toRect();
+ case PPK_PrinterName:
+ d->changePrinter(value.toString());
break;
case PPK_CupsOptions:
d->cupsOptions = value.toStringList();
break;
- case PPK_CupsStringPageSize:
- case PPK_PaperName:
- d->cupsStringPageSize = value.toString();
- d->setPaperName();
+ case PPK_QPageSize:
+ d->setPageSize(value.value<QPageSize>());
break;
- case PPK_PrinterName:
- // prevent setting the defaults again for the same printer
- if (d->printerName != value.toString()) {
- d->printerName = value.toString();
- d->setCupsDefaults();
+ case PPK_QPageLayout: {
+ QPageLayout pageLayout = value.value<QPageLayout>();
+ if (pageLayout.isValid() && d->m_printDevice.isValidPageLayout(pageLayout, d->resolution)) {
+ d->m_pageLayout = pageLayout;
+ // Replace the page size with the CUPS page size
+ d->setPageSize(d->m_printDevice.supportedPageSize(pageLayout.pageSize()));
}
break;
+ }
default:
QPdfPrintEngine::setProperty(key, value);
break;
@@ -127,24 +124,15 @@ QVariant QCupsPrintEngine::property(PrintEnginePropertyKey key) const
QVariant ret;
switch (int(key)) {
case PPK_SupportsMultipleCopies:
+ // CUPS server always supports multiple copies, even if individual m_printDevice doesn't
ret = true;
break;
case PPK_NumberOfCopies:
ret = 1;
break;
- case PPK_CupsPageRect:
- ret = d->cupsPageRect;
- break;
- case PPK_CupsPaperRect:
- ret = d->cupsPaperRect;
- break;
case PPK_CupsOptions:
ret = d->cupsOptions;
break;
- case PPK_CupsStringPageSize:
- case PPK_PaperName:
- ret = d->cupsStringPageSize;
- break;
default:
ret = QPdfPrintEngine::property(key);
break;
@@ -173,17 +161,16 @@ bool QCupsPrintEnginePrivate::openPrintDevice()
return false;
}
outDevice = file;
- } else if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- QPair<int, QString> ret = cups.tempFd();
- if (ret.first < 0) {
+ } else {
+ char filename[512];
+ fd = cupsTempFd(filename, 512);
+ if (fd < 0) {
qWarning("QPdfPrinter: Could not open temporary file to print");
return false;
}
- cupsTempFile = ret.second;
+ cupsTempFile = QString::fromLocal8Bit(filename);
outDevice = new QFile();
- static_cast<QFile *>(outDevice)->open(ret.first, QIODevice::WriteOnly);
- fd = ret.first;
+ static_cast<QFile *>(outDevice)->open(fd, QIODevice::WriteOnly);
}
return true;
@@ -196,27 +183,19 @@ void QCupsPrintEnginePrivate::closePrintDevice()
if (!cupsTempFile.isEmpty()) {
QString tempFile = cupsTempFile;
cupsTempFile.clear();
- QCUPSSupport cups;
+
+ // Should never have got here without a printer, but check anyway
+ if (printerName.isEmpty()) {
+ qWarning("Could not determine printer to print to");
+ QFile::remove(tempFile);
+ return;
+ }
// Set up print options.
- QByteArray prnName;
QList<QPair<QByteArray, QByteArray> > options;
QVector<cups_option_t> cupsOptStruct;
- if (!printerName.isEmpty()) {
- prnName = printerName.toLocal8Bit();
- } else {
- QPrinterInfo def = QPrinterInfo::defaultPrinter();
- if (def.isNull()) {
- qWarning("Could not determine printer to print to");
- QFile::remove(tempFile);
- return;
- }
- prnName = def.printerName().toLocal8Bit();
- }
-
- if (!cupsStringPageSize.isEmpty())
- options.append(QPair<QByteArray, QByteArray>("media", cupsStringPageSize.toLocal8Bit()));
+ options.append(QPair<QByteArray, QByteArray>("media", m_pageLayout.pageSize().key().toLocal8Bit()));
if (copies > 1)
options.append(QPair<QByteArray, QByteArray>("copies", QString::number(copies).toLocal8Bit()));
@@ -225,24 +204,24 @@ void QCupsPrintEnginePrivate::closePrintDevice()
options.append(QPair<QByteArray, QByteArray>("Collate", "True"));
switch (duplex) {
- case QPrinter::DuplexNone:
+ case QPrint::DuplexNone:
options.append(QPair<QByteArray, QByteArray>("sides", "one-sided"));
break;
- case QPrinter::DuplexAuto:
- if (!landscape)
+ case QPrint::DuplexAuto:
+ if (m_pageLayout.orientation() == QPageLayout::Portrait)
options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
else
options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
break;
- case QPrinter::DuplexLongSide:
+ case QPrint::DuplexLongSide:
options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-long-edge"));
break;
- case QPrinter::DuplexShortSide:
+ case QPrint::DuplexShortSide:
options.append(QPair<QByteArray, QByteArray>("sides", "two-sided-short-edge"));
break;
}
- if (QCUPSSupport::cupsVersion() >= 10300 && landscape)
+ if (m_pageLayout.orientation() == QPageLayout::Landscape)
options.append(QPair<QByteArray, QByteArray>("landscape", ""));
QStringList::const_iterator it = cupsOptions.constBegin();
@@ -260,164 +239,85 @@ void QCupsPrintEnginePrivate::closePrintDevice()
// Print the file.
cups_option_t* optPtr = cupsOptStruct.size() ? &cupsOptStruct.first() : 0;
- cups.printFile(prnName.constData(), tempFile.toLocal8Bit().constData(),
- title.toLocal8Bit().constData(), cupsOptStruct.size(), optPtr);
+ cupsPrintFile(printerName.toLocal8Bit().constData(), tempFile.toLocal8Bit().constData(),
+ title.toLocal8Bit().constData(), cupsOptStruct.size(), optPtr);
QFile::remove(tempFile);
}
}
-void QCupsPrintEnginePrivate::updatePaperSize()
+void QCupsPrintEnginePrivate::setupDefaultPrinter()
{
- if (printerPaperSize == QPrinter::Custom) {
- paperSize = customPaperSize;
- } else if (!cupsPaperRect.isNull()) {
- QRect r = cupsPaperRect;
- paperSize = r.size();
- } else {
- QPdf::PaperSize s = QPdf::paperSize(printerPaperSize);
- paperSize = QSize(s.width, s.height);
+ // Should never have reached here if no plugin available, but check just in case
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (!ps)
+ return;
+
+ // Get default printer id, if no default then use the first available
+ // TODO Find way to remove printerName from base class?
+ printerName = ps->defaultPrintDeviceId();
+ if (printerName.isEmpty()) {
+ QStringList list = ps->availablePrintDeviceIds();
+ if (list.size() > 0)
+ printerName = list.at(0);
}
-}
-void QCupsPrintEnginePrivate::setPaperSize()
-{
- if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(printerPaperSize));
-
- if (cups.currentPPD()) {
- cupsStringPageSize = QLatin1String("Custom");
- const ppd_option_t* pageSizes = cups.pageSizes();
- for (int i = 0; i < pageSizes->num_choices; ++i) {
- QByteArray cupsPageSize = pageSizes->choices[i].choice;
- QRect tmpCupsPaperRect = cups.paperRect(cupsPageSize);
- QRect tmpCupsPageRect = cups.pageRect(cupsPageSize);
-
- if (qAbs(size.width - tmpCupsPaperRect.width()) < 5 && qAbs(size.height - tmpCupsPaperRect.height()) < 5) {
- cupsPaperRect = tmpCupsPaperRect;
- cupsPageRect = tmpCupsPageRect;
- cupsStringPageSize = pageSizes->choices[i].text;
- leftMargin = cupsPageRect.x() - cupsPaperRect.x();
- topMargin = cupsPageRect.y() - cupsPaperRect.y();
- rightMargin = cupsPaperRect.right() - cupsPageRect.right();
- bottomMargin = cupsPaperRect.bottom() - cupsPageRect.bottom();
-
- updatePaperSize();
- break;
- }
- }
- }
- }
+ // Should never have reached here if no printers available, but check just in case
+ if (printerName.isEmpty())
+ return;
+
+ m_printDevice = ps->createPrintDevice(printerName);
+ if (!m_printDevice.isValid())
+ return;
+
+ // Setup the printer defaults
+ duplex = m_printDevice.defaultDuplexMode();
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+ // CUPS server always supports collation, even if individual m_printDevice doesn't
+ collate = true;
+ setPageSize(m_printDevice.defaultPageSize());
}
-void QCupsPrintEnginePrivate::setPaperName()
+void QCupsPrintEnginePrivate::changePrinter(const QString &newPrinter)
{
- if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- if (cups.currentPPD()) {
- const ppd_option_t* pageSizes = cups.pageSizes();
- bool foundPaperName = false;
- for (int i = 0; i < pageSizes->num_choices; ++i) {
- if (cupsStringPageSize == pageSizes->choices[i].text) {
- foundPaperName = true;
- QByteArray cupsPageSize = pageSizes->choices[i].choice;
- cupsPaperRect = cups.paperRect(cupsPageSize);
- cupsPageRect = cups.pageRect(cupsPageSize);
- leftMargin = cupsPageRect.x() - cupsPaperRect.x();
- topMargin = cupsPageRect.y() - cupsPaperRect.y();
- rightMargin = cupsPaperRect.right() - cupsPageRect.right();
- bottomMargin = cupsPaperRect.bottom() - cupsPageRect.bottom();
- printerPaperSize = QPrinter::Custom;
- customPaperSize = cupsPaperRect.size();
- for (int ps = 0; ps < QPrinter::NPageSize; ++ps) {
- QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
- if (qAbs(size.width - cupsPaperRect.width()) < 5 && qAbs(size.height - cupsPaperRect.height()) < 5) {
- printerPaperSize = static_cast<QPrinter::PaperSize>(ps);
- customPaperSize = QSize();
- break;
- }
- }
- updatePaperSize();
- break;
- }
- }
- if (!foundPaperName)
- cupsStringPageSize = QString();
- }
- }
+ // Don't waste time if same printer name
+ if (newPrinter == printerName)
+ return;
+
+ // Should never have reached here if no plugin available, but check just in case
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (!ps)
+ return;
+
+ // Try create the printer, only use it if it returns valid
+ QPrintDevice printDevice = ps->createPrintDevice(newPrinter);
+ if (!m_printDevice.isValid())
+ return;
+ m_printDevice.swap(printDevice);
+ printerName = m_printDevice.id();
+
+ // Check if new printer supports current settings, otherwise us defaults
+ if (duplex != QPrint::DuplexAuto && !m_printDevice.supportedDuplexModes().contains(duplex))
+ duplex = m_printDevice.defaultDuplexMode();
+ QPrint::ColorMode colorMode = grayscale ? QPrint::GrayScale : QPrint::Color;
+ if (!m_printDevice.supportedColorModes().contains(colorMode))
+ grayscale = m_printDevice.defaultColorMode() == QPrint::GrayScale;
+
+ // Get the equivalent page size for this printer as supported names may be different
+ setPageSize(m_pageLayout.pageSize());
}
-void QCupsPrintEnginePrivate::setCupsDefaults()
+void QCupsPrintEnginePrivate::setPageSize(const QPageSize &pageSize)
{
- if (QCUPSSupport::isAvailable()) {
- int cupsPrinterIndex = -1;
- QCUPSSupport cups;
-
- const cups_dest_t* printers = cups.availablePrinters();
- int prnCount = cups.availablePrintersCount();
- for (int i = 0; i < prnCount; ++i) {
- QString name = QString::fromLocal8Bit(printers[i].name);
- if (name == printerName) {
- cupsPrinterIndex = i;
- break;
- }
- }
-
- if (cupsPrinterIndex < 0)
- return;
-
- cups.setCurrentPrinter(cupsPrinterIndex);
-
- if (cups.currentPPD()) {
- const ppd_option_t *ppdDuplex = cups.ppdOption("Duplex");
- if (ppdDuplex) {
- if (qstrcmp(ppdDuplex->defchoice, "DuplexTumble") == 0)
- duplex = QPrinter::DuplexShortSide;
- else if (qstrcmp(ppdDuplex->defchoice, "DuplexNoTumble") == 0)
- duplex = QPrinter::DuplexLongSide;
- else
- duplex = QPrinter::DuplexNone;
- }
-
- grayscale = !cups.currentPPD()->color_device;
-
- const ppd_option_t *ppdCollate = cups.ppdOption("Collate");
- if (ppdCollate)
- collate = qstrcmp(ppdCollate->defchoice, "True") == 0;
-
- const ppd_option_t* pageSizes = cups.pageSizes();
- QByteArray cupsPageSize;
- for (int i = 0; i < pageSizes->num_choices; ++i) {
- if (static_cast<int>(pageSizes->choices[i].marked) == 1) {
- cupsPageSize = pageSizes->choices[i].choice;
- cupsStringPageSize = pageSizes->choices[i].text;
- }
- }
-
- cupsOptions = cups.options();
- cupsPaperRect = cups.paperRect(cupsPageSize);
- cupsPageRect = cups.pageRect(cupsPageSize);
-
- for (int ps = 0; ps < QPrinter::NPageSize; ++ps) {
- QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(ps));
- if (qAbs(size.width - cupsPaperRect.width()) < 5 && qAbs(size.height - cupsPaperRect.height()) < 5) {
- printerPaperSize = static_cast<QPrinter::PaperSize>(ps);
-
- leftMargin = cupsPageRect.x() - cupsPaperRect.x();
- topMargin = cupsPageRect.y() - cupsPaperRect.y();
- rightMargin = cupsPaperRect.right() - cupsPageRect.right();
- bottomMargin = cupsPaperRect.bottom() - cupsPageRect.bottom();
-
- updatePaperSize();
- break;
- }
- }
- }
+ if (pageSize.isValid()) {
+ // Find if the requested page size has a matching printer page size, if so use its defined name instead
+ QPageSize printerPageSize = m_printDevice.supportedPageSize(pageSize);
+ QPageSize usePageSize = printerPageSize.isValid() ? printerPageSize : pageSize;
+ QMarginsF printable = m_printDevice.printableMargins(usePageSize, m_pageLayout.orientation(), resolution);
+ m_pageLayout.setPageSize(usePageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units()));
}
}
-
QT_END_NAMESPACE
#endif // QT_NO_PRINTER
diff --git a/src/plugins/printsupport/cups/qcupsprintengine_p.h b/src/plugins/printsupport/cups/qcupsprintengine_p.h
index db947a0232..393fef42a3 100644
--- a/src/plugins/printsupport/cups/qcupsprintengine_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintengine_p.h
@@ -61,9 +61,8 @@
#include <QtGui/qpaintengine.h>
#include <private/qpaintengine_p.h>
+#include <private/qprintdevice_p.h>
#include <private/qprintengine_pdf_p.h>
-#include <QtPrintSupport/qprintengine.h>
-#include <private/qcups_p.h>
QT_BEGIN_NAMESPACE
@@ -95,18 +94,15 @@ public:
bool openPrintDevice();
void closePrintDevice();
- void updatePaperSize();
- void setPaperSize();
- void setPaperName();
- void setCupsDefaults();
-
private:
Q_DISABLE_COPY(QCupsPrintEnginePrivate)
+ void setupDefaultPrinter();
+ void changePrinter(const QString &newPrinter);
+ void setPageSize(const QPageSize &pageSize);
+
+ QPrintDevice m_printDevice;
QStringList cupsOptions;
- QString cupsStringPageSize;
- QRect cupsPaperRect;
- QRect cupsPageRect;
QString cupsTempFile;
};
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport.cpp b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
index b9f0c394f8..b2abb07fc7 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport.cpp
+++ b/src/plugins/printsupport/cups/qcupsprintersupport.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -44,7 +45,9 @@
#ifndef QT_NO_PRINTER
#include "qcupsprintengine_p.h"
+#include "qppdprintdevice.h"
#include <private/qprinterinfo_p.h>
+#include <private/qprintdevice_p.h>
#include <QtPrintSupport/QPrinterInfo>
@@ -55,18 +58,13 @@
QT_BEGIN_NAMESPACE
-QCupsPrinterSupport::QCupsPrinterSupport() : QPlatformPrinterSupport(),
- m_cups(QLatin1String("cups"), 2),
- m_cupsPrinters(0),
- m_cupsPrintersCount(0)
+QCupsPrinterSupport::QCupsPrinterSupport()
+ : QPlatformPrinterSupport()
{
- loadCups();
- loadCupsPrinters();
}
QCupsPrinterSupport::~QCupsPrinterSupport()
{
- freeCupsPrinters();
}
QPrintEngine *QCupsPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode)
@@ -80,85 +78,42 @@ QPaintEngine *QCupsPrinterSupport::createPaintEngine(QPrintEngine *engine, QPrin
return static_cast<QCupsPrintEngine *>(engine);
}
-QList<QPrinter::PaperSize> QCupsPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const
+QPrintDevice QCupsPrinterSupport::createPrintDevice(const QString &id)
{
- return QCUPSSupport::getCupsPrinterPaperSizes(printerIndex(printerInfo));
+ return QPlatformPrinterSupport::createPrintDevice(new QPpdPrintDevice(id));
}
-QList<QPair<QString, QSizeF> > QCupsPrinterSupport::supportedSizesWithNames(const QPrinterInfo &printerInfo) const
+QStringList QCupsPrinterSupport::availablePrintDeviceIds() const
{
- return QCUPSSupport::getCupsPrinterPaperSizesWithNames(printerIndex(printerInfo));
-}
-
-void QCupsPrinterSupport::loadCups()
-{
- cupsGetDests = (CupsGetDests) m_cups.resolve("cupsGetDests");
- cupsFreeDests = (CupsFreeDests) m_cups.resolve("cupsFreeDests");
- cupsGetOption = (CupsGetOption) m_cups.resolve("cupsGetOption");
-}
-
-void QCupsPrinterSupport::freeCupsPrinters()
-{
- if (cupsFreeDests && m_cupsPrintersCount) {
- cupsFreeDests(m_cupsPrintersCount, m_cupsPrinters);
- m_cupsPrintersCount = 0;
- m_cupsPrinters = 0;
+ QStringList list;
+ cups_dest_t *dests;
+ int count = cupsGetDests(&dests);
+ for (int i = 0; i < count; ++i) {
+ QString printerId = QString::fromLocal8Bit(dests[i].name);
+ if (dests[i].instance)
+ printerId += QLatin1Char('/') + QString::fromLocal8Bit(dests[i].instance);
+ list.append(printerId);
}
+ cupsFreeDests(count, dests);
+ return list;
}
-void QCupsPrinterSupport::loadCupsPrinters()
-{
- freeCupsPrinters();
- m_printers.clear();
-
- if (cupsGetDests)
- m_cupsPrintersCount = cupsGetDests(&m_cupsPrinters);
-
- for (int i = 0; i < m_cupsPrintersCount; ++i) {
- QString printerName = QString::fromLocal8Bit(m_cupsPrinters[i].name);
- if (m_cupsPrinters[i].instance)
- printerName += QLatin1Char('/') + QString::fromLocal8Bit(m_cupsPrinters[i].instance);
- QString description = cupsOption(i, "printer-info");
- QString location = cupsOption(i, "printer-location");
- QString makeAndModel = cupsOption(i, "printer-make-and-model");
- QPrinterInfo printer = createPrinterInfo(printerName, description, location, makeAndModel,
- m_cupsPrinters[i].is_default, i);
- m_printers.append(printer);
- }
-}
-
-QList<QPrinterInfo> QCupsPrinterSupport::availablePrinters()
-{
- loadCupsPrinters();
- return QPlatformPrinterSupport::availablePrinters();
-}
-
-QString QCupsPrinterSupport::printerOption(const QPrinterInfo &printer, const QString &key) const
-{
- return cupsOption(printerIndex(printer), key);
-}
-
-QString QCupsPrinterSupport::cupsOption(int i, const QString &key) const
-{
- QString value;
- if (i > -1 && i < m_cupsPrintersCount && cupsGetOption)
- value = cupsGetOption(key.toLocal8Bit(), m_cupsPrinters[i].num_options, m_cupsPrinters[i].options);
- return value;
-}
-
-PrinterOptions QCupsPrinterSupport::printerOptions(const QPrinterInfo &printer) const
+QString QCupsPrinterSupport::defaultPrintDeviceId() const
{
- PrinterOptions options;
- int p = printerIndex(printer);
- if (p <= -1 || p >= m_cupsPrintersCount)
- return options;
- int numOptions = m_cupsPrinters[p].num_options;
- for (int i = 0; i < numOptions; ++i) {
- QString name = m_cupsPrinters[p].options[i].name;
- QString value = m_cupsPrinters[p].options[i].value;
- options.insert(name, value);
+ QString printerId;
+ cups_dest_t *dests;
+ int count = cupsGetDests(&dests);
+ for (int i = 0; i < count; ++i) {
+ if (dests[i].is_default) {
+ printerId = QString::fromLocal8Bit(dests[i].name);
+ if (dests[i].instance) {
+ printerId += QLatin1Char('/') + QString::fromLocal8Bit(dests[i].instance);
+ break;
+ }
+ }
}
- return options;
+ cupsFreeDests(count, dests);
+ return printerId;
}
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/cups/qcupsprintersupport_p.h b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
index d42c0d2630..1cba4e997b 100644
--- a/src/plugins/printsupport/cups/qcupsprintersupport_p.h
+++ b/src/plugins/printsupport/cups/qcupsprintersupport_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the plugins of the Qt Toolkit.
@@ -42,49 +43,29 @@
#ifndef QCUPSPRINTERSUPPORT_H
#define QCUPSPRINTERSUPPORT_H
-#include <QtCore/qfeatures.h> // Some feature dependencies might define QT_NO_PRINTER
-#ifndef QT_NO_PRINTER
-
#include <qpa/qplatformprintersupport.h>
-#include <QtCore/qlibrary.h>
-#include <QtCore/qlist.h>
+#ifndef QT_NO_PRINTER
-#include <cups/cups.h>
+#include <QtCore/qstringlist.h>
QT_BEGIN_NAMESPACE
-typedef int (*CupsGetDests)(cups_dest_t **dests);
-typedef void (*CupsFreeDests)(int num_dests, cups_dest_t *dests);
-typedef const char* (*CupsGetOption)(const char *name, int num_options, cups_option_t *options);
-
class QCupsPrinterSupport : public QPlatformPrinterSupport
{
public:
QCupsPrinterSupport();
~QCupsPrinterSupport();
- virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode);
- virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode);
- virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
- virtual QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &) const;
- virtual QList<QPrinterInfo> availablePrinters();
- virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const;
- virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const;
+ QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE;
+ QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) Q_DECL_OVERRIDE;
+
+ QPrintDevice createPrintDevice(const QString &id) Q_DECL_OVERRIDE;
+ QStringList availablePrintDeviceIds() const Q_DECL_OVERRIDE;
+ QString defaultPrintDeviceId() const Q_DECL_OVERRIDE;
private:
- void loadCups();
- void loadCupsPrinters();
- void freeCupsPrinters();
QString cupsOption(int i, const QString &key) const;
-
- QLibrary m_cups;
- cups_dest_t *m_cupsPrinters;
- int m_cupsPrintersCount;
-
- CupsGetDests cupsGetDests;
- CupsFreeDests cupsFreeDests;
- CupsGetOption cupsGetOption;
};
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.cpp b/src/plugins/printsupport/cups/qppdprintdevice.cpp
new file mode 100644
index 0000000000..56ae5600c4
--- /dev/null
+++ b/src/plugins/printsupport/cups/qppdprintdevice.cpp
@@ -0,0 +1,503 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qppdprintdevice.h"
+
+#include <QtCore/QMimeDatabase>
+#include <qdebug.h>
+
+#ifndef QT_LINUXBASE // LSB merges everything into cups.h
+#include <cups/language.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+QPpdPrintDevice::QPpdPrintDevice()
+ : QPlatformPrintDevice(),
+ m_cupsDest(0),
+ m_ppd(0)
+{
+}
+
+QPpdPrintDevice::QPpdPrintDevice(const QString &id)
+ : QPlatformPrintDevice(id),
+ m_cupsDest(0),
+ m_ppd(0)
+{
+ if (!id.isEmpty()) {
+
+ // TODO For now each dest is an individual device
+ QStringList parts = id.split(QLatin1Char('/'));
+ m_cupsName = parts.at(0).toUtf8();
+ if (parts.size() > 1)
+ m_cupsInstance = parts.at(1).toUtf8();
+ loadPrinter();
+
+ if (m_cupsDest && m_ppd) {
+ m_name = printerOption("printer-info");
+ m_location = printerOption("printer-location");
+ m_makeAndModel = printerOption("printer-make-and-model");
+ cups_ptype_e type = printerTypeFlags();
+ m_isRemote = type & CUPS_PRINTER_REMOTE;
+ // Note this is if the hardware does multiple copies, not if Cups can
+ m_supportsMultipleCopies = type & CUPS_PRINTER_COPIES;
+ // Note this is if the hardware does collation, not if Cups can
+ m_supportsCollateCopies = type & CUPS_PRINTER_COLLATE;
+
+ // Custom Page Size support
+ // Cups cups_ptype_e CUPS_PRINTER_VARIABLE
+ // 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]);
+ }
+ }
+}
+
+QPpdPrintDevice::QPpdPrintDevice(const QPpdPrintDevice &other)
+ : QPlatformPrintDevice(other),
+ m_cupsDest(0),
+ m_ppd(0)
+{
+ m_cupsName = other.m_cupsName;
+ m_cupsInstance = other.m_cupsInstance;
+ loadPrinter();
+}
+
+QPpdPrintDevice::~QPpdPrintDevice()
+{
+ if (m_ppd)
+ ppdClose(m_ppd);
+ if (m_cupsDest)
+ cupsFreeDests(1, m_cupsDest);
+ m_cupsDest = 0;
+ m_ppd = 0;
+}
+
+QPpdPrintDevice &QPpdPrintDevice::operator=(const QPpdPrintDevice &other)
+{
+ m_cupsName = other.m_cupsName;
+ m_cupsInstance = other.m_cupsInstance;
+ if (other.m_cupsDest && other.m_ppd)
+ loadPrinter();
+ return *this;
+}
+
+bool QPpdPrintDevice::operator==(const QPpdPrintDevice &other) const
+{
+ return (m_id == other.m_id);
+}
+
+bool QPpdPrintDevice::isValid() const
+{
+ return m_cupsDest && m_ppd;
+}
+
+bool QPpdPrintDevice::isDefault() const
+{
+ return printerTypeFlags() & CUPS_PRINTER_DEFAULT;
+}
+
+QPrint::DeviceState QPpdPrintDevice::state() const
+{
+ // 3 = idle, 4 = printing, 5 = stopped
+ // More details available from printer-state-message and printer-state-reasons
+ int state = printerOption(QStringLiteral("printer-state")).toInt();
+ if (state == 3)
+ return QPrint::Idle;
+ else if (state == 4)
+ return QPrint::Active;
+ else
+ return QPrint::Error;
+}
+
+void QPpdPrintDevice::loadPageSizes() const
+{
+ m_pageSizes.clear();
+ m_printableMargins.clear();
+
+ ppd_option_t *pageSizes = ppdFindOption(m_ppd, "PageSize");
+ if (pageSizes) {
+ for (int i = 0; i < pageSizes->num_choices; ++i) {
+ const ppd_size_t *ppdSize = ppdPageSize(m_ppd, pageSizes->choices[i].choice);
+ if (ppdSize) {
+ // Returned size is in points
+ QString key = QString::fromUtf8(ppdSize->name);
+ QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
+ QString name = QString::fromUtf8(pageSizes->choices[i].text);
+ if (!size.isEmpty()) {
+ QPageSize ps = createPageSize(key, size, name);
+ if (ps.isValid()) {
+ m_pageSizes.append(ps);
+ m_printableMargins.insert(key, QMarginsF(ppdSize->left, ppdSize->length - ppdSize->top,
+ ppdSize->width - ppdSize->right, ppdSize->bottom));
+ }
+ }
+ }
+ }
+ m_havePageSizes = true;
+ }
+}
+
+QPageSize QPpdPrintDevice::defaultPageSize() const
+{
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "PageSize");
+ if (defaultChoice) {
+ ppd_size_t *ppdSize = ppdPageSize(m_ppd, defaultChoice->choice);
+ if (ppdSize) {
+ // Returned size is in points
+ QString key = QString::fromUtf8(ppdSize->name);
+ QSize size = QSize(qRound(ppdSize->width), qRound(ppdSize->length));
+ QString name = QString::fromUtf8(defaultChoice->text);
+ return createPageSize(key, size, name);
+ }
+ }
+ return QPageSize();
+}
+
+QMarginsF QPpdPrintDevice::printableMargins(const QPageSize &pageSize,
+ QPageLayout::Orientation orientation,
+ int resolution) const
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(resolution)
+ if (!m_havePageSizes)
+ loadPageSizes();
+ // TODO Orientation?
+ if (m_printableMargins.contains(pageSize.key()))
+ return m_printableMargins.value(pageSize.key());
+ return m_customMargins;
+}
+
+void QPpdPrintDevice::loadResolutions() const
+{
+ m_resolutions.clear();
+
+ // Try load standard PPD options first
+ ppd_option_t *resolutions = ppdFindOption(m_ppd, "Resolution");
+ if (resolutions) {
+ for (int i = 0; i < resolutions->num_choices; ++i) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ // If no result, try just the default
+ if (m_resolutions.size() == 0) {
+ resolutions = ppdFindOption(m_ppd, "DefaultResolution");
+ if (resolutions) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ // If still no result, then try HP's custom options
+ if (m_resolutions.size() == 0) {
+ resolutions = ppdFindOption(m_ppd, "HPPrintQuality");
+ if (resolutions) {
+ for (int i = 0; i < resolutions->num_choices; ++i) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[i].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ }
+ if (m_resolutions.size() == 0) {
+ resolutions = ppdFindOption(m_ppd, "DefaultHPPrintQuality");
+ if (resolutions) {
+ int res = QPrintUtils::parsePpdResolution(resolutions->choices[0].choice);
+ if (res > 0)
+ m_resolutions.append(res);
+ }
+ }
+ m_haveResolutions = true;
+}
+
+int QPpdPrintDevice::defaultResolution() const
+{
+ // Try load standard PPD option first
+ ppd_option_t *resolution = ppdFindOption(m_ppd, "DefaultResolution");
+ if (resolution) {
+ int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
+ if (res > 0)
+ return res;
+ }
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "Resolution");
+ if (defaultChoice) {
+ int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
+ if (res > 0)
+ return res;
+ }
+ // If still no result, then try HP's custom options
+ resolution = ppdFindOption(m_ppd, "DefaultHPPrintQuality");
+ if (resolution) {
+ int res = QPrintUtils::parsePpdResolution(resolution->choices[0].choice);
+ if (res > 0)
+ return res;
+ }
+ defaultChoice = ppdFindMarkedChoice(m_ppd, "HPPrintQuality");
+ if (defaultChoice) {
+ int res = QPrintUtils::parsePpdResolution(defaultChoice->choice);
+ if (res > 0)
+ return res;
+ }
+ // Otherwise return a sensible default.
+ // TODO What is sensible? 150? 300?
+ return 72;
+}
+
+void QPpdPrintDevice::loadInputSlots() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // TODO Deal with concatenated names like Tray1Manual or Tray1_Man,
+ // will currently show as CustomInputSlot
+ // TODO Deal with separate ManualFeed key
+ // Try load standard PPD options first
+ m_inputSlots.clear();
+ if (m_ppd) {
+ ppd_option_t *inputSlots = ppdFindOption(m_ppd, "InputSlot");
+ if (inputSlots) {
+ for (int i = 0; i < inputSlots->num_choices; ++i)
+ m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i]));
+ }
+ // If no result, try just the default
+ if (m_inputSlots.size() == 0) {
+ inputSlots = ppdFindOption(m_ppd, "DefaultInputSlot");
+ if (inputSlots)
+ m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[0]));
+ }
+ }
+ // If still no result, just use Auto
+ if (m_inputSlots.size() == 0)
+ m_inputSlots.append(QPlatformPrintDevice::defaultInputSlot());
+ m_haveInputSlots = true;
+}
+
+QPrint::InputSlot QPpdPrintDevice::defaultInputSlot() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *inputSlot = ppdFindOption(m_ppd, "DefaultInputSlot");
+ if (inputSlot)
+ return QPrintUtils::ppdChoiceToInputSlot(inputSlot->choices[0]);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "InputSlot");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToInputSlot(*defaultChoice);
+ }
+ // Otherwise return Auto
+ return QPlatformPrintDevice::defaultInputSlot();
+}
+
+void QPpdPrintDevice::loadOutputBins() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ m_outputBins.clear();
+ if (m_ppd) {
+ ppd_option_t *outputBins = ppdFindOption(m_ppd, "OutputBin");
+ if (outputBins) {
+ for (int i = 0; i < outputBins->num_choices; ++i)
+ m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i]));
+ }
+ // If no result, try just the default
+ if (m_outputBins.size() == 0) {
+ outputBins = ppdFindOption(m_ppd, "DefaultOutputBin");
+ if (outputBins)
+ m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[0]));
+ }
+ }
+ // If still no result, just use Auto
+ if (m_outputBins.size() == 0)
+ m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
+ m_haveOutputBins = true;
+}
+
+QPrint::OutputBin QPpdPrintDevice::defaultOutputBin() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *outputBin = ppdFindOption(m_ppd, "DefaultOutputBin");
+ if (outputBin)
+ return QPrintUtils::ppdChoiceToOutputBin(outputBin->choices[0]);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "OutputBin");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToOutputBin(*defaultChoice);
+ }
+ // Otherwise return AutoBin
+ return QPlatformPrintDevice::defaultOutputBin();
+}
+
+void QPpdPrintDevice::loadDuplexModes() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Try load standard PPD options first
+ m_duplexModes.clear();
+ if (m_ppd) {
+ ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex");
+ if (duplexModes) {
+ for (int i = 0; i < duplexModes->num_choices; ++i)
+ 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)
+ m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice));
+ }
+ }
+ // If still no result, or not added in PPD, then add None
+ if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone))
+ m_duplexModes.append(QPrint::DuplexNone);
+ m_haveDuplexModes = true;
+}
+
+QPrint::DuplexMode QPpdPrintDevice::defaultDuplexMode() const
+{
+ // Try load standard PPD option first
+ if (m_ppd) {
+ ppd_option_t *inputSlot = ppdFindOption(m_ppd, "DefaultDuplex");
+ if (inputSlot)
+ return QPrintUtils::ppdChoiceToDuplexMode(inputSlot->choices[0].choice);
+ // If no result, then try a marked option
+ ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "Duplex");
+ if (defaultChoice)
+ return QPrintUtils::ppdChoiceToDuplexMode(defaultChoice->choice);
+ }
+ // Otherwise return None
+ return QPrint::DuplexNone;
+}
+
+void QPpdPrintDevice::loadColorModes() const
+{
+ // Cups cups_ptype_e CUPS_PRINTER_BW CUPS_PRINTER_COLOR
+ // Cups ppd_file_t color_device
+ // PPD ColorDevice
+ m_colorModes.clear();
+ cups_ptype_e type = printerTypeFlags();
+ if (type & CUPS_PRINTER_BW)
+ m_colorModes.append(QPrint::GrayScale);
+ if (type & CUPS_PRINTER_COLOR)
+ m_colorModes.append(QPrint::Color);
+ m_haveColorModes = true;
+}
+
+QPrint::ColorMode QPpdPrintDevice::defaultColorMode() const
+{
+ // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
+ // Not a proper option, usually only know if supports color or not, but some
+ // users known to abuse ColorModel to always force GrayScale.
+ if (m_ppd && supportedColorModes().contains(QPrint::Color)) {
+ ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel");
+ if (!colorModel)
+ colorModel = ppdFindOption(m_ppd, "ColorModel");
+ if (!colorModel || (colorModel && !qstrcmp(colorModel->defchoice, "Gray")))
+ return QPrint::Color;
+ }
+ return QPrint::GrayScale;
+}
+
+void QPpdPrintDevice::loadMimeTypes() const
+{
+ // TODO No CUPS api? Need to manually load CUPS mime.types file?
+ // For now hard-code most common support types
+ QMimeDatabase db;
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("application/pdf")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("application/postscript")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/gif")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/png")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/jpeg")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("image/tiff")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("text/html")));
+ m_mimeTypes.append(db.mimeTypeForName(QStringLiteral("text/plain")));
+ m_haveMimeTypes = true;
+}
+
+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);
+ if (m_cupsDest) {
+ const char *ppdFile = cupsGetPPD(m_cupsName);
+ if (ppdFile)
+ m_ppd = ppdOpenFile(ppdFile);
+ unlink(ppdFile);
+ if (m_ppd) {
+ ppdMarkDefaults(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);
+}
+
+cups_ptype_e QPpdPrintDevice::printerTypeFlags() const
+{
+ return static_cast<cups_ptype_e>(printerOption("printer-type").toUInt());
+}
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/cups/qppdprintdevice.h b/src/plugins/printsupport/cups/qppdprintdevice.h
new file mode 100644
index 0000000000..982f46d71f
--- /dev/null
+++ b/src/plugins/printsupport/cups/qppdprintdevice.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPPDPRINTDEVICE_H
+#define QPPDPRINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpa/qplatformprintdevice.h>
+
+#ifndef QT_NO_PRINTER
+
+#include <cups/cups.h>
+#include <cups/ppd.h>
+
+QT_BEGIN_NAMESPACE
+
+class QPpdPrintDevice : public QPlatformPrintDevice
+{
+public:
+ QPpdPrintDevice();
+ explicit QPpdPrintDevice(const QString &id);
+ QPpdPrintDevice(const QPpdPrintDevice &other);
+ virtual ~QPpdPrintDevice();
+
+ QPpdPrintDevice &operator=(const QPpdPrintDevice &other);
+
+ QPpdPrintDevice *clone();
+
+ bool operator==(const QPpdPrintDevice &other) const;
+
+ bool isValid() const Q_DECL_OVERRIDE;
+ bool isDefault() const Q_DECL_OVERRIDE;
+
+ QPrint::DeviceState state() const Q_DECL_OVERRIDE;
+
+ QPageSize defaultPageSize() const Q_DECL_OVERRIDE;
+
+ QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ int resolution) const Q_DECL_OVERRIDE;
+
+ int defaultResolution() const Q_DECL_OVERRIDE;
+
+ QPrint::InputSlot defaultInputSlot() const Q_DECL_OVERRIDE;
+
+ QPrint::OutputBin defaultOutputBin() const Q_DECL_OVERRIDE;
+
+ QPrint::DuplexMode defaultDuplexMode() const Q_DECL_OVERRIDE;
+
+ QPrint::ColorMode defaultColorMode() const Q_DECL_OVERRIDE;
+
+protected:
+ void loadPageSizes() const Q_DECL_OVERRIDE;
+ void loadResolutions() const Q_DECL_OVERRIDE;
+ void loadInputSlots() const Q_DECL_OVERRIDE;
+ void loadOutputBins() const Q_DECL_OVERRIDE;
+ void loadDuplexModes() const Q_DECL_OVERRIDE;
+ void loadColorModes() const Q_DECL_OVERRIDE;
+ void loadMimeTypes() const Q_DECL_OVERRIDE;
+
+private:
+ void loadPrinter();
+ QString printerOption(const QString &key) const;
+ cups_ptype_e printerTypeFlags() const;
+
+ cups_dest_t *m_cupsDest;
+ ppd_file_t *m_ppd;
+ QByteArray m_cupsName;
+ QByteArray m_cupsInstance;
+ QMarginsF m_customMargins;
+ mutable QHash<QString, QMarginsF> m_printableMargins;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+#endif // QPPDPRINTDEVICE_H
diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
new file mode 100644
index 0000000000..1b55937ec7
--- /dev/null
+++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
@@ -0,0 +1,480 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsprintdevice.h"
+
+#include <qdebug.h>
+
+#ifndef DC_COLLATE
+# define DC_COLLATE 22
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+extern qreal qt_pointMultiplier(QPageLayout::Unit unit);
+
+static inline uint qwcsnlen(const wchar_t *str, uint maxlen)
+{
+ uint length = 0;
+ if (str) {
+ while (length < maxlen && *str++)
+ length++;
+ }
+ return length;
+}
+
+static QPrint::InputSlot paperBinToInputSlot(int windowsId, const QString &name)
+{
+ QPrint::InputSlot slot;
+ slot.name = name;
+ int i;
+ for (i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) {
+ if (inputSlotMap[i].windowsId == windowsId) {
+ slot.key = inputSlotMap[i].key;
+ slot.id = inputSlotMap[i].id;
+ slot.windowsId = inputSlotMap[i].windowsId;
+ return slot;
+ }
+ }
+ slot.key = inputSlotMap[i].key;
+ slot.id = inputSlotMap[i].id;
+ return slot;
+}
+
+
+QWindowsPrintDevice::QWindowsPrintDevice()
+ : QPlatformPrintDevice(),
+ m_hPrinter(0)
+{
+}
+
+QWindowsPrintDevice::QWindowsPrintDevice(const QString &id)
+ : QPlatformPrintDevice(id),
+ m_hPrinter(0)
+{
+ // 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)) {
+ DWORD needed = 0;
+ GetPrinter(m_hPrinter, 2, 0, 0, &needed);
+ QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
+ if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) {
+ PPRINTER_INFO_2 info = reinterpret_cast<PPRINTER_INFO_2>(buffer.data());
+ m_name = QString::fromWCharArray(info->pPrinterName);
+ m_location = QString::fromWCharArray(info->pLocation);
+ 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);
+ }
+ }
+}
+
+QWindowsPrintDevice::QWindowsPrintDevice(const QWindowsPrintDevice &other)
+ : QPlatformPrintDevice(other)
+{
+ OpenPrinter((LPWSTR)other.m_id.utf16(), &m_hPrinter, NULL);
+}
+
+QWindowsPrintDevice::~QWindowsPrintDevice()
+{
+ ClosePrinter(m_hPrinter);
+}
+
+QWindowsPrintDevice &QWindowsPrintDevice::operator=(const QWindowsPrintDevice &other)
+{
+ OpenPrinter((LPWSTR)other.m_id.utf16(), &m_hPrinter, NULL);
+ return *this;
+}
+
+bool QWindowsPrintDevice::operator==(const QWindowsPrintDevice &other) const
+{
+ return (m_id == other.m_id);
+}
+
+bool QWindowsPrintDevice::isValid() const
+{
+ return m_hPrinter;
+}
+
+bool QWindowsPrintDevice::isDefault() const
+{
+ return m_id == defaultPrintDeviceId();
+}
+
+QPrint::DeviceState QWindowsPrintDevice::state() const
+{
+ DWORD needed = 0;
+ GetPrinter(m_hPrinter, 6, 0, 0, &needed);
+ QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
+
+ if (GetPrinter(m_hPrinter, 6, buffer.data(), needed, &needed)) {
+ PPRINTER_INFO_6 info = reinterpret_cast<PPRINTER_INFO_6>(buffer.data());
+ // TODO Check mapping
+ if (info->dwStatus == 0
+ || (info->dwStatus & PRINTER_STATUS_WAITING) == PRINTER_STATUS_WAITING
+ || (info->dwStatus & PRINTER_STATUS_POWER_SAVE) == PRINTER_STATUS_POWER_SAVE) {
+ return QPrint::Idle;
+ } else if ((info->dwStatus & PRINTER_STATUS_PRINTING) == PRINTER_STATUS_PRINTING
+ || (info->dwStatus & PRINTER_STATUS_BUSY) == PRINTER_STATUS_BUSY
+ || (info->dwStatus & PRINTER_STATUS_INITIALIZING) == PRINTER_STATUS_INITIALIZING
+ || (info->dwStatus & PRINTER_STATUS_IO_ACTIVE) == PRINTER_STATUS_IO_ACTIVE
+ || (info->dwStatus & PRINTER_STATUS_PROCESSING) == PRINTER_STATUS_PROCESSING
+ || (info->dwStatus & PRINTER_STATUS_WARMING_UP) == PRINTER_STATUS_WARMING_UP) {
+ return QPrint::Active;
+ }
+ }
+
+ return QPrint::Error;
+}
+
+void QWindowsPrintDevice::loadPageSizes() const
+{
+ // Get the number of paper sizes and check all 3 attributes have same count
+ DWORD paperCount = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERNAMES, NULL, NULL);
+ if (int(paperCount) > 0
+ && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERSIZE, NULL, NULL) == paperCount
+ && 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<wchar_t> papers(new wchar_t[paperCount]);
+
+ // Get the details and match the default paper size
+ if (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERNAMES, paperNames.data(), NULL) == paperCount
+ && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERSIZE, (wchar_t *)winSizes.data(), NULL) == paperCount
+ && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_PAPERS, papers.data(), NULL) == paperCount) {
+
+ // Returned size is in tenths of a millimeter
+ const qreal multiplier = qt_pointMultiplier(QPageLayout::Millimeter);
+ for (int i = 0; i < int(paperCount); ++i) {
+ QSize size = QSize(qRound((winSizes[i].x / 10.0) * multiplier), qRound((winSizes[i].y / 10.0) * multiplier));
+ wchar_t *paper = paperNames.data() + (i * 64);
+ QString name = QString::fromWCharArray(paper, qwcsnlen(paper, 64));
+ m_pageSizes.append(createPageSize(papers[i], size, name));
+ }
+
+ }
+ }
+
+ m_havePageSizes = true;
+}
+
+QPageSize QWindowsPrintDevice::defaultPageSize() const
+{
+ if (!m_havePageSizes)
+ loadPageSizes();
+
+ QPageSize pageSize;
+
+ // Allocate the required DEVMODE buffer
+ DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0);
+ LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize);
+
+ // Get the default DevMode
+ DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER);
+
+ // Get the default paper size
+ if (result == IDOK && pDevMode->dmFields & DM_PAPERSIZE) {
+ // Find the supported page size that matches, in theory default should be one of them
+ foreach (const QPageSize &ps, m_pageSizes) {
+ if (ps.windowsId() == pDevMode->dmPaperSize) {
+ pageSize = ps;
+ break;
+ }
+ }
+ }
+
+ // Clean-up
+ free(pDevMode);
+ return pageSize;
+}
+
+QMarginsF QWindowsPrintDevice::printableMargins(const QPageSize &pageSize,
+ QPageLayout::Orientation orientation,
+ int resolution) const
+{
+ // TODO This is slow, need to cache values or find better way!
+ // Modify the DevMode to get the DC printable margins in device pixels
+ QMarginsF margins = QMarginsF(0, 0, 0, 0);
+ DWORD needed = 0;
+ GetPrinter(m_hPrinter, 2, 0, 0, &needed);
+ QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
+ if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) {
+ PPRINTER_INFO_2 info = reinterpret_cast<PPRINTER_INFO_2>(buffer.data());
+ DEVMODE *devMode = info->pDevMode;
+ HDC pDC = CreateDC(NULL, (LPWSTR)m_id.utf16(), NULL, devMode);
+ if (pageSize.id() == QPageSize::Custom || pageSize.windowsId() <= 0 || pageSize.windowsId() > DMPAPER_LAST) {
+ devMode->dmPaperSize = 0;
+ devMode->dmPaperWidth = pageSize.size(QPageSize::Millimeter).width() * 10.0;
+ devMode->dmPaperLength = pageSize.size(QPageSize::Millimeter).height() * 10.0;
+ } else {
+ devMode->dmPaperSize = pageSize.windowsId();
+ }
+ devMode->dmPrintQuality = resolution;
+ devMode->dmOrientation = orientation == QPageLayout::Portrait ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE;
+ ResetDC(pDC, devMode);
+ const int dpiWidth = GetDeviceCaps(pDC, LOGPIXELSX);
+ const int dpiHeight = GetDeviceCaps(pDC, LOGPIXELSY);
+ const qreal wMult = 72.0 / dpiWidth;
+ const qreal hMult = 72.0 / dpiHeight;
+ const qreal physicalWidth = GetDeviceCaps(pDC, PHYSICALWIDTH) * wMult;
+ const qreal physicalHeight = GetDeviceCaps(pDC, PHYSICALHEIGHT) * hMult;
+ const qreal printableWidth = GetDeviceCaps(pDC, HORZRES) * wMult;
+ const qreal printableHeight = GetDeviceCaps(pDC, VERTRES) * hMult;
+ const qreal leftMargin = GetDeviceCaps(pDC, PHYSICALOFFSETX)* wMult;
+ const qreal topMargin = GetDeviceCaps(pDC, PHYSICALOFFSETY) * hMult;
+ const qreal rightMargin = physicalWidth - leftMargin - printableWidth;
+ const qreal bottomMargin = physicalHeight - topMargin - printableHeight;
+ margins = QMarginsF(leftMargin, topMargin, rightMargin, bottomMargin);
+ ReleaseDC(NULL, pDC);
+ }
+ return margins;
+}
+
+void QWindowsPrintDevice::loadResolutions() const
+{
+ DWORD resCount = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_ENUMRESOLUTIONS, NULL, NULL);
+ if (int(resCount) > 0) {
+ QScopedArrayPointer<LONG> resolutions(new LONG[resCount*sizeof(LONG)]);
+ // Get the details and match the default paper size
+ if (DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_ENUMRESOLUTIONS, (LPWSTR)resolutions.data(), NULL) == resCount) {
+ for (int i = 0; i < int(resCount); ++i)
+ m_resolutions.append(resolutions[i]);
+ }
+ }
+ m_haveResolutions = true;
+}
+
+int QWindowsPrintDevice::defaultResolution() const
+{
+ int resolution = 72; // TODO Set a sensible default?
+
+ // Allocate the required DEVMODE buffer
+ DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0);
+ LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize);
+
+ // Get the default DevMode
+ DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER);
+
+ // Get the default resolution
+ if (result == IDOK && pDevMode->dmFields & DM_YRESOLUTION) {
+ if (pDevMode->dmPrintQuality > 0)
+ resolution = pDevMode->dmPrintQuality;
+ else
+ resolution = pDevMode->dmYResolution;
+ }
+
+ // Clean-up
+ free(pDevMode);
+ return resolution;
+}
+
+void QWindowsPrintDevice::loadInputSlots() const
+{
+ DWORD binCount = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_BINS, NULL, NULL);
+ if (int(binCount) > 0
+ && DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_BINNAMES, NULL, NULL) == binCount) {
+
+ QScopedArrayPointer<WORD> bins(new WORD[binCount*sizeof(WORD)]);
+ 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) {
+
+ for (int i = 0; i < int(binCount); ++i) {
+ wchar_t *binName = binNames.data() + (i * 24);
+ QString name = QString::fromWCharArray(binName, qwcsnlen(binName, 24));
+ m_inputSlots.append(paperBinToInputSlot(bins[i], name));
+ }
+
+ }
+ }
+
+ m_haveInputSlots = true;
+}
+
+QPrint::InputSlot QWindowsPrintDevice::defaultInputSlot() const
+{
+ QPrint::InputSlot inputSlot = QPlatformPrintDevice::defaultInputSlot();;
+
+ // Allocate the required DEVMODE buffer
+ DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0);
+ LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize);
+
+ // Get the default DevMode
+ DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER);
+
+ // Get the default input slot
+ if (result == IDOK && pDevMode->dmFields & DM_DEFAULTSOURCE) {
+ QPrint::InputSlot tempSlot = paperBinToInputSlot(pDevMode->dmDefaultSource, QString());
+ foreach (const QPrint::InputSlot &slot, supportedInputSlots()) {
+ if (slot.key == tempSlot.key) {
+ inputSlot = slot;
+ break;
+ }
+ }
+ }
+
+ // Clean-up
+ free(pDevMode);
+ return inputSlot;
+}
+
+void QWindowsPrintDevice::loadOutputBins() const
+{
+ m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
+ m_haveOutputBins = true;
+}
+
+void QWindowsPrintDevice::loadDuplexModes() const
+{
+ m_duplexModes.append(QPrint::DuplexNone);
+ DWORD duplex = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_DUPLEX, NULL, NULL);
+ if (int(duplex) == 1) {
+ // TODO Assume if duplex flag supports both modes
+ m_duplexModes.append(QPrint::DuplexLongSide);
+ m_duplexModes.append(QPrint::DuplexShortSide);
+ }
+ m_haveDuplexModes = true;
+}
+
+QPrint::DuplexMode QWindowsPrintDevice::defaultDuplexMode() const
+{
+ QPrint::DuplexMode duplexMode = QPrint::DuplexNone;
+
+ // Allocate the required DEVMODE buffer
+ DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0);
+ LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize);
+
+ // Get the default DevMode
+ DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER);
+
+ // Get the default duplex mode
+ if (result == IDOK && pDevMode->dmFields & DM_DUPLEX) {
+ if (pDevMode->dmDuplex == DMDUP_VERTICAL)
+ duplexMode = QPrint::DuplexLongSide;
+ else if (pDevMode->dmDuplex == DMDUP_HORIZONTAL)
+ duplexMode = QPrint::DuplexShortSide;
+ }
+
+ // Clean-up
+ free(pDevMode);
+ return duplexMode;
+}
+
+void QWindowsPrintDevice::loadColorModes() const
+{
+ m_colorModes.append(QPrint::GrayScale);
+ DWORD color = DeviceCapabilities((LPWSTR)m_id.utf16(), NULL, DC_COLORDEVICE, NULL, NULL);
+ if (int(color) == 1)
+ m_colorModes.append(QPrint::Color);
+ m_haveColorModes = true;
+}
+
+QPrint::ColorMode QWindowsPrintDevice::defaultColorMode() const
+{
+ if (!m_haveColorModes)
+ loadColorModes();
+ if (!m_colorModes.contains(QPrint::Color))
+ return QPrint::GrayScale;
+
+ QPrint::ColorMode colorMode = QPrint::GrayScale;
+
+ // Allocate the required DEVMODE buffer
+ DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0);
+ LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize);
+
+ // Get the default DevMode
+ DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER);
+
+ // Get the default color mode
+ if (result == IDOK && pDevMode->dmFields & DM_COLOR) {
+ if (pDevMode->dmColor == DMCOLOR_COLOR)
+ colorMode = QPrint::Color;
+ }
+
+ // Clean-up
+ free(pDevMode);
+ return colorMode;
+}
+
+QStringList QWindowsPrintDevice::availablePrintDeviceIds()
+{
+ QStringList list;
+ DWORD needed = 0;
+ DWORD returned = 0;
+ if ((!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ || !needed) {
+ return list;
+ }
+ QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
+ if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer.data(), needed, &needed, &returned))
+ return list;
+ PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer.data());
+ for (uint i = 0; i < returned; ++i)
+ list.append(QString::fromWCharArray(infoList[i].pPrinterName));
+ return list;
+}
+
+QString QWindowsPrintDevice::defaultPrintDeviceId()
+{
+ DWORD size = 0;
+ GetDefaultPrinter(NULL, &size);
+ QScopedArrayPointer<wchar_t> name(new wchar_t[size]);
+ GetDefaultPrinter(name.data(), &size);
+ return QString::fromWCharArray(name.data());
+}
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.h b/src/plugins/printsupport/windows/qwindowsprintdevice.h
new file mode 100644
index 0000000000..2d11787305
--- /dev/null
+++ b/src/plugins/printsupport/windows/qwindowsprintdevice.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWINDOWSPRINTDEVICE_H
+#define QWINDOWSPRINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qpa/qplatformprintdevice.h>
+
+#ifndef QT_NO_PRINTER
+
+#include <QtCore/qt_windows.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsPrintDevice : public QPlatformPrintDevice
+{
+public:
+ QWindowsPrintDevice();
+ explicit QWindowsPrintDevice(const QString &id);
+ QWindowsPrintDevice(const QWindowsPrintDevice &other);
+ virtual ~QWindowsPrintDevice();
+
+ QWindowsPrintDevice &operator=(const QWindowsPrintDevice &other);
+
+ QWindowsPrintDevice *clone();
+
+ bool operator==(const QWindowsPrintDevice &other) const;
+
+ bool isValid() const Q_DECL_OVERRIDE;
+ bool isDefault() const Q_DECL_OVERRIDE;
+
+ QPrint::DeviceState state() const Q_DECL_OVERRIDE;
+
+ QPageSize defaultPageSize() const Q_DECL_OVERRIDE;
+
+ QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ int resolution) const Q_DECL_OVERRIDE;
+
+ int defaultResolution() const Q_DECL_OVERRIDE;
+
+ QPrint::InputSlot defaultInputSlot() const Q_DECL_OVERRIDE;
+
+ QPrint::DuplexMode defaultDuplexMode() const Q_DECL_OVERRIDE;
+
+ QPrint::ColorMode defaultColorMode() const Q_DECL_OVERRIDE;
+
+ static QStringList availablePrintDeviceIds();
+ static QString defaultPrintDeviceId();
+
+protected:
+ void loadPageSizes() const Q_DECL_OVERRIDE;
+ void loadResolutions() const Q_DECL_OVERRIDE;
+ void loadInputSlots() const Q_DECL_OVERRIDE;
+ void loadOutputBins() const Q_DECL_OVERRIDE;
+ void loadDuplexModes() const Q_DECL_OVERRIDE;
+ void loadColorModes() const Q_DECL_OVERRIDE;
+
+private:
+ HANDLE m_hPrinter;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+#endif // QWINDOWSPRINTDEVICE_H
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
index b7ba9ef5e7..997082a367 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.cpp
@@ -40,20 +40,17 @@
****************************************************************************/
#include "qwindowsprintersupport.h"
+#include "qwindowsprintdevice.h"
-#include <QtCore/QList>
-#include <QtCore/QScopedArrayPointer>
-#include <QtPrintSupport/QPrinterInfo>
+#include <QtCore/QStringList>
#include <qprintengine_win_p.h>
-#include <private/qpaintengine_alpha_p.h>
-#include <private/qprinterinfo_p.h>
+#include <private/qprintdevice_p.h>
QT_BEGIN_NAMESPACE
QWindowsPrinterSupport::QWindowsPrinterSupport()
: QPlatformPrinterSupport()
{
- m_printers = QWindowsPrinterSupport::queryPrinters();
}
QWindowsPrinterSupport::~QWindowsPrinterSupport()
@@ -71,43 +68,19 @@ QPaintEngine *QWindowsPrinterSupport::createPaintEngine(QPrintEngine *engine, QP
return static_cast<QWin32PrintEngine *>(engine);
}
-QList<QPrinter::PaperSize> QWindowsPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const
+QPrintDevice QWindowsPrinterSupport::createPrintDevice(const QString &id)
{
- return QWin32PrintEngine::supportedPaperSizes(printerInfo);
+ return QPlatformPrinterSupport::createPrintDevice(new QWindowsPrintDevice(id));
}
-QList<QPair<QString, QSizeF> >QWindowsPrinterSupport::supportedSizesWithNames(const QPrinterInfo &printerInfo) const
+QStringList QWindowsPrinterSupport::availablePrintDeviceIds() const
{
- return QWin32PrintEngine::supportedSizesWithNames(printerInfo);
+ return QWindowsPrintDevice::availablePrintDeviceIds();
}
-QList<QPrinterInfo> QWindowsPrinterSupport::availablePrinters()
+QString QWindowsPrinterSupport::defaultPrintDeviceId() const
{
- m_printers = QWindowsPrinterSupport::queryPrinters();
- return QPlatformPrinterSupport::availablePrinters();
-}
-
-QList<QPrinterInfo> QWindowsPrinterSupport::queryPrinters()
-{
- QList<QPrinterInfo> result;
- DWORD needed = 0;
- DWORD returned = 0;
- if ((!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, 0, 0, &needed, &returned) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- || !needed) {
- return result;
- }
- QScopedArrayPointer<BYTE> buffer(new BYTE[needed]);
- if (!EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 4, buffer.data(), needed, &needed, &returned))
- return result;
- PPRINTER_INFO_4 infoList = reinterpret_cast<PPRINTER_INFO_4>(buffer.data());
- QString defaultPrinterName;
- QWin32PrintEngine::queryDefaultPrinter(defaultPrinterName);
- for (uint i = 0; i < returned; ++i) {
- const QString printerName(QString::fromWCharArray(infoList[i].pPrinterName));
- const bool isDefault = (printerName == defaultPrinterName);
- result.append(QPlatformPrinterSupport::createPrinterInfo(printerName, QString(), QString(), QString(), isDefault, i));
- }
- return result;
+ return QWindowsPrintDevice::defaultPrintDeviceId();
}
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/qwindowsprintersupport.h b/src/plugins/printsupport/windows/qwindowsprintersupport.h
index 1b1b1fa215..6a84b667dd 100644
--- a/src/plugins/printsupport/windows/qwindowsprintersupport.h
+++ b/src/plugins/printsupport/windows/qwindowsprintersupport.h
@@ -46,22 +46,18 @@
QT_BEGIN_NAMESPACE
-class QWin32PrintEngine;
-
class QWindowsPrinterSupport : public QPlatformPrinterSupport
{
public:
QWindowsPrinterSupport();
~QWindowsPrinterSupport();
- virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode);
- virtual QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode);
- virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
- virtual QList<QPair<QString, QSizeF> >supportedSizesWithNames(const QPrinterInfo &printerInfo) const;
- virtual QList<QPrinterInfo> availablePrinters();
+ QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode) Q_DECL_OVERRIDE;
+ QPaintEngine *createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode) Q_DECL_OVERRIDE;
-private:
- static QList<QPrinterInfo> queryPrinters();
+ QPrintDevice createPrintDevice(const QString &id) Q_DECL_OVERRIDE;
+ QStringList availablePrintDeviceIds() const Q_DECL_OVERRIDE;
+ QString defaultPrintDeviceId() const Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/printsupport/windows/windows.pro b/src/plugins/printsupport/windows/windows.pro
index ae9efa342b..364e19e68e 100644
--- a/src/plugins/printsupport/windows/windows.pro
+++ b/src/plugins/printsupport/windows/windows.pro
@@ -12,10 +12,12 @@ INCLUDEPATH *= $$QT_SOURCE_TREE/src/printsupport/kernel
SOURCES += \
main.cpp \
- qwindowsprintersupport.cpp
+ qwindowsprintersupport.cpp \
+ qwindowsprintdevice.cpp \
HEADERS += \
- qwindowsprintersupport.h
+ qwindowsprintersupport.h \
+ qwindowsprintdevice.h \
OTHER_FILES += windows.json
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
index 6801863a3a..b9041bb242 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -44,68 +44,25 @@
#ifndef QT_NO_PRINTDIALOG
#include "qpagesetupdialog_unix_p.h"
+#include <private/qpagesetupdialog_p.h>
+#include <private/qprintdevice_p.h>
+#include <private/qcups_p.h>
+
#include "qpainter.h"
#include "qprintdialog.h"
#include "qdialogbuttonbox.h"
#include <ui_qpagesetupwidget.h>
#include <QtPrintSupport/qprinter.h>
-#include <private/qpagesetupdialog_p.h>
-#include <private/qprinter_p.h>
-#include <private/qprintengine_pdf_p.h>
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-# include <private/qcups_p.h>
-#endif
+#include <qpa/qplatformprintplugin.h>
+#include <qpa/qplatformprintersupport.h>
QT_BEGIN_NAMESPACE
-QSizeF qt_printerPaperSize(QPrinter::Orientation, QPrinter::PaperSize, QPrinter::Unit, int);
-
// Disabled until we have support for papersources on unix
// #define PSD_ENABLE_PAPERSOURCE
-static void populatePaperSizes(QComboBox* cb)
-{
- cb->addItem(QPrintDialog::tr("A0"), QPrinter::A0);
- cb->addItem(QPrintDialog::tr("A1"), QPrinter::A1);
- cb->addItem(QPrintDialog::tr("A2"), QPrinter::A2);
- cb->addItem(QPrintDialog::tr("A3"), QPrinter::A3);
- cb->addItem(QPrintDialog::tr("A4"), QPrinter::A4);
- cb->addItem(QPrintDialog::tr("A5"), QPrinter::A5);
- cb->addItem(QPrintDialog::tr("A6"), QPrinter::A6);
- cb->addItem(QPrintDialog::tr("A7"), QPrinter::A7);
- cb->addItem(QPrintDialog::tr("A8"), QPrinter::A8);
- cb->addItem(QPrintDialog::tr("A9"), QPrinter::A9);
- cb->addItem(QPrintDialog::tr("B0"), QPrinter::B0);
- cb->addItem(QPrintDialog::tr("B1"), QPrinter::B1);
- cb->addItem(QPrintDialog::tr("B2"), QPrinter::B2);
- cb->addItem(QPrintDialog::tr("B3"), QPrinter::B3);
- cb->addItem(QPrintDialog::tr("B4"), QPrinter::B4);
- cb->addItem(QPrintDialog::tr("B5"), QPrinter::B5);
- cb->addItem(QPrintDialog::tr("B6"), QPrinter::B6);
- cb->addItem(QPrintDialog::tr("B7"), QPrinter::B7);
- cb->addItem(QPrintDialog::tr("B8"), QPrinter::B8);
- cb->addItem(QPrintDialog::tr("B9"), QPrinter::B9);
- cb->addItem(QPrintDialog::tr("B10"), QPrinter::B10);
- cb->addItem(QPrintDialog::tr("C5E"), QPrinter::C5E);
- cb->addItem(QPrintDialog::tr("DLE"), QPrinter::DLE);
- cb->addItem(QPrintDialog::tr("Executive"), QPrinter::Executive);
- cb->addItem(QPrintDialog::tr("Folio"), QPrinter::Folio);
- cb->addItem(QPrintDialog::tr("Ledger"), QPrinter::Ledger);
- cb->addItem(QPrintDialog::tr("Legal"), QPrinter::Legal);
- cb->addItem(QPrintDialog::tr("Letter"), QPrinter::Letter);
- cb->addItem(QPrintDialog::tr("Tabloid"), QPrinter::Tabloid);
- cb->addItem(QPrintDialog::tr("US Common #10 Envelope"), QPrinter::Comm10E);
- cb->addItem(QPrintDialog::tr("Custom"), QPrinter::Custom);
-}
-
-
-static QSizeF sizeForOrientation(QPrinter::Orientation orientation, const QSizeF &size)
-{
- return (orientation == QPrinter::Portrait) ? size : QSizeF(size.height(), size.width());
-}
-
#ifdef PSD_ENABLE_PAPERSOURCE
static const char *paperSourceNames[] = {
"Only One",
@@ -134,6 +91,10 @@ struct PaperSourceNames
#endif
+// QPagePreview
+// - Private widget to display preview of page layout
+// - Embedded in QPageSetupWidget
+
class QPagePreview : public QWidget
{
public:
@@ -143,18 +104,9 @@ public:
setMinimumSize(50, 50);
}
- void setPaperSize(const QSizeF& size)
- {
- m_size = size;
- update();
- }
-
- void setMargins(qreal left, qreal top, qreal right, qreal bottom)
+ void setPageLayout(const QPageLayout &layout)
{
- m_left = left;
- m_top = top;
- m_right = right;
- m_bottom = bottom;
+ m_pageLayout = layout;
update();
}
@@ -168,22 +120,19 @@ public:
protected:
void paintEvent(QPaintEvent *)
{
- QRect pageRect;
- QSizeF adjustedSize(m_size);
- adjustedSize.scale(width()-10, height()-10, Qt::KeepAspectRatio);
- pageRect = QRect(QPoint(0,0), adjustedSize.toSize());
+ QSize pageSize = m_pageLayout.fullRectPoints().size();
+ QSizeF scaledSize = pageSize.scaled(width() - 10, height() - 10, Qt::KeepAspectRatio);
+ QRect pageRect = QRect(QPoint(0,0), scaledSize.toSize());
pageRect.moveCenter(rect().center());
-
- qreal width_factor = pageRect.width() / m_size.width();
- qreal height_factor = pageRect.height() / m_size.height();
- int leftSize = qRound(m_left*width_factor);
- int topSize = qRound(m_top*height_factor);
- int rightSize = qRound(m_right*width_factor);
- int bottomSize = qRound(m_bottom * height_factor);
- QRect marginRect(pageRect.x()+leftSize,
- pageRect.y()+topSize,
- pageRect.width() - (leftSize+rightSize+1),
- pageRect.height() - (topSize+bottomSize+1));
+ qreal width_factor = scaledSize.width() / pageSize.width();
+ qreal height_factor = scaledSize.height() / pageSize.height();
+ QMarginsF margins = m_pageLayout.margins(QPageLayout::Point);
+ int left = qRound(margins.left() * width_factor);
+ int top = qRound(margins.top() * height_factor);
+ int right = qRound(margins.right() * width_factor);
+ int bottom = qRound(margins.bottom() * height_factor);
+ QRect marginRect(pageRect.x() + left, pageRect.y() + top,
+ pageRect.width() - (left + right + 1), pageRect.height() - (top + bottom + 1));
QPainter p(this);
QColor shadow(palette().mid().color());
@@ -226,14 +175,17 @@ protected:
}
private:
- // all these are in points
- qreal m_left, m_top, m_right, m_bottom;
- // specify width / height of one page in preview
+ // Page Layout
+ QPageLayout m_pageLayout;
+ // Pages Per Sheet / n-up layout
int m_pagePreviewColumns, m_pagePreviewRows;
- QSizeF m_size;
};
+// QUnixPageSetupDialogPrivate
+// - Linux / Cups implementation of QPageSetupDialogPrivate
+// - Embeds QPageSetupWidget
+
class QUnixPageSetupDialogPrivate : public QPageSetupDialogPrivate
{
Q_DECLARE_PUBLIC(QPageSetupDialog)
@@ -272,27 +224,24 @@ void QUnixPageSetupDialogPrivate::init()
lay->addWidget(buttons);
}
+// QPageSetupWidget
+// - Private widget implementation for Linux / CUPS
+// - Embeds QPagePreview
+// - TODO Could be made public as a stand-alone widget?
+
QPageSetupWidget::QPageSetupWidget(QWidget *parent)
: QWidget(parent),
- m_printer(0),
- m_blockSignals(false),
- m_cups(false)
+ m_pagePreview(0),
+ m_printer(0),
+ m_outputFormat(QPrinter::PdfFormat),
+ m_units(QPageLayout::Point),
+ m_blockSignals(false)
{
- widget.setupUi(this);
-
- QString suffix = (QLocale::system().measurementSystem() == QLocale::ImperialSystem)
- ? QString::fromLatin1(" in")
- : QString::fromLatin1(" mm");
- widget.topMargin->setSuffix(suffix);
- widget.bottomMargin->setSuffix(suffix);
- widget.leftMargin->setSuffix(suffix);
- widget.rightMargin->setSuffix(suffix);
- widget.paperWidth->setSuffix(suffix);
- widget.paperHeight->setSuffix(suffix);
-
- QVBoxLayout *lay = new QVBoxLayout(widget.preview);
- widget.preview->setLayout(lay);
- m_pagePreview = new QPagePreview(widget.preview);
+ m_ui.setupUi(this);
+
+ QVBoxLayout *lay = new QVBoxLayout(m_ui.preview);
+ m_ui.preview->setLayout(lay);
+ m_pagePreview = new QPagePreview(m_ui.preview);
m_pagePreview->setPagePreviewLayout(1, 1);
lay->addWidget(m_pagePreview);
@@ -301,253 +250,308 @@ QPageSetupWidget::QPageSetupWidget(QWidget *parent)
#ifdef PSD_ENABLE_PAPERSOURCE
for (int i=0; paperSourceNames[i]; ++i)
- widget.paperSource->insertItem(paperSourceNames[i]);
+ m_ui.paperSource->insertItem(paperSourceNames[i]);
#else
- widget.paperSourceLabel->setVisible(false);
- widget.paperSource->setVisible(false);
+ m_ui.paperSourceLabel->setVisible(false);
+ m_ui.paperSource->setVisible(false);
#endif
- widget.reverseLandscape->setVisible(false);
- widget.reversePortrait->setVisible(false);
+ m_ui.reverseLandscape->setVisible(false);
+ m_ui.reversePortrait->setVisible(false);
- populatePaperSizes(widget.paperSize);
+ initUnits();
initPagesPerSheet();
- QStringList units;
- units << tr("Centimeters (cm)") << tr("Millimeters (mm)") << tr("Inches (in)") << tr("Points (pt)");
- widget.unit->addItems(units);
- connect(widget.unit, SIGNAL(activated(int)), this, SLOT(unitChanged(int)));
- widget.unit->setCurrentIndex((QLocale::system().measurementSystem() == QLocale::ImperialSystem) ? 2 : 1);
- connect(widget.paperSize, SIGNAL(currentIndexChanged(int)), this, SLOT(_q_paperSizeChanged()));
- connect(widget.paperWidth, SIGNAL(valueChanged(double)), this, SLOT(_q_paperSizeChanged()));
- connect(widget.paperHeight, SIGNAL(valueChanged(double)), this, SLOT(_q_paperSizeChanged()));
+ connect(m_ui.unitCombo, SIGNAL(activated(int)), this, SLOT(unitChanged()));
- connect(widget.leftMargin, SIGNAL(valueChanged(double)), this, SLOT(setLeftMargin(double)));
- connect(widget.topMargin, SIGNAL(valueChanged(double)), this, SLOT(setTopMargin(double)));
- connect(widget.rightMargin, SIGNAL(valueChanged(double)), this, SLOT(setRightMargin(double)));
- connect(widget.bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(setBottomMargin(double)));
+ connect(m_ui.pageSizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pageSizeChanged()));
+ connect(m_ui.pageWidth, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged()));
+ connect(m_ui.pageHeight, SIGNAL(valueChanged(double)), this, SLOT(pageSizeChanged()));
- connect(widget.portrait, SIGNAL(clicked()), this, SLOT(_q_pageOrientationChanged()));
- connect(widget.landscape, SIGNAL(clicked()), this, SLOT(_q_pageOrientationChanged()));
- connect(widget.pagesPerSheetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_q_pagesPerSheetChanged()));
+ connect(m_ui.leftMargin, SIGNAL(valueChanged(double)), this, SLOT(leftMarginChanged(double)));
+ connect(m_ui.topMargin, SIGNAL(valueChanged(double)), this, SLOT(topMarginChanged(double)));
+ connect(m_ui.rightMargin, SIGNAL(valueChanged(double)), this, SLOT(rightMarginChanged(double)));
+ connect(m_ui.bottomMargin, SIGNAL(valueChanged(double)), this, SLOT(bottomMarginChanged(double)));
+ connect(m_ui.portrait, SIGNAL(clicked()), this, SLOT(pageOrientationChanged()));
+ connect(m_ui.landscape, SIGNAL(clicked()), this, SLOT(pageOrientationChanged()));
+
+ connect(m_ui.pagesPerSheetCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(pagesPerSheetChanged()));
}
-void QPageSetupWidget::setPrinter(QPrinter *printer)
+// Init the Units combo box
+void QPageSetupWidget::initUnits()
{
- m_printer = printer;
- m_blockSignals = true;
- selectPdfPsPrinter(printer);
- printer->getPageMargins(&m_leftMargin, &m_topMargin, &m_rightMargin, &m_bottomMargin, QPrinter::Point);
- unitChanged(widget.unit->currentIndex());
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
- m_paperSize = printer->paperSize(QPrinter::Point);
- widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
- widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
-
- widget.landscape->setChecked(printer->orientation() == QPrinter::Landscape);
+ m_ui.unitCombo->addItem(tr("Millimeters (mm)"), QVariant::fromValue(QPageLayout::Millimeter));
+ m_ui.unitCombo->addItem(tr("Inches (in)"), QVariant::fromValue(QPageLayout::Inch));
+ m_ui.unitCombo->addItem(tr("Points (pt)"), QVariant::fromValue(QPageLayout::Point));
+ m_ui.unitCombo->addItem(tr("Pica (P̸)"), QVariant::fromValue(QPageLayout::Pica));
+ m_ui.unitCombo->addItem(tr("Didot (DD)"), QVariant::fromValue(QPageLayout::Didot));
+ m_ui.unitCombo->addItem(tr("Cicero (CC)"), QVariant::fromValue(QPageLayout::Cicero));
+
+ // Initailly default to locale measurement system, mm if metric, in otherwise
+ m_ui.unitCombo->setCurrentIndex(QLocale().measurementSystem() != QLocale::MetricSystem);
+}
-#ifdef PSD_ENABLE_PAPERSOURCE
- widget.paperSource->setCurrentItem(printer->paperSource());
+// Init the Pages Per Sheet (n-up) combo boxes if using CUPS
+void QPageSetupWidget::initPagesPerSheet()
+{
+#if !defined(QT_NO_CUPS)
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Left to Right, Top to Bottom"),
+ QVariant::fromValue(QCUPSSupport::LeftToRightTopToBottom));
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Left to Right, Bottom to Top"),
+ QVariant::fromValue(QCUPSSupport::LeftToRightBottomToTop));
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Right to Left, Bottom to Top"),
+ QVariant::fromValue(QCUPSSupport::RightToLeftBottomToTop));
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Right to Left, Top to Bottom"),
+ QVariant::fromValue(QCUPSSupport::RightToLeftTopToBottom));
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Bottom to Top, Left to Right"),
+ QVariant::fromValue(QCUPSSupport::BottomToTopLeftToRight));
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Bottom to Top, Right to Left"),
+ QVariant::fromValue(QCUPSSupport::BottomToTopRightToLeft));
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Top to Bottom, Left to Right"),
+ QVariant::fromValue(QCUPSSupport::TopToBottomLeftToRight));
+ m_ui.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Top to Bottom, Right to Left"),
+ QVariant::fromValue(QCUPSSupport::TopToBottomRightToLeft));
+
+ m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("1 (1x1)"),
+ QVariant::fromValue(QCUPSSupport::OnePagePerSheet));
+ m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("2 (2x1)"),
+ QVariant::fromValue(QCUPSSupport::TwoPagesPerSheet));
+ m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("4 (2x2)"),
+ QVariant::fromValue(QCUPSSupport::FourPagesPerSheet));
+ m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("6 (2x3)"),
+ QVariant::fromValue(QCUPSSupport::SixPagesPerSheet));
+ m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("9 (3x3)"),
+ QVariant::fromValue(QCUPSSupport::NinePagesPerSheet));
+ m_ui.pagesPerSheetCombo->addItem(QPrintDialog::tr("16 (4x4)"),
+ QVariant::fromValue(QCUPSSupport::SixteenPagesPerSheet));
+
+ // Set to QCUPSSupport::OnePagePerSheet
+ m_ui.pagesPerSheetCombo->setCurrentIndex(0);
+ // Set to QCUPSSupport::LeftToRightTopToBottom
+ m_ui.pagesPerSheetLayoutCombo->setCurrentIndex(0);
+#else
+ // Disable if CUPS wasn't found
+ m_ui.pagesPerSheetButtonGroup->hide();
#endif
- Q_ASSERT(m_blockSignals);
- m_blockSignals = false;
- _q_paperSizeChanged();
}
-// set gui data on printer
-void QPageSetupWidget::setupPrinter() const
+void QPageSetupWidget::initPageSizes()
{
- QPrinter::Orientation orientation = widget.portrait->isChecked()
- ? QPrinter::Portrait
- : QPrinter::Landscape;
- m_printer->setOrientation(orientation);
- // paper format
- QVariant val = widget.paperSize->itemData(widget.paperSize->currentIndex());
- int ps = m_printer->pageSize();
- if (val.type() == QVariant::Int) {
- ps = val.toInt();
- }
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- else if (val.type() == QVariant::ByteArray) {
- for (int papersize = 0; papersize < QPrinter::NPageSize; ++papersize) {
- QPdf::PaperSize size = QPdf::paperSize(QPrinter::PaperSize(papersize));
- if (size.width == m_paperSize.width() && size.height == m_paperSize.height()) {
- ps = static_cast<QPrinter::PaperSize>(papersize);
- break;
+ m_blockSignals = true;
+
+ m_ui.pageSizeCombo->clear();
+
+ if (m_outputFormat == QPrinter::NativeFormat && !m_printerName.isEmpty()) {
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps) {
+ QPrintDevice printDevice = ps->createPrintDevice(m_printerName);
+ foreach (const QPageSize &pageSize, printDevice.supportedPageSizes()) {
+ m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize.id()));
+ }
+ if (m_ui.pageSizeCombo->count() > 0 && printDevice.supportsCustomPageSizes()) {
+ m_ui.pageSizeCombo->addItem(tr("Custom"), QVariant::fromValue(QPageSize::Custom));
+ m_blockSignals = false;
+ return;
}
}
}
-#endif
- if (ps == QPrinter::Custom) {
- m_printer->setPaperSize(sizeForOrientation(orientation, m_paperSize), QPrinter::Point);
- }
- else {
- m_printer->setPaperSize(static_cast<QPrinter::PaperSize>(ps));
- }
- m_printer->setPaperName(widget.paperSize->currentText());
-#ifdef PSD_ENABLE_PAPERSOURCE
- m_printer->setPaperSource((QPrinter::PaperSource)widget.paperSource->currentIndex());
-#endif
- m_printer->setPageMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin, QPrinter::Point);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- QCUPSSupport::PagesPerSheet pagesPerSheet = widget.pagesPerSheetCombo->currentData()
- .value<QCUPSSupport::PagesPerSheet>();
- QCUPSSupport::PagesPerSheetLayout pagesPerSheetLayout = widget.pagesPerSheetLayoutCombo->currentData()
- .value<QCUPSSupport::PagesPerSheetLayout>();
+ // If PdfFormat or no available printer page sizes, populate with all page sizes
+ for (int id = 0; id < QPageSize::LastPageSize; ++id) {
+ if (QPageSize::PageSizeId(id) == QPageSize::Custom) {
+ m_ui.pageSizeCombo->addItem(tr("Custom"), id);
+ } else {
+ QPageSize pageSize = QPageSize(QPageSize::PageSizeId(id));
+ m_ui.pageSizeCombo->addItem(pageSize.name(), id);
+ }
+ }
- QCUPSSupport::setPagesPerSheetLayout(m_printer, pagesPerSheet, pagesPerSheetLayout);
-#endif
+ m_blockSignals = false;
}
-void QPageSetupWidget::selectPrinter()
+// Set the dialog to use the given QPrinter
+// Usually only called on first creation
+void QPageSetupWidget::setPrinter(QPrinter *printer)
{
- widget.paperSize->clear();
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- m_cups = true;
- QCUPSSupport cups;
- cups.setCurrentPrinter(m_printer->printerName());
- const ppd_option_t* pageSizes = cups.pageSizes();
- const int numChoices = pageSizes ? pageSizes->num_choices : 0;
-
- int cupsDefaultSize = 0;
- QSize qtPreferredSize = m_printer->paperSize(QPrinter::Point).toSize();
- QString qtPaperName = m_printer->paperName();
- bool preferredSizeMatched = false;
- for (int i = 0; i < numChoices; ++i) {
- widget.paperSize->addItem(QString::fromLocal8Bit(pageSizes->choices[i].text), QByteArray(pageSizes->choices[i].choice));
- if (static_cast<int>(pageSizes->choices[i].marked) == 1)
- cupsDefaultSize = i;
- if (qtPaperName == QString::fromLocal8Bit(pageSizes->choices[i].text)) {
- widget.paperSize->setCurrentIndex(i);
- preferredSizeMatched = true;
- } else {
- QRect cupsPaperSize = cups.paperRect(pageSizes->choices[i].choice);
- QSize diff = cupsPaperSize.size() - qtPreferredSize;
- if (qAbs(diff.width()) < 5 && qAbs(diff.height()) < 5) {
- widget.paperSize->setCurrentIndex(i);
- preferredSizeMatched = true;
- }
- }
- }
- if (!preferredSizeMatched)
- widget.paperSize->setCurrentIndex(cupsDefaultSize);
- if (m_printer->d_func()->hasCustomPageMargins) {
- m_printer->getPageMargins(&m_leftMargin, &m_topMargin, &m_rightMargin, &m_bottomMargin, QPrinter::Point);
- } else {
- QByteArray cupsPaperSizeChoice = widget.paperSize->itemData(widget.paperSize->currentIndex()).toByteArray();
- QRect paper = cups.paperRect(cupsPaperSizeChoice);
- QRect content = cups.pageRect(cupsPaperSizeChoice);
-
- m_leftMargin = content.x() - paper.x();
- m_topMargin = content.y() - paper.y();
- m_rightMargin = paper.right() - content.right();
- m_bottomMargin = paper.bottom() - content.bottom();
- }
- } else
- m_cups = false;
-#endif
- if (widget.paperSize->count() == 0) {
- populatePaperSizes(widget.paperSize);
- widget.paperSize->setCurrentIndex(widget.paperSize->findData(
- QLocale::system().measurementSystem() == QLocale::ImperialSystem ? QPrinter::Letter : QPrinter::A4));
+ m_printer = printer;
+
+ // Initialize the layout to the current QPrinter layout
+ m_pageLayout = m_printer->pageLayout();
+ // Assume if margins are Points then is by default, so set to locale default units
+ if (m_pageLayout.units() == QPageLayout::Point) {
+ if (QLocale().measurementSystem() == QLocale::MetricSystem)
+ m_pageLayout.setUnits(QPageLayout::Millimeter);
+ else
+ m_pageLayout.setUnits(QPageLayout::Inch);
}
+ m_units = m_pageLayout.units();
+ m_pagePreview->setPageLayout(m_pageLayout);
- unitChanged(widget.unit->currentIndex());
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+ // Then update the widget with the current printer details
+ selectPrinter(m_printer->outputFormat(), m_printer->printerName());
}
-void QPageSetupWidget::selectPdfPsPrinter(const QPrinter *p)
+// The printer selected in the QPrintDialog has been changed, update the widget to reflect this
+// Note the QPrinter is not updated at this time in case the user presses the Cancel button in QPrintDialog
+void QPageSetupWidget::selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName)
{
- m_cups = false;
- widget.paperSize->clear();
- populatePaperSizes(widget.paperSize);
- widget.paperSize->setCurrentIndex(widget.paperSize->findData(p->paperSize()));
- unitChanged(widget.unit->currentIndex());
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+ m_outputFormat = outputFormat;
+ m_printerName = printerName;
+ initPageSizes();
+ updateWidget();
}
-// Updates size/preview after the combobox has been changed.
-void QPageSetupWidget::_q_paperSizeChanged()
+// Update the widget with the current settings
+// TODO Break up into more intelligent chunks?
+void QPageSetupWidget::updateWidget()
{
- if (m_blockSignals) return;
m_blockSignals = true;
- bool custom = false;
- QVariant val = widget.paperSize->itemData(widget.paperSize->currentIndex());
- QPrinter::Orientation orientation = widget.portrait->isChecked() ? QPrinter::Portrait : QPrinter::Landscape;
-
- if (m_cups) {
- // OutputFormat == NativeFormat, data is QString Cups paper name
- QByteArray cupsPageSize = val.toByteArray();
- custom = (cupsPageSize == QByteArrayLiteral("Custom"));
-#ifndef QT_NO_CUPS
- if (!custom) {
- QCUPSSupport cups;
- cups.setCurrentPrinter(m_printer->printerName());
- m_paperSize = sizeForOrientation(orientation, cups.paperRect(cupsPageSize).size());
- }
-#endif
- } else {
- // OutputFormat == PdfFormat, data is QPrinter::PageSize
- QPrinter::PaperSize size = QPrinter::PaperSize(val.toInt());
- custom = size == QPrinter::Custom;
- if (!custom)
- m_paperSize = qt_printerPaperSize(orientation, size, QPrinter::Point, 1);
+ QString suffix;
+ switch (m_units) {
+ case QPageLayout::Millimeter:
+ //: Unit 'Millimeter'
+ suffix = tr("mm");
+ break;
+ case QPageLayout::Point:
+ //: Unit 'Points'
+ suffix = tr("pt");
+ break;
+ case QPageLayout::Inch:
+ //: Unit 'Inch'
+ suffix = tr("in");
+ break;
+ case QPageLayout::Pica:
+ //: Unit 'Pica'
+ suffix = tr("P̸");
+ break;
+ case QPageLayout::Didot:
+ //: Unit 'Didot'
+ suffix = tr("DD");
+ break;
+ case QPageLayout::Cicero:
+ //: Unit 'Cicero'
+ suffix = tr("CC");
+ break;
}
- if (custom) {
- // Convert input custom size Units to Points
- m_paperSize = QSizeF(widget.paperWidth->value() * m_currentMultiplier,
- widget.paperHeight->value() * m_currentMultiplier);
+ m_ui.unitCombo->setCurrentIndex(m_ui.unitCombo->findData(QVariant::fromValue(m_units)));
+
+ m_ui.pageSizeCombo->setCurrentIndex(m_ui.pageSizeCombo->findData(QVariant::fromValue(m_pageLayout.pageSize().id())));
+
+ QMarginsF min;
+ QMarginsF max;
+
+ if (m_pageLayout.mode() == QPageLayout::FullPageMode) {
+ min = QMarginsF(0.0, 0.0, 0.0, 0.0);
+ max = QMarginsF(9999.9999, 9999.9999, 9999.9999, 9999.9999);
} else {
- // Display standard size Points as Units
- widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
- widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
+ min = m_pageLayout.minimumMargins();
+ max = m_pageLayout.maximumMargins();
}
- m_pagePreview->setPaperSize(m_paperSize);
+ m_ui.leftMargin->setSuffix(suffix);
+ m_ui.leftMargin->setMinimum(min.left());
+ m_ui.leftMargin->setMaximum(max.left());
+ m_ui.leftMargin->setValue(m_pageLayout.margins().left());
+
+ m_ui.rightMargin->setSuffix(suffix);
+ m_ui.rightMargin->setMinimum(min.right());
+ m_ui.rightMargin->setMaximum(max.right());
+ m_ui.rightMargin->setValue(m_pageLayout.margins().right());
- widget.paperWidth->setEnabled(custom);
- widget.paperHeight->setEnabled(custom);
- widget.widthLabel->setEnabled(custom);
- widget.heightLabel->setEnabled(custom);
+ m_ui.topMargin->setSuffix(suffix);
+ m_ui.topMargin->setMinimum(min.top());
+ m_ui.topMargin->setMaximum(max.top());
+ m_ui.topMargin->setValue(m_pageLayout.margins().top());
+
+ m_ui.bottomMargin->setSuffix(suffix);
+ m_ui.bottomMargin->setMinimum(min.bottom());
+ m_ui.bottomMargin->setMaximum(max.bottom());
+ m_ui.bottomMargin->setValue(m_pageLayout.margins().bottom());
+
+ bool isCustom = m_ui.pageSizeCombo->currentData().value<QPageSize::PageSizeId>() == QPageSize::Custom;
+
+ m_ui.pageWidth->setSuffix(suffix);
+ m_ui.pageWidth->setValue(m_pageLayout.fullRect(m_units).width());
+ m_ui.pageWidth->setEnabled(isCustom);
+ m_ui.widthLabel->setEnabled(isCustom);
+
+ m_ui.pageHeight->setSuffix(suffix);
+ m_ui.pageHeight->setValue(m_pageLayout.fullRect(m_units).height());
+ m_ui.pageHeight->setEnabled(isCustom);
+ m_ui.heightLabel->setEnabled(isCustom);
+
+ m_ui.landscape->setChecked(m_pageLayout.orientation() == QPageLayout::Landscape);
+
+ m_ui.pagesPerSheetButtonGroup->setEnabled(m_outputFormat == QPrinter::NativeFormat);
+
+#ifdef PSD_ENABLE_PAPERSOURCE
+ m_ui.paperSource->setCurrentItem(printer->paperSource());
+#endif
m_blockSignals = false;
}
-void QPageSetupWidget::_q_pageOrientationChanged()
+// Set the dialog chosen options on the QPrinter
+// Normally only called when the QPrintDialog or QPageSetupDialog OK button is pressed
+void QPageSetupWidget::setupPrinter() const
{
- bool custom = false;
- QVariant val = widget.paperSize->itemData(widget.paperSize->currentIndex());
+ m_printer->setPageLayout(m_pageLayout);
+#if !defined(QT_NO_CUPS)
+ QCUPSSupport::PagesPerSheet pagesPerSheet = m_ui.pagesPerSheetCombo->currentData()
+ .value<QCUPSSupport::PagesPerSheet>();
+ QCUPSSupport::PagesPerSheetLayout pagesPerSheetLayout = m_ui.pagesPerSheetLayoutCombo->currentData()
+ .value<QCUPSSupport::PagesPerSheetLayout>();
+ QCUPSSupport::setPagesPerSheetLayout(m_printer, pagesPerSheet, pagesPerSheetLayout);
+#endif
+#ifdef PSD_ENABLE_PAPERSOURCE
+ m_printer->setPaperSource((QPrinter::PaperSource)m_ui.paperSource->currentIndex());
+#endif
+}
- if (m_cups) {
- // OutputFormat == NativeFormat, data is QString Cups paper name
- QByteArray cupsPageSize = val.toByteArray();
- custom = (cupsPageSize == QByteArrayLiteral("Custom"));
+// Updates size/preview after the combobox has been changed.
+void QPageSetupWidget::pageSizeChanged()
+{
+ if (m_blockSignals)
+ return;
+
+ QPageSize::PageSizeId id = m_ui.pageSizeCombo->currentData().value<QPageSize::PageSizeId>();
+ if (id != QPageSize::Custom) {
+ // TODO Set layout margin min/max to printer custom min/max
+ m_pageLayout.setPageSize(QPageSize(id));
} else {
- // OutputFormat == PdfFormat, data is QPrinter::PageSize
- QPrinter::PaperSize size = QPrinter::PaperSize(val.toInt());
- custom = size == QPrinter::Custom;
+ QSizeF customSize;
+ if (m_pageLayout.orientation() == QPageLayout::Landscape)
+ customSize = QSizeF(m_ui.pageHeight->value(), m_ui.pageWidth->value());
+ else
+ customSize = QSizeF(m_ui.pageWidth->value(), m_ui.pageHeight->value());
+ // TODO Set layout margin min/max to printer min/max for page size
+ m_pageLayout.setPageSize(QPageSize(customSize, QPageSize::Unit(m_units)));
}
+ m_pagePreview->setPageLayout(m_pageLayout);
- if (custom) {
- double tmp = widget.paperWidth->value();
- widget.paperWidth->setValue(widget.paperHeight->value());
- widget.paperHeight->setValue(tmp);
- }
- _q_paperSizeChanged();
+ updateWidget();
}
-void QPageSetupWidget::_q_pagesPerSheetChanged()
+void QPageSetupWidget::pageOrientationChanged()
{
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- QCUPSSupport::PagesPerSheet pagesPerSheet = widget.pagesPerSheetCombo->currentData()
- .value<QCUPSSupport::PagesPerSheet>();
+ if (m_blockSignals)
+ return;
+ m_pageLayout.setOrientation(m_ui.portrait->isChecked() ? QPageLayout::Portrait : QPageLayout::Landscape);
+ m_pagePreview->setPageLayout(m_pageLayout);
+ updateWidget();
+}
- switch (pagesPerSheet) {
+void QPageSetupWidget::pagesPerSheetChanged()
+{
+#if !defined(QT_NO_CUPS)
+ switch (m_ui.pagesPerSheetCombo->currentData().toInt()) {
+ case QCUPSSupport::OnePagePerSheet:
+ m_pagePreview->setPagePreviewLayout(1, 1);
+ break;
case QCUPSSupport::TwoPagesPerSheet:
m_pagePreview->setPagePreviewLayout(1, 2);
break;
@@ -563,84 +567,53 @@ void QPageSetupWidget::_q_pagesPerSheetChanged()
case QCUPSSupport::SixteenPagesPerSheet:
m_pagePreview->setPagePreviewLayout(4, 4);
break;
- case QCUPSSupport::OnePagePerSheet:
- default:
- m_pagePreview->setPagePreviewLayout(1, 1);
- break;
}
#endif
}
-extern double qt_multiplierForUnit(QPrinter::Unit unit, int resolution);
-
-void QPageSetupWidget::unitChanged(int item)
+void QPageSetupWidget::unitChanged()
{
- QString suffix;
- switch(item) {
- case 0:
- m_currentMultiplier = 10 * qt_multiplierForUnit(QPrinter::Millimeter, 1);
- suffix = QString::fromLatin1(" cm");
- break;
- case 2:
- m_currentMultiplier = qt_multiplierForUnit(QPrinter::Inch, 1);
- suffix = QString::fromLatin1(" in");
- break;
- case 3:
- m_currentMultiplier = qt_multiplierForUnit(QPrinter::Point, 1);
- suffix = QString::fromLatin1(" pt");
- break;
- case 1:
- default:
- m_currentMultiplier = qt_multiplierForUnit(QPrinter::Millimeter, 1);
- suffix = QString::fromLatin1(" mm");
- break;
- }
- const bool old = m_blockSignals;
- m_blockSignals = true;
- widget.topMargin->setSuffix(suffix);
- widget.leftMargin->setSuffix(suffix);
- widget.rightMargin->setSuffix(suffix);
- widget.bottomMargin->setSuffix(suffix);
- widget.paperWidth->setSuffix(suffix);
- widget.paperHeight->setSuffix(suffix);
- widget.topMargin->setValue(m_topMargin / m_currentMultiplier);
- widget.leftMargin->setValue(m_leftMargin / m_currentMultiplier);
- widget.rightMargin->setValue(m_rightMargin / m_currentMultiplier);
- widget.bottomMargin->setValue(m_bottomMargin / m_currentMultiplier);
- widget.paperWidth->setValue(m_paperSize.width() / m_currentMultiplier);
- widget.paperHeight->setValue(m_paperSize.height() / m_currentMultiplier);
- m_blockSignals = old;
+ if (m_blockSignals)
+ return;
+ m_units = m_ui.unitCombo->currentData().value<QPageLayout::Unit>();
+ m_pageLayout.setUnits(m_units);
+ updateWidget();
}
-void QPageSetupWidget::setTopMargin(double newValue)
+void QPageSetupWidget::topMarginChanged(double newValue)
{
- if (m_blockSignals) return;
- m_topMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+ if (m_blockSignals)
+ return;
+ m_pageLayout.setTopMargin(newValue);
+ m_pagePreview->setPageLayout(m_pageLayout);
}
-void QPageSetupWidget::setBottomMargin(double newValue)
+void QPageSetupWidget::bottomMarginChanged(double newValue)
{
- if (m_blockSignals) return;
- m_bottomMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+ if (m_blockSignals)
+ return;
+ m_pageLayout.setBottomMargin(newValue);
+ m_pagePreview->setPageLayout(m_pageLayout);
}
-void QPageSetupWidget::setLeftMargin(double newValue)
+void QPageSetupWidget::leftMarginChanged(double newValue)
{
- if (m_blockSignals) return;
- m_leftMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+ if (m_blockSignals)
+ return;
+ m_pageLayout.setLeftMargin(newValue);
+ m_pagePreview->setPageLayout(m_pageLayout);
}
-void QPageSetupWidget::setRightMargin(double newValue)
+void QPageSetupWidget::rightMarginChanged(double newValue)
{
- if (m_blockSignals) return;
- m_rightMargin = newValue * m_currentMultiplier;
- m_pagePreview->setMargins(m_leftMargin, m_topMargin, m_rightMargin, m_bottomMargin);
+ if (m_blockSignals)
+ return;
+ m_pageLayout.setRightMargin(newValue);
+ m_pagePreview->setPageLayout(m_pageLayout);
}
-
+// QPageSetupDialog
+// - Public Linux / CUPS class implementation
QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
: QDialog(*(new QUnixPageSetupDialogPrivate(printer)), parent)
@@ -650,7 +623,6 @@ QPageSetupDialog::QPageSetupDialog(QPrinter *printer, QWidget *parent)
static_cast<QUnixPageSetupDialogPrivate *>(d)->init();
}
-
QPageSetupDialog::QPageSetupDialog(QWidget *parent)
: QDialog(*(new QUnixPageSetupDialogPrivate(0)), parent)
{
@@ -669,35 +641,6 @@ int QPageSetupDialog::exec()
return ret;
}
-void QPageSetupWidget::initPagesPerSheet()
-{
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Left to Right, Top to Bottom"), QVariant::fromValue(QCUPSSupport::LeftToRightTopToBottom));
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Left to Right, Bottom to Top"), QVariant::fromValue(QCUPSSupport::LeftToRightBottomToTop));
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Right to Left, Bottom to Top"), QVariant::fromValue(QCUPSSupport::RightToLeftBottomToTop));
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Right to Left, Top to Bottom"), QVariant::fromValue(QCUPSSupport::RightToLeftTopToBottom));
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Bottom to Top, Left to Right"), QVariant::fromValue(QCUPSSupport::BottomToTopLeftToRight));
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Bottom to Top, Right to Left"), QVariant::fromValue(QCUPSSupport::BottomToTopRightToLeft));
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Top to Bottom, Left to Right"), QVariant::fromValue(QCUPSSupport::TopToBottomLeftToRight));
- widget.pagesPerSheetLayoutCombo->addItem(QPrintDialog::tr("Top to Bottom, Right to Left"), QVariant::fromValue(QCUPSSupport::TopToBottomRightToLeft));
-
- widget.pagesPerSheetCombo->addItem(QPrintDialog::tr("1 (1x1)"), QVariant::fromValue(QCUPSSupport::OnePagePerSheet));
- widget.pagesPerSheetCombo->addItem(QPrintDialog::tr("2 (2x1)"), QVariant::fromValue(QCUPSSupport::TwoPagesPerSheet));
- widget.pagesPerSheetCombo->addItem(QPrintDialog::tr("4 (2x2)"), QVariant::fromValue(QCUPSSupport::FourPagesPerSheet));
- widget.pagesPerSheetCombo->addItem(QPrintDialog::tr("6 (2x3)"), QVariant::fromValue(QCUPSSupport::SixPagesPerSheet));
- widget.pagesPerSheetCombo->addItem(QPrintDialog::tr("9 (3x3)"), QVariant::fromValue(QCUPSSupport::NinePagesPerSheet));
- widget.pagesPerSheetCombo->addItem(QPrintDialog::tr("16 (4x4)"), QVariant::fromValue(QCUPSSupport::SixteenPagesPerSheet));
-
- // Set the combo to "1 (1x1)" -- QCUPSSupport::OnePagePerSheet
- widget.pagesPerSheetCombo->setCurrentIndex(0);
- // Set the layout combo to QCUPSSupport::LeftToRightTopToBottom
- widget.pagesPerSheetLayoutCombo->setCurrentIndex(0);
-#else
- // Disable if CUPS wasn't found
- widget.pagesPerSheetButtonGroup->hide();
-#endif
-}
-
QT_END_NAMESPACE
#include "moc_qpagesetupdialog.cpp"
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
index 4245c3ae5f..2a359a8118 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix_p.h
@@ -57,6 +57,10 @@
#ifndef QT_NO_PRINTDIALOG
+#include "qprinter.h"
+
+#include <QtGui/qpagelayout.h>
+
#include <ui_qpagesetupwidget.h>
QT_BEGIN_NAMESPACE
@@ -69,37 +73,37 @@ class QPageSetupWidget : public QWidget {
public:
explicit QPageSetupWidget(QWidget *parent = 0);
explicit QPageSetupWidget(QPrinter *printer, QWidget *parent = 0);
+
void setPrinter(QPrinter *printer);
- /// copy information from the widget and apply that to the printer.
+ void selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName);
void setupPrinter() const;
- void selectPrinter();
- void selectPdfPsPrinter(const QPrinter *p);
private slots:
- void _q_pageOrientationChanged();
- void _q_paperSizeChanged();
- void _q_pagesPerSheetChanged();
- void unitChanged(int item);
- void setTopMargin(double newValue);
- void setBottomMargin(double newValue);
- void setLeftMargin(double newValue);
- void setRightMargin(double newValue);
+ void pageSizeChanged();
+ void pageOrientationChanged();
+ void pagesPerSheetChanged();
+ void unitChanged();
+ void topMarginChanged(double newValue);
+ void bottomMarginChanged(double newValue);
+ void leftMarginChanged(double newValue);
+ void rightMarginChanged(double newValue);
private:
- friend class QUnixPrintWidgetPrivate;
- Ui::QPageSetupWidget widget;
+ friend class QUnixPrintWidgetPrivate; // Needed by checkFields()
+
+ void updateWidget();
+ void initUnits();
+ void initPagesPerSheet();
+ void initPageSizes();
+
+ Ui::QPageSetupWidget m_ui;
QPagePreview *m_pagePreview;
QPrinter *m_printer;
- qreal m_leftMargin;
- qreal m_topMargin;
- qreal m_rightMargin;
- qreal m_bottomMargin;
- QSizeF m_paperSize; // In QPrinter::Point
- qreal m_currentMultiplier;
+ QPrinter::OutputFormat m_outputFormat;
+ QString m_printerName;
+ QPageLayout m_pageLayout;
+ QPageLayout::Unit m_units;
bool m_blockSignals;
- bool m_cups;
-
- void initPagesPerSheet();
};
QT_END_NAMESPACE
diff --git a/src/printsupport/dialogs/qpagesetupdialog_win.cpp b/src/printsupport/dialogs/qpagesetupdialog_win.cpp
index 345e698b82..5da87cce18 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_win.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_win.cpp
@@ -106,42 +106,40 @@ int QPageSetupDialog::exec()
psd.hwndOwner = parentWindow ? (HWND)QGuiApplication::platformNativeInterface()->nativeResourceForWindow("handle", parentWindow) : 0;
psd.Flags = PSD_MARGINS;
- double multiplier = 1;
- switch (QLocale::system().measurementSystem()) {
- case QLocale::MetricSystem:
- psd.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
- multiplier = 1;
+ QPageLayout layout = d->printer->pageLayout();
+ switch (layout.units()) {
+ case QPageLayout::Millimeter:
+ case QPageLayout::Inch:
break;
- case QLocale::ImperialSystem:
- case QLocale::ImperialUKSystem:
- psd.Flags |= PSD_INTHOUSANDTHSOFINCHES;
- multiplier = 25.4/10;
+ case QPageLayout::Point:
+ case QPageLayout::Pica:
+ case QPageLayout::Didot:
+ case QPageLayout::Cicero:
+ layout.setUnits(QLocale::system().measurementSystem() == QLocale::MetricSystem ? QPageLayout::Millimeter
+ : QPageLayout::Inch);
break;
}
-
- QRect marginRect = ep->getPageMargins();
- psd.rtMargin.left = marginRect.left() / multiplier;
- psd.rtMargin.top = marginRect.top() / multiplier;
- psd.rtMargin.right = marginRect.width() / multiplier;;
- psd.rtMargin.bottom = marginRect.height() / multiplier;;
+ qreal multiplier = 1.0;
+ if (layout.units() == QPageLayout::Millimeter) {
+ psd.Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
+ multiplier = 100.0;
+ } else { // QPageLayout::Inch)
+ psd.Flags |= PSD_INTHOUSANDTHSOFINCHES;
+ multiplier = 1000.0;
+ }
+ psd.rtMargin.left = layout.margins().left() * multiplier;
+ psd.rtMargin.top = layout.margins().top() * multiplier;
+ psd.rtMargin.right = layout.margins().right() * multiplier;
+ psd.rtMargin.bottom = layout.margins().bottom() * multiplier;
QDialog::setVisible(true);
bool result = PageSetupDlg(&psd);
QDialog::setVisible(false);
if (result) {
engine->setGlobalDevMode(psd.hDevNames, psd.hDevMode);
-
- QRect theseMargins = QRect(psd.rtMargin.left * multiplier,
- psd.rtMargin.top * multiplier,
- psd.rtMargin.right * multiplier,
- psd.rtMargin.bottom * multiplier);
-
- if (theseMargins != marginRect) {
- ep->setPageMargins(psd.rtMargin.left * multiplier,
- psd.rtMargin.top * multiplier,
- psd.rtMargin.right * multiplier,
- psd.rtMargin.bottom * multiplier);
- }
+ d->printer->setPageMargins(QMarginsF(psd.rtMargin.left / multiplier, psd.rtMargin.right / multiplier,
+ psd.rtMargin.top / multiplier, psd.rtMargin.bottom / multiplier),
+ layout.units());
// copy from our temp DEVMODE struct
if (!engine->globalDevMode() && hDevMode) {
diff --git a/src/printsupport/dialogs/qpagesetupwidget.ui b/src/printsupport/dialogs/qpagesetupwidget.ui
index ffd2650f4c..960a9dac17 100644
--- a/src/printsupport/dialogs/qpagesetupwidget.ui
+++ b/src/printsupport/dialogs/qpagesetupwidget.ui
@@ -28,12 +28,12 @@
<string>Page size:</string>
</property>
<property name="buddy">
- <cstring>paperSize</cstring>
+ <cstring>pageSizeCombo</cstring>
</property>
</widget>
</item>
<item row="0" column="1" >
- <widget class="QComboBox" name="paperSize" />
+ <widget class="QComboBox" name="pageSizeCombo" />
</item>
<item row="1" column="0" >
<widget class="QLabel" name="widthLabel" >
@@ -41,14 +41,14 @@
<string>Width:</string>
</property>
<property name="buddy" >
- <cstring>paperWidth</cstring>
+ <cstring>pageWidth</cstring>
</property>
</widget>
</item>
<item row="1" column="1" >
<layout class="QHBoxLayout" name="horizontalLayout_3" >
<item>
- <widget class="QDoubleSpinBox" name="paperWidth" >
+ <widget class="QDoubleSpinBox" name="pageWidth" >
<property name="maximum" >
<double>9999.989999999999782</double>
</property>
@@ -60,12 +60,12 @@
<string>Height:</string>
</property>
<property name="buddy" >
- <cstring>paperHeight</cstring>
+ <cstring>pageHeight</cstring>
</property>
</widget>
</item>
<item>
- <widget class="QDoubleSpinBox" name="paperHeight" >
+ <widget class="QDoubleSpinBox" name="pageHeight" >
<property name="maximum" >
<double>9999.989999999999782</double>
</property>
@@ -105,7 +105,7 @@
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
- <widget class="QComboBox" name="unit"/>
+ <widget class="QComboBox" name="unitCombo"/>
</item>
<item>
<spacer name="horizontalSpacer_3">
diff --git a/src/printsupport/dialogs/qprintdialog_mac.mm b/src/printsupport/dialogs/qprintdialog_mac.mm
index bf1617065b..9ff7c4766a 100644
--- a/src/printsupport/dialogs/qprintdialog_mac.mm
+++ b/src/printsupport/dialogs/qprintdialog_mac.mm
@@ -49,11 +49,14 @@
#include <QtWidgets/private/qapplication_p.h>
#include <QtPrintSupport/qprinter.h>
#include <QtPrintSupport/qprintengine.h>
+#include <qpa/qplatformprintdevice.h>
#ifndef QT_NO_PRINTDIALOG
QT_BEGIN_NAMESPACE
+extern qreal qt_pointMultiplier(QPageLayout::Unit unit);
+
class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
{
Q_DECLARE_PUBLIC(QPrintDialog)
@@ -148,6 +151,47 @@ QT_USE_NAMESPACE
}
}
+ // Note this code should be in QCocoaPrintDevice, but that implementation is in the plugin,
+ // we need to move the dialog implementation into the plugin first to be able to access it.
+ // Need to tell QPrinter/QPageLayout if the page size or orientation has been changed
+ PMPageFormat pageFormat = static_cast<PMPageFormat>([printInfo PMPageFormat]);
+ PMPaper paper;
+ PMGetPageFormatPaper(pageFormat, &paper);
+ PMOrientation orientation;
+ PMGetOrientation(pageFormat, &orientation);
+ QPageSize pageSize;
+ QCFString key;
+ double width = 0;
+ double height = 0;
+ // If the PPD name is empty then is custom, for some reason PMPaperIsCustom doesn't work here
+ PMPaperGetPPDPaperName(paper, &key);
+ if (PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr) {
+ QString ppdKey = key;
+ if (ppdKey.isEmpty()) {
+ // Is using a custom page size as defined in the Print Dialog custom settings using mm or inches.
+ // We can't ask PMPaper what those units actually are, we can only get the point size which may return
+ // slightly wrong results due to rounding.
+ // Testing shows if using metric/mm then is rounded mm, if imperial/inch is rounded to 2 decimal places
+ // Even if we pass in our own custom size in mm with decimal places, the dialog will still round it!
+ // Suspect internal storage is in rounded mm?
+ if (QLocale().measurementSystem() == QLocale::MetricSystem) {
+ QSizeF sizef = QSizeF(width, height) / qt_pointMultiplier(QPageLayout::Millimeter);
+ // Round to 0 decimal places
+ pageSize = QPageSize(sizef.toSize(), QPageSize::Millimeter);
+ } else {
+ qreal multiplier = qt_pointMultiplier(QPageLayout::Inch);
+ const int w = qRound(width * 100 / multiplier);
+ const int h = qRound(height * 100 / multiplier);
+ pageSize = QPageSize(QSizeF(w / 100.0, h / 100.0), QPageSize::Inch);
+ }
+ } else {
+ pageSize = QPlatformPrintDevice::createPageSize(key, QSize(width, height), QString());
+ }
+ }
+ if (pageSize.isValid() && !pageSize.isEquivalentTo(printer->pageLayout().pageSize()))
+ printer->setPageSize(pageSize);
+ printer->setOrientation(orientation == kPMLandscape ? QPrinter::Landscape : QPrinter::Portrait);
+
dialog->done((returnCode == NSOKButton) ? QDialog::Accepted : QDialog::Rejected);
}
@end
diff --git a/src/printsupport/dialogs/qprintdialog_unix.cpp b/src/printsupport/dialogs/qprintdialog_unix.cpp
index 2ec1088bb4..ab31db76aa 100644
--- a/src/printsupport/dialogs/qprintdialog_unix.cpp
+++ b/src/printsupport/dialogs/qprintdialog_unix.cpp
@@ -52,8 +52,11 @@
#include <QtWidgets/qfilesystemmodel.h>
#include <QtWidgets/qstyleditemdelegate.h>
#include <QtPrintSupport/qprinter.h>
-#include <QtPrintSupport/qprinterinfo.h>
-#include <private/qprintengine_pdf_p.h>
+
+#include <qpa/qplatformprintplugin.h>
+#include <qpa/qplatformprintersupport.h>
+
+#include <private/qprintdevice_p.h>
#include <QtWidgets/qdialogbuttonbox.h>
@@ -62,12 +65,9 @@
#include "ui_qprintsettingsoutput.h"
#include "ui_qprintwidget.h"
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
-# include <private/qcups_p.h>
-# include "qcupsjobwidget_p.h"
-#else
-# include <QtCore/qlibrary.h>
-# include <private/qprintengine_pdf_p.h>
+#ifndef QT_NO_CUPS
+#include <private/qcups_p.h>
+#include "qcupsjobwidget_p.h"
#endif
/*
@@ -120,8 +120,7 @@ public:
QPrintPropertiesDialog(QAbstractPrintDialog *parent = 0);
~QPrintPropertiesDialog();
- void selectPrinter();
- void selectPdfPsPrinter(const QPrinter *p);
+ void selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName);
/// copy printer properties to the widget
void applyPrinterProperties(QPrinter *p);
@@ -134,7 +133,7 @@ private:
friend class QUnixPrintWidgetPrivate;
Ui::QPrintPropertiesWidget widget;
QDialogButtonBox *m_buttons;
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+#ifndef QT_NO_CUPS
QCupsJobWidget *m_jobOptions;
#endif
};
@@ -181,6 +180,8 @@ public:
Ui::QPrintWidget widget;
QAbstractPrintDialog * q;
QPrinter *printer;
+ QPrintDevice m_currentPrintDevice;
+
void updateWidget();
private:
@@ -249,11 +250,9 @@ QPrintPropertiesDialog::QPrintPropertiesDialog(QAbstractPrintDialog *parent)
connect(m_buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(accept()));
connect(m_buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), this, SLOT(reject()));
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- m_jobOptions = new QCupsJobWidget();
- widget.tabs->addTab(m_jobOptions, tr("Job Options"));
- }
+#ifndef QT_NO_CUPS
+ m_jobOptions = new QCupsJobWidget();
+ widget.tabs->addTab(m_jobOptions, tr("Job Options"));
#endif
}
@@ -264,31 +263,22 @@ QPrintPropertiesDialog::~QPrintPropertiesDialog()
void QPrintPropertiesDialog::applyPrinterProperties(QPrinter *p)
{
widget.pageSetup->setPrinter(p);
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- m_jobOptions->setPrinter(p);
- }
+#ifndef QT_NO_CUPS
+ m_jobOptions->setPrinter(p);
#endif
}
void QPrintPropertiesDialog::setupPrinter() const
{
widget.pageSetup->setupPrinter();
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- m_jobOptions->setupPrinter();
- }
+#ifndef QT_NO_CUPS
+ m_jobOptions->setupPrinter();
#endif
}
-void QPrintPropertiesDialog::selectPrinter()
+void QPrintPropertiesDialog::selectPrinter(QPrinter::OutputFormat outputFormat, const QString &printerName)
{
- widget.pageSetup->selectPrinter();
-}
-
-void QPrintPropertiesDialog::selectPdfPsPrinter(const QPrinter *p)
-{
- widget.pageSetup->selectPdfPsPrinter(p);
+ widget.pageSetup->selectPrinter(outputFormat, printerName);
}
void QPrintPropertiesDialog::showEvent(QShowEvent* event)
@@ -329,13 +319,11 @@ void QPrintDialogPrivate::init()
options.grayscale->setIconSize(QSize(32, 32));
options.grayscale->setIcon(QIcon(QLatin1String(":/qt-project.org/dialogs/qprintdialog/images/status-gray-scale.png")));
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+#ifndef QT_NO_CUPS
// Add Page Set widget if CUPS is available
- if (QCUPSSupport::isAvailable()) {
- options.pageSetCombo->addItem(tr("All Pages"), QVariant::fromValue(QCUPSSupport::AllPages));
- options.pageSetCombo->addItem(tr("Odd Pages"), QVariant::fromValue(QCUPSSupport::OddPages));
- options.pageSetCombo->addItem(tr("Even Pages"), QVariant::fromValue(QCUPSSupport::EvenPages));
- }
+ options.pageSetCombo->addItem(tr("All Pages"), QVariant::fromValue(QCUPSSupport::AllPages));
+ options.pageSetCombo->addItem(tr("Odd Pages"), QVariant::fromValue(QCUPSSupport::OddPages));
+ options.pageSetCombo->addItem(tr("Even Pages"), QVariant::fromValue(QCUPSSupport::EvenPages));
#endif
top->d->setOptionsPane(this);
@@ -453,24 +441,27 @@ void QPrintDialogPrivate::setupPrinter()
}
}
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+#ifndef QT_NO_CUPS
// page set
- if (QCUPSSupport::isAvailable()) {
- if (p->printRange() == QPrinter::AllPages || p->printRange() == QPrinter::PageRange) {
- //If the application is selecting pages and the first page number is even then need to adjust the odd-even accordingly
- QCUPSSupport::PageSet pageSet = options.pageSetCombo->itemData(options.pageSetCombo->currentIndex()).value<QCUPSSupport::PageSet>();
- if (q->isOptionEnabled(QPrintDialog::PrintPageRange)
- && p->printRange() == QPrinter::PageRange
- && (q->fromPage() % 2 == 0)) {
-
- if (pageSet == QCUPSSupport::OddPages)
- QCUPSSupport::setPageSet(p, QCUPSSupport::EvenPages);
- else if (pageSet == QCUPSSupport::EvenPages)
- QCUPSSupport::setPageSet(p, QCUPSSupport::OddPages);
- } else if (pageSet != QCUPSSupport::AllPages) {
- QCUPSSupport::setPageSet(p, pageSet);
+ if (p->printRange() == QPrinter::AllPages || p->printRange() == QPrinter::PageRange) {
+ //If the application is selecting pages and the first page number is even then need to adjust the odd-even accordingly
+ QCUPSSupport::PageSet pageSet = options.pageSetCombo->itemData(options.pageSetCombo->currentIndex()).value<QCUPSSupport::PageSet>();
+ if (q->isOptionEnabled(QPrintDialog::PrintPageRange)
+ && p->printRange() == QPrinter::PageRange
+ && (q->fromPage() % 2 == 0)) {
+
+ switch (pageSet) {
+ case QCUPSSupport::AllPages:
+ break;
+ case QCUPSSupport::OddPages:
+ QCUPSSupport::setPageSet(p, QCUPSSupport::EvenPages);
+ break;
+ case QCUPSSupport::EvenPages:
+ QCUPSSupport::setPageSet(p, QCUPSSupport::OddPages);
+ break;
}
-
+ } else if (pageSet != QCUPSSupport::AllPages) {
+ QCUPSSupport::setPageSet(p, pageSet);
}
// server-side page range, since we set the page range on the printer to 0-0/AllPages above,
@@ -533,26 +524,22 @@ void QPrintDialogPrivate::updateWidgets()
options.printCurrentPage->setVisible(q->isOptionEnabled(QPrintDialog::PrintCurrentPage));
options.collate->setVisible(q->isOptionEnabled(QPrintDialog::PrintCollateCopies));
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
- if (QCUPSSupport::isAvailable()) {
- // Don't display Page Set if only Selection or Current Page are enabled
- if (!q->isOptionEnabled(QPrintDialog::PrintPageRange) && (
- q->isOptionEnabled(QPrintDialog::PrintSelection) ||
- q->isOptionEnabled(QPrintDialog::PrintCurrentPage))) {
-
- options.pageSetCombo->setVisible(false);
- options.pageSetLabel->setVisible(false);
- } else {
- options.pageSetCombo->setVisible(true);
- options.pageSetLabel->setVisible(true);
- }
+#ifndef QT_NO_CUPS
+ // Don't display Page Set if only Selection or Current Page are enabled
+ if (!q->isOptionEnabled(QPrintDialog::PrintPageRange)
+ && (q->isOptionEnabled(QPrintDialog::PrintSelection) || q->isOptionEnabled(QPrintDialog::PrintCurrentPage))) {
+ options.pageSetCombo->setVisible(false);
+ options.pageSetLabel->setVisible(false);
+ } else {
+ options.pageSetCombo->setVisible(true);
+ options.pageSetLabel->setVisible(true);
+ }
- if (!q->isOptionEnabled(QPrintDialog::PrintPageRange)) {
- // If we can do CUPS server side pages selection,
- // display the page range widgets
- options.gbPrintRange->setVisible(true);
- options.printRange->setEnabled(true);
- }
+ if (!q->isOptionEnabled(QPrintDialog::PrintPageRange)) {
+ // If we can do CUPS server side pages selection,
+ // display the page range widgets
+ options.gbPrintRange->setVisible(true);
+ options.printRange->setEnabled(true);
}
#endif
@@ -681,12 +668,17 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p, QPrinter *
widget.setupUi(parent);
int currentPrinterIndex = 0;
- QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters();
+ QStringList printers;
+ QString defaultPrinter;
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps) {
+ printers = ps->availablePrintDeviceIds();
+ defaultPrinter = ps->defaultPrintDeviceId();
+ }
for (int i = 0; i < printers.size(); ++i) {
- QPrinterInfo pInfo = printers.at(i);
- widget.printers->addItem(pInfo.printerName());
- if (pInfo.isDefault())
+ widget.printers->addItem(printers.at(i));
+ if (printers.at(i) == defaultPrinter)
currentPrinterIndex = i;
}
widget.properties->setEnabled(true);
@@ -775,12 +767,14 @@ void QUnixPrintWidgetPrivate::_q_printerChanged(int index)
}
if (printer) {
- QString printerName = widget.printers->itemText(index);
- printer->setPrinterName(printerName);
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps)
+ m_currentPrintDevice = ps->createPrintDevice(widget.printers->itemText(index));
+
+ printer->setPrinterName(m_currentPrintDevice.id());
- QPrinterInfo printerInfo = QPrinterInfo::printerInfo(printer->printerName());
- widget.location->setText(printerInfo.location());
- widget.type->setText(printerInfo.makeAndModel());
+ widget.location->setText(m_currentPrintDevice.location());
+ widget.type->setText(m_currentPrintDevice.makeAndModel());
if (optionsPane)
optionsPane->selectPrinter(QPrinter::NativeFormat);
}
@@ -847,7 +841,7 @@ void QUnixPrintWidgetPrivate::applyPrinterProperties()
}
}
}
- // PDF and PS printers are not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget
+ // PDF printer not added to the dialog yet, we'll handle those cases in QUnixPrintWidgetPrivate::updateWidget
if (propertiesDialog)
propertiesDialog->applyPrinterProperties(printer);
@@ -884,9 +878,10 @@ bool QUnixPrintWidgetPrivate::checkFields()
}
}
-#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY)
+#ifndef QT_NO_CUPS
if (propertiesDialogShown) {
- QCUPSSupport::PagesPerSheet pagesPerSheet = propertiesDialog->widget.pageSetup->widget.pagesPerSheetCombo->currentData().value<QCUPSSupport::PagesPerSheet>();
+ QCUPSSupport::PagesPerSheet pagesPerSheet = propertiesDialog->widget.pageSetup->m_ui.pagesPerSheetCombo
+ ->currentData().value<QCUPSSupport::PagesPerSheet>();
QCUPSSupport::PageSet pageSet = optionsPane->options.pageSetCombo->currentData().value<QCUPSSupport::PageSet>();
@@ -918,10 +913,10 @@ void QUnixPrintWidgetPrivate::setupPrinterProperties()
if (q->isOptionEnabled(QPrintDialog::PrintToFile)
&& (widget.printers->currentIndex() == widget.printers->count() - 1)) {// PDF
- propertiesDialog->selectPdfPsPrinter(q->printer());
+ propertiesDialog->selectPrinter(QPrinter::PdfFormat, QString());
}
else
- propertiesDialog->selectPrinter();
+ propertiesDialog->selectPrinter(QPrinter::NativeFormat, widget.printers->currentText());
}
void QUnixPrintWidgetPrivate::_q_btnPropertiesClicked()
diff --git a/src/printsupport/kernel/kernel.pri b/src/printsupport/kernel/kernel.pri
index 67fcc8597c..cbbb14342a 100644
--- a/src/printsupport/kernel/kernel.pri
+++ b/src/printsupport/kernel/kernel.pri
@@ -1,11 +1,14 @@
HEADERS += \
$$PWD/qpaintengine_alpha_p.h \
$$PWD/qpaintengine_preview_p.h \
+ $$PWD/qprint_p.h \
+ $$PWD/qprintdevice_p.h \
$$PWD/qprintengine.h \
$$PWD/qprinter.h \
$$PWD/qprinter_p.h \
$$PWD/qprinterinfo.h \
$$PWD/qprinterinfo_p.h \
+ $$PWD/qplatformprintdevice.h \
$$PWD/qplatformprintplugin.h \
$$PWD/qplatformprintersupport.h \
$$PWD/qtprintsupportglobal.h
@@ -13,9 +16,11 @@ HEADERS += \
SOURCES += \
$$PWD/qpaintengine_alpha.cpp \
$$PWD/qpaintengine_preview.cpp \
+ $$PWD/qprintdevice.cpp \
$$PWD/qprintengine_pdf.cpp \
$$PWD/qprinter.cpp \
$$PWD/qprinterinfo.cpp \
+ $$PWD/qplatformprintdevice.cpp \
$$PWD/qplatformprintplugin.cpp \
$$PWD/qplatformprintersupport.cpp
diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp
index e237d44dcd..a1c657eda4 100644
--- a/src/printsupport/kernel/qcups.cpp
+++ b/src/printsupport/kernel/qcups.cpp
@@ -41,322 +41,12 @@
#include "qcups_p.h"
-#include <qdebug.h>
+#include "qprintengine.h"
#ifndef QT_NO_CUPS
-#ifndef QT_LINUXBASE // LSB merges everything into cups.h
-# include <cups/language.h>
-#endif
-#include <qtextcodec.h>
-
-#include <algorithm>
-
QT_BEGIN_NAMESPACE
-extern double qt_multiplierForUnit(QPrinter::Unit unit, int resolution);
-
-typedef int (*CupsGetDests)(cups_dest_t **dests);
-typedef void (*CupsFreeDests)(int num_dests, cups_dest_t *dests);
-typedef const char* (*CupsGetPPD)(const char *printer);
-typedef int (*CupsMarkOptions)(ppd_file_t *ppd, int num_options, cups_option_t *options);
-typedef ppd_file_t* (*PPDOpenFile)(const char *filename);
-typedef void (*PPDMarkDefaults)(ppd_file_t *ppd);
-typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
-typedef void (*PPDClose)(ppd_file_t *ppd);
-typedef int (*PPDMarkOption)(ppd_file_t *ppd, const char *keyword, const char *option);
-typedef void (*CupsFreeOptions)(int num_options, cups_option_t *options);
-typedef void (*CupsSetDests)(int num_dests, cups_dest_t *dests);
-typedef cups_lang_t* (*CupsLangGet)(const char *language);
-typedef const char* (*CupsLangEncoding)(cups_lang_t *language);
-typedef int (*CupsAddOption)(const char *name, const char *value, int num_options, cups_option_t **options);
-typedef int (*CupsTempFd)(char *name, int len);
-typedef int (*CupsPrintFile)(const char * name, const char * filename, const char * title, int num_options, cups_option_t * options);
-
-static bool cupsLoaded = false;
-static int qt_cups_num_printers = 0;
-static CupsGetDests _cupsGetDests = 0;
-static CupsFreeDests _cupsFreeDests = 0;
-static CupsGetPPD _cupsGetPPD = 0;
-static PPDOpenFile _ppdOpenFile = 0;
-static PPDMarkDefaults _ppdMarkDefaults = 0;
-static PPDClose _ppdClose = 0;
-static CupsMarkOptions _cupsMarkOptions = 0;
-static PPDMarkOption _ppdMarkOption = 0;
-static CupsFreeOptions _cupsFreeOptions = 0;
-static CupsSetDests _cupsSetDests = 0;
-static CupsLangGet _cupsLangGet = 0;
-static CupsLangEncoding _cupsLangEncoding = 0;
-static CupsAddOption _cupsAddOption = 0;
-static CupsTempFd _cupsTempFd = 0;
-static CupsPrintFile _cupsPrintFile = 0;
-
-static void resolveCups()
-{
- QLibrary cupsLib(QLatin1String("cups"), 2);
- if(cupsLib.load()) {
- _cupsGetDests = (CupsGetDests) cupsLib.resolve("cupsGetDests");
- _cupsFreeDests = (CupsFreeDests) cupsLib.resolve("cupsFreeDests");
- _cupsGetPPD = (CupsGetPPD) cupsLib.resolve("cupsGetPPD");
- _cupsLangGet = (CupsLangGet) cupsLib.resolve("cupsLangGet");
- _cupsLangEncoding = (CupsLangEncoding) cupsLib.resolve("cupsLangEncoding");
- _ppdOpenFile = (PPDOpenFile) cupsLib.resolve("ppdOpenFile");
- _ppdMarkDefaults = (PPDMarkDefaults) cupsLib.resolve("ppdMarkDefaults");
- _ppdClose = (PPDClose) cupsLib.resolve("ppdClose");
- _cupsMarkOptions = (CupsMarkOptions) cupsLib.resolve("cupsMarkOptions");
- _ppdMarkOption = (PPDMarkOption) cupsLib.resolve("ppdMarkOption");
- _cupsFreeOptions = (CupsFreeOptions) cupsLib.resolve("cupsFreeOptions");
- _cupsSetDests = (CupsSetDests) cupsLib.resolve("cupsSetDests");
- _cupsAddOption = (CupsAddOption) cupsLib.resolve("cupsAddOption");
- _cupsTempFd = (CupsTempFd) cupsLib.resolve("cupsTempFd");
- _cupsPrintFile = (CupsPrintFile) cupsLib.resolve("cupsPrintFile");
-
- if (_cupsGetDests && _cupsFreeDests) {
- cups_dest_t *printers;
- int num_printers = _cupsGetDests(&printers);
- if (num_printers)
- _cupsFreeDests(num_printers, printers);
- qt_cups_num_printers = num_printers;
- }
- }
- cupsLoaded = true;
-}
-
-// ================ CUPS Support class ========================
-
-QCUPSSupport::QCUPSSupport()
- :
- prnCount(0),
- printers(0),
- page_sizes(0),
- currPrinterIndex(0),
- currPPD(0)
-{
- if (!cupsLoaded)
- resolveCups();
-
- // getting all available printers
- if (!isAvailable())
- return;
-
- qt_cups_num_printers = prnCount = _cupsGetDests(&printers);
-
- for (int i = 0; i < prnCount; ++i) {
- if (printers[i].is_default) {
- currPrinterIndex = i;
- break;
- }
- }
-
- if (prnCount > 0)
- setCurrentPrinter(currPrinterIndex);
-
-#ifndef QT_NO_TEXTCODEC
- cups_lang_t *cupsLang = _cupsLangGet(0);
- codec = QTextCodec::codecForName(_cupsLangEncoding(cupsLang));
- if (!codec)
- codec = QTextCodec::codecForLocale();
-#endif
-}
-
-QCUPSSupport::~QCUPSSupport()
-{
- if (currPPD)
- _ppdClose(currPPD);
- if (prnCount)
- _cupsFreeDests(prnCount, printers);
-}
-
-int QCUPSSupport::availablePrintersCount() const
-{
- return prnCount;
-}
-
-const cups_dest_t* QCUPSSupport::availablePrinters() const
-{
- return printers;
-}
-
-const ppd_file_t* QCUPSSupport::currentPPD() const
-{
- return currPPD;
-}
-
-const ppd_file_t* QCUPSSupport::setCurrentPrinter(int index)
-{
- Q_ASSERT(index >= 0 && index <= prnCount);
- if (index == prnCount)
- return 0;
-
- currPrinterIndex = index;
-
- if (currPPD)
- _ppdClose(currPPD);
- currPPD = 0;
- page_sizes = 0;
-
- const char *ppdFile = _cupsGetPPD(printers[index].name);
-
- if (!ppdFile)
- return 0;
-
- currPPD = _ppdOpenFile(ppdFile);
- unlink(ppdFile);
-
- // marking default options
- _ppdMarkDefaults(currPPD);
-
- // marking options explicitly set
- _cupsMarkOptions(currPPD, printers[currPrinterIndex].num_options, printers[currPrinterIndex].options);
-
- // getting pointer to page sizes
- page_sizes = ppdOption("PageSize");
-
- return currPPD;
-}
-
-const ppd_file_t* QCUPSSupport::setCurrentPrinter(const QString &printerName)
-{
- Q_FOREACH (const QCUPSSupport::Printer &printer, QCUPSSupport::availableUnixPrinters()) {
- if (printer.name == printerName) {
- return setCurrentPrinter(printer.cupsPrinterIndex);
- }
- }
-
- return 0;
-}
-
-int QCUPSSupport::currentPrinterIndex() const
-{
- return currPrinterIndex;
-}
-
-bool QCUPSSupport::isAvailable()
-{
- if(!cupsLoaded)
- resolveCups();
-
- return _cupsGetDests &&
- _cupsFreeDests &&
- _cupsGetPPD &&
- _ppdOpenFile &&
- _ppdMarkDefaults &&
- _ppdClose &&
- _cupsMarkOptions &&
- _ppdMarkOption &&
- _cupsFreeOptions &&
- _cupsSetDests &&
- _cupsLangGet &&
- _cupsLangEncoding &&
- _cupsAddOption &&
- (qt_cups_num_printers > 0);
-}
-
-const ppd_option_t* QCUPSSupport::ppdOption(const char *key) const
-{
- if (currPPD) {
- for (int gr = 0; gr < currPPD->num_groups; ++gr) {
- for (int opt = 0; opt < currPPD->groups[gr].num_options; ++opt) {
- if (qstrcmp(currPPD->groups[gr].options[opt].keyword, key) == 0)
- return &currPPD->groups[gr].options[opt];
- }
- }
- }
- return 0;
-}
-
-const cups_option_t* QCUPSSupport::printerOption(const QString &key) const
-{
- for (int i = 0; i < printers[currPrinterIndex].num_options; ++i) {
- if (QLatin1String(printers[currPrinterIndex].options[i].name) == key)
- return &printers[currPrinterIndex].options[i];
- }
- return 0;
-}
-
-const ppd_option_t* QCUPSSupport::pageSizes() const
-{
- return page_sizes;
-}
-
-int QCUPSSupport::markOption(const char* name, const char* value)
-{
- return _ppdMarkOption(currPPD, name, value);
-}
-
-void QCUPSSupport::saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions)
-{
- int oldOptionCount = printers[currPrinterIndex].num_options;
- cups_option_t* oldOptions = printers[currPrinterIndex].options;
-
- int newOptionCount = 0;
- cups_option_t* newOptions = 0;
-
- // copying old options that are not on the new list
- for (int i = 0; i < oldOptionCount; ++i) {
- bool contains = false;
- for (int j = 0; j < options.count(); ++j) {
- if (qstrcmp(options.at(j)->keyword, oldOptions[i].name) == 0) {
- contains = true;
- break;
- }
- }
-
- if (!contains) {
- newOptionCount = _cupsAddOption(oldOptions[i].name, oldOptions[i].value, newOptionCount, &newOptions);
- }
- }
-
- // we can release old option list
- _cupsFreeOptions(oldOptionCount, oldOptions);
-
- // adding marked options
- for (int i = 0; i < markedOptions.count(); ++i) {
- const char* name = markedOptions.at(i);
- ++i;
- newOptionCount = _cupsAddOption(name, markedOptions.at(i), newOptionCount, &newOptions);
- }
-
- // placing the new option list
- printers[currPrinterIndex].num_options = newOptionCount;
- printers[currPrinterIndex].options = newOptions;
-
- // saving new default values
- _cupsSetDests(prnCount, printers);
-}
-
-QRect QCUPSSupport::paperRect(const char *choice) const
-{
- if (!currPPD)
- return QRect();
- for (int i = 0; i < currPPD->num_sizes; ++i) {
- if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
- return QRect(0, 0, qRound(currPPD->sizes[i].width), qRound(currPPD->sizes[i].length));
- }
- return QRect();
-}
-
-QRect QCUPSSupport::pageRect(const char *choice) const
-{
- if (!currPPD)
- return QRect();
- for (int i = 0; i < currPPD->num_sizes; ++i) {
- if (qstrcmp(currPPD->sizes[i].name, choice) == 0)
- return QRect(qRound(currPPD->sizes[i].left),
- qRound(currPPD->sizes[i].length - currPPD->sizes[i].top),
- qRound(currPPD->sizes[i].right - currPPD->sizes[i].left),
- qRound(currPPD->sizes[i].top - currPPD->sizes[i].bottom));
- }
- return QRect();
-}
-
-QStringList QCUPSSupport::options() const
-{
- QStringList list;
- collectMarkedOptions(list);
- return list;
-}
-
QStringList QCUPSSupport::cupsOptionsList(QPrinter *printer)
{
return printer->printEngine()->property(PPK_CupsOptions).toStringList();
@@ -544,175 +234,6 @@ void QCUPSSupport::setPageRange(QPrinter *printer, int pageFrom, int pageTo)
setCupsOptions(printer, cupsOptions);
}
-bool QCUPSSupport::printerHasPPD(const char *printerName)
-{
- if (!isAvailable())
- return false;
- const char *ppdFile = _cupsGetPPD(printerName);
- if (ppdFile)
- unlink(ppdFile);
- return (ppdFile != 0);
-}
-
-QString QCUPSSupport::unicodeString(const char *s)
-{
-#ifndef QT_NO_TEXTCODEC
- return codec->toUnicode(s);
-#else
- return QLatin1String(s);
-#endif
-}
-
-void QCUPSSupport::collectMarkedOptions(QStringList& list, const ppd_group_t* group) const
-{
- if (group == 0) {
- if (!currPPD)
- return;
- for (int i = 0; i < currPPD->num_groups; ++i) {
- collectMarkedOptions(list, &currPPD->groups[i]);
- collectMarkedOptionsHelper(list, &currPPD->groups[i]);
- }
- } else {
- for (int i = 0; i < group->num_subgroups; ++i)
- collectMarkedOptionsHelper(list, &group->subgroups[i]);
- }
-}
-
-void QCUPSSupport::collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const
-{
- for (int i = 0; i < group->num_options; ++i) {
- for (int j = 0; j < group->options[i].num_choices; ++j) {
- if (group->options[i].choices[j].marked == 1 && qstrcmp(group->options[i].choices[j].choice, group->options[i].defchoice) != 0)
- list << QString::fromLocal8Bit(group->options[i].keyword) << QString::fromLocal8Bit(group->options[i].choices[j].choice);
- }
- }
-}
-
-QPair<int, QString> QCUPSSupport::tempFd()
-{
- char filename[512];
- int fd = _cupsTempFd(filename, 512);
- return QPair<int, QString>(fd, QString::fromLocal8Bit(filename));
-}
-
-// Prints the given file and returns a job id.
-int QCUPSSupport::printFile(const char * printerName, const char * filename, const char * title,
- int num_options, cups_option_t * options)
-{
- return _cupsPrintFile(printerName, filename, title, num_options, options);
-}
-
-QCUPSSupport::Printer::Printer(const QString &n) : name(n), isDefault(false), cupsPrinterIndex(-1)
-{
-}
-
-QList<QCUPSSupport::Printer> QCUPSSupport::availableUnixPrinters()
-{
- QList<Printer> printers;
-
- if (QCUPSSupport::isAvailable()) {
- QCUPSSupport cups;
- int cupsPrinterCount = cups.availablePrintersCount();
- const cups_dest_t* cupsPrinters = cups.availablePrinters();
- for (int i = 0; i < cupsPrinterCount; ++i) {
- QString printerName(QString::fromLocal8Bit(cupsPrinters[i].name));
- if (cupsPrinters[i].instance)
- printerName += QLatin1Char('/') + QString::fromLocal8Bit(cupsPrinters[i].instance);
-
- Printer p(printerName);
- if (cupsPrinters[i].is_default)
- p.isDefault = true;
- p.cupsPrinterIndex = i;
- printers.append(p);
- }
- }
-
- return printers;
-}
-
-// preserve names in ascending order for the binary search
-static const struct NamedPaperSize {
- const char *const name;
- QPrinter::PaperSize size;
-} named_sizes_map[QPrinter::NPageSize] = {
- { "A0", QPrinter::A0 },
- { "A1", QPrinter::A1 },
- { "A2", QPrinter::A2 },
- { "A3", QPrinter::A3 },
- { "A4", QPrinter::A4 },
- { "A5", QPrinter::A5 },
- { "A6", QPrinter::A6 },
- { "A7", QPrinter::A7 },
- { "A8", QPrinter::A8 },
- { "A9", QPrinter::A9 },
- { "B0", QPrinter::B0 },
- { "B1", QPrinter::B1 },
- { "B10", QPrinter::B10 },
- { "B2", QPrinter::B2 },
- { "B4", QPrinter::B4 },
- { "B5", QPrinter::B5 },
- { "B6", QPrinter::B6 },
- { "B7", QPrinter::B7 },
- { "B8", QPrinter::B8 },
- { "B9", QPrinter::B9 },
- { "C5E", QPrinter::C5E },
- { "Comm10E", QPrinter::Comm10E },
- { "Custom", QPrinter::Custom },
- { "DLE", QPrinter::DLE },
- { "Executive", QPrinter::Executive },
- { "Folio", QPrinter::Folio },
- { "Ledger", QPrinter::Ledger },
- { "Legal", QPrinter::Legal },
- { "Letter", QPrinter::Letter },
- { "Tabloid", QPrinter::Tabloid }
-};
-
-inline bool operator<(const char *name, const NamedPaperSize &data)
-{ return qstrcmp(name, data.name) < 0; }
-inline bool operator<(const NamedPaperSize &data, const char *name)
-{ return qstrcmp(data.name, name) < 0; }
-
-static inline QPrinter::PaperSize string2PaperSize(const char *name)
-{
- const NamedPaperSize *r = std::lower_bound(named_sizes_map, named_sizes_map + QPrinter::NPageSize, name);
- if ((r != named_sizes_map + QPrinter::NPageSize) && !(name < *r))
- return r->size;
- return QPrinter::Custom;
-}
-
-QList<QPrinter::PaperSize> QCUPSSupport::getCupsPrinterPaperSizes(int cupsPrinterIndex)
-{
- QList<QPrinter::PaperSize> result;
- if (!QCUPSSupport::isAvailable() || cupsPrinterIndex < 0)
- return result;
- // Find paper sizes from CUPS.
- QCUPSSupport cups;
- cups.setCurrentPrinter(cupsPrinterIndex);
- if (const ppd_option_t* size = cups.pageSizes()) {
- for (int j = 0; j < size->num_choices; ++j)
- result.append(string2PaperSize(size->choices[j].choice));
- }
- return result;
-}
-
-QList<QPair<QString, QSizeF> > QCUPSSupport::getCupsPrinterPaperSizesWithNames(int cupsPrinterIndex)
-{
- QList<QPair<QString, QSizeF> > result;
- if (!QCUPSSupport::isAvailable() || cupsPrinterIndex < 0)
- return result;
- // Find paper sizes from CUPS.
- QCUPSSupport cups;
- cups.setCurrentPrinter(cupsPrinterIndex);
- if (const ppd_option_t* size = cups.pageSizes()) {
- for (int j = 0; j < size->num_choices; ++j) {
- double multiplier = qt_multiplierForUnit(QPrinter::Millimeter, 0); // resolution is not needed here
- QSize sz = cups.paperRect(size->choices[j].choice).size();
- result.append(qMakePair(QString::fromUtf8(size->choices[j].text), QSizeF(sz.width() / multiplier, sz.height() / multiplier)));
- }
- }
- return result;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_CUPS
diff --git a/src/printsupport/kernel/qcups_p.h b/src/printsupport/kernel/qcups_p.h
index 95ca323c22..0b327d4228 100644
--- a/src/printsupport/kernel/qcups_p.h
+++ b/src/printsupport/kernel/qcups_p.h
@@ -54,15 +54,10 @@
//
#include "QtCore/qstring.h"
#include "QtCore/qstringlist.h"
-#include "QtCore/qpair.h"
#include "QtPrintSupport/qprinter.h"
#include "QtCore/qdatetime.h"
#ifndef QT_NO_CUPS
-#include <QtCore/qlibrary.h>
-#include <cups/cups.h>
-#include <cups/ppd.h>
-#include "qprintengine.h"
QT_BEGIN_NAMESPACE
@@ -71,26 +66,10 @@ QT_BEGIN_NAMESPACE
// Move back to qcupsprintengine_p.h in the plugin once all usage
// removed from the dialogs.
#define PPK_CupsOptions QPrintEngine::PrintEnginePropertyKey(0xfe00)
-#define PPK_CupsPageRect QPrintEngine::PrintEnginePropertyKey(0xfe01)
-#define PPK_CupsPaperRect QPrintEngine::PrintEnginePropertyKey(0xfe02)
-#define PPK_CupsStringPageSize QPrintEngine::PrintEnginePropertyKey(0xfe03)
-
-Q_DECLARE_TYPEINFO(cups_option_t, Q_MOVABLE_TYPE | Q_PRIMITIVE_TYPE);
class Q_PRINTSUPPORT_EXPORT QCUPSSupport
{
public:
- struct Printer
- {
- Printer(const QString &name = QString());
-
- QString name;
- bool isDefault;
- int cupsPrinterIndex;
- };
- QCUPSSupport();
- ~QCUPSSupport();
-
// Enum for values of job-hold-until option
enum JobHoldUntil {
NoHold = 0, //CUPS Default
@@ -143,28 +122,6 @@ public:
TopToBottomRightToLeft
};
- static bool isAvailable();
- static int cupsVersion() { return isAvailable() ? CUPS_VERSION_MAJOR*10000+CUPS_VERSION_MINOR*100+CUPS_VERSION_PATCH : 0; }
- int availablePrintersCount() const;
- const cups_dest_t* availablePrinters() const;
- int currentPrinterIndex() const;
- const ppd_file_t* setCurrentPrinter(int index);
- const ppd_file_t* setCurrentPrinter(const QString &printerName);
-
- const ppd_file_t* currentPPD() const;
- const ppd_option_t* ppdOption(const char *key) const;
-
- const cups_option_t* printerOption(const QString &key) const;
- const ppd_option_t* pageSizes() const;
-
- int markOption(const char* name, const char* value);
- void saveOptions(QList<const ppd_option_t*> options, QList<const char*> markedOptions);
-
- QRect paperRect(const char *choice) const;
- QRect pageRect(const char *choice) const;
-
- QStringList options() const;
-
static QStringList cupsOptionsList(QPrinter *printer);
static void setCupsOptions(QPrinter *printer, const QStringList &cupsOptions);
static void setCupsOption(QStringList &cupsOptions, const QString &option, const QString &value);
@@ -177,31 +134,6 @@ public:
static void setPagesPerSheetLayout(QPrinter *printer, const PagesPerSheet pagesPerSheet,
const PagesPerSheetLayout pagesPerSheetLayout);
static void setPageRange(QPrinter *printer, int pageFrom, int pageTo);
-
- static bool printerHasPPD(const char *printerName);
-
- QString unicodeString(const char *s);
-
- QPair<int, QString> tempFd();
- int printFile(const char * printerName, const char * filename, const char * title,
- int num_options, cups_option_t * options);
-
- static QList<Printer> availableUnixPrinters();
- static QList<QPrinter::PaperSize> getCupsPrinterPaperSizes(int cupsPrinterIndex);
- static QList<QPair<QString, QSizeF> > getCupsPrinterPaperSizesWithNames(int cupsPrinterIndex);
-
-private:
- void collectMarkedOptions(QStringList& list, const ppd_group_t* group = 0) const;
- void collectMarkedOptionsHelper(QStringList& list, const ppd_group_t* group) const;
-
- int prnCount;
- cups_dest_t *printers;
- const ppd_option_t* page_sizes;
- int currPrinterIndex;
- ppd_file_t *currPPD;
-#ifndef QT_NO_TEXTCODEC
- QTextCodec *codec;
-#endif
};
QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qpaintengine_alpha.cpp b/src/printsupport/kernel/qpaintengine_alpha.cpp
index 298bb8d218..7d4dc18111 100644
--- a/src/printsupport/kernel/qpaintengine_alpha.cpp
+++ b/src/printsupport/kernel/qpaintengine_alpha.cpp
@@ -345,6 +345,7 @@ void QAlphaPaintEngine::flushAndInit(bool init)
d->m_picpainter->setFont(painter()->font());
d->m_picpainter->setOpacity(painter()->opacity());
d->m_picpainter->setTransform(painter()->combinedTransform());
+ *d->m_picpainter->d_func()->state = *painter()->d_func()->state;
d->m_picengine->syncState();
}
}
diff --git a/src/printsupport/kernel/qplatformprintdevice.cpp b/src/printsupport/kernel/qplatformprintdevice.cpp
new file mode 100644
index 0000000000..4932bf1d04
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintdevice.cpp
@@ -0,0 +1,393 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPrintSupport 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformprintdevice.h"
+
+#include "qprintdevice_p.h"
+#include "qprintdialog.h"
+
+#include <QtGui/qpagelayout.h>
+
+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)
+{
+}
+
+QPlatformPrintDevice::QPlatformPrintDevice(const QString &id)
+ : m_id(id),
+ 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)
+{
+}
+
+QPlatformPrintDevice::~QPlatformPrintDevice()
+{
+}
+
+bool QPlatformPrintDevice::operator==(const QPlatformPrintDevice &other) const
+{
+ return m_id == other.m_id;
+}
+
+QString QPlatformPrintDevice::id() const
+{
+ return m_id;
+}
+
+QString QPlatformPrintDevice::name() const
+{
+ return m_name;
+}
+
+QString QPlatformPrintDevice::location() const
+{
+ return m_location;
+}
+
+QString QPlatformPrintDevice::makeAndModel() const
+{
+ return m_makeAndModel;
+}
+
+bool QPlatformPrintDevice::isValid() const
+{
+ return false;
+}
+
+bool QPlatformPrintDevice::isDefault() const
+{
+ return false;
+}
+
+bool QPlatformPrintDevice::isRemote() const
+{
+ return m_isRemote;
+}
+
+bool QPlatformPrintDevice::isValidPageLayout(const QPageLayout &layout, int resolution) const
+{
+ // Check the page size is supported
+ if (!supportedPageSize(layout.pageSize()).isValid())
+ return false;
+
+ // Check the margins are valid
+ QMarginsF pointMargins = layout.margins(QPageLayout::Point);
+ QMarginsF printMargins = printableMargins(layout.pageSize(), layout.orientation(), resolution);
+ return pointMargins.left() >= printMargins.left()
+ && pointMargins.right() >= printMargins.right()
+ && pointMargins.top() >= printMargins.top()
+ && pointMargins.bottom() >= printMargins.bottom();
+}
+
+QPrint::DeviceState QPlatformPrintDevice::state() const
+{
+ return QPrint::Error;
+}
+
+bool QPlatformPrintDevice::supportsMultipleCopies() const
+{
+ return m_supportsMultipleCopies;
+}
+
+bool QPlatformPrintDevice::supportsCollateCopies() const
+{
+ return m_supportsCollateCopies;
+}
+
+void QPlatformPrintDevice::loadPageSizes() const
+{
+}
+
+QPageSize QPlatformPrintDevice::defaultPageSize() const
+{
+ return QPageSize();
+}
+
+QList<QPageSize> QPlatformPrintDevice::supportedPageSizes() const
+{
+ if (!m_havePageSizes)
+ loadPageSizes();
+ return m_pageSizes.toList();
+}
+
+QPageSize QPlatformPrintDevice::supportedPageSize(const QPageSize &pageSize) const
+{
+ if (!pageSize.isValid())
+ return QPageSize();
+
+ if (!m_havePageSizes)
+ loadPageSizes();
+
+ // First try match on name and id for case where printer defines same size twice with different names
+ // e.g. Windows defines DMPAPER_11X17 and DMPAPER_TABLOID with names "11x17" and "Tabloid", but both
+ // map to QPageSize::Tabloid / PPD Key "Tabloid" / ANSI B Tabloid
+ if (pageSize.id() != QPageSize::Custom) {
+ foreach (const QPageSize &ps, m_pageSizes) {
+ if (ps.id() == pageSize.id() && ps.name() == pageSize.name())
+ return ps;
+ }
+ }
+
+ // Next try match on id only if not custom
+ if (pageSize.id() != QPageSize::Custom) {
+ foreach (const QPageSize &ps, m_pageSizes) {
+ if (ps.id() == pageSize.id())
+ return ps;
+ }
+ }
+
+ // Next try a match on size, in case it's a custom with a different name
+ return supportedPageSizeMatch(pageSize);
+}
+
+QPageSize QPlatformPrintDevice::supportedPageSize(QPageSize::PageSizeId pageSizeId) const
+{
+ if (!m_havePageSizes)
+ loadPageSizes();
+
+ foreach (const QPageSize &ps, m_pageSizes) {
+ if (ps.id() == pageSizeId)
+ return ps;
+ }
+
+ // If no supported page size found, try use a custom size instead if supported
+ return supportedPageSizeMatch(QPageSize(pageSizeId));
+}
+
+QPageSize QPlatformPrintDevice::supportedPageSize(const QString &pageName) const
+{
+ if (!m_havePageSizes)
+ loadPageSizes();
+
+ foreach (const QPageSize &ps, m_pageSizes) {
+ if (ps.name() == pageName)
+ return ps;
+ }
+
+ return QPageSize();
+}
+
+QPageSize QPlatformPrintDevice::supportedPageSize(const QSize &sizePoints) const
+{
+ if (!m_havePageSizes)
+ loadPageSizes();
+
+ // Try to find a supported page size based on fuzzy-matched point size
+ return supportedPageSizeMatch(QPageSize(sizePoints));
+}
+
+QPageSize QPlatformPrintDevice::supportedPageSize(const QSizeF &size, QPageSize::Unit units) const
+{
+ if (!m_havePageSizes)
+ loadPageSizes();
+
+ // Try to find a supported page size based on fuzzy-matched unit size
+ return supportedPageSizeMatch(QPageSize(size, units));
+}
+
+QPageSize QPlatformPrintDevice::supportedPageSizeMatch(const QPageSize &pageSize) const
+{
+ // Try to find a supported page size based on point size
+ foreach (const QPageSize &ps, m_pageSizes) {
+ if (ps.sizePoints() == pageSize.sizePoints())
+ return ps;
+ }
+ return QPageSize();
+}
+
+bool QPlatformPrintDevice::supportsCustomPageSizes() const
+{
+ return m_supportsCustomPageSizes;
+}
+
+QSize QPlatformPrintDevice::minimumPhysicalPageSize() const
+{
+ return m_minimumPhysicalPageSize;
+}
+
+QSize QPlatformPrintDevice::maximumPhysicalPageSize() const
+{
+ return m_maximumPhysicalPageSize;
+}
+
+QMarginsF QPlatformPrintDevice::printableMargins(const QPageSize &pageSize,
+ QPageLayout::Orientation orientation,
+ int resolution) const
+{
+ Q_UNUSED(pageSize)
+ Q_UNUSED(orientation)
+ Q_UNUSED(resolution)
+ return QMarginsF(0, 0, 0, 0);
+}
+
+void QPlatformPrintDevice::loadResolutions() const
+{
+}
+
+int QPlatformPrintDevice::defaultResolution() const
+{
+ return 0;
+}
+
+QList<int> QPlatformPrintDevice::supportedResolutions() const
+{
+ if (!m_haveResolutions)
+ loadResolutions();
+ return m_resolutions.toList();
+}
+
+void QPlatformPrintDevice::loadInputSlots() const
+{
+}
+
+QPrint::InputSlot QPlatformPrintDevice::defaultInputSlot() const
+{
+ QPrint::InputSlot input;
+ input.key = QByteArrayLiteral("Auto");
+ input.name = QPrintDialog::tr("Automatic");
+ input.id = QPrint::Auto;
+ return input;
+}
+
+QList<QPrint::InputSlot> QPlatformPrintDevice::supportedInputSlots() const
+{
+ if (!m_haveInputSlots)
+ loadInputSlots();
+ return m_inputSlots.toList();
+}
+
+void QPlatformPrintDevice::loadOutputBins() const
+{
+}
+
+QPrint::OutputBin QPlatformPrintDevice::defaultOutputBin() const
+{
+ QPrint::OutputBin output;
+ output.key = QByteArrayLiteral("Auto");
+ output.name = QPrintDialog::tr("Automatic");
+ output.id = QPrint::AutoOutputBin;
+ return output;
+}
+
+QList<QPrint::OutputBin> QPlatformPrintDevice::supportedOutputBins() const
+{
+ if (!m_haveOutputBins)
+ loadOutputBins();
+ return m_outputBins.toList();
+}
+
+void QPlatformPrintDevice::loadDuplexModes() const
+{
+}
+
+QPrint::DuplexMode QPlatformPrintDevice::defaultDuplexMode() const
+{
+ return QPrint::DuplexNone;
+}
+
+QList<QPrint::DuplexMode> QPlatformPrintDevice::supportedDuplexModes() const
+{
+ if (!m_haveDuplexModes)
+ loadDuplexModes();
+ return m_duplexModes.toList();
+}
+
+void QPlatformPrintDevice::loadColorModes() const
+{
+}
+
+QPrint::ColorMode QPlatformPrintDevice::defaultColorMode() const
+{
+ return QPrint::GrayScale;
+}
+
+QList<QPrint::ColorMode> QPlatformPrintDevice::supportedColorModes() const
+{
+ if (!m_haveColorModes)
+ loadColorModes();
+ return m_colorModes.toList();
+}
+
+void QPlatformPrintDevice::loadMimeTypes() const
+{
+}
+
+QList<QMimeType> QPlatformPrintDevice::supportedMimeTypes() const
+{
+ if (!m_haveMimeTypes)
+ loadMimeTypes();
+ return m_mimeTypes.toList();
+}
+
+QPageSize QPlatformPrintDevice::createPageSize(const QString &key, const QSize &size, const QString &localizedName)
+{
+ return QPageSize(key, size, localizedName);
+}
+
+QPageSize QPlatformPrintDevice::createPageSize(int windowsId, const QSize &size, const QString &localizedName)
+{
+ return QPageSize(windowsId, size, localizedName);
+}
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qplatformprintdevice.h b/src/printsupport/kernel/qplatformprintdevice.h
new file mode 100644
index 0000000000..7674c50c2f
--- /dev/null
+++ b/src/printsupport/kernel/qplatformprintdevice.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPrintSupport 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMPRINTDEVICE_H
+#define QPLATFORMPRINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qprint_p.h>
+
+#include <QtCore/qvector.h>
+#include <QtCore/qmimetype.h>
+#include <QtGui/qpagelayout.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+class Q_PRINTSUPPORT_EXPORT QPlatformPrintDevice : public QSharedData
+{
+public:
+ QPlatformPrintDevice();
+ explicit QPlatformPrintDevice(const QString &id);
+ virtual ~QPlatformPrintDevice();
+
+ QPlatformPrintDevice *clone();
+
+ bool operator==(const QPlatformPrintDevice &other) const;
+
+ virtual QString id() const;
+ virtual QString name() const;
+ virtual QString location() const;
+ virtual QString makeAndModel() const;
+
+ virtual bool isValid() const;
+ virtual bool isDefault() const;
+ virtual bool isRemote() const;
+
+ virtual QPrint::DeviceState state() const;
+
+ virtual bool isValidPageLayout(const QPageLayout &layout, int resolution) const;
+
+ virtual bool supportsMultipleCopies() const;
+ virtual bool supportsCollateCopies() const;
+
+ virtual QPageSize defaultPageSize() const;
+ virtual QList<QPageSize> supportedPageSizes() const;
+
+ virtual QPageSize supportedPageSize(const QPageSize &pageSize) const;
+ virtual QPageSize supportedPageSize(QPageSize::PageSizeId pageSizeId) const;
+ virtual QPageSize supportedPageSize(const QString &pageName) const;
+ virtual QPageSize supportedPageSize(const QSize &pointSize) const;
+ virtual QPageSize supportedPageSize(const QSizeF &size, QPageSize::Unit units) const;
+
+ virtual bool supportsCustomPageSizes() const;
+
+ virtual QSize minimumPhysicalPageSize() const;
+ virtual QSize maximumPhysicalPageSize() const;
+
+ virtual QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation,
+ int resolution) const;
+
+ virtual int defaultResolution() const;
+ virtual QList<int> supportedResolutions() const;
+
+ virtual QPrint::InputSlot defaultInputSlot() const;
+ virtual QList<QPrint::InputSlot> supportedInputSlots() const;
+
+ virtual QPrint::OutputBin defaultOutputBin() const;
+ virtual QList<QPrint::OutputBin> supportedOutputBins() const;
+
+ virtual QPrint::DuplexMode defaultDuplexMode() const;
+ virtual QList<QPrint::DuplexMode> supportedDuplexModes() const;
+
+ virtual QPrint::ColorMode defaultColorMode() const;
+ virtual QList<QPrint::ColorMode> supportedColorModes() const;
+
+ virtual QList<QMimeType> supportedMimeTypes() const;
+
+ static QPageSize createPageSize(const QString &key, const QSize &size, const QString &localizedName);
+ static QPageSize createPageSize(int windowsId, const QSize &size, const QString &localizedName);
+
+protected:
+ virtual void loadPageSizes() const;
+ virtual void loadResolutions() const;
+ virtual void loadInputSlots() const;
+ virtual void loadOutputBins() const;
+ virtual void loadDuplexModes() const;
+ virtual void loadColorModes() const;
+ virtual void loadMimeTypes() const;
+
+ QPageSize supportedPageSizeMatch(const QPageSize &pageSize) const;
+
+ QString m_id;
+ QString m_name;
+ QString m_location;
+ QString m_makeAndModel;
+
+ bool m_isRemote;
+
+ bool m_supportsMultipleCopies;
+ bool m_supportsCollateCopies;
+
+ mutable bool m_havePageSizes;
+ mutable QVector<QPageSize> m_pageSizes;
+
+ bool m_supportsCustomPageSizes;
+
+ QSize m_minimumPhysicalPageSize;
+ QSize m_maximumPhysicalPageSize;
+
+ mutable bool m_haveResolutions;
+ mutable QVector<int> m_resolutions;
+
+ mutable bool m_haveInputSlots;
+ mutable QVector<QPrint::InputSlot> m_inputSlots;
+
+ mutable bool m_haveOutputBins;
+ mutable QVector<QPrint::OutputBin> m_outputBins;
+
+ mutable bool m_haveDuplexModes;
+ mutable QVector<QPrint::DuplexMode> m_duplexModes;
+
+ mutable bool m_haveColorModes;
+ mutable QVector<QPrint::ColorMode> m_colorModes;
+
+ mutable bool m_haveMimeTypes;
+ mutable QVector<QMimeType> m_mimeTypes;
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPLATFORMPRINTDEVICE_H
diff --git a/src/printsupport/kernel/qplatformprintersupport.cpp b/src/printsupport/kernel/qplatformprintersupport.cpp
index 4d80e55ab6..1494155302 100644
--- a/src/printsupport/kernel/qplatformprintersupport.cpp
+++ b/src/printsupport/kernel/qplatformprintersupport.cpp
@@ -40,10 +40,13 @@
****************************************************************************/
#include "qplatformprintersupport.h"
+#include "qplatformprintdevice.h"
+#include <QtGui/qpagesize.h>
#include <QtPrintSupport/qprinterinfo.h>
#include <private/qprinterinfo_p.h>
+#include <private/qprintdevice_p.h>
#ifndef QT_NO_PRINTER
@@ -77,90 +80,38 @@ QPaintEngine *QPlatformPrinterSupport::createPaintEngine(QPrintEngine *, QPrinte
return 0;
}
-QList<QPrinter::PaperSize> QPlatformPrinterSupport::supportedPaperSizes(const QPrinterInfo &) const
+QPrintDevice QPlatformPrinterSupport::createPrintDevice(QPlatformPrintDevice *device)
{
- return QList<QPrinter::PaperSize>();
+ return QPrintDevice(device);
}
-QList<QPair<QString, QSizeF> > QPlatformPrinterSupport::supportedSizesWithNames(const QPrinterInfo &) const
+QPrintDevice QPlatformPrinterSupport::createPrintDevice(const QString &id)
{
- return QList<QPair<QString, QSizeF> >();
+ Q_UNUSED(id)
+ return QPrintDevice();
}
-QList<QPrinterInfo> QPlatformPrinterSupport::availablePrinters()
+QPrintDevice QPlatformPrinterSupport::createDefaultPrintDevice()
{
- return m_printers;
+ return createPrintDevice(defaultPrintDeviceId());
}
-QPrinterInfo QPlatformPrinterSupport::defaultPrinter()
+QStringList QPlatformPrinterSupport::availablePrintDeviceIds() const
{
- const QList<QPrinterInfo> printers = availablePrinters();
- foreach (const QPrinterInfo &printerInfo, printers) {
- if (printerInfo.isDefault())
- return printerInfo;
- }
- return QPrinterInfo();
+ return QStringList();
}
-QPrinterInfo QPlatformPrinterSupport::printerInfo(const QString &printerName)
+QString QPlatformPrinterSupport::defaultPrintDeviceId() const
{
- const QList<QPrinterInfo> printers = availablePrinters();
- foreach (const QPrinterInfo &printerInfo, printers) {
- if (printerInfo.printerName() == printerName)
- return printerInfo;
- }
- return QPrinterInfo();
-}
-
-QString QPlatformPrinterSupport::printerOption(const QPrinterInfo &printer, const QString &key) const
-{
- Q_UNUSED(printer)
- Q_UNUSED(key)
return QString();
}
-PrinterOptions QPlatformPrinterSupport::printerOptions(const QPrinterInfo &printer) const
-{
- Q_UNUSED(printer)
- return PrinterOptions();
-}
-
-int QPlatformPrinterSupport::printerIndex(const QPrinterInfo &printer)
-{
- return printer.d_func()->index;
-}
-
-QPrinterInfo QPlatformPrinterSupport::createPrinterInfo(const QString &name, const QString &description,
- const QString &location, const QString &makeAndModel,
- bool isDefault, int index)
-{
- QPrinterInfo printer(name);
- printer.d_func()->description = description;
- printer.d_func()->location = location;
- printer.d_func()->makeAndModel = makeAndModel;
- printer.d_func()->isDefault = isDefault;
- printer.d_func()->index = index;
- return printer;
-}
-
-/*
- Converts QSizeF in millimeters to a predefined PaperSize (returns Custom if
- the size isn't a standard size)
-*/
-extern QPrinter::PaperSize qSizeFTopaperSize(const QSizeF &);
-QPrinter::PaperSize QPlatformPrinterSupport::convertQSizeFToPaperSize(const QSizeF &sizef)
-{
- return qSizeFTopaperSize(sizef);
-}
-
-/*
- Converts a predefined PaperSize to a QSizeF in millimeters (returns
- QSizeF(0.0, 0.0) if PaperSize is Custom)
-*/
-extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size);
-QSizeF QPlatformPrinterSupport::convertPaperSizeToQSizeF(QPrinter::PaperSize paperSize)
+QPageSize QPlatformPrinterSupport::createPageSize(const QString &id, QSize size, const QString &localizedName)
{
- return qt_paperSizeToQSizeF(paperSize);
+ Q_UNUSED(id)
+ Q_UNUSED(size)
+ Q_UNUSED(localizedName)
+ return QPageSize();
}
QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qplatformprintersupport.h b/src/printsupport/kernel/qplatformprintersupport.h
index c4ffcffd1e..0efec08f64 100644
--- a/src/printsupport/kernel/qplatformprintersupport.h
+++ b/src/printsupport/kernel/qplatformprintersupport.h
@@ -52,6 +52,7 @@
#include <QtPrintSupport/qprinter.h>
+#include <QtCore/qstringlist.h>
#include <QtCore/qlist.h>
#include <QtCore/qhash.h>
@@ -61,6 +62,9 @@ QT_BEGIN_NAMESPACE
typedef QHash<QString, QString> PrinterOptions;
+class QPageSize;
+class QPlatformPrintDevice;
+class QPrintDevice;
class QPrintEngine;
class Q_PRINTSUPPORT_EXPORT QPlatformPrinterSupport
@@ -71,25 +75,15 @@ public:
virtual QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode);
virtual QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode);
- virtual QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
- virtual QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &printerInfo) const;
- virtual QList<QPrinterInfo> availablePrinters();
- virtual QPrinterInfo defaultPrinter();
- virtual QPrinterInfo printerInfo(const QString &printerName);
- virtual QString printerOption(const QPrinterInfo &printer, const QString &key) const;
- virtual PrinterOptions printerOptions(const QPrinterInfo &printer) const;
-
- static QPrinter::PaperSize convertQSizeFToPaperSize(const QSizeF &sizef);
- static QSizeF convertPaperSizeToQSizeF(QPrinter::PaperSize paperSize);
+ virtual QPrintDevice createPrintDevice(const QString &id);
+ virtual QPrintDevice createDefaultPrintDevice();
+ virtual QStringList availablePrintDeviceIds() const;
+ virtual QString defaultPrintDeviceId() const;
protected:
- static int printerIndex(const QPrinterInfo &printer);
- static QPrinterInfo createPrinterInfo(const QString &name, const QString &description,
- const QString &location, const QString &makeAndModel,
- bool isDefault, int index);
-
- QList<QPrinterInfo> m_printers;
+ static QPrintDevice createPrintDevice(QPlatformPrintDevice *device);
+ static QPageSize createPageSize(const QString &id, QSize size, const QString &localizedName);
};
#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprint_p.h b/src/printsupport/kernel/qprint_p.h
new file mode 100644
index 0000000000..30f7c4a65e
--- /dev/null
+++ b/src/printsupport/kernel/qprint_p.h
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPrintSupport 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINT_P_H
+#define QPRINT_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 <QtPrintSupport/qprinter.h>
+
+#include <QtCore/qstring.h>
+#include <QtCore/qlist.h>
+
+#if (defined Q_OS_MAC && !defined Q_OS_IOS) || (defined Q_OS_UNIX && !defined QT_NO_CUPS)
+#include <cups/ppd.h> // Use for type defs only, don't want to actually link in main module
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+// From windgdi.h
+#define DMBIN_UPPER 1
+#define DMBIN_ONLYONE 1
+#define DMBIN_LOWER 2
+#define DMBIN_MIDDLE 3
+#define DMBIN_MANUAL 4
+#define DMBIN_ENVELOPE 5
+#define DMBIN_ENVMANUAL 6
+#define DMBIN_AUTO 7
+#define DMBIN_TRACTOR 8
+#define DMBIN_SMALLFMT 9
+#define DMBIN_LARGEFMT 10
+#define DMBIN_LARGECAPACITY 11
+#define DMBIN_CASSETTE 14
+#define DMBIN_FORMSOURCE 15
+#define DMBIN_USER 256
+
+namespace QPrint {
+
+ // Note: Keep in sync with QPrinter::PrinterState for now
+ // Replace later with more detailed status reporting
+ enum DeviceState {
+ Idle,
+ Active,
+ Aborted,
+ Error
+ };
+
+ // Note: Keep in sync with QPrinter::DuplexMode
+ enum DuplexMode {
+ DuplexNone = 0,
+ DuplexAuto,
+ DuplexLongSide,
+ DuplexShortSide
+ };
+
+ enum ColorMode {
+ GrayScale,
+ Color
+ };
+
+ // Note: Keep in sync with QPrinter::PaperSource for now
+ // If/when made public, rearrange and rename
+ enum InputSlotId {
+ Upper,
+ Lower,
+ Middle,
+ Manual,
+ Envelope,
+ EnvelopeManual,
+ Auto,
+ Tractor,
+ SmallFormat,
+ LargeFormat,
+ LargeCapacity,
+ Cassette,
+ FormSource,
+ MaxPageSource, // Deprecated, kept for compatibility to QPrinter
+ CustomInputSlot,
+ LastInputSlot = CustomInputSlot,
+ OnlyOne = Upper
+ };
+
+ struct InputSlot {
+ QByteArray key;
+ QString name;
+ QPrint::InputSlotId id;
+ int windowsId;
+ };
+
+ enum OutputBinId {
+ AutoOutputBin,
+ UpperBin,
+ LowerBin,
+ RearBin,
+ CustomOutputBin,
+ LastOutputBin = CustomOutputBin
+ };
+
+ struct OutputBin {
+ QByteArray key;
+ QString name;
+ QPrint::OutputBinId id;
+ };
+
+};
+
+struct InputSlotMap {
+ QPrint::InputSlotId id;
+ int windowsId;
+ const char *key;
+};
+
+// Note: PPD standard does not define a standard set of InputSlot keywords,
+// it is a free form text field left to the PPD writer to decide,
+// but it does suggest some names for consistency with the Windows enum.
+static const InputSlotMap inputSlotMap[] = {
+ { QPrint::Upper, DMBIN_UPPER, "Upper" },
+ { QPrint::Lower, DMBIN_LOWER, "Lower" },
+ { QPrint::Middle, DMBIN_MIDDLE, "Middle" },
+ { QPrint::Manual, DMBIN_MANUAL, "Manual" },
+ { QPrint::Envelope, DMBIN_ENVELOPE, "Envelope" },
+ { QPrint::EnvelopeManual, DMBIN_ENVMANUAL, "EnvelopeManual" },
+ { QPrint::Auto, DMBIN_AUTO, "Auto" },
+ { QPrint::Tractor, DMBIN_TRACTOR, "Tractor" },
+ { QPrint::SmallFormat, DMBIN_SMALLFMT, "AnySmallFormat" },
+ { QPrint::LargeFormat, DMBIN_LARGEFMT, "AnyLargeFormat" },
+ { QPrint::LargeCapacity, DMBIN_LARGECAPACITY, "LargeCapacity" },
+ { QPrint::Cassette, DMBIN_CASSETTE, "Cassette" },
+ { QPrint::FormSource, DMBIN_FORMSOURCE, "FormSource" },
+ { QPrint::Manual, DMBIN_MANUAL, "ManualFeed" },
+ { QPrint::OnlyOne, DMBIN_ONLYONE, "OnlyOne" }, // = QPrint::Upper
+ { QPrint::CustomInputSlot, DMBIN_USER, "" } // Must always be last row
+};
+
+struct OutputBinMap {
+ QPrint::OutputBinId id;
+ const char *key;
+};
+
+static const OutputBinMap outputBinMap[] = {
+ { QPrint::AutoOutputBin, "" }, // Not a PPD defined value, internal use only
+ { QPrint::UpperBin, "Upper" },
+ { QPrint::LowerBin, "Lower" },
+ { QPrint::RearBin, "Rear" },
+ { QPrint::CustomOutputBin, "" } // Must always be last row
+};
+
+// Print utilities shared by print plugins
+
+class QPrintUtils
+{
+
+public:
+
+ static QPrint::InputSlotId inputSlotKeyToInputSlotId(const QByteArray &key)
+ {
+ for (int i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) {
+ if (inputSlotMap[i].key == key)
+ return inputSlotMap[i].id;
+ }
+ return QPrint::CustomInputSlot;
+ }
+
+ static QByteArray inputSlotIdToInputSlotKey(QPrint::InputSlotId id)
+ {
+ for (int i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) {
+ if (inputSlotMap[i].id == id)
+ return QByteArray(inputSlotMap[i].key);
+ }
+ return QByteArray();
+ }
+
+ static int inputSlotIdToWindowsId(QPrint::InputSlotId id)
+ {
+ for (int i = 0; inputSlotMap[i].id != QPrint::CustomInputSlot; ++i) {
+ if (inputSlotMap[i].id == id)
+ return inputSlotMap[i].windowsId;
+ }
+ return 0;
+ }
+
+ static QPrint::OutputBinId outputBinKeyToOutputBinId(const QByteArray &key)
+ {
+ for (int i = 0; outputBinMap[i].id != QPrint::CustomOutputBin; ++i) {
+ if (outputBinMap[i].key == key)
+ return outputBinMap[i].id;
+ }
+ return QPrint::CustomOutputBin;
+ }
+
+ static QByteArray outputBinIdToOutputBinKey(QPrint::OutputBinId id)
+ {
+ for (int i = 0; outputBinMap[i].id != QPrint::CustomOutputBin; ++i) {
+ if (outputBinMap[i].id == id)
+ return QByteArray(outputBinMap[i].key);
+ }
+ return QByteArray();
+ }
+
+#if (defined Q_OS_MAC && !defined Q_OS_IOS) || (defined Q_OS_UNIX && !defined QT_NO_CUPS)
+
+ // PPD utilities shared by CUPS and Mac plugins requiring CUPS headers
+ // May turn into a proper internal QPpd class if enough shared between Mac and CUPS,
+ // but where would it live? Not in base module as don't want to link to CUPS.
+ // May have to have two copies in plugins to keep in sync.
+
+ static QPrint::InputSlot ppdChoiceToInputSlot(ppd_choice_t choice)
+ {
+ QPrint::InputSlot input;
+ input.key = choice.choice;
+ input.name = QString::fromUtf8(choice.text);
+ input.id = inputSlotKeyToInputSlotId(input.key);
+ input.windowsId = inputSlotMap[input.id].windowsId;
+ return input;
+ }
+
+ static QPrint::OutputBin ppdChoiceToOutputBin(ppd_choice_t choice)
+ {
+ QPrint::OutputBin output;
+ output.key = choice.choice;
+ output.name = QString::fromUtf8(choice.text);
+ output.id = outputBinKeyToOutputBinId(output.key);
+ return output;
+ }
+
+ static int parsePpdResolution(const QByteArray &value)
+ {
+ if (value.isEmpty())
+ return -1;
+ // value can be in form 600dpi or 600x600dpi
+ QByteArray result = value.split('x').at(0);
+ if (result.endsWith("dpi"))
+ result.chop(3);
+ return result.toInt();
+ }
+
+ static QPrint::DuplexMode ppdChoiceToDuplexMode(const QByteArray &choice)
+ {
+ if (choice == QByteArrayLiteral("DuplexTumble"))
+ return QPrint::DuplexShortSide;
+ else if (choice == QByteArrayLiteral("DuplexNoTumble"))
+ return QPrint::DuplexLongSide;
+ else // None or SimplexTumble or SimplexNoTumble
+ return QPrint::DuplexNone;
+ }
+
+#endif // Mac and CUPS PPD Utilities
+
+};
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
+
+#endif // QPRINT_P_H
diff --git a/src/printsupport/kernel/qprintdevice.cpp b/src/printsupport/kernel/qprintdevice.cpp
new file mode 100644
index 0000000000..eb0af455ee
--- /dev/null
+++ b/src/printsupport/kernel/qprintdevice.cpp
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPrintSupport 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprintdevice_p.h"
+#include "qplatformprintdevice.h"
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+QPrintDevice::QPrintDevice()
+ : d(new QPlatformPrintDevice())
+{
+}
+
+QPrintDevice::QPrintDevice(const QString &id)
+ : d(new QPlatformPrintDevice(id))
+{
+}
+
+QPrintDevice::QPrintDevice(QPlatformPrintDevice *dd)
+ : d(dd)
+{
+}
+
+QPrintDevice::QPrintDevice(const QPrintDevice &other)
+ : d(other.d)
+{
+}
+
+QPrintDevice::~QPrintDevice()
+{
+}
+
+QPrintDevice &QPrintDevice::operator=(const QPrintDevice &other)
+{
+ d = other.d;
+ return *this;
+}
+
+bool QPrintDevice::operator==(const QPrintDevice &other) const
+{
+ if (d && other.d)
+ return *d == *other.d;
+ return d == other.d;
+}
+
+QString QPrintDevice::id() const
+{
+ return isValid() ? d->id() : QString();
+}
+
+QString QPrintDevice::name() const
+{
+ return isValid() ? d->name() : QString();
+}
+
+QString QPrintDevice::location() const
+{
+ return isValid() ? d->location() : QString();
+}
+
+QString QPrintDevice::makeAndModel() const
+{
+ return isValid() ? d->makeAndModel() : QString();
+}
+
+bool QPrintDevice::isValid() const
+{
+ return d && d->isValid();
+}
+
+bool QPrintDevice::isDefault() const
+{
+ return isValid() && d->isDefault();
+}
+
+bool QPrintDevice::isRemote() const
+{
+ return isValid() && d->isRemote();
+}
+
+QPrint::DeviceState QPrintDevice::state() const
+{
+ return isValid() ? d->state() : QPrint::Error;
+}
+
+bool QPrintDevice::isValidPageLayout(const QPageLayout &layout, int resolution) const
+{
+ return isValid() && d->isValidPageLayout(layout, resolution);
+}
+
+bool QPrintDevice::supportsMultipleCopies() const
+{
+ return isValid() && d->supportsMultipleCopies();
+}
+
+bool QPrintDevice::supportsCollateCopies() const
+{
+ return isValid() && d->supportsCollateCopies();
+}
+
+QPageSize QPrintDevice::defaultPageSize() const
+{
+ return isValid() ? d->defaultPageSize() : QPageSize();
+}
+
+QList<QPageSize> QPrintDevice::supportedPageSizes() const
+{
+ return isValid() ? d->supportedPageSizes() : QList<QPageSize>();
+}
+
+QPageSize QPrintDevice::supportedPageSize(const QPageSize &pageSize) const
+{
+ return isValid() ? d->supportedPageSize(pageSize) : QPageSize();
+}
+
+QPageSize QPrintDevice::supportedPageSize(QPageSize::PageSizeId pageSizeId) const
+{
+ return isValid() ? d->supportedPageSize(pageSizeId) : QPageSize();
+}
+
+QPageSize QPrintDevice::supportedPageSize(const QString &pageName) const
+{
+ return isValid() ? d->supportedPageSize(pageName) : QPageSize();
+}
+
+QPageSize QPrintDevice::supportedPageSize(const QSize &pointSize) const
+{
+ return isValid() ? d->supportedPageSize(pointSize) : QPageSize();
+}
+
+QPageSize QPrintDevice::supportedPageSize(const QSizeF &size, QPageSize::Unit units) const
+{
+ return isValid() ? d->supportedPageSize(size, units) : QPageSize();
+}
+
+bool QPrintDevice::supportsCustomPageSizes() const
+{
+ return isValid() && d->supportsCustomPageSizes();
+}
+
+QSize QPrintDevice::minimumPhysicalPageSize() const
+{
+ return isValid() ? d->minimumPhysicalPageSize() : QSize();
+}
+
+QSize QPrintDevice::maximumPhysicalPageSize() const
+{
+ return isValid() ? d->maximumPhysicalPageSize() : QSize();
+}
+
+QMarginsF QPrintDevice::printableMargins(const QPageSize &pageSize,
+ QPageLayout::Orientation orientation,
+ int resolution) const
+{
+ return isValid() ? d->printableMargins(pageSize, orientation, resolution) : QMarginsF();
+}
+
+int QPrintDevice::defaultResolution() const
+{
+ return isValid() ? d->defaultResolution() : 0;
+}
+
+QList<int> QPrintDevice::supportedResolutions() const
+{
+ return isValid() ? d->supportedResolutions() : QList<int>();
+}
+
+QPrint::InputSlot QPrintDevice::defaultInputSlot() const
+{
+ return isValid() ? d->defaultInputSlot() : QPrint::InputSlot();
+}
+
+QList<QPrint::InputSlot> QPrintDevice::supportedInputSlots() const
+{
+ return isValid() ? d->supportedInputSlots() : QList<QPrint::InputSlot>();
+}
+
+QPrint::OutputBin QPrintDevice::defaultOutputBin() const
+{
+ return isValid() ? d->defaultOutputBin() : QPrint::OutputBin();
+}
+
+QList<QPrint::OutputBin> QPrintDevice::supportedOutputBins() const
+{
+ return isValid() ? d->supportedOutputBins() : QList<QPrint::OutputBin>();
+}
+
+QPrint::DuplexMode QPrintDevice::defaultDuplexMode() const
+{
+ return isValid() ? d->defaultDuplexMode() : QPrint::DuplexNone;
+}
+
+QList<QPrint::DuplexMode> QPrintDevice::supportedDuplexModes() const
+{
+ return isValid() ? d->supportedDuplexModes() : QList<QPrint::DuplexMode>();
+}
+
+QPrint::ColorMode QPrintDevice::defaultColorMode() const
+{
+ return isValid() ? d->defaultColorMode() : QPrint::GrayScale;
+}
+
+QList<QPrint::ColorMode> QPrintDevice::supportedColorModes() const
+{
+ return isValid() ? d->supportedColorModes() : QList<QPrint::ColorMode>();
+}
+
+QList<QMimeType> QPrintDevice::supportedMimeTypes() const
+{
+ return isValid() ? d->supportedMimeTypes() : QList<QMimeType>();
+}
+
+#endif // QT_NO_PRINTER
+
+QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qprintdevice_p.h b/src/printsupport/kernel/qprintdevice_p.h
new file mode 100644
index 0000000000..4d63d46aeb
--- /dev/null
+++ b/src/printsupport/kernel/qprintdevice_p.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 John Layt <jlayt@kde.org>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtPrintSupport 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTDEVICE_H
+#define QPRINTDEVICE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "private/qprint_p.h"
+
+#include <QtCore/qsharedpointer.h>
+#include <QtGui/qpagelayout.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_PRINTER
+
+class QPlatformPrintDevice;
+class QMarginsF;
+class QMimeType;
+
+class Q_PRINTSUPPORT_EXPORT QPrintDevice
+{
+public:
+
+ QPrintDevice();
+ QPrintDevice(const QString & id);
+ QPrintDevice(const QPrintDevice &other);
+ ~QPrintDevice();
+
+ QPrintDevice &operator=(const QPrintDevice &other);
+ #ifdef Q_COMPILER_RVALUE_REFS
+ QPrintDevice &operator=(QPrintDevice &&other) { swap(other); return *this; }
+#endif
+
+ void swap(QPrintDevice &other) { d.swap(other.d); }
+
+ bool operator==(const QPrintDevice &other) const;
+
+ QString id() const;
+ QString name() const;
+ QString location() const;
+ QString makeAndModel() const;
+
+ bool isValid() const;
+ bool isDefault() const;
+ bool isRemote() const;
+
+ QPrint::DeviceState state() const;
+
+ bool isValidPageLayout(const QPageLayout &layout, int resolution) const;
+
+ bool supportsMultipleCopies() const;
+ bool supportsCollateCopies() const;
+
+ QPageSize defaultPageSize() const;
+ QList<QPageSize> supportedPageSizes() const;
+
+ QPageSize supportedPageSize(const QPageSize &pageSize) const;
+ QPageSize supportedPageSize(QPageSize::PageSizeId pageSizeId) const;
+ QPageSize supportedPageSize(const QString &pageName) const;
+ QPageSize supportedPageSize(const QSize &pointSize) const;
+ QPageSize supportedPageSize(const QSizeF &size, QPageSize::Unit units = QPageSize::Point) const;
+
+ bool supportsCustomPageSizes() const;
+
+ QSize minimumPhysicalPageSize() const;
+ QSize maximumPhysicalPageSize() const;
+
+ QMarginsF printableMargins(const QPageSize &pageSize, QPageLayout::Orientation orientation, int resolution) const;
+
+ int defaultResolution() const;
+ QList<int> supportedResolutions() const;
+
+ QPrint::InputSlot defaultInputSlot() const;
+ QList<QPrint::InputSlot> supportedInputSlots() const;
+
+ QPrint::OutputBin defaultOutputBin() const;
+ QList<QPrint::OutputBin> supportedOutputBins() const;
+
+ QPrint::DuplexMode defaultDuplexMode() const;
+ QList<QPrint::DuplexMode> supportedDuplexModes() const;
+
+ QPrint::ColorMode defaultColorMode() const;
+ QList<QPrint::ColorMode> supportedColorModes() const;
+
+ QList<QMimeType> supportedMimeTypes() const;
+
+private:
+ friend class QPlatformPrinterSupport;
+ friend class QPlatformPrintDevice;
+ QPrintDevice(QPlatformPrintDevice *dd);
+ QSharedDataPointer<QPlatformPrintDevice> d;
+};
+
+Q_DECLARE_SHARED(QPrintDevice)
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPLATFORMPRINTDEVICE_H
diff --git a/src/printsupport/kernel/qprintengine.h b/src/printsupport/kernel/qprintengine.h
index 3993a22bef..a69fe01fd4 100644
--- a/src/printsupport/kernel/qprintengine.h
+++ b/src/printsupport/kernel/qprintengine.h
@@ -45,6 +45,8 @@
#include <QtCore/qvariant.h>
#include <QtPrintSupport/qprinter.h>
+Q_DECLARE_METATYPE(QMarginsF)
+
QT_BEGIN_NAMESPACE
@@ -85,6 +87,9 @@ public:
PPK_CopyCount,
PPK_SupportsMultipleCopies,
PPK_PaperName,
+ PPK_QPageSize,
+ PPK_QPageMargins,
+ PPK_QPageLayout,
PPK_PaperSize = PPK_PageSize,
PPK_CustomBase = 0xff00
diff --git a/src/printsupport/kernel/qprintengine_pdf.cpp b/src/printsupport/kernel/qprintengine_pdf.cpp
index 6c65300462..a2ab68a96d 100644
--- a/src/printsupport/kernel/qprintengine_pdf.cpp
+++ b/src/printsupport/kernel/qprintengine_pdf.cpp
@@ -48,6 +48,7 @@
#include <qdebug.h>
#include <qbuffer.h>
#include "qprinterinfo.h"
+#include <QtGui/qpagelayout.h>
#include <limits.h>
#include <math.h>
@@ -63,34 +64,6 @@
QT_BEGIN_NAMESPACE
-//#define FONT_DUMP
-
-extern QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size);
-
-#define Q_MM(n) int((n * 720 + 127) / 254)
-#define Q_IN(n) int(n * 72)
-
-static const char * const psToStr[QPrinter::NPageSize+1] =
-{
- "A4", "B5", "Letter", "Legal", "Executive",
- "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1",
- "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E",
- "DLE", "Folio", "Ledger", "Tabloid", 0
-};
-
-QPdf::PaperSize QPdf::paperSize(QPrinter::PaperSize paperSize)
-{
- QSizeF s = qt_paperSizeToQSizeF(paperSize);
- PaperSize p = { Q_MM(s.width()), Q_MM(s.height()) };
- return p;
-}
-
-const char *QPdf::paperSizeToString(QPrinter::PaperSize paperSize)
-{
- return psToStr[paperSize];
-}
-
-
QPdfPrintEngine::QPdfPrintEngine(QPrinter::PrinterMode m)
: QPdfEngine(*new QPdfPrintEnginePrivate(m))
{
@@ -163,10 +136,6 @@ 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_PaperName:
- break;
- case PPK_WindowsPageSize:
- break;
// The following keys are properties and settings that are supported by the PDF PrintEngine
case PPK_CollateCopies:
@@ -182,14 +151,17 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->title = value.toString();
break;
case PPK_FullPage:
- d->fullPage = value.toBool();
+ if (value.toBool())
+ d->m_pageLayout.setMode(QPageLayout::FullPageMode);
+ else
+ d->m_pageLayout.setMode(QPageLayout::StandardMode);
break;
case PPK_CopyCount: // fallthrough
case PPK_NumberOfCopies:
d->copies = value.toInt();
break;
case PPK_Orientation:
- d->landscape = (QPrinter::Orientation(value.toInt()) == QPrinter::Landscape);
+ d->m_pageLayout.setOrientation(QPageLayout::Orientation(value.toInt()));
break;
case PPK_OutputFileName:
d->outputFileName = value.toString();
@@ -197,9 +169,25 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
case PPK_PageOrder:
d->pageOrder = QPrinter::PageOrder(value.toInt());
break;
- case PPK_PaperSize:
- d->printerPaperSize = QPrinter::PaperSize(value.toInt());
- d->updatePaperSize();
+ case PPK_PageSize: {
+ QPageSize pageSize = QPageSize(QPageSize::PageSizeId(value.toInt()));
+ if (pageSize.isValid())
+ d->m_pageLayout.setPageSize(pageSize);
+ break;
+ }
+ case PPK_PaperName: {
+ QString name = value.toString();
+ for (int i = 0; i <= QPageSize::LastPageSize; ++i) {
+ QPageSize pageSize = QPageSize(QPageSize::PageSizeId(i));
+ if (name == pageSize.name()) {
+ d->m_pageLayout.setPageSize(pageSize);
+ break;
+ }
+ }
+ break;
+ }
+ case PPK_WindowsPageSize:
+ d->m_pageLayout.setPageSize(QPageSize(QPageSize::id(value.toInt())));
break;
case PPK_PaperSource:
d->paperSource = QPrinter::PaperSource(value.toInt());
@@ -220,22 +208,35 @@ void QPdfPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &va
d->embedFonts = value.toBool();
break;
case PPK_Duplex:
- d->duplex = static_cast<QPrinter::DuplexMode> (value.toInt());
+ d->duplex = static_cast<QPrint::DuplexMode>(value.toInt());
break;
case PPK_CustomPaperSize:
- d->printerPaperSize = QPrinter::Custom;
- d->customPaperSize = value.toSizeF();
- d->updatePaperSize();
+ d->m_pageLayout.setPageSize(QPageSize(value.toSizeF(), QPageSize::Point));
break;
- case PPK_PageMargins:
- {
+ case PPK_PageMargins: {
QList<QVariant> margins(value.toList());
Q_ASSERT(margins.size() == 4);
- d->leftMargin = margins.at(0).toReal();
- d->topMargin = margins.at(1).toReal();
- d->rightMargin = margins.at(2).toReal();
- d->bottomMargin = margins.at(3).toReal();
- d->pageMarginsSet = true;
+ d->m_pageLayout.setUnits(QPageLayout::Point);
+ d->m_pageLayout.setMargins(QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(),
+ margins.at(2).toReal(), margins.at(3).toReal()));
+ break;
+ }
+ case PPK_QPageSize: {
+ QPageSize pageSize = value.value<QPageSize>();
+ if (pageSize.isValid())
+ d->m_pageLayout.setPageSize(pageSize);
+ break;
+ }
+ case PPK_QPageMargins: {
+ QPair<QMarginsF, QPageLayout::Unit> pair = value.value<QPair<QMarginsF, QPageLayout::Unit> >();
+ d->m_pageLayout.setUnits(pair.second);
+ d->m_pageLayout.setMargins(pair.first);
+ break;
+ }
+ case PPK_QPageLayout: {
+ QPageLayout pageLayout = value.value<QPageLayout>();
+ if (pageLayout.isValid())
+ d->m_pageLayout = pageLayout;
break;
}
// No default so that compiler will complain if new keys added and not handled in this engine
@@ -254,12 +255,6 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_CustomBase:
// Special case, leave null
break;
- case PPK_PaperName:
- ret = QString();
- break;
- case PPK_WindowsPageSize:
- // Special case, leave null
- break;
// The following keys are properties and settings that are supported by the PDF PrintEngine
case PPK_CollateCopies:
@@ -275,7 +270,7 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
ret = d->title;
break;
case PPK_FullPage:
- ret = d->fullPage;
+ ret = d->m_pageLayout.mode() == QPageLayout::FullPageMode;
break;
case PPK_CopyCount:
ret = d->copies;
@@ -287,7 +282,7 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
ret = d->copies;
break;
case PPK_Orientation:
- ret = d->landscape ? QPrinter::Landscape : QPrinter::Portrait;
+ ret = d->m_pageLayout.orientation();
break;
case PPK_OutputFileName:
ret = d->outputFileName;
@@ -295,8 +290,14 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
case PPK_PageOrder:
ret = d->pageOrder;
break;
- case PPK_PaperSize:
- ret = d->printerPaperSize;
+ case PPK_PageSize:
+ ret = d->m_pageLayout.pageSize().id();
+ break;
+ case PPK_PaperName:
+ ret = d->m_pageLayout.pageSize().name();
+ break;
+ case PPK_WindowsPageSize:
+ ret = d->m_pageLayout.pageSize().windowsId();
break;
case PPK_PaperSource:
ret = d->paperSource;
@@ -314,10 +315,10 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
ret = QList<QVariant>() << 72;
break;
case PPK_PaperRect:
- ret = d->paperRect();
+ ret = d->m_pageLayout.fullRectPixels(d->resolution);
break;
case PPK_PageRect:
- ret = d->pageRect();
+ ret = d->m_pageLayout.paintRectPixels(d->resolution);
break;
case PPK_SelectionOption:
ret = d->selectionOption;
@@ -329,19 +330,26 @@ QVariant QPdfPrintEngine::property(PrintEnginePropertyKey key) const
ret = d->duplex;
break;
case PPK_CustomPaperSize:
- ret = d->customPaperSize;
+ ret = d->m_pageLayout.fullRectPoints().size();
break;
- case PPK_PageMargins:
- {
- QList<QVariant> margins;
- if (d->printerPaperSize == QPrinter::Custom && !d->pageMarginsSet)
- margins << 0 << 0 << 0 << 0;
- else
- margins << d->leftMargin << d->topMargin
- << d->rightMargin << d->bottomMargin;
- ret = margins;
+ case PPK_PageMargins: {
+ QList<QVariant> list;
+ QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Point);
+ list << margins.left() << margins.top() << margins.right() << margins.bottom();
+ ret = list;
+ break;
+ }
+ case PPK_QPageSize:
+ ret.setValue(d->m_pageLayout.pageSize());
+ break;
+ case PPK_QPageMargins: {
+ QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(d->m_pageLayout.margins(), d->m_pageLayout.units());
+ ret.setValue(pair);
break;
}
+ case PPK_QPageLayout:
+ ret.setValue(d->m_pageLayout);
+ break;
// No default so that compiler will complain if new keys added and not handled in this engine
}
return ret;
@@ -385,13 +393,11 @@ void QPdfPrintEnginePrivate::closePrintDevice()
QPdfPrintEnginePrivate::QPdfPrintEnginePrivate(QPrinter::PrinterMode m)
: QPdfEnginePrivate(),
- duplex(QPrinter::DuplexNone),
+ duplex(QPrint::DuplexNone),
collate(true),
copies(1),
pageOrder(QPrinter::FirstPageFirst),
paperSource(QPrinter::Auto),
- printerPaperSize(QPrinter::A4),
- pageMarginsSet(false),
fd(-1)
{
resolution = 72;
@@ -405,18 +411,6 @@ QPdfPrintEnginePrivate::~QPdfPrintEnginePrivate()
{
}
-
-void QPdfPrintEnginePrivate::updatePaperSize()
-{
- if (printerPaperSize == QPrinter::Custom) {
- paperSize = customPaperSize;
- } else {
- QPdf::PaperSize s = QPdf::paperSize(printerPaperSize);
- paperSize = QSize(s.width, s.height);
- }
-}
-
-
QT_END_NAMESPACE
#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprintengine_pdf_p.h b/src/printsupport/kernel/qprintengine_pdf_p.h
index eec6d48181..80d81b4ed3 100644
--- a/src/printsupport/kernel/qprintengine_pdf_p.h
+++ b/src/printsupport/kernel/qprintengine_pdf_p.h
@@ -68,6 +68,7 @@
#include "private/qpdf_p.h"
#include "private/qpaintengine_p.h"
#include "qprintengine.h"
+#include "qprint_p.h"
QT_BEGIN_NAMESPACE
@@ -77,16 +78,6 @@ class QPen;
class QPointF;
class QRegion;
class QFile;
-class QPdfPrintEngine;
-
-namespace QPdf {
-
- struct PaperSize {
- int width, height; // in postscript points
- };
- Q_PRINTSUPPORT_EXPORT PaperSize paperSize(QPrinter::PaperSize paperSize);
- Q_PRINTSUPPORT_EXPORT const char *paperSizeToString(QPrinter::PaperSize paperSize);
-}
class QPdfPrintEnginePrivate;
@@ -131,8 +122,6 @@ public:
virtual bool openPrintDevice();
virtual void closePrintDevice();
- virtual void updatePaperSize();
-
private:
Q_DISABLE_COPY(QPdfPrintEnginePrivate)
@@ -143,15 +132,12 @@ private:
QString printProgram;
QString selectionOption;
- QPrinter::DuplexMode duplex;
+ QPrint::DuplexMode duplex;
bool collate;
int copies;
QPrinter::PageOrder pageOrder;
QPrinter::PaperSource paperSource;
- QPrinter::PaperSize printerPaperSize;
- QSizeF customPaperSize; // in postscript points
- bool pageMarginsSet;
int fd;
};
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index 02b5d824f4..52b67d162b 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -50,6 +50,9 @@
#include <private/qfontengine_p.h>
#include <private/qpainter_p.h>
+#include <qpa/qplatformprintplugin.h>
+#include <qpa/qplatformprintersupport.h>
+
#include <qbitmap.h>
#include <qdebug.h>
#include <qvector.h>
@@ -59,6 +62,7 @@
#include <private/qpixmap_raster_p.h>
#include <QtCore/QMetaType>
#include <QtCore/qt_windows.h>
+#include <QtGui/qpagelayout.h>
Q_DECLARE_METATYPE(HFONT)
Q_DECLARE_METATYPE(LOGFONT)
@@ -67,164 +71,14 @@ QT_BEGIN_NAMESPACE
Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0);
extern QPainterPath qt_regionToPath(const QRegion &region);
-Q_PRINTSUPPORT_EXPORT QSizeF qt_SizeFromUnitToMillimeter(const QSizeF &, QPrinter::Unit, double);
-Q_PRINTSUPPORT_EXPORT double qt_multiplierForUnit(QPrinter::Unit unit, int resolution);
+extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits);
// #define QT_DEBUG_DRAW
+// #define QT_DEBUG_METRICS
static void draw_text_item_win(const QPointF &_pos, const QTextItemInt &ti, HDC hdc,
bool convertToText, const QTransform &xform, const QPointF &topLeft);
-static const struct {
- int winSizeName;
- QPrinter::PaperSize qtSizeName;
-} dmMapping[] = {
- { DMPAPER_LETTER, QPrinter::Letter },
- { DMPAPER_LETTERSMALL, QPrinter::Letter },
- { DMPAPER_TABLOID, QPrinter::Tabloid },
- { DMPAPER_LEDGER, QPrinter::Ledger },
- { DMPAPER_LEGAL, QPrinter::Legal },
- { DMPAPER_EXECUTIVE, QPrinter::Executive },
- { DMPAPER_A3, QPrinter::A3 },
- { DMPAPER_A4, QPrinter::A4 },
- { DMPAPER_A4SMALL, QPrinter::A4 },
- { DMPAPER_A5, QPrinter::A5 },
- { DMPAPER_B4, QPrinter::B4 },
- { DMPAPER_B5, QPrinter::B5 },
- { DMPAPER_A4_PLUS, QPrinter::Folio },
- { DMPAPER_ENV_10, QPrinter::Comm10E },
- { DMPAPER_ENV_DL, QPrinter::DLE },
- { DMPAPER_ENV_C3, QPrinter::C5E },
- { DMPAPER_LETTER_EXTRA, QPrinter::Letter },
- { DMPAPER_LEGAL_EXTRA, QPrinter::Legal },
- { DMPAPER_TABLOID_EXTRA, QPrinter::Tabloid },
- { DMPAPER_A4_EXTRA, QPrinter::A4},
- { DMPAPER_LETTER_TRANSVERSE, QPrinter::Letter},
- { DMPAPER_A4_TRANSVERSE, QPrinter::A4},
- { DMPAPER_LETTER_EXTRA_TRANSVERSE, QPrinter::Letter },
- { DMPAPER_A_PLUS, QPrinter::A4 },
- { DMPAPER_B_PLUS, QPrinter::A3 },
- { DMPAPER_LETTER_PLUS, QPrinter::Letter },
- { DMPAPER_A5_TRANSVERSE, QPrinter::A5 },
- { DMPAPER_B5_TRANSVERSE, QPrinter::B5 },
- { DMPAPER_A3_EXTRA, QPrinter::A3 },
- { DMPAPER_A5_EXTRA, QPrinter::A5 },
- { DMPAPER_B5_EXTRA, QPrinter::B5 },
- { DMPAPER_A2, QPrinter::A2 },
- { DMPAPER_A3_TRANSVERSE, QPrinter::A3 },
- { DMPAPER_A3_EXTRA_TRANSVERSE,QPrinter::A3 },
- { 0, QPrinter::Custom }
-};
-
-// Return a list of printer paper sizes in millimeters with the corresponding dmPaperSize value
-static QList<QPair<QSizeF, int> > printerPaperSizes(const QString &printerName)
-{
- QList<QPair<QSizeF, int> > result;
- const wchar_t *name = reinterpret_cast<const wchar_t*>(printerName.utf16());
- DWORD paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL);
- if ((int)paperNameCount > 0) {
- // If they are not equal, then there seems to be a problem with the driver
- if (paperNameCount != DeviceCapabilities(name, NULL, DC_PAPERSIZE, NULL, NULL))
- return result;
- QScopedArrayPointer<wchar_t> papersNames(new wchar_t[paperNameCount]);
- paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERS, papersNames.data(), NULL);
- result.reserve(paperNameCount);
- QScopedArrayPointer<POINT> paperSizes(new POINT[paperNameCount]);
- paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERSIZE, (wchar_t *)paperSizes.data(), NULL);
- for (int i=0; i <(int)paperNameCount; i++)
- result.push_back(qMakePair(QSizeF(paperSizes[i].x / 10, paperSizes[i].y / 10), papersNames[i]));
- }
- return result;
-}
-
-// Find the best-matching printer paper for size in millimeters.
-static inline int findCustomPaperSize(const QSizeF &needlePt, const QString &printerName)
-{
- const QList<QPair<QSizeF, int> > sizes = printerPaperSizes(printerName);
- const qreal nw = needlePt.width();
- const qreal nh = needlePt.height();
- for (int i = 0; i < sizes.size(); ++i) {
- if (qAbs(nw - sizes.at(i).first.width()) <= 1 && qAbs(nh - sizes.at(i).first.height()) <= 1)
- return sizes.at(i).second;
- }
- return -1;
-}
-
-static inline void setDevModePaperFlags(DEVMODE *devMode, bool custom)
-{
- if (custom) {
- devMode->dmPaperSize = DMPAPER_USER;
- devMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
- } else {
- devMode->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH);
- devMode->dmPaperLength = 0;
- devMode->dmPaperWidth = 0;
- }
-}
-
-QPrinter::PaperSize mapDevmodePaperSize(int s)
-{
- int i = 0;
- while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].winSizeName != s))
- i++;
- return dmMapping[i].qtSizeName;
-}
-
-static int mapPaperSizeDevmode(QPrinter::PaperSize s)
-{
- int i = 0;
- while ((dmMapping[i].winSizeName > 0) && (dmMapping[i].qtSizeName != s))
- i++;
- return dmMapping[i].winSizeName;
-}
-
-static const struct {
- int winSourceName;
- QPrinter::PaperSource qtSourceName;
-} sources[] = {
- { DMBIN_UPPER, QPrinter::Upper }, // = DBMIN_ONLYONE
- { DMBIN_LOWER, QPrinter::Lower },
- { DMBIN_MIDDLE, QPrinter::Middle },
- { DMBIN_MANUAL, QPrinter::Manual },
- { DMBIN_ENVELOPE, QPrinter::Envelope },
- { DMBIN_ENVMANUAL, QPrinter::EnvelopeManual },
- { DMBIN_AUTO, QPrinter::Auto },
- { DMBIN_TRACTOR, QPrinter::Tractor },
- { DMBIN_SMALLFMT, QPrinter::SmallFormat },
- { DMBIN_LARGEFMT, QPrinter::LargeFormat },
- { DMBIN_LARGECAPACITY, QPrinter::LargeCapacity },
- { DMBIN_CASSETTE, QPrinter::Cassette },
- { DMBIN_FORMSOURCE, QPrinter::FormSource },
- { DMBIN_USER, QPrinter::CustomSource },
- { 0, (QPrinter::PaperSource) -1 }
-};
-
-static QPrinter::PaperSource mapDevmodePaperSource(int s)
-{
- int i = 0;
- while ((sources[i].winSourceName > 0) && (sources[i].winSourceName != s))
- i++;
- return sources[i].winSourceName ? sources[i].qtSourceName : (QPrinter::PaperSource) s;
-}
-
-static int mapPaperSourceDevmode(QPrinter::PaperSource s)
-{
- int i = 0;
- while ((sources[i].qtSourceName >= 0) && (sources[i].qtSourceName != s))
- i++;
- return sources[i].winSourceName ? sources[i].winSourceName : s;
-}
-
-static inline uint qwcsnlen(const wchar_t *str, uint maxlen)
-{
- uint length = 0;
- if (str) {
- while (length < maxlen && *str++)
- length++;
- }
- return length;
-}
-
QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode mode)
: QAlphaPaintEngine(*(new QWin32PrintEnginePrivate),
PaintEngineFeatures(PrimitiveTransform
@@ -236,7 +90,10 @@ QWin32PrintEngine::QWin32PrintEngine(QPrinter::PrinterMode mode)
{
Q_D(QWin32PrintEngine);
d->mode = mode;
- d->queryDefault();
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps)
+ d->m_printDevice = ps->createDefaultPrintDevice();
+ d->m_pageLayout.setPageSize(d->m_printDevice.defaultPageSize());
d->initialize();
}
@@ -301,6 +158,11 @@ bool QWin32PrintEngine::begin(QPaintDevice *pdev)
if (!ok)
cleanUp();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::begin()";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
+
return ok;
}
@@ -363,6 +225,11 @@ bool QWin32PrintEngine::newPage()
if (transparent)
SetBkMode(d->hdc, TRANSPARENT);
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::newPage()";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
+
// ###
return true;
@@ -456,21 +323,11 @@ void QWin32PrintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem
SelectObject(d->hdc, CreatePen(PS_SOLID, 1, cf));
SetTextColor(d->hdc, cf);
- draw_text_item_win(p, ti, d->hdc, convertToText, d->matrix, d->devPaperRect.topLeft());
+ draw_text_item_win(p, ti, d->hdc, convertToText, d->matrix, QPointF(0.0, 0.0));
DeleteObject(SelectObject(d->hdc,GetStockObject(HOLLOW_BRUSH)));
DeleteObject(SelectObject(d->hdc,GetStockObject(BLACK_PEN)));
}
-static inline qreal mmToInches(double mm)
-{
- return mm*0.039370147;
-}
-
-static inline qreal inchesToMM(double in)
-{
- return in/0.039370147;
-}
-
int QWin32PrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
{
Q_D(const QWin32PrintEngine);
@@ -483,40 +340,18 @@ int QWin32PrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
switch (m) {
case QPaintDevice::PdmWidth:
- if (d->has_custom_paper_size) {
- val = qRound(d->paper_size.width() * res / 72.0);
- } else {
- int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX);
- if (logPixelsX == 0) {
- qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
- "might be a driver problem");
- logPixelsX = 600; // Reasonable default
- }
- val = res
- * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALWIDTH : HORZRES)
- / logPixelsX;
- }
- if (d->pageMarginsSet)
- val -= int(mmToInches((d->previousDialogMargins.left() +
- d->previousDialogMargins.width()) / 100.0) * res);
+ val = d->m_paintRectPixels.width();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::metric(PdmWidth) = " << val;
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
break;
case QPaintDevice::PdmHeight:
- if (d->has_custom_paper_size) {
- val = qRound(d->paper_size.height() * res / 72.0);
- } else {
- int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY);
- if (logPixelsY == 0) {
- qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
- "might be a driver problem");
- logPixelsY = 600; // Reasonable default
- }
- val = res
- * GetDeviceCaps(d->hdc, d->fullPage ? PHYSICALHEIGHT : VERTRES)
- / logPixelsY;
- }
- if (d->pageMarginsSet)
- val -= int(mmToInches((d->previousDialogMargins.top() +
- d->previousDialogMargins.height()) / 100.0) * res);
+ val = d->m_paintRectPixels.height();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::metric(PdmHeight) = " << val;
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
break;
case QPaintDevice::PdmDpiX:
val = res;
@@ -531,46 +366,18 @@ int QWin32PrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
val = GetDeviceCaps(d->hdc, LOGPIXELSY);
break;
case QPaintDevice::PdmWidthMM:
- if (d->has_custom_paper_size) {
- val = qRound(d->paper_size.width()*25.4/72);
- } else {
- if (!d->fullPage) {
- val = GetDeviceCaps(d->hdc, HORZSIZE);
- } else {
- float wi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALWIDTH);
- int logPixelsX = GetDeviceCaps(d->hdc, LOGPIXELSX);
- if (logPixelsX == 0) {
- qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
- "might be a driver problem");
- logPixelsX = 600; // Reasonable default
- }
- val = qRound(wi / logPixelsX);
- }
- }
- if (d->pageMarginsSet)
- val -= (d->previousDialogMargins.left() +
- d->previousDialogMargins.width()) / 100.0;
+ val = d->m_paintSizeMM.width();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::metric(PdmWidthMM) = " << val;
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
break;
case QPaintDevice::PdmHeightMM:
- if (d->has_custom_paper_size) {
- val = qRound(d->paper_size.height()*25.4/72);
- } else {
- if (!d->fullPage) {
- val = GetDeviceCaps(d->hdc, VERTSIZE);
- } else {
- float hi = 25.4 * GetDeviceCaps(d->hdc, PHYSICALHEIGHT);
- int logPixelsY = GetDeviceCaps(d->hdc, LOGPIXELSY);
- if (logPixelsY == 0) {
- qWarning("QWin32PrintEngine::metric: GetDeviceCaps() failed, "
- "might be a driver problem");
- logPixelsY = 600; // Reasonable default
- }
- val = qRound(hi / logPixelsY);
- }
- }
- if (d->pageMarginsSet)
- val -= (d->previousDialogMargins.top() +
- d->previousDialogMargins.height()) / 100.0;
+ val = d->m_paintSizeMM.height();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::metric(PdmHeightMM) = " << val;
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
break;
case QPaintDevice::PdmNumColors:
{
@@ -1035,11 +842,6 @@ void QWin32PrintEngine::drawPolygon(const QPointF *points, int pointCount, Polyg
d->has_brush = has_brush;
}
-void QWin32PrintEnginePrivate::queryDefault()
-{
- QWin32PrintEngine::queryDefaultPrinter(name);
-}
-
QWin32PrintEnginePrivate::~QWin32PrintEnginePrivate()
{
if (hdc)
@@ -1055,12 +857,12 @@ void QWin32PrintEnginePrivate::initialize()
Q_ASSERT(!devMode);
Q_ASSERT(!pInfo);
- if (name.isEmpty())
+ if (!m_printDevice.isValid())
return;
txop = QTransform::TxNone;
- bool ok = OpenPrinter((LPWSTR)name.utf16(), (LPHANDLE)&hPrinter, 0);
+ bool ok = OpenPrinter((LPWSTR)m_printDevice.id().utf16(), (LPHANDLE)&hPrinter, 0);
if (!ok) {
qErrnoWarning("QWin32PrintEngine::initialize: OpenPrinter failed");
return;
@@ -1086,7 +888,7 @@ void QWin32PrintEnginePrivate::initialize()
}
devMode = pInfo->pDevMode;
- hdc = CreateDC(NULL, reinterpret_cast<const wchar_t *>(name.utf16()), 0, devMode);
+ hdc = CreateDC(NULL, reinterpret_cast<const wchar_t *>(m_printDevice.id().utf16()), 0, devMode);
Q_ASSERT(hPrinter);
Q_ASSERT(pInfo);
@@ -1094,19 +896,15 @@ void QWin32PrintEnginePrivate::initialize()
if (devMode) {
num_copies = devMode->dmCopies;
devMode->dmCollate = DMCOLLATE_TRUE;
+ updatePageLayout();
}
initHDC();
-#ifdef QT_DEBUG_DRAW
- qDebug() << "QWin32PrintEngine::initialize()" << endl
- << " - paperRect" << devPaperRect << endl
- << " - pageRect" << devPageRect << endl
- << " - stretch_x" << stretch_x << endl
- << " - stretch_y" << stretch_y << endl
- << " - origin_x" << origin_x << endl
- << " - origin_y" << origin_y << endl;
-#endif
+#if defined QT_DEBUG_DRAW || defined QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::initialize()";
+ debugMetrics();
+#endif // QT_DEBUG_DRAW || QT_DEBUG_METRICS
}
void QWin32PrintEnginePrivate::initHDC()
@@ -1139,50 +937,6 @@ void QWin32PrintEnginePrivate::initHDC()
default:
break;
}
-
- initDevRects();
-}
-
-void QWin32PrintEnginePrivate::initDevRects()
-{
- devPaperRect = QRect(0, 0,
- GetDeviceCaps(hdc, PHYSICALWIDTH),
- GetDeviceCaps(hdc, PHYSICALHEIGHT));
- devPhysicalPageRect = QRect(GetDeviceCaps(hdc, PHYSICALOFFSETX),
- GetDeviceCaps(hdc, PHYSICALOFFSETY),
- GetDeviceCaps(hdc, HORZRES),
- GetDeviceCaps(hdc, VERTRES));
- if (!pageMarginsSet)
- devPageRect = devPhysicalPageRect;
- else
- devPageRect = devPaperRect.adjusted(qRound(mmToInches(previousDialogMargins.left() / 100.0) * dpi_x),
- qRound(mmToInches(previousDialogMargins.top() / 100.0) * dpi_y),
- -qRound(mmToInches(previousDialogMargins.width() / 100.0) * dpi_x),
- -qRound(mmToInches(previousDialogMargins.height() / 100.0) * dpi_y));
- updateOrigin();
-}
-
-void QWin32PrintEnginePrivate::setPageMargins(int marginLeft, int marginTop, int marginRight, int marginBottom)
-{
- pageMarginsSet = true;
- previousDialogMargins = QRect(marginLeft, marginTop, marginRight, marginBottom);
-
- devPageRect = devPaperRect.adjusted(qRound(mmToInches(marginLeft / 100.0) * dpi_x),
- qRound(mmToInches(marginTop / 100.0) * dpi_y),
- - qRound(mmToInches(marginRight / 100.0) * dpi_x),
- - qRound(mmToInches(marginBottom / 100.0) * dpi_y));
- updateOrigin();
-}
-
-QRect QWin32PrintEnginePrivate::getPageMargins() const
-{
- if (pageMarginsSet)
- return previousDialogMargins;
- else
- return QRect(qRound(inchesToMM(devPhysicalPageRect.left()) * 100.0 / dpi_x),
- qRound(inchesToMM(devPhysicalPageRect.top()) * 100.0 / dpi_y),
- qRound(inchesToMM(devPaperRect.right() - devPhysicalPageRect.right()) * 100.0 / dpi_x),
- qRound(inchesToMM(devPaperRect.bottom() - devPhysicalPageRect.bottom()) * 100.0 / dpi_y));
}
void QWin32PrintEnginePrivate::release()
@@ -1208,63 +962,16 @@ void QWin32PrintEnginePrivate::release()
devMode = 0;
}
-QList<QVariant> QWin32PrintEnginePrivate::queryResolutions() const
-{
- // Read the supported resolutions of the printer.
- QList<QVariant> list;
-
- DWORD numRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()), NULL,
- DC_ENUMRESOLUTIONS, 0, 0);
- if (numRes == (DWORD)-1)
- return list;
-
- LONG *enumRes = (LONG*)malloc(numRes * 2 * sizeof(LONG));
- DWORD errRes = DeviceCapabilities(reinterpret_cast<const wchar_t *>(name.utf16()), NULL,
- DC_ENUMRESOLUTIONS, (LPWSTR)enumRes, 0);
-
- if (errRes == (DWORD)-1) {
- qErrnoWarning("QWin32PrintEngine::queryResolutions: DeviceCapabilities failed");
- return list;
- }
-
- for (uint i=0; i<numRes; ++i)
- list.append(int(enumRes[i * 2]));
-
- return list;
-}
-
void QWin32PrintEnginePrivate::doReinit()
{
if (state == QPrinter::Active) {
reinit = true;
} else {
resetDC();
- initDevRects();
reinit = false;
}
}
-void QWin32PrintEnginePrivate::updateOrigin()
-{
- if (fullPage) {
- // subtract physical margins to make (0,0) absolute top corner of paper
- // then add user defined margins
- origin_x = -devPhysicalPageRect.x();
- origin_y = -devPhysicalPageRect.y();
- if (pageMarginsSet) {
- origin_x += devPageRect.left();
- origin_y += devPageRect.top();
- }
- } else {
- origin_x = 0;
- origin_y = 0;
- if (pageMarginsSet) {
- origin_x = devPageRect.left() - devPhysicalPageRect.x();
- origin_y = devPageRect.top() - devPhysicalPageRect.y();
- }
- }
-}
-
void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
{
Q_D(QWin32PrintEngine);
@@ -1329,8 +1036,15 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
break;
case PPK_FullPage:
- d->fullPage = value.toBool();
- d->updateOrigin();
+ if (value.toBool())
+ d->m_pageLayout.setMode(QPageLayout::FullPageMode);
+ else
+ d->m_pageLayout.setMode(QPageLayout::StandardMode);
+ d->updateMetrics();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_FullPage," << value.toBool() << + ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
break;
case PPK_CopyCount: // fallthrough
@@ -1342,18 +1056,20 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
d->doReinit();
break;
- case PPK_Orientation:
- {
- if (!d->devMode)
- break;
- int orientation = value.toInt() == QPrinter::Landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
- int old_orientation = d->devMode->dmOrientation;
- d->devMode->dmOrientation = orientation;
- if (d->has_custom_paper_size && old_orientation != orientation)
- d->paper_size = QSizeF(d->paper_size.height(), d->paper_size.width());
- d->doReinit();
- }
+ case PPK_Orientation: {
+ if (!d->devMode)
+ break;
+ QPageLayout::Orientation orientation = QPageLayout::Orientation(value.toInt());
+ d->devMode->dmOrientation = orientation == QPageLayout::Landscape ? DMORIENT_LANDSCAPE : DMORIENT_PORTRAIT;
+ d->m_pageLayout.setOrientation(orientation);
+ d->updateMetrics();
+ d->doReinit();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_Orientation," << orientation << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
break;
+ }
case PPK_OutputFileName:
if (isActive()) {
@@ -1364,130 +1080,166 @@ void QWin32PrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &
}
break;
- case PPK_PaperSize:
+ case PPK_PageSize: {
if (!d->devMode)
break;
- d->devMode->dmPaperSize = mapPaperSizeDevmode(QPrinter::PaperSize(value.toInt()));
- d->has_custom_paper_size = (QPrinter::PaperSize(value.toInt()) == QPrinter::Custom);
- setDevModePaperFlags(d->devMode, d->has_custom_paper_size);
- d->doReinit();
- break;
-
- case PPK_PaperName:
- {
- if (!d->devMode)
- break;
- const wchar_t *name = reinterpret_cast<const wchar_t*>(d->name.utf16());
- DWORD size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, NULL, NULL);
- if ((int)size > 0) {
- QScopedArrayPointer<wchar_t> paperNames(new wchar_t[size*64]);
- if (size != DeviceCapabilities(name, NULL, DC_PAPERNAMES, paperNames.data(), NULL))
- break;
- int paperPos = -1;
- for (int i = 0; i < (int)size; ++i) {
- wchar_t *copyOfPaper = paperNames.data() + (i * 64);
- if (value.toString() == QString::fromWCharArray(copyOfPaper, qwcsnlen(copyOfPaper, 64))) {
- paperPos = i;
- break;
- }
- }
- size = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL);
- if ((int)size > 0) {
- QScopedArrayPointer<wchar_t> papers(new wchar_t[size]);
- size = DeviceCapabilities(name, NULL, DC_PAPERS, papers.data(), NULL);
- QScopedArrayPointer<POINT> paperSizes(new POINT[size]);
- DWORD paperNameCount = DeviceCapabilities(name, NULL, DC_PAPERSIZE, (wchar_t *)paperSizes.data(), NULL);
- if (paperNameCount == size) {
- const double multiplier = qt_multiplierForUnit(QPrinter::Millimeter, d->resolution);
- d->paper_size = QSizeF((paperSizes[paperPos].x / 10.0) * multiplier, (paperSizes[paperPos].y / 10.0) * multiplier);
- // Our sizes may not match the paper name's size exactly
- // So we treat it as custom so we know the paper size is correct
- d->has_custom_paper_size = true;
- d->devMode->dmPaperSize = papers[paperPos];
- setDevModePaperFlags(d->devMode, false);
- d->doReinit();
- }
- }
- }
+ const QPageSize pageSize = QPageSize(QPageSize::PageSizeId(value.toInt()));
+ if (pageSize.isValid()) {
+ d->setPageSize(pageSize);
+ d->doReinit();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_PageSize," << value.toInt() << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
}
break;
- case PPK_PaperSource:
- {
- if (!d->devMode)
- break;
- int dmMapped = DMBIN_AUTO;
-
- QList<QVariant> v = property(PPK_PaperSources).toList();
- if (v.contains(value))
- dmMapped = mapPaperSourceDevmode(QPrinter::PaperSource(value.toInt()));
+ }
- d->devMode->dmDefaultSource = dmMapped;
+ case PPK_PaperName: {
+ if (!d->devMode)
+ break;
+ // Get the named page size from the printer if supported
+ const QPageSize pageSize = d->m_printDevice.supportedPageSize(value.toString());
+ if (pageSize.isValid()) {
+ d->setPageSize(pageSize);
d->doReinit();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_PaperName," << value.toString() << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
}
break;
+ }
- case PPK_PrinterName:
- d->name = value.toString();
- if (d->name.isEmpty())
- d->queryDefault();
- d->initialize();
+ case PPK_PaperSource: {
+ if (!d->devMode)
+ break;
+ QPrint::InputSlotId inputSlotId = QPrint::InputSlotId(value.toInt());
+ foreach (const QPrint::InputSlot &inputSlot, d->m_printDevice.supportedInputSlots()) {
+ if (inputSlot.id == inputSlotId) {
+ d->devMode->dmDefaultSource = inputSlot.windowsId;
+ d->doReinit();
+ break;
+ }
+ }
break;
+ }
- case PPK_Resolution:
- {
- d->resolution = value.toInt();
-
- d->stretch_x = d->dpi_x / double(d->resolution);
- d->stretch_y = d->dpi_y / double(d->resolution);
+ case PPK_PrinterName: {
+ QString id = value.toString();
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (!ps)
+ return;
+ QPrintDevice printDevice = ps->createPrintDevice(id.isEmpty() ? ps->defaultPrintDeviceId() : id);
+ if (printDevice.isValid()) {
+ d->m_printDevice = printDevice;
+ // TODO Do we need to check if the page size is valid on new printer?
+ d->initialize();
}
break;
+ }
- case PPK_WindowsPageSize:
+ case PPK_Resolution: {
+ d->resolution = value.toInt();
+ d->stretch_x = d->dpi_x / double(d->resolution);
+ d->stretch_y = d->dpi_y / double(d->resolution);
+ d->updateMetrics();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_Resolution," << value.toInt() << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
+ break;
+ }
+
+ case PPK_WindowsPageSize: {
if (!d->devMode)
break;
- d->has_custom_paper_size = false;
- d->devMode->dmPaperSize = value.toInt();
- setDevModePaperFlags(d->devMode, d->has_custom_paper_size);
- d->doReinit();
+ const QPageSize pageSize = QPageSize(QPageSize::id(value.toInt()));
+ if (pageSize.isValid()) {
+ d->setPageSize(pageSize);
+ d->doReinit();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_WindowsPageSize," << value.toInt() << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
+ break;
+ }
break;
+ }
- case PPK_CustomPaperSize:
- {
- d->has_custom_paper_size = true;
- d->paper_size = value.toSizeF();
+ case PPK_CustomPaperSize: {
if (!d->devMode)
break;
- const QSizeF sizeMM = qt_SizeFromUnitToMillimeter(d->paper_size, QPrinter::Point, d->resolution);
- const int match = findCustomPaperSize(sizeMM, d->name);
- setDevModePaperFlags(d->devMode, (match >= 0) ? false : true);
- if (match >= 0) {
- d->devMode->dmPaperSize = match;
- if (d->devMode->dmOrientation != DMORIENT_PORTRAIT)
- qSwap(d->paper_size.rwidth(), d->paper_size.rheight());
- } else {
- d->devMode->dmPaperLength = qRound(sizeMM.height() * 10.0);
- d->devMode->dmPaperWidth = qRound(sizeMM.width() * 10.0);
+ const QPageSize pageSize = QPageSize(value.toSizeF(), QPageSize::Point);
+ if (pageSize.isValid()) {
+ d->setPageSize(pageSize);
+ d->doReinit();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_CustomPaperSize," << value.toSizeF() << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
}
- d->doReinit();
break;
}
- case PPK_PageMargins:
- {
+ case PPK_PageMargins: {
QList<QVariant> margins(value.toList());
Q_ASSERT(margins.size() == 4);
- int left, top, right, bottom;
- // specified in 1/100 mm
- left = (margins.at(0).toReal()*25.4/72.0) * 100;
- top = (margins.at(1).toReal()*25.4/72.0) * 100;
- right = (margins.at(2).toReal()*25.4/72.0) * 100;
- bottom = (margins.at(3).toReal()*25.4/72.0) * 100;
- d->setPageMargins(left, top, right, bottom);
+ d->m_pageLayout.setUnits(QPageLayout::Point);
+ d->m_pageLayout.setMargins(QMarginsF(margins.at(0).toReal(), margins.at(1).toReal(),
+ margins.at(2).toReal(), margins.at(3).toReal()));
+ d->updateMetrics();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_PageMargins," << margins << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
break;
}
- // No default so that compiler will complain if new keys added and not handled in this engine
+ case PPK_QPageSize: {
+ // Get the page size from the printer if supported
+ const QPageSize pageSize = value.value<QPageSize>();
+ if (pageSize.isValid()) {
+ d->setPageSize(pageSize);
+ d->doReinit();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_QPageSize," << pageSize << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
+ }
+ break;
+ }
+ case PPK_QPageMargins: {
+ QPair<QMarginsF, QPageLayout::Unit> pair = value.value<QPair<QMarginsF, QPageLayout::Unit> >();
+ d->m_pageLayout.setUnits(pair.second);
+ d->m_pageLayout.setMargins(pair.first);
+ d->updateMetrics();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_QPageMargins," << pair.first << pair.second << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
+ break;
+ }
+
+ case PPK_QPageLayout: {
+ QPageLayout pageLayout = value.value<QPageLayout>();
+ if (pageLayout.isValid() && d->m_printDevice.isValidPageLayout(pageLayout, d->resolution)) {
+ setProperty(PPK_QPageSize, QVariant::fromValue(pageLayout.pageSize()));
+ setProperty(PPK_FullPage, pageLayout.mode() == QPageLayout::FullPageMode);
+ setProperty(PPK_Orientation, QVariant::fromValue(pageLayout.orientation()));
+ d->m_pageLayout.setUnits(pageLayout.units());
+ d->m_pageLayout.setMargins(pageLayout.margins());
+ d->updateMetrics();
+#ifdef QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setProperty(PPK_QPageLayout," << pageLayout << ")";
+ d->debugMetrics();
+#endif // QT_DEBUG_METRICS
+ }
+ break;
+ }
+
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
}
@@ -1540,7 +1292,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
break;
case PPK_FullPage:
- value = d->fullPage;
+ value = d->m_pageLayout.mode() == QPageLayout::FullPageMode;
break;
case PPK_CopyCount:
@@ -1556,13 +1308,7 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
break;
case PPK_Orientation:
- {
- if (!d->devMode) {
- value = QPrinter::Portrait;
- } else {
- value = (d->devMode->dmOrientation == DMORIENT_LANDSCAPE) ? QPrinter::Landscape : QPrinter::Portrait;
- }
- }
+ value = d->m_pageLayout.orientation();
break;
case PPK_OutputFileName:
@@ -1570,150 +1316,93 @@ QVariant QWin32PrintEngine::property(PrintEnginePropertyKey key) const
break;
case PPK_PageRect:
- if (d->has_custom_paper_size) {
- QRect rect(0, 0,
- qRound(d->paper_size.width() * d->resolution / 72.0),
- qRound(d->paper_size.height() * d->resolution / 72.0));
- if (d->pageMarginsSet) {
- rect = rect.adjusted(qRound(mmToInches(d->previousDialogMargins.left()/100.0) * d->resolution),
- qRound(mmToInches(d->previousDialogMargins.top()/100.0) * d->resolution),
- -qRound(mmToInches(d->previousDialogMargins.width()/100.0) * d->resolution),
- -qRound(mmToInches(d->previousDialogMargins.height()/100.0) * d->resolution));
- }
- value = rect;
- } else {
- value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0)
- .mapRect(d->fullPage ? d->devPhysicalPageRect : d->devPageRect);
- }
+ // PageRect is returned in device pixels
+ value = d->m_pageLayout.paintRectPixels(d->resolution);
break;
- case PPK_PaperSize:
- if (d->has_custom_paper_size) {
- value = QPrinter::Custom;
- } else {
- if (!d->devMode) {
- value = QPrinter::A4;
- } else {
- value = mapDevmodePaperSize(d->devMode->dmPaperSize);
- }
- }
+ case PPK_PageSize:
+ value = d->m_pageLayout.pageSize().id();
break;
case PPK_PaperRect:
- if (d->has_custom_paper_size) {
- value = QRect(0, 0,
- qRound(d->paper_size.width() * d->resolution / 72.0),
- qRound(d->paper_size.height() * d->resolution / 72.0));
- } else {
- value = QTransform(1/d->stretch_x, 0, 0, 1/d->stretch_y, 0, 0).mapRect(d->devPaperRect);
- }
+ // PaperRect is returned in device pixels
+ value = d->m_pageLayout.fullRectPixels(d->resolution);
break;
case PPK_PaperName:
- if (!d->devMode) {
- value = QLatin1String("A4");
- } else {
- const wchar_t *name = reinterpret_cast<const wchar_t*>(d->name.utf16());
- DWORD size = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL);
- int paperSizePos = -1;
- if ((int)size > 0) {
- QScopedArrayPointer<wchar_t> papers(new wchar_t[size]);
- if (size != DeviceCapabilities(name, NULL, DC_PAPERS, papers.data(), NULL))
- break;
- for (int i=0;i<(int)size;i++) {
- if (papers[i] == d->devMode->dmPaperSize) {
- paperSizePos = i;
- break;
- }
- }
- }
- if (paperSizePos != -1) {
- size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, NULL, NULL);
- if ((int)size > 0) {
- QScopedArrayPointer<wchar_t> paperNames(new wchar_t[size*64]);
- size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, paperNames.data(), NULL);
- wchar_t *copyOfPaper = paperNames.data() + (paperSizePos * 64);
- value = QString::fromWCharArray(copyOfPaper, qwcsnlen(copyOfPaper, 64));
- }
- }
- }
+ value = d->m_pageLayout.pageSize().name();
break;
case PPK_PaperSource:
if (!d->devMode) {
- value = QPrinter::Auto;
+ value = d->m_printDevice.defaultInputSlot().id;
} else {
- value = mapDevmodePaperSource(d->devMode->dmDefaultSource);
+ value = QPrint::Auto;
+ foreach (const QPrint::InputSlot inputSlot, d->m_printDevice.supportedInputSlots()) {
+ if (inputSlot.windowsId == d->devMode->dmDefaultSource) {
+ value = inputSlot.id;
+ break;
+ }
+ }
}
break;
case PPK_PrinterName:
- value = d->name;
+ value = d->m_printDevice.id();
break;
case PPK_Resolution:
- if (d->resolution || !d->name.isEmpty())
+ if (d->resolution || d->m_printDevice.isValid())
value = d->resolution;
break;
- case PPK_SupportedResolutions:
- value = d->queryResolutions();
+ case PPK_SupportedResolutions: {
+ QList<QVariant> list;
+ foreach (int resolution, d->m_printDevice.supportedResolutions())
+ list << resolution;
+ value = list;
break;
+ }
case PPK_WindowsPageSize:
- if (!d->devMode) {
- value = -1;
- } else {
- value = d->devMode->dmPaperSize;
- }
+ value = d->m_pageLayout.pageSize().windowsId();
break;
- case PPK_PaperSources:
- {
- int available = DeviceCapabilities((const wchar_t *)d->name.utf16(), NULL, DC_BINS, 0, d->devMode);
-
- if (available <= 0)
- break;
-
- wchar_t *data = new wchar_t[available];
- int count = DeviceCapabilities((const wchar_t *)d->name.utf16(), NULL, DC_BINS, data, d->devMode);
-
- QList<QVariant> out;
- for (int i=0; i<count; ++i) {
- QPrinter::PaperSource src = mapDevmodePaperSource(data[i]);
- if (src != -1)
- out << (int) src;
- }
- value = out;
-
- delete [] data;
- }
+ case PPK_PaperSources: {
+ QList<QVariant> out;
+ foreach (const QPrint::InputSlot inputSlot, d->m_printDevice.supportedInputSlots())
+ out << inputSlot.id;
+ value = out;
break;
+ }
case PPK_CustomPaperSize:
- value = d->paper_size;
+ value = d->m_pageLayout.fullRectPoints().size();
break;
- case PPK_PageMargins:
- {
- QList<QVariant> margins;
- if (d->has_custom_paper_size && !d->pageMarginsSet) {
- margins << 0 << 0 << 0 << 0;
- } else {
- QRect pageMargins(d->getPageMargins());
+ case PPK_PageMargins: {
+ QList<QVariant> list;
+ QMarginsF margins = d->m_pageLayout.margins(QPageLayout::Point);
+ list << margins.left() << margins.top() << margins.right() << margins.bottom();
+ value = list;
+ break;
+ }
- // specified in 1/100 mm
- margins << (mmToInches(pageMargins.left()/100.0) * 72)
- << (mmToInches(pageMargins.top()/100.0) * 72)
- << (mmToInches(pageMargins.width()/100.0) * 72)
- << (mmToInches(pageMargins.height()/100.0) * 72);
- }
- value = margins;
+ case PPK_QPageSize:
+ value.setValue(d->m_pageLayout.pageSize());
+ break;
+
+ case PPK_QPageMargins: {
+ QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(d->m_pageLayout.margins(), d->m_pageLayout.units());
+ value.setValue(pair);
break;
}
- // No default so that compiler will complain if new keys added and not handled in this engine
+ case PPK_QPageLayout:
+ value.setValue(d->m_pageLayout);
+ break;
+ // No default so that compiler will complain if new keys added and not handled in this engine
}
return value;
}
@@ -1733,76 +1422,11 @@ void QWin32PrintEngine::releaseDC(HDC) const
}
-QList<QPrinter::PaperSize> QWin32PrintEngine::supportedPaperSizes(const QPrinterInfo &printerInfo)
-{
- QList<QPrinter::PaperSize> returnList;
-
- if (printerInfo.isNull())
- return returnList;
- const wchar_t *name = reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16());
- DWORD size = DeviceCapabilities(name, NULL, DC_PAPERS, NULL, NULL);
- if ((int)size != -1) {
- QScopedArrayPointer<wchar_t> papers(new wchar_t[size]);
- if (size != DeviceCapabilities(name, NULL, DC_PAPERS, papers.data(), NULL))
- return returnList;
- for (int c = 0; c < (int)size; ++c)
- returnList.append(mapDevmodePaperSize(papers[c]));
- }
- return returnList;
-}
-
-QList<QPair<QString, QSizeF> > QWin32PrintEngine::supportedSizesWithNames(const QPrinterInfo &printerInfo)
-{
- QList<QPair<QString, QSizeF> > paperSizes;
- if (printerInfo.isNull())
- return paperSizes;
- const wchar_t *name = reinterpret_cast<const wchar_t*>(printerInfo.printerName().utf16());
- DWORD size = DeviceCapabilities(name, NULL, DC_PAPERNAMES, NULL, NULL);
- if ((int)size > 0) {
- QScopedArrayPointer<wchar_t> papers(new wchar_t[size*64]);
- if (size != DeviceCapabilities(name, NULL, DC_PAPERNAMES, papers.data(), NULL))
- return paperSizes;
- if (size != DeviceCapabilities(name, NULL, DC_PAPERSIZE, NULL, NULL))
- return paperSizes;
- QScopedArrayPointer<POINT> points(new POINT[size*sizeof(POINT)]);
- if (size != DeviceCapabilities(name, NULL, DC_PAPERSIZE, (wchar_t *)points.data(), NULL))
- return paperSizes;
- for (int i = 0; i < (int)size; ++i) {
- wchar_t *paper = papers.data() + (i * 64);
- QString str = QString::fromWCharArray(paper, qwcsnlen(paper, 64));
- paperSizes << qMakePair(str, QSizeF(points[i].x / 10.0, points[i].y / 10.0));
- }
- }
- return paperSizes;
-}
-
-void QWin32PrintEngine::queryDefaultPrinter(QString &name)
-{
- /* Read the default printer name, driver and port with the intuitive function
- * Strings "windows" and "device" are specified in the MSDN under EnumPrinters()
- */
- QString noPrinters(QLatin1String("qt_no_printers"));
- wchar_t buffer[256];
- GetProfileString(L"windows", L"device",
- reinterpret_cast<const wchar_t *>(noPrinters.utf16()),
- buffer, 256);
- QString output = QString::fromWCharArray(buffer);
- if (output.isEmpty() || output == noPrinters) // no printers
- return;
-
- QStringList info = output.split(QLatin1Char(','));
- int infoSize = info.size();
- if (infoSize > 0) {
- if (name.isEmpty())
- name = info.at(0);
- }
-}
-
HGLOBAL *QWin32PrintEngine::createGlobalDevNames()
{
Q_D(QWin32PrintEngine);
- int size = sizeof(DEVNAMES) + d->name.length() * 2 + 2;
+ int size = sizeof(DEVNAMES) + d->m_printDevice.id().length() * 2 + 2;
HGLOBAL *hGlobal = (HGLOBAL *) GlobalAlloc(GMEM_MOVEABLE, size);
DEVNAMES *dn = (DEVNAMES*) GlobalLock(hGlobal);
@@ -1810,7 +1434,7 @@ HGLOBAL *QWin32PrintEngine::createGlobalDevNames()
dn->wDeviceOffset = sizeof(DEVNAMES) / sizeof(wchar_t);
dn->wOutputOffset = 0;
- memcpy((ushort*)dn + dn->wDeviceOffset, d->name.utf16(), d->name.length() * 2 + 2);
+ memcpy((ushort*)dn + dn->wDeviceOffset, d->m_printDevice.id().utf16(), d->m_printDevice.id().length() * 2 + 2);
dn->wDefault = 0;
GlobalUnlock(hGlobal);
@@ -1822,7 +1446,10 @@ void QWin32PrintEngine::setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalD
Q_D(QWin32PrintEngine);
if (globalDevNames) {
DEVNAMES *dn = (DEVNAMES*) GlobalLock(globalDevNames);
- d->name = QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset);
+ QString id = QString::fromWCharArray((wchar_t*)(dn) + dn->wDeviceOffset);
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps)
+ d->m_printDevice = ps->createPrintDevice(id.isEmpty() ? ps->defaultPrintDeviceId() : id);
GlobalUnlock(globalDevNames);
}
@@ -1831,17 +1458,22 @@ void QWin32PrintEngine::setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalD
d->release();
d->globalDevMode = globalDevMode;
d->devMode = dm;
- d->hdc = CreateDC(NULL, reinterpret_cast<const wchar_t *>(d->name.utf16()), 0, dm);
+ d->hdc = CreateDC(NULL, reinterpret_cast<const wchar_t *>(d->m_printDevice.id().utf16()), 0, dm);
d->num_copies = d->devMode->dmCopies;
- d->updateCustomPaperSize();
+ d->updatePageLayout();
- if (!OpenPrinter((wchar_t*)d->name.utf16(), &d->hPrinter, 0))
+ if (!OpenPrinter((wchar_t*)d->m_printDevice.id().utf16(), &d->hPrinter, 0))
qWarning("QPrinter: OpenPrinter() failed after reading DEVMODE.");
}
if (d->hdc)
d->initHDC();
+
+#if defined QT_DEBUG_DRAW || defined QT_DEBUG_METRICS
+ qDebug() << "QWin32PrintEngine::setGlobalDevMode()";
+ debugMetrics();
+#endif // QT_DEBUG_DRAW || QT_DEBUG_METRICS
}
HGLOBAL QWin32PrintEngine::globalDevMode()
@@ -1850,6 +1482,78 @@ HGLOBAL QWin32PrintEngine::globalDevMode()
return d->globalDevMode;
}
+void QWin32PrintEnginePrivate::setPageSize(const QPageSize &pageSize)
+{
+ if (!pageSize.isValid())
+ return;
+
+ // Use the printer page size if supported
+ const QPageSize printerPageSize = m_printDevice.supportedPageSize(pageSize);
+ const QPageSize usePageSize = printerPageSize.isValid() ? printerPageSize : pageSize;
+
+ const QMarginsF printable = m_printDevice.printableMargins(usePageSize, m_pageLayout.orientation(), resolution);
+ m_pageLayout.setPageSize(usePageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units()));
+
+ // Setup if Windows custom size, i.e. not a known Windows ID
+ if (printerPageSize.isValid()) {
+ has_custom_paper_size = false;
+ devMode->dmPaperSize = m_pageLayout.pageSize().windowsId();
+ devMode->dmFields &= ~(DM_PAPERLENGTH | DM_PAPERWIDTH);
+ devMode->dmPaperWidth = 0;
+ devMode->dmPaperLength = 0;
+ } else {
+ devMode->dmPaperSize = DMPAPER_USER;
+ devMode->dmFields |= DM_PAPERLENGTH | DM_PAPERWIDTH;
+ // Size in tenths of a millimeter
+ const QSizeF sizeMM = m_pageLayout.pageSize().size(QPageSize::Millimeter);
+ devMode->dmPaperWidth = qRound(sizeMM.width() * 10.0);
+ devMode->dmPaperLength = qRound(sizeMM.height() * 10.0);
+ }
+ updateMetrics();
+}
+
+// Update the page layout after any changes made to devMode
+void QWin32PrintEnginePrivate::updatePageLayout()
+{
+ // Update orientation first as is needed to obtain printable margins when changing page size
+ m_pageLayout.setOrientation(devMode->dmOrientation == DMORIENT_LANDSCAPE ? QPageLayout::Landscape : QPageLayout::Portrait);
+ if (devMode->dmPaperSize >= DMPAPER_USER) {
+ // Is a custom size
+ QPageSize pageSize = QPageSize(QSizeF(devMode->dmPaperWidth / 10.0f, devMode->dmPaperLength / 10.0f),
+ QPageSize::Millimeter);
+ setPageSize(pageSize);
+ } else {
+ // Is a supported size
+ setPageSize(QPageSize(QPageSize::id(devMode->dmPaperSize)));
+ }
+ updateMetrics();
+}
+
+// Update the cached page paint metrics whenever page layout is changed
+void QWin32PrintEnginePrivate::updateMetrics()
+{
+ m_paintRectPixels = m_pageLayout.paintRectPixels(resolution);
+ QSizeF sizeMM = m_pageLayout.paintRect(QPageLayout::Millimeter).size();
+ m_paintSizeMM = QSize(qRound(sizeMM.width()), qRound(sizeMM.height()));
+ // Calculate the origin using the physical device pixels, not our paint pixels
+ // Origin is defined as User Margins - Device Margins
+ QMarginsF margins = m_pageLayout.margins(QPageLayout::Millimeter) / 25.4;
+ origin_x = qRound(margins.left() * dpi_x) - GetDeviceCaps(hdc, PHYSICALOFFSETX);
+ origin_y = qRound(margins.top() * dpi_y) - GetDeviceCaps(hdc, PHYSICALOFFSETY);
+}
+
+void QWin32PrintEnginePrivate::debugMetrics() const
+{
+ qDebug() << " " << "m_pageLayout = " << m_pageLayout;
+ qDebug() << " " << "m_paintRectPixels = " << m_paintRectPixels;
+ qDebug() << " " << "m_paintSizeMM = " << m_paintSizeMM;
+ qDebug() << " " << "resolution = " << resolution;
+ qDebug() << " " << "stretch = " << stretch_x << stretch_y;
+ qDebug() << " " << "origin = " << origin_x << origin_y;
+ qDebug() << " " << "dpi = " << dpi_x << dpi_y;
+ qDebug() << "";
+}
+
static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC hdc,
bool convertToText, const QTransform &xform, const QPointF &topLeft)
{
@@ -1965,27 +1669,6 @@ static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC h
SelectObject(hdc, old_font);
}
-void QWin32PrintEnginePrivate::updateCustomPaperSize()
-{
- const uint paperSize = devMode->dmPaperSize;
- const double multiplier = qt_multiplierForUnit(QPrinter::Millimeter, resolution);
- has_custom_paper_size = false;
- if (paperSize == DMPAPER_USER) {
- has_custom_paper_size = true;
- paper_size = QSizeF((devMode->dmPaperWidth / 10.0) * multiplier, (devMode->dmPaperLength / 10.0) * multiplier);
- } else if (mapDevmodePaperSize(paperSize) == QPrinter::Custom) {
- has_custom_paper_size = true;
- const QList<QPair<QSizeF, int> > paperSizes = printerPaperSizes(name);
- for (int i=0; i<paperSizes.size(); i++) {
- if ((uint)paperSizes.at(i).second == paperSize) {
- paper_size = paperSizes.at(i).first * multiplier;
- has_custom_paper_size = false;
- break;
- }
- }
- }
-}
-
QT_END_NAMESPACE
#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprintengine_win_p.h b/src/printsupport/kernel/qprintengine_win_p.h
index d720561c2a..9b944d5921 100644
--- a/src/printsupport/kernel/qprintengine_win_p.h
+++ b/src/printsupport/kernel/qprintengine_win_p.h
@@ -58,10 +58,11 @@
#ifndef QT_NO_PRINTER
#include <QtGui/qpaintengine.h>
+#include <QtGui/qpagelayout.h>
#include <QtPrintSupport/QPrintEngine>
#include <QtPrintSupport/QPrinter>
-#include <QtPrintSupport/QPrinterInfo>
#include <private/qpaintengine_alpha_p.h>
+#include <private/qprintdevice_p.h>
#include <QtCore/qt_windows.h>
QT_BEGIN_NAMESPACE
@@ -105,16 +106,11 @@ public:
HDC getDC() const;
void releaseDC(HDC) const;
- static QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &printerInfo);
- static QList<QPair<QString, QSizeF> > supportedSizesWithNames(const QPrinterInfo &printerInfo);
-
/* Used by print/page setup dialogs */
void setGlobalDevMode(HGLOBAL globalDevNames, HGLOBAL globalDevMode);
HGLOBAL *createGlobalDevNames();
HGLOBAL globalDevMode();
- static void queryDefaultPrinter(QString &name);
-
private:
friend class QPrintDialog;
friend class QPageSetupDialog;
@@ -133,22 +129,16 @@ public:
mode(QPrinter::ScreenResolution),
state(QPrinter::Idle),
resolution(0),
- pageMarginsSet(false),
+ m_pageLayout(QPageLayout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0, 0, 0, 0))),
num_copies(1),
printToFile(false),
- fullPage(false),
- reinit(false),
- has_custom_paper_size(false)
+ reinit(false)
{
}
~QWin32PrintEnginePrivate();
- /* Reads the default printer name and its driver (printerProgram) into
- the engines private data. */
- void queryDefault();
-
/* Initializes the printer data based on the current printer name. This
function creates a DEVMODE struct, HDC and a printer handle. If these
structures are already in use, they are freed using release
@@ -163,10 +153,6 @@ public:
etc and resets the corresponding members to 0. */
void release();
- /* Queries the resolutions for the current printer, and returns them
- in a list. */
- QList<QVariant> queryResolutions() const;
-
/* Resets the DC with changes in devmode. If the printer is active
this function only sets the reinit variable to true so it
is handled in the next begin or newpage. */
@@ -184,12 +170,10 @@ public:
void fillPath_dev(const QPainterPath &path, const QColor &color);
void strokePath_dev(const QPainterPath &path, const QColor &color, qreal width);
- void updateOrigin();
-
- void initDevRects();
- void setPageMargins(int margin_left, int margin_top, int margin_right, int margin_bottom);
- QRect getPageMargins() const;
- void updateCustomPaperSize();
+ void setPageSize(const QPageSize &pageSize);
+ void updatePageLayout();
+ void updateMetrics();
+ void debugMetrics() const;
// Windows GDI printer references.
HANDLE hPrinter;
@@ -203,8 +187,8 @@ public:
QPrinter::PrinterMode mode;
- // Printer info
- QString name;
+ // Print Device
+ QPrintDevice m_printDevice;
// Document info
QString docName;
@@ -214,19 +198,14 @@ public:
QPrinter::PrinterState state;
int resolution;
- // This QRect is used to store the exact values
- // entered into the PageSetup Dialog because those are
- // entered in mm but are since converted to device coordinates.
- // If they were to be converted back when displaying the dialog
- // again, there would be inaccuracies so when the user entered 10
- // it may show up as 9.99 the next time the dialog is opened.
- // We don't want that confusion.
- QRect previousDialogMargins;
-
- bool pageMarginsSet;
- QRect devPageRect;
- QRect devPhysicalPageRect;
- QRect devPaperRect;
+ // Page Layout
+ QPageLayout m_pageLayout;
+
+ // Page metrics cache
+ QRect m_paintRectPixels;
+ QSize m_paintSizeMM;
+
+ // Windows painting
qreal stretch_x;
qreal stretch_y;
int origin_x;
@@ -238,7 +217,6 @@ public:
int num_copies;
uint printToFile : 1;
- uint fullPage : 1;
uint reinit : 1;
uint complex_xform : 1;
@@ -251,7 +229,7 @@ public:
QColor brush_color;
QPen pen;
QColor pen_color;
- QSizeF paper_size;
+ QSizeF paper_size; // In points
QTransform painterMatrix;
QTransform matrix;
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index 496883f44b..153fb23d36 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -67,39 +67,14 @@ QT_BEGIN_NAMESPACE
return; \
}
-// NB! This table needs to be in sync with QPrinter::PaperSize
-static const float qt_paperSizes[][2] = {
- {210, 297}, // A4
- {176, 250}, // B5
- {215.9f, 279.4f}, // Letter
- {215.9f, 355.6f}, // Legal
- {190.5f, 254}, // Executive
- {841, 1189}, // A0
- {594, 841}, // A1
- {420, 594}, // A2
- {297, 420}, // A3
- {148, 210}, // A5
- {105, 148}, // A6
- {74, 105}, // A7
- {52, 74}, // A8
- {37, 52}, // A8
- {1000, 1414}, // B0
- {707, 1000}, // B1
- {31, 44}, // B10
- {500, 707}, // B2
- {353, 500}, // B3
- {250, 353}, // B4
- {125, 176}, // B6
- {88, 125}, // B7
- {62, 88}, // B8
- {44, 62}, // B9
- {163, 229}, // C5E
- {105, 241}, // US Common
- {110, 220}, // DLE
- {210, 330}, // Folio
- {431.8f, 279.4f}, // Ledger
- {279.4f, 431.8f} // Tabloid
-};
+#define ABORT_IF_ACTIVE_RETURN(location, retValue) \
+ if (d->printEngine->printerState() == QPrinter::Active) { \
+ qWarning("%s: Cannot be changed while printer is active", location); \
+ return retValue; \
+ }
+
+extern qreal qt_pixelMultiplier(int resolution);
+extern QMarginsF qt_convertMargins(const QMarginsF &margins, QPageLayout::Unit fromUnits, QPageLayout::Unit toUnits);
/// return the multiplier of converting from the unit value to postscript-points.
Q_PRINTSUPPORT_EXPORT double qt_multiplierForUnit(QPrinter::Unit unit, int resolution)
@@ -123,43 +98,19 @@ Q_PRINTSUPPORT_EXPORT double qt_multiplierForUnit(QPrinter::Unit unit, int resol
return 1.0;
}
-/// return the QSize from the specified in unit as millimeters
-Q_PRINTSUPPORT_EXPORT QSizeF qt_SizeFromUnitToMillimeter(const QSizeF &size, QPrinter::Unit unit, double resolution)
-{
- switch (unit) {
- case QPrinter::Millimeter:
- return size;
- case QPrinter::Point:
- return size * 0.352777778;
- case QPrinter::Inch:
- return size * 25.4;
- case QPrinter::Pica:
- return size * 4.23333333334;
- case QPrinter::Didot:
- return size * 0.377;
- case QPrinter::Cicero:
- return size * 4.511666667;
- case QPrinter::DevicePixel:
- return size * (0.352777778 * 72.0 / resolution);
- }
- return size;
-}
-
// not static: it's needed in qpagesetupdialog_unix.cpp
Q_PRINTSUPPORT_EXPORT QSizeF qt_printerPaperSize(QPrinter::Orientation orientation,
QPrinter::PaperSize paperSize,
QPrinter::Unit unit,
int resolution)
{
- int width_index = 0;
- int height_index = 1;
- if (orientation == QPrinter::Landscape) {
- width_index = 1;
- height_index = 0;
- }
- const qreal multiplier = qt_multiplierForUnit(unit, resolution);
- return QSizeF((qt_paperSizes[paperSize][width_index] * 72 / 25.4) / multiplier,
- (qt_paperSizes[paperSize][height_index] * 72 / 25.4) / multiplier);
+ QPageSize pageSize = QPageSize(QPageSize::PageSizeId(paperSize));
+ QSizeF sizef;
+ if (unit == QPrinter::DevicePixel)
+ sizef = pageSize.size(QPageSize::Point) * qt_multiplierForUnit(unit, resolution);
+ else
+ sizef = pageSize.size(QPageSize::Unit(unit));
+ return orientation == QPrinter::Landscape ? sizef.transposed() : sizef;
}
QPrinterInfo QPrinterPrivate::findValidPrinter(const QPrinterInfo &printer)
@@ -414,61 +365,157 @@ void QPrinterPrivate::setProperty(QPrintEngine::PrintEnginePropertyKey key, cons
\value PageRange The specified page range should be printed.
\value CurrentPage Only the current page should be printed.
- \sa QAbstractPrintDialog::PrintRange
+ \sa setPrintRange(), printRange(), QAbstractPrintDialog::PrintRange
*/
/*!
- \enum QPrinter::PaperSize
- \since 4.4
+ \enum QPrinter::PaperSize
+ \since 4.4
- This enum type specifies what paper size QPrinter should use.
- QPrinter does not check that the paper size is available; it just
- uses this information, together with QPrinter::Orientation and
- QPrinter::setFullPage(), to determine the printable area.
-
- The defined sizes (with setFullPage(true)) are:
-
- \value A0 841 x 1189 mm
- \value A1 594 x 841 mm
- \value A2 420 x 594 mm
- \value A3 297 x 420 mm
- \value A4 210 x 297 mm, 8.26 x 11.69 inches
- \value A5 148 x 210 mm
- \value A6 105 x 148 mm
- \value A7 74 x 105 mm
- \value A8 52 x 74 mm
- \value A9 37 x 52 mm
- \value B0 1000 x 1414 mm
- \value B1 707 x 1000 mm
- \value B2 500 x 707 mm
- \value B3 353 x 500 mm
- \value B4 250 x 353 mm
- \value B5 176 x 250 mm, 6.93 x 9.84 inches
- \value B6 125 x 176 mm
- \value B7 88 x 125 mm
- \value B8 62 x 88 mm
- \value B9 44 x 62 mm
- \value B10 31 x 44 mm
- \value C5E 163 x 229 mm
- \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
- \value DLE 110 x 220 mm
- \value Executive 7.5 x 10 inches, 190.5 x 254 mm
- \value Folio 210 x 330 mm
- \value Ledger 431.8 x 279.4 mm
- \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
- \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
- \value Tabloid 279.4 x 431.8 mm
- \value Custom Unknown, or a user defined size.
-
- With setFullPage(false) (the default), the metrics will be a bit
- smaller; how much depends on the printer in use.
-
- \note QPrinter::Folio is the Adobe specification for the Folio size.
- On Windows if you want to use the same as DMPAPER_FOLIO then you should use
- setPaperSize(QSizeF(8.5, 13), QPrinter::Inch).
-
- \omitvalue NPageSize
- \omitvalue NPaperSize
+ This enum type specifies what paper size QPrinter should use.
+ QPrinter does not check that the paper size is available; it just
+ uses this information, together with QPrinter::Orientation and
+ QPrinter::setFullPage(), to determine the printable area.
+
+ The defined sizes (with setFullPage(true)) are:
+
+ \value A0 841 x 1189 mm
+ \value A1 594 x 841 mm
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.69 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1000 x 1414 mm
+ \value B1 707 x 1000 mm
+ \value B2 500 x 707 mm
+ \value B3 353 x 500 mm
+ \value B4 250 x 353 mm
+ \value B5 176 x 250 mm, 6.93 x 9.84 inches
+ \value B6 125 x 176 mm
+ \value B7 88 x 125 mm
+ \value B8 62 x 88 mm
+ \value B9 33 x 62 mm
+ \value B10 31 x 44 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, U.S. Common 10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 190.5 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 431.8 x 279.4 mm
+ \value Legal 8.5 x 14 inches, 215.9 x 355.6 mm
+ \value Letter 8.5 x 11 inches, 215.9 x 279.4 mm
+ \value Tabloid 279.4 x 431.8 mm
+ \value Custom Unknown, or a user defined size.
+ \value A10
+ \value A3Extra
+ \value A4Extra
+ \value A4Plus
+ \value A4Small
+ \value A5Extra
+ \value B5Extra
+ \value JisB0
+ \value JisB1
+ \value JisB2
+ \value JisB3
+ \value JisB4
+ \value JisB5
+ \value JisB6,
+ \value JisB7
+ \value JisB8
+ \value JisB9
+ \value JisB10
+ \value AnsiA = Letter
+ \value AnsiB = Ledger
+ \value AnsiC
+ \value AnsiD
+ \value AnsiE
+ \value LegalExtra
+ \value LetterExtra
+ \value LetterPlus
+ \value LetterSmall
+ \value TabloidExtra
+ \value ArchA
+ \value ArchB
+ \value ArchC
+ \value ArchD
+ \value ArchE
+ \value Imperial7x9
+ \value Imperial8x10
+ \value Imperial9x11
+ \value Imperial9x12
+ \value Imperial10x11
+ \value Imperial10x13
+ \value Imperial10x14
+ \value Imperial12x11
+ \value Imperial15x11
+ \value ExecutiveStandard
+ \value Note
+ \value Quarto
+ \value Statement
+ \value SuperA
+ \value SuperB
+ \value Postcard
+ \value DoublePostcard
+ \value Prc16K
+ \value Prc32K
+ \value Prc32KBig
+ \value FanFoldUS
+ \value FanFoldGerman
+ \value FanFoldGermanLegal
+ \value EnvelopeB4
+ \value EnvelopeB5
+ \value EnvelopeB6
+ \value EnvelopeC0
+ \value EnvelopeC1
+ \value EnvelopeC2
+ \value EnvelopeC3
+ \value EnvelopeC4
+ \value EnvelopeC5 = C5E
+ \value EnvelopeC6
+ \value EnvelopeC65
+ \value EnvelopeC7
+ \value EnvelopeDL = DLE
+ \value Envelope9
+ \value Envelope10 = Comm10E
+ \value Envelope11
+ \value Envelope12
+ \value Envelope14
+ \value EnvelopeMonarch
+ \value EnvelopePersonal
+ \value EnvelopeChou3
+ \value EnvelopeChou4
+ \value EnvelopeInvite
+ \value EnvelopeItalian
+ \value EnvelopeKaku2
+ \value EnvelopeKaku3
+ \value EnvelopePrc1
+ \value EnvelopePrc2
+ \value EnvelopePrc3
+ \value EnvelopePrc4
+ \value EnvelopePrc5
+ \value EnvelopePrc6
+ \value EnvelopePrc7
+ \value EnvelopePrc8
+ \value EnvelopePrc9
+ \value EnvelopePrc10
+ \value EnvelopeYou4
+ \value LastPageSize = EnvelopeYou4
+ \omitvalue NPageSize
+ \omitvalue NPaperSize
+
+ With setFullPage(false) (the default), the metrics will be a bit
+ smaller; how much depends on the printer in use.
+
+ Due to historic reasons QPageSize::Executive is not the same as the standard
+ Postscript and Windows Executive size, use QPageSize::ExecutiveStandard instead.
+
+ The Postscript standard size QPageSize::Folio is different to the Windows
+ DMPAPER_FOLIO size, use the Postscript standard size QPageSize::FanFoldGermanLegal
+ if needed.
*/
@@ -547,21 +594,6 @@ void QPrinterPrivate::setProperty(QPrintEngine::PrintEnginePropertyKey key, cons
the printer.
*/
-
-/*
- \enum QPrinter::PrintRange
-
- This enum is used to specify which print range the application
- should use to print.
-
- \value AllPages All the pages should be printed.
- \value Selection Only the selection should be printed.
- \value PageRange Print according to the from page and to page options.
- \value CurrentPage Only the current page should be printed.
-
- \sa setPrintRange(), printRange()
-*/
-
/*!
Creates a new printer object with the given \a mode.
*/
@@ -915,21 +947,165 @@ void QPrinter::setCreator(const QString &creator)
d->setProperty(QPrintEngine::PPK_Creator, creator);
}
+/*!
+ \since 5.3
+
+ Sets the page layout to \a newLayout.
+
+ If the \a newLayout is not valid for the current printer then the page
+ layout will not be changed. For example, if the page size is not supported
+ by the printer, or if the margins fall outside the printable area.
+
+ Returns true if the page layout was successfully set to \a newLayout.
+
+ \sa pageLayout(), setPageSize(), setPageOrientation(), setPageMargins()
+*/
+
+bool QPrinter::setPageLayout(const QPageLayout &newLayout)
+{
+ Q_D(QPrinter);
+
+ if (d->paintEngine->type() != QPaintEngine::Pdf)
+ ABORT_IF_ACTIVE_RETURN("QPrinter::setPageLayout", false);
+
+ // Try to set the print engine page layout
+ d->setProperty(QPrintEngine::PPK_QPageLayout, QVariant::fromValue(newLayout));
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ devicePageLayout() = pageLayout();
+
+ return pageLayout().isEquivalentTo(newLayout);
+}
+
+/*!
+ \since 5.3
+
+ Sets the page size to \a pageSize.
+
+ If the \a pageSize is not valid for the current printer then the page
+ size will not be changed.
+
+ Changing the page size may affect the current page margins if they fall
+ outside the printable margins for the new page size on the current printer.
+
+ To obtain the current QPageSize use pageLayout().pageSize().
+
+ Returns true if the page size was successfully set to \a pageSize.
+
+ \sa pageLayout(), setPageLayout()
+*/
+
+bool QPrinter::setPageSize(const QPageSize &pageSize)
+{
+ Q_D(QPrinter);
+
+ if (d->paintEngine->type() != QPaintEngine::Pdf)
+ ABORT_IF_ACTIVE_RETURN("QPrinter::setPageSize", false);
+
+ // Try to set the print engine page size
+ d->setProperty(QPrintEngine::PPK_QPageSize, QVariant::fromValue(pageSize));
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ devicePageLayout() = pageLayout();
+
+ return pageLayout().pageSize().isEquivalentTo(pageSize);
+}
+
+/*!
+ \since 5.3
+
+ Sets the page \a orientation to QPageLayout::Portrait or QPageLayout::Landscape.
+
+ The printer driver reads this setting and prints the page using the
+ specified orientation.
+
+ On Windows and Mac, this option can be changed while printing and will
+ take effect from the next call to newPage().
+
+ To obtain the current QPageLayout::Orientation use pageLayout().pageOrientation().
+
+ Returns true if the page orientation was successfully set to \a orientation.
+
+ \sa pageLayout(), setPageLayout()
+*/
+
+bool QPrinter::setPageOrientation(QPageLayout::Orientation orientation)
+{
+ Q_D(QPrinter);
+
+ // Set the print engine value
+ d->setProperty(QPrintEngine::PPK_Orientation, orientation);
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ devicePageLayout() = pageLayout();
+
+ return pageLayout().orientation() == orientation;
+}
+
+/*!
+ \since 5.3
+
+ Set the page margins to \a margins in the given \a units. If \a units are
+ not provided then the current units are used.
+
+ If in Full Page mode then no check is performed on the \a margins set,
+ otherwise the \a margins must fall within the printable area for the page
+ size on the current printer.
+
+ To obtain the current page margins use pageLayout().pageMargins().
+
+ Returns true if the page margins was successfully set to \a margins.
+
+ \sa pageLayout(), setPageLayout()
+*/
+
+bool QPrinter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
+{
+ Q_D(QPrinter);
+
+ // Try to set print engine margins
+ QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(margins, units);
+ d->setProperty(QPrintEngine::PPK_QPageMargins, QVariant::fromValue(pair));
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ devicePageLayout() = pageLayout();
+
+ return pageLayout().margins() == margins && pageLayout().units() == units;
+}
/*!
+ Returns the current page layout. Use this method to access the current
+ QPageSize, QPageLayout::Orientation, QMarginsF, fullPageRect() and paintRect().
+
+ Note that you cannot use the setters on the returned object, you must either
+ call the QPrinter methods or setPageLayout().
+
+ \sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins()
+*/
+
+QPageLayout QPrinter::pageLayout() const
+{
+ Q_D(const QPrinter);
+ return d->printEngine->property(QPrintEngine::PPK_QPageLayout).value<QPageLayout>();
+}
+
+/*!
+ \obsolete Use pageLayout().pageOrientation() instead.
+
Returns the orientation setting. This is driver-dependent, but is usually
QPrinter::Portrait.
- \sa setOrientation()
+ \sa pageLayout()
*/
QPrinter::Orientation QPrinter::orientation() const
{
- Q_D(const QPrinter);
- return QPrinter::Orientation(d->printEngine->property(QPrintEngine::PPK_Orientation).toInt());
+ return QPrinter::Orientation(pageLayout().orientation());
}
/*!
+ \obsolete Use setPageOrientation() instead.
+
Sets the print orientation to \a orientation.
The orientation can be either QPrinter::Portrait or
@@ -941,32 +1117,34 @@ QPrinter::Orientation QPrinter::orientation() const
On Windows and Mac, this option can be changed while printing and will
take effect from the next call to newPage().
- \sa orientation()
+ \sa setPageOrientation()
*/
void QPrinter::setOrientation(Orientation orientation)
{
- Q_D(QPrinter);
- d->setProperty(QPrintEngine::PPK_Orientation, orientation);
+ setPageOrientation(QPageLayout::Orientation(orientation));
}
-
/*!
\since 4.4
+
+ \obsolete Use pageLayout().pageSize().id() instead.
+
Returns the printer paper size. The default value is driver-dependent.
- \sa setPaperSize(), pageRect(), paperRect()
+ \sa pageLayout()
*/
QPrinter::PaperSize QPrinter::paperSize() const
{
- Q_D(const QPrinter);
- return QPrinter::PaperSize(d->printEngine->property(QPrintEngine::PPK_PaperSize).toInt());
+ return pageSize();
}
/*!
\since 4.4
+ \obsolete Use setPageSize(QPageSize) instead.
+
Sets the printer paper size to \a newPaperSize if that size is
supported. The result is undefined if \a newPaperSize is not
supported.
@@ -976,108 +1154,103 @@ QPrinter::PaperSize QPrinter::paperSize() const
This function is useful mostly for setting a default value that
the user can override in the print dialog.
- \sa paperSize(), PaperSize, setFullPage(), setResolution(), pageRect(), paperRect()
+ \sa setPageSize()
*/
void QPrinter::setPaperSize(PaperSize newPaperSize)
{
- setPageSize(newPaperSize);
+ setPageSize(QPageSize(QPageSize::PageSizeId(newPaperSize)));
}
/*!
- \obsolete
+ \obsolete Use pageLayout().pageSize().id() instead.
Returns the printer page size. The default value is driver-dependent.
- Use paperSize() instead.
+ \sa pageLayout()
*/
QPrinter::PageSize QPrinter::pageSize() const
{
- return paperSize();
+ return QPrinter::PaperSize(pageLayout().pageSize().id());
}
/*!
- \obsolete
+ \obsolete Use setPageSize(QPageSize) instead.
Sets the printer page size based on \a newPageSize.
- Use setPaperSize() instead.
+ \sa setPageSize()
*/
void QPrinter::setPageSize(PageSize newPageSize)
{
- QPagedPaintDevice::setPageSize(newPageSize);
-
- Q_D(QPrinter);
- if (d->paintEngine->type() != QPaintEngine::Pdf)
- ABORT_IF_ACTIVE("QPrinter::setPaperSize");
- if (newPageSize < 0 || newPageSize >= NPageSize) {
- qWarning("QPrinter::setPaperSize: Illegal paper size %d", newPageSize);
- return;
- }
- d->setProperty(QPrintEngine::PPK_PaperSize, newPageSize);
- d->hasUserSetPageSize = true;
+ setPageSize(QPageSize(QPageSize::PageSizeId(newPageSize)));
}
/*!
\since 4.4
+ \obsolete Use setPageSize(QPageSize) instead.
+
Sets the paper size based on \a paperSize in \a unit.
- \sa paperSize()
+ Note that the paper size is defined in a portrait layout, regardless of
+ what the current printer orientation is set to.
+
+ \sa setPageSize()
*/
void QPrinter::setPaperSize(const QSizeF &paperSize, QPrinter::Unit unit)
{
- Q_D(QPrinter);
- if (d->paintEngine->type() != QPaintEngine::Pdf)
- ABORT_IF_ACTIVE("QPrinter::setPaperSize");
- setPageSizeMM(qt_SizeFromUnitToMillimeter(paperSize, unit, resolution()));
+ setPageSize(QPageSize(paperSize, QPageSize::Unit(unit)));
}
/*!
- \reimp
- */
-void QPrinter::setPageSizeMM(const QSizeF &size)
-{
- Q_D(QPrinter);
+ \reimp
- QPagedPaintDevice::setPageSizeMM(size);
+ \obsolete Use setPageSize(QPageSize) instead.
- QSizeF s = size * 72./25.4;
- d->setProperty(QPrintEngine::PPK_CustomPaperSize, s);
- d->hasUserSetPageSize = true;
+ Use setPageSize(QPageSize) instead.
+
+ Note that the page size is defined in a portrait layout, regardless of
+ what the current printer orientation is set to.
+
+ \sa setPageSize()
+*/
+void QPrinter::setPageSizeMM(const QSizeF &size)
+{
+ setPageSize(QPageSize(size, QPageSize::Millimeter));
}
/*!
\since 4.4
+ \obsolete Use pageLayout().pageSize().size() or
+ pageLayout().fullPageSize() instead.
+
Returns the paper size in \a unit.
- \sa setPaperSize()
+ Note that the returned size reflects the current paper orientation.
+
+ \sa pageLayout()
*/
QSizeF QPrinter::paperSize(Unit unit) const
{
- Q_D(const QPrinter);
- int res = resolution();
- const qreal multiplier = qt_multiplierForUnit(unit, res);
- PaperSize paperType = paperSize();
- if (paperType == Custom) {
- QSizeF size = d->printEngine->property(QPrintEngine::PPK_CustomPaperSize).toSizeF();
- return QSizeF(size.width() / multiplier, size.height() / multiplier);
- }
- else {
- return qt_printerPaperSize(orientation(), paperType, unit, res);
- }
+ if (unit == QPrinter::DevicePixel)
+ return pageLayout().fullRectPixels(resolution()).size();
+ else
+ return pageLayout().fullRect(QPageLayout::Unit(unit)).size();
}
/*!
\since 5.1
+ \obsolete Use setPageSize(QPageSize) instead.
+
Sets the paper used by the printer to \a paperName.
- \sa paperName()
+ \sa setPageSize()
*/
void QPrinter::setPaperName(const QString &paperName)
@@ -1091,9 +1264,13 @@ void QPrinter::setPaperName(const QString &paperName)
/*!
\since 5.1
+ \obsolete Use pageLayout().pageSize().name() instead.
+
Returns the paper name of the paper set on the printer.
The default value for this is driver-dependent.
+
+ \sa pageLayout()
*/
QString QPrinter::paperName() const
@@ -1338,13 +1515,16 @@ void QPrinter::setCollateCopies(bool collate)
printer's margins, so the application must account for the margins
itself.
- \sa fullPage(), setPaperSize(), width(), height()
+ \sa fullPage(), pageLayout(), setPageSize(), width(), height()
*/
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();
}
@@ -1355,7 +1535,7 @@ void QPrinter::setFullPage(bool fp)
See setFullPage() for details and caveats.
- \sa setFullPage(), PaperSize
+ \sa setFullPage(), pageLayout()
*/
bool QPrinter::fullPage() const
@@ -1535,19 +1715,10 @@ QPrinter::DuplexMode QPrinter::duplex() const
*/
QRectF QPrinter::pageRect(Unit unit) const
{
- Q_D(const QPrinter);
- int res = resolution();
- const qreal multiplier = qt_multiplierForUnit(unit, res);
- // the page rect is in device pixels
- QRect devRect(d->printEngine->property(QPrintEngine::PPK_PageRect).toRect());
- if (unit == DevicePixel)
- return devRect;
- QRectF diRect(devRect.x()*72.0/res,
- devRect.y()*72.0/res,
- devRect.width()*72.0/res,
- devRect.height()*72.0/res);
- return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
- diRect.width()/multiplier, diRect.height()/multiplier);
+ if (unit == QPrinter::DevicePixel)
+ return pageLayout().paintRectPixels(resolution());
+ else
+ return pageLayout().paintRect(QPageLayout::Unit(unit));
}
@@ -1561,29 +1732,22 @@ QRectF QPrinter::pageRect(Unit unit) const
*/
QRectF QPrinter::paperRect(Unit unit) const
{
- Q_D(const QPrinter);
- int res = resolution();
- const qreal multiplier = qt_multiplierForUnit(unit, resolution());
- // the page rect is in device pixels
- QRect devRect(d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect());
- if (unit == DevicePixel)
- return devRect;
- QRectF diRect(devRect.x()*72.0/res,
- devRect.y()*72.0/res,
- devRect.width()*72.0/res,
- devRect.height()*72.0/res);
- return QRectF(diRect.x()/multiplier, diRect.y()/multiplier,
- diRect.width()/multiplier, diRect.height()/multiplier);
+ if (unit == QPrinter::DevicePixel)
+ return pageLayout().fullRectPixels(resolution());
+ else
+ return pageLayout().fullRect(QPageLayout::Unit(unit));
}
/*!
+ \obsolete Use pageLayout().paintRect() instead.
+
Returns the page's rectangle; this is usually smaller than the
paperRect() since the page normally has margins between its
borders and the paper.
The unit of the returned rectangle is DevicePixel.
- \sa paperSize()
+ \sa pageLayout()
*/
QRect QPrinter::pageRect() const
{
@@ -1592,12 +1756,14 @@ QRect QPrinter::pageRect() const
}
/*!
+ \obsolete Use pageLayout().fullPageRect() instead.
+
Returns the paper's rectangle; this is usually larger than the
pageRect().
The unit of the returned rectangle is DevicePixel.
- \sa pageRect()
+ \sa pageLayout()
*/
QRect QPrinter::paperRect() const
{
@@ -1605,61 +1771,69 @@ QRect QPrinter::paperRect() const
return d->printEngine->property(QPrintEngine::PPK_PaperRect).toRect();
}
-
/*!
\since 4.4
+ \obsolete Use setPageMargins(QMarginsF, QPageLayout::Unit) instead.
+
This function sets the \a left, \a top, \a right and \a bottom
page margins for this printer. The unit of the margins are
specified with the \a unit parameter.
- \sa getPageMargins()
+ \sa setPageMargins()
*/
void QPrinter::setPageMargins(qreal left, qreal top, qreal right, qreal bottom, QPrinter::Unit unit)
{
- const qreal multiplier = qt_multiplierForUnit(unit, resolution()) * 25.4/72.;
- Margins m = { left*multiplier, right*multiplier, top*multiplier, bottom*multiplier };
- setMargins(m);
+ if (unit == QPrinter::DevicePixel) {
+ QMarginsF margins = QMarginsF(left, top, right, bottom);
+ margins *= qt_pixelMultiplier(resolution());
+ margins = qt_convertMargins(margins, QPageLayout::Point, pageLayout().units());
+ setPageMargins(margins, pageLayout().units());
+ } else {
+ setPageMargins(QMarginsF(left, top, right, bottom), QPageLayout::Unit(unit));
+ }
}
/*!
- \reimp
+ \reimp
+
+ \obsolete Use setPageMargins(QMarginsF, QPageLayout::Unit) instead.
+
+ \sa setPageMargins()
*/
void QPrinter::setMargins(const Margins &m)
{
- Q_D(QPrinter);
-
- // set margins also to super class
- QPagedPaintDevice::setMargins(m);
-
- const qreal multiplier = 72./25.4;
- QList<QVariant> margins;
- margins << (m.left * multiplier) << (m.top * multiplier)
- << (m.right * multiplier) << (m.bottom * multiplier);
- d->setProperty(QPrintEngine::PPK_PageMargins, margins);
- d->hasCustomPageMargins = true;
+ setPageMargins(QMarginsF(m.left, m.top, m.right, m.bottom), QPageLayout::Millimeter);
}
-
/*!
\since 4.4
+ \obsolete Use pageLayout().pageMargins() instead.
+
Returns the page margins for this printer in \a left, \a top, \a
right, \a bottom. The unit of the returned margins are specified
with the \a unit parameter.
- \sa setPageMargins()
+ \sa pageLayout(), setPageMargins()
*/
void QPrinter::getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, QPrinter::Unit unit) const
{
- Q_D(const QPrinter);
- Q_ASSERT(left && top && right && bottom);
- const qreal multiplier = qt_multiplierForUnit(unit, resolution());
- QList<QVariant> margins(d->printEngine->property(QPrintEngine::PPK_PageMargins).toList());
- *left = margins.at(0).toReal() / multiplier;
- *top = margins.at(1).toReal() / multiplier;
- *right = margins.at(2).toReal() / multiplier;
- *bottom = margins.at(3).toReal() / multiplier;
+ QMarginsF margins;
+ if (unit == QPrinter::DevicePixel) {
+ QMargins tmp = pageLayout().marginsPixels(resolution());
+ margins = QMarginsF(tmp.left(), tmp.top(), tmp.right(), tmp.bottom());
+ } else {
+ margins = pageLayout().margins(QPageLayout::Unit(unit));
+ }
+ if (left)
+ *left = margins.left();
+ if (right)
+ *right = margins.right();
+ if (top)
+ *top = margins.top();
+ if (bottom)
+ *bottom = margins.bottom();
}
/*!
@@ -1693,15 +1867,13 @@ QPrintEngine *QPrinter::printEngine() const
return d->printEngine;
}
-#if defined (Q_OS_WIN)
/*!
+ \obsolete Use QPageSize::id(windowsId) and setPageLayout(QPageSize) instead.
+
Sets the page size to be used by the printer under Windows to \a
pageSize.
- \warning This function is not portable so you may prefer to use
- setPaperSize() instead.
-
- \sa winPageSize()
+ \sa pageLayout()
*/
void QPrinter::setWinPageSize(int pageSize)
{
@@ -1711,19 +1883,17 @@ void QPrinter::setWinPageSize(int pageSize)
}
/*!
- Returns the page size used by the printer under Windows.
+ \obsolete Use pageLayout.pageSize().windowsId() instead.
- \warning This function is not portable so you may prefer to use
- paperSize() instead.
+ Returns the page size used by the printer under Windows.
- \sa setWinPageSize()
+ \sa pageLayout()
*/
int QPrinter::winPageSize() const
{
Q_D(const QPrinter);
return d->printEngine->property(QPrintEngine::PPK_WindowsPageSize).toInt();
}
-#endif // Q_OS_WIN
/*!
Returns a list of the resolutions (a list of dots-per-inch
@@ -2048,13 +2218,19 @@ QPrinter::PrintRange QPrinter::printRange() const
in the QPrinter::Point unit.
\value PPK_PageMargins A QList<QVariant> containing the left, top,
- right and bottom margin values.
+ right and bottom margin values in the QPrinter::Point unit.
\value PPK_CopyCount An integer specifying the number of copies to print.
\value PPK_SupportsMultipleCopies A boolean value indicating whether or not
the printer supports printing multiple copies in one job.
+ \value PPK_QPageSize Set the page size using a QPageSize object.
+
+ \value PPK_QPageMargins Set the page margins using a QPair of QMarginsF and QPageLayout::Unit.
+
+ \value PPK_QPageLayout Set the page layout using a QPageLayout object.
+
\value PPK_CustomBase Basis for extension.
*/
@@ -2106,37 +2282,6 @@ QPrinter::PrintRange QPrinter::printRange() const
Returns the current state of the printer being used by the print engine.
*/
-/*
- Returns the dimensions for the given paper size, \a size, in millimeters.
-*/
-QSizeF qt_paperSizeToQSizeF(QPrinter::PaperSize size)
-{
- if (size == QPrinter::Custom) return QSizeF(0, 0);
- return QSizeF(qt_paperSizes[size][0], qt_paperSizes[size][1]);
-}
-
-/*
- Returns the PaperSize type that matches \a size, where \a size
- is in millimeters.
-
- Because dimensions may not always be completely accurate (for
- example when converting between units), a particular PaperSize
- will be returned if it matches within -1/+1 millimeters.
-*/
-QPrinter::PaperSize qSizeFTopaperSize(const QSizeF& size)
-{
- for (int i = 0; i < static_cast<int>(QPrinter::NPageSize); ++i) {
- if (qt_paperSizes[i][0] >= size.width() - 1 &&
- qt_paperSizes[i][0] <= size.width() + 1 &&
- qt_paperSizes[i][1] >= size.height() - 1 &&
- qt_paperSizes[i][1] <= size.height() + 1) {
- return QPrinter::PaperSize(i);
- }
- }
-
- return QPrinter::Custom;
-}
-
QT_END_NAMESPACE
#endif // QT_NO_PRINTER
diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h
index 679f3af043..1f0639d81f 100644
--- a/src/printsupport/kernel/qprinter.h
+++ b/src/printsupport/kernel/qprinter.h
@@ -45,6 +45,7 @@
#include <QtCore/qstring.h>
#include <QtCore/qscopedpointer.h>
#include <QtGui/qpagedpaintdevice.h>
+#include <QtGui/qpagelayout.h>
#include <QtPrintSupport/qtprintsupportglobal.h>
QT_BEGIN_NAMESPACE
@@ -60,6 +61,8 @@ class QPrinterPrivate;
class QPaintEngine;
class QPrintEngine;
class QPrinterInfo;
+class QPageSize;
+class QPageMargins;
class Q_PRINTSUPPORT_EXPORT QPrinter : public QPagedPaintDevice
{
@@ -75,13 +78,161 @@ public:
enum Orientation { Portrait, Landscape };
+ // ### Qt6 Remove in favor of QPage::PageSize
+ // NOTE: Must keep in sync with QPageSize and QPagedPaintDevice
#ifndef Q_QDOC
typedef PageSize PaperSize;
#else
- enum PaperSize { A4, B5, Letter, Legal, Executive,
- A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
- B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
- DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom, NPaperSize = Custom };
+ enum PaperSize {
+ // Existing Qt sizes
+ A4,
+ B5,
+ Letter,
+ Legal,
+ Executive,
+ A0,
+ A1,
+ A2,
+ A3,
+ A5,
+ A6,
+ A7,
+ A8,
+ A9,
+ B0,
+ B1,
+ B10,
+ B2,
+ B3,
+ B4,
+ B6,
+ B7,
+ B8,
+ B9,
+ C5E,
+ Comm10E,
+ DLE,
+ Folio,
+ Ledger,
+ Tabloid,
+ Custom,
+
+ // New values derived from PPD standard
+ A10,
+ A3Extra,
+ A4Extra,
+ A4Plus,
+ A4Small,
+ A5Extra,
+ B5Extra,
+
+ JisB0,
+ JisB1,
+ JisB2,
+ JisB3,
+ JisB4,
+ JisB5,
+ JisB6,
+ JisB7,
+ JisB8,
+ JisB9,
+ JisB10,
+
+ // AnsiA = Letter,
+ // AnsiB = Ledger,
+ AnsiC,
+ AnsiD,
+ AnsiE,
+ LegalExtra,
+ LetterExtra,
+ LetterPlus,
+ LetterSmall,
+ TabloidExtra,
+
+ ArchA,
+ ArchB,
+ ArchC,
+ ArchD,
+ ArchE,
+
+ Imperial7x9,
+ Imperial8x10,
+ Imperial9x11,
+ Imperial9x12,
+ Imperial10x11,
+ Imperial10x13,
+ Imperial10x14,
+ Imperial12x11,
+ Imperial15x11,
+
+ ExecutiveStandard,
+ Note,
+ Quarto,
+ Statement,
+ SuperA,
+ SuperB,
+ Postcard,
+ DoublePostcard,
+ Prc16K,
+ Prc32K,
+ Prc32KBig,
+
+ FanFoldUS,
+ FanFoldGerman,
+ FanFoldGermanLegal,
+
+ EnvelopeB4,
+ EnvelopeB5,
+ EnvelopeB6,
+ EnvelopeC0,
+ EnvelopeC1,
+ EnvelopeC2,
+ EnvelopeC3,
+ EnvelopeC4,
+ // EnvelopeC5 = C5E,
+ EnvelopeC6,
+ EnvelopeC65,
+ EnvelopeC7,
+ // EnvelopeDL = DLE,
+
+ Envelope9,
+ // Envelope10 = Comm10E,
+ Envelope11,
+ Envelope12,
+ Envelope14,
+ EnvelopeMonarch,
+ EnvelopePersonal,
+
+ EnvelopeChou3,
+ EnvelopeChou4,
+ EnvelopeInvite,
+ EnvelopeItalian,
+ EnvelopeKaku2,
+ EnvelopeKaku3,
+ EnvelopePrc1,
+ EnvelopePrc2,
+ EnvelopePrc3,
+ EnvelopePrc4,
+ EnvelopePrc5,
+ EnvelopePrc6,
+ EnvelopePrc7,
+ EnvelopePrc8,
+ EnvelopePrc9,
+ EnvelopePrc10,
+ EnvelopeYou4,
+
+ // Last item, with commonly used synynoms from QPagedPrintEngine / QPrinter
+ LastPageSize = EnvelopeYou4,
+ NPageSize = LastPageSize,
+ NPaperSize = LastPageSize,
+
+ // Convenience overloads for naming consistency
+ AnsiA = Letter,
+ AnsiB = Ledger,
+ EnvelopeC5 = C5E,
+ EnvelopeDL = DLE,
+ Envelope10 = Comm10E
+ };
#endif
enum PageOrder { FirstPageFirst,
@@ -156,6 +307,12 @@ public:
void setCreator(const QString &);
QString creator() const;
+ bool setPageLayout(const QPageLayout &pageLayout);
+ bool setPageSize(const QPageSize &pageSize);
+ bool setPageOrientation(QPageLayout::Orientation orientation);
+ bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units);
+ QPageLayout pageLayout() const;
+
void setOrientation(Orientation);
Orientation orientation() const;
@@ -215,10 +372,8 @@ public:
void setDoubleSidedPrinting(bool enable);
bool doubleSidedPrinting() const;
-#ifdef Q_OS_WIN
void setWinPageSize(int winPageSize);
int winPageSize() const;
-#endif
QRect paperRect() const;
QRect pageRect() const;
diff --git a/src/printsupport/kernel/qprinter_p.h b/src/printsupport/kernel/qprinter_p.h
index 2357b9e944..ddc2dad413 100644
--- a/src/printsupport/kernel/qprinter_p.h
+++ b/src/printsupport/kernel/qprinter_p.h
@@ -87,9 +87,7 @@ public:
q_ptr(printer),
printRange(QPrinter::AllPages),
use_default_engine(true),
- validPrinter(false),
- hasCustomPageMargins(false),
- hasUserSetPageSize(false)
+ validPrinter(false)
{
}
@@ -129,7 +127,6 @@ public:
uint validPrinter : 1;
uint hasCustomPageMargins : 1;
- uint hasUserSetPageSize : 1;
// Used to remember which properties have been manually set by the user.
QSet<QPrintEngine::PrintEnginePropertyKey> m_properties;
diff --git a/src/printsupport/kernel/qprinterinfo.cpp b/src/printsupport/kernel/qprinterinfo.cpp
index e02617fe93..b1321bf57a 100644
--- a/src/printsupport/kernel/qprinterinfo.cpp
+++ b/src/printsupport/kernel/qprinterinfo.cpp
@@ -27,6 +27,7 @@
#include "qprinterinfo.h"
#include "qprinterinfo_p.h"
+#include "qprintdevice_p.h"
#ifndef QT_NO_PRINTER
@@ -47,6 +48,19 @@ public:
}
};
+QPrinterInfoPrivate::QPrinterInfoPrivate(const QString &id)
+{
+ if (!id.isEmpty()) {
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps)
+ m_printDevice = ps->createPrintDevice(id);
+ }
+}
+
+QPrinterInfoPrivate::~QPrinterInfoPrivate()
+{
+}
+
/*!
\class QPrinterInfo
@@ -65,28 +79,6 @@ public:
*/
/*!
- \fn QList<QPrinterInfo> QPrinterInfo::availablePrinters()
-
- Returns a list of available printers on the system.
-*/
-
-/*!
- \fn QPrinterInfo QPrinterInfo::defaultPrinter()
-
- Returns the default printer on the system.
-
- The return value should be checked using isNull() before being
- used, in case there is no default printer.
-
- On some systems it is possible for there to be available printers
- but none of them set to be the default printer.
-
- \sa isNull()
- \sa isDefault()
- \sa availablePrinters()
-*/
-
-/*!
Constructs an empty QPrinterInfo object.
\sa isNull()
@@ -112,7 +104,7 @@ QPrinterInfo::QPrinterInfo(const QPrinter &printer)
{
QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
if (ps) {
- QPrinterInfo pi = ps->printerInfo(printer.printerName());
+ QPrinterInfo pi(printer.printerName());
if (pi.d_ptr.data() == shared_null)
d_ptr.reset(shared_null);
else
@@ -160,7 +152,7 @@ QPrinterInfo &QPrinterInfo::operator=(const QPrinterInfo &other)
QString QPrinterInfo::printerName() const
{
const Q_D(QPrinterInfo);
- return d->name;
+ return d->m_printDevice.id();
}
/*!
@@ -172,7 +164,7 @@ QString QPrinterInfo::printerName() const
QString QPrinterInfo::description() const
{
const Q_D(QPrinterInfo);
- return d->description;
+ return d->m_printDevice.name();
}
/*!
@@ -183,7 +175,7 @@ QString QPrinterInfo::description() const
QString QPrinterInfo::location() const
{
const Q_D(QPrinterInfo);
- return d->location;
+ return d->m_printDevice.location();
}
/*!
@@ -194,7 +186,7 @@ QString QPrinterInfo::location() const
QString QPrinterInfo::makeAndModel() const
{
const Q_D(QPrinterInfo);
- return d->makeAndModel;
+ return d->m_printDevice.makeAndModel();
}
/*!
@@ -206,23 +198,114 @@ QString QPrinterInfo::makeAndModel() const
bool QPrinterInfo::isNull() const
{
Q_D(const QPrinterInfo);
- return d == shared_null || d->name.isEmpty();
+ return d == shared_null || !d->m_printDevice.isValid();
}
/*!
- Returns whether this printer is the default printer.
+ Returns whether this printer is currently the default printer.
*/
bool QPrinterInfo::isDefault() const
{
Q_D(const QPrinterInfo);
- return d->isDefault;
+ return d->m_printDevice.isDefault();
+}
+
+/*!
+ Returns whether this printer is a remote network printer.
+
+ \since 5.3
+*/
+bool QPrinterInfo::isRemote() const
+{
+ Q_D(const QPrinterInfo);
+ return d->m_printDevice.isRemote();
+}
+
+/*!
+ Returns the current state of this printer.
+
+ This state may not always be accurate, depending on the platform, printer
+ driver, or printer itself.
+
+ \since 5.3
+*/
+QPrinter::PrinterState QPrinterInfo::state() const
+{
+ Q_D(const QPrinterInfo);
+ return QPrinter::PrinterState(d->m_printDevice.state());
+}
+
+/*!
+ Returns a list of Page Sizes supported by this printer.
+
+ \since 5.3
+*/
+
+QList<QPageSize> QPrinterInfo::supportedPageSizes() const
+{
+ Q_D(const QPrinterInfo);
+ return d->m_printDevice.supportedPageSizes();
+}
+
+/*!
+ Returns the current default Page Size for this printer.
+
+ \since 5.3
+*/
+
+QPageSize QPrinterInfo::defaultPageSize() const
+{
+ Q_D(const QPrinterInfo);
+ return d->m_printDevice.defaultPageSize();
+}
+
+/*!
+ Returns whether this printer supports custom page sizes.
+
+ \since 5.3
+*/
+
+bool QPrinterInfo::supportsCustomPageSizes() const
+{
+ Q_D(const QPrinterInfo);
+ return d->m_printDevice.supportsCustomPageSizes();
}
/*!
+ Returns the minimum physical page size supported by this printer.
+
+ \sa maximumPhysicalPageSize()
+
+ \since 5.3
+*/
+
+QPageSize QPrinterInfo::minimumPhysicalPageSize() const
+{
+ Q_D(const QPrinterInfo);
+ return QPageSize(d->m_printDevice.minimumPhysicalPageSize(), QString(), QPageSize::ExactMatch);
+}
+
+/*!
+ Returns the maximum physical page size supported by this printer.
+
+ \sa minimumPhysicalPageSize()
+
+ \since 5.3
+*/
+
+QPageSize QPrinterInfo::maximumPhysicalPageSize() const
+{
+ Q_D(const QPrinterInfo);
+ return QPageSize(d->m_printDevice.maximumPhysicalPageSize(), QString(), QPageSize::ExactMatch);
+}
+
+#if QT_DEPRECATED_SINCE(5,3)
+/*!
+ \obsolete Use supportedPageSizes() instead.
+
Returns a list of supported paper sizes by the printer.
Not all printer drivers support this query, so the list may be empty.
- On Mac OS X 10.3, this function always returns an empty list.
\since 4.4
*/
@@ -230,14 +313,15 @@ bool QPrinterInfo::isDefault() const
QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
{
Q_D(const QPrinterInfo);
- if (!isNull() && !d->hasPaperSizes) {
- d->paperSizes = QPlatformPrinterSupportPlugin::get()->supportedPaperSizes(*this);
- d->hasPaperSizes = true;
- }
- return d->paperSizes;
+ QList<QPrinter::PaperSize> list;
+ foreach (const QPageSize &pageSize, d->m_printDevice.supportedPageSizes())
+ list.append(QPrinter::PaperSize(pageSize.id()));
+ return list;
}
/*!
+ \obsolete Use supportedPageSizes() instead.
+
Returns a list of all the paper names supported by the driver with the
corresponding size in millimeters.
@@ -249,27 +333,99 @@ QList<QPrinter::PaperSize> QPrinterInfo::supportedPaperSizes() const
QList<QPair<QString, QSizeF> > QPrinterInfo::supportedSizesWithNames() const
{
Q_D(const QPrinterInfo);
- if (!isNull() && !d->hasPaperNames) {
- d->paperNames = QPlatformPrinterSupportPlugin::get()->supportedSizesWithNames(*this);
- d->hasPaperNames = true;
- }
- return d->paperNames;
+ QList<QPair<QString, QSizeF> > list;
+ foreach (const QPageSize &pageSize, d->m_printDevice.supportedPageSizes())
+ list.append(qMakePair(pageSize.name(), pageSize.size(QPageSize::Millimeter)));
+ return list;
+}
+#endif // QT_DEPRECATED_SINCE(5,3)
+
+/*!
+ Returns a list of resolutions supported by this printer.
+
+ \since 5.3
+*/
+
+QList<int> QPrinterInfo::supportedResolutions() const
+{
+ Q_D(const QPrinterInfo);
+ return d->m_printDevice.supportedResolutions();
}
+/*!
+ Returns a list of all the available Printer Names on this system.
+
+ It is recommended to use this instead of availablePrinters() as
+ it will be faster on most systems.
+
+ Note that the list may become outdated if changes are made on the local
+ system or remote print server. Only instantiate required QPrinterInfo
+ instances when needed, and always check for validity before calling.
+
+ \since 5.3
+*/
+QStringList QPrinterInfo::availablePrinterNames()
+{
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps)
+ return ps->availablePrintDeviceIds();
+ return QStringList();
+}
+
+/*!
+ Returns a list of QPrinterInfo objects for all the available printers
+ on this system.
+
+ It is NOT recommended to use this as creating each printer instance may
+ take a long time, especially if there are remote networked printers, and
+ retained instances may become outdated if changes are made on the local
+ system or remote print server. Use availablePrinterNames() instead and
+ only instantiate printer instances as you need them.
+*/
QList<QPrinterInfo> QPrinterInfo::availablePrinters()
{
+ QList<QPrinterInfo> list;
+ QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
+ if (ps) {
+ foreach (const QString &id, ps->availablePrintDeviceIds())
+ list.append(QPrinterInfo(id));
+ }
+ return list;
+}
+
+/*!
+ Returns the current default printer name.
+
+ \since 5.3
+*/
+QString QPrinterInfo::defaultPrinterName()
+{
QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
- if (!ps)
- return QList<QPrinterInfo>();
- return ps->availablePrinters();
+ if (ps)
+ return ps->defaultPrintDeviceId();
+ return QString();
}
+/*!
+ Returns the default printer on the system.
+
+ The return value should be checked using isNull() before being
+ used, in case there is no default printer.
+
+ On some systems it is possible for there to be available printers
+ but none of them set to be the default printer.
+
+ \sa isNull()
+ \sa isDefault()
+ \sa availablePrinters()
+*/
+
QPrinterInfo QPrinterInfo::defaultPrinter()
{
QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
- if (!ps)
- return QPrinterInfo();
- return ps->defaultPrinter();
+ if (ps)
+ return QPrinterInfo(ps->defaultPrintDeviceId());
+ return QPrinterInfo();
}
/*!
@@ -283,10 +439,7 @@ QPrinterInfo QPrinterInfo::defaultPrinter()
*/
QPrinterInfo QPrinterInfo::printerInfo(const QString &printerName)
{
- QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
- if (!ps)
- return QPrinterInfo();
- return ps->printerInfo(printerName);
+ return QPrinterInfo(printerName);
}
QT_END_NAMESPACE
diff --git a/src/printsupport/kernel/qprinterinfo.h b/src/printsupport/kernel/qprinterinfo.h
index 0dc19c1da7..73ec48dfe7 100644
--- a/src/printsupport/kernel/qprinterinfo.h
+++ b/src/printsupport/kernel/qprinterinfo.h
@@ -42,9 +42,11 @@
#ifndef QPRINTERINFO_H
#define QPRINTERINFO_H
+#include <QtPrintSupport/qprinter.h>
+
#include <QtCore/QList>
#include <QtCore/QPair>
-#include <QtPrintSupport/QPrinter>
+#include <QtGui/qpagesize.h>
QT_BEGIN_NAMESPACE
@@ -69,12 +71,31 @@ public:
bool isNull() const;
bool isDefault() const;
+ bool isRemote() const;
+
+ QPrinter::PrinterState state() const;
+
+ QList<QPageSize> supportedPageSizes() const;
+ QPageSize defaultPageSize() const;
+
+ bool supportsCustomPageSizes() const;
- QList<QPrinter::PaperSize> supportedPaperSizes() const;
- QList<QPair<QString, QSizeF> > supportedSizesWithNames() const;
+ QPageSize minimumPhysicalPageSize() const;
+ QPageSize maximumPhysicalPageSize() const;
+#if QT_DEPRECATED_SINCE(5,3)
+ QT_DEPRECATED QList<QPrinter::PaperSize> supportedPaperSizes() const;
+ QT_DEPRECATED QList<QPair<QString, QSizeF> > supportedSizesWithNames() const;
+#endif // QT_DEPRECATED_SINCE(5,3)
+
+ QList<int> supportedResolutions() const;
+
+ static QStringList availablePrinterNames();
static QList<QPrinterInfo> availablePrinters();
+
+ static QString defaultPrinterName();
static QPrinterInfo defaultPrinter();
+
static QPrinterInfo printerInfo(const QString &printerName);
private:
diff --git a/src/printsupport/kernel/qprinterinfo_p.h b/src/printsupport/kernel/qprinterinfo_p.h
index 6ae64b5653..7083356e1c 100644
--- a/src/printsupport/kernel/qprinterinfo_p.h
+++ b/src/printsupport/kernel/qprinterinfo_p.h
@@ -57,32 +57,17 @@
#ifndef QT_NO_PRINTER
-#include "QtCore/qlist.h"
-#include "QtCore/qpair.h"
+#include "qprintdevice_p.h"
QT_BEGIN_NAMESPACE
class QPrinterInfoPrivate
{
public:
- QPrinterInfoPrivate(const QString& name = QString()) :
- name(name), isDefault(false), index(-1), hasPaperSizes(false),
- hasPaperNames(false)
- {}
- ~QPrinterInfoPrivate()
- {}
+ QPrinterInfoPrivate(const QString& id = QString());
+ ~QPrinterInfoPrivate();
- QString name;
- QString description;
- QString location;
- QString makeAndModel;
- bool isDefault;
- int index; // Internal printer plugin use only
-
- mutable bool hasPaperSizes;
- mutable QList<QPrinter::PaperSize> paperSizes;
- mutable bool hasPaperNames;
- mutable QList<QPair<QString, QSizeF> > paperNames;
+ QPrintDevice m_printDevice;
};
QT_END_NAMESPACE
diff --git a/src/printsupport/widgets/qcupsjobwidget.cpp b/src/printsupport/widgets/qcupsjobwidget.cpp
index 9940e6a1af..7fd3e0105d 100644
--- a/src/printsupport/widgets/qcupsjobwidget.cpp
+++ b/src/printsupport/widgets/qcupsjobwidget.cpp
@@ -56,6 +56,8 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_PRINTER
+
/*!
\internal
\class QCupsJobWidget
@@ -212,4 +214,6 @@ QCUPSSupport::BannerPage QCupsJobWidget::endBannerPage() const
return m_ui.endBannerPageCombo->itemData(m_ui.endBannerPageCombo->currentIndex()).value<QCUPSSupport::BannerPage>();
}
+#endif // QT_NO_PRINTER
+
QT_END_NAMESPACE
diff --git a/src/printsupport/widgets/qcupsjobwidget_p.h b/src/printsupport/widgets/qcupsjobwidget_p.h
index a5e2bf8083..2a50a12b89 100644
--- a/src/printsupport/widgets/qcupsjobwidget_p.h
+++ b/src/printsupport/widgets/qcupsjobwidget_p.h
@@ -60,6 +60,8 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_PRINTER
+
class QString;
class QTime;
class QPrinter;
@@ -106,6 +108,8 @@ private:
Q_DISABLE_COPY(QCupsJobWidget)
};
+#endif // QT_NO_PRINTER
+
QT_END_NAMESPACE
#endif // QCUPSJOBWIDGET_P_H
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index fe5a3cd23a..d50078b5ff 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -1490,27 +1490,22 @@ bool QIBaseDriver::open(const QString & db,
pass.truncate(255);
QByteArray ba;
- ba.resize(usr.length() + pass.length() + enc.length() + role.length() + 6);
- int i = -1;
- ba[++i] = isc_dpb_version1;
- ba[++i] = isc_dpb_user_name;
- ba[++i] = usr.length();
- memcpy(ba.data() + ++i, usr.data(), usr.length());
- i += usr.length();
- ba[i] = isc_dpb_password;
- ba[++i] = pass.length();
- memcpy(ba.data() + ++i, pass.data(), pass.length());
- i += pass.length();
- ba[i] = isc_dpb_lc_ctype;
- ba[++i] = enc.length();
- memcpy(ba.data() + ++i, enc.data(), enc.length());
- i += enc.length();
+ ba.reserve(usr.length() + pass.length() + enc.length() + role.length() + 9);
+ ba.append(char(isc_dpb_version1));
+ ba.append(char(isc_dpb_user_name));
+ ba.append(char(usr.length()));
+ ba.append(usr.data(), usr.length());
+ ba.append(char(isc_dpb_password));
+ ba.append(char(pass.length()));
+ ba.append(pass.data(), pass.length());
+ ba.append(char(isc_dpb_lc_ctype));
+ ba.append(char(enc.length()));
+ ba.append(enc.data(), enc.length());
if (!role.isEmpty()) {
- ba[i] = isc_dpb_sql_role_name;
- ba[++i] = role.length();
- memcpy(ba.data() + ++i, role.data(), role.length());
- i += role.length();
+ ba.append(char(isc_dpb_sql_role_name));
+ ba.append(char(role.length()));
+ ba.append(role.data(), role.length());
}
QString portString;
@@ -1522,7 +1517,7 @@ bool QIBaseDriver::open(const QString & db,
ldb += host + portString + QLatin1Char(':');
ldb += db;
isc_attach_database(d->status, 0, const_cast<char *>(ldb.toLocal8Bit().constData()),
- &d->ibase, i, ba.data());
+ &d->ibase, ba.size(), ba.data());
if (d->isError(QT_TRANSLATE_NOOP("QIBaseDriver", "Error opening database"),
QSqlError::ConnectionError)) {
setOpenError(true);
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index 31b05ab9e9..6959dc39f7 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -64,15 +64,20 @@ QString QSqlResultPrivate::holderAt(int index) const
// return a unique id for bound names
QString QSqlResultPrivate::fieldSerial(int i) const
{
- ushort arr[] = { ':', 'f', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
- ushort *ptr = &arr[1];
+ ushort arr[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ ushort *end = &arr[(sizeof(arr)/sizeof(*arr))];
+ ushort *ptr = end;
while (i > 0) {
- *(++ptr) = 'a' + i % 16;
+ *(--ptr) = 'a' + i % 16;
i >>= 4;
}
- return QString(reinterpret_cast<const QChar *>(arr), int(ptr - arr) + 1);
+ const int nb = end - ptr;
+ *(--ptr) = 'a' + nb;
+ *(--ptr) = ':';
+
+ return QString::fromUtf16(ptr, int(end - ptr));
}
static bool qIsAlnum(QChar ch)
diff --git a/src/src.pro b/src/src.pro
index 114ee5e424..0d854a85c1 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -80,6 +80,9 @@ src_testlib.subdir = $$PWD/testlib
src_testlib.target = sub-testlib
src_testlib.depends = src_corelib # src_gui & src_widgets are not build-depends
+src_3rdparty_harfbuzzng.subdir = $$PWD/3rdparty/harfbuzz-ng
+src_3rdparty_harfbuzzng.target = sub-3rdparty-harfbuzzng
+
src_angle.subdir = $$PWD/angle
src_angle.target = sub-angle
angle_d3d11: src_angle.depends = src_corelib
@@ -130,6 +133,10 @@ contains(QT_CONFIG, dbus) {
}
contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
!contains(QT_CONFIG, no-gui) {
+ contains(QT_CONFIG, harfbuzz) {
+ SUBDIRS += src_3rdparty_harfbuzzng
+ src_gui.depends += src_3rdparty_harfbuzzng
+ }
win32:contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) {
SUBDIRS += src_angle
src_gui.depends += src_angle
@@ -141,7 +148,7 @@ contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
SUBDIRS += src_tools_uic src_widgets
TOOLS += src_tools_uic
src_plugins.depends += src_widgets
- contains(QT_CONFIG, opengl(es1|es2)?) {
+ contains(QT_CONFIG, opengl(es1|es2)?):!contains(QT_CONFIG, dynamicgl) {
SUBDIRS += src_opengl
src_plugins.depends += src_opengl
}
@@ -159,7 +166,8 @@ android:!android-no-sdk: SUBDIRS += src_android
TR_EXCLUDE = \
src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic src_tools_qlalr \
- src_tools_bootstrap_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml
+ src_tools_bootstrap_dbus src_tools_qdbusxml2cpp src_tools_qdbuscpp2xml \
+ src_3rdparty_harfbuzzng
sub-tools.depends = $$TOOLS
QMAKE_EXTRA_TARGETS = sub-tools
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 10bf200f4f..7b225ef5b4 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -2863,6 +2863,8 @@ bool QTest::currentTestFailed()
void QTest::qSleep(int ms)
{
QTEST_ASSERT(ms > 0);
+ QElapsedTimer timer;
+ timer.start();
#if defined(Q_OS_WINRT)
WaitForSingleObjectEx(GetCurrentThread(), ms, true);
@@ -2872,6 +2874,15 @@ void QTest::qSleep(int ms)
struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
nanosleep(&ts, NULL);
#endif
+ // Warn if the elapsed time was more than 50% longer or more than 10% shorter than the
+ // requested time.
+ qint64 requested = 1000000 * (qint64)ms;
+ qint64 diff = timer.nsecsElapsed() - requested;
+ if (diff * 2 > requested || diff * 10 < -requested) {
+ QTestLog::warn(qPrintable(
+ QString::fromLatin1("QTest::qSleep() should have taken %1ns, but actually took %2ns!")
+ .arg(requested).arg(diff + requested)), __FILE__, __LINE__);
+ }
}
/*! \internal
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp
index fa976ea94d..b1f47e3096 100644
--- a/src/widgets/accessible/qaccessiblewidgets.cpp
+++ b/src/widgets/accessible/qaccessiblewidgets.cpp
@@ -143,6 +143,8 @@ void *QAccessiblePlainTextEdit::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::TextInterface)
return static_cast<QAccessibleTextInterface*>(this);
+ else if (t == QAccessible::EditableTextInterface)
+ return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
}
@@ -267,6 +269,8 @@ void *QAccessibleTextEdit::interface_cast(QAccessible::InterfaceType t)
{
if (t == QAccessible::TextInterface)
return static_cast<QAccessibleTextInterface*>(this);
+ else if (t == QAccessible::EditableTextInterface)
+ return static_cast<QAccessibleEditableTextInterface*>(this);
return QAccessibleWidget::interface_cast(t);
}
@@ -829,7 +833,7 @@ QString QAccessibleTextWidget::text(int startOffset, int endOffset) const
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
- return cursor.selectedText();
+ return cursor.selectedText().replace(QChar(QChar::ParagraphSeparator), QLatin1Char('\n'));
}
QPoint QAccessibleTextWidget::scrollBarPosition() const
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 3e4490e890..80e8d152ff 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -79,35 +79,6 @@ QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QString, lastVisitedDir)
-/*
- \internal
-
- Exported hooks that can be used to customize the static functions.
- */
-typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
-Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook = 0;
-
-typedef QUrl (*_qt_filedialog_existing_directory_url_hook)(QWidget *parent, const QString &caption, const QUrl &dir, QFileDialog::Options options, const QStringList &supportedSchemes);
-Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_url_hook qt_filedialog_existing_directory_url_hook = 0;
-
-typedef QString (*_qt_filedialog_open_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-Q_WIDGETS_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook = 0;
-
-typedef QUrl (*_qt_filedialog_open_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
-Q_WIDGETS_EXPORT _qt_filedialog_open_file_url_hook qt_filedialog_open_file_url_hook = 0;
-
-typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-Q_WIDGETS_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook = 0;
-
-typedef QList<QUrl> (*_qt_filedialog_open_file_urls_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
-Q_WIDGETS_EXPORT _qt_filedialog_open_file_urls_hook qt_filedialog_open_file_urls_hook = 0;
-
-typedef QString (*_qt_filedialog_save_filename_hook)(QWidget * parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook = 0;
-
-typedef QUrl (*_qt_filedialog_save_file_url_hook)(QWidget * parent, const QString &caption, const QUrl &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options, const QStringList &supportedSchemes);
-Q_WIDGETS_EXPORT _qt_filedialog_save_file_url_hook qt_filedialog_save_file_url_hook = 0;
-
/*!
\class QFileDialog
\brief The QFileDialog class provides a dialog that allow users to select files or directories.
@@ -1342,13 +1313,13 @@ QStringList qt_make_filter_list(const QString &filter)
Sets the filter used in the file dialog to the given \a filter.
If \a filter contains a pair of parentheses containing one or more
- of \b{anything*something}, separated by spaces, then only the
+ filename-wildcard patterns, separated by spaces, then only the
text contained in the parentheses is used as the filter. This means
that these calls are all equivalent:
\snippet code/src_gui_dialogs_qfiledialog.cpp 6
- \sa setNameFilters()
+ \sa setMimeTypeFilters(), setNameFilters()
*/
void QFileDialog::setNameFilter(const QString &filter)
{
@@ -1402,7 +1373,19 @@ QStringList qt_strip_filters(const QStringList &filters)
Sets the \a filters used in the file dialog.
+ Note that the filter \b{*.*} is not portable, because the historical
+ assumption that the file extension determines the file type is not
+ consistent on every operating system. It is possible to have a file with no
+ dot in its name (for example, \c Makefile). In a native Windows file
+ dialog, \b{*.*} will match such files, while in other types of file dialogs
+ it may not. So it is better to use \b{*} if you mean to select any file.
+
\snippet code/src_gui_dialogs_qfiledialog.cpp 7
+
+ \l setMimeTypeFilters() has the advantage of providing all possible name
+ filters for each file type. For example, JPEG images have three possible
+ extensions; if your application can open such files, selecting the
+ \c image/jpeg mime type as a filter will allow you to open all of them.
*/
void QFileDialog::setNameFilters(const QStringList &filters)
{
@@ -2099,8 +2082,6 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
QString *selectedFilter,
Options options)
{
- if (qt_filedialog_open_filename_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_open_filename_hook(parent, caption, dir, filter, selectedFilter, options);
QFileDialogArgs args;
args.parent = parent;
args.caption = caption;
@@ -2162,8 +2143,7 @@ QUrl QFileDialog::getOpenFileUrl(QWidget *parent,
Options options,
const QStringList &supportedSchemes)
{
- if (qt_filedialog_open_file_url_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_open_file_url_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+ Q_UNUSED(supportedSchemes);
// Falls back to local file
return QUrl::fromLocalFile(getOpenFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
@@ -2225,8 +2205,6 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
QString *selectedFilter,
Options options)
{
- if (qt_filedialog_open_filenames_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_open_filenames_hook(parent, caption, dir, filter, selectedFilter, options);
QFileDialogArgs args;
args.parent = parent;
args.caption = caption;
@@ -2290,8 +2268,7 @@ QList<QUrl> QFileDialog::getOpenFileUrls(QWidget *parent,
Options options,
const QStringList &supportedSchemes)
{
- if (qt_filedialog_open_file_urls_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_open_file_urls_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+ Q_UNUSED(supportedSchemes);
// Falls back to local files
QList<QUrl> urls;
@@ -2360,8 +2337,6 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
QString *selectedFilter,
Options options)
{
- if (qt_filedialog_save_filename_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_save_filename_hook(parent, caption, dir, filter, selectedFilter, options);
QFileDialogArgs args;
args.parent = parent;
args.caption = caption;
@@ -2426,8 +2401,7 @@ QUrl QFileDialog::getSaveFileUrl(QWidget *parent,
Options options,
const QStringList &supportedSchemes)
{
- if (qt_filedialog_save_file_url_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_save_file_url_hook(parent, caption, dir, filter, selectedFilter, options, supportedSchemes);
+ Q_UNUSED(supportedSchemes);
// Falls back to local file
return QUrl::fromLocalFile(getSaveFileName(parent, caption, dir.toLocalFile(), filter, selectedFilter, options));
@@ -2477,8 +2451,6 @@ QString QFileDialog::getExistingDirectory(QWidget *parent,
const QString &dir,
Options options)
{
- if (qt_filedialog_existing_directory_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_existing_directory_hook(parent, caption, dir, options);
QFileDialogArgs args;
args.parent = parent;
args.caption = caption;
@@ -2537,8 +2509,7 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
Options options,
const QStringList &supportedSchemes)
{
- if (qt_filedialog_existing_directory_url_hook && !(options & DontUseNativeDialog))
- return qt_filedialog_existing_directory_url_hook(parent, caption, dir, options, supportedSchemes);
+ Q_UNUSED(supportedSchemes);
// Falls back to local file
return QUrl::fromLocalFile(getExistingDirectory(parent, caption, dir.toLocalFile(), options));
@@ -3904,13 +3875,8 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e)
int key = e->key();
QLineEdit::keyPressEvent(e);
- if (key != Qt::Key_Escape)
+ if (key != Qt::Key_Escape && key != Qt::Key_Back)
e->accept();
- if (hideOnEsc && (key == Qt::Key_Escape || key == Qt::Key_Return || key == Qt::Key_Enter)) {
- e->accept();
- hide();
- d_ptr->currentView()->setFocus(Qt::ShortcutFocusReason);
- }
}
#ifndef QT_NO_FSCOMPLETER
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index faa721572c..632bbca5a4 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -286,7 +286,7 @@ private:
class QFileDialogLineEdit : public QLineEdit
{
public:
- QFileDialogLineEdit(QWidget *parent = 0) : QLineEdit(parent), hideOnEsc(false), d_ptr(0){}
+ QFileDialogLineEdit(QWidget *parent = 0) : QLineEdit(parent), d_ptr(0){}
void setFileDialogPrivate(QFileDialogPrivate *d_pointer) {d_ptr = d_pointer; }
void keyPressEvent(QKeyEvent *e);
bool hideOnEsc;
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 207fe3d527..dcddc693c8 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -1912,7 +1912,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title)
"to comply with the terms of the GNU GPL version 3.0.</p>"
"<p>Please see <a href=\"http://qt.digia.com/Product/Licensing/\">qt.digia.com/Product/Licensing</a> "
"for an overview of Qt licensing.</p>"
- "<p>Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) and other "
+ "<p>Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies) and other "
"contributors.</p>"
"<p>Qt and the Qt logo are trademarks of Digia Plc and/or its subsidiary(-ies).</p>"
"<p>Qt is developed as an open source project on "
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index ae2423400a..d4edc63403 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -472,7 +472,7 @@
notification).
\value ItemTransformChange The item's transformation matrix changes. This
- notification is send if the ItemSendsGeometryChanges flag is enabled, and
+ notification is sent if the ItemSendsGeometryChanges flag is enabled, and
when the item's local transformation matrix changes (i.e., as a result of
calling setTransform(). The value argument is the new matrix (i.e., a
QTransform); to get the old matrix, call transform(). Do not call
@@ -6604,7 +6604,7 @@ void QGraphicsItem::removeSceneEventFilter(QGraphicsItem *filterItem)
Reimplementing this function in a subclass makes it possible
for the item to be used as an event filter for other items,
- intercepting all the events send to those items before they are
+ intercepting all the events sent to those items before they are
able to respond.
Reimplementations must return true to prevent further processing of
@@ -9592,9 +9592,9 @@ QRectF QGraphicsPixmapItem::boundingRect() const
return QRectF();
if (d->flags & ItemIsSelectable) {
qreal pw = 1.0;
- return QRectF(d->offset, d->pixmap.size()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
+ return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio()).adjusted(-pw/2, -pw/2, pw/2, pw/2);
} else {
- return QRectF(d->offset, d->pixmap.size());
+ return QRectF(d->offset, d->pixmap.size() / d->pixmap.devicePixelRatio());
}
}
@@ -10778,7 +10778,6 @@ void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphic
tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
QStackTextEngine engine(tmp, d->font);
QTextLayout layout(&engine);
- setupTextLayout(&layout);
QPen p;
p.setBrush(d->brush);
@@ -10795,6 +10794,7 @@ void QGraphicsSimpleTextItem::paint(QPainter *painter, const QStyleOptionGraphic
layout.setAdditionalFormats(formats);
}
+ setupTextLayout(&layout);
layout.draw(painter, QPointF(0, 0));
if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus))
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index c053fdfb22..92d3359909 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -2697,7 +2697,8 @@ void QApplication::setStartDragDistance(int l)
Qt uses this value internally, e.g. in QFileDialog.
- The default value is 4 pixels.
+ The default value (if the platform doesn't provide a different default)
+ is 10 pixels.
\sa startDragTime(), QPoint::manhattanLength(), {Drag and Drop}
*/
@@ -3102,12 +3103,12 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QPoint relpos = wheel->pos();
bool eventAccepted = wheel->isAccepted();
- if (e->spontaneous())
+ if (e->spontaneous() && wheel->phase() == Qt::ScrollUpdate)
QApplicationPrivate::giveFocusAccordingToFocusPolicy(w, e, relpos);
while (w) {
QWheelEvent we(relpos, wheel->globalPos(), wheel->pixelDelta(), wheel->angleDelta(), wheel->delta(), wheel->orientation(), wheel->buttons(),
- wheel->modifiers());
+ wheel->modifiers(), wheel->phase());
we.spont = wheel->spontaneous();
res = d->notify_helper(w, w == receiver ? wheel : &we);
eventAccepted = ((w == receiver) ? wheel : &we)->isAccepted();
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 5ce2ac2c4b..1c40ca01be 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -288,7 +288,7 @@ void QApplicationPrivate::initializeWidgetPaletteHash()
setPossiblePalette(platformTheme->palette(QPlatformTheme::RadioButtonPalette), "QRadioButton");
setPossiblePalette(platformTheme->palette(QPlatformTheme::HeaderPalette), "QHeaderView");
setPossiblePalette(platformTheme->palette(QPlatformTheme::ItemViewPalette), "QAbstractItemView");
- setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPelette), "QMessageBoxLabel");
+ setPossiblePalette(platformTheme->palette(QPlatformTheme::MessageBoxLabelPalette), "QMessageBoxLabel");
setPossiblePalette(platformTheme->palette(QPlatformTheme::TabBarPalette), "QTabBar");
setPossiblePalette(platformTheme->palette(QPlatformTheme::LabelPalette), "QLabel");
setPossiblePalette(platformTheme->palette(QPlatformTheme::GroupBoxPalette), "QGroupBox");
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index e05c03d952..66aacadb28 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -163,7 +163,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *)
d->context.makeCurrent(d->surface());
delete d->fbo; // recreate when resized
- d->fbo = new QOpenGLFramebufferObject(size());
+ d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio());
d->fbo->bind();
QOpenGLFunctions *funcs = d->context.functions();
funcs->glBindTexture(GL_TEXTURE_2D, d->fbo->texture());
diff --git a/src/widgets/kernel/qtooltip.cpp b/src/widgets/kernel/qtooltip.cpp
index c898f56015..5aea55e196 100644
--- a/src/widgets/kernel/qtooltip.cpp
+++ b/src/widgets/kernel/qtooltip.cpp
@@ -322,13 +322,32 @@ bool QTipLabel::eventFilter(QObject *o, QEvent *e)
case QEvent::Leave:
hideTip();
break;
+
+
+#if defined (Q_OS_QNX) // On QNX the window activate and focus events are delayed and will appear
+ // after the window is shown.
+ case QEvent::WindowActivate:
+ case QEvent::FocusIn:
+ return false;
+ case QEvent::WindowDeactivate:
+ if (o != this)
+ return false;
+ hideTipImmediately();
+ break;
+ case QEvent::FocusOut:
+ if (reinterpret_cast<QWindow*>(o) != windowHandle())
+ return false;
+ hideTipImmediately();
+ break;
+#else
case QEvent::WindowActivate:
case QEvent::WindowDeactivate:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+#endif
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
- case QEvent::FocusIn:
- case QEvent::FocusOut:
case QEvent::Wheel:
hideTipImmediately();
break;
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
index 88a08060c1..85ae55b8ac 100644
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -959,6 +959,8 @@ void QWidgetPrivate::deleteTLSysExtra()
#ifndef QT_NO_OPENGL
if (textureChildSeen && extra->topextra->shareContext)
extra->topextra->shareContext->doneCurrent();
+ delete extra->topextra->shareContext;
+ extra->topextra->shareContext = 0;
#endif
//the toplevel might have a context with a "qglcontext associated with it. We need to
@@ -972,10 +974,6 @@ void QWidgetPrivate::deleteTLSysExtra()
delete extra->topextra->window;
extra->topextra->window = 0;
-#ifndef QT_NO_OPENGL
- delete extra->topextra->shareContext;
- extra->topextra->shareContext = 0;
-#endif
}
}
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index e50736d6b8..ef138267bb 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -100,6 +100,7 @@ QWidgetWindow::QWidgetWindow(QWidget *widget)
setSurfaceType(QSurface::RasterGLSurface);
}
connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName);
+ connect(this, SIGNAL(screenChanged(QScreen*)), this, SLOT(repaintWindow()));
}
QWidgetWindow::~QWidgetWindow()
@@ -560,6 +561,19 @@ void QWidgetWindow::updateGeometry()
m_widget->data->fstrut_dirty = false;
}
+// Invalidates the backing store buffer and repaints immediately.
+// ### Qt 5.4: replace with QUpdateWindowRequestEvent.
+void QWidgetWindow::repaintWindow()
+{
+ if (!m_widget->isVisible() || !m_widget->updatesEnabled())
+ return;
+
+ QTLWExtra *tlwExtra = m_widget->window()->d_func()->maybeTopData();
+ if (tlwExtra && !tlwExtra->inTopLevelResize && tlwExtra->backingStore)
+ tlwExtra->backingStoreTracker->markDirty(m_widget->rect(), m_widget,
+ QWidgetBackingStore::UpdateNow, QWidgetBackingStore::BufferInvalid);
+}
+
Qt::WindowState effectiveState(Qt::WindowStates state);
// Store normal geometry used for saving application settings.
diff --git a/src/widgets/kernel/qwidgetwindow_qpa_p.h b/src/widgets/kernel/qwidgetwindow_qpa_p.h
index 8d6f14a669..06ba8ea646 100644
--- a/src/widgets/kernel/qwidgetwindow_qpa_p.h
+++ b/src/widgets/kernel/qwidgetwindow_qpa_p.h
@@ -101,6 +101,7 @@ protected:
private slots:
void updateObjectName();
+ void repaintWindow();
private:
void updateGeometry();
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 6b5af8ed8b..4a9852108c 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -3939,7 +3939,9 @@ QRect QCommonStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex
case CC_ScrollBar:
if (const QStyleOptionSlider *scrollbar = qstyleoption_cast<const QStyleOptionSlider *>(opt)) {
const QRect scrollBarRect = scrollbar->rect;
- int sbextent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar, widget);
+ int sbextent = 0;
+ if (!proxy()->styleHint(SH_ScrollBar_Transient, scrollbar, widget))
+ sbextent = proxy()->pixelMetric(PM_ScrollBarExtent, scrollbar, widget);
int maxlen = ((scrollbar->orientation == Qt::Horizontal) ?
scrollBarRect.width() : scrollBarRect.height()) - (sbextent * 2);
int sliderlen;
@@ -4896,6 +4898,10 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
ret = 256;
break;
+ case SH_Menu_SloppySubMenus:
+ ret = true;
+ break;
+
case SH_ProgressDialog_TextLabelAlignment:
ret = Qt::AlignCenter;
break;
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index c4bc5a5e96..2172c9082f 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -2393,6 +2393,91 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
case CC_ScrollBar:
painter->save();
if (const QStyleOptionSlider *scrollBar = qstyleoption_cast<const QStyleOptionSlider *>(option)) {
+ bool wasActive = false;
+ qreal expandScale = 1.0;
+ qreal expandOffset = -1.0;
+ QObject *styleObject = option->styleObject;
+ if (styleObject && proxy()->styleHint(SH_ScrollBar_Transient, option, widget)) {
+ qreal opacity = 0.0;
+ bool shouldExpand = false;
+ const qreal maxExpandScale = 13.0 / 9.0;
+
+ int oldPos = styleObject->property("_q_stylepos").toInt();
+ int oldMin = styleObject->property("_q_stylemin").toInt();
+ int oldMax = styleObject->property("_q_stylemax").toInt();
+ QRect oldRect = styleObject->property("_q_stylerect").toRect();
+ int oldState = styleObject->property("_q_stylestate").toInt();
+ uint oldActiveControls = styleObject->property("_q_stylecontrols").toUInt();
+
+ // a scrollbar is transient when the the scrollbar itself and
+ // its sibling are both inactive (ie. not pressed/hovered/moved)
+ bool transient = !option->activeSubControls && !(option->state & State_On);
+
+ if (!transient ||
+ oldPos != scrollBar->sliderPosition ||
+ oldMin != scrollBar->minimum ||
+ oldMax != scrollBar->maximum ||
+ oldRect != scrollBar->rect ||
+ oldState != scrollBar->state ||
+ oldActiveControls != scrollBar->activeSubControls) {
+
+ // if the scrollbar is transient or its attributes, geometry or
+ // state has changed, the opacity is reset back to 100% opaque
+ opacity = 1.0;
+
+ styleObject->setProperty("_q_stylepos", scrollBar->sliderPosition);
+ styleObject->setProperty("_q_stylemin", scrollBar->minimum);
+ styleObject->setProperty("_q_stylemax", scrollBar->maximum);
+ styleObject->setProperty("_q_stylerect", scrollBar->rect);
+ styleObject->setProperty("_q_stylestate", static_cast<int>(scrollBar->state));
+ styleObject->setProperty("_q_stylecontrols", static_cast<uint>(scrollBar->activeSubControls));
+
+ QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
+ if (transient) {
+ if (!anim) {
+ anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Deactivating, styleObject);
+ d->startAnimation(anim);
+ } else if (anim->mode() == QScrollbarStyleAnimation::Deactivating) {
+ // the scrollbar was already fading out while the
+ // state changed -> restart the fade out animation
+ anim->setCurrentTime(0);
+ }
+ } else if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
+ d->stopAnimation(styleObject);
+ }
+ }
+
+ QScrollbarStyleAnimation *anim = qobject_cast<QScrollbarStyleAnimation *>(d->animation(styleObject));
+ if (anim && anim->mode() == QScrollbarStyleAnimation::Deactivating) {
+ // once a scrollbar was active (hovered/pressed), it retains
+ // the active look even if it's no longer active while fading out
+ if (oldActiveControls)
+ anim->setActive(true);
+
+ wasActive = anim->wasActive();
+ opacity = anim->currentValue();
+ }
+
+ shouldExpand = (option->activeSubControls || wasActive);
+ if (shouldExpand) {
+ if (!anim && !oldActiveControls) {
+ // Start expand animation only once and when entering
+ anim = new QScrollbarStyleAnimation(QScrollbarStyleAnimation::Activating, styleObject);
+ d->startAnimation(anim);
+ }
+ if (anim && anim->mode() == QScrollbarStyleAnimation::Activating) {
+ expandScale = 1.0 + (maxExpandScale - 1.0) * anim->currentValue();
+ expandOffset = 5.5 * anim->currentValue() - 1;
+ } else {
+ // Keep expanded state after the animation ends, and when fading out
+ expandScale = maxExpandScale;
+ expandOffset = 4.5;
+ }
+ }
+ painter->setOpacity(opacity);
+ }
+
+ bool transient = proxy()->styleHint(SH_ScrollBar_Transient, option, widget);
bool horizontal = scrollBar->orientation == Qt::Horizontal;
bool sunken = scrollBar->state & State_Sunken;
@@ -2408,20 +2493,53 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
QColor arrowColor = option->palette.foreground().color();
arrowColor.setAlpha(220);
+ const QColor bgColor = option->palette.color(QPalette::Base);
+ const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
+
+ if (transient) {
+ if (horizontal) {
+ rect.setY(rect.y() + 4.5 - expandOffset);
+ scrollBarSlider.setY(scrollBarSlider.y() + 4.5 - expandOffset);
+ scrollBarGroove.setY(scrollBarGroove.y() + 4.5 - expandOffset);
+
+ rect.setHeight(rect.height() * expandScale);
+ scrollBarGroove.setHeight(scrollBarGroove.height() * expandScale);
+ } else {
+ rect.setX(rect.x() + 4.5 - expandOffset);
+ scrollBarSlider.setX(scrollBarSlider.x() + 4.5 - expandOffset);
+ scrollBarGroove.setX(scrollBarGroove.x() + 4.5 - expandOffset);
+
+ rect.setWidth(rect.width() * expandScale);
+ scrollBarGroove.setWidth(scrollBarGroove.width() * expandScale);
+ }
+ }
+
// Paint groove
- if (scrollBar->subControls & SC_ScrollBarGroove) {
+ if ((!transient || scrollBar->activeSubControls || wasActive) && scrollBar->subControls & SC_ScrollBarGroove) {
QLinearGradient gradient(rect.center().x(), rect.top(),
rect.center().x(), rect.bottom());
if (!horizontal)
gradient = QLinearGradient(rect.left(), rect.center().y(),
rect.right(), rect.center().y());
- gradient.setColorAt(0, buttonColor.darker(107));
- gradient.setColorAt(0.1, buttonColor.darker(105));
- gradient.setColorAt(0.9, buttonColor.darker(105));
- gradient.setColorAt(1, buttonColor.darker(107));
+ if (!transient || !isDarkBg) {
+ gradient.setColorAt(0, buttonColor.darker(107));
+ gradient.setColorAt(0.1, buttonColor.darker(105));
+ gradient.setColorAt(0.9, buttonColor.darker(105));
+ gradient.setColorAt(1, buttonColor.darker(107));
+ } else {
+ gradient.setColorAt(0, bgColor.lighter(157));
+ gradient.setColorAt(0.1, bgColor.lighter(155));
+ gradient.setColorAt(0.9, bgColor.lighter(155));
+ gradient.setColorAt(1, bgColor.lighter(157));
+ }
- painter->fillRect(option->rect, gradient);
+ painter->save();
+ if (transient)
+ painter->setOpacity(0.8);
+ painter->fillRect(rect, gradient);
painter->setPen(Qt::NoPen);
+ if (transient)
+ painter->setOpacity(0.4);
painter->setPen(alphaOutline);
if (horizontal)
painter->drawLine(rect.topLeft(), rect.topRight());
@@ -2432,7 +2550,6 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
subtleEdge.setAlpha(40);
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::NoBrush);
- painter->save();
painter->setClipRect(scrollBarGroove.adjusted(1, 0, -1, -3));
painter->drawRect(scrollBarGroove.adjusted(1, 0, -1, -1));
painter->restore();
@@ -2456,33 +2573,45 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
// Paint slider
if (scrollBar->subControls & SC_ScrollBarSlider) {
- QRect pixmapRect = scrollBarSlider;
- painter->setPen(QPen(alphaOutline));
- if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider)
- painter->setBrush(midColor2);
- else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider)
- painter->setBrush(highlightedGradient);
- else
- painter->setBrush(gradient);
+ if (transient) {
+ QRect rect = scrollBarSlider.adjusted(horizontal ? 1 : 2, horizontal ? 2 : 1, -1, -1);
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(isDarkBg ? d->lightShade() : d->darkShade());
+ int r = qMin(rect.width(), rect.height()) / 2;
- painter->drawRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : 1, horizontal ? 1 : 0));
-
- painter->setPen(d->innerContrastLine());
- painter->drawRect(scrollBarSlider.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, -1, -1));
-
- // Outer shadow
- // painter->setPen(subtleEdge);
- // if (horizontal) {
- //// painter->drawLine(scrollBarSlider.topLeft() + QPoint(-2, 0), scrollBarSlider.bottomLeft() + QPoint(2, 0));
- //// painter->drawLine(scrollBarSlider.topRight() + QPoint(-2, 0), scrollBarSlider.bottomRight() + QPoint(2, 0));
- // } else {
- //// painter->drawLine(pixmapRect.topLeft() + QPoint(0, -2), pixmapRect.bottomLeft() + QPoint(0, -2));
- //// painter->drawLine(pixmapRect.topRight() + QPoint(0, 2), pixmapRect.bottomRight() + QPoint(0, 2));
- // }
+ painter->save();
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ painter->drawRoundedRect(rect, r, r);
+ painter->restore();
+ } else {
+ QRect pixmapRect = scrollBarSlider;
+ painter->setPen(QPen(alphaOutline));
+ if (option->state & State_Sunken && scrollBar->activeSubControls & SC_ScrollBarSlider)
+ painter->setBrush(midColor2);
+ else if (option->state & State_MouseOver && scrollBar->activeSubControls & SC_ScrollBarSlider)
+ painter->setBrush(highlightedGradient);
+ else
+ painter->setBrush(gradient);
+
+ painter->drawRect(pixmapRect.adjusted(horizontal ? -1 : 0, horizontal ? 0 : -1, horizontal ? 0 : 1, horizontal ? 1 : 0));
+
+ painter->setPen(d->innerContrastLine());
+ painter->drawRect(scrollBarSlider.adjusted(horizontal ? 0 : 1, horizontal ? 1 : 0, -1, -1));
+
+ // Outer shadow
+ // painter->setPen(subtleEdge);
+ // if (horizontal) {
+ //// painter->drawLine(scrollBarSlider.topLeft() + QPoint(-2, 0), scrollBarSlider.bottomLeft() + QPoint(2, 0));
+ //// painter->drawLine(scrollBarSlider.topRight() + QPoint(-2, 0), scrollBarSlider.bottomRight() + QPoint(2, 0));
+ // } else {
+ //// painter->drawLine(pixmapRect.topLeft() + QPoint(0, -2), pixmapRect.bottomLeft() + QPoint(0, -2));
+ //// painter->drawLine(pixmapRect.topRight() + QPoint(0, 2), pixmapRect.bottomRight() + QPoint(0, 2));
+ // }
+ }
}
// The SubLine (up/left) buttons
- if (scrollBar->subControls & SC_ScrollBarSubLine) {
+ if (!transient && scrollBar->subControls & SC_ScrollBarSubLine) {
if ((scrollBar->activeSubControls & SC_ScrollBarSubLine) && sunken)
painter->setBrush(gradientStopColor);
else if ((scrollBar->activeSubControls & SC_ScrollBarSubLine))
@@ -2523,7 +2652,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
}
// The AddLine (down/right) button
- if (scrollBar->subControls & SC_ScrollBarAddLine) {
+ if (!transient && scrollBar->subControls & SC_ScrollBarAddLine) {
if ((scrollBar->activeSubControls & SC_ScrollBarAddLine) && sunken)
painter->setBrush(gradientStopColor);
else if ((scrollBar->activeSubControls & SC_ScrollBarAddLine))
@@ -2970,6 +3099,10 @@ int QFusionStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, co
return 14;
case PM_ScrollView_ScrollBarSpacing:
return 0;
+ case PM_ScrollView_ScrollBarOverlap:
+ if (proxy()->styleHint(SH_ScrollBar_Transient, option, widget))
+ return proxy()->pixelMetric(PM_ScrollBarExtent, option, widget);
+ return 0;
default:
break;
}
@@ -3099,6 +3232,7 @@ void QFusionStyle::polish(QWidget *widget)
|| (widget->inherits("QDockWidgetSeparator"))
) {
widget->setAttribute(Qt::WA_Hover, true);
+ widget->setAttribute(Qt::WA_OpaquePaintEvent, false);
}
}
diff --git a/src/widgets/styles/qgtkstyle.cpp b/src/widgets/styles/qgtkstyle.cpp
index 9ad0484bc2..9fa056960a 100644
--- a/src/widgets/styles/qgtkstyle.cpp
+++ b/src/widgets/styles/qgtkstyle.cpp
@@ -471,15 +471,8 @@ void QGtkStyle::polish(QApplication *app)
QApplicationPrivate::setSystemPalette(standardPalette());
QApplicationPrivate::setSystemFont(d->getThemeFont());
d->applyCustomPaletteHash();
- if (!d->isKDE4Session()) {
-#ifndef QT_NO_FILEDIALOG
- qt_filedialog_open_filename_hook = &QGtkStylePrivate::openFilename;
- qt_filedialog_save_filename_hook = &QGtkStylePrivate::saveFilename;
- qt_filedialog_open_filenames_hook = &QGtkStylePrivate::openFilenames;
- qt_filedialog_existing_directory_hook = &QGtkStylePrivate::openDirectory;
-#endif
+ if (!d->isKDE4Session())
qApp->installEventFilter(&d->filter);
- }
}
}
@@ -493,16 +486,8 @@ void QGtkStyle::unpolish(QApplication *app)
QCommonStyle::unpolish(app);
QPixmapCache::clear();
- if (app->desktopSettingsAware() && d->isThemeAvailable()
- && !d->isKDE4Session()) {
-#ifndef QT_NO_FILEDIALOG
- qt_filedialog_open_filename_hook = 0;
- qt_filedialog_save_filename_hook = 0;
- qt_filedialog_open_filenames_hook = 0;
- qt_filedialog_existing_directory_hook = 0;
-#endif
+ if (app->desktopSettingsAware() && d->isThemeAvailable() && !d->isKDE4Session())
qApp->removeEventFilter(&d->filter);
- }
}
/*!
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index c53a21e59a..2bd978bcb8 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -180,20 +180,6 @@ Ptr_pango_font_description_get_weight QGtkStylePrivate::pango_font_description_g
Ptr_pango_font_description_get_family QGtkStylePrivate::pango_font_description_get_family = 0;
Ptr_pango_font_description_get_style QGtkStylePrivate::pango_font_description_get_style = 0;
-Ptr_gtk_file_filter_new QGtkStylePrivate::gtk_file_filter_new = 0;
-Ptr_gtk_file_filter_set_name QGtkStylePrivate::gtk_file_filter_set_name = 0;
-Ptr_gtk_file_filter_add_pattern QGtkStylePrivate::gtk_file_filter_add_pattern = 0;
-Ptr_gtk_file_chooser_add_filter QGtkStylePrivate::gtk_file_chooser_add_filter = 0;
-Ptr_gtk_file_chooser_set_filter QGtkStylePrivate::gtk_file_chooser_set_filter = 0;
-Ptr_gtk_file_chooser_get_filter QGtkStylePrivate::gtk_file_chooser_get_filter = 0;
-Ptr_gtk_file_chooser_dialog_new QGtkStylePrivate::gtk_file_chooser_dialog_new = 0;
-Ptr_gtk_file_chooser_set_current_folder QGtkStylePrivate::gtk_file_chooser_set_current_folder = 0;
-Ptr_gtk_file_chooser_get_filename QGtkStylePrivate::gtk_file_chooser_get_filename = 0;
-Ptr_gtk_file_chooser_get_filenames QGtkStylePrivate::gtk_file_chooser_get_filenames = 0;
-Ptr_gtk_file_chooser_set_current_name QGtkStylePrivate::gtk_file_chooser_set_current_name = 0;
-Ptr_gtk_dialog_run QGtkStylePrivate::gtk_dialog_run = 0;
-Ptr_gtk_file_chooser_set_filename QGtkStylePrivate::gtk_file_chooser_set_filename = 0;
-
Ptr_gdk_pixbuf_get_pixels QGtkStylePrivate::gdk_pixbuf_get_pixels = 0;
Ptr_gdk_pixbuf_get_width QGtkStylePrivate::gdk_pixbuf_get_width = 0;
Ptr_gdk_pixbuf_get_height QGtkStylePrivate::gdk_pixbuf_get_height = 0;
@@ -356,21 +342,6 @@ void QGtkStylePrivate::resolveGtk() const
gtk_widget_destroy = (Ptr_gtk_widget_destroy)libgtk.resolve("gtk_widget_destroy");
gtk_widget_realize = (Ptr_gtk_widget_realize)libgtk.resolve("gtk_widget_realize");
- gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
- gtk_file_filter_new = (Ptr_gtk_file_filter_new)libgtk.resolve("gtk_file_filter_new");
- gtk_file_filter_set_name = (Ptr_gtk_file_filter_set_name)libgtk.resolve("gtk_file_filter_set_name");
- gtk_file_filter_add_pattern = (Ptr_gtk_file_filter_add_pattern)libgtk.resolve("gtk_file_filter_add_pattern");
- gtk_file_chooser_add_filter = (Ptr_gtk_file_chooser_add_filter)libgtk.resolve("gtk_file_chooser_add_filter");
- gtk_file_chooser_set_filter = (Ptr_gtk_file_chooser_set_filter)libgtk.resolve("gtk_file_chooser_set_filter");
- gtk_file_chooser_get_filter = (Ptr_gtk_file_chooser_get_filter)libgtk.resolve("gtk_file_chooser_get_filter");
- gtk_file_chooser_dialog_new = (Ptr_gtk_file_chooser_dialog_new)libgtk.resolve("gtk_file_chooser_dialog_new");
- gtk_file_chooser_set_current_folder = (Ptr_gtk_file_chooser_set_current_folder)libgtk.resolve("gtk_file_chooser_set_current_folder");
- gtk_file_chooser_get_filename = (Ptr_gtk_file_chooser_get_filename)libgtk.resolve("gtk_file_chooser_get_filename");
- gtk_file_chooser_get_filenames = (Ptr_gtk_file_chooser_get_filenames)libgtk.resolve("gtk_file_chooser_get_filenames");
- gtk_file_chooser_set_current_name = (Ptr_gtk_file_chooser_set_current_name)libgtk.resolve("gtk_file_chooser_set_current_name");
- gtk_dialog_run = (Ptr_gtk_dialog_run)libgtk.resolve("gtk_dialog_run");
- gtk_file_chooser_set_filename = (Ptr_gtk_file_chooser_set_filename)libgtk.resolve("gtk_file_chooser_set_filename");
-
gdk_pixbuf_get_pixels = (Ptr_gdk_pixbuf_get_pixels)libgtk.resolve("gdk_pixbuf_get_pixels");
gdk_pixbuf_get_width = (Ptr_gdk_pixbuf_get_width)libgtk.resolve("gdk_pixbuf_get_width");
gdk_pixbuf_get_height = (Ptr_gdk_pixbuf_get_height)libgtk.resolve("gdk_pixbuf_get_height");
@@ -881,233 +852,6 @@ QFont QGtkStylePrivate::getThemeFont()
return font;
}
-
-// ----------- Native file dialogs -----------
-
-// Extract filter list from expressions of type: foo (*.a *.b *.c)"
-QStringList QGtkStylePrivate::extract_filter(const QString &rawFilter)
-{
- QString result = rawFilter;
- QRegExp r(QString::fromLatin1("^([^()]*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"));
- int index = r.indexIn(result);
- if (index >= 0)
- result = r.cap(2);
- return result.split(QLatin1Char(' '));
-}
-
-extern QStringList qt_make_filter_list(const QString &filter);
-
-#ifndef QT_NO_FILEDIALOG
-void QGtkStylePrivate::setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
- const QString &dir, const QString &filter, QString *selectedFilter,
- QFileDialog::Options options, bool isSaveDialog,
- QHash<GtkFileFilter *, QString> *filterMap)
-{
- g_object_set(gtkFileChooser, "do-overwrite-confirmation", gboolean(!(options & QFileDialog::DontConfirmOverwrite)), NULL);
- g_object_set(gtkFileChooser, "local_only", gboolean(true), NULL);
- if (!filter.isEmpty()) {
- QStringList filters = qt_make_filter_list(filter);
- foreach (const QString &rawfilter, filters) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_filter_new ();
- QString name = rawfilter.left(rawfilter.indexOf(QLatin1Char('(')));
- QStringList extensions = extract_filter(rawfilter);
- QGtkStylePrivate::gtk_file_filter_set_name(gtkFilter, qPrintable(name.isEmpty() ? extensions.join(QLS(", ")) : name));
-
- foreach (const QString &fileExtension, extensions) {
- // Note Gtk file dialogs are by default case sensitive
- // and only supports basic glob syntax so we
- // rewrite .xyz to .[xX][yY][zZ]
- QString caseInsensitive;
- for (int i = 0 ; i < fileExtension.length() ; ++i) {
- QChar ch = fileExtension.at(i);
- if (ch.isLetter()) {
- caseInsensitive.append(
- QLatin1Char('[') +
- ch.toLower() +
- ch.toUpper() +
- QLatin1Char(']'));
- } else {
- caseInsensitive.append(ch);
- }
- }
- QGtkStylePrivate::gtk_file_filter_add_pattern (gtkFilter, qPrintable(caseInsensitive));
-
- }
- if (filterMap)
- filterMap->insert(gtkFilter, rawfilter);
- QGtkStylePrivate::gtk_file_chooser_add_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
- if (selectedFilter && (rawfilter == *selectedFilter))
- QGtkStylePrivate::gtk_file_chooser_set_filter((GtkFileChooser*)gtkFileChooser, gtkFilter);
- }
- }
-
- // Using the currently active window is not entirely correct, however
- // it gives more sensible behavior for applications that do not provide a
- // parent
- QWidget *modalFor = parent ? parent->window() : qApp->activeWindow();
- if (modalFor) {
- QGtkStylePrivate::gtk_widget_realize(gtkFileChooser); // Creates X window
-#ifndef Q_OS_MAC
- XSetTransientForHint(QGtkStylePrivate::gdk_x11_drawable_get_xdisplay(gtkFileChooser->window),
- QGtkStylePrivate::gdk_x11_drawable_get_xid(gtkFileChooser->window),
- modalFor->winId());
-#ifdef Q_WS_X11
- QGtkStylePrivate::gdk_x11_window_set_user_time (gtkFileChooser->window, QX11Info::appUserTime());
-#endif
-#endif
- }
-
- QFileInfo fileinfo(dir);
- if (dir.isEmpty())
- fileinfo.setFile(QDir::currentPath());
- fileinfo.makeAbsolute();
- if (fileinfo.isDir()) {
- QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
- } else if (isSaveDialog) {
- QGtkStylePrivate::gtk_file_chooser_set_current_folder((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.absolutePath()));
- QGtkStylePrivate::gtk_file_chooser_set_current_name((GtkFileChooser*)gtkFileChooser, qPrintable(fileinfo.fileName()));
- } else {
- QGtkStylePrivate::gtk_file_chooser_set_filename((GtkFileChooser*)gtkFileChooser, qPrintable(dir));
- }
-}
-
-QString QGtkStylePrivate::openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QHash<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
-
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- modal_widget.createWinId();
- QGuiApplicationPrivate::showModalWindow(modal_widget.windowHandle());
-
- QString filename;
- if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::hideModalWindow(modal_widget.windowHandle());
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-
-
-QString QGtkStylePrivate::openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
-{
- QHash<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- setupGtkFileChooser(gtkFileChooser, parent, dir, QString(), 0, options);
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- modal_widget.createWinId();
- QGuiApplicationPrivate::showModalWindow(modal_widget.windowHandle());
-
- QString filename;
- if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- }
-
- QApplicationPrivate::hideModalWindow(modal_widget.windowHandle());
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-
-QStringList QGtkStylePrivate::openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QStringList filenames;
- QHash<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
-
- setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, false, &filterMap);
- g_object_set(gtkFileChooser, "select-multiple", gboolean(true), NULL);
-
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- modal_widget.createWinId();
- QGuiApplicationPrivate::showModalWindow(modal_widget.windowHandle());
-
- if (gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- GSList *gtk_file_names = QGtkStylePrivate::gtk_file_chooser_get_filenames((GtkFileChooser*)gtkFileChooser);
- for (GSList *iterator = gtk_file_names ; iterator; iterator = iterator->next)
- filenames << QString::fromUtf8((const char*)iterator->data);
- g_slist_free(gtk_file_names);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::hideModalWindow(modal_widget.windowHandle());
- gtk_widget_destroy (gtkFileChooser);
- return filenames;
-}
-
-QString QGtkStylePrivate::saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options)
-{
- QHash<GtkFileFilter *, QString> filterMap;
- GtkWidget *gtkFileChooser = QGtkStylePrivate::gtk_file_chooser_dialog_new (qPrintable(caption),
- NULL,
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- setupGtkFileChooser(gtkFileChooser, parent, dir, filter, selectedFilter, options, true, &filterMap);
-
- QWidget modal_widget;
- modal_widget.setAttribute(Qt::WA_NoChildEventsForParent, true);
- modal_widget.setParent(parent, Qt::Window);
- modal_widget.createWinId();
- QGuiApplicationPrivate::showModalWindow(modal_widget.windowHandle());
-
- QString filename;
- if (QGtkStylePrivate::gtk_dialog_run ((GtkDialog*)gtkFileChooser) == GTK_RESPONSE_ACCEPT) {
- char *gtk_filename = QGtkStylePrivate::gtk_file_chooser_get_filename ((GtkFileChooser*)gtkFileChooser);
- filename = QString::fromUtf8(gtk_filename);
- g_free (gtk_filename);
- if (selectedFilter) {
- GtkFileFilter *gtkFilter = QGtkStylePrivate::gtk_file_chooser_get_filter ((GtkFileChooser*)gtkFileChooser);
- *selectedFilter = filterMap.value(gtkFilter);
- }
- }
-
- QApplicationPrivate::hideModalWindow(modal_widget.windowHandle());
- gtk_widget_destroy (gtkFileChooser);
- return filename;
-}
-#endif
-
QIcon QGtkStylePrivate::getFilesystemIcon(const QFileInfo &info)
{
QIcon icon;
diff --git a/src/widgets/styles/qgtkstyle_p_p.h b/src/widgets/styles/qgtkstyle_p_p.h
index 6f3759bd9e..1a8aa77042 100644
--- a/src/widgets/styles/qgtkstyle_p_p.h
+++ b/src/widgets/styles/qgtkstyle_p_p.h
@@ -200,23 +200,6 @@ typedef gint (*Ptr_pango_font_description_get_size) (const PangoFontDescription
typedef PangoWeight (*Ptr_pango_font_description_get_weight) (const PangoFontDescription *);
typedef const char* (*Ptr_pango_font_description_get_family) (const PangoFontDescription *);
typedef PangoStyle (*Ptr_pango_font_description_get_style) (const PangoFontDescription *desc);
-typedef gboolean (*Ptr_gtk_file_chooser_set_current_folder)(GtkFileChooser *, const gchar *);
-typedef GtkFileFilter* (*Ptr_gtk_file_filter_new)(void);
-typedef void (*Ptr_gtk_file_filter_set_name)(GtkFileFilter *, const gchar *);
-typedef void (*Ptr_gtk_file_filter_add_pattern)(GtkFileFilter *filter, const gchar *pattern);
-typedef void (*Ptr_gtk_file_chooser_add_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
-typedef void (*Ptr_gtk_file_chooser_set_filter)(GtkFileChooser *chooser, GtkFileFilter *filter);
-typedef GtkFileFilter* (*Ptr_gtk_file_chooser_get_filter)(GtkFileChooser *chooser);
-typedef gchar* (*Ptr_gtk_file_chooser_get_filename)(GtkFileChooser *chooser);
-typedef GSList* (*Ptr_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
-typedef GtkWidget* (*Ptr_gtk_file_chooser_dialog_new)(const gchar *title,
- GtkWindow *parent,
- GtkFileChooserAction action,
- const gchar *first_button_text,
- ...);
-typedef void (*Ptr_gtk_file_chooser_set_current_name) (GtkFileChooser *, const gchar *);
-typedef gboolean (*Ptr_gtk_file_chooser_set_filename) (GtkFileChooser *chooser, const gchar *name);
-typedef gint (*Ptr_gtk_dialog_run) (GtkDialog*);
typedef void (*Ptr_gtk_border_free)(GtkBorder *);
typedef void (*Ptr_gtk_widget_get_allocation) (GtkWidget*, GtkAllocation*);
typedef void (*Ptr_gtk_widget_set_allocation) (GtkWidget*, const GtkAllocation*);
@@ -242,22 +225,6 @@ typedef Display* (*Ptr_gdk_x11_drawable_get_xdisplay) ( GdkDrawable *);
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_FILEDIALOG
-typedef QStringList (*_qt_filedialog_open_filenames_hook)(QWidget * parent, const QString &caption, const QString &dir,
- const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-typedef QString (*_qt_filedialog_open_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
- const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-typedef QString (*_qt_filedialog_save_filename_hook) (QWidget * parent, const QString &caption, const QString &dir,
- const QString &filter, QString *selectedFilter, QFileDialog::Options options);
-typedef QString (*_qt_filedialog_existing_directory_hook)(QWidget *parent, const QString &caption, const QString &dir,
- QFileDialog::Options options);
-
-extern Q_WIDGETS_EXPORT _qt_filedialog_open_filename_hook qt_filedialog_open_filename_hook;
-extern Q_WIDGETS_EXPORT _qt_filedialog_open_filenames_hook qt_filedialog_open_filenames_hook;
-extern Q_WIDGETS_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook;
-extern Q_WIDGETS_EXPORT _qt_filedialog_existing_directory_hook qt_filedialog_existing_directory_hook;
-#endif //!QT_NO_FILEDIALOG
-
class QGtkPainter;
class QGtkStylePrivate;
@@ -326,20 +293,6 @@ public:
static QString getThemeName();
virtual int getSpinboxArrowSize() const;
-#ifndef QT_NO_FILEDIALOG
- static void setupGtkFileChooser(GtkWidget* gtkFileChooser, QWidget *parent,
- const QString &dir, const QString &filter, QString *selectedFilter,
- QFileDialog::Options options, bool isSaveDialog = false,
- QHash<GtkFileFilter *, QString> *filterMap = 0);
-
- static QString openFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options);
- static QString saveFilename(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options);
- static QString openDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options);
- static QStringList openFilenames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter,
- QString *selectedFilter, QFileDialog::Options options);
-#endif
static QIcon getFilesystemIcon(const QFileInfo &);
static Ptr_gtk_container_forall gtk_container_forall;
@@ -425,20 +378,6 @@ public:
static Ptr_pango_font_description_get_family pango_font_description_get_family;
static Ptr_pango_font_description_get_style pango_font_description_get_style;
- static Ptr_gtk_file_filter_new gtk_file_filter_new;
- static Ptr_gtk_file_filter_set_name gtk_file_filter_set_name;
- static Ptr_gtk_file_filter_add_pattern gtk_file_filter_add_pattern;
- static Ptr_gtk_file_chooser_add_filter gtk_file_chooser_add_filter;
- static Ptr_gtk_file_chooser_set_filter gtk_file_chooser_set_filter;
- static Ptr_gtk_file_chooser_get_filter gtk_file_chooser_get_filter;
- static Ptr_gtk_file_chooser_dialog_new gtk_file_chooser_dialog_new;
- static Ptr_gtk_file_chooser_set_current_folder gtk_file_chooser_set_current_folder;
- static Ptr_gtk_file_chooser_get_filename gtk_file_chooser_get_filename;
- static Ptr_gtk_file_chooser_get_filenames gtk_file_chooser_get_filenames;
- static Ptr_gtk_file_chooser_set_current_name gtk_file_chooser_set_current_name;
- static Ptr_gtk_dialog_run gtk_dialog_run;
- static Ptr_gtk_file_chooser_set_filename gtk_file_chooser_set_filename;
-
static Ptr_gdk_pixbuf_get_pixels gdk_pixbuf_get_pixels;
static Ptr_gdk_pixbuf_get_width gdk_pixbuf_get_width;
static Ptr_gdk_pixbuf_get_height gdk_pixbuf_get_height;
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 53568f3c53..55e808e9ba 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -526,18 +526,6 @@ static QColor qcolorFromCGColor(CGColorRef cgcolor)
return pc;
}
-static inline QColor leopardBrush(ThemeBrush brush)
-{
- QCFType<CGColorRef> cgClr = 0;
- HIThemeBrushCreateCGColor(brush, &cgClr);
- return qcolorFromCGColor(cgClr);
-}
-
-QColor qcolorForTheme(ThemeBrush brush)
-{
- return leopardBrush(brush);
-}
-
OSStatus qt_mac_shape2QRegionHelper(int inMessage, HIShapeRef, const CGRect *inRect, void *inRefcon)
{
QRegion *region = static_cast<QRegion *>(inRefcon);
@@ -1917,11 +1905,6 @@ void QMacStyle::polish(QPalette &pal)
qt_mac_backgroundPattern = new QPixmap(d->generateBackgroundPattern());
}
- QColor pc(Qt::black);
- pc = qcolorForTheme(kThemeBrushDialogBackgroundActive);
- QBrush background(pc, *qt_mac_backgroundPattern);
- pal.setBrush(QPalette::All, QPalette::Window, background);
- pal.setBrush(QPalette::All, QPalette::Button, background);
QCFString theme;
const OSErr err = CopyThemeIdentifier(&theme);
@@ -2517,12 +2500,12 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
ret = 100;
break;
case SH_ScrollBar_LeftClickAbsolutePosition: {
+ NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
+ bool result = [defaults boolForKey:@"AppleScrollerPagingBehavior"];
if(QApplication::keyboardModifiers() & Qt::AltModifier)
- ret = false;
- //ret = !qt_scrollbar_jump_to_pos;
+ ret = !result;
else
- ret = true;
- //ret = qt_scrollbar_jump_to_pos;
+ ret = result;
break; }
case SH_TabBar_PreferNoArrows:
ret = true;
@@ -2532,9 +2515,6 @@ int QMacStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
ret = QDialogButtons::Reject;
break;
*/
- case SH_Menu_SloppySubMenus:
- ret = true;
- break;
case SH_GroupBox_TextLabelVerticalAlignment:
ret = Qt::AlignTop;
break;
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 005e324442..37c0a41227 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1706,8 +1706,10 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_Menu_Scrollable Whether popup menus must support scrolling.
- \value SH_Menu_SloppySubMenus Whether popupmenu's must support
- sloppy submenu; as implemented on Mac OS.
+ \value SH_Menu_SloppySubMenus Whether popup menus must support
+ the user moving the mouse cursor to a submenu while crossing
+ other items of the menu. This is supported on most modern
+ desktop platforms.
\value SH_ScrollView_FrameOnlyAroundContents Whether scrollviews
draw their frame only around contents (like Motif), or around
diff --git a/src/widgets/styles/qstyle_p.h b/src/widgets/styles/qstyle_p.h
index 70221f6d8f..9f25492173 100644
--- a/src/widgets/styles/qstyle_p.h
+++ b/src/widgets/styles/qstyle_p.h
@@ -96,8 +96,8 @@ inline QPixmap styleCachePixmap(const QSize &size)
QPainter *p = painter; \
QString unique = QStyleHelper::uniqueName((a), option, option->rect.size()); \
int txType = painter->deviceTransform().type() | painter->worldTransform().type(); \
- bool doPixmapCache = (txType <= QTransform::TxTranslate) \
- || (painter->deviceTransform().type() == QTransform::TxScale); \
+ bool doPixmapCache = (!option->rect.isEmpty()) \
+ && ((txType <= QTransform::TxTranslate) || (painter->deviceTransform().type() == QTransform::TxScale)); \
if (doPixmapCache && QPixmapCache::find(unique, internalPixmapCache)) { \
painter->drawPixmap(option->rect.topLeft(), internalPixmapCache); \
} else { \
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 711b0f579d..5eea903773 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -3383,6 +3383,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (const QStyleOptionButton *button = qstyleoption_cast<const QStyleOptionButton *>(opt)) {
QStyleOptionButton butOpt(*button);
rule.configurePalette(&butOpt.palette, QPalette::ButtonText, QPalette::Button);
+
+ const QFont oldFont = p->font();
+ if (rule.hasFont)
+ p->setFont(rule.font);
+
if (rule.hasPosition() && rule.position()->textAlignment != 0) {
Qt::Alignment textAlignment = rule.position()->textAlignment;
QRect textRect = button->rect;
@@ -3455,6 +3460,9 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
} else {
ParentStyle::drawControl(ce, &butOpt, p, w);
}
+
+ if (rule.hasFont)
+ p->setFont(oldFont);
}
return;
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index 3d77e39ce8..9c3e1eac99 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -626,14 +626,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
anim->paint(painter, option);
} else {
QPainter *p = painter;
- QWidget *parentWidget = 0;
- if (widget) {
- parentWidget = widget->parentWidget();
- if (parentWidget)
- parentWidget = parentWidget->parentWidget();
- }
- if (widget && widget->inherits("QLineEdit")
- && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+ if (QWindowsXPStylePrivate::isItemViewDelegateLineEdit(widget)) {
// we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
QPen oldPen = p->pen();
// Inner white border
@@ -1273,7 +1266,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
QPoint p1 = QPoint(x + checkcol, yoff);
QPoint p2 = QPoint(x + w + 6 , yoff);
stateId = MBI_HOT;
- QRect subRect(p1.x(), p1.y(), p2.x() - p1.x(), 6);
+ QRect subRect(p1.x() + (3 - menuitem->rect.x()), p1.y(), p2.x() - p1.x(), 6);
subRect = QStyle::visualRect(option->direction, option->rect, subRect );
XPThemeData theme2(widget, painter,
QWindowsXPStylePrivate::MenuTheme,
@@ -1348,7 +1341,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (dis)
painter->setPen(textColor);
- int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin + (3 - menuitem->rect.x()) - 1;
int xpos = menuitem->rect.x() + xm;
QRect textRect(xpos, y + windowsItemVMargin, w - xm - windowsRightBorder - tab + 1, h - 2 * windowsItemVMargin);
QRect vTextRect = visualRect(option->direction, menuitem->rect, textRect);
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
index 63ed3ef7c8..e694eb4e7e 100644
--- a/src/widgets/styles/qwindowsxpstyle.cpp
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -346,6 +346,19 @@ QString QWindowsXPStylePrivate::themeName(int theme)
QString();
}
+bool QWindowsXPStylePrivate::isItemViewDelegateLineEdit(const QWidget *widget)
+{
+ if (!widget)
+ return false;
+ const QWidget *parent1 = widget->parentWidget();
+ // Exlude dialogs or other toplevels parented on item views.
+ if (!parent1 || parent1->isWindow())
+ return false;
+ const QWidget *parent2 = parent1->parentWidget();
+ return parent2 && widget->inherits("QLineEdit")
+ && parent2->inherits("QAbstractItemView");
+}
+
/*! \internal
This function will always return a valid window handle, and might
create a limbo widget to do so.
@@ -1548,13 +1561,7 @@ case PE_Frame:
}
case PE_FrameLineEdit: {
// we try to check if this lineedit is a delegate on a QAbstractItemView-derived class.
- QWidget *parentWidget = 0;
- if (widget)
- parentWidget = widget->parentWidget();
- if (parentWidget)
- parentWidget = parentWidget->parentWidget();
- if (widget && widget->inherits("QLineEdit")
- && parentWidget && parentWidget->inherits("QAbstractItemView")) {
+ if (QWindowsXPStylePrivate::isItemViewDelegateLineEdit(widget)) {
QPen oldPen = p->pen();
// Inner white border
p->setPen(QPen(option->palette.base().color(), 1));
diff --git a/src/widgets/styles/qwindowsxpstyle_p_p.h b/src/widgets/styles/qwindowsxpstyle_p_p.h
index 27d9c9acc9..7327fa5581 100644
--- a/src/widgets/styles/qwindowsxpstyle_p_p.h
+++ b/src/widgets/styles/qwindowsxpstyle_p_p.h
@@ -350,6 +350,7 @@ public:
static HTHEME createTheme(int theme, HWND hwnd);
static QString themeName(int theme);
static inline bool hasTheme(int theme) { return theme >= 0 && theme < NThemes && m_themes[theme]; }
+ static bool isItemViewDelegateLineEdit(const QWidget *widget);
QIcon dockFloat, dockClose;
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index db4ff8a2b7..e1e933cdd8 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -329,19 +329,21 @@ void QAbstractScrollAreaPrivate::setSingleFingerPanEnabled(bool on)
void QAbstractScrollAreaPrivate::layoutChildren()
{
Q_Q(QAbstractScrollArea);
- bool transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar ? vbar : hbar);
- bool needh = (hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !transient)
- || ((hbarpolicy == Qt::ScrollBarAsNeeded || transient)
+ bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar);
+ bool needh = (hbarpolicy != Qt::ScrollBarAlwaysOff) && ((hbarpolicy == Qt::ScrollBarAlwaysOn && !htransient)
+ || ((hbarpolicy == Qt::ScrollBarAsNeeded || htransient)
&& hbar->minimum() < hbar->maximum() && !hbar->sizeHint().isEmpty()));
- bool needv = (vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !transient)
- || ((vbarpolicy == Qt::ScrollBarAsNeeded || transient)
+ bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar);
+ bool needv = (vbarpolicy != Qt::ScrollBarAlwaysOff) && ((vbarpolicy == Qt::ScrollBarAlwaysOn && !vtransient)
+ || ((vbarpolicy == Qt::ScrollBarAsNeeded || vtransient)
&& vbar->minimum() < vbar->maximum() && !vbar->sizeHint().isEmpty()));
QStyleOption opt(0);
opt.init(q);
- const int scrollOverlap = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap,
- &opt, q);
+
+ const int hscrollOverlap = hbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &opt, hbar);
+ const int vscrollOverlap = vbar->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarOverlap, &opt, vbar);
#ifdef Q_WS_MAC
QWidget * const window = q->window();
@@ -408,7 +410,7 @@ void QAbstractScrollAreaPrivate::layoutChildren()
}
#endif
- QPoint cornerOffset((needv && scrollOverlap == 0) ? vsbExt : 0, (needh && scrollOverlap == 0) ? hsbExt : 0);
+ QPoint cornerOffset((needv && vscrollOverlap == 0) ? vsbExt : 0, (needh && hscrollOverlap == 0) ? hsbExt : 0);
QRect controlsRect;
QRect viewportRect;
@@ -417,8 +419,8 @@ void QAbstractScrollAreaPrivate::layoutChildren()
if ((frameStyle != QFrame::NoFrame) &&
q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents, &opt, q)) {
controlsRect = widgetRect;
- const int extra = scrollOverlap + q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q);
- const QPoint cornerExtra(needv ? extra : 0, needh ? extra : 0);
+ const int spacing = q->style()->pixelMetric(QStyle::PM_ScrollView_ScrollBarSpacing, &opt, q);
+ const QPoint cornerExtra(needv ? spacing + vscrollOverlap : 0, needh ? spacing + hscrollOverlap : 0);
QRect frameRect = widgetRect;
frameRect.adjust(0, 0, -cornerOffset.x() - cornerExtra.x(), -cornerOffset.y() - cornerExtra.y());
q->setFrameRect(QStyle::visualRect(opt.direction, opt.rect, frameRect));
@@ -436,7 +438,7 @@ void QAbstractScrollAreaPrivate::layoutChildren()
// If we have a corner widget and are only showing one scroll bar, we need to move it
// to make room for the corner widget.
- if (hasCornerWidget && (needv || needh) && scrollOverlap == 0)
+ if (hasCornerWidget && ((needv && vscrollOverlap == 0) || (needh && hscrollOverlap == 0)))
cornerOffset = extPoint;
#ifdef Q_WS_MAC
@@ -452,7 +454,7 @@ void QAbstractScrollAreaPrivate::layoutChildren()
// Some styles paints the corner if both scorllbars are showing and there is
// no corner widget. Also, on the Mac we paint if there is a native
// (transparent) sizegrip in the area where a corner widget would be.
- if ((needv && needh && hasCornerWidget == false && scrollOverlap == 0)
+ if ((needv && needh && hasCornerWidget == false && hscrollOverlap == 0 && vscrollOverlap == 0)
|| ((needv || needh)
#ifdef Q_WS_MAC
&& hasMacSizeGrip
@@ -474,7 +476,7 @@ void QAbstractScrollAreaPrivate::layoutChildren()
// move the scrollbars away from top/left headers
int vHeaderRight = 0;
int hHeaderBottom = 0;
- if (scrollOverlap > 0 && (needv || needh)) {
+ if ((vscrollOverlap > 0 && needv) || (hscrollOverlap > 0 && needh)) {
const QList<QHeaderView *> headers = q->findChildren<QHeaderView*>();
if (headers.count() <= 2) {
Q_FOREACH (const QHeaderView *header, headers) {
@@ -493,20 +495,22 @@ void QAbstractScrollAreaPrivate::layoutChildren()
if (hasMacReverseSizeGrip)
horizontalScrollBarRect.adjust(vsbExt, 0, 0, 0);
#endif
+ if (!hasCornerWidget && htransient)
#ifdef Q_OS_MAC
- if (!hasCornerWidget && QSysInfo::macVersion() >= QSysInfo::MV_10_8 && transient)
- horizontalScrollBarRect.adjust(0, 0, cornerOffset.x(), 0);
+ if (QSysInfo::macVersion() >= QSysInfo::MV_10_8)
#endif
+ horizontalScrollBarRect.adjust(0, 0, cornerOffset.x(), 0);
scrollBarContainers[Qt::Horizontal]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, horizontalScrollBarRect));
scrollBarContainers[Qt::Horizontal]->raise();
}
if (needv) {
QRect verticalScrollBarRect (QPoint(cornerPoint.x(), controlsRect.top() + hHeaderBottom), QPoint(controlsRect.right(), cornerPoint.y() - 1));
+ if (!hasCornerWidget && vtransient)
#ifdef Q_OS_MAC
- if (!hasCornerWidget && QSysInfo::macVersion() >= QSysInfo::MV_10_8 && transient)
- verticalScrollBarRect.adjust(0, 0, 0, cornerOffset.y());
+ if (QSysInfo::macVersion() >= QSysInfo::MV_10_8)
#endif
+ verticalScrollBarRect.adjust(0, 0, 0, cornerOffset.y());
scrollBarContainers[Qt::Vertical]->setGeometry(QStyle::visualRect(opt.direction, opt.rect, verticalScrollBarRect));
scrollBarContainers[Qt::Vertical]->raise();
}
@@ -957,10 +961,12 @@ bool QAbstractScrollArea::eventFilter(QObject *o, QEvent *e)
{
Q_D(QAbstractScrollArea);
if ((o == d->hbar || o == d->vbar) && (e->type() == QEvent::HoverEnter || e->type() == QEvent::HoverLeave)) {
- Qt::ScrollBarPolicy policy = o == d->hbar ? d->vbarpolicy : d->hbarpolicy;
- if (policy == Qt::ScrollBarAsNeeded || style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, d->vbar ? d->vbar : d->hbar)) {
- QScrollBar *sibling = o == d->hbar ? d->vbar : d->hbar;
- d->setScrollBarTransient(sibling, e->type() == QEvent::HoverLeave);
+ if (d->hbarpolicy == Qt::ScrollBarAsNeeded && d->vbarpolicy == Qt::ScrollBarAsNeeded) {
+ QScrollBar *sbar = static_cast<QScrollBar*>(o);
+ QScrollBar *sibling = sbar == d->hbar ? d->vbar : d->hbar;
+ if (sbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, sbar) &&
+ sibling->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, sibling))
+ d->setScrollBarTransient(sibling, e->type() == QEvent::HoverLeave);
}
}
return QFrame::eventFilter(o, e);
@@ -1479,11 +1485,11 @@ bool QAbstractScrollAreaPrivate::canStartScrollingAt( const QPoint &startPos )
void QAbstractScrollAreaPrivate::flashScrollBars()
{
- Q_Q(QAbstractScrollArea);
- bool transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar ? vbar : hbar);
- if ((hbarpolicy != Qt::ScrollBarAlwaysOff) && (hbarpolicy == Qt::ScrollBarAsNeeded || transient))
+ bool htransient = hbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, hbar);
+ if ((hbarpolicy != Qt::ScrollBarAlwaysOff) && (hbarpolicy == Qt::ScrollBarAsNeeded || htransient))
hbar->d_func()->flash();
- if ((vbarpolicy != Qt::ScrollBarAlwaysOff) && (vbarpolicy == Qt::ScrollBarAsNeeded || transient))
+ bool vtransient = vbar->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, vbar);
+ if ((vbarpolicy != Qt::ScrollBarAlwaysOff) && (vbarpolicy == Qt::ScrollBarAsNeeded || vtransient))
vbar->d_func()->flash();
}
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 17a6ededfe..e0f5ac1050 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -3057,6 +3057,8 @@ void QComboBox::keyReleaseEvent(QKeyEvent *e)
Q_D(QComboBox);
if (d->lineEdit)
d->lineEdit->event(e);
+ else
+ QWidget::keyReleaseEvent(e);
}
/*!
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 7521feb72d..adec9cae18 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -310,9 +310,7 @@ QLineEditIconButton::QLineEditIconButton(QWidget *parent)
: QToolButton(parent)
, m_opacity(0)
{
-#ifndef QT_NO_CURSOR
- setCursor(Qt::ArrowCursor);
-#endif
+ updateCursor();
setFocusPolicy(Qt::NoFocus);
}
@@ -343,11 +341,19 @@ void QLineEditIconButton::setOpacity(qreal value)
void QLineEditIconButton::startOpacityAnimation(qreal endValue)
{
QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"));
+ connect(animation, &QAbstractAnimation::finished, this, &QLineEditIconButton::updateCursor);
animation->setDuration(160);
animation->setEndValue(endValue);
animation->start(QAbstractAnimation::DeleteWhenStopped);
}
+void QLineEditIconButton::updateCursor()
+{
+#ifndef QT_NO_CURSOR
+ setCursor(qFuzzyCompare(m_opacity, 1.0) || !parentWidget() ? QCursor(Qt::ArrowCursor) : parentWidget()->cursor());
+#endif
+}
+
void QLineEditPrivate::_q_textChanged(const QString &text)
{
if (hasSideWidgets()) {
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index aa5b57a920..db8edee005 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -89,6 +89,9 @@ public:
protected:
void paintEvent(QPaintEvent *event);
+private slots:
+ void updateCursor();
+
private:
void startOpacityAnimation(qreal endValue);
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 07db78c06c..1d0268a244 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1508,19 +1508,17 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
#ifdef Q_OS_OSX
Q_D(QMainWindow);
if (isWindow()) {
+ d->useUnifiedToolBar = set;
+ createWinId();
+
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
- nativeInterface->nativeResourceFunctionForIntegration("setContentBorderThickness");
+ nativeInterface->nativeResourceFunctionForIntegration("enableContentBorderArea");
if (!function)
return; // Not Cocoa platform plugin.
- createWinId();
-
- d->useUnifiedToolBar = set;
-
- const int toolBarHeight = 50;
- typedef void (*SetContentBorderThicknessFunction)(QWindow *window, int topThickness, int bottomThickness);
- (reinterpret_cast<SetContentBorderThicknessFunction>(function))(window()->windowHandle(), toolBarHeight, 0);
+ typedef void (*EnableContentBorderAreaFunction)(QWindow *window, bool enable);
+ (reinterpret_cast<EnableContentBorderAreaFunction>(function))(window()->windowHandle(), set);
}
#endif
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index 2820608621..eb93e461c0 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -75,7 +75,6 @@
QT_BEGIN_NAMESPACE
QMenu *QMenuPrivate::mouseDown = 0;
-int QMenuPrivate::sloppyDelayTimer = 0;
/* QMenu code */
// internal class used for the torn off popup
@@ -433,10 +432,6 @@ QRect QMenuPrivate::actionRect(QAction *act) const
return actionRects.at(index);
}
-#if defined(Q_OS_MAC)
-static const qreal MenuFadeTimeInSec = 0.150;
-#endif
-
void QMenuPrivate::hideUpToMenuBar()
{
Q_Q(QMenu);
@@ -2891,6 +2886,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e)
QAction *action = d->actionAt(e->pos());
if (!action || action->isSeparator()) {
if (d->hasHadMouse
+ && d->sloppyDelayTimer == 0 // Keep things as they are while we're moving to the submenu
&& (!d->currentAction || (action && action->isSeparator())
|| !(d->currentAction->menu() && d->currentAction->menu()->isVisible())))
d->setCurrentAction(0);
@@ -2900,13 +2896,13 @@ void QMenu::mouseMoveEvent(QMouseEvent *e)
}
if (d->sloppyRegion.contains(e->pos())) {
// If the timer is already running then don't start a new one unless the action is the same
- if (d->sloppyAction != action && QMenuPrivate::sloppyDelayTimer != 0) {
- killTimer(QMenuPrivate::sloppyDelayTimer);
- QMenuPrivate::sloppyDelayTimer = 0;
+ if (d->sloppyAction != action && d->sloppyDelayTimer != 0) {
+ killTimer(d->sloppyDelayTimer);
+ d->sloppyDelayTimer = 0;
}
- if (QMenuPrivate::sloppyDelayTimer == 0) {
+ if (d->sloppyDelayTimer == 0) {
d->sloppyAction = action;
- QMenuPrivate::sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this) * 6);
+ d->sloppyDelayTimer = startTimer(style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this) * 6);
}
} else if (action != d->currentAction) {
d->setCurrentAction(action, style()->styleHint(QStyle::SH_Menu_SubMenuPopupDelay, 0, this));
@@ -2948,9 +2944,9 @@ QMenu::timerEvent(QTimerEvent *e)
} else if(d->menuDelayTimer.timerId() == e->timerId()) {
d->menuDelayTimer.stop();
internalDelayedPopup();
- } else if(QMenuPrivate::sloppyDelayTimer == e->timerId()) {
- killTimer(QMenuPrivate::sloppyDelayTimer);
- QMenuPrivate::sloppyDelayTimer = 0;
+ } else if (d->sloppyDelayTimer == e->timerId()) {
+ killTimer(d->sloppyDelayTimer);
+ d->sloppyDelayTimer = 0;
internalSetSloppyAction();
} else if(d->searchBufferTimer.timerId() == e->timerId()) {
d->searchBuffer.clear();
diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h
index afd34a5c47..9d9851af64 100644
--- a/src/widgets/widgets/qmenu_p.h
+++ b/src/widgets/widgets/qmenu_p.h
@@ -92,7 +92,7 @@ public:
cancelAction(0),
#endif
scroll(0), eventLoop(0), tearoff(0), tornoff(0), tearoffHighlighted(0),
- hasCheckableItems(0), sloppyAction(0), doChildEffects(false), platformMenu(0)
+ hasCheckableItems(0), sloppyDelayTimer(0), sloppyAction(0), doChildEffects(false), platformMenu(0)
#if defined(Q_OS_WINCE) && !defined(QT_NO_MENUBAR)
,wce_menu(0)
@@ -204,7 +204,7 @@ public:
mutable bool hasCheckableItems;
//sloppy selection
- static int sloppyDelayTimer;
+ int sloppyDelayTimer;
mutable QAction *sloppyAction;
QRegion sloppyRegion;
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index f6ec2a75aa..e41cb64463 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -1810,7 +1810,7 @@ void QPlainTextEdit::keyReleaseEvent(QKeyEvent *e)
}
}
#else
- Q_UNUSED(e);
+ QWidget::keyReleaseEvent(e);
#endif
}
@@ -2185,6 +2185,13 @@ void QPlainTextEdit::scrollContentsBy(int dx, int /*dy*/)
*/
QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
+ return inputMethodQuery(property, QVariant());
+}
+
+/*!\internal
+ */
+QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
+{
Q_D(const QPlainTextEdit);
QVariant v;
switch (property) {
@@ -2192,7 +2199,7 @@ QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
v = QWidget::inputMethodQuery(property);
break;
default:
- v = d->control->inputMethodQuery(property, QVariant());
+ v = d->control->inputMethodQuery(property, argument);
const QPoint offset(-d->horizontalOffset(), -0);
if (v.type() == QVariant::RectF)
v = v.toRectF().toRect().translated(offset);
diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h
index 1fb4625fb1..54cd3e14ed 100644
--- a/src/widgets/widgets/qplaintextedit.h
+++ b/src/widgets/widgets/qplaintextedit.h
@@ -185,6 +185,7 @@ public:
int blockCount() const;
QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
public Q_SLOTS:
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index fe919feba9..020d180778 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <qapplication.h>
#include <qaction.h>
#include <qwidgetaction.h>
#include <qtoolbar.h>
@@ -47,6 +48,9 @@
#include <qmenu.h>
#include <qdebug.h>
#include <qmath.h>
+#ifdef Q_OS_OSX
+#include <qpa/qplatformnativeinterface.h>
+#endif
#include "qmainwindowlayout_p.h"
#include "qtoolbarextension_p.h"
@@ -341,6 +345,37 @@ static bool defaultWidgetAction(QToolBarItem *item)
return a != 0 && a->defaultWidget() == item->widget();
}
+void QToolBarLayout::updateMacBorderMetrics()
+{
+#ifdef Q_OS_OSX
+ QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
+ if (!tb)
+ return;
+
+ QRect rect = geometry();
+
+ QMainWindow *mainWindow = qobject_cast<QMainWindow*>(tb->parentWidget());
+ if (!mainWindow || !mainWindow->isWindow() || !mainWindow->unifiedTitleAndToolBarOnMac())
+ return;
+
+ QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("registerContentBorderArea");
+ if (!function)
+ return; // Not Cocoa platform plugin.
+
+ QPoint upper = tb->mapToParent(rect.topLeft());
+ QPoint lower = tb->mapToParent(rect.bottomLeft() + QPoint(0, 1));
+
+ typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, void *identifier, int upper, int lower);
+ if (mainWindow->toolBarArea(tb) == Qt::TopToolBarArea) {
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, upper.y(), lower.y());
+ } else {
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, 0, 0);
+ }
+#endif
+}
+
void QToolBarLayout::setGeometry(const QRect &rect)
{
QToolBar *tb = qobject_cast<QToolBar*>(parentWidget());
@@ -355,6 +390,8 @@ void QToolBarLayout::setGeometry(const QRect &rect)
QLayout::setGeometry(rect);
+ updateMacBorderMetrics();
+
bool ranOutOfSpace = false;
if (!animating)
ranOutOfSpace = layoutActions(rect.size());
diff --git a/src/widgets/widgets/qtoolbarlayout_p.h b/src/widgets/widgets/qtoolbarlayout_p.h
index 8605a9a6ac..b250f3adee 100644
--- a/src/widgets/widgets/qtoolbarlayout_p.h
+++ b/src/widgets/widgets/qtoolbarlayout_p.h
@@ -111,6 +111,7 @@ public:
void updateMarginAndSpacing();
bool hasExpandFlag() const;
+ void updateMacBorderMetrics();
public Q_SLOTS:
void setExpanded(bool b);
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index 151294d2c4..22d3f5bd91 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -81,6 +81,27 @@ typedef ITypedEventHandler<Core::CoreApplicationView *, Activation::IActivatedEv
static int g_mainExitCode;
+static QtMessageHandler defaultMessageHandler;
+static void devMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message)
+{
+#ifndef Q_OS_WINPHONE
+ static HANDLE shmem = 0;
+ static HANDLE event = 0;
+ if (!shmem)
+ shmem = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 4096, L"qdebug-shmem");
+ if (!event)
+ event = CreateEventEx(NULL, L"qdebug-event", 0, EVENT_ALL_ACCESS);
+
+ void *data = MapViewOfFileFromApp(shmem, FILE_MAP_WRITE, 0, 4096);
+ memset(data, quint32(type), sizeof(quint32));
+ memcpy_s(static_cast<quint32 *>(data) + 1, 4096 - sizeof(quint32),
+ message.data(), (message.length() + 1) * sizeof(wchar_t));
+ UnmapViewOfFile(data);
+ SetEvent(event);
+#endif // !Q_OS_WINPHONE
+ defaultMessageHandler(type, context, message);
+}
+
class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView>
{
public:
@@ -127,6 +148,10 @@ public:
// (Unused) handle will automatically be closed when the app exits
CreateFile2(reinterpret_cast<LPCWSTR>(pidFileName.utf16()),
0, FILE_SHARE_READ|FILE_SHARE_DELETE, CREATE_ALWAYS, &params);
+ // Install the develMode message handler
+#ifndef Q_OS_WINPHONE
+ defaultMessageHandler = qInstallMessageHandler(devMessageHandler);
+#endif
}
// Wait for debugger before continuing
if (debugWait) {