summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.cc33
-rw-r--r--src/3rdparty/md5/md5.cpp2
-rw-r--r--src/3rdparty/sqlite/sqlite3.c8
-rw-r--r--src/3rdparty/sqlite/sqlite3.h4
-rw-r--r--src/3rdparty/xkbcommon.pri5
-rw-r--r--src/3rdparty/xkbcommon/NEWS43
-rw-r--r--src/3rdparty/xkbcommon/README114
-rw-r--r--src/3rdparty/xkbcommon/README.md109
-rw-r--r--src/3rdparty/xkbcommon/src/context-priv.c41
-rw-r--r--src/3rdparty/xkbcommon/src/context.c6
-rw-r--r--src/3rdparty/xkbcommon/src/context.h17
-rw-r--r--src/3rdparty/xkbcommon/src/darray.h250
-rw-r--r--src/3rdparty/xkbcommon/src/keymap-priv.c16
-rw-r--r--src/3rdparty/xkbcommon/src/keymap.h6
-rw-r--r--src/3rdparty/xkbcommon/src/keysym-utf.c48
-rw-r--r--src/3rdparty/xkbcommon/src/keysym.c6
-rw-r--r--src/3rdparty/xkbcommon/src/scanner-utils.h (renamed from src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h)26
-rw-r--r--src/3rdparty/xkbcommon/src/state.c308
-rw-r--r--src/3rdparty/xkbcommon/src/text.c14
-rw-r--r--src/3rdparty/xkbcommon/src/utf8.c142
-rw-r--r--src/3rdparty/xkbcommon/src/utf8.h36
-rw-r--r--src/3rdparty/xkbcommon/src/utils.h22
-rw-r--r--src/3rdparty/xkbcommon/src/x11/x11-keymap.c73
-rw-r--r--src/3rdparty/xkbcommon/src/x11/x11-priv.h2
-rw-r--r--src/3rdparty/xkbcommon/src/xkb-keymap.c33
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/action.c427
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c59
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h10
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/ast.h10
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/compat.c203
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/expr.c12
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c81
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c91
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keymap.c8
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/keywords.c5
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h12
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser.c472
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/parser.h2
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/rules.c259
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/scanner.c54
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/symbols.c129
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/types.c121
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/vmod.c63
-rw-r--r--src/3rdparty/xkbcommon/src/xkbcomp/vmod.h3
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h4
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h8
-rw-r--r--src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h140
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java15
-rw-r--r--src/angle/src/d3dcompiler/main.cpp2
-rw-r--r--src/corelib/animation/qabstractanimation.cpp10
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp12
-rw-r--r--src/corelib/global/qcompilerdetection.h10
-rw-r--r--src/corelib/global/qglobal.h2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp16
-rw-r--r--src/corelib/global/qprocessordetection.h12
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp7
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp4
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm2
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp3
-rw-r--r--src/corelib/io/qloggingregistry.cpp13
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp4
-rw-r--r--src/corelib/kernel/qjni.cpp11
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp8
-rw-r--r--src/corelib/thread/qmutex.cpp12
-rw-r--r--src/corelib/thread/qmutex.h6
-rw-r--r--src/corelib/tools/qbytearray.h2
-rw-r--r--src/corelib/tools/qstring.cpp18
-rw-r--r--src/gui/accessible/accessible.pri2
-rw-r--r--src/gui/accessible/qaccessible.cpp28
-rw-r--r--src/gui/accessible/qaccessiblecache.cpp13
-rw-r--r--src/gui/accessible/qaccessiblecache_mac.mm67
-rw-r--r--src/gui/accessible/qaccessiblecache_p.h29
-rw-r--r--src/gui/doc/qtgui.qdocconf2
-rw-r--r--src/gui/doc/src/qtgui.qdoc52
-rw-r--r--src/gui/gui.pro13
-rw-r--r--src/gui/kernel/qguiapplication.cpp17
-rw-r--r--src/gui/kernel/qkeysequence.cpp16
-rw-r--r--src/gui/kernel/qopenglcontext.cpp33
-rw-r--r--src/gui/kernel/qopenglcontext.h3
-rw-r--r--src/gui/kernel/qopenglcontext_p.h3
-rw-r--r--src/gui/kernel/qplatformmenu.h6
-rw-r--r--src/gui/kernel/qplatformtheme.cpp26
-rw-r--r--src/gui/kernel/qstylehints.cpp2
-rw-r--r--src/gui/kernel/qwindow.cpp3
-rw-r--r--src/gui/opengl/qopenglbuffer.cpp16
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp2
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp22
-rw-r--r--src/gui/opengl/qopengltextureblitter.cpp6
-rw-r--r--src/gui/opengl/qopengltextureblitter_p.h1
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp11
-rw-r--r--src/gui/painting/qdrawhelper_neon_p.h4
-rw-r--r--src/gui/painting/qpagedpaintdevice.cpp146
-rw-r--r--src/gui/painting/qpagedpaintdevice.h12
-rw-r--r--src/gui/painting/qpagedpaintdevice_p.h42
-rw-r--r--src/gui/painting/qpagelayout.cpp82
-rw-r--r--src/gui/painting/qpagelayout.h30
-rw-r--r--src/gui/painting/qpagesize.cpp326
-rw-r--r--src/gui/painting/qpagesize.h54
-rw-r--r--src/gui/painting/qpdfwriter.cpp129
-rw-r--r--src/gui/painting/qpdfwriter.h5
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp10
-rw-r--r--src/gui/painting/qplatformbackingstore.h2
-rw-r--r--src/gui/text/qfontengine.cpp5
-rw-r--r--src/gui/text/qharfbuzzng.cpp8
-rw-r--r--src/gui/text/qtextengine.cpp53
-rw-r--r--src/gui/text/qtextimagehandler.cpp42
-rw-r--r--src/gui/text/qtextlayout.cpp5
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp27
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp3
-rw-r--r--src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp2
-rw-r--r--src/network/ssl/qsslcontext.cpp59
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp3
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp10
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h11
-rw-r--r--src/opengl/opengl.pro1
-rw-r--r--src/opengl/qgl.cpp10
-rw-r--r--src/opengl/qgl_qpa.cpp5
-rw-r--r--src/opengl/qglbuffer.cpp16
-rw-r--r--src/opengl/qglframebufferobject.cpp3
-rw-r--r--src/opengl/qglfunctions.cpp22
-rw-r--r--src/openglextensions/openglextensions.pro1
-rw-r--r--src/platformsupport/fbconvenience/qfbcursor.cpp2
-rw-r--r--src/plugins/generic/evdevkeyboard/evdevkeyboard.pro1
-rw-r--r--src/plugins/generic/evdevmouse/evdevmouse.pro1
-rw-r--r--src/plugins/generic/evdevtablet/evdevtablet.pro1
-rw-r--r--src/plugins/generic/evdevtouch/evdevtouch.pro1
-rw-r--r--src/plugins/generic/meego/meego.pro1
-rw-r--r--src/plugins/generic/tslib/tslib.pro1
-rw-r--r--src/plugins/platforminputcontexts/compose/compose.pro1
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp2
-rw-r--r--src/plugins/platforminputcontexts/ibus/ibus.pro1
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp467
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp3
-rw-r--r--src/plugins/platforms/cocoa/messages.cpp8
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm43
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h5
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm101
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm37
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenubar.mm63
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamimetypes.mm67
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h17
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm33
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintdevice.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm93
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm5
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm40
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm3
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp19
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp46
-rw-r--r--src/plugins/platforms/windows/qplatformfunctions_wince.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp33
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp50
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h11
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp2
-rw-r--r--src/plugins/platformthemes/gtk2/gtk2.pro1
-rw-r--r--src/printsupport/kernel/qcups.cpp2
-rw-r--r--src/printsupport/kernel/qprinter.cpp160
-rw-r--r--src/printsupport/kernel/qprinter.h6
-rw-r--r--src/printsupport/printsupport.pro3
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp45
-rw-r--r--src/src.pro4
-rw-r--r--src/testlib/qtestcase.cpp7
-rw-r--r--src/testlib/qtestcase.h14
-rw-r--r--src/widgets/accessible/widgets.pro1
-rw-r--r--src/widgets/kernel/qapplication_qpa.cpp14
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp8
-rw-r--r--src/widgets/kernel/qwidget.cpp7
-rw-r--r--src/widgets/kernel/qwidget_qpa.cpp20
-rw-r--r--src/widgets/kernel/qwidgetwindow.cpp14
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm63
-rw-r--r--src/widgets/styles/qstyle.cpp3
-rw-r--r--src/widgets/styles/qstyle.h1
-rw-r--r--src/widgets/widgets/qcombobox.cpp108
-rw-r--r--src/widgets/widgets/qcombobox_p.h4
-rw-r--r--src/widgets/widgets/qmainwindow.cpp6
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp12
-rw-r--r--src/widgets/widgets/qmdisubwindow.cpp2
-rw-r--r--src/widgets/widgets/qtabbar.cpp71
-rw-r--r--src/widgets/widgets/qtabbar_p.h1
-rw-r--r--src/widgets/widgets/qtoolbar.cpp19
-rw-r--r--src/widgets/widgets/qtoolbararealayout.cpp38
-rw-r--r--src/widgets/widgets/qtoolbararealayout_p.h2
-rw-r--r--src/widgets/widgets/qtoolbarlayout.cpp4
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp28
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p.h1
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p_p.h1
-rw-r--r--src/winmain/qtmain_winrt.cpp19
202 files changed, 4213 insertions, 2955 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
index 40c06371bd..4a905ee189 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
@@ -691,11 +691,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
CFDictionaryRef attributes = CTRunGetAttributes (run);
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
+
+ CFRange range = CTRunGetStringRange (run);
if (!CFEqual (run_cg_font, face_data->cg_font))
{
CFRelease (run_cg_font);
- CFRange range = CTRunGetStringRange (run);
buffer->ensure (buffer->len + range.length);
if (buffer->in_error)
FAIL ("Buffer resize failed");
@@ -732,11 +733,16 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
}
CFRelease (run_cg_font);
+ /* CoreText throws away the PDF token, while the OpenType backend will add a zero-advance
+ * glyph for this. We need to make sure the two produce the same output. */
+ UniChar endGlyph = CFStringGetCharacterAtIndex(string_ref, range.location + range.length - 1);
+ bool endWithPDF = endGlyph == 0x202c;
+
unsigned int num_glyphs = CTRunGetGlyphCount (run);
if (num_glyphs == 0)
continue;
- buffer->ensure (buffer->len + num_glyphs);
+ buffer->ensure (buffer->len + num_glyphs + (endWithPDF ? 1 : 0));
scratch = buffer->get_scratch_buffer (&scratch_size);
@@ -783,10 +789,27 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
buffer->len++;
}
+
+ if (endWithPDF) {
+ hb_glyph_info_t *info = &buffer->info[buffer->len];
+
+ info->codepoint = 0xffff;
+ info->cluster = range.location + range.length - 1;
+
+ /* Currently, we do all x-positioning by setting the advance, we never use x-offset. */
+ info->mask = 0;
+ info->var1.u32 = 0;
+ info->var2.u32 = 0;
+
+ buffer->len++;
+ }
}
buffer->clear_positions ();
+ bool bufferRtl = !HB_DIRECTION_IS_FORWARD (buffer->props.direction);
+ bool runRtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(glyph_runs, 0))) & kCTRunStatusRightToLeft);
+
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; ++i) {
hb_glyph_info_t *info = &buffer->info[i];
@@ -796,6 +819,12 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
pos->x_advance = info->mask;
pos->x_offset = info->var1.u32;
pos->y_offset = info->var2.u32;
+
+ if (bufferRtl != runRtl && i < count / 2) {
+ unsigned int temp = buffer->info[count - i - 1].cluster;
+ buffer->info[count - i - 1].cluster = info->cluster;
+ info->cluster = temp;
+ }
}
/* Fix up clusters so that we never return out-of-order indices;
diff --git a/src/3rdparty/md5/md5.cpp b/src/3rdparty/md5/md5.cpp
index 16871e6626..cc69b56213 100644
--- a/src/3rdparty/md5/md5.cpp
+++ b/src/3rdparty/md5/md5.cpp
@@ -161,7 +161,7 @@ MD5Final(struct MD5Context *ctx, md5byte digest[16])
static void
MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
{
- register UWORD32 a, b, c, d;
+ UWORD32 a, b, c, d;
a = buf[0];
b = buf[1];
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index f8a10149bc..27b5beac12 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.4.2. By combining all the individual C code files into this
+** version 3.8.4.3. 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
@@ -222,9 +222,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.4.2"
+#define SQLITE_VERSION "3.8.4.3"
#define SQLITE_VERSION_NUMBER 3008004
-#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e"
+#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -115273,7 +115273,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
for(; k<last; k++, pOp++){
if( pOp->p1!=pLevel->iTabCur ) continue;
if( pOp->opcode==OP_Column ){
- pOp->opcode = OP_SCopy;
+ pOp->opcode = OP_Copy;
pOp->p1 = pOp->p2 + pTabItem->regResult;
pOp->p2 = pOp->p3;
pOp->p3 = 0;
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index d0d676afae..0884ebad0e 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.4.2"
+#define SQLITE_VERSION "3.8.4.3"
#define SQLITE_VERSION_NUMBER 3008004
-#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e"
+#define SQLITE_SOURCE_ID "2014-04-03 16:53:12 a611fa96c4a848614efe899130359c9f6fb889c3"
/*
** CAPI3REF: Run-Time Library Version Numbers
diff --git a/src/3rdparty/xkbcommon.pri b/src/3rdparty/xkbcommon.pri
index eb34403746..eaef4749db 100644
--- a/src/3rdparty/xkbcommon.pri
+++ b/src/3rdparty/xkbcommon.pri
@@ -26,7 +26,8 @@ SOURCES += \
$$PWD/xkbcommon/src/text.c \
$$PWD/xkbcommon/src/context-priv.c \
$$PWD/xkbcommon/src/keymap-priv.c \
- $$PWD/xkbcommon/src/utils.c
+ $$PWD/xkbcommon/src/utils.c \
+ $$PWD/xkbcommon/src/utf8.c
SOURCES += \
$$PWD/xkbcommon/src/xkbcomp/action.c \
@@ -54,7 +55,7 @@ SOURCES += \
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
+ $$PWD/xkbcommon/src/x11/x11-state.c # renamed: state.c -> x11-state.c
}
TR_EXCLUDE += $$PWD/*
diff --git a/src/3rdparty/xkbcommon/NEWS b/src/3rdparty/xkbcommon/NEWS
index 450b7535ee..07ebdd97e3 100644
--- a/src/3rdparty/xkbcommon/NEWS
+++ b/src/3rdparty/xkbcommon/NEWS
@@ -1,3 +1,46 @@
+libxkbcommon 0.4.1
+==================
+
+- Converted README to markdown and added a Quick Guide to the
+ documentation, which breezes through the most common parts of
+ xkbcommon.
+
+- Added two new functions, xkb_state_key_get_utf{8,32}(). They
+ combine the operations of xkb_state_key_get_syms() and
+ xkb_keysym_to_utf{8,32}(), and provide a nicer interface for it
+ (espcially for multiple-keysyms-per-level).
+
+- The xkb_state_key_get_utf{8,32}() functions now apply Control
+ transformation: when the Control modifier is active, the string
+ is converted to an appropriate control character.
+ This matches the behavior of libX11's XLookupString(3), and
+ required by the XKB specification:
+ http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=75892
+
+- The consumed modifiers for a key are now calculated similarly
+ to libX11. The previous behavior caused a bug where Shift would
+ not cancel an active Caps Lock.
+
+- Make xkbcommon-x11 work with the keymap reported by the XQuartz
+ X server.
+
+ https://bugs.freedesktop.org/show_bug.cgi?id=75798
+
+- Reduce memory usage during keymap compilation some more.
+
+- New API:
+ xkb_state_key_get_consumed_mods()
+ xkb_state_key_get_utf8()
+ xkb_state_key_get_utf32()
+
+- Deprecated API:
+ XKB_MAP_COMPILE_PLACEHOLDER, XKB_MAP_NO_FLAGS
+ use XKB_KEYMAP_NO_FLAGS instead.
+
+- Bug fixes.
+
libxkbcommon 0.4.0
==================
diff --git a/src/3rdparty/xkbcommon/README b/src/3rdparty/xkbcommon/README
deleted file mode 100644
index 6b99c46620..0000000000
--- a/src/3rdparty/xkbcommon/README
+++ /dev/null
@@ -1,114 +0,0 @@
-Overview {#mainpage}
-========
-
-xkbcommon is a keymap compiler and support library which processes a
-reduced subset of keymaps as defined by the XKB specification. Primarily,
-a keymap is created from a set of Rules/Model/Layout/Variant/Options names,
-processed through an XKB ruleset, and compiled into a struct xkb_keymap,
-which is the base type for all xkbcommon operations.
-
-From an xkb_keymap, an xkb_state object is created which holds the current
-state of all modifiers, groups, LEDs, etc, relating to that keymap. All
-key events must be fed into the xkb_state object using xkb_state_update_key().
-Once this is done, the xkb_state object will be properly updated, and the
-keysyms to use can be obtained with xkb_state_key_get_syms().
-
-libxkbcommon does not distribute a dataset itself, other than for testing
-purposes. The most common dataset is xkeyboard-config, as used by all
-current distributions for their X11 XKB data. More information on
-xkeyboard-config is available here:
- http://www.freedesktop.org/wiki/Software/XKeyboardConfig
-
-
-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 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>.
-
-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
-===============
-
-Relative to the XKB 1.1 specification implemented in current X servers,
-xkbcommon has removed support for some parts of the specification which
-introduced unnecessary complications. Many of these removals were in fact
-not implemented, or half-implemented at best, as well as being totally
-unused in the standard dataset.
-
-Notable removals:
- - geometry support
- + there were very few geometry definitions available, and while
- xkbcommon was responsible for parsing this insanely complex format,
- it never actually did anything with it
- + hopefully someone will develop a companion library which supports
- keyboard geometries in a more useful format
- - KcCGST (keycodes/compat/geometry/symbols/types) API
- + use RMLVO instead; KcCGST is now an implementation detail
- + including pre-defined keymap files
- - XKM support
- + may come in an optional X11 support/compatibility library
- - around half of the interpret actions
- + pointer device, message and redirect actions in particular
- - non-virtual modifiers
- + core and virtual modifiers have been collapsed into the same
- namespace, with a 'significant' flag that largely parallels the
- core/virtual split
- - radio groups
- + completely unused in current keymaps, never fully implemented
- - overlays
- + almost completely unused in current keymaps
- - key behaviors
- + used to implement radio groups and overlays, and to deal with things
- like keys that physically lock; unused in current keymaps
- - indicator behaviours such as LED-controls-key
- + the only supported LED behaviour is key-controls-LED; again this
- was never really used in current keymaps
-
-Notable additions:
- - 32-bit keycodes
- - extended number of modifiers
- - extended number of groups
- - multiple keysyms per level
- + this requires incompatible dataset changes, such that X11 would
- not be able to parse these
-
-
-Development
-===========
-
-An extremely rudimentary homepage can be found at:
- http://xkbcommon.org
-
-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:
- https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon
-Or in github at:
- https://github.com/xkbcommon/libxkbcommon/issues
-
-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.
diff --git a/src/3rdparty/xkbcommon/README.md b/src/3rdparty/xkbcommon/README.md
new file mode 100644
index 0000000000..2627a324a6
--- /dev/null
+++ b/src/3rdparty/xkbcommon/README.md
@@ -0,0 +1,109 @@
+# libxkbcommon
+
+xkbcommon is a keymap compiler and support library which processes a
+reduced subset of keymaps as defined by the XKB specification. Primarily,
+a keymap is created from a set of Rules/Model/Layout/Variant/Options names,
+processed through an XKB ruleset, and compiled into a struct xkb_keymap,
+which is the base type for all xkbcommon operations.
+
+From an xkb_keymap, an xkb_state object is created which holds the current
+state of all modifiers, groups, LEDs, etc, relating to that keymap. All
+key events must be fed into the xkb_state object using xkb_state_update_key().
+Once this is done, the xkb_state object will be properly updated, and the
+keysyms to use can be obtained with xkb_state_key_get_syms().
+
+libxkbcommon does not distribute a dataset itself, other than for testing
+purposes. The most common dataset is xkeyboard-config, as used by all
+current distributions for their X11 XKB data. More information on
+xkeyboard-config is available here:
+ http://www.freedesktop.org/wiki/Software/XKeyboardConfig
+
+## Quick Guide
+
+See [Quick Guide](doc/quick-guide.md).
+
+## 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 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.
+
+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
+
+Relative to the XKB 1.1 specification implemented in current X servers,
+xkbcommon has removed support for some parts of the specification which
+introduced unnecessary complications. Many of these removals were in fact
+not implemented, or half-implemented at best, as well as being totally
+unused in the standard dataset.
+
+Notable removals:
+- geometry support
+ + there were very few geometry definitions available, and while
+ xkbcommon was responsible for parsing this insanely complex format,
+ it never actually did anything with it
+ + hopefully someone will develop a companion library which supports
+ keyboard geometries in a more useful format
+- KcCGST (keycodes/compat/geometry/symbols/types) API
+ + use RMLVO instead; KcCGST is now an implementation detail
+ + including pre-defined keymap files
+- XKM support
+ + may come in an optional X11 support/compatibility library
+- around half of the interpret actions
+ + pointer device, message and redirect actions in particular
+- non-virtual modifiers
+ + core and virtual modifiers have been collapsed into the same
+ namespace, with a 'significant' flag that largely parallels the
+ core/virtual split
+- radio groups
+ + completely unused in current keymaps, never fully implemented
+- overlays
+ + almost completely unused in current keymaps
+- key behaviors
+ + used to implement radio groups and overlays, and to deal with things
+ like keys that physically lock; unused in current keymaps
+- indicator behaviours such as LED-controls-key
+ + the only supported LED behaviour is key-controls-LED; again this
+ was never really used in current keymaps
+
+Notable additions:
+- 32-bit keycodes
+- extended number of modifiers
+- extended number of groups
+- multiple keysyms per level
+ + this requires incompatible dataset changes, such that X11 would
+ not be able to parse these
+
+## Development
+
+An extremely rudimentary homepage can be found at
+ http://xkbcommon.org
+
+xkbcommon is maintained in git at
+ 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 also welcome, and may be reported either at
+ Bugzilla https://bugs.freedesktop.org/describecomponents.cgi?product=libxkbcommon
+or
+ Github https://github.com/xkbcommon/libxkbcommon/issues
+
+The maintainers are
+- Daniel Stone <daniel@fooishbar.org>
+- Ran Benita <ran234@gmail.com>
+
+## Credits
+
+Many thanks are due to Dan Nicholson for his heroic work in getting xkbcommon
+off the ground initially.
diff --git a/src/3rdparty/xkbcommon/src/context-priv.c b/src/3rdparty/xkbcommon/src/context-priv.c
index 4d7b2ed110..c934201685 100644
--- a/src/3rdparty/xkbcommon/src/context-priv.c
+++ b/src/3rdparty/xkbcommon/src/context-priv.c
@@ -112,60 +112,79 @@ xkb_context_get_buffer(struct xkb_context *ctx, size_t size)
#define DEFAULT_XKB_OPTIONS NULL
#endif
-const char *
+static 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");
+ env = secure_getenv("XKB_DEFAULT_RULES");
return env ? env : DEFAULT_XKB_RULES;
}
-const char *
+static 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");
+ env = secure_getenv("XKB_DEFAULT_MODEL");
return env ? env : DEFAULT_XKB_MODEL;
}
-const char *
+static 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");
+ env = secure_getenv("XKB_DEFAULT_LAYOUT");
return env ? env : DEFAULT_XKB_LAYOUT;
}
-const char *
+static const char *
xkb_context_get_default_variant(struct xkb_context *ctx)
{
const char *env = NULL;
- const char *layout = getenv("XKB_DEFAULT_VARIANT");
+ const char *layout = secure_getenv("XKB_DEFAULT_LAYOUT");
/* 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");
+ env = secure_getenv("XKB_DEFAULT_VARIANT");
return env ? env : DEFAULT_XKB_VARIANT;
}
-const char *
+static 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");
+ env = secure_getenv("XKB_DEFAULT_OPTIONS");
return env ? env : DEFAULT_XKB_OPTIONS;
}
+
+void
+xkb_context_sanitize_rule_names(struct xkb_context *ctx,
+ struct xkb_rule_names *rmlvo)
+{
+ if (isempty(rmlvo->rules))
+ rmlvo->rules = xkb_context_get_default_rules(ctx);
+ if (isempty(rmlvo->model))
+ rmlvo->model = xkb_context_get_default_model(ctx);
+ /* Layout and variant are tied together, so don't try to use one from
+ * the caller and one from the environment. */
+ if (isempty(rmlvo->layout)) {
+ rmlvo->layout = xkb_context_get_default_layout(ctx);
+ rmlvo->variant = xkb_context_get_default_variant(ctx);
+ }
+ /* Options can be empty, so respect that if passed in. */
+ if (rmlvo->options == NULL)
+ rmlvo->options = xkb_context_get_default_options(ctx);
+}
diff --git a/src/3rdparty/xkbcommon/src/context.c b/src/3rdparty/xkbcommon/src/context.c
index e64b91542f..e9c52ebeee 100644
--- a/src/3rdparty/xkbcommon/src/context.c
+++ b/src/3rdparty/xkbcommon/src/context.c
@@ -82,7 +82,7 @@ xkb_context_include_path_append_default(struct xkb_context *ctx)
ret |= xkb_context_include_path_append(ctx, DFLT_XKB_CONFIG_ROOT);
- home = getenv("HOME");
+ home = secure_getenv("HOME");
if (!home)
return ret;
err = asprintf(&user_path, "%s/.xkb", home);
@@ -252,11 +252,11 @@ xkb_context_new(enum xkb_context_flags flags)
ctx->log_verbosity = 0;
/* Environment overwrites defaults. */
- env = getenv("XKB_LOG_LEVEL");
+ env = secure_getenv("XKB_LOG_LEVEL");
if (env)
xkb_context_set_log_level(ctx, log_level(env));
- env = getenv("XKB_LOG_VERBOSITY");
+ env = secure_getenv("XKB_LOG_VERBOSITY");
if (env)
xkb_context_set_log_verbosity(ctx, log_verbosity(env));
diff --git a/src/3rdparty/xkbcommon/src/context.h b/src/3rdparty/xkbcommon/src/context.h
index 486f4085a6..03e6d50abb 100644
--- a/src/3rdparty/xkbcommon/src/context.h
+++ b/src/3rdparty/xkbcommon/src/context.h
@@ -91,20 +91,9 @@ ATTR_PRINTF(4, 5) void
xkb_log(struct xkb_context *ctx, enum xkb_log_level level, int verbosity,
const char *fmt, ...);
-const char *
-xkb_context_get_default_rules(struct xkb_context *ctx);
-
-const char *
-xkb_context_get_default_model(struct xkb_context *ctx);
-
-const char *
-xkb_context_get_default_layout(struct xkb_context *ctx);
-
-const char *
-xkb_context_get_default_variant(struct xkb_context *ctx);
-
-const char *
-xkb_context_get_default_options(struct xkb_context *ctx);
+void
+xkb_context_sanitize_rule_names(struct xkb_context *ctx,
+ struct xkb_rule_names *rmlvo);
/*
* The format is not part of the argument list in order to avoid the
diff --git a/src/3rdparty/xkbcommon/src/darray.h b/src/3rdparty/xkbcommon/src/darray.h
index 0cf3747be7..d3fe37b089 100644
--- a/src/3rdparty/xkbcommon/src/darray.h
+++ b/src/3rdparty/xkbcommon/src/darray.h
@@ -23,93 +23,15 @@
#ifndef CCAN_DARRAY_H
#define CCAN_DARRAY_H
+/* Originally taken from: http://ccodearchive.net/info/darray.html
+ * But modified for libxkbcommon. */
+
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
+#include <limits.h>
-/*
- * SYNOPSIS
- *
- * Life cycle of a darray (dynamically-allocated array):
- *
- * darray(int) a = darray_new();
- * darray_free(a);
- *
- * struct {darray(int) a;} foo;
- * darray_init(foo.a);
- * darray_free(foo.a);
- *
- * Typedefs for darrays of common types:
- *
- * darray_char, darray_schar, darray_uchar
- * darray_short, darray_int, darray_long
- * darray_ushort, darray_uint, darray_ulong
- *
- * Access:
- *
- * T darray_item(darray(T) arr, size_t index);
- * size_t darray_size(darray(T) arr);
- * size_t darray_alloc(darray(T) arr);
- * bool darray_empty(darray(T) arr);
- *
- * // Access raw memory, starting from the item in offset.
- * // Not safe, be careful, etc.
- * T* darray_mem(darray(T) arr, size_t offset);
- *
- * Insertion (single item):
- *
- * void darray_append(darray(T) arr, T item);
- * void darray_prepend(darray(T) arr, T item);
- * void darray_push(darray(T) arr, T item); // same as darray_append
- *
- * Insertion (multiple items):
- *
- * void darray_append_items(darray(T) arr, T *items, size_t count);
- * void darray_prepend_items(darray(T) arr, T *items, size_t count);
- *
- * void darray_appends(darray(T) arr, [T item, [...]]);
- * void darray_prepends(darray(T) arr, [T item, [...]]);
- *
- * Removal:
- *
- * T darray_pop(darray(T) arr | darray_size(arr) != 0);
- * T* darray_pop_check(darray(T*) arr);
- *
- * Replacement:
- *
- * void darray_from_items(darray(T) arr, T *items, size_t count);
- * void darray_from_c(darray(T) arr, T c_array[N]);
- *
- * String buffer:
- *
- * void darray_append_string(darray(char) arr, const char *str);
- * void darray_append_lit(darray(char) arr, char stringLiteral[N+1]);
- *
- * void darray_prepend_string(darray(char) arr, const char *str);
- * void darray_prepend_lit(darray(char) arr, char stringLiteral[N+1]);
- *
- * void darray_from_string(darray(T) arr, const char *str);
- * void darray_from_lit(darray(char) arr, char stringLiteral[N+1]);
- *
- * Size management:
- *
- * void darray_resize(darray(T) arr, size_t newSize);
- * void darray_resize0(darray(T) arr, size_t newSize);
- *
- * void darray_realloc(darray(T) arr, size_t newAlloc);
- * void darray_growalloc(darray(T) arr, size_t newAlloc);
- *
- * Traversal:
- *
- * darray_foreach(T *&i, darray(T) arr) {...}
- * darray_foreach_reverse(T *&i, darray(T) arr) {...}
- *
- * Except for darray_foreach and darray_foreach_reverse,
- * all macros evaluate their non-darray arguments only once.
- */
-
-/*** Life cycle ***/
-
-#define darray(type) struct { type *item; size_t size; size_t alloc; }
+#define darray(type) struct { type *item; unsigned size; unsigned alloc; }
#define darray_new() { 0, 0, 0 }
@@ -118,7 +40,8 @@
} while (0)
#define darray_free(arr) do { \
- free((arr).item); darray_init(arr); \
+ free((arr).item); \
+ darray_init(arr); \
} while (0)
/*
@@ -154,11 +77,8 @@ typedef darray (unsigned long) darray_ulong;
#define darray_item(arr, i) ((arr).item[i])
#define darray_size(arr) ((arr).size)
-#define darray_alloc(arr) ((arr).alloc)
#define darray_empty(arr) ((arr).size == 0)
-
#define darray_mem(arr, offset) ((arr).item + (offset))
-#define darray_same(arr1, arr2) ((arr1).item == (arr2).item)
/*** Insertion (single item) ***/
@@ -167,74 +87,20 @@ typedef darray (unsigned long) darray_ulong;
(arr).item[(arr).size - 1] = (__VA_ARGS__); \
} while (0)
-#define darray_prepend(arr, ...) do { \
- darray_resize(arr, (arr).size + 1); \
- memmove((arr).item + 1, (arr).item, \
- ((arr).size - 1) * sizeof(*(arr).item)); \
- (arr).item[0] = (__VA_ARGS__); \
-} while (0)
-
-#define darray_push(arr, ...) darray_append(arr, __VA_ARGS__)
-
/*** Insertion (multiple items) ***/
#define darray_append_items(arr, items, count) do { \
- size_t __count = (count), __oldSize = (arr).size; \
+ unsigned __count = (count), __oldSize = (arr).size; \
darray_resize(arr, __oldSize + __count); \
memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
} while (0)
-#define darray_prepend_items(arr, items, count) do { \
- size_t __count = (count), __oldSize = (arr).size; \
- darray_resize(arr, __count + __oldSize); \
- memmove((arr).item + __count, (arr).item, \
- __oldSize * sizeof(*(arr).item)); \
- memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
-} while (0)
-
-#define darray_append_items_nullterminate(arr, items, count) do { \
- size_t __count = (count), __oldSize = (arr).size; \
- darray_resize(arr, __oldSize + __count + 1); \
- memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
- (arr).item[--(arr).size] = 0; \
-} while (0)
-
-#define darray_prepend_items_nullterminate(arr, items, count) do { \
- size_t __count = (count), __oldSize = (arr).size; \
- darray_resize(arr, __count + __oldSize + 1); \
- memmove((arr).item + __count, (arr).item, \
- __oldSize * sizeof(*(arr).item)); \
- memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
- (arr).item[--(arr).size] = 0; \
-} while (0)
-
-#define darray_appends_t(arr, type, ...) do { \
- type __src[] = { __VA_ARGS__ }; \
- darray_append_items(arr, __src, sizeof(__src) / sizeof(*__src)); \
-} while (0)
-
-#define darray_prepends_t(arr, type, ...) do { \
- type __src[] = { __VA_ARGS__ }; \
- darray_prepend_items(arr, __src, sizeof(__src) / sizeof(*__src)); \
-} while (0)
-
-/*** Removal ***/
-
-/* Warning: Do not call darray_pop on an empty darray. */
-#define darray_pop(arr) ((arr).item[--(arr).size])
-#define darray_pop_check(arr) ((arr).size ? darray_pop(arr) : NULL)
-
-/*** Replacement ***/
-
#define darray_from_items(arr, items, count) do { \
- size_t __count = (count); \
+ unsigned __count = (count); \
darray_resize(arr, __count); \
memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
} while (0)
-#define darray_from_c(arr, c_array) \
- darray_from_items(arr, c_array, sizeof(c_array) / sizeof(*(c_array)))
-
#define darray_copy(arr_to, arr_from) \
darray_from_items((arr_to), (arr_from).item, (arr_from).size)
@@ -251,24 +117,20 @@ typedef darray (unsigned long) darray_ulong;
(arr).size--; \
} while (0)
-#define darray_prepend_string(arr, str) do { \
- const char *__str = (str); \
- darray_prepend_items_nullterminate(arr, __str, strlen(__str)); \
-} while (0)
-
-#define darray_prepend_lit(arr, stringLiteral) \
- darray_prepend_items_nullterminate(arr, stringLiteral, \
- sizeof(stringLiteral) - 1)
-
-#define darray_from_string(arr, str) do { \
- const char *__str = (str); \
- darray_from_items(arr, __str, strlen(__str) + 1); \
- (arr).size--; \
+#define darray_appends_nullterminate(arr, items, count) do { \
+ unsigned __count = (count), __oldSize = (arr).size; \
+ darray_resize(arr, __oldSize + __count + 1); \
+ memcpy((arr).item + __oldSize, items, __count * sizeof(*(arr).item)); \
+ (arr).item[--(arr).size] = 0; \
} while (0)
-#define darray_from_lit(arr, stringLiteral) do { \
- darray_from_items(arr, stringLiteral, sizeof(stringLiteral)); \
- (arr).size--; \
+#define darray_prepends_nullterminate(arr, items, count) do { \
+ unsigned __count = (count), __oldSize = (arr).size; \
+ darray_resize(arr, __count + __oldSize + 1); \
+ memmove((arr).item + __count, (arr).item, \
+ __oldSize * sizeof(*(arr).item)); \
+ memcpy((arr).item, items, __count * sizeof(*(arr).item)); \
+ (arr).item[--(arr).size] = 0; \
} while (0)
/*** Size management ***/
@@ -277,7 +139,7 @@ typedef darray (unsigned long) darray_ulong;
darray_growalloc(arr, (arr).size = (newSize))
#define darray_resize0(arr, newSize) do { \
- size_t __oldSize = (arr).size, __newSize = (newSize); \
+ unsigned __oldSize = (arr).size, __newSize = (newSize); \
(arr).size = __newSize; \
if (__newSize > __oldSize) { \
darray_growalloc(arr, __newSize); \
@@ -292,14 +154,16 @@ typedef darray (unsigned long) darray_ulong;
} while (0)
#define darray_growalloc(arr, need) do { \
- size_t __need = (need); \
+ unsigned __need = (need); \
if (__need > (arr).alloc) \
- darray_realloc(arr, darray_next_alloc((arr).alloc, __need)); \
+ darray_realloc(arr, darray_next_alloc((arr).alloc, __need, \
+ sizeof(*(arr).item))); \
} while (0)
-static inline size_t
-darray_next_alloc(size_t alloc, size_t need)
+static inline unsigned
+darray_next_alloc(unsigned alloc, unsigned need, unsigned itemSize)
{
+ assert(need < UINT_MAX / itemSize / 2); /* Overflow. */
if (alloc == 0)
alloc = 4;
while (alloc < need)
@@ -309,11 +173,6 @@ darray_next_alloc(size_t alloc, size_t need)
/*** Traversal ***/
-/*
- * darray_foreach(T *&i, darray(T) arr) {...}
- *
- * Traverse a darray. `i` must be declared in advance as a pointer to an item.
- */
#define darray_foreach(i, arr) \
for ((i) = &(arr).item[0]; (i) < &(arr).item[(arr).size]; (i)++)
@@ -331,58 +190,7 @@ darray_next_alloc(size_t alloc, size_t need)
(idx) < (arr).size; \
(idx)++, (val)++)
-/*
- * darray_foreach_reverse(T *&i, darray(T) arr) {...}
- *
- * Like darray_foreach, but traverse in reverse order.
- */
#define darray_foreach_reverse(i, arr) \
for ((i) = &(arr).item[(arr).size]; (i)-- > &(arr).item[0]; )
#endif /* CCAN_DARRAY_H */
-
-/*
- *
- * darray_growalloc(arr, newAlloc) sees if the darray can currently hold newAlloc items;
- * if not, it increases the alloc to satisfy this requirement, allocating slack
- * space to avoid having to reallocate for every size increment.
- *
- * darray_from_string(arr, str) copies a string to an darray_char.
- *
- * darray_push(arr, item) pushes an item to the end of the darray.
- * darray_pop(arr) pops it back out. Be sure there is at least one item in the darray before calling.
- * darray_pop_check(arr) does the same as darray_pop, but returns NULL if there are no more items left in the darray.
- *
- * darray_make_room(arr, room) ensures there's 'room' elements of space after the end of the darray, and it returns a pointer to this space.
- * Currently requires HAVE_STATEMENT_EXPR, but I plan to remove this dependency by creating an inline function.
- *
- * The following require HAVE_TYPEOF==1 :
- *
- * darray_appends(arr, item0, item1...) appends a collection of comma-delimited items to the darray.
- * darray_prepends(arr, item0, item1...) prepends a collection of comma-delimited items to the darray.\
- *
- *
- * Examples:
- *
- * darray(int) arr;
- * int *i;
- *
- * darray_appends(arr, 0,1,2,3,4);
- * darray_appends(arr, -5,-4,-3,-2,-1);
- * darray_foreach(i, arr)
- * printf("%d ", *i);
- * printf("\n");
- *
- * darray_free(arr);
- *
- *
- * typedef struct {int n,d;} Fraction;
- * darray(Fraction) fractions;
- * Fraction *i;
- *
- * darray_appends(fractions, {3,4}, {3,5}, {2,1});
- * darray_foreach(i, fractions)
- * printf("%d/%d\n", i->n, i->d);
- *
- * darray_free(fractions);
- */
diff --git a/src/3rdparty/xkbcommon/src/keymap-priv.c b/src/3rdparty/xkbcommon/src/keymap-priv.c
index 9f42040828..2b3f8cde0c 100644
--- a/src/3rdparty/xkbcommon/src/keymap-priv.c
+++ b/src/3rdparty/xkbcommon/src/keymap-priv.c
@@ -30,12 +30,7 @@ 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,
+ const struct xkb_mod builtin_mods[] = {
{ .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 },
@@ -43,7 +38,14 @@ update_builtin_keymap_fields(struct xkb_keymap *keymap)
{ .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 });
+ { .name = xkb_atom_intern_literal(ctx, "Mod5"), .type = MOD_REAL },
+ };
+
+ /*
+ * Add predefined (AKA real, core, X11) modifiers.
+ * The order is important!
+ */
+ darray_append_items(keymap->mods, builtin_mods, ARRAY_SIZE(builtin_mods));
}
struct xkb_keymap *
diff --git a/src/3rdparty/xkbcommon/src/keymap.h b/src/3rdparty/xkbcommon/src/keymap.h
index 5f514ec779..39ac4209ae 100644
--- a/src/3rdparty/xkbcommon/src/keymap.h
+++ b/src/3rdparty/xkbcommon/src/keymap.h
@@ -146,7 +146,7 @@ enum xkb_action_flags {
ACTION_ABSOLUTE_SWITCH = (1 << 5),
ACTION_ABSOLUTE_X = (1 << 6),
ACTION_ABSOLUTE_Y = (1 << 7),
- ACTION_NO_ACCEL = (1 << 8),
+ ACTION_ACCEL = (1 << 8),
ACTION_SAME_SCREEN = (1 << 9),
};
@@ -223,7 +223,7 @@ struct xkb_pointer_button_action {
enum xkb_action_type type;
enum xkb_action_flags flags;
uint8_t count;
- int8_t button;
+ uint8_t button;
};
struct xkb_private_action {
@@ -262,10 +262,10 @@ struct xkb_key_type {
struct xkb_sym_interpret {
xkb_keysym_t sym;
enum xkb_match_operation match;
- bool level_one_only;
xkb_mod_mask_t mods;
xkb_mod_index_t virtual_mod;
union xkb_action action;
+ bool level_one_only;
bool repeat;
};
diff --git a/src/3rdparty/xkbcommon/src/keysym-utf.c b/src/3rdparty/xkbcommon/src/keysym-utf.c
index 129da15cf8..ffe2cea48e 100644
--- a/src/3rdparty/xkbcommon/src/keysym-utf.c
+++ b/src/3rdparty/xkbcommon/src/keysym-utf.c
@@ -37,6 +37,7 @@
#include "xkbcommon/xkbcommon.h"
#include "utils.h"
+#include "utf8.h"
/* We don't use the uint32_t types here, to save some space. */
struct codepair {
@@ -838,15 +839,15 @@ static const struct codepair keysymtab[] = {
static uint32_t
bin_search(const struct codepair *table, size_t length, xkb_keysym_t keysym)
{
- int first = 0;
- int last = length;
+ size_t first = 0;
+ size_t last = length;
if (keysym < table[0].keysym || keysym > table[length].keysym)
return 0;
/* binary search in table */
while (last >= first) {
- int mid = (first + last) / 2;
+ size_t mid = (first + last) / 2;
if (table[mid].keysym < keysym)
first = mid + 1;
else if (table[mid].keysym > keysym)
@@ -912,47 +913,6 @@ xkb_keysym_to_utf32(xkb_keysym_t keysym)
* Author: Rob Bradford <rob@linux.intel.com>
*/
-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;
-}
-
XKB_EXPORT int
xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size)
{
diff --git a/src/3rdparty/xkbcommon/src/keysym.c b/src/3rdparty/xkbcommon/src/keysym.c
index f52d751973..e8fa5e12ba 100644
--- a/src/3rdparty/xkbcommon/src/keysym.c
+++ b/src/3rdparty/xkbcommon/src/keysym.c
@@ -64,7 +64,11 @@ compare_by_keysym(const void *a, const void *b)
{
const xkb_keysym_t *key = a;
const struct name_keysym *entry = b;
- return *key - (int32_t) entry->keysym;
+ if (*key < entry->keysym)
+ return -1;
+ if (*key > entry->keysym)
+ return 1;
+ return 0;
}
static int
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h b/src/3rdparty/xkbcommon/src/scanner-utils.h
index 7e21b00662..e4e90eb0b6 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner-utils.h
+++ b/src/3rdparty/xkbcommon/src/scanner-utils.h
@@ -49,13 +49,25 @@ struct scanner {
size_t len;
char buf[1024];
size_t buf_pos;
- int line, column;
+ unsigned line, column;
/* The line/column of the start of the current token. */
- int token_line, token_column;
+ unsigned token_line, token_column;
const char *file_name;
struct xkb_context *ctx;
};
+#define scanner_log(scanner, level, fmt, ...) \
+ xkb_log((scanner)->ctx, (level), 0, \
+ "%s:%u:%u: " fmt "\n", \
+ (scanner)->file_name, \
+ (scanner)->token_line, (scanner)->token_column, ##__VA_ARGS__)
+
+#define scanner_err(scanner, fmt, ...) \
+ scanner_log(scanner, XKB_LOG_LEVEL_ERROR, fmt, ##__VA_ARGS__)
+
+#define scanner_warn(scanner, fmt, ...) \
+ scanner_log(scanner, XKB_LOG_LEVEL_WARNING, fmt, ##__VA_ARGS__)
+
static inline void
scanner_init(struct scanner *s, struct xkb_context *ctx,
const char *string, size_t len, const char *file_name)
@@ -72,7 +84,9 @@ scanner_init(struct scanner *s, struct xkb_context *ctx,
static inline char
peek(struct scanner *s)
{
- return s->pos < s->len ? s->s[s->pos] : '\0';
+ if (unlikely(s->pos >= s->len))
+ return '\0';
+ return s->s[s->pos];
}
static inline bool
@@ -90,9 +104,9 @@ eol(struct scanner *s)
static inline char
next(struct scanner *s)
{
- if (eof(s))
+ if (unlikely(eof(s)))
return '\0';
- if (eol(s)) {
+ if (unlikely(eol(s))) {
s->line++;
s->column = 1;
}
@@ -105,7 +119,7 @@ next(struct scanner *s)
static inline bool
chr(struct scanner *s, char ch)
{
- if (peek(s) != ch)
+ if (likely(peek(s) != ch))
return false;
s->pos++; s->column++;
return true;
diff --git a/src/3rdparty/xkbcommon/src/state.c b/src/3rdparty/xkbcommon/src/state.c
index 768d47c182..0f9ea79264 100644
--- a/src/3rdparty/xkbcommon/src/state.c
+++ b/src/3rdparty/xkbcommon/src/state.c
@@ -61,6 +61,7 @@
#include "keymap.h"
#include "keysym.h"
+#include "utf8.h"
struct xkb_filter {
union xkb_action action;
@@ -108,7 +109,7 @@ struct xkb_state {
* < Left Shift down, Right Shift down, Left Shift Up >
* the modifier should still be set. This keeps the count.
*/
- int16_t mod_key_count[sizeof(xkb_mod_mask_t) * 8];
+ int16_t mod_key_count[XKB_MAX_MODS];
int refcnt;
darray(struct xkb_filter) filters;
@@ -121,9 +122,8 @@ get_entry_for_key_state(struct xkb_state *state, const struct xkb_key *key,
{
const struct xkb_key_type *type = key->groups[group].type;
xkb_mod_mask_t active_mods = state->components.mods & type->mods.mask;
- unsigned int i;
- for (i = 0; i < type->num_entries; i++) {
+ for (unsigned i = 0; i < type->num_entries; i++) {
/*
* If the virtual modifiers are not bound to anything, we're
* supposed to skip the entry (xserver does this with cached
@@ -170,7 +170,7 @@ wrap_group_into_range(int32_t group,
if (num_groups == 0)
return XKB_LAYOUT_INVALID;
- if (group < num_groups)
+ if (group >= 0 && (xkb_layout_index_t) group < num_groups)
return group;
switch (out_of_range_group_action) {
@@ -623,30 +623,42 @@ xkb_state_led_update_all(struct xkb_state *state)
xkb_mod_mask_t mod_mask = 0;
xkb_layout_mask_t group_mask = 0;
- if (led->which_mods & XKB_STATE_MODS_EFFECTIVE)
- mod_mask |= state->components.mods;
- if (led->which_mods & XKB_STATE_MODS_DEPRESSED)
- mod_mask |= state->components.base_mods;
- if (led->which_mods & XKB_STATE_MODS_LATCHED)
- mod_mask |= state->components.latched_mods;
- if (led->which_mods & XKB_STATE_MODS_LOCKED)
- mod_mask |= state->components.locked_mods;
- if (led->mods.mask & mod_mask)
- state->components.leds |= (1 << idx);
-
- if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
- group_mask |= (1 << state->components.group);
- if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED)
- group_mask |= (1 << state->components.base_group);
- if (led->which_groups & XKB_STATE_LAYOUT_LATCHED)
- group_mask |= (1 << state->components.latched_group);
- if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
- group_mask |= (1 << state->components.locked_group);
- if (led->groups & group_mask)
- state->components.leds |= (1 << idx);
-
- if (led->ctrls & state->keymap->enabled_ctrls)
- state->components.leds |= (1 << idx);
+ if (led->which_mods != 0 && led->mods.mask != 0) {
+ if (led->which_mods & XKB_STATE_MODS_EFFECTIVE)
+ mod_mask |= state->components.mods;
+ if (led->which_mods & XKB_STATE_MODS_DEPRESSED)
+ mod_mask |= state->components.base_mods;
+ if (led->which_mods & XKB_STATE_MODS_LATCHED)
+ mod_mask |= state->components.latched_mods;
+ if (led->which_mods & XKB_STATE_MODS_LOCKED)
+ mod_mask |= state->components.locked_mods;
+
+ if (led->mods.mask & mod_mask) {
+ state->components.leds |= (1u << idx);
+ continue;
+ }
+ }
+
+ if (led->which_groups != 0 && led->groups != 0) {
+ if (led->which_groups & XKB_STATE_LAYOUT_EFFECTIVE)
+ group_mask |= (1u << state->components.group);
+ if (led->which_groups & XKB_STATE_LAYOUT_DEPRESSED)
+ group_mask |= (1u << state->components.base_group);
+ if (led->which_groups & XKB_STATE_LAYOUT_LATCHED)
+ group_mask |= (1u << state->components.latched_group);
+ if (led->which_groups & XKB_STATE_LAYOUT_LOCKED)
+ group_mask |= (1u << state->components.locked_group);
+
+ if (led->groups & group_mask) {
+ state->components.leds |= (1u << idx);
+ continue;
+ }
+ }
+
+ if (led->ctrls & state->keymap->enabled_ctrls) {
+ state->components.leds |= (1u << idx);
+ continue;
+ }
}
}
@@ -657,23 +669,27 @@ xkb_state_led_update_all(struct xkb_state *state)
static void
xkb_state_update_derived(struct xkb_state *state)
{
+ xkb_layout_index_t wrapped;
+
state->components.mods = (state->components.base_mods |
state->components.latched_mods |
state->components.locked_mods);
/* TODO: Use groups_wrap control instead of always RANGE_WRAP. */
+ wrapped = wrap_group_into_range(state->components.locked_group,
+ state->keymap->num_groups,
+ RANGE_WRAP, 0);
state->components.locked_group =
- wrap_group_into_range(state->components.locked_group,
- state->keymap->num_groups,
- RANGE_WRAP, 0);
+ (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped);
+ wrapped = wrap_group_into_range(state->components.base_group +
+ state->components.latched_group +
+ state->components.locked_group,
+ state->keymap->num_groups,
+ RANGE_WRAP, 0);
state->components.group =
- wrap_group_into_range(state->components.base_group +
- state->components.latched_group +
- state->components.locked_group,
- state->keymap->num_groups,
- RANGE_WRAP, 0);
+ (wrapped == XKB_LAYOUT_INVALID ? 0 : wrapped);
xkb_state_led_update_all(state);
}
@@ -781,7 +797,7 @@ xkb_state_update_mask(struct xkb_state *state,
num_mods = xkb_keymap_num_mods(state->keymap);
for (idx = 0; idx < num_mods; idx++) {
- xkb_mod_mask_t mod = (1 << idx);
+ xkb_mod_mask_t mod = (1u << idx);
if (base_mods & mod)
state->components.base_mods |= mod;
if (latched_mods & mod)
@@ -826,6 +842,53 @@ err:
return 0;
}
+/*
+ * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Lock_Modifier
+ */
+static bool
+should_do_caps_transformation(struct xkb_state *state, xkb_keycode_t kc)
+{
+ xkb_mod_index_t caps =
+ xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CAPS);
+
+ return
+ xkb_state_mod_index_is_active(state, caps, XKB_STATE_MODS_EFFECTIVE) > 0 &&
+ xkb_state_mod_index_is_consumed(state, kc, caps) == 0;
+}
+
+/*
+ * http://www.x.org/releases/current/doc/kbproto/xkbproto.html#Interpreting_the_Control_Modifier
+ */
+static bool
+should_do_ctrl_transformation(struct xkb_state *state, xkb_keycode_t kc)
+{
+ xkb_mod_index_t ctrl =
+ xkb_keymap_mod_get_index(state->keymap, XKB_MOD_NAME_CTRL);
+
+ return
+ xkb_state_mod_index_is_active(state, ctrl, XKB_STATE_MODS_EFFECTIVE) > 0 &&
+ xkb_state_mod_index_is_consumed(state, kc, ctrl) == 0;
+}
+
+/* Verbatim from libX11:src/xkb/XKBBind.c */
+static char
+XkbToControl(char ch)
+{
+ char c = ch;
+
+ if ((c >= '@' && c < '\177') || c == ' ')
+ c &= 0x1F;
+ else if (c == '2')
+ c = '\000';
+ else if (c >= '3' && c <= '7')
+ c -= ('3' - '\033');
+ else if (c == '8')
+ c = '\177';
+ else if (c == '/')
+ c = '_' & 0x1F;
+ return c;
+}
+
/**
* Provides either exactly one symbol, or XKB_KEY_NoSymbol.
*/
@@ -835,7 +898,6 @@ 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)
@@ -843,18 +905,135 @@ xkb_state_key_get_one_sym(struct xkb_state *state, xkb_keycode_t kc)
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)
+ if (should_do_caps_transformation(state, kc))
+ sym = xkb_keysym_to_upper(sym);
+
+ return sym;
+}
+
+/*
+ * The caps and ctrl transformations require some special handling,
+ * so we cannot simply use xkb_state_get_one_sym() for them.
+ * In particular, if Control is set, we must try very hard to find
+ * some layout in which the keysym is ASCII and thus can be (maybe)
+ * converted to a control character. libX11 allows to disable this
+ * behavior with the XkbLC_ControlFallback (see XkbSetXlibControls(3)),
+ * but it is enabled by default, yippee.
+ */
+static xkb_keysym_t
+get_one_sym_for_string(struct xkb_state *state, xkb_keycode_t kc)
+{
+ xkb_level_index_t level;
+ xkb_layout_index_t layout, num_layouts;
+ const xkb_keysym_t *syms;
+ int nsyms;
+ xkb_keysym_t sym;
+
+ layout = xkb_state_key_get_layout(state, kc);
+ num_layouts = xkb_keymap_num_layouts_for_key(state->keymap, kc);
+ level = xkb_state_key_get_level(state, kc, layout);
+ if (layout == XKB_LAYOUT_INVALID || num_layouts == 0 ||
+ level == XKB_LEVEL_INVALID)
+ return XKB_KEY_NoSymbol;
+
+ nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc,
+ layout, level, &syms);
+ if (nsyms != 1)
+ return XKB_KEY_NoSymbol;
+ sym = syms[0];
+
+ if (should_do_ctrl_transformation(state, kc) && sym > 127u) {
+ for (xkb_layout_index_t i = 0; i < num_layouts; i++) {
+ level = xkb_state_key_get_level(state, kc, i);
+ if (level == XKB_LEVEL_INVALID)
+ continue;
+
+ nsyms = xkb_keymap_key_get_syms_by_level(state->keymap, kc,
+ i, level, &syms);
+ if (nsyms == 1 && syms[0] <= 127u) {
+ sym = syms[0];
+ break;
+ }
+ }
+ }
+
+ if (should_do_caps_transformation(state, kc)) {
sym = xkb_keysym_to_upper(sym);
+ }
return sym;
}
+XKB_EXPORT int
+xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t kc,
+ char *buffer, size_t size)
+{
+ xkb_keysym_t sym;
+ const xkb_keysym_t *syms;
+ int nsyms;
+ int offset;
+ char tmp[7];
+
+ sym = get_one_sym_for_string(state, kc);
+ if (sym != XKB_KEY_NoSymbol) {
+ nsyms = 1; syms = &sym;
+ }
+ else {
+ nsyms = xkb_state_key_get_syms(state, kc, &syms);
+ }
+
+ /* Make sure not to truncate in the middle of a UTF-8 sequence. */
+ offset = 0;
+ for (int i = 0; i < nsyms; i++) {
+ int ret = xkb_keysym_to_utf8(syms[i], tmp, sizeof(tmp));
+ if (ret <= 0)
+ goto err_bad;
+
+ ret--;
+ if ((size_t) (offset + ret) <= size)
+ memcpy(buffer + offset, tmp, ret);
+ offset += ret;
+ }
+
+ if ((size_t) offset >= size)
+ goto err_trunc;
+ buffer[offset] = '\0';
+
+ if (!is_valid_utf8(buffer, offset))
+ goto err_bad;
+
+ if (offset == 1 && (unsigned int) buffer[0] <= 127u &&
+ should_do_ctrl_transformation(state, kc))
+ buffer[0] = XkbToControl(buffer[0]);
+
+ return offset;
+
+err_trunc:
+ if (size > 0)
+ buffer[size - 1] = '\0';
+ return offset;
+
+err_bad:
+ if (size > 0)
+ buffer[0] = '\0';
+ return 0;
+}
+
+XKB_EXPORT uint32_t
+xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t kc)
+{
+ xkb_keysym_t sym;
+ uint32_t cp;
+
+ sym = get_one_sym_for_string(state, kc);
+ cp = xkb_keysym_to_utf32(sym);
+
+ if (cp <= 127u && should_do_ctrl_transformation(state, kc))
+ cp = (uint32_t) XkbToControl((char) cp);
+
+ return cp;
+}
+
/**
* Serialises the requested modifier state into an xkb_mod_mask_t, with all
* the same disclaimers as in xkb_state_update_mask.
@@ -913,7 +1092,7 @@ xkb_state_mod_index_is_active(struct xkb_state *state,
if (idx >= xkb_keymap_num_mods(state->keymap))
return -1;
- return !!(xkb_state_serialize_mods(state, type) & (1 << idx));
+ return !!(xkb_state_serialize_mods(state, type) & (1u << idx));
}
/**
@@ -964,7 +1143,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state,
ret = -1;
break;
}
- wanted |= (1 << idx);
+ wanted |= (1u << idx);
}
va_end(ap);
@@ -1015,7 +1194,7 @@ xkb_state_mod_names_are_active(struct xkb_state *state,
ret = -1;
break;
}
- wanted |= (1 << idx);
+ wanted |= (1u << idx);
}
va_end(ap);
@@ -1042,11 +1221,11 @@ xkb_state_layout_index_is_active(struct xkb_state *state,
if (type & XKB_STATE_LAYOUT_EFFECTIVE)
ret |= (state->components.group == idx);
if (type & XKB_STATE_LAYOUT_DEPRESSED)
- ret |= (state->components.base_group == idx);
+ ret |= (state->components.base_group == (int32_t) idx);
if (type & XKB_STATE_LAYOUT_LATCHED)
- ret |= (state->components.latched_group == idx);
+ ret |= (state->components.latched_group == (int32_t) idx);
if (type & XKB_STATE_LAYOUT_LOCKED)
- ret |= (state->components.locked_group == idx);
+ ret |= (state->components.locked_group == (int32_t) idx);
return ret;
}
@@ -1077,7 +1256,7 @@ xkb_state_led_index_is_active(struct xkb_state *state, xkb_led_index_t idx)
darray_item(state->keymap->leds, idx).name == XKB_ATOM_NONE)
return -1;
- return !!(state->components.leds & (1 << idx));
+ return !!(state->components.leds & (1u << idx));
}
/**
@@ -1097,18 +1276,24 @@ xkb_state_led_name_is_active(struct xkb_state *state, const char *name)
static xkb_mod_mask_t
key_get_consumed(struct xkb_state *state, const struct xkb_key *key)
{
+ const struct xkb_key_type *type;
const struct xkb_key_type_entry *entry;
+ xkb_mod_mask_t preserve;
xkb_layout_index_t group;
group = xkb_state_key_get_layout(state, key->keycode);
if (group == XKB_LAYOUT_INVALID)
return 0;
+ type = key->groups[group].type;
+
entry = get_entry_for_key_state(state, key, group);
- if (!entry)
- return 0;
+ if (entry)
+ preserve = entry->preserve.mask;
+ else
+ preserve = 0;
- return entry->mods.mask & ~entry->preserve.mask;
+ return type->mods.mask & ~preserve;
}
/**
@@ -1132,7 +1317,7 @@ xkb_state_mod_index_is_consumed(struct xkb_state *state, xkb_keycode_t kc,
if (!key || idx >= xkb_keymap_num_mods(state->keymap))
return -1;
- return !!((1 << idx) & key_get_consumed(state, key));
+ return !!((1u << idx) & key_get_consumed(state, key));
}
/**
@@ -1154,3 +1339,14 @@ xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t kc,
return mask & ~key_get_consumed(state, key);
}
+
+XKB_EXPORT xkb_mod_mask_t
+xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t kc)
+{
+ const struct xkb_key *key = XkbKey(state->keymap, kc);
+
+ if (!key)
+ return 0;
+
+ return key_get_consumed(state, key);
+}
diff --git a/src/3rdparty/xkbcommon/src/text.c b/src/3rdparty/xkbcommon/src/text.c
index 59d6c775cb..f3a09e843d 100644
--- a/src/3rdparty/xkbcommon/src/text.c
+++ b/src/3rdparty/xkbcommon/src/text.c
@@ -280,7 +280,7 @@ ModMaskText(const struct xkb_keymap *keymap, xkb_mod_mask_t mask)
darray_enumerate(i, mod, keymap->mods) {
int ret;
- if (!(mask & (1 << i)))
+ if (!(mask & (1u << i)))
continue;
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
@@ -307,14 +307,14 @@ LedStateMaskText(struct xkb_context *ctx, enum xkb_state_component mask)
for (unsigned i = 0; mask; i++) {
int ret;
- if (!(mask & (1 << i)))
+ if (!(mask & (1u << i)))
continue;
- mask &= ~(1 << i);
+ mask &= ~(1u << i);
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
pos == 0 ? "" : "+",
- LookupValue(modComponentMaskNames, 1 << i));
+ LookupValue(modComponentMaskNames, 1u << i));
if (ret <= 0 || pos + ret >= sizeof(buf))
break;
else
@@ -339,14 +339,14 @@ ControlMaskText(struct xkb_context *ctx, enum xkb_action_controls mask)
for (unsigned i = 0; mask; i++) {
int ret;
- if (!(mask & (1 << i)))
+ if (!(mask & (1u << i)))
continue;
- mask &= ~(1 << i);
+ mask &= ~(1u << i);
ret = snprintf(buf + pos, sizeof(buf) - pos, "%s%s",
pos == 0 ? "" : "+",
- LookupValue(ctrlMaskNames, 1 << i));
+ LookupValue(ctrlMaskNames, 1u << i));
if (ret <= 0 || pos + ret >= sizeof(buf))
break;
else
diff --git a/src/3rdparty/xkbcommon/src/utf8.c b/src/3rdparty/xkbcommon/src/utf8.c
new file mode 100644
index 0000000000..11382c809d
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/utf8.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2014 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: Rob Bradford <rob@linux.intel.com>
+ */
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include "utf8.h"
+
+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;
+}
+
+bool
+is_valid_utf8(const char *ss, size_t len)
+{
+ size_t i = 0;
+ size_t tail_bytes = 0;
+ const uint8_t *s = (const uint8_t *) ss;
+
+ /* This beauty is from:
+ * The Unicode Standard Version 6.2 - Core Specification, Table 3.7
+ * http://www.unicode.org/versions/Unicode6.2.0/ch03.pdf#G7404
+ * We can optimize if needed. */
+ while (i < len)
+ {
+ if (s[i] <= 0x7F) {
+ tail_bytes = 0;
+ }
+ else if (s[i] >= 0xC2 && s[i] <= 0xDF) {
+ tail_bytes = 1;
+ }
+ else if (s[i] == 0xE0) {
+ i++;
+ if (i >= len || !(s[i] >= 0xA0 && s[i] <= 0xBF))
+ return false;
+ tail_bytes = 1;
+ }
+ else if (s[i] >= 0xE1 && s[i] <= 0xEC) {
+ tail_bytes = 2;
+ }
+ else if (s[i] == 0xED) {
+ i++;
+ if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x9F))
+ return false;
+ tail_bytes = 1;
+ }
+ else if (s[i] >= 0xEE && s[i] <= 0xEF) {
+ tail_bytes = 2;
+ }
+ else if (s[i] == 0xF0) {
+ i++;
+ if (i >= len || !(s[i] >= 0x90 && s[i] <= 0xBF))
+ return false;
+ tail_bytes = 2;
+ }
+ else if (s[i] >= 0xF1 && s[i] <= 0xF3) {
+ tail_bytes = 3;
+ }
+ else if (s[i] == 0xF4) {
+ i++;
+ if (i >= len || !(s[i] >= 0x80 && s[i] <= 0x8F))
+ return false;
+ tail_bytes = 2;
+ }
+ else {
+ return false;
+ }
+
+ i++;
+
+ while (i < len && tail_bytes > 0 && s[i] >= 0x80 && s[i] <= 0xBF) {
+ i++;
+ tail_bytes--;
+ }
+
+ if (tail_bytes != 0)
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/3rdparty/xkbcommon/src/utf8.h b/src/3rdparty/xkbcommon/src/utf8.h
new file mode 100644
index 0000000000..6371cb5596
--- /dev/null
+++ b/src/3rdparty/xkbcommon/src/utf8.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ * Copyright © 2014 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: Rob Bradford <rob@linux.intel.com>
+ */
+
+#ifndef XKBCOMMON_UTF8_H
+#define XKBCOMMON_UTF8_H
+
+int
+utf32_to_utf8(uint32_t unichar, char *buffer);
+
+bool
+is_valid_utf8(const char *ss, size_t len);
+
+#endif
diff --git a/src/3rdparty/xkbcommon/src/utils.h b/src/3rdparty/xkbcommon/src/utils.h
index 81d1cc9412..878c2ac1e3 100644
--- a/src/3rdparty/xkbcommon/src/utils.h
+++ b/src/3rdparty/xkbcommon/src/utils.h
@@ -163,13 +163,13 @@ is_graph(char ch)
* Note: this is 1-based! It's more useful this way, and returns 0 when
* mask is all 0s.
*/
-static inline int
+static inline unsigned
msb_pos(uint32_t mask)
{
- int pos = 0;
+ unsigned pos = 0;
while (mask) {
pos++;
- mask >>= 1;
+ mask >>= 1u;
}
return pos;
}
@@ -187,6 +187,22 @@ unmap_file(const char *str, size_t size);
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX3(a, b, c) MAX(MAX((a), (b)), (c))
+#if defined(HAVE_SECURE_GETENV)
+# define secure_getenv secure_getenv
+#elif defined(HAVE___SECURE_GETENV)
+# define secure_getenv __secure_getenv
+#else
+# define secure_getenv getenv
+#endif
+
+#if defined(HAVE___BUILTIN_EXPECT)
+# define likely(x) __builtin_expect(!!(x), 1)
+# define unlikely(x) __builtin_expect(!!(x), 0)
+#else
+# define likely(x) (x)
+# define unlikely(x) (x)
+#endif
+
/* Compiler Attributes */
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__)
diff --git a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
index 968f187621..76adf7428d 100644
--- a/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
+++ b/src/3rdparty/xkbcommon/src/x11/x11-keymap.c
@@ -43,13 +43,13 @@
/* Constants from /usr/include/X11/extensions/XKB.h */
/* XkbNumModifiers. */
-#define NUM_REAL_MODS 8
+#define NUM_REAL_MODS 8u
/* XkbNumVirtualMods. */
-#define NUM_VMODS 16
+#define NUM_VMODS 16u
/* XkbNoModifier. */
#define NO_MODIFIER 0xff
/* XkbNumIndicators. */
-#define NUM_INDICATORS 32
+#define NUM_INDICATORS 32u
/* XkbAllIndicatorsMask. */
#define ALL_INDICATORS_MASK 0xffffffff
@@ -92,11 +92,14 @@ 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);
+ return
+ ((xkb_mod_mask_t) rmods) |
+ ((xkb_mod_mask_t) vmods_low << 8) |
+ ((xkb_mod_mask_t) vmods_high << 16);
}
static enum xkb_action_controls
-translate_controls_mask(uint16_t wire)
+translate_controls_mask(uint32_t wire)
{
enum xkb_action_controls ret = 0;
if (wire & XCB_XKB_BOOL_CTRL_REPEAT_KEYS)
@@ -218,8 +221,8 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
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_NO_ACCELERATION))
+ action->ptr.flags |= ACTION_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)
@@ -263,7 +266,7 @@ translate_action(union xkb_action *action, const xcb_xkb_action_t *wire)
action->screen.screen = wire->switchscreen.newScreen;
- if (wire->switchscreen.flags & XCB_XKB_SWITCH_SCREEN_FLAG_APPLICATION)
+ 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;
@@ -351,7 +354,7 @@ get_types(struct xkb_keymap *keymap, xcb_connection_t *conn,
xcb_xkb_mod_def_iterator_t preserves_iter =
xcb_xkb_key_type_preserve_iterator(wire_type);
- FAIL_UNLESS(preserves_length <= type->num_entries);
+ FAIL_UNLESS((unsigned) preserves_length <= type->num_entries);
for (int j = 0; j < preserves_length; j++) {
xcb_xkb_mod_def_t *wire_preserve = preserves_iter.data;
@@ -402,7 +405,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
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++) {
+ for (unsigned 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]];
@@ -424,7 +427,7 @@ get_sym_maps(struct xkb_keymap *keymap, xcb_connection_t *conn,
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);
+ FAIL_UNLESS((unsigned) syms_length == wire_sym_map->width * key->num_groups);
for (int j = 0; j < syms_length; j++) {
xcb_keysym_t wire_keysym = *syms_iter;
@@ -468,9 +471,12 @@ get_actions(struct xkb_keymap *keymap, xcb_connection_t *conn,
for (int i = 0; i < acts_count_length; i++) {
xcb_xkb_key_sym_map_t *wire_sym_map = sym_maps_iter.data;
+ int syms_length = xcb_xkb_key_sym_map_syms_length(wire_sym_map);
uint8_t wire_count = *acts_count_iter;
struct xkb_key *key = &keymap->keys[reply->firstKeyAction + i];
+ FAIL_UNLESS(wire_count == 0 || wire_count == syms_length);
+
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;
@@ -505,8 +511,8 @@ get_vmods(struct xkb_keymap *keymap, xcb_connection_t *conn,
darray_resize0(keymap->mods,
NUM_REAL_MODS + msb_pos(reply->virtualMods));
- for (int i = 0; i < NUM_VMODS; i++) {
- if (reply->virtualMods & (1 << i)) {
+ for (unsigned i = 0; i < NUM_VMODS; i++) {
+ if (reply->virtualMods & (1u << i)) {
uint8_t wire = *iter;
struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i);
@@ -530,11 +536,13 @@ get_explicits(struct xkb_keymap *keymap, xcb_connection_t *conn,
for (int i = 0; i < length; i++) {
xcb_xkb_set_explicit_t *wire = iter.data;
- struct xkb_key *key = &keymap->keys[wire->keycode];
+ struct xkb_key *key;
FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
wire->keycode <= keymap->max_key_code);
+ key = &keymap->keys[wire->keycode];
+
if ((wire->explicit & XCB_XKB_EXPLICIT_KEY_TYPE_1) &&
key->num_groups > 0)
key->groups[0].explicit_type = true;
@@ -573,11 +581,12 @@ get_modmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
for (int i = 0; i < length; i++) {
xcb_xkb_key_mod_map_t *wire = iter.data;
- struct xkb_key *key = &keymap->keys[wire->keycode];
+ struct xkb_key *key;
FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
wire->keycode <= keymap->max_key_code);
+ key = &keymap->keys[wire->keycode];
key->modmap = wire->mods;
xcb_xkb_key_mod_map_next(&iter);
@@ -599,11 +608,12 @@ get_vmodmaps(struct xkb_keymap *keymap, xcb_connection_t *conn,
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];
+ struct xkb_key *key;
FAIL_UNLESS(wire->keycode >= keymap->min_key_code &&
wire->keycode <= keymap->max_key_code);
+ key = &keymap->keys[wire->keycode];
key->vmodmap = translate_mods(0, wire->vmods, 0);
xcb_xkb_key_v_mod_map_next(&iter);
@@ -677,8 +687,8 @@ get_indicators(struct xkb_keymap *keymap, xcb_connection_t *conn,
darray_resize0(keymap->leds, msb_pos(reply->which));
- for (int i = 0; i < NUM_INDICATORS; i++) {
- if (reply->which & (1 << i)) {
+ for (unsigned i = 0; i < NUM_INDICATORS; i++) {
+ if (reply->which & (1u << i)) {
xcb_xkb_indicator_map_t *wire = iter.data;
struct xkb_led *led = &darray_item(keymap->leds, i);
@@ -879,8 +889,8 @@ get_indicator_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
FAIL_UNLESS(msb_pos(reply->indicators) <= darray_size(keymap->leds));
- for (int i = 0; i < NUM_INDICATORS; i++) {
- if (reply->indicators & (1 << i)) {
+ for (unsigned i = 0; i < NUM_INDICATORS; i++) {
+ if (reply->indicators & (1u << i)) {
xcb_atom_t wire = *iter;
struct xkb_led *led = &darray_item(keymap->leds, i);
@@ -911,8 +921,8 @@ get_vmod_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
*/
darray_resize0(keymap->mods, NUM_REAL_MODS + msb_pos(reply->virtualMods));
- for (int i = 0; i < NUM_VMODS; i++) {
- if (reply->virtualMods & (1 << i)) {
+ for (unsigned i = 0; i < NUM_VMODS; i++) {
+ if (reply->virtualMods & (1u << i)) {
xcb_atom_t wire = *iter;
struct xkb_mod *mod = &darray_item(keymap->mods, NUM_REAL_MODS + i);
@@ -959,7 +969,7 @@ get_key_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
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);
+ FAIL_UNLESS(reply->firstKey + reply->nKeys - 1U == keymap->max_key_code);
for (int i = 0; i < length; i++) {
xcb_xkb_key_name_t *wire = iter.data;
@@ -1023,7 +1033,7 @@ 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 =
+ static const xcb_xkb_name_detail_t wanted =
(XCB_XKB_NAME_DETAIL_KEYCODES |
XCB_XKB_NAME_DETAIL_SYMBOLS |
XCB_XKB_NAME_DETAIL_TYPES |
@@ -1035,17 +1045,21 @@ get_names(struct xkb_keymap *keymap, xcb_connection_t *conn,
XCB_XKB_NAME_DETAIL_KEY_ALIASES |
XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES |
XCB_XKB_NAME_DETAIL_GROUP_NAMES);
+ static const xcb_xkb_name_detail_t required =
+ (XCB_XKB_NAME_DETAIL_KEY_TYPE_NAMES |
+ XCB_XKB_NAME_DETAIL_KT_LEVEL_NAMES |
+ XCB_XKB_NAME_DETAIL_KEY_NAMES |
+ XCB_XKB_NAME_DETAIL_VIRTUAL_MOD_NAMES);
xcb_xkb_get_names_cookie_t cookie =
- xcb_xkb_get_names(conn, device_id, required_names);
+ xcb_xkb_get_names(conn, device_id, wanted);
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;
+ FAIL_UNLESS((reply->which & required) == required);
xcb_xkb_get_names_value_list_unpack(xcb_xkb_get_names_value_list(reply),
reply->nTypes,
@@ -1093,13 +1107,14 @@ get_controls(struct xkb_keymap *keymap, xcb_connection_t *conn,
xcb_xkb_get_controls_reply(conn, cookie, NULL);
FAIL_IF_BAD_REPLY(reply, "XkbGetControls");
+ FAIL_UNLESS(reply->numGroups > 0 && reply->numGroups <= 4);
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++)
+ for (xkb_keycode_t i = keymap->min_key_code; i <= keymap->max_key_code; i++)
keymap->keys[i].repeats = !!(reply->perKeyRepeat[i / 8] & (1 << (i % 8)));
free(reply);
@@ -1119,7 +1134,7 @@ xkb_x11_keymap_new_from_device(struct xkb_context *ctx,
struct xkb_keymap *keymap;
const enum xkb_keymap_format format = XKB_KEYMAP_FORMAT_TEXT_V1;
- if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL;
}
diff --git a/src/3rdparty/xkbcommon/src/x11/x11-priv.h b/src/3rdparty/xkbcommon/src/x11/x11-priv.h
index 03f9ee6710..3a19e99c04 100644
--- a/src/3rdparty/xkbcommon/src/x11/x11-priv.h
+++ b/src/3rdparty/xkbcommon/src/x11/x11-priv.h
@@ -26,8 +26,8 @@
#include <xcb/xkb.h>
-#include "xkbcommon/xkbcommon-x11.h"
#include "keymap.h"
+#include "xkbcommon/xkbcommon-x11.h"
/* Get a strdup'd name of an X atom. */
bool
diff --git a/src/3rdparty/xkbcommon/src/xkb-keymap.c b/src/3rdparty/xkbcommon/src/xkb-keymap.c
index 7d991d535d..892b7cf198 100644
--- a/src/3rdparty/xkbcommon/src/xkb-keymap.c
+++ b/src/3rdparty/xkbcommon/src/xkb-keymap.c
@@ -110,10 +110,10 @@ get_keymap_format_ops(enum xkb_keymap_format format)
[XKB_KEYMAP_FORMAT_TEXT_V1] = &text_v1_keymap_format_ops,
};
- if ((int) format < 0 || (int) format >= ARRAY_SIZE(keymap_format_ops))
+ if ((int) format < 0 || (int) format >= (int) ARRAY_SIZE(keymap_format_ops))
return NULL;
- return keymap_format_ops[format];
+ return keymap_format_ops[(int) format];
}
XKB_EXPORT struct xkb_keymap *
@@ -132,33 +132,20 @@ xkb_keymap_new_from_names(struct xkb_context *ctx,
return NULL;
}
- if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL;
}
+ keymap = xkb_keymap_new(ctx, format, flags);
+ if (!keymap)
+ return NULL;
+
if (rmlvo_in)
rmlvo = *rmlvo_in;
else
memset(&rmlvo, 0, sizeof(rmlvo));
-
- if (isempty(rmlvo.rules))
- rmlvo.rules = xkb_context_get_default_rules(ctx);
- if (isempty(rmlvo.model))
- rmlvo.model = xkb_context_get_default_model(ctx);
- /* Layout and variant are tied together, so don't try to use one from
- * the caller and one from the environment. */
- if (isempty(rmlvo.layout)) {
- rmlvo.layout = xkb_context_get_default_layout(ctx);
- rmlvo.variant = xkb_context_get_default_variant(ctx);
- }
- /* Options can be empty, so respect that if passed in. */
- if (rmlvo.options == NULL)
- rmlvo.options = xkb_context_get_default_options(ctx);
-
- keymap = xkb_keymap_new(ctx, format, flags);
- if (!keymap)
- return NULL;
+ xkb_context_sanitize_rule_names(ctx, &rmlvo);
if (!ops->keymap_new_from_names(keymap, &rmlvo)) {
xkb_keymap_unref(keymap);
@@ -193,7 +180,7 @@ xkb_keymap_new_from_buffer(struct xkb_context *ctx,
return NULL;
}
- if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL;
}
@@ -230,7 +217,7 @@ xkb_keymap_new_from_file(struct xkb_context *ctx,
return NULL;
}
- if (flags & ~(XKB_MAP_COMPILE_PLACEHOLDER)) {
+ if (flags & ~(XKB_KEYMAP_COMPILE_NO_FLAGS)) {
log_err_func(ctx, "unrecognized flags: %#x\n", flags);
return NULL;
}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/action.c b/src/3rdparty/xkbcommon/src/xkbcomp/action.c
index 2bd0bd1589..eb3d37fbbe 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/action.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/action.c
@@ -118,6 +118,8 @@ NewActionsInfo(void)
/* Increment default button. */
info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.flags = 0;
info->actions[ACTION_TYPE_PTR_DEFAULT].dflt.value = 1;
+ info->actions[ACTION_TYPE_PTR_MOVE].ptr.flags = ACTION_ACCEL;
+ info->actions[ACTION_TYPE_SWITCH_VT].screen.flags = ACTION_SAME_SCREEN;
return info;
}
@@ -186,10 +188,10 @@ fieldText(enum action_field field)
/***====================================================================***/
static inline bool
-ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action,
+ReportMismatch(struct xkb_context *ctx, enum xkb_action_type action,
enum action_field field, const char *type)
{
- log_err(keymap->ctx,
+ log_err(ctx,
"Value of %s field must be of type %s; "
"Action %s definition ignored\n",
fieldText(field), type, ActionTypeText(action));
@@ -197,10 +199,10 @@ ReportMismatch(struct xkb_keymap *keymap, enum xkb_action_type action,
}
static inline bool
-ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action,
+ReportIllegal(struct xkb_context *ctx, enum xkb_action_type action,
enum action_field field)
{
- log_err(keymap->ctx,
+ log_err(ctx,
"Field %s is not defined for an action of type %s; "
"Action definition ignored\n",
fieldText(field), ActionTypeText(action));
@@ -208,10 +210,10 @@ ReportIllegal(struct xkb_keymap *keymap, enum xkb_action_type action,
}
static inline bool
-ReportActionNotArray(struct xkb_keymap *keymap, enum xkb_action_type action,
+ReportActionNotArray(struct xkb_context *ctx, enum xkb_action_type action,
enum action_field field)
{
- log_err(keymap->ctx,
+ log_err(ctx,
"The %s field in the %s action is not an array; "
"Action definition ignored\n",
fieldText(field), ActionTypeText(action));
@@ -228,42 +230,40 @@ HandleNoAction(struct xkb_keymap *keymap, union xkb_action *action,
}
static bool
-CheckLatchLockFlags(struct xkb_keymap *keymap, enum xkb_action_type action,
- enum action_field field, const ExprDef *value,
- enum xkb_action_flags *flags_inout)
+CheckBooleanFlag(struct xkb_context *ctx, enum xkb_action_type action,
+ enum action_field field, enum xkb_action_flags flag,
+ const ExprDef *array_ndx, const ExprDef *value,
+ enum xkb_action_flags *flags_inout)
{
- enum xkb_action_flags tmp;
- bool result;
+ bool set;
- if (field == ACTION_FIELD_CLEAR_LOCKS)
- tmp = ACTION_LOCK_CLEAR;
- else if (field == ACTION_FIELD_LATCH_TO_LOCK)
- tmp = ACTION_LATCH_TO_LOCK;
- else
- return false; /* WSGO! */
+ if (array_ndx)
+ return ReportActionNotArray(ctx, action, field);
- if (!ExprResolveBoolean(keymap->ctx, value, &result))
- return ReportMismatch(keymap, action, field, "boolean");
+ if (!ExprResolveBoolean(ctx, value, &set))
+ return ReportMismatch(ctx, action, field, "boolean");
- if (result)
- *flags_inout |= tmp;
+ if (set)
+ *flags_inout |= flag;
else
- *flags_inout &= ~tmp;
+ *flags_inout &= ~flag;
return true;
}
static bool
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)
+ const ExprDef *array_ndx, const ExprDef *value,
+ enum xkb_action_flags *flags_inout, xkb_mod_mask_t *mods_rtrn)
{
+ if (array_ndx)
+ return ReportActionNotArray(keymap->ctx, action, ACTION_FIELD_MODIFIERS);
+
if (value->expr.op == EXPR_IDENT) {
const char *valStr;
valStr = xkb_atom_text(keymap->ctx, value->ident.ident);
if (valStr && (istreq(valStr, "usemodmapmods") ||
istreq(valStr, "modmapmods"))) {
-
*mods_rtrn = 0;
*flags_inout |= ACTION_MODS_LOOKUP_MODMAP;
return true;
@@ -271,184 +271,130 @@ CheckModifierField(struct xkb_keymap *keymap, enum xkb_action_type action,
}
if (!ExprResolveModMask(keymap, value, MOD_BOTH, mods_rtrn))
- return ReportMismatch(keymap, action,
+ return ReportMismatch(keymap->ctx, action,
ACTION_FIELD_MODIFIERS, "modifier mask");
*flags_inout &= ~ACTION_MODS_LOOKUP_MODMAP;
return true;
}
+static const LookupEntry lockWhich[] = {
+ { "both", 0 },
+ { "lock", ACTION_LOCK_NO_UNLOCK },
+ { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) },
+ { "unlock", ACTION_LOCK_NO_LOCK },
+ { NULL, 0 }
+};
+
static bool
-HandleSetLatchMods(struct xkb_keymap *keymap, union xkb_action *action,
- enum action_field field, const ExprDef *array_ndx,
- const ExprDef *value)
+CheckAffectField(struct xkb_context *ctx, enum xkb_action_type action,
+ const ExprDef *array_ndx, const ExprDef *value,
+ enum xkb_action_flags *flags_inout)
{
- struct xkb_mod_action *act = &action->mods;
- enum xkb_action_flags rtrn, t1;
- xkb_mod_mask_t t2;
-
- if (array_ndx != NULL) {
- switch (field) {
- case ACTION_FIELD_CLEAR_LOCKS:
- case ACTION_FIELD_LATCH_TO_LOCK:
- case ACTION_FIELD_MODIFIERS:
- return ReportActionNotArray(keymap, action->type, field);
- default:
- break;
- }
- }
-
- switch (field) {
- case ACTION_FIELD_CLEAR_LOCKS:
- case ACTION_FIELD_LATCH_TO_LOCK:
- rtrn = act->flags;
- if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) {
- act->flags = rtrn;
- return true;
- }
- return false;
+ enum xkb_action_flags flags;
- case ACTION_FIELD_MODIFIERS:
- t1 = act->flags;
- if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
- act->flags = t1;
- act->mods.mods = t2;
- return true;
- }
- return false;
+ if (array_ndx)
+ return ReportActionNotArray(ctx, action, ACTION_FIELD_AFFECT);
- default:
- break;
- }
+ if (!ExprResolveEnum(ctx, value, &flags, lockWhich))
+ return ReportMismatch(ctx, action, ACTION_FIELD_AFFECT,
+ "lock, unlock, both, neither");
- return ReportIllegal(keymap, action->type, field);
+ *flags_inout &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK);
+ *flags_inout |= flags;
+ return true;
}
static bool
-HandleLockMods(struct xkb_keymap *keymap, union xkb_action *action,
- enum action_field field, const ExprDef *array_ndx,
- const ExprDef *value)
+HandleSetLatchLockMods(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
{
struct xkb_mod_action *act = &action->mods;
- enum xkb_action_flags t1;
- xkb_mod_mask_t t2;
-
- if (array_ndx && field == ACTION_FIELD_MODIFIERS)
- return ReportActionNotArray(keymap, action->type, field);
-
- switch (field) {
- case ACTION_FIELD_MODIFIERS:
- t1 = act->flags;
- if (CheckModifierField(keymap, action->type, value, &t1, &t2)) {
- act->flags = t1;
- act->mods.mods = t2;
- return true;
- }
- return false;
-
- default:
- break;
- }
-
- return ReportIllegal(keymap, action->type, field);
+ const enum xkb_action_type type = action->type;
+
+ if (field == ACTION_FIELD_MODIFIERS)
+ return CheckModifierField(keymap, action->type, array_ndx, value,
+ &act->flags, &act->mods.mods);
+ if ((type == ACTION_TYPE_MOD_SET || type == ACTION_TYPE_MOD_LATCH) &&
+ field == ACTION_FIELD_CLEAR_LOCKS)
+ return CheckBooleanFlag(keymap->ctx, action->type, field,
+ ACTION_LOCK_CLEAR, array_ndx, value,
+ &act->flags);
+ if (type == ACTION_TYPE_MOD_LATCH &&
+ field == ACTION_FIELD_LATCH_TO_LOCK)
+ return CheckBooleanFlag(keymap->ctx, action->type, field,
+ ACTION_LATCH_TO_LOCK, array_ndx, value,
+ &act->flags);
+ if (type == ACTION_TYPE_MOD_LOCK &&
+ field == ACTION_FIELD_AFFECT)
+ return CheckAffectField(keymap->ctx, action->type, array_ndx, value,
+ &act->flags);
+
+ return ReportIllegal(keymap->ctx, action->type, field);
}
static bool
-CheckGroupField(struct xkb_keymap *keymap, unsigned action,
- const ExprDef *value, enum xkb_action_flags *flags_inout,
- xkb_layout_index_t *grp_rtrn)
+CheckGroupField(struct xkb_context *ctx, unsigned action,
+ const ExprDef *array_ndx, const ExprDef *value,
+ enum xkb_action_flags *flags_inout, int32_t *group_rtrn)
{
const ExprDef *spec;
+ xkb_layout_index_t idx;
+ enum xkb_action_flags flags = *flags_inout;
+
+ if (array_ndx)
+ return ReportActionNotArray(ctx, action, ACTION_FIELD_GROUP);
if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) {
- *flags_inout &= ~ACTION_ABSOLUTE_SWITCH;
+ flags &= ~ACTION_ABSOLUTE_SWITCH;
spec = value->unary.child;
}
else {
- *flags_inout |= ACTION_ABSOLUTE_SWITCH;
+ flags |= ACTION_ABSOLUTE_SWITCH;
spec = value;
}
- if (!ExprResolveGroup(keymap->ctx, spec, grp_rtrn))
- return ReportMismatch(keymap, action, ACTION_FIELD_GROUP,
+ if (!ExprResolveGroup(ctx, spec, &idx))
+ return ReportMismatch(ctx, action, ACTION_FIELD_GROUP,
"integer (range 1..8)");
- if (value->expr.op == EXPR_NEGATE)
- *grp_rtrn = -*grp_rtrn;
- else if (value->expr.op != EXPR_UNARY_PLUS)
- (*grp_rtrn)--;
-
- return true;
-}
-
-static bool
-HandleSetLatchGroup(struct xkb_keymap *keymap, union xkb_action *action,
- enum action_field field, const ExprDef *array_ndx,
- const ExprDef *value)
-{
- struct xkb_group_action *act = &action->group;
- enum xkb_action_flags rtrn, t1;
- xkb_layout_index_t t2;
-
- if (array_ndx != NULL) {
- switch (field) {
- case ACTION_FIELD_CLEAR_LOCKS:
- case ACTION_FIELD_LATCH_TO_LOCK:
- case ACTION_FIELD_GROUP:
- return ReportActionNotArray(keymap, action->type, field);
-
- default:
- break;
- }
+ /* +n, -n are relative, n is absolute. */
+ if (value->expr.op == EXPR_NEGATE || value->expr.op == EXPR_UNARY_PLUS) {
+ *group_rtrn = (int32_t) idx;
+ if (value->expr.op == EXPR_NEGATE)
+ *group_rtrn = -*group_rtrn;
}
-
- switch (field) {
- case ACTION_FIELD_CLEAR_LOCKS:
- case ACTION_FIELD_LATCH_TO_LOCK:
- rtrn = act->flags;
- if (CheckLatchLockFlags(keymap, action->type, field, value, &rtrn)) {
- act->flags = rtrn;
- return true;
- }
- return false;
-
- case ACTION_FIELD_GROUP:
- t1 = act->flags;
- if (CheckGroupField(keymap, action->type, value, &t1, &t2)) {
- act->flags = t1;
- act->group = t2;
- return true;
- }
- return false;
-
- default:
- break;
+ else {
+ *group_rtrn = (int32_t) (idx - 1);
}
-
- return ReportIllegal(keymap, action->type, field);
+ *flags_inout = flags;
+ return true;
}
static bool
-HandleLockGroup(struct xkb_keymap *keymap, union xkb_action *action,
- enum action_field field, const ExprDef *array_ndx,
- const ExprDef *value)
+HandleSetLatchLockGroup(struct xkb_keymap *keymap, union xkb_action *action,
+ enum action_field field, const ExprDef *array_ndx,
+ const ExprDef *value)
{
struct xkb_group_action *act = &action->group;
- enum xkb_action_flags t1;
- xkb_layout_index_t t2;
-
- if ((array_ndx != NULL) && (field == ACTION_FIELD_GROUP))
- return ReportActionNotArray(keymap, action->type, field);
- if (field == ACTION_FIELD_GROUP) {
- t1 = act->flags;
- if (CheckGroupField(keymap, action->type, value, &t1, &t2)) {
- act->flags = t1;
- act->group = t2;
- return true;
- }
- return false;
- }
- return ReportIllegal(keymap, action->type, field);
+ const enum xkb_action_type type = action->type;
+
+ if (field == ACTION_FIELD_GROUP)
+ return CheckGroupField(keymap->ctx, action->type, array_ndx, value,
+ &act->flags, &act->group);
+ if ((type == ACTION_TYPE_GROUP_SET || type == ACTION_TYPE_GROUP_LATCH) &&
+ field == ACTION_FIELD_CLEAR_LOCKS)
+ return CheckBooleanFlag(keymap->ctx, action->type, field,
+ ACTION_LOCK_CLEAR, array_ndx, value,
+ &act->flags);
+ if (type == ACTION_TYPE_GROUP_LATCH &&
+ field == ACTION_FIELD_LATCH_TO_LOCK)
+ return CheckBooleanFlag(keymap->ctx, action->type, field,
+ ACTION_LATCH_TO_LOCK, array_ndx, value,
+ &act->flags);
+
+ return ReportIllegal(keymap->ctx, action->type, field);
}
static bool
@@ -458,53 +404,47 @@ HandleMovePtr(struct xkb_keymap *keymap, union xkb_action *action,
{
struct xkb_pointer_action *act = &action->ptr;
- 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;
const bool absolute = (value->expr.op != EXPR_NEGATE &&
value->expr.op != EXPR_UNARY_PLUS);
+ if (array_ndx)
+ return ReportActionNotArray(keymap->ctx, action->type, field);
+
if (!ExprResolveInteger(keymap->ctx, value, &val))
- return ReportMismatch(keymap, action->type, field, "integer");
+ return ReportMismatch(keymap->ctx, action->type, field, "integer");
+
+ if (val < INT16_MIN || val > INT16_MAX) {
+ log_err(keymap->ctx,
+ "The %s field in the %s action must be in range %d..%d; "
+ "Action definition ignored\n",
+ fieldText(field), ActionTypeText(action->type),
+ INT16_MIN, INT16_MAX);
+ return false;
+ }
if (field == ACTION_FIELD_X) {
if (absolute)
act->flags |= ACTION_ABSOLUTE_X;
- act->x = val;
+ act->x = (int16_t) val;
}
else {
if (absolute)
act->flags |= ACTION_ABSOLUTE_Y;
- act->y = val;
+ act->y = (int16_t) val;
}
return true;
}
else if (field == ACTION_FIELD_ACCEL) {
- bool set;
-
- if (!ExprResolveBoolean(keymap->ctx, value, &set))
- return ReportMismatch(keymap, action->type, field, "boolean");
-
- if (set)
- act->flags &= ~ACTION_NO_ACCEL;
- else
- act->flags |= ACTION_NO_ACCEL;
+ return CheckBooleanFlag(keymap->ctx, action->type, field,
+ ACTION_ACCEL, array_ndx, value, &act->flags);
}
- return ReportIllegal(keymap, action->type, field);
+ return ReportIllegal(keymap->ctx, action->type, field);
}
-static const LookupEntry lockWhich[] = {
- { "both", 0 },
- { "lock", ACTION_LOCK_NO_UNLOCK },
- { "neither", (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK) },
- { "unlock", ACTION_LOCK_NO_LOCK },
- { NULL, 0 }
-};
-
static bool
HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action,
enum action_field field, const ExprDef *array_ndx,
@@ -516,10 +456,10 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action,
int btn;
if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
+ return ReportActionNotArray(keymap->ctx, action->type, field);
if (!ExprResolveButton(keymap->ctx, value, &btn))
- return ReportMismatch(keymap, action->type, field,
+ return ReportMismatch(keymap->ctx, action->type, field,
"integer (range 1..5)");
if (btn < 0 || btn > 5) {
@@ -534,40 +474,30 @@ HandlePtrBtn(struct xkb_keymap *keymap, union xkb_action *action,
}
else if (action->type == ACTION_TYPE_PTR_LOCK &&
field == ACTION_FIELD_AFFECT) {
- enum xkb_action_flags val;
-
- if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
-
- if (!ExprResolveEnum(keymap->ctx, value, &val, lockWhich))
- return ReportMismatch(keymap, action->type, field,
- "lock or unlock");
-
- act->flags &= ~(ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK);
- act->flags |= val;
- return true;
+ return CheckAffectField(keymap->ctx, action->type, array_ndx, value,
+ &act->flags);
}
else if (field == ACTION_FIELD_COUNT) {
- int btn;
+ int val;
if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
+ return ReportActionNotArray(keymap->ctx, action->type, field);
- /* XXX: Should this actually be ResolveButton? */
- if (!ExprResolveButton(keymap->ctx, value, &btn))
- return ReportMismatch(keymap, action->type, field, "integer");
+ if (!ExprResolveInteger(keymap->ctx, value, &val))
+ return ReportMismatch(keymap->ctx, action->type, field, "integer");
- if (btn < 0 || btn > 255) {
+ if (val < 0 || val > 255) {
log_err(keymap->ctx,
"The count field must have a value in the range 0..255; "
- "Illegal count %d ignored\n", btn);
+ "Illegal count %d ignored\n", val);
return false;
}
- act->count = btn;
+ act->count = (uint8_t) val;
return true;
}
- return ReportIllegal(keymap, action->type, field);
+
+ return ReportIllegal(keymap->ctx, action->type, field);
}
static const LookupEntry ptrDflts[] = {
@@ -588,10 +518,10 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
unsigned int val;
if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
+ return ReportActionNotArray(keymap->ctx, action->type, field);
if (!ExprResolveEnum(keymap->ctx, value, &val, ptrDflts))
- return ReportMismatch(keymap, action->type, field,
+ return ReportMismatch(keymap->ctx, action->type, field,
"pointer component");
return true;
}
@@ -600,7 +530,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
int btn;
if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
+ return ReportActionNotArray(keymap->ctx, action->type, field);
if (value->expr.op == EXPR_NEGATE ||
value->expr.op == EXPR_UNARY_PLUS) {
@@ -613,7 +543,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
}
if (!ExprResolveButton(keymap->ctx, button, &btn))
- return ReportMismatch(keymap, action->type, field,
+ return ReportMismatch(keymap->ctx, action->type, field,
"integer (range 1..5)");
if (btn < 0 || btn > 5) {
@@ -633,7 +563,7 @@ HandleSetPtrDflt(struct xkb_keymap *keymap, union xkb_action *action,
return true;
}
- return ReportIllegal(keymap, action->type, field);
+ return ReportIllegal(keymap->ctx, action->type, field);
}
static bool
@@ -648,7 +578,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
int val;
if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
+ return ReportActionNotArray(keymap->ctx, action->type, field);
if (value->expr.op == EXPR_NEGATE ||
value->expr.op == EXPR_UNARY_PLUS) {
@@ -661,7 +591,7 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
}
if (!ExprResolveInteger(keymap->ctx, scrn, &val))
- return ReportMismatch(keymap, action->type, field,
+ return ReportMismatch(keymap->ctx, action->type, field,
"integer (0..255)");
if (val < 0 || val > 255) {
@@ -675,23 +605,12 @@ HandleSwitchScreen(struct xkb_keymap *keymap, union xkb_action *action,
return true;
}
else if (field == ACTION_FIELD_SAME) {
- bool set;
-
- if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
-
- if (!ExprResolveBoolean(keymap->ctx, value, &set))
- return ReportMismatch(keymap, action->type, field, "boolean");
-
- if (set)
- act->flags &= ~ACTION_SAME_SCREEN;
- else
- act->flags |= ACTION_SAME_SCREEN;
-
- return true;
+ return CheckBooleanFlag(keymap->ctx, action->type, field,
+ ACTION_SAME_SCREEN, array_ndx, value,
+ &act->flags);
}
- return ReportIllegal(keymap, action->type, field);
+ return ReportIllegal(keymap->ctx, action->type, field);
}
static bool
@@ -705,17 +624,21 @@ HandleSetLockControls(struct xkb_keymap *keymap, union xkb_action *action,
unsigned int mask;
if (array_ndx)
- return ReportActionNotArray(keymap, action->type, field);
+ return ReportActionNotArray(keymap->ctx, action->type, field);
if (!ExprResolveMask(keymap->ctx, value, &mask, ctrlMaskNames))
- return ReportMismatch(keymap, action->type, field,
+ return ReportMismatch(keymap->ctx, action->type, field,
"controls mask");
act->ctrls = mask;
return true;
}
+ else if (field == ACTION_FIELD_AFFECT) {
+ return CheckAffectField(keymap->ctx, action->type, array_ndx, value,
+ &act->flags);
+ }
- return ReportIllegal(keymap, action->type, field);
+ return ReportIllegal(keymap->ctx, action->type, field);
}
static bool
@@ -728,8 +651,11 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
if (field == ACTION_FIELD_TYPE) {
int type;
+ if (array_ndx)
+ return ReportActionNotArray(keymap->ctx, action->type, field);
+
if (!ExprResolveInteger(keymap->ctx, value, &type))
- return ReportMismatch(keymap, ACTION_TYPE_PRIVATE, field, "integer");
+ return ReportMismatch(keymap->ctx, ACTION_TYPE_PRIVATE, field, "integer");
if (type < 0 || type > 255) {
log_err(keymap->ctx,
@@ -764,17 +690,17 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
if (array_ndx == NULL) {
xkb_atom_t val;
const char *str;
- int len;
+ size_t len;
if (!ExprResolveString(keymap->ctx, value, &val))
- return ReportMismatch(keymap, action->type, field, "string");
+ return ReportMismatch(keymap->ctx, action->type, field, "string");
str = xkb_atom_text(keymap->ctx, val);
len = strlen(str);
if (len < 1 || len > 7) {
log_warn(keymap->ctx,
"A private action has 7 data bytes; "
- "Extra %d bytes ignored\n", len - 6);
+ "Illegal data ignored\n");
return false;
}
@@ -791,7 +717,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
return false;
}
- if (ndx < 0 || ndx >= sizeof(act->data)) {
+ if (ndx < 0 || (size_t) ndx >= sizeof(act->data)) {
log_err(keymap->ctx,
"The data for a private action is %lu bytes long; "
"Attempt to use data[%d] ignored\n",
@@ -800,7 +726,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
}
if (!ExprResolveInteger(keymap->ctx, value, &datum))
- return ReportMismatch(keymap, act->type, field, "integer");
+ return ReportMismatch(keymap->ctx, act->type, field, "integer");
if (datum < 0 || datum > 255) {
log_err(keymap->ctx,
@@ -814,7 +740,7 @@ HandlePrivate(struct xkb_keymap *keymap, union xkb_action *action,
}
}
- return ReportIllegal(keymap, ACTION_TYPE_NONE, field);
+ return ReportIllegal(keymap->ctx, ACTION_TYPE_NONE, field);
}
typedef bool (*actionHandler)(struct xkb_keymap *keymap,
@@ -825,12 +751,12 @@ typedef bool (*actionHandler)(struct xkb_keymap *keymap,
static const actionHandler handleAction[_ACTION_TYPE_NUM_ENTRIES] = {
[ACTION_TYPE_NONE] = HandleNoAction,
- [ACTION_TYPE_MOD_SET] = HandleSetLatchMods,
- [ACTION_TYPE_MOD_LATCH] = HandleSetLatchMods,
- [ACTION_TYPE_MOD_LOCK] = HandleLockMods,
- [ACTION_TYPE_GROUP_SET] = HandleSetLatchGroup,
- [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchGroup,
- [ACTION_TYPE_GROUP_LOCK] = HandleLockGroup,
+ [ACTION_TYPE_MOD_SET] = HandleSetLatchLockMods,
+ [ACTION_TYPE_MOD_LATCH] = HandleSetLatchLockMods,
+ [ACTION_TYPE_MOD_LOCK] = HandleSetLatchLockMods,
+ [ACTION_TYPE_GROUP_SET] = HandleSetLatchLockGroup,
+ [ACTION_TYPE_GROUP_LATCH] = HandleSetLatchLockGroup,
+ [ACTION_TYPE_GROUP_LOCK] = HandleSetLatchLockGroup,
[ACTION_TYPE_PTR_MOVE] = HandleMovePtr,
[ACTION_TYPE_PTR_BUTTON] = HandlePtrBtn,
[ACTION_TYPE_PTR_LOCK] = HandlePtrBtn,
@@ -921,7 +847,6 @@ HandleActionDef(ExprDef *def, struct xkb_keymap *keymap,
return true;
}
-
bool
SetActionField(struct xkb_keymap *keymap, const char *elem, const char *field,
ExprDef *array_ndx, ExprDef *value, ActionsInfo *info)
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
index d470884e78..11bc0912d1 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.c
@@ -53,7 +53,6 @@
#include "xkbcomp-priv.h"
#include "ast-build.h"
-#include "parser-priv.h"
#include "include.h"
ParseCommon *
@@ -202,7 +201,7 @@ ExprCreateKeysymList(xkb_keysym_t sym)
ExprDef *
ExprCreateMultiKeysymList(ExprDef *expr)
{
- size_t nLevels = darray_size(expr->keysym_list.symsMapIndex);
+ unsigned nLevels = darray_size(expr->keysym_list.symsMapIndex);
darray_resize(expr->keysym_list.symsMapIndex, 1);
darray_resize(expr->keysym_list.symsNumEntries, 1);
@@ -215,7 +214,7 @@ ExprCreateMultiKeysymList(ExprDef *expr)
ExprDef *
ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
{
- size_t nSyms = darray_size(expr->keysym_list.syms);
+ unsigned nSyms = darray_size(expr->keysym_list.syms);
darray_append(expr->keysym_list.symsMapIndex, nSyms);
darray_append(expr->keysym_list.symsNumEntries, 1);
@@ -227,8 +226,8 @@ ExprAppendKeysymList(ExprDef *expr, xkb_keysym_t sym)
ExprDef *
ExprAppendMultiKeysymList(ExprDef *expr, ExprDef *append)
{
- size_t nSyms = darray_size(expr->keysym_list.syms);
- size_t numEntries = darray_size(append->keysym_list.syms);
+ unsigned nSyms = darray_size(expr->keysym_list.syms);
+ unsigned numEntries = darray_size(append->keysym_list.syms);
darray_append(expr->keysym_list.symsMapIndex, nSyms);
darray_append(expr->keysym_list.symsNumEntries, numEntries);
@@ -356,7 +355,7 @@ SymbolsCreate(xkb_atom_t keyName, VarDef *symbols)
}
GroupCompatDef *
-GroupCompatCreate(int group, ExprDef *val)
+GroupCompatCreate(unsigned group, ExprDef *val)
{
GroupCompatDef *def = malloc(sizeof(*def));
if (!def)
@@ -372,7 +371,7 @@ GroupCompatCreate(int group, ExprDef *val)
}
ModMapDef *
-ModMapCreate(uint32_t modifier, ExprDef *keys)
+ModMapCreate(xkb_atom_t modifier, ExprDef *keys)
{
ModMapDef *def = malloc(sizeof(*def));
if (!def)
@@ -404,7 +403,7 @@ LedMapCreate(xkb_atom_t name, VarDef *body)
}
LedNameDef *
-LedNameCreate(int ndx, ExprDef *name, bool virtual)
+LedNameCreate(unsigned ndx, ExprDef *name, bool virtual)
{
LedNameDef *def = malloc(sizeof(*def));
if (!def)
@@ -496,8 +495,8 @@ err:
}
XkbFile *
-XkbFileCreate(struct xkb_context *ctx, enum xkb_file_type type, char *name,
- ParseCommon *defs, enum xkb_map_flags flags)
+XkbFileCreate(enum xkb_file_type type, char *name, ParseCommon *defs,
+ enum xkb_map_flags flags)
{
XkbFile *file;
@@ -533,7 +532,7 @@ XkbFileFromComponents(struct xkb_context *ctx,
if (!include)
goto err;
- file = XkbFileCreate(ctx, type, NULL, &include->common, 0);
+ file = XkbFileCreate(type, NULL, (ParseCommon *) include, 0);
if (!file) {
FreeInclude(include);
goto err;
@@ -542,7 +541,7 @@ XkbFileFromComponents(struct xkb_context *ctx,
defs = AppendStmt(defs, &file->common);
}
- file = XkbFileCreate(ctx, FILE_TYPE_KEYMAP, NULL, defs, 0);
+ file = XkbFileCreate(FILE_TYPE_KEYMAP, NULL, defs, 0);
if (!file)
goto err;
@@ -565,7 +564,7 @@ FreeExpr(ExprDef *expr)
case EXPR_UNARY_PLUS:
case EXPR_NOT:
case EXPR_INVERT:
- FreeStmt(&expr->unary.child->common);
+ FreeStmt((ParseCommon *) expr->unary.child);
break;
case EXPR_DIVIDE:
@@ -573,16 +572,16 @@ FreeExpr(ExprDef *expr)
case EXPR_SUBTRACT:
case EXPR_MULTIPLY:
case EXPR_ASSIGN:
- FreeStmt(&expr->binary.left->common);
- FreeStmt(&expr->binary.right->common);
+ FreeStmt((ParseCommon *) expr->binary.left);
+ FreeStmt((ParseCommon *) expr->binary.right);
break;
case EXPR_ACTION_DECL:
- FreeStmt(&expr->action.args->common);
+ FreeStmt((ParseCommon *) expr->action.args);
break;
case EXPR_ARRAY_REF:
- FreeStmt(&expr->array_ref.entry->common);
+ FreeStmt((ParseCommon *) expr->array_ref.entry);
break;
case EXPR_KEYSYM_LIST:
@@ -619,12 +618,10 @@ void
FreeStmt(ParseCommon *stmt)
{
ParseCommon *next;
- YYSTYPE u;
while (stmt)
{
next = stmt->next;
- u.any = stmt;
switch (stmt->type) {
case STMT_INCLUDE:
@@ -633,36 +630,36 @@ FreeStmt(ParseCommon *stmt)
stmt = NULL;
break;
case STMT_EXPR:
- FreeExpr(u.expr);
+ FreeExpr((ExprDef *) stmt);
break;
case STMT_VAR:
- FreeStmt(&u.var->name->common);
- FreeStmt(&u.var->value->common);
+ FreeStmt((ParseCommon *) ((VarDef *) stmt)->name);
+ FreeStmt((ParseCommon *) ((VarDef *) stmt)->value);
break;
case STMT_TYPE:
- FreeStmt(&u.keyType->body->common);
+ FreeStmt((ParseCommon *) ((KeyTypeDef *) stmt)->body);
break;
case STMT_INTERP:
- FreeStmt(&u.interp->match->common);
- FreeStmt(&u.interp->def->common);
+ FreeStmt((ParseCommon *) ((InterpDef *) stmt)->match);
+ FreeStmt((ParseCommon *) ((InterpDef *) stmt)->def);
break;
case STMT_VMOD:
- FreeStmt(&u.vmod->value->common);
+ FreeStmt((ParseCommon *) ((VModDef *) stmt)->value);
break;
case STMT_SYMBOLS:
- FreeStmt(&u.syms->symbols->common);
+ FreeStmt((ParseCommon *) ((SymbolsDef *) stmt)->symbols);
break;
case STMT_MODMAP:
- FreeStmt(&u.modMask->keys->common);
+ FreeStmt((ParseCommon *) ((ModMapDef *) stmt)->keys);
break;
case STMT_GROUP_COMPAT:
- FreeStmt(&u.groupCompat->def->common);
+ FreeStmt((ParseCommon *) ((GroupCompatDef *) stmt)->def);
break;
case STMT_LED_MAP:
- FreeStmt(&u.ledMap->body->common);
+ FreeStmt((ParseCommon *) ((LedMapDef *) stmt)->body);
break;
case STMT_LED_NAME:
- FreeStmt(&u.ledName->name->common);
+ FreeStmt((ParseCommon *) ((LedNameDef *) stmt)->name);
break;
default:
break;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
index 8146b066d1..b57e4cdce1 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast-build.h
@@ -98,23 +98,23 @@ SymbolsDef *
SymbolsCreate(xkb_atom_t keyName, VarDef *symbols);
GroupCompatDef *
-GroupCompatCreate(int group, ExprDef *def);
+GroupCompatCreate(unsigned group, ExprDef *def);
ModMapDef *
-ModMapCreate(uint32_t modifier, ExprDef *keys);
+ModMapCreate(xkb_atom_t modifier, ExprDef *keys);
LedMapDef *
LedMapCreate(xkb_atom_t name, VarDef *body);
LedNameDef *
-LedNameCreate(int ndx, ExprDef *name, bool virtual);
+LedNameCreate(unsigned ndx, ExprDef *name, bool virtual);
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, enum xkb_map_flags flags);
+XkbFileCreate(enum xkb_file_type type, char *name, 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 489b33193c..26cbb3a3e4 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/ast.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/ast.h
@@ -143,9 +143,7 @@ expr_op_type_to_string(enum expr_op_type type);
const char *
expr_value_type_to_string(enum expr_value_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 {
+typedef struct _ParseCommon {
struct _ParseCommon *next;
enum stmt_type type;
} ParseCommon;
@@ -226,7 +224,7 @@ typedef struct {
typedef struct {
ExprCommon expr;
darray(xkb_keysym_t) syms;
- darray(int) symsMapIndex;
+ darray(unsigned int) symsMapIndex;
darray(unsigned int) symsNumEntries;
} ExprKeysymList;
@@ -299,7 +297,7 @@ typedef struct {
typedef struct {
ParseCommon common;
enum merge_mode merge;
- int group;
+ unsigned group;
ExprDef *def;
} GroupCompatDef;
@@ -314,7 +312,7 @@ typedef struct {
typedef struct {
ParseCommon common;
enum merge_mode merge;
- int ndx;
+ unsigned ndx;
ExprDef *name;
bool virtual;
} LedNameDef;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
index fffb2d34b2..475895c6c1 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/compat.c
@@ -54,179 +54,6 @@
#include "vmod.h"
#include "include.h"
-/*
- * The xkb_compat section
- * =====================
- * This section is the third to be processed, after xkb_keycodes and
- * xkb_types.
- *
- * Interpret statements
- * --------------------
- * Statements of the form:
- * interpret Num_Lock+Any { ... }
- * interpret Shift_Lock+AnyOf(Shift+Lock) { ... }
- *
- * The xkb_symbols section (see symbols.c) allows the keymap author to do,
- * among other things, the following for each key:
- * - Bind an action, like SetMods or LockGroup, to the key. Actions, like
- * symbols, are specified for each level of each group in the key
- * separately.
- * - Add a virtual modifier to the key's virtual modifier mapping (vmodmap).
- * - Specify whether the key should repeat or not.
- *
- * However, doing this for each key (or level) is tedious and inflexible.
- * Interpret's are a mechanism to apply these settings to a bunch of
- * keys/levels at once.
- *
- * Each interpret specifies a condition by which it attaches to certain
- * levels. The condition consists of two parts:
- * - A keysym. If the level has a different (or more than one) keysym, the
- * match failes. Leaving out the keysym is equivalent to using the
- * NoSymbol keysym, which always matches successfully.
- * - A modifier predicate. The predicate consists of a matching operation
- * and a mask of (real) modifiers. The modifers are matched against the
- * key's modifier map (modmap). The matching operation can be one of the
- * following:
- * + AnyOfOrNone - The modmap must either be empty or include at least
- * one of the specified modifiers.
- * + AnyOf - The modmap must include at least one of the specified
- * modifiers.
- * + NoneOf - The modmap must not include any of the specified modifiers.
- * + AllOf - The modmap must include all of the specified modifiers (but
- * may include others as well).
- * + Exactly - The modmap must be exactly the same as the specified
- * modifiers.
- * Leaving out the predicate is equivalent to usign AnyOfOrNone while
- * specifying all modifiers. Leaving out just the matching condtition
- * is equivalent to using Exactly.
- * An interpret may also include "useModMapMods = level1;" - see below.
- *
- * If a level fulfils the conditions of several interpret's, only the
- * most specific one is used:
- * - A specific keysym will always match before a generic NoSymbol
- * condition.
- * - If the keysyms are the same, the interpret with the more specific
- * matching operation is used. The above list is sorted from least to
- * most specific.
- * - If both the keysyms and the matching operations are the same (but the
- * modifiers are different), the first interpret is used.
- *
- * As described above, once an interpret "attaches" to a level, it can bind
- * an action to that level, add one virtual modifier to the key's vmodmap,
- * or set the key's repeat setting. You should note the following:
- * - The key repeat is a property of the entire key; it is not level-specific.
- * In order to avoid confusion, it is only inspected for the first level of
- * the first group; the interpret's repeat setting is ignored when applied
- * to other levels.
- * - If one of the above fields was set directly for a key in xkb_symbols,
- * the explicit setting takes precedence over the interpret.
- *
- * The body of the statment may include statements of the following
- * forms (all of which are optional):
- *
- * - useModMapMods statement:
- * useModMapMods = level1;
- *
- * When set to 'level1', the interpret will only match levels which are
- * the first level of the first group of the keys. This can be useful in
- * conjunction with e.g. a virtualModifier statement.
- *
- * - action statement:
- * action = LockMods(modifiers=NumLock);
- *
- * Bind this action to the matching levels.
- *
- * - virtual modifier statement:
- * virtualModifier = NumLock;
- *
- * Add this virtual modifier to the key's vmodmap. The given virtual
- * modifier must be declared at the top level of the file with a
- * virtual_modifiers statement, e.g.:
- * virtual_modifiers NumLock;
- *
- * - repeat statement:
- * repeat = True;
- *
- * Set whether the key should repeat or not. Must be a boolean value.
- *
- * Led map statements
- * ------------------------
- * Statements of the form:
- * indicator "Shift Lock" { ... }
- *
- * This statement specifies the behavior and binding of the LED (a.k.a
- * indicator) with the given name ("Shift Lock" above). The name should
- * have been declared previously in the xkb_keycodes section (see Led
- * name statement), and given an index there. If it wasn't, it is created
- * with the next free index.
- * The body of the statement describes the conditions of the keyboard
- * state which will cause the LED to be lit. It may include the following
- * statements:
- *
- * - modifiers statment:
- * modifiers = ScrollLock;
- *
- * If the given modifiers are in the required state (see below), the
- * led is lit.
- *
- * - whichModifierState statment:
- * whichModState = Latched + Locked;
- *
- * Can be any combination of:
- * base, latched, locked, effective
- * any (i.e. all of the above)
- * none (i.e. none of the above)
- * compat (legacy value, treated as effective)
- * This will cause the respective portion of the modifer state (see
- * struct xkb_state) to be matched against the modifiers given in the
- * "modifiers" statement.
- *
- * Here's a simple example:
- * indicator "Num Lock" {
- * modifiers = NumLock;
- * whichModState = Locked;
- * };
- * Whenever the NumLock modifier is locked, the Num Lock LED will light
- * up.
- *
- * - groups statment:
- * groups = All - group1;
- *
- * If the given groups are in the required state (see below), the led
- * is lit.
- *
- * - whichGroupState statment:
- * whichGroupState = Effective;
- *
- * Can be any combination of:
- * base, latched, locked, effective
- * any (i.e. all of the above)
- * none (i.e. none of the above)
- * This will cause the respective portion of the group state (see
- * struct xkb_state) to be matched against the groups given in the
- * "groups" statement.
- *
- * Note: the above conditions are disjunctive, i.e. if any of them are
- * satisfied the led is lit.
- *
- * Virtual modifier statements
- * ---------------------------
- * Statements of the form:
- * virtual_modifiers LControl;
- *
- * Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
- * TODO
- *
- * Effect on keymap
- * ----------------
- * After all of the xkb_compat sections have been compiled, the following
- * members of struct xkb_keymap are finalized:
- * darray(struct xkb_sym_interpret) sym_interprets;
- * darray(struct xkb_led) leds;
- * char *compat_section_name;
- * TODO: virtual modifiers.
- */
-
enum si_field {
SI_FIELD_VIRTUAL_MOD = (1 << 0),
SI_FIELD_ACTION = (1 << 1),
@@ -555,16 +382,28 @@ MergeIncludedCompatMaps(CompatInfo *into, CompatInfo *from,
from->name = NULL;
}
- darray_foreach(si, from->interps) {
- si->merge = (merge == MERGE_DEFAULT ? si->merge : merge);
- if (!AddInterp(into, si, false))
- into->errorCount++;
+ if (darray_empty(into->interps)) {
+ into->interps = from->interps;
+ darray_init(from->interps);
+ }
+ else {
+ darray_foreach(si, from->interps) {
+ si->merge = (merge == MERGE_DEFAULT ? si->merge : merge);
+ if (!AddInterp(into, si, false))
+ into->errorCount++;
+ }
}
- darray_foreach(ledi, from->leds) {
- ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge);
- if (!AddLedMap(into, ledi, false))
- into->errorCount++;
+ if (darray_empty(into->leds)) {
+ into->leds = from->leds;
+ darray_init(from->leds);
+ }
+ else {
+ darray_foreach(ledi, from->leds) {
+ ledi->merge = (merge == MERGE_DEFAULT ? ledi->merge : merge);
+ if (!AddLedMap(into, ledi, false))
+ into->errorCount++;
+ }
}
}
@@ -929,7 +768,7 @@ HandleCompatMapFile(CompatInfo *info, XkbFile *file, enum merge_mode merge)
ok = HandleGlobalVar(info, (VarDef *) stmt);
break;
case STMT_VMOD:
- ok = HandleVModDef(info->keymap, (VModDef *) stmt);
+ ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break;
default:
log_err(info->keymap->ctx,
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
index ba71208f7e..c514f8d54c 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/expr.c
@@ -116,7 +116,7 @@ LookupModMask(struct xkb_context *ctx, const void *priv, xkb_atom_t field,
if (ndx == XKB_MOD_INVALID)
return false;
- *val_rtrn = (1 << ndx);
+ *val_rtrn = (1u << ndx);
return true;
}
@@ -427,14 +427,8 @@ ExprResolveLevel(struct xkb_context *ctx, const ExprDef *expr,
bool
ExprResolveButton(struct xkb_context *ctx, const ExprDef *expr, int *btn_rtrn)
{
- int result;
-
- if (!ExprResolveIntegerLookup(ctx, expr, &result, SimpleLookup,
- buttonNames))
- return false;
-
- *btn_rtrn = result;
- return true;
+ return ExprResolveIntegerLookup(ctx, expr, btn_rtrn, SimpleLookup,
+ buttonNames);
}
bool
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
index 59916b7266..d90f6a4465 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keycodes.c
@@ -29,79 +29,6 @@
#include "expr.h"
#include "include.h"
-/*
- * The xkb_keycodes section
- * ========================
- *
- * This is the simplest section type, and is the first one to be
- * compiled. The purpose of this is mostly to map between the
- * hardware/evdev scancodes and xkb keycodes. Each key is given a name
- * by which it can be referred to later, e.g. in the symbols section.
- *
- * Keycode statements
- * ------------------
- * Statements of the form:
- * <TLDE> = 49;
- * <AE01> = 10;
- *
- * The above would let 49 and 10 be valid keycodes in the keymap, and
- * assign them the names TLDE and AE01 respectively. The format <WXYZ> is
- * always used to refer to a key by name.
- *
- * [ The naming convention <AE01> just denoted the position of the key
- * in the main alphanumric section of the keyboard, with the two letters
- * specifying the row and the two digits specifying the column, from
- * the bottom left.]
- *
- * In the common case this just maps to the evdev scancodes from
- * /usr/include/linux/input.h, e.g. the following definitions:
- * #define KEY_GRAVE 41
- * #define KEY_1 2
- * Similar definitions appear in the xf86-input-keyboard driver. Note
- * that in all current keymaps there's a constant offset of 8 (for
- * historical reasons).
- *
- * If there's a conflict, like the same name given to different keycodes,
- * or same keycode given different names, it is resolved according to the
- * merge mode which applies to the definitions.
- *
- * Alias statements
- * ----------------
- * Statements of the form:
- * alias <MENU> = <COMP>;
- *
- * Allows to refer to a previously defined key (here <COMP>) by another
- * name (here <MENU>). Conflicts are handled similarly.
- *
- * LED name statements
- * -------------------------
- * Statements of the form:
- * indicator 1 = "Caps Lock";
- * indicator 2 = "Num Lock";
- * indicator 3 = "Scroll Lock";
- *
- * Assigns a name to the keyboard LED (a.k.a indicator) with the given index.
- * The led may be referred by this name later in the compat section
- * and by the user.
- *
- * Effect on the keymap
- * --------------------
- * After all of the xkb_keycodes sections have been compiled, the
- * following members of struct xkb_keymap are finalized:
- * xkb_keycode_t min_key_code;
- * xkb_keycode_t max_key_code;
- * unsigned int num_aliases;
- * struct xkb_key_alias *key_aliases;
- * char *keycodes_section_name;
- * The 'name' field of leds declared in xkb_keycodes:
- * darray(struct xkb_led) leds;
- * Further, the array of keys:
- * struct xkb_key *keys;
- * had been resized to its final size (i.e. all of the xkb_key objects are
- * referable by their keycode). However the objects themselves do not
- * contain any useful information besides the key name at this point.
- */
-
typedef struct {
enum merge_mode merge;
@@ -322,7 +249,7 @@ AddKeyName(KeyNamesInfo *info, xkb_keycode_t kc, xkb_atom_t name,
/***====================================================================***/
-static int
+static bool
HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge);
static void
@@ -459,7 +386,7 @@ HandleKeycodeDef(KeyNamesInfo *info, KeycodeDef *stmt, enum merge_mode merge)
return AddKeyName(info, stmt->value, stmt->name, merge, false, true);
}
-static int
+static bool
HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge)
{
AliasInfo *old, new;
@@ -499,7 +426,7 @@ HandleAliasDef(KeyNamesInfo *info, KeyAliasDef *def, enum merge_mode merge)
return true;
}
-static int
+static bool
HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt)
{
const char *elem, *field;
@@ -524,7 +451,7 @@ HandleKeyNameVar(KeyNamesInfo *info, VarDef *stmt)
return true;
}
-static int
+static bool
HandleLedNameDef(KeyNamesInfo *info, LedNameDef *def,
enum merge_mode merge)
{
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
index 6b4c266ec0..7f70ca3481 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap-dump.c
@@ -92,7 +92,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...)
if (printed < 0)
goto err;
- if (printed >= available)
+ if ((size_t) printed >= available)
if (!do_realloc(buf, printed))
goto err;
@@ -103,7 +103,7 @@ check_write_buf(struct buf *buf, const char *fmt, ...)
printed = vsnprintf(buf->buf + buf->size, available, fmt, args);
va_end(args);
- if (printed >= available || printed < 0)
+ if (printed < 0 || (size_t) printed >= available)
goto err;
buf->size += printed;
@@ -273,6 +273,20 @@ write_led_map(struct xkb_keymap *keymap, struct buf *buf,
return true;
}
+static const char *
+affect_lock_text(enum xkb_action_flags flags)
+{
+ switch (flags & (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) {
+ case ACTION_LOCK_NO_UNLOCK:
+ return ",affect=lock";
+ case ACTION_LOCK_NO_LOCK:
+ return ",affect=unlock";
+ case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK:
+ return ",affect=neither";
+ }
+ return "";
+}
+
static bool
write_action(struct xkb_keymap *keymap, struct buf *buf,
const union xkb_action *action,
@@ -289,20 +303,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
type = ActionTypeText(action->type);
switch (action->type) {
+ case ACTION_TYPE_MOD_LOCK:
case ACTION_TYPE_MOD_SET:
case ACTION_TYPE_MOD_LATCH:
- case ACTION_TYPE_MOD_LOCK:
if (action->mods.flags & ACTION_MODS_LOOKUP_MODMAP)
args = "modMapMods";
else
args = ModMaskText(keymap, action->mods.mods.mods);
- write_buf(buf, "%s%s(modifiers=%s%s%s)%s", prefix, type, args,
- (action->type != ACTION_TYPE_MOD_LOCK &&
- (action->mods.flags & ACTION_LOCK_CLEAR)) ?
- ",clearLocks" : "",
- (action->type != ACTION_TYPE_MOD_LOCK &&
- (action->mods.flags & ACTION_LATCH_TO_LOCK)) ?
- ",latchToLock" : "",
+ write_buf(buf, "%s%s(modifiers=%s%s%s%s)%s", prefix, type, args,
+ (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "",
+ (action->type != ACTION_TYPE_MOD_LOCK && (action->mods.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "",
+ (action->type == ACTION_TYPE_MOD_LOCK) ? affect_lock_text(action->mods.flags) : "",
suffix);
break;
@@ -310,16 +321,10 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
case ACTION_TYPE_GROUP_LATCH:
case ACTION_TYPE_GROUP_LOCK:
write_buf(buf, "%s%s(group=%s%d%s%s)%s", prefix, type,
- (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) &&
- action->group.group > 0) ? "+" : "",
- (action->group.flags & ACTION_ABSOLUTE_SWITCH) ?
- action->group.group + 1 : action->group.group,
- (action->type != ACTION_TYPE_GROUP_LOCK &&
- (action->group.flags & ACTION_LOCK_CLEAR)) ?
- ",clearLocks" : "",
- (action->type != ACTION_TYPE_GROUP_LOCK &&
- (action->group.flags & ACTION_LATCH_TO_LOCK)) ?
- ",latchToLock" : "",
+ (!(action->group.flags & ACTION_ABSOLUTE_SWITCH) && action->group.group > 0) ? "+" : "",
+ (action->group.flags & ACTION_ABSOLUTE_SWITCH) ? action->group.group + 1 : action->group.group,
+ (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LOCK_CLEAR)) ? ",clearLocks" : "",
+ (action->type != ACTION_TYPE_GROUP_LOCK && (action->group.flags & ACTION_LATCH_TO_LOCK)) ? ",latchToLock" : "",
suffix);
break;
@@ -329,35 +334,17 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
case ACTION_TYPE_PTR_MOVE:
write_buf(buf, "%s%s(x=%s%d,y=%s%d%s)%s", prefix, type,
- (!(action->ptr.flags & ACTION_ABSOLUTE_X) &&
- action->ptr.x >= 0) ? "+" : "",
+ (!(action->ptr.flags & ACTION_ABSOLUTE_X) && action->ptr.x >= 0) ? "+" : "",
action->ptr.x,
- (!(action->ptr.flags & ACTION_ABSOLUTE_Y) &&
- action->ptr.y >= 0) ? "+" : "",
+ (!(action->ptr.flags & ACTION_ABSOLUTE_Y) && action->ptr.y >= 0) ? "+" : "",
action->ptr.y,
- (action->ptr.flags & ACTION_NO_ACCEL) ? ",!accel" : "",
+ (action->ptr.flags & ACTION_ACCEL) ? "" : ",!accel",
suffix);
break;
case ACTION_TYPE_PTR_LOCK:
- switch (action->btn.flags &
- (ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK)) {
- case ACTION_LOCK_NO_UNLOCK:
- args = ",affect=lock";
- break;
-
- case ACTION_LOCK_NO_LOCK:
- args = ",affect=unlock";
- break;
-
- case ACTION_LOCK_NO_LOCK | ACTION_LOCK_NO_UNLOCK:
- args = ",affect=neither";
- break;
-
- default:
- args = ",affect=both";
- break;
- }
+ args = affect_lock_text(action->btn.flags);
+ /* fallthrough */
case ACTION_TYPE_PTR_BUTTON:
write_buf(buf, "%s%s(button=", prefix, type);
if (action->btn.button > 0 && action->btn.button <= 5)
@@ -374,25 +361,25 @@ write_action(struct xkb_keymap *keymap, struct buf *buf,
case ACTION_TYPE_PTR_DEFAULT:
write_buf(buf, "%s%s(", prefix, type);
write_buf(buf, "affect=button,button=%s%d",
- (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) &&
- action->dflt.value >= 0) ? "+" : "",
+ (!(action->dflt.flags & ACTION_ABSOLUTE_SWITCH) && action->dflt.value >= 0) ? "+" : "",
action->dflt.value);
write_buf(buf, ")%s", suffix);
break;
case ACTION_TYPE_SWITCH_VT:
write_buf(buf, "%s%s(screen=%s%d,%ssame)%s", prefix, type,
- (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) &&
- action->screen.screen >= 0) ? "+" : "",
+ (!(action->screen.flags & ACTION_ABSOLUTE_SWITCH) && action->screen.screen >= 0) ? "+" : "",
action->screen.screen,
- (action->screen.flags & ACTION_SAME_SCREEN) ? "!" : "",
+ (action->screen.flags & ACTION_SAME_SCREEN) ? "" : "!",
suffix);
break;
case ACTION_TYPE_CTRL_SET:
case ACTION_TYPE_CTRL_LOCK:
- write_buf(buf, "%s%s(controls=%s)%s", prefix, type,
- ControlMaskText(keymap->ctx, action->ctrls.ctrls), suffix);
+ write_buf(buf, "%s%s(controls=%s%s)%s", prefix, type,
+ ControlMaskText(keymap->ctx, action->ctrls.ctrls),
+ (action->type == ACTION_TYPE_CTRL_LOCK) ? affect_lock_text(action->ctrls.flags) : "",
+ suffix);
break;
case ACTION_TYPE_NONE:
@@ -429,7 +416,7 @@ write_compat(struct xkb_keymap *keymap, struct buf *buf)
write_buf(buf, "\tinterpret.useModMapMods= AnyLevel;\n");
write_buf(buf, "\tinterpret.repeat= False;\n");
- for (int i = 0; i < keymap->num_sym_interprets; i++) {
+ for (unsigned 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",
@@ -635,7 +622,7 @@ write_symbols(struct xkb_keymap *keymap, struct buf *buf)
continue;
darray_enumerate(i, mod, keymap->mods)
- if (key->modmap & (1 << i))
+ if (key->modmap & (1u << i))
write_buf(buf, "\tmodifier_map %s { %s };\n",
xkb_atom_text(keymap->ctx, mod->name),
KeyNameText(keymap->ctx, key->name));
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
index 549cf05da6..8a70577faf 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keymap.c
@@ -39,7 +39,7 @@ ComputeEffectiveMask(struct xkb_keymap *keymap, struct xkb_mods *mods)
mods->mask = mods->mods & MOD_REAL_MASK_ALL;
darray_enumerate(i, mod, keymap->mods)
- if (mods->mods & (1 << i))
+ if (mods->mods & (1u << i))
mods->mask |= mod->mapping;
}
@@ -92,7 +92,7 @@ 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.
*/
- for (int i = 0; i < keymap->num_sym_interprets; i++) {
+ for (unsigned i = 0; i < keymap->num_sym_interprets; i++) {
const struct xkb_sym_interpret *interp = &keymap->sym_interprets[i];
xkb_mod_mask_t mods;
@@ -158,7 +158,7 @@ ApplyInterpsToKey(struct xkb_keymap *keymap, struct xkb_key *key)
if ((group == 0 && level == 0) || !interp->level_one_only)
if (interp->virtual_mod != XKB_MOD_INVALID)
- vmodmap |= (1 << interp->virtual_mod);
+ vmodmap |= (1u << interp->virtual_mod);
if (interp->action.type != ACTION_TYPE_NONE)
key->groups[group].levels[level].action = interp->action;
@@ -194,7 +194,7 @@ UpdateDerivedKeymapFields(struct xkb_keymap *keymap)
/* Update keymap->mods, the virtual -> real mod mapping. */
xkb_foreach_key(key, keymap)
darray_enumerate(i, mod, keymap->mods)
- if (key->vmodmap & (1 << i))
+ if (key->vmodmap & (1u << i))
mod->mapping |= key->modmap;
/* Now update the level masks for all the types to reflect the vmods. */
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c
index c19d66ffde..abab7fe266 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/keywords.c
@@ -339,10 +339,9 @@ keyword_gperf_lookup (register const char *str, register unsigned int len)
int
-keyword_to_token(const char *string)
+keyword_to_token(const char *string, unsigned int len)
{
- const struct keyword_tok *kt;
- kt = keyword_gperf_lookup(string, strlen(string));
+ const struct keyword_tok *kt = keyword_gperf_lookup(string, len);
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 05e725eb00..0675e55a8f 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser-priv.h
@@ -27,24 +27,18 @@
#ifndef XKBCOMP_PARSER_PRIV_H
#define XKBCOMP_PARSER_PRIV_H
-struct scanner;
struct parser_param;
+#include "scanner-utils.h"
#include "parser.h"
int
-scanner_error(struct scanner *scanner, const char *msg);
-
-void
-scanner_warn(struct scanner *s, const char *msg);
-
-int
_xkbcommon_lex(YYSTYPE *yylval, struct scanner *scanner);
XkbFile *
-parse(struct xkb_context *ctx, void *scanner, const char *map);
+parse(struct xkb_context *ctx, struct scanner *scanner, const char *map);
int
-keyword_to_token(const char *string);
+keyword_to_token(const char *string, unsigned int len);
#endif
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
index 26bbf30be8..eaa7384369 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.c
@@ -82,27 +82,21 @@
struct parser_param {
struct xkb_context *ctx;
- void *scanner;
+ struct scanner *scanner;
XkbFile *rtrn;
bool more_maps;
};
-static void
-parser_error(struct parser_param *param, const char *msg)
-{
- scanner_error(param->scanner, msg);
-}
+#define parser_err(param, fmt, ...) \
+ scanner_err((param)->scanner, fmt, ##__VA_ARGS__)
-static void
-parser_warn(struct parser_param *param, const char *msg)
-{
- scanner_warn(param->scanner, msg);
-}
+#define parser_warn(param, fmt, ...) \
+ scanner_warn((param)->scanner, fmt, ##__VA_ARGS__)
static void
_xkbcommon_error(struct parser_param *param, const char *msg)
{
- parser_error(param, msg);
+ parser_err(param, "%s", msg);
}
static bool
@@ -129,11 +123,11 @@ resolve_keysym(const char *str, xkb_keysym_t *sym_rtrn)
return false;
}
-#define scanner param->scanner
+#define param_scanner param->scanner
/* Line 268 of yacc.c */
-#line 137 "src/xkbcomp/parser.c"
+#line 131 "src/xkbcomp/parser.c"
/* Enabling traces. */
#ifndef YYDEBUG
@@ -298,7 +292,7 @@ typedef union YYSTYPE
{
/* Line 293 of yacc.c */
-#line 167 "parser.y"
+#line 161 "parser.y"
int ival;
int64_t num;
@@ -327,7 +321,7 @@ typedef union YYSTYPE
/* Line 293 of yacc.c */
-#line 331 "src/xkbcomp/parser.c"
+#line 325 "src/xkbcomp/parser.c"
} YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
@@ -339,7 +333,7 @@ typedef union YYSTYPE
/* Line 343 of yacc.c */
-#line 343 "src/xkbcomp/parser.c"
+#line 337 "src/xkbcomp/parser.c"
#ifdef short
# undef short
@@ -698,25 +692,25 @@ static const yytype_int16 yyrhs[] =
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
{
- 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,
+ 0, 232, 232, 234, 236, 240, 246, 247, 248, 251,
+ 259, 263, 278, 279, 280, 281, 282, 285, 286, 289,
+ 290, 293, 294, 295, 296, 297, 298, 299, 300, 303,
+ 305, 308, 313, 318, 323, 328, 333, 338, 343, 348,
+ 353, 358, 363, 364, 365, 366, 373, 375, 377, 381,
+ 385, 389, 393, 396, 400, 402, 406, 412, 414, 418,
+ 421, 425, 431, 437, 440, 442, 445, 446, 447, 448,
+ 449, 452, 454, 458, 462, 466, 470, 472, 476, 478,
+ 482, 486, 487, 490, 492, 494, 496, 498, 502, 503,
+ 506, 507, 511, 512, 515, 517, 521, 525, 526, 529,
+ 532, 534, 538, 540, 542, 546, 548, 552, 556, 560,
+ 561, 562, 563, 566, 567, 570, 572, 574, 576, 578,
+ 580, 582, 584, 586, 588, 590, 594, 595, 598, 599,
+ 600, 601, 602, 612, 613, 616, 619, 623, 625, 627,
+ 629, 631, 633, 637, 639, 641, 643, 645, 647, 649,
+ 651, 655, 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
+ 710, 711, 731, 732, 735, 736, 739, 742, 745, 748,
+ 749, 752, 755, 756, 759
};
#endif
@@ -1217,7 +1211,7 @@ while (YYID (0))
#ifdef YYLEX_PARAM
# define YYLEX yylex (&yylval, YYLEX_PARAM)
#else
-# define YYLEX yylex (&yylval, scanner)
+# define YYLEX yylex (&yylval, param_scanner)
#endif
/* Enable debugging if requested. */
@@ -1970,75 +1964,76 @@ yyreduce:
case 2:
/* Line 1806 of yacc.c */
-#line 239 "parser.y"
+#line 233 "parser.y"
{ (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; }
break;
case 3:
/* Line 1806 of yacc.c */
-#line 241 "parser.y"
+#line 235 "parser.y"
{ (yyval.file) = param->rtrn = (yyvsp[(1) - (1)].file); param->more_maps = true; YYACCEPT; }
break;
case 4:
/* Line 1806 of yacc.c */
-#line 243 "parser.y"
+#line 237 "parser.y"
{ (yyval.file) = param->rtrn = NULL; param->more_maps = false; }
break;
case 5:
/* Line 1806 of yacc.c */
-#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)); }
+#line 243 "parser.y"
+ { (yyval.file) = XkbFileCreate((yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (ParseCommon *) (yyvsp[(5) - (7)].file), (yyvsp[(1) - (7)].mapFlags)); }
break;
case 6:
/* Line 1806 of yacc.c */
-#line 252 "parser.y"
+#line 246 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYMAP; }
break;
case 7:
/* Line 1806 of yacc.c */
-#line 253 "parser.y"
+#line 247 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYMAP; }
break;
case 8:
/* Line 1806 of yacc.c */
-#line 254 "parser.y"
+#line 248 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYMAP; }
break;
case 9:
/* Line 1806 of yacc.c */
-#line 258 "parser.y"
+#line 252 "parser.y"
{
if (!(yyvsp[(2) - (2)].file))
(yyval.file) = (yyvsp[(1) - (2)].file);
else
- (yyval.file) = (XkbFile *)AppendStmt(&(yyvsp[(1) - (2)].file)->common, &(yyvsp[(2) - (2)].file)->common);
+ (yyval.file) = (XkbFile *) AppendStmt((ParseCommon *) (yyvsp[(1) - (2)].file),
+ (ParseCommon *) (yyvsp[(2) - (2)].file));
}
break;
case 10:
/* Line 1806 of yacc.c */
-#line 265 "parser.y"
+#line 260 "parser.y"
{ (yyval.file) = (yyvsp[(1) - (1)].file); }
break;
case 11:
/* Line 1806 of yacc.c */
-#line 271 "parser.y"
+#line 266 "parser.y"
{
if ((yyvsp[(2) - (7)].file_type) == FILE_TYPE_GEOMETRY) {
free((yyvsp[(3) - (7)].str));
@@ -2046,7 +2041,7 @@ yyreduce:
(yyval.file) = NULL;
}
else {
- (yyval.file) = XkbFileCreate(param->ctx, (yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (yyvsp[(5) - (7)].any), (yyvsp[(1) - (7)].mapFlags));
+ (yyval.file) = XkbFileCreate((yyvsp[(2) - (7)].file_type), (yyvsp[(3) - (7)].str), (yyvsp[(5) - (7)].any), (yyvsp[(1) - (7)].mapFlags));
}
}
break;
@@ -2054,273 +2049,273 @@ yyreduce:
case 12:
/* Line 1806 of yacc.c */
-#line 283 "parser.y"
+#line 278 "parser.y"
{ (yyval.file_type) = FILE_TYPE_KEYCODES; }
break;
case 13:
/* Line 1806 of yacc.c */
-#line 284 "parser.y"
+#line 279 "parser.y"
{ (yyval.file_type) = FILE_TYPE_TYPES; }
break;
case 14:
/* Line 1806 of yacc.c */
-#line 285 "parser.y"
+#line 280 "parser.y"
{ (yyval.file_type) = FILE_TYPE_COMPAT; }
break;
case 15:
/* Line 1806 of yacc.c */
-#line 286 "parser.y"
+#line 281 "parser.y"
{ (yyval.file_type) = FILE_TYPE_SYMBOLS; }
break;
case 16:
/* Line 1806 of yacc.c */
-#line 287 "parser.y"
+#line 282 "parser.y"
{ (yyval.file_type) = FILE_TYPE_GEOMETRY; }
break;
case 17:
/* Line 1806 of yacc.c */
-#line 290 "parser.y"
+#line 285 "parser.y"
{ (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); }
break;
case 18:
/* Line 1806 of yacc.c */
-#line 291 "parser.y"
+#line 286 "parser.y"
{ (yyval.mapFlags) = 0; }
break;
case 19:
/* Line 1806 of yacc.c */
-#line 294 "parser.y"
+#line 289 "parser.y"
{ (yyval.mapFlags) = ((yyvsp[(1) - (2)].mapFlags) | (yyvsp[(2) - (2)].mapFlags)); }
break;
case 20:
/* Line 1806 of yacc.c */
-#line 295 "parser.y"
+#line 290 "parser.y"
{ (yyval.mapFlags) = (yyvsp[(1) - (1)].mapFlags); }
break;
case 21:
/* Line 1806 of yacc.c */
-#line 298 "parser.y"
+#line 293 "parser.y"
{ (yyval.mapFlags) = MAP_IS_PARTIAL; }
break;
case 22:
/* Line 1806 of yacc.c */
-#line 299 "parser.y"
+#line 294 "parser.y"
{ (yyval.mapFlags) = MAP_IS_DEFAULT; }
break;
case 23:
/* Line 1806 of yacc.c */
-#line 300 "parser.y"
+#line 295 "parser.y"
{ (yyval.mapFlags) = MAP_IS_HIDDEN; }
break;
case 24:
/* Line 1806 of yacc.c */
-#line 301 "parser.y"
+#line 296 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_ALPHANUMERIC; }
break;
case 25:
/* Line 1806 of yacc.c */
-#line 302 "parser.y"
+#line 297 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_MODIFIER; }
break;
case 26:
/* Line 1806 of yacc.c */
-#line 303 "parser.y"
+#line 298 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_KEYPAD; }
break;
case 27:
/* Line 1806 of yacc.c */
-#line 304 "parser.y"
+#line 299 "parser.y"
{ (yyval.mapFlags) = MAP_HAS_FN; }
break;
case 28:
/* Line 1806 of yacc.c */
-#line 305 "parser.y"
+#line 300 "parser.y"
{ (yyval.mapFlags) = MAP_IS_ALTGR; }
break;
case 29:
/* Line 1806 of yacc.c */
-#line 309 "parser.y"
+#line 304 "parser.y"
{ (yyval.any) = AppendStmt((yyvsp[(1) - (2)].any), (yyvsp[(2) - (2)].any)); }
break;
case 30:
/* Line 1806 of yacc.c */
-#line 310 "parser.y"
+#line 305 "parser.y"
{ (yyval.any) = NULL; }
break;
case 31:
/* Line 1806 of yacc.c */
-#line 314 "parser.y"
+#line 309 "parser.y"
{
(yyvsp[(2) - (2)].var)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].var)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].var);
}
break;
case 32:
/* Line 1806 of yacc.c */
-#line 319 "parser.y"
+#line 314 "parser.y"
{
(yyvsp[(2) - (2)].vmod)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].vmod)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].vmod);
}
break;
case 33:
/* Line 1806 of yacc.c */
-#line 324 "parser.y"
+#line 319 "parser.y"
{
(yyvsp[(2) - (2)].interp)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].interp)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].interp);
}
break;
case 34:
/* Line 1806 of yacc.c */
-#line 329 "parser.y"
+#line 324 "parser.y"
{
(yyvsp[(2) - (2)].keyCode)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].keyCode)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyCode);
}
break;
case 35:
/* Line 1806 of yacc.c */
-#line 334 "parser.y"
+#line 329 "parser.y"
{
(yyvsp[(2) - (2)].keyAlias)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].keyAlias)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyAlias);
}
break;
case 36:
/* Line 1806 of yacc.c */
-#line 339 "parser.y"
+#line 334 "parser.y"
{
(yyvsp[(2) - (2)].keyType)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].keyType)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].keyType);
}
break;
case 37:
/* Line 1806 of yacc.c */
-#line 344 "parser.y"
+#line 339 "parser.y"
{
(yyvsp[(2) - (2)].syms)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].syms)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].syms);
}
break;
case 38:
/* Line 1806 of yacc.c */
-#line 349 "parser.y"
+#line 344 "parser.y"
{
(yyvsp[(2) - (2)].modMask)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].modMask)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].modMask);
}
break;
case 39:
/* Line 1806 of yacc.c */
-#line 354 "parser.y"
+#line 349 "parser.y"
{
(yyvsp[(2) - (2)].groupCompat)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].groupCompat)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].groupCompat);
}
break;
case 40:
/* Line 1806 of yacc.c */
-#line 359 "parser.y"
+#line 354 "parser.y"
{
(yyvsp[(2) - (2)].ledMap)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].ledMap)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].ledMap);
}
break;
case 41:
/* Line 1806 of yacc.c */
-#line 364 "parser.y"
+#line 359 "parser.y"
{
(yyvsp[(2) - (2)].ledName)->merge = (yyvsp[(1) - (2)].merge);
- (yyval.any) = &(yyvsp[(2) - (2)].ledName)->common;
+ (yyval.any) = (ParseCommon *) (yyvsp[(2) - (2)].ledName);
}
break;
case 42:
/* Line 1806 of yacc.c */
-#line 368 "parser.y"
+#line 363 "parser.y"
{ (yyval.any) = NULL; }
break;
case 43:
/* Line 1806 of yacc.c */
-#line 369 "parser.y"
+#line 364 "parser.y"
{ (yyval.any) = NULL; }
break;
case 44:
/* Line 1806 of yacc.c */
-#line 370 "parser.y"
+#line 365 "parser.y"
{ (yyval.any) = NULL; }
break;
case 45:
/* Line 1806 of yacc.c */
-#line 372 "parser.y"
+#line 367 "parser.y"
{
- (yyval.any) = &IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge))->common;
+ (yyval.any) = (ParseCommon *) IncludeCreate(param->ctx, (yyvsp[(2) - (2)].str), (yyvsp[(1) - (2)].merge));
free((yyvsp[(2) - (2)].str));
}
break;
@@ -2328,609 +2323,612 @@ yyreduce:
case 46:
/* Line 1806 of yacc.c */
-#line 379 "parser.y"
+#line 374 "parser.y"
{ (yyval.var) = VarCreate((yyvsp[(1) - (4)].expr), (yyvsp[(3) - (4)].expr)); }
break;
case 47:
/* Line 1806 of yacc.c */
-#line 381 "parser.y"
+#line 376 "parser.y"
{ (yyval.var) = BoolVarCreate((yyvsp[(1) - (2)].sval), true); }
break;
case 48:
/* Line 1806 of yacc.c */
-#line 383 "parser.y"
+#line 378 "parser.y"
{ (yyval.var) = BoolVarCreate((yyvsp[(2) - (3)].sval), false); }
break;
case 49:
/* Line 1806 of yacc.c */
-#line 387 "parser.y"
+#line 382 "parser.y"
{ (yyval.keyCode) = KeycodeCreate((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].num)); }
break;
case 50:
/* Line 1806 of yacc.c */
-#line 391 "parser.y"
+#line 386 "parser.y"
{ (yyval.keyAlias) = KeyAliasCreate((yyvsp[(2) - (5)].sval), (yyvsp[(4) - (5)].sval)); }
break;
case 51:
/* Line 1806 of yacc.c */
-#line 395 "parser.y"
+#line 390 "parser.y"
{ (yyval.vmod) = (yyvsp[(2) - (3)].vmod); }
break;
case 52:
/* Line 1806 of yacc.c */
-#line 399 "parser.y"
- { (yyval.vmod) = (VModDef *)AppendStmt(&(yyvsp[(1) - (3)].vmod)->common, &(yyvsp[(3) - (3)].vmod)->common); }
+#line 394 "parser.y"
+ { (yyval.vmod) = (VModDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].vmod),
+ (ParseCommon *) (yyvsp[(3) - (3)].vmod)); }
break;
case 53:
/* Line 1806 of yacc.c */
-#line 401 "parser.y"
+#line 397 "parser.y"
{ (yyval.vmod) = (yyvsp[(1) - (1)].vmod); }
break;
case 54:
/* Line 1806 of yacc.c */
-#line 405 "parser.y"
+#line 401 "parser.y"
{ (yyval.vmod) = VModCreate((yyvsp[(1) - (1)].sval), NULL); }
break;
case 55:
/* Line 1806 of yacc.c */
-#line 407 "parser.y"
+#line 403 "parser.y"
{ (yyval.vmod) = VModCreate((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].expr)); }
break;
case 56:
/* Line 1806 of yacc.c */
-#line 413 "parser.y"
+#line 409 "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 417 "parser.y"
+#line 413 "parser.y"
{ (yyval.interp) = InterpCreate((yyvsp[(1) - (3)].keysym), (yyvsp[(3) - (3)].expr)); }
break;
case 58:
/* Line 1806 of yacc.c */
-#line 419 "parser.y"
+#line 415 "parser.y"
{ (yyval.interp) = InterpCreate((yyvsp[(1) - (1)].keysym), NULL); }
break;
case 59:
/* Line 1806 of yacc.c */
-#line 423 "parser.y"
- { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (2)].var)->common, &(yyvsp[(2) - (2)].var)->common); }
+#line 419 "parser.y"
+ { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (2)].var),
+ (ParseCommon *) (yyvsp[(2) - (2)].var)); }
break;
case 60:
/* Line 1806 of yacc.c */
-#line 425 "parser.y"
+#line 422 "parser.y"
{ (yyval.var) = (yyvsp[(1) - (1)].var); }
break;
case 61:
/* Line 1806 of yacc.c */
-#line 431 "parser.y"
+#line 428 "parser.y"
{ (yyval.keyType) = KeyTypeCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
break;
case 62:
/* Line 1806 of yacc.c */
-#line 437 "parser.y"
+#line 434 "parser.y"
{ (yyval.syms) = SymbolsCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
break;
case 63:
/* Line 1806 of yacc.c */
-#line 441 "parser.y"
- { (yyval.var) = (VarDef *)AppendStmt(&(yyvsp[(1) - (3)].var)->common, &(yyvsp[(3) - (3)].var)->common); }
+#line 438 "parser.y"
+ { (yyval.var) = (VarDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].var),
+ (ParseCommon *) (yyvsp[(3) - (3)].var)); }
break;
case 64:
/* Line 1806 of yacc.c */
-#line 443 "parser.y"
+#line 441 "parser.y"
{ (yyval.var) = (yyvsp[(1) - (1)].var); }
break;
case 65:
/* Line 1806 of yacc.c */
-#line 444 "parser.y"
+#line 442 "parser.y"
{ (yyval.var) = NULL; }
break;
case 66:
/* Line 1806 of yacc.c */
-#line 447 "parser.y"
+#line 445 "parser.y"
{ (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 67:
/* Line 1806 of yacc.c */
-#line 448 "parser.y"
+#line 446 "parser.y"
{ (yyval.var) = VarCreate((yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 68:
/* Line 1806 of yacc.c */
-#line 449 "parser.y"
+#line 447 "parser.y"
{ (yyval.var) = BoolVarCreate((yyvsp[(1) - (1)].sval), true); }
break;
case 69:
/* Line 1806 of yacc.c */
-#line 450 "parser.y"
+#line 448 "parser.y"
{ (yyval.var) = BoolVarCreate((yyvsp[(2) - (2)].sval), false); }
break;
case 70:
/* Line 1806 of yacc.c */
-#line 451 "parser.y"
+#line 449 "parser.y"
{ (yyval.var) = VarCreate(NULL, (yyvsp[(1) - (1)].expr)); }
break;
case 71:
/* Line 1806 of yacc.c */
-#line 455 "parser.y"
+#line 453 "parser.y"
{ (yyval.expr) = (yyvsp[(2) - (3)].expr); }
break;
case 72:
/* Line 1806 of yacc.c */
-#line 457 "parser.y"
+#line 455 "parser.y"
{ (yyval.expr) = ExprCreateUnary(EXPR_ACTION_LIST, EXPR_TYPE_ACTION, (yyvsp[(2) - (3)].expr)); }
break;
case 73:
/* Line 1806 of yacc.c */
-#line 461 "parser.y"
+#line 459 "parser.y"
{ (yyval.groupCompat) = GroupCompatCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr)); }
break;
case 74:
/* Line 1806 of yacc.c */
-#line 465 "parser.y"
+#line 463 "parser.y"
{ (yyval.modMask) = ModMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].expr)); }
break;
case 75:
/* Line 1806 of yacc.c */
-#line 469 "parser.y"
+#line 467 "parser.y"
{ (yyval.ledMap) = LedMapCreate((yyvsp[(2) - (6)].sval), (yyvsp[(4) - (6)].var)); }
break;
case 76:
/* Line 1806 of yacc.c */
-#line 473 "parser.y"
+#line 471 "parser.y"
{ (yyval.ledName) = LedNameCreate((yyvsp[(2) - (5)].ival), (yyvsp[(4) - (5)].expr), false); }
break;
case 77:
/* Line 1806 of yacc.c */
-#line 475 "parser.y"
+#line 473 "parser.y"
{ (yyval.ledName) = LedNameCreate((yyvsp[(3) - (6)].ival), (yyvsp[(5) - (6)].expr), true); }
break;
case 78:
/* Line 1806 of yacc.c */
-#line 479 "parser.y"
+#line 477 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 79:
/* Line 1806 of yacc.c */
-#line 481 "parser.y"
+#line 479 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 80:
/* Line 1806 of yacc.c */
-#line 485 "parser.y"
+#line 483 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 81:
/* Line 1806 of yacc.c */
-#line 488 "parser.y"
+#line 486 "parser.y"
{ (yyval.geom) = NULL;}
break;
case 82:
/* Line 1806 of yacc.c */
-#line 489 "parser.y"
+#line 487 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 83:
/* Line 1806 of yacc.c */
-#line 493 "parser.y"
+#line 491 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 84:
/* Line 1806 of yacc.c */
-#line 495 "parser.y"
- { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; }
+#line 493 "parser.y"
+ { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].var)); (yyval.geom) = NULL; }
break;
case 85:
/* Line 1806 of yacc.c */
-#line 497 "parser.y"
+#line 495 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 86:
/* Line 1806 of yacc.c */
-#line 499 "parser.y"
- { FreeStmt(&(yyvsp[(1) - (1)].ledMap)->common); (yyval.geom) = NULL; }
+#line 497 "parser.y"
+ { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].ledMap)); (yyval.geom) = NULL; }
break;
case 87:
/* Line 1806 of yacc.c */
-#line 501 "parser.y"
+#line 499 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 88:
/* Line 1806 of yacc.c */
-#line 504 "parser.y"
+#line 502 "parser.y"
{ (yyval.geom) = NULL;}
break;
case 89:
/* Line 1806 of yacc.c */
-#line 505 "parser.y"
+#line 503 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 90:
/* Line 1806 of yacc.c */
-#line 508 "parser.y"
+#line 506 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 91:
/* Line 1806 of yacc.c */
-#line 510 "parser.y"
- { FreeStmt(&(yyvsp[(1) - (1)].var)->common); (yyval.geom) = NULL; }
+#line 508 "parser.y"
+ { FreeStmt((ParseCommon *) (yyvsp[(1) - (1)].var)); (yyval.geom) = NULL; }
break;
case 92:
/* Line 1806 of yacc.c */
-#line 513 "parser.y"
+#line 511 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 93:
/* Line 1806 of yacc.c */
-#line 514 "parser.y"
+#line 512 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 94:
/* Line 1806 of yacc.c */
-#line 518 "parser.y"
+#line 516 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 95:
/* Line 1806 of yacc.c */
-#line 520 "parser.y"
- { FreeStmt(&(yyvsp[(2) - (3)].expr)->common); (yyval.geom) = NULL; }
+#line 518 "parser.y"
+ { FreeStmt((ParseCommon *) (yyvsp[(2) - (3)].expr)); (yyval.geom) = NULL; }
break;
case 96:
/* Line 1806 of yacc.c */
-#line 524 "parser.y"
+#line 522 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 97:
/* Line 1806 of yacc.c */
-#line 527 "parser.y"
+#line 525 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 98:
/* Line 1806 of yacc.c */
-#line 528 "parser.y"
+#line 526 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 99:
/* Line 1806 of yacc.c */
-#line 531 "parser.y"
+#line 529 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 100:
/* Line 1806 of yacc.c */
-#line 535 "parser.y"
+#line 533 "parser.y"
{ (yyval.geom) = NULL;}
break;
case 101:
/* Line 1806 of yacc.c */
-#line 537 "parser.y"
+#line 535 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 102:
/* Line 1806 of yacc.c */
-#line 541 "parser.y"
+#line 539 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 103:
/* Line 1806 of yacc.c */
-#line 543 "parser.y"
+#line 541 "parser.y"
{ (yyval.geom) = NULL; }
break;
case 104:
/* Line 1806 of yacc.c */
-#line 545 "parser.y"
- { FreeStmt(&(yyvsp[(3) - (3)].expr)->common); (yyval.geom) = NULL; }
+#line 543 "parser.y"
+ { FreeStmt((ParseCommon *) (yyvsp[(3) - (3)].expr)); (yyval.geom) = NULL; }
break;
case 105:
/* Line 1806 of yacc.c */
-#line 549 "parser.y"
+#line 547 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 106:
/* Line 1806 of yacc.c */
-#line 551 "parser.y"
+#line 549 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 107:
/* Line 1806 of yacc.c */
-#line 555 "parser.y"
+#line 553 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 108:
/* Line 1806 of yacc.c */
-#line 559 "parser.y"
- { FreeStmt(&(yyvsp[(4) - (6)].var)->common); (yyval.geom) = NULL; }
+#line 557 "parser.y"
+ { FreeStmt((ParseCommon *) (yyvsp[(4) - (6)].var)); (yyval.geom) = NULL; }
break;
case 109:
/* Line 1806 of yacc.c */
-#line 562 "parser.y"
+#line 560 "parser.y"
{ (yyval.ival) = 0; }
break;
case 110:
/* Line 1806 of yacc.c */
-#line 563 "parser.y"
+#line 561 "parser.y"
{ (yyval.ival) = 0; }
break;
case 111:
/* Line 1806 of yacc.c */
-#line 564 "parser.y"
+#line 562 "parser.y"
{ (yyval.ival) = 0; }
break;
case 112:
/* Line 1806 of yacc.c */
-#line 565 "parser.y"
+#line 563 "parser.y"
{ (yyval.ival) = 0; }
break;
case 113:
/* Line 1806 of yacc.c */
-#line 568 "parser.y"
+#line 566 "parser.y"
{ (yyval.sval) = (yyvsp[(1) - (1)].sval); }
break;
case 114:
/* Line 1806 of yacc.c */
-#line 569 "parser.y"
+#line 567 "parser.y"
{ (yyval.sval) = (yyvsp[(1) - (1)].sval); }
break;
case 115:
/* Line 1806 of yacc.c */
-#line 573 "parser.y"
+#line 571 "parser.y"
{ (yyval.sval) = xkb_atom_intern_literal(param->ctx, "action"); }
break;
case 116:
/* Line 1806 of yacc.c */
-#line 575 "parser.y"
+#line 573 "parser.y"
{ (yyval.sval) = xkb_atom_intern_literal(param->ctx, "interpret"); }
break;
case 117:
/* Line 1806 of yacc.c */
-#line 577 "parser.y"
+#line 575 "parser.y"
{ (yyval.sval) = xkb_atom_intern_literal(param->ctx, "type"); }
break;
case 118:
/* Line 1806 of yacc.c */
-#line 579 "parser.y"
+#line 577 "parser.y"
{ (yyval.sval) = xkb_atom_intern_literal(param->ctx, "key"); }
break;
case 119:
/* Line 1806 of yacc.c */
-#line 581 "parser.y"
+#line 579 "parser.y"
{ (yyval.sval) = xkb_atom_intern_literal(param->ctx, "group"); }
break;
case 120:
/* Line 1806 of yacc.c */
-#line 583 "parser.y"
+#line 581 "parser.y"
{(yyval.sval) = xkb_atom_intern_literal(param->ctx, "modifier_map");}
break;
case 121:
/* Line 1806 of yacc.c */
-#line 585 "parser.y"
+#line 583 "parser.y"
{ (yyval.sval) = xkb_atom_intern_literal(param->ctx, "indicator"); }
break;
case 122:
/* Line 1806 of yacc.c */
-#line 587 "parser.y"
+#line 585 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 123:
/* Line 1806 of yacc.c */
-#line 589 "parser.y"
+#line 587 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 124:
/* Line 1806 of yacc.c */
-#line 591 "parser.y"
+#line 589 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 125:
/* Line 1806 of yacc.c */
-#line 593 "parser.y"
+#line 591 "parser.y"
{ (yyval.sval) = XKB_ATOM_NONE; }
break;
case 126:
/* Line 1806 of yacc.c */
-#line 596 "parser.y"
+#line 594 "parser.y"
{ (yyval.merge) = (yyvsp[(1) - (1)].merge); }
break;
case 127:
/* Line 1806 of yacc.c */
-#line 597 "parser.y"
+#line 595 "parser.y"
{ (yyval.merge) = MERGE_DEFAULT; }
break;
case 128:
/* Line 1806 of yacc.c */
-#line 600 "parser.y"
+#line 598 "parser.y"
{ (yyval.merge) = MERGE_DEFAULT; }
break;
case 129:
/* Line 1806 of yacc.c */
-#line 601 "parser.y"
+#line 599 "parser.y"
{ (yyval.merge) = MERGE_AUGMENT; }
break;
case 130:
/* Line 1806 of yacc.c */
-#line 602 "parser.y"
+#line 600 "parser.y"
{ (yyval.merge) = MERGE_OVERRIDE; }
break;
case 131:
/* Line 1806 of yacc.c */
-#line 603 "parser.y"
+#line 601 "parser.y"
{ (yyval.merge) = MERGE_REPLACE; }
break;
case 132:
/* Line 1806 of yacc.c */
-#line 605 "parser.y"
+#line 603 "parser.y"
{
/*
* This used to be MERGE_ALT_FORM. This functionality was
@@ -2943,134 +2941,136 @@ yyreduce:
case 133:
/* Line 1806 of yacc.c */
-#line 614 "parser.y"
+#line 612 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 134:
/* Line 1806 of yacc.c */
-#line 615 "parser.y"
+#line 613 "parser.y"
{ (yyval.expr) = NULL; }
break;
case 135:
/* Line 1806 of yacc.c */
-#line 619 "parser.y"
- { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); }
+#line 617 "parser.y"
+ { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].expr),
+ (ParseCommon *) (yyvsp[(3) - (3)].expr)); }
break;
case 136:
/* Line 1806 of yacc.c */
-#line 621 "parser.y"
+#line 620 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 137:
/* Line 1806 of yacc.c */
-#line 625 "parser.y"
+#line 624 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_DIVIDE, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 138:
/* Line 1806 of yacc.c */
-#line 627 "parser.y"
+#line 626 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_ADD, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 139:
/* Line 1806 of yacc.c */
-#line 629 "parser.y"
+#line 628 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_SUBTRACT, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 140:
/* Line 1806 of yacc.c */
-#line 631 "parser.y"
+#line 630 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_MULTIPLY, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 141:
/* Line 1806 of yacc.c */
-#line 633 "parser.y"
+#line 632 "parser.y"
{ (yyval.expr) = ExprCreateBinary(EXPR_ASSIGN, (yyvsp[(1) - (3)].expr), (yyvsp[(3) - (3)].expr)); }
break;
case 142:
/* Line 1806 of yacc.c */
-#line 635 "parser.y"
+#line 634 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 143:
/* Line 1806 of yacc.c */
-#line 639 "parser.y"
+#line 638 "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 641 "parser.y"
+#line 640 "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 643 "parser.y"
+#line 642 "parser.y"
{ (yyval.expr) = ExprCreateUnary(EXPR_NOT, EXPR_TYPE_BOOLEAN, (yyvsp[(2) - (2)].expr)); }
break;
case 146:
/* Line 1806 of yacc.c */
-#line 645 "parser.y"
+#line 644 "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 647 "parser.y"
+#line 646 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 148:
/* Line 1806 of yacc.c */
-#line 649 "parser.y"
+#line 648 "parser.y"
{ (yyval.expr) = ExprCreateAction((yyvsp[(1) - (4)].sval), (yyvsp[(3) - (4)].expr)); }
break;
case 149:
/* Line 1806 of yacc.c */
-#line 651 "parser.y"
+#line 650 "parser.y"
{ (yyval.expr) = (yyvsp[(1) - (1)].expr); }
break;
case 150:
/* Line 1806 of yacc.c */
-#line 653 "parser.y"
+#line 652 "parser.y"
{ (yyval.expr) = (yyvsp[(2) - (3)].expr); }
break;
case 151:
/* Line 1806 of yacc.c */
-#line 657 "parser.y"
- { (yyval.expr) = (ExprDef *)AppendStmt(&(yyvsp[(1) - (3)].expr)->common, &(yyvsp[(3) - (3)].expr)->common); }
+#line 656 "parser.y"
+ { (yyval.expr) = (ExprDef *) AppendStmt((ParseCommon *) (yyvsp[(1) - (3)].expr),
+ (ParseCommon *) (yyvsp[(3) - (3)].expr)); }
break;
case 152:
@@ -3215,14 +3215,20 @@ yyreduce:
/* Line 1806 of yacc.c */
#line 712 "parser.y"
{
- if ((yyvsp[(1) - (1)].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */
- (yyval.keysym) = XKB_KEY_0 + (yyvsp[(1) - (1)].ival);
+ if ((yyvsp[(1) - (1)].ival) < 0) {
+ parser_warn(param, "unrecognized keysym");
+ (yyval.keysym) = XKB_KEY_NoSymbol;
+ }
+ else if ((yyvsp[(1) - (1)].ival) < 10) { /* XKB_KEY_0 .. XKB_KEY_9 */
+ (yyval.keysym) = XKB_KEY_0 + (xkb_keysym_t) (yyvsp[(1) - (1)].ival);
}
else {
char buf[17];
snprintf(buf, sizeof(buf), "0x%x", (yyvsp[(1) - (1)].ival));
- if (!resolve_keysym(buf, &(yyval.keysym)))
+ if (!resolve_keysym(buf, &(yyval.keysym))) {
parser_warn(param, "unrecognized keysym");
+ (yyval.keysym) = XKB_KEY_NoSymbol;
+ }
}
}
break;
@@ -3230,98 +3236,98 @@ yyreduce:
case 172:
/* Line 1806 of yacc.c */
-#line 725 "parser.y"
+#line 731 "parser.y"
{ (yyval.ival) = -(yyvsp[(2) - (2)].ival); }
break;
case 173:
/* Line 1806 of yacc.c */
-#line 726 "parser.y"
+#line 732 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].ival); }
break;
case 174:
/* Line 1806 of yacc.c */
-#line 729 "parser.y"
+#line 735 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].num); }
break;
case 175:
/* Line 1806 of yacc.c */
-#line 730 "parser.y"
+#line 736 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].num); }
break;
case 176:
/* Line 1806 of yacc.c */
-#line 733 "parser.y"
+#line 739 "parser.y"
{ (yyval.ival) = 0; }
break;
case 177:
/* Line 1806 of yacc.c */
-#line 736 "parser.y"
+#line 742 "parser.y"
{ (yyval.ival) = (yyvsp[(1) - (1)].num); }
break;
case 178:
/* Line 1806 of yacc.c */
-#line 739 "parser.y"
+#line 745 "parser.y"
{ (yyval.num) = (yyvsp[(1) - (1)].num); }
break;
case 179:
/* Line 1806 of yacc.c */
-#line 742 "parser.y"
+#line 748 "parser.y"
{ (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); }
break;
case 180:
/* Line 1806 of yacc.c */
-#line 743 "parser.y"
+#line 749 "parser.y"
{ (yyval.sval) = xkb_atom_intern_literal(param->ctx, "default"); }
break;
case 181:
/* Line 1806 of yacc.c */
-#line 746 "parser.y"
+#line 752 "parser.y"
{ (yyval.sval) = xkb_atom_steal(param->ctx, (yyvsp[(1) - (1)].str)); }
break;
case 182:
/* Line 1806 of yacc.c */
-#line 749 "parser.y"
+#line 755 "parser.y"
{ (yyval.str) = (yyvsp[(1) - (1)].str); }
break;
case 183:
/* Line 1806 of yacc.c */
-#line 750 "parser.y"
+#line 756 "parser.y"
{ (yyval.str) = NULL; }
break;
case 184:
/* Line 1806 of yacc.c */
-#line 753 "parser.y"
+#line 759 "parser.y"
{ (yyval.str) = (yyvsp[(1) - (1)].str); }
break;
/* Line 1806 of yacc.c */
-#line 3325 "src/xkbcomp/parser.c"
+#line 3331 "src/xkbcomp/parser.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -3552,13 +3558,11 @@ yyreturn:
/* Line 2067 of yacc.c */
-#line 756 "parser.y"
+#line 762 "parser.y"
-#undef scanner
-
XkbFile *
-parse(struct xkb_context *ctx, void *scanner, const char *map)
+parse(struct xkb_context *ctx, struct scanner *scanner, const char *map)
{
int ret;
XkbFile *first = NULL;
@@ -3604,5 +3608,3 @@ 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 f85a2bad85..ee9b4468b5 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/parser.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/parser.h
@@ -175,7 +175,7 @@ typedef union YYSTYPE
{
/* Line 2068 of yacc.c */
-#line 167 "parser.y"
+#line 161 "parser.y"
int ival;
int64_t num;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
index de82d96119..61799e7059 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/rules.c
@@ -52,84 +52,6 @@
#include "include.h"
#include "scanner-utils.h"
-/*
- * The rules file
- * ==============
- * The purpose of this file is to map between configuration values that
- * are easy for a user to specify and understand, and the configuration
- * values xkbcomp uses and understands.
- * xkbcomp uses the xkb_component_names struct, which maps directly to
- * include statements of the appropriate sections, called for short
- * KcCGST (see keycodes.c, types.c, compat.c, symbols.c; geometry.c was
- * removed). These are not really intuitive or straight-forward for
- * the uninitiated.
- * Instead, the user passes in a xkb_rule_names struct, which consists
- * of the name of a rules file (in Linux this is usually "evdev"), a
- * keyboard model (e.g. "pc105"), a set of layouts (which will end up
- * in different groups, e.g. "us,fr"), variants (used to alter/augment
- * the respective layout, e.g. "intl,dvorak"), and a set of options
- * (used to tweak some general behavior of the keyboard, e.g.
- * "ctrl:nocaps,compose:menu" to make the Caps Lock key act like Ctrl
- * and the Menu key like Compose). We call these RMLVO.
- *
- * Format of the file
- * ------------------
- * The file consists of rule sets, each consisting of rules (one per
- * line), which match the MLVO values on the left hand side, and, if
- * the values match to the values the user passed in, results in the
- * values on the right hand side being added to the resulting KcCGST.
- * Since some values are related and repeated often, it is possible
- * to group them together and refer to them by a group name in the
- * rules.
- * Along with matching values by simple string equality, and for
- * membership in a group defined previously, rules may also contain
- * "wildcard" values - "*" - which always match. These usually appear
- * near the end.
- *
- * Grammer
- * -------
- * (It might be helpful to look at a file like rules/evdev along with
- * this grammer. Comments, whitespace, etc. are not shown.)
- *
- * File ::= { "!" (Group | RuleSet) }
- *
- * Group ::= GroupName "=" { GroupElement } "\n"
- * GroupName ::= "$"<ident>
- * GroupElement ::= <ident>
- *
- * RuleSet ::= Mapping { Rule }
- *
- * Mapping ::= { Mlvo } "=" { Kccgst } "\n"
- * Mlvo ::= "model" | "option" | ("layout" | "variant") [ Index ]
- * Index ::= "[" 1..XKB_NUM_GROUPS "]"
- * Kccgst ::= "keycodes" | "symbols" | "types" | "compat" | "geometry"
- *
- * Rule ::= { MlvoValue } "=" { KccgstValue } "\n"
- * MlvoValue ::= "*" | GroupName | <ident>
- * KccgstValue ::= <ident>
- *
- * Notes:
- * - The order of values in a Rule must be the same as the Mapping it
- * follows. The mapping line determines the meaning of the values in
- * the rules which follow in the RuleSet.
- * - If a Rule is matched, %-expansion is performed on the KccgstValue,
- * as follows:
- * %m, %l, %v:
- * The model, layout or variant, if only one was given (e.g.
- * %l for "us,il" is invalid).
- * %l[1], %v[1]:
- * Layout or variant for the specified group Index, if more than
- * one was given (e.g. %l[1] for "us" is invalid).
- * %+m, %+l, %+v, %+l[1], %+v[1]
- * As above, but prefixed with '+'. Similarly, '|', '-', '_' may be
- * used instead of '+'.
- * %(m), %(l), %(l[1]), %(v), %(v[1]):
- * As above, but prefixed by '(' and suffixed by ')'.
- * In case the expansion is invalid, as described above, it is
- * skipped (the rest of the string is still processed); this includes
- * the prefix and suffix (that's why you shouldn't use e.g. "(%v[1])").
- */
-
/* Scanner / Lexer */
/* Values returned with some tokens, like yylval. */
@@ -137,14 +59,6 @@ union lvalue {
struct sval string;
};
-/*
- * Holds the location in the file of the last processed token,
- * like yylloc.
- */
-struct location {
- int line, column;
-};
-
enum rules_token {
TOK_END_OF_FILE = 0,
TOK_END_OF_LINE,
@@ -156,14 +70,6 @@ enum rules_token {
TOK_ERROR
};
-/* 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: %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 inline bool
is_ident(char ch)
{
@@ -171,7 +77,7 @@ is_ident(char ch)
}
static enum rules_token
-lex(struct scanner *s, union lvalue *val, struct location *loc)
+lex(struct scanner *s, union lvalue *val)
{
skip_more_whitespace_and_comments:
/* Skip spaces. */
@@ -191,8 +97,7 @@ skip_more_whitespace_and_comments:
/* Escaped line continuation. */
if (chr(s, '\\')) {
if (!eol(s)) {
- scanner_error1(s, loc,
- "illegal new line escape; must appear at end of line");
+ scanner_err(s, "illegal new line escape; must appear at end of line");
return TOK_ERROR;
}
next(s);
@@ -203,8 +108,8 @@ skip_more_whitespace_and_comments:
if (eof(s)) return TOK_END_OF_FILE;
/* New token. */
- loc->line = s->line;
- loc->column = s->column;
+ s->token_line = s->line;
+ s->token_column = s->column;
/* Operators and punctuation. */
if (chr(s, '!')) return TOK_BANG;
@@ -220,8 +125,7 @@ skip_more_whitespace_and_comments:
val->string.len++;
}
if (val->string.len == 0) {
- scanner_error1(s, loc,
- "unexpected character after \'$\'; expected name");
+ scanner_err(s, "unexpected character after \'$\'; expected name");
return TOK_ERROR;
}
return TOK_GROUP_NAME;
@@ -238,7 +142,7 @@ skip_more_whitespace_and_comments:
return TOK_IDENTIFIER;
}
- scanner_error1(s, loc, "unrecognized token");
+ scanner_err(s, "unrecognized token");
return TOK_ERROR;
}
@@ -330,7 +234,6 @@ struct matcher {
struct xkb_context *ctx;
/* Input.*/
struct rule_names rmlvo;
- struct location loc;
union lvalue val;
struct scanner scanner;
darray(struct group) groups;
@@ -410,10 +313,8 @@ matcher_free(struct matcher *m)
free(m);
}
-#define matcher_error1(matcher, msg) \
- scanner_error1(&(matcher)->scanner, &(matcher)->loc, msg)
-#define matcher_error(matcher, fmt, ...) \
- scanner_error(&(matcher)->scanner, &(matcher)->loc, fmt, __VA_ARGS__)
+#define matcher_err(matcher, fmt, ...) \
+ scanner_err(&(matcher)->scanner, fmt, ## __VA_ARGS__)
static void
matcher_group_start_new(struct matcher *m, struct sval name)
@@ -474,19 +375,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
/* Not found. */
if (mlvo >= _MLVO_NUM_ENTRIES) {
- matcher_error(m,
- "invalid mapping: %.*s is not a valid value here; "
- "ignoring rule set",
- ident.len, ident.start);
+ matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set",
+ ident.len, ident.start);
m->mapping.skip = true;
return;
}
- if (m->mapping.defined_mlvo_mask & (1 << mlvo)) {
- matcher_error(m,
- "invalid mapping: %.*s appears twice on the same line; "
- "ignoring rule set",
- mlvo_sval.len, mlvo_sval.start);
+ if (m->mapping.defined_mlvo_mask & (1u << mlvo)) {
+ matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set",
+ mlvo_sval.len, mlvo_sval.start);
m->mapping.skip = true;
return;
}
@@ -497,10 +394,8 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
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; "
- "ignoring rule set",
- mlvo_sval.len, mlvo_sval.start);
+ matcher_err(m, "invalid mapping: \"%.*s\" may only be followed by a valid group index; ignoring rule set",
+ mlvo_sval.len, mlvo_sval.start);
m->mapping.skip = true;
return;
}
@@ -512,17 +407,15 @@ matcher_mapping_set_mlvo(struct matcher *m, struct sval ident)
m->mapping.variant_idx = idx;
}
else {
- matcher_error(m,
- "invalid mapping: \"%.*s\" cannot be followed by a group index; "
- "ignoring rule set",
- mlvo_sval.len, mlvo_sval.start);
+ matcher_err(m, "invalid mapping: \"%.*s\" cannot be followed by a group index; ignoring rule set",
+ mlvo_sval.len, mlvo_sval.start);
m->mapping.skip = true;
return;
}
}
m->mapping.mlvo_at_pos[m->mapping.num_mlvo] = mlvo;
- m->mapping.defined_mlvo_mask |= 1 << mlvo;
+ m->mapping.defined_mlvo_mask |= 1u << mlvo;
m->mapping.num_mlvo++;
}
@@ -541,25 +434,21 @@ matcher_mapping_set_kccgst(struct matcher *m, struct sval ident)
/* Not found. */
if (kccgst >= _KCCGST_NUM_ENTRIES) {
- matcher_error(m,
- "invalid mapping: %.*s is not a valid value here; "
- "ignoring rule set",
- ident.len, ident.start);
+ matcher_err(m, "invalid mapping: %.*s is not a valid value here; ignoring rule set",
+ ident.len, ident.start);
m->mapping.skip = true;
return;
}
- if (m->mapping.defined_kccgst_mask & (1 << kccgst)) {
- matcher_error(m,
- "invalid mapping: %.*s appears twice on the same line; "
- "ignoring rule set",
- kccgst_sval.len, kccgst_sval.start);
+ if (m->mapping.defined_kccgst_mask & (1u << kccgst)) {
+ matcher_err(m, "invalid mapping: %.*s appears twice on the same line; ignoring rule set",
+ kccgst_sval.len, kccgst_sval.start);
m->mapping.skip = true;
return;
}
m->mapping.kccgst_at_pos[m->mapping.num_kccgst] = kccgst;
- m->mapping.defined_kccgst_mask |= 1 << kccgst;
+ m->mapping.defined_kccgst_mask |= 1u << kccgst;
m->mapping.num_kccgst++;
}
@@ -567,16 +456,12 @@ static void
matcher_mapping_verify(struct matcher *m)
{
if (m->mapping.num_mlvo == 0) {
- matcher_error1(m,
- "invalid mapping: must have at least one value on the left hand side; "
- "ignoring rule set");
+ matcher_err(m, "invalid mapping: must have at least one value on the left hand side; ignoring rule set");
goto skip;
}
if (m->mapping.num_kccgst == 0) {
- matcher_error1(m,
- "invalid mapping: must have at least one value on the right hand side; "
- "ignoring rule set");
+ matcher_err(m, "invalid mapping: must have at least one value on the right hand side; ignoring rule set");
goto skip;
}
@@ -585,7 +470,7 @@ matcher_mapping_verify(struct matcher *m)
* See the "Notes" section in the overview above.
*/
- if (m->mapping.defined_mlvo_mask & (1 << MLVO_LAYOUT)) {
+ if (m->mapping.defined_mlvo_mask & (1u << MLVO_LAYOUT)) {
if (m->mapping.layout_idx == XKB_LAYOUT_INVALID) {
if (darray_size(m->rmlvo.layouts) > 1)
goto skip;
@@ -597,7 +482,7 @@ matcher_mapping_verify(struct matcher *m)
}
}
- if (m->mapping.defined_mlvo_mask & (1 << MLVO_VARIANT)) {
+ if (m->mapping.defined_mlvo_mask & (1u << MLVO_VARIANT)) {
if (m->mapping.variant_idx == XKB_LAYOUT_INVALID) {
if (darray_size(m->rmlvo.variants) > 1)
goto skip;
@@ -627,9 +512,7 @@ matcher_rule_set_mlvo_common(struct matcher *m, struct sval ident,
enum mlvo_match_type match_type)
{
if (m->rule.num_mlvo_values + 1 > m->mapping.num_mlvo) {
- matcher_error1(m,
- "invalid rule: has more values than the mapping line; "
- "ignoring rule");
+ matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule");
m->rule.skip = true;
return;
}
@@ -661,9 +544,7 @@ static void
matcher_rule_set_kccgst(struct matcher *m, struct sval ident)
{
if (m->rule.num_kccgst_values + 1 > m->mapping.num_kccgst) {
- matcher_error1(m,
- "invalid rule: has more values than the mapping line; "
- "ignoring rule");
+ matcher_err(m, "invalid rule: has more values than the mapping line; ignoring rule");
m->rule.skip = true;
return;
}
@@ -720,20 +601,10 @@ static bool
append_expanded_kccgst_value(struct matcher *m, darray_char *to,
struct sval value)
{
- const size_t original_size = darray_size(*to);
const char *s = value.start;
-
- /*
- * Appending bar to foo -> foo (not an error if this happens)
- * Appending +bar to foo -> foo+bar
- * Appending bar to +foo -> bar+foo
- * Appending +bar to +foo -> +foo+bar
- */
- if (!darray_empty(*to) && s[0] != '+' && s[0] != '|') {
- if (darray_item(*to, 0) == '+' || darray_item(*to, 0) == '|')
- darray_prepend_items_nullterminate(*to, value.start, value.len);
- return true;
- }
+ darray_char expanded = darray_new();
+ char ch;
+ bool expanded_plus, to_plus;
/*
* Some ugly hand-lexing here, but going through the scanner is more
@@ -743,12 +614,12 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
enum rules_mlvo mlv;
xkb_layout_index_t idx;
char pfx, sfx;
- struct sval expanded;
+ struct sval expanded_value;
/* Check if that's a start of an expansion. */
if (s[i] != '%') {
/* Just a normal character. */
- darray_append_items_nullterminate(*to, &s[i++], 1);
+ darray_appends_nullterminate(expanded, &s[i++], 1);
continue;
}
if (++i >= value.len) goto error;
@@ -777,9 +648,7 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
int consumed;
if (mlv != MLVO_LAYOUT && mlv != MLVO_VARIANT) {
- matcher_error1(m,
- "invalid index in %%-expansion; "
- "may only index layout or variant");
+ matcher_err(m, "invalid index in %%-expansion; may only index layout or variant");
goto error;
}
@@ -795,46 +664,65 @@ append_expanded_kccgst_value(struct matcher *m, darray_char *to,
}
/* Get the expanded value. */
- expanded.len = 0;
+ expanded_value.len = 0;
if (mlv == MLVO_LAYOUT) {
if (idx != XKB_LAYOUT_INVALID &&
idx < darray_size(m->rmlvo.layouts) &&
darray_size(m->rmlvo.layouts) > 1)
- expanded = darray_item(m->rmlvo.layouts, idx);
+ expanded_value = darray_item(m->rmlvo.layouts, idx);
else if (idx == XKB_LAYOUT_INVALID &&
darray_size(m->rmlvo.layouts) == 1)
- expanded = darray_item(m->rmlvo.layouts, 0);
+ expanded_value = darray_item(m->rmlvo.layouts, 0);
}
else if (mlv == MLVO_VARIANT) {
if (idx != XKB_LAYOUT_INVALID &&
idx < darray_size(m->rmlvo.variants) &&
darray_size(m->rmlvo.variants) > 1)
- expanded = darray_item(m->rmlvo.variants, idx);
+ expanded_value = darray_item(m->rmlvo.variants, idx);
else if (idx == XKB_LAYOUT_INVALID &&
darray_size(m->rmlvo.variants) == 1)
- expanded = darray_item(m->rmlvo.variants, 0);
+ expanded_value = darray_item(m->rmlvo.variants, 0);
}
else if (mlv == MLVO_MODEL) {
- expanded = m->rmlvo.model;
+ expanded_value = m->rmlvo.model;
}
/* If we didn't get one, skip silently. */
- if (expanded.len <= 0)
+ if (expanded_value.len <= 0)
continue;
if (pfx != 0)
- darray_append_items_nullterminate(*to, &pfx, 1);
- darray_append_items_nullterminate(*to, expanded.start, expanded.len);
+ darray_appends_nullterminate(expanded, &pfx, 1);
+ darray_appends_nullterminate(expanded,
+ expanded_value.start, expanded_value.len);
if (sfx != 0)
- darray_append_items_nullterminate(*to, &sfx, 1);
+ darray_appends_nullterminate(expanded, &sfx, 1);
}
+ /*
+ * Appending bar to foo -> foo (not an error if this happens)
+ * Appending +bar to foo -> foo+bar
+ * Appending bar to +foo -> bar+foo
+ * Appending +bar to +foo -> +foo+bar
+ */
+
+ ch = (darray_empty(expanded) ? '\0' : darray_item(expanded, 0));
+ expanded_plus = (ch == '+' || ch == '|');
+ ch = (darray_empty(*to) ? '\0' : darray_item(*to, 0));
+ to_plus = (ch == '+' || ch == '|');
+
+ if (expanded_plus || darray_empty(*to))
+ darray_appends_nullterminate(*to, expanded.item, expanded.size);
+ else if (to_plus)
+ darray_prepends_nullterminate(*to, expanded.item, expanded.size);
+
+ darray_free(expanded);
return true;
error:
- matcher_error1(m, "invalid %%-expansion in value; not used");
- darray_resize(*to, original_size);
+ darray_free(expanded);
+ matcher_err(m, "invalid %%-expansion in value; not used");
return false;
}
@@ -843,9 +731,7 @@ matcher_rule_verify(struct matcher *m)
{
if (m->rule.num_mlvo_values != m->mapping.num_mlvo ||
m->rule.num_kccgst_values != m->mapping.num_kccgst) {
- matcher_error1(m,
- "invalid rule: must have same number of values as mapping line;"
- "ignoring rule");
+ matcher_err(m, "invalid rule: must have same number of values as mapping line; ignoring rule");
m->rule.skip = true;
}
}
@@ -907,7 +793,7 @@ matcher_rule_apply_if_matches(struct matcher *m)
static enum rules_token
gettok(struct matcher *m)
{
- return lex(&m->scanner, &m->val, &m->loc);
+ return lex(&m->scanner, &m->val);
}
static bool
@@ -1068,7 +954,7 @@ finish:
return true;
state_error:
- matcher_error1(m, "unexpected token");
+ matcher_err(m, "unexpected token");
error:
return false;
}
@@ -1091,12 +977,13 @@ xkb_components_from_rules(struct xkb_context *ctx,
ret = map_file(file, &string, &size);
if (!ret) {
- log_err(ctx, "Couldn't read rules file: %s\n", strerror(errno));
+ log_err(ctx, "Couldn't read rules file \"%s\": %s\n",
+ path, strerror(errno));
goto err_file;
}
matcher = matcher_new(ctx, rmlvo);
- ret = matcher_match(matcher, string, size, rmlvo->rules, out);
+ ret = matcher_match(matcher, string, size, path, out);
if (!ret)
log_err(ctx, "No components returned from XKB rules \"%s\"\n", path);
matcher_free(matcher);
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
index 48df488547..9f200bbec4 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/scanner.c
@@ -23,27 +23,6 @@
#include "xkbcomp-priv.h"
#include "parser-priv.h"
-#include "scanner-utils.h"
-
-static void
-scanner_log(enum xkb_log_level level, struct scanner *s, const char *msg)
-{
- xkb_log(s->ctx, level, 0, "%s:%d:%d: %s\n", s->file_name,
- s->token_line, s->token_column, msg);
-}
-
-int
-scanner_error(struct scanner *s, const char *msg)
-{
- scanner_log(XKB_LOG_LEVEL_ERROR, s, msg);
- return ERROR_TOK;
-}
-
-void
-scanner_warn(struct scanner *s, const char *msg)
-{
- scanner_log(XKB_LOG_LEVEL_WARNING, s, msg);
-}
static bool
number(struct scanner *s, int64_t *out, int *out_tok)
@@ -123,11 +102,13 @@ skip_more_whitespace_and_comments:
buf_append(s, next(s));
}
}
- if (!buf_append(s, '\0') || !chr(s, '\"'))
- return scanner_error(s, "unterminated string literal");
+ if (!buf_append(s, '\0') || !chr(s, '\"')) {
+ scanner_err(s, "unterminated string literal");
+ return ERROR_TOK;
+ }
yylval->str = strdup(s->buf);
if (!yylval->str)
- return scanner_error(s, "scanner out of memory");
+ return ERROR_TOK;
return STRING;
}
@@ -135,8 +116,10 @@ skip_more_whitespace_and_comments:
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");
+ if (!buf_append(s, '\0') || !chr(s, '>')) {
+ scanner_err(s, "unterminated key name literal");
+ return ERROR_TOK;
+ }
/* Empty key name literals are allowed. */
yylval->sval = xkb_atom_intern(s->ctx, s->buf, s->buf_pos - 1);
return KEYNAME;
@@ -165,27 +148,32 @@ skip_more_whitespace_and_comments:
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");
+ if (!buf_append(s, '\0')) {
+ scanner_err(s, "identifier too long");
+ return ERROR_TOK;
+ }
/* Keyword. */
- tok = keyword_to_token(s->buf);
+ tok = keyword_to_token(s->buf, s->buf_pos - 1);
if (tok != -1) return tok;
yylval->str = strdup(s->buf);
if (!yylval->str)
- return scanner_error(s, "scanner out of memory");
+ return ERROR_TOK;
return IDENT;
}
/* Number literal (hexadecimal / decimal / float). */
if (number(s, &yylval->num, &tok)) {
- if (tok == ERROR_TOK)
- return scanner_error(s, "malformed number literal");
+ if (tok == ERROR_TOK) {
+ scanner_err(s, "malformed number literal");
+ return ERROR_TOK;
+ }
return tok;
}
- return scanner_error(s, "unrecognized token");
+ scanner_err(s, "unrecognized token");
+ return ERROR_TOK;
}
XkbFile *
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
index 56cce431da..bd7f73d4f1 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/symbols.c
@@ -125,12 +125,11 @@ ClearGroupInfo(GroupInfo *groupi)
static void
CopyGroupInfo(GroupInfo *to, const GroupInfo *from)
{
- xkb_level_index_t j;
to->defined = from->defined;
to->type = from->type;
darray_init(to->levels);
darray_copy(to->levels, from->levels);
- for (j = 0; j < darray_size(to->levels); j++)
+ for (xkb_level_index_t j = 0; j < darray_size(to->levels); j++)
if (darray_item(from->levels, j).num_syms > 1)
darray_item(to->levels, j).u.syms =
memdup(darray_item(from->levels, j).u.syms,
@@ -480,7 +479,6 @@ static void
MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
enum merge_mode merge)
{
- unsigned int i;
KeyInfo *keyi;
ModMapEntry *mm;
xkb_atom_t *group_name;
@@ -498,7 +496,7 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
group_names_in_both = MIN(darray_size(into->group_names),
darray_size(from->group_names));
- for (i = 0; i < group_names_in_both; i++) {
+ for (xkb_layout_index_t i = 0; i < group_names_in_both; i++) {
if (!darray_item(from->group_names, i))
continue;
@@ -511,16 +509,28 @@ MergeIncludedSymbols(SymbolsInfo *into, SymbolsInfo *from,
darray_foreach_from(group_name, from->group_names, group_names_in_both)
darray_append(into->group_names, *group_name);
- darray_foreach(keyi, from->keys) {
- keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge);
- if (!AddKeySymbols(into, keyi, false))
- into->errorCount++;
+ if (darray_empty(into->keys)) {
+ into->keys = from->keys;
+ darray_init(from->keys);
+ }
+ else {
+ darray_foreach(keyi, from->keys) {
+ keyi->merge = (merge == MERGE_DEFAULT ? keyi->merge : merge);
+ if (!AddKeySymbols(into, keyi, false))
+ into->errorCount++;
+ }
}
- darray_foreach(mm, from->modmaps) {
- mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge);
- if (!AddModMapEntry(into, mm))
- into->errorCount++;
+ if (darray_empty(into->modmaps)) {
+ into->modmaps = from->modmaps;
+ darray_init(from->modmaps);
+ }
+ else {
+ darray_foreach(mm, from->modmaps) {
+ mm->merge = (merge == MERGE_DEFAULT ? mm->merge : merge);
+ if (!AddModMapEntry(into, mm))
+ into->errorCount++;
+ }
}
}
@@ -633,8 +643,6 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
xkb_layout_index_t ndx;
GroupInfo *groupi;
xkb_level_index_t nLevels;
- xkb_level_index_t i;
- int j;
if (!GetGroupIndex(info, keyi, arrayNdx, SYMBOLS, &ndx))
return false;
@@ -669,7 +677,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
groupi->defined |= GROUP_FIELD_SYMS;
- for (i = 0; i < nLevels; i++) {
+ for (xkb_level_index_t i = 0; i < nLevels; i++) {
unsigned int sym_index;
struct xkb_level *leveli = &darray_item(groupi->levels, i);
@@ -678,7 +686,7 @@ AddSymbolsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
if (leveli->num_syms > 1)
leveli->u.syms = calloc(leveli->num_syms, sizeof(*leveli->u.syms));
- for (j = 0; j < leveli->num_syms; j++) {
+ for (unsigned j = 0; j < leveli->num_syms; j++) {
xkb_keysym_t keysym = darray_item(value->keysym_list.syms,
sym_index + j);
@@ -701,7 +709,6 @@ static bool
AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
ExprDef *value)
{
- unsigned int i;
xkb_layout_index_t ndx;
GroupInfo *groupi;
unsigned int nActs;
@@ -742,7 +749,7 @@ AddActionsToKey(SymbolsInfo *info, KeyInfo *keyi, ExprDef *arrayNdx,
groupi->defined |= GROUP_FIELD_ACTS;
act = value->unary.child;
- for (i = 0; i < nActs; i++) {
+ for (unsigned i = 0; i < nActs; i++) {
union xkb_action *toAct = &darray_item(groupi->levels, i).action;
if (!HandleActionDef(act, info->keymap, toAct, info->actions))
@@ -772,19 +779,20 @@ static bool
SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
ExprDef *arrayNdx, ExprDef *value)
{
- bool ok = true;
struct xkb_context *ctx = info->keymap->ctx;
if (istreq(field, "type")) {
xkb_layout_index_t ndx;
xkb_atom_t val;
- if (!ExprResolveString(ctx, value, &val))
- log_vrb(ctx, 1,
+ if (!ExprResolveString(ctx, value, &val)) {
+ log_err(ctx,
"The type field of a key symbol map must be a string; "
"Ignoring illegal type definition\n");
+ return false;
+ }
- if (arrayNdx == NULL) {
+ if (!arrayNdx) {
keyi->default_type = val;
keyi->defined |= KEY_FIELD_DEFAULT_TYPE;
}
@@ -803,32 +811,33 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
darray_item(keyi->groups, ndx).defined |= GROUP_FIELD_TYPE;
}
}
- else if (istreq(field, "symbols"))
+ else if (istreq(field, "symbols")) {
return AddSymbolsToKey(info, keyi, arrayNdx, value);
- else if (istreq(field, "actions"))
+ }
+ else if (istreq(field, "actions")) {
return AddActionsToKey(info, keyi, arrayNdx, value);
+ }
else if (istreq(field, "vmods") ||
istreq(field, "virtualmods") ||
istreq(field, "virtualmodifiers")) {
xkb_mod_mask_t mask;
- ok = ExprResolveModMask(info->keymap, value, MOD_VIRT, &mask);
- if (ok) {
- keyi->vmodmap = mask;
- keyi->defined |= KEY_FIELD_VMODMAP;
- }
- else {
- log_err(info->keymap->ctx,
+ if (!ExprResolveModMask(info->keymap, value, MOD_VIRT, &mask)) {
+ log_err(ctx,
"Expected a virtual modifier mask, found %s; "
"Ignoring virtual modifiers definition for key %s\n",
expr_op_type_to_string(value->expr.op),
KeyInfoText(info, keyi));
+ return false;
}
+
+ keyi->vmodmap = mask;
+ keyi->defined |= KEY_FIELD_VMODMAP;
}
else if (istreq(field, "locking") ||
istreq(field, "lock") ||
istreq(field, "locks")) {
- log_err(info->keymap->ctx,
+ log_vrb(ctx, 1,
"Key behaviors not supported; "
"Ignoring locking specification for key %s\n",
KeyInfoText(info, keyi));
@@ -836,14 +845,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
else if (istreq(field, "radiogroup") ||
istreq(field, "permanentradiogroup") ||
istreq(field, "allownone")) {
- log_err(info->keymap->ctx,
+ log_vrb(ctx, 1,
"Radio groups not supported; "
"Ignoring radio group specification for key %s\n",
KeyInfoText(info, keyi));
}
else if (istreq_prefix("overlay", field) ||
istreq_prefix("permanentoverlay", field)) {
- log_err(info->keymap->ctx,
+ log_vrb(ctx, 1,
"Overlays not supported; "
"Ignoring overlay specification for key %s\n",
KeyInfoText(info, keyi));
@@ -853,14 +862,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
istreq(field, "repeat")) {
unsigned int val;
- ok = ExprResolveEnum(ctx, value, &val, repeatEntries);
- if (!ok) {
- log_err(info->keymap->ctx,
+ if (!ExprResolveEnum(ctx, value, &val, repeatEntries)) {
+ log_err(ctx,
"Illegal repeat setting for %s; "
"Non-boolean repeat setting ignored\n",
KeyInfoText(info, keyi));
return false;
}
+
keyi->repeat = val;
keyi->defined |= KEY_FIELD_REPEAT;
}
@@ -869,18 +878,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
bool set;
if (!ExprResolveBoolean(ctx, value, &set)) {
- log_err(info->keymap->ctx,
+ log_err(ctx,
"Illegal groupsWrap setting for %s; "
"Non-boolean value ignored\n",
KeyInfoText(info, keyi));
return false;
}
- if (set)
- keyi->out_of_range_group_action = RANGE_WRAP;
- else
- keyi->out_of_range_group_action = RANGE_SATURATE;
-
+ keyi->out_of_range_group_action = (set ? RANGE_WRAP : RANGE_SATURATE);
keyi->defined |= KEY_FIELD_GROUPINFO;
}
else if (istreq(field, "groupsclamp") ||
@@ -888,18 +893,14 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
bool set;
if (!ExprResolveBoolean(ctx, value, &set)) {
- log_err(info->keymap->ctx,
+ log_err(ctx,
"Illegal groupsClamp setting for %s; "
"Non-boolean value ignored\n",
KeyInfoText(info, keyi));
return false;
}
- if (set)
- keyi->out_of_range_group_action = RANGE_SATURATE;
- else
- keyi->out_of_range_group_action = RANGE_WRAP;
-
+ keyi->out_of_range_group_action = (set ? RANGE_SATURATE : RANGE_WRAP);
keyi->defined |= KEY_FIELD_GROUPINFO;
}
else if (istreq(field, "groupsredirect") ||
@@ -907,7 +908,7 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
xkb_layout_index_t grp;
if (!ExprResolveGroup(ctx, value, &grp)) {
- log_err(info->keymap->ctx,
+ log_err(ctx,
"Illegal group index for redirect of key %s; "
"Definition with non-integer group ignored\n",
KeyInfoText(info, keyi));
@@ -919,17 +920,17 @@ SetSymbolsField(SymbolsInfo *info, KeyInfo *keyi, const char *field,
keyi->defined |= KEY_FIELD_GROUPINFO;
}
else {
- log_err(info->keymap->ctx,
+ log_err(ctx,
"Unknown field %s in a symbol interpretation; "
"Definition ignored\n",
field);
- ok = false;
+ return false;
}
- return ok;
+ return true;
}
-static int
+static bool
SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value)
{
xkb_layout_index_t group, group_to_use;
@@ -979,16 +980,16 @@ SetGroupName(SymbolsInfo *info, ExprDef *arrayNdx, ExprDef *value)
return true;
}
-static int
+static bool
HandleGlobalVar(SymbolsInfo *info, VarDef *stmt)
{
const char *elem, *field;
ExprDef *arrayNdx;
bool ret;
- if (ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field,
- &arrayNdx) == 0)
- return 0; /* internal error, already reported */
+ if (!ExprResolveLhs(info->keymap->ctx, stmt->name, &elem, &field, &arrayNdx))
+ return false;
+
if (elem && istreq(elem, "key")) {
ret = SetSymbolsField(info, &info->default_key, field, arrayNdx,
stmt->value);
@@ -1098,16 +1099,15 @@ SetExplicitGroup(SymbolsInfo *info, KeyInfo *keyi)
return true;
}
-static int
+static bool
HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt)
{
KeyInfo keyi;
- xkb_layout_index_t i;
keyi = info->default_key;
darray_init(keyi.groups);
darray_copy(keyi.groups, info->default_key.groups);
- for (i = 0; i < darray_size(keyi.groups); i++)
+ for (xkb_layout_index_t i = 0; i < darray_size(keyi.groups); i++)
CopyGroupInfo(&darray_item(keyi.groups, i),
&darray_item(info->default_key.groups, i));
keyi.merge = stmt->merge;
@@ -1134,7 +1134,6 @@ HandleSymbolsDef(SymbolsInfo *info, SymbolsDef *stmt)
static bool
HandleModMapDef(SymbolsInfo *info, ModMapDef *def)
{
- ExprDef *key;
ModMapEntry tmp;
xkb_mod_index_t ndx;
bool ok;
@@ -1153,7 +1152,7 @@ HandleModMapDef(SymbolsInfo *info, ModMapDef *def)
tmp.modifier = ndx;
tmp.merge = def->merge;
- for (key = def->keys; key != NULL; key = (ExprDef *) key->common.next) {
+ for (ExprDef *key = def->keys; key; key = (ExprDef *) key->common.next) {
xkb_keysym_t sym;
if (key->expr.op == EXPR_VALUE &&
@@ -1198,7 +1197,7 @@ HandleSymbolsFile(SymbolsInfo *info, XkbFile *file, enum merge_mode merge)
ok = HandleGlobalVar(info, (VarDef *) stmt);
break;
case STMT_VMOD:
- ok = HandleVModDef(info->keymap, (VModDef *) stmt);
+ ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break;
case STMT_MODMAP:
ok = HandleModMapDef(info, (ModMapDef *) stmt);
@@ -1518,7 +1517,7 @@ CopyModMapDef(SymbolsInfo *info, ModMapEntry *entry)
}
}
- key->modmap |= (1 << entry->modifier);
+ key->modmap |= (1u << entry->modifier);
return true;
}
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/types.c b/src/3rdparty/xkbcommon/src/xkbcomp/types.c
index 5b7ccbb4db..7708da3882 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/types.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/types.c
@@ -30,111 +30,6 @@
#include "expr.h"
#include "include.h"
-/*
- * The xkb_types section
- * =====================
- * This section is the second to be processesed, after xkb_keycodes.
- * However, it is completely independent and could have been the first
- * to be processed (it does not refer to specific keys as specified in
- * the xkb_keycodes section).
- *
- * This section defines key types, which, given a key and a keyboard
- * state (i.e. modifier state and group), determine the shift level to
- * be used in translating the key to keysyms. These types are assigned
- * to each group in each key, in the xkb_symbols section.
- *
- * Key types are called this way because, in a way, they really describe
- * the "type" of the key (or more correctly, a specific group of the
- * key). For example, an ordinary keymap will provide a type called
- * "KEYPAD", which consists of two levels, with the second level being
- * chosen according to the state of the Num Lock (or Shift) modifiers.
- * Another example is a type called "ONE_LEVEL", which is usually
- * assigned to keys such as Escape; these have just one level and are
- * not affected by the modifier state. Yet more common examples are
- * "TWO_LEVEL" (with Shift choosing the second level), "ALPHABETIC"
- * (where Caps Lock may also choose the second level), etc.
- *
- * Type definitions
- * ----------------
- * Statements of the form:
- * type "FOUR_LEVEL" { ... }
- *
- * The above would create a new type named "FOUR_LEVEL".
- * The body of the definition may include statements of the following
- * forms:
- *
- * - level_name statements (mandatory for each level in the type):
- * level_name[Level1] = "Base";
- *
- * Gives each level in this type a descriptive name. It isn't used
- * for any thing.
- * Note: A level may be specified as Level[1-8] or just a number (can
- * be more than 8).
- *
- * - modifiers statement (mandatory, should be specified only once):
- * modifiers = Shift+Lock+LevelThree;
- *
- * A mask of real and virtual modifiers. These are the only modifiers
- * being considered when matching the modifier state against the type.
- * The other modifiers, whether active or not, are masked out in the
- * calculation.
- *
- * - map entry statements (should have at least as many mappings as there
- * are levels in the type):
- * map[Shift+LevelThree] = Level4;
- *
- * If the active modifiers, masked with the type's modifiers (as stated
- * above), match (i.e. equal) the modifiers inside the map[] statement,
- * then the level in the right hand side is chosen. For example, in the
- * above, if in the current keyboard state the Shift and LevelThree
- * modifiers are active, while the Lock modifier is not, then the
- * keysym(s) in the 4th level of the group will be returned to the
- * user.
- *
- * - preserve statements:
- * map[Shift+Lock+LevelThree] = Level5;
- * preserve[Shift+Lock+LevelThree] = Lock;
- *
- * When a map entry matches the active modifiers and the level it
- * specified is chosen, then these modifiers are said to be "consumed";
- * for example, in a simple US keymap where the "g" key is assigned an
- * ordinary ALPHABETIC key type, if the Lock (Caps Lock) modifier is
- * active and the key is pressed, then a "G" keysym is produced (as
- * opposed to lower-case "g"). This is because the type definition has
- * a map entry like the following:
- * map[Lock] = Level2;
- * And as such the Lock modifier is consumed. This information is
- * relevant for applications which further process the modifiers,
- * since by then the consumed modifiers have already "done their part"
- * and should be masked out.
- *
- * However, sometimes even if a modifier is actually used to choose
- * the shift level (as Lock above), it should *not* be reported as
- * consumed, for various reasons. In this case, a preserve[] statement
- * can be used to augment the map entry. The modifiers inside the square
- * brackets should match one of the map[] statements in the type. The
- * right hand side should consists of modifiers from the left hand
- * side; these modifiers are then "preserved" and not reported as
- * consumed.
- *
- * Virtual modifier statements
- * ---------------------------
- * Statements of the form:
- * virtual_modifiers LControl;
- *
- * Can appear in the xkb_types, xkb_compat, xkb_symbols sections.
- * TODO
- *
- * Effect on keymap
- * ----------------
- * After all of the xkb_types sections have been compiled, the following
- * members of struct xkb_keymap are finalized:
- * struct xkb_key_type *types;
- * unsigned int num_types;
- * char *types_section_name;
- * TODO: virtual modifiers.
- */
-
enum type_field {
TYPE_FIELD_MASK = (1 << 0),
TYPE_FIELD_MAP = (1 << 1),
@@ -287,10 +182,16 @@ MergeIncludedKeyTypes(KeyTypesInfo *into, KeyTypesInfo *from,
from->name = NULL;
}
- darray_foreach(type, from->types) {
- type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
- if (!AddKeyType(into, type, false))
- into->errorCount++;
+ if (darray_empty(into->types)) {
+ into->types = from->types;
+ darray_init(from->types);
+ }
+ else {
+ darray_foreach(type, from->types) {
+ type->merge = (merge == MERGE_DEFAULT ? type->merge : merge);
+ if (!AddKeyType(into, type, false))
+ into->errorCount++;
+ }
}
}
@@ -738,7 +639,7 @@ HandleKeyTypesFile(KeyTypesInfo *info, XkbFile *file, enum merge_mode merge)
ok = true;
break;
case STMT_VMOD:
- ok = HandleVModDef(info->keymap, (VModDef *) stmt);
+ ok = HandleVModDef(info->keymap, (VModDef *) stmt, merge);
break;
default:
log_err(info->keymap->ctx,
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c
index 206e1624e6..86e7bec786 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.c
@@ -30,27 +30,64 @@
#include "vmod.h"
bool
-HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt)
+HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt,
+ enum merge_mode merge)
{
xkb_mod_index_t i;
- const struct xkb_mod *mod;
+ struct xkb_mod *mod;
+ xkb_mod_mask_t mapping;
struct xkb_mod new;
- if (stmt->value)
- log_err(keymap->ctx,
- "Support for setting a value in a virtual_modifiers statement has been removed; "
- "Value ignored\n");
+ merge = (merge == MERGE_DEFAULT ? stmt->merge : merge);
+
+ if (stmt->value) {
+ /*
+ * This is a statement such as 'virtualModifiers NumLock = Mod1';
+ * it sets the vmod-to-real-mod[s] mapping directly instead of going
+ * through modifier_map or some such.
+ */
+ if (!ExprResolveModMask(keymap, stmt->value, MOD_REAL, &mapping)) {
+ log_err(keymap->ctx,
+ "Declaration of %s ignored\n",
+ xkb_atom_text(keymap->ctx, stmt->name));
+ return false;
+ }
+ }
+ else {
+ mapping = 0;
+ }
darray_enumerate(i, mod, keymap->mods) {
if (mod->name == stmt->name) {
- if (mod->type == MOD_VIRT)
+ if (mod->type != MOD_VIRT) {
+ log_err(keymap->ctx,
+ "Can't add a virtual modifier named \"%s\"; "
+ "there is already a non-virtual modifier with this name! Ignored\n",
+ xkb_atom_text(keymap->ctx, mod->name));
+ return false;
+ }
+
+ if (mod->mapping == mapping)
return true;
- log_err(keymap->ctx,
- "Can't add a virtual modifier named \"%s\"; "
- "there is already a non-virtual modifier with this name! Ignored\n",
- xkb_atom_text(keymap->ctx, mod->name));
- return false;
+ if (mod->mapping != 0) {
+ xkb_mod_mask_t use, ignore;
+
+ use = (merge == MERGE_OVERRIDE ? mapping : mod->mapping);
+ ignore = (merge == MERGE_OVERRIDE ? mod->mapping : mapping);
+
+ log_warn(keymap->ctx,
+ "Virtual modifier %s defined multiple times; "
+ "Using %s, ignoring %s\n",
+ xkb_atom_text(keymap->ctx, stmt->name),
+ ModMaskText(keymap, use),
+ ModMaskText(keymap, ignore));
+
+ mapping = use;
+ }
+
+ mod->mapping = mapping;
+ return true;
}
}
@@ -62,7 +99,7 @@ HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt)
}
new.name = stmt->name;
- new.mapping = 0;
+ new.mapping = mapping;
new.type = MOD_VIRT;
darray_append(keymap->mods, new);
return true;
diff --git a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h
index 991550735f..1ba59f73cd 100644
--- a/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h
+++ b/src/3rdparty/xkbcommon/src/xkbcomp/vmod.h
@@ -28,6 +28,7 @@
#define XKBCOMP_VMOD_H
bool
-HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt);
+HandleVModDef(struct xkb_keymap *keymap, VModDef *stmt,
+ enum merge_mode merge);
#endif
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h
index f96e4c806f..299732fdc3 100644
--- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h
+++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-compat.h
@@ -91,4 +91,8 @@
#define xkb_state_get_map(state) xkb_state_get_keymap(state)
+/* Not needed anymore, since there's NO_FLAGS. */
+#define XKB_MAP_COMPILE_PLACEHOLDER XKB_KEYMAP_COMPILE_NO_FLAGS
+#define XKB_MAP_COMPILE_NO_FLAGS XKB_KEYMAP_COMPILE_NO_FLAGS
+
#endif
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h
index 4ec9b649c7..d9e2a4f11a 100644
--- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h
+++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon-x11.h
@@ -27,6 +27,10 @@
#include <xcb/xcb.h>
#include <xkbcommon/xkbcommon.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* @file
* libxkbcommon-x11 API - Additional X11 support for xkbcommon.
@@ -163,4 +167,8 @@ xkb_x11_state_new_from_device(struct xkb_keymap *keymap,
/** @} */
+#ifdef __cplusplus
+} /* extern "C" */
#endif
+
+#endif /* _XKBCOMMON_X11_H */
diff --git a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
index cc9262ff89..36251db443 100644
--- a/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
+++ b/src/3rdparty/xkbcommon/xkbcommon/xkbcommon.h
@@ -305,26 +305,60 @@ typedef uint32_t xkb_led_mask_t;
/**
* Names to compile a keymap with, also known as RMLVO.
*
- * These names together are the primary identifier for a keymap.
- * If any of the members is NULL or an empty string (""), a default value is
- * used. It is recommended to use the system default by passing NULL for
- * unspecified values, instead of providing your own defaults.
+ * The names are the common configuration values by which a user picks
+ * a keymap.
+ *
+ * If the entire struct is NULL, then each field is taken to be NULL.
+ * You should prefer passing NULL instead of choosing your own defaults.
*/
struct xkb_rule_names {
- /** The rules file to use. The rules file describes how to interpret
- * the values of the model, layout, variant and options fields. */
+ /**
+ * The rules file to use. The rules file describes how to interpret
+ * the values of the model, layout, variant and options fields.
+ *
+ * If NULL or the empty string "", a default value is used.
+ * If the XKB_DEFAULT_RULES environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
const char *rules;
- /** The keyboard model by which to interpret keycodes and LEDs. */
+ /**
+ * The keyboard model by which to interpret keycodes and LEDs.
+ *
+ * If NULL or the empty string "", a default value is used.
+ * If the XKB_DEFAULT_MODEL environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
const char *model;
- /** A comma separated list of layouts (languages) to include in the
- * keymap. */
+ /**
+ * A comma separated list of layouts (languages) to include in the
+ * keymap.
+ *
+ * If NULL or the empty string "", a default value is used.
+ * If the XKB_DEFAULT_LAYOUT environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
const char *layout;
- /** A comma separated list of variants, one per layout, which may
- * modify or augment the respective layout in various ways. */
+ /**
+ * A comma separated list of variants, one per layout, which may
+ * modify or augment the respective layout in various ways.
+ *
+ * If NULL or the empty string "", and a default value is also used
+ * for the layout, a default value is used. Otherwise no variant is
+ * used.
+ * If the XKB_DEFAULT_VARIANT environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
const char *variant;
- /** A comma separated list of options, through which the user specifies
- * non-layout related preferences, like which key combinations are used
- * for switching layouts, or which key is the Compose key. */
+ /**
+ * A comma separated list of options, through which the user specifies
+ * non-layout related preferences, like which key combinations are used
+ * for switching layouts, or which key is the Compose key.
+ *
+ * If NULL, a default value is used. If the empty string "", no
+ * options are used.
+ * If the XKB_DEFAULT_OPTIONS environment variable is set, it is used
+ * as the default. Otherwise the system default is used.
+ */
const char *options;
};
@@ -399,6 +433,11 @@ xkb_keysym_from_name(const char *name, enum xkb_keysym_flags flags);
* @returns The number of bytes written to the buffer (including the
* terminating byte). If the keysym does not have a Unicode
* representation, returns 0. If the buffer is too small, returns -1.
+ *
+ * Prefer not to use this function on keysyms obtained from an
+ * xkb_state. In this case, use xkb_state_key_get_utf8() instead.
+ *
+ * @sa xkb_state_key_get_utf8()
*/
int
xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size);
@@ -409,6 +448,11 @@ xkb_keysym_to_utf8(xkb_keysym_t keysym, char *buffer, size_t size);
* @returns The Unicode/UTF-32 representation of keysym, which is also
* compatible with UCS-4. If the keysym does not have a Unicode
* representation, returns 0.
+ *
+ * Prefer not to use this function on keysyms obtained from an
+ * xkb_state. In this case, use xkb_state_key_get_utf32() instead.
+ *
+ * @sa xkb_state_key_get_utf32()
*/
uint32_t
xkb_keysym_to_utf32(xkb_keysym_t keysym);
@@ -681,9 +725,7 @@ 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
+ XKB_KEYMAP_COMPILE_NO_FLAGS = 0
};
/**
@@ -692,13 +734,8 @@ enum xkb_keymap_compile_flags {
* The primary keymap entry point: creates a new XKB keymap from a set of
* RMLVO (Rules + Model + Layouts + Variants + Options) names.
*
- * You should almost certainly be using this and nothing else to create
- * keymaps.
- *
* @param context The context in which to create the keymap.
- * @param names The RMLVO names to use. In xkbcommon versions prior
- * to 0.2.1, this field must be non-NULL. In later
- * versions, passing NULL will use the default keymap.
+ * @param names The RMLVO names to use. See xkb_rule_names.
* @param flags Optional flags for the keymap, or 0.
*
* @returns A keymap compiled according to the RMLVO names, or NULL if
@@ -1159,6 +1196,13 @@ enum xkb_state_component {
* is pressed twice, it should be released twice; etc. Otherwise (e.g. due
* to missed input events), situations like "stuck modifiers" may occur.
*
+ * This function is often used in conjunction with the function
+ * xkb_state_key_get_syms() (or xkb_state_key_get_one_sym()), for example,
+ * when handling a key event. In this case, you should prefer to get the
+ * keysyms *before* updating the key, such that the keysyms reported for
+ * the key event are not affected by the event itself. This is the
+ * conventional behavior.
+ *
* @returns A mask of state components that have changed as a result of
* the update. If nothing in the state has changed, returns 0.
*
@@ -1235,6 +1279,44 @@ xkb_state_key_get_syms(struct xkb_state *state, xkb_keycode_t key,
const xkb_keysym_t **syms_out);
/**
+ * Get the Unicode/UTF-8 string obtained from pressing a particular key
+ * in a given keyboard state.
+ *
+ * @param[in] state The keyboard state object.
+ * @param[in] key The keycode of the key.
+ * @param[out] buffer A buffer to write the string into.
+ * @param[in] size Size of the buffer.
+ *
+ * @warning If the buffer passed is too small, the string is truncated
+ * (though still NUL-terminated).
+ *
+ * @returns The number of bytes required for the string, excluding the
+ * NUL byte. If there is nothing to write, returns 0.
+ *
+ * You may check if truncation has occurred by comparing the return value
+ * with the size of @p buffer, similarly to the snprintf(3) function.
+ * You may safely pass NULL and 0 to @p buffer and @p size to find the
+ * required size (without the NUL-byte).
+ *
+ * @memberof xkb_state
+ */
+int
+xkb_state_key_get_utf8(struct xkb_state *state, xkb_keycode_t key,
+ char *buffer, size_t size);
+
+/**
+ * Get the Unicode/UTF-32 codepoint obtained from pressing a particular
+ * key in a a given keyboard state.
+ *
+ * @returns The UTF-32 representation for the key, if it consists of only
+ * a single codepoint. Otherwise, returns 0.
+ *
+ * @memberof xkb_state
+ */
+uint32_t
+xkb_state_key_get_utf32(struct xkb_state *state, xkb_keycode_t key);
+
+/**
* Get the single keysym obtained from pressing a particular key in a
* given keyboard state.
*
@@ -1485,6 +1567,7 @@ xkb_state_mod_indices_are_active(struct xkb_state *state,
* index is not valid in the keymap, returns -1.
*
* @sa xkb_state_mod_mask_remove_consumed()
+ * @sa xkb_state_key_get_consumed_mods()
* @memberof xkb_state
*/
int
@@ -1505,6 +1588,17 @@ xkb_state_mod_mask_remove_consumed(struct xkb_state *state, xkb_keycode_t key,
xkb_mod_mask_t mask);
/**
+ * Get the mask of modifiers consumed by translating a given key.
+ *
+ * @returns a mask of the consumed modifiers.
+ *
+ * @sa xkb_state_mod_index_is_consumed()
+ * @memberof xkb_state
+ */
+xkb_mod_mask_t
+xkb_state_key_get_consumed_mods(struct xkb_state *state, xkb_keycode_t key);
+
+/**
* Test whether a layout is active in a given keyboard state by name.
*
* @returns 1 if the layout is active, 0 if it is not. If no layout with
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 e62b5dab82..b396dfdfa1 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -75,6 +75,7 @@ import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
+import java.lang.System;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -806,6 +807,13 @@ public class QtActivityDelegate
c = composed;
}
+ if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+ || keyCode == KeyEvent.KEYCODE_MUTE)
+ && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
+ return false;
+ }
+
m_lastChar = lc;
if (keyCode == KeyEvent.KEYCODE_BACK) {
m_backKeyPressedSent = !m_keyboardIsVisible;
@@ -831,6 +839,13 @@ public class QtActivityDelegate
}
}
+ if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP
+ || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
+ || keyCode == KeyEvent.KEYCODE_MUTE)
+ && System.getenv("QT_ANDROID_VOLUME_KEYS") == null) {
+ return false;
+ }
+
if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) {
hideSoftwareKeyboard();
setKeyboardVisibility(false, System.nanoTime());
diff --git a/src/angle/src/d3dcompiler/main.cpp b/src/angle/src/d3dcompiler/main.cpp
index 63ee1cf976..7647319396 100644
--- a/src/angle/src/d3dcompiler/main.cpp
+++ b/src/angle/src/d3dcompiler/main.cpp
@@ -207,7 +207,7 @@ HRESULT WINAPI D3DCompile(
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_BINARY_DIR"))
precompiledPath = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_BINARY_DIR"));
else
- precompiledPath = QStringLiteral(":/qt.d3dcompiler"); // Default QRC path
+ precompiledPath = QStringLiteral(":/qt.d3dcompiler/"); // Default QRC path
if (QDir(precompiledPath).exists())
binaryPaths.append(precompiledPath);
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index 139876de3a..f7bb1e91bd 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -277,10 +277,12 @@ void QUnifiedTimer::updateAnimationTimers(qint64 currentTick)
lastTick = totalElapsed;
- //we make sure we only call update time if the time has actually changed
- //it might happen in some cases that the time doesn't change because events are delayed
- //when the CPU load is high
- if (delta) {
+ //we make sure we only call update time if the time has actually advanced
+ //* it might happen in some cases that the time doesn't change because events are delayed
+ // when the CPU load is high
+ //* it might happen in some cases that the delta is negative because the animation driver
+ // advances faster than time.elapsed()
+ if (delta > 0) {
insideTick = true;
if (profilerCallback)
profilerCallback(delta);
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp
index e8ec95f4ee..4b2916a619 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbitarray.cpp
@@ -115,7 +115,7 @@ a[2] = a[0] ^ a[1];
QBitArray a(3);
QBitArray b(2);
a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ]
-b[0] = 1; b[1] = 0; // b: [ 1, 1 ]
+b[0] = 1; b[1] = 1; // b: [ 1, 1 ]
a &= b; // a: [ 1, 0, 0 ]
//! [8]
@@ -124,7 +124,7 @@ a &= b; // a: [ 1, 0, 0 ]
QBitArray a(3);
QBitArray b(2);
a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ]
-b[0] = 1; b[1] = 0; // b: [ 1, 1 ]
+b[0] = 1; b[1] = 1; // b: [ 1, 1 ]
a |= b; // a: [ 1, 1, 1 ]
//! [9]
@@ -133,7 +133,7 @@ a |= b; // a: [ 1, 1, 1 ]
QBitArray a(3);
QBitArray b(2);
a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ]
-b[0] = 1; b[1] = 0; // b: [ 1, 1 ]
+b[0] = 1; b[1] = 1; // b: [ 1, 1 ]
a ^= b; // a: [ 0, 1, 1 ]
//! [10]
@@ -151,7 +151,7 @@ QBitArray a(3);
QBitArray b(2);
QBitArray c;
a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ]
-b[0] = 1; b[1] = 0; // b: [ 1, 1 ]
+b[0] = 1; b[1] = 1; // b: [ 1, 1 ]
c = a & b; // c: [ 1, 0, 0 ]
//! [12]
@@ -161,7 +161,7 @@ QBitArray a(3);
QBitArray b(2);
QBitArray c;
a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ]
-b[0] = 1; b[1] = 0; // b: [ 1, 1 ]
+b[0] = 1; b[1] = 1; // b: [ 1, 1 ]
c = a | b; // c: [ 1, 1, 1 ]
//! [13]
@@ -171,6 +171,6 @@ QBitArray a(3);
QBitArray b(2);
QBitArray c;
a[0] = 1; a[1] = 0; a[2] = 1; // a: [ 1, 0, 1 ]
-b[0] = 1; b[1] = 0; // b: [ 1, 1 ]
+b[0] = 1; b[1] = 1; // b: [ 1, 1 ]
c = a ^ b; // c: [ 0, 1, 1 ]
//! [14]
diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h
index dfa3d83fb8..b62ae30fc5 100644
--- a/src/corelib/global/qcompilerdetection.h
+++ b/src/corelib/global/qcompilerdetection.h
@@ -485,6 +485,8 @@
* N3652 Q_COMPILER_RELAXED_CONSTEXPR_FUNCTIONS
* N3386 N3638 Q_COMPILER_RETURN_TYPE_DEDUCTION
* N3651 Q_COMPILER_VARIABLE_TEMPLATES
+ *
+ * C++14 Technical Specifications / C++17:
* N3639 Q_COMPILER_VLA (see also Q_COMPILER_RESTRICTED_VLA)
*
*/
@@ -776,7 +778,6 @@
//# define Q_COMPILER_BINARY_LITERALS // already supported since GCC 4.3 as an extension
# define Q_COMPILER_LAMBDA_CAPTURES
# define Q_COMPILER_RETURN_TYPE_DEDUCTION
-# define Q_COMPILER_VLA
# endif
# endif
#endif
@@ -828,13 +829,18 @@
# define Q_COMPILER_DELEGATING_CONSTRUCTORS
# define Q_COMPILER_EXPLICIT_CONVERSIONS
# define Q_COMPILER_NONSTATIC_MEMBER_INIT
-# define Q_COMPILER_INITIALIZER_LISTS
+// implemented, but nested initialization fails (eg tst_qvector): http://connect.microsoft.com/VisualStudio/feedback/details/800364/initializer-list-calls-object-destructor-twice
+// #define Q_COMPILER_INITIALIZER_LISTS
// implemented in principle, but has a bug that makes it unusable: http://connect.microsoft.com/VisualStudio/feedback/details/802058/c-11-unified-initialization-fails-with-c-style-arrays
// #define Q_COMPILER_UNIFORM_INIT
# define Q_COMPILER_RAW_STRINGS
# define Q_COMPILER_TEMPLATE_ALIAS
# define Q_COMPILER_VARIADIC_TEMPLATES
# endif /* VC 12 */
+# if _MSC_FULL_VER >= 180030324 // VC 12 SP 2 RC
+# define Q_COMPILER_INITIALIZER_LISTS
+# endif /* VC 12 SP 2 RC */
+
#endif /* Q_CC_MSVC */
#ifdef __cplusplus
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index cd422dfd87..3832e70c94 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -995,7 +995,7 @@ Q_CORE_EXPORT QString qtTrId(const char *id, int n = -1);
dynamic_cast to cause a compile failure.
*/
-#ifdef QT_NO_DYNAMIC_CAST
+#if defined(QT_NO_DYNAMIC_CAST) && !defined(dynamic_cast)
# define dynamic_cast QT_PREPEND_NAMESPACE(qt_dynamic_cast_check)
template<typename T, typename X>
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index d31916abeb..a4bb8cfacb 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -500,7 +500,9 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
if (urlRef) {
QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
#ifdef Q_OS_MACX
- return QDir::cleanPath(QString(path) + QLatin1String("/Contents/") + ret);
+ QString bundleContentsDir = QString(path) + QLatin1String("/Contents/");
+ if (QDir(bundleContentsDir).exists())
+ return QDir::cleanPath(bundleContentsDir + ret);
#else
return QDir::cleanPath(QString(path) + QLatin1Char('/') + ret); // iOS
#endif
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 8c1d8b867d..da26490d18 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -64,7 +64,9 @@
#endif
#if defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
+# define SD_JOURNAL_SUPPRESS_LOCATION
# include <systemd/sd-journal.h>
+# include <syslog.h>
# include <unistd.h>
#endif
@@ -1170,13 +1172,13 @@ static void systemd_default_message_handler(QtMsgType type,
break;
}
- char filebuf[PATH_MAX + sizeof("CODE_FILE=")];
- snprintf(filebuf, sizeof(filebuf), "CODE_FILE=%s", context.file ? context.file : "unknown");
-
- char linebuf[20];
- snprintf(linebuf, sizeof(linebuf), "CODE_LINE=%d", context.line);
-
- sd_journal_print_with_location(priority, filebuf, linebuf, context.function ? context.function : "unknown", "%s", message.toUtf8().constData());
+ sd_journal_send("MESSAGE=%s", message.toUtf8().constData(),
+ "PRIORITY=%i", priority,
+ "CODE_FUNC=%s", context.function ? context.function : "unknown",
+ "CODE_LINE=%d", context.line,
+ "CODE_FILE=%s", context.file ? context.file : "unknown",
+ "QT_CATEGORY=%s", context.category ? context.category : "unknown",
+ NULL);
}
#endif
diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h
index cf7ee1b7aa..384df8fd54 100644
--- a/src/corelib/global/qprocessordetection.h
+++ b/src/corelib/global/qprocessordetection.h
@@ -269,12 +269,12 @@
S390 is big-endian.
*/
-// #elif defined(__s390__)
-// # define Q_PROCESSOR_S390
-// # if defined(__s390x__)
-// # define Q_PROCESSOR_S390_X
-// # endif
-// # define Q_BYTE_ORDER Q_BIG_ENDIAN
+#elif defined(__s390__)
+# define Q_PROCESSOR_S390
+# if defined(__s390x__)
+# define Q_PROCESSOR_S390_X
+# endif
+# define Q_BYTE_ORDER Q_BIG_ENDIAN
/*
SuperH family, optional revision: SH-4A
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index 6c0f31fb55..eabedaa80a 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -113,9 +113,10 @@ static bool isPackage(const QFileSystemMetaData &data, const QFileSystemEntry &e
&application);
if (application) {
- CFStringRef path = CFURLGetString(application);
- QString applicationPath = QCFString::toQString(path);
- if (applicationPath != QLatin1String("file://localhost/System/Library/CoreServices/Finder.app/"))
+ QCFType<CFBundleRef> bundle = CFBundleCreate(kCFAllocatorDefault, application);
+ CFStringRef identifier = CFBundleGetIdentifier(bundle);
+ QString applicationId = QCFString::toQString(identifier);
+ if (applicationId != QLatin1String("com.apple.finder"))
return true;
}
}
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 7741eb4c1e..8e3bacd6b7 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -606,7 +606,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
// FILE_INFO_BY_HANDLE_CLASS has been extended by FileIdInfo = 18 as of VS2012.
typedef enum { Q_FileIdInfo = 18 } Q_FILE_INFO_BY_HANDLE_CLASS;
-# if defined(Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700)
+# if defined(Q_CC_MINGW) || (defined(Q_CC_MSVC) && (_MSC_VER < 1700 || WINVER <= 0x0601))
// MinGW-64 defines FILE_ID_128 as of gcc-4.8.1 along with FILE_SUPPORTS_INTEGRITY_STREAMS
# if !(defined(Q_CC_MINGW) && defined(FILE_SUPPORTS_INTEGRITY_STREAMS))
@@ -619,7 +619,7 @@ typedef struct _FILE_ID_INFO {
ULONGLONG VolumeSerialNumber;
FILE_ID_128 FileId;
} FILE_ID_INFO, *PFILE_ID_INFO;
-# endif // if defined (Q_CC_MINGW) || (defined(Q_CC_MSVC) && _MSC_VER < 1700))
+# endif // if defined (Q_CC_MINGW) || (defined(Q_CC_MSVC) && (_MSC_VER < 1700 || WINVER <= 0x0601))
// File ID for Windows up to version 7.
static inline QByteArray fileId(HANDLE handle)
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index bfcae2a3a2..981d663694 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -478,7 +478,7 @@ bool QFseventsFileSystemWatcherEngine::startStream()
NSMutableArray *pathsToWatch = [NSMutableArray arrayWithCapacity:watchedPaths.size()];
for (PathRefCounts::const_iterator i = watchedPaths.begin(), ei = watchedPaths.end(); i != ei; ++i)
- [pathsToWatch addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(i.key()))];
+ [pathsToWatch addObject:i.key().toNSString()];
struct FSEventStreamContext callBackInfo = {
0,
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index c974daab06..fb4107b95d 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -1034,7 +1034,8 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
LPVOID mapAddress = ::MapViewOfFile(mapHandle, access,
offsetHi, offsetLo, size + extra);
#else
- LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size);
+ LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access,
+ (ULONG64(offsetHi) << 32) + offsetLo, size);
#endif
if (mapAddress) {
uchar *address = extra + static_cast<uchar*>(mapAddress);
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index 7e6883fd14..575150f148 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -218,11 +218,14 @@ void QLoggingSettingsParser::setContent(QTextStream &stream)
if ((equalPos != -1)
&& (line.lastIndexOf(QLatin1Char('=')) == equalPos)) {
const QStringRef pattern = line.leftRef(equalPos);
- const QStringRef value = line.midRef(equalPos + 1);
- bool enabled = (value.compare(QLatin1String("true"),
- Qt::CaseInsensitive) == 0);
- QLoggingRule rule(pattern, enabled);
- if (rule.flags != 0)
+ const QStringRef valueStr = line.midRef(equalPos + 1);
+ int value = -1;
+ if (valueStr == QLatin1String("true"))
+ value = 1;
+ else if (valueStr == QLatin1String("false"))
+ value = 0;
+ QLoggingRule rule(pattern, (value == 1));
+ if (rule.flags != 0 && (value != -1))
_rules.append(rule);
else
warnMsg("Ignoring malformed logging rule: '%s'", line.toUtf8().constData());
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index dfb897c0fd..7debf0d774 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -435,10 +435,10 @@ static inline UINT inputTimerMask()
UINT result = QS_TIMER | QS_INPUT | QS_RAWINPUT;
// QTBUG 28513, QTBUG-29097, QTBUG-29435: QS_TOUCH, QS_POINTER became part of
// QS_INPUT in Windows Kit 8. They should not be used when running on pre-Windows 8.
-#if defined(_MSC_VER) && _MSC_VER >= 1700
+#if WINVER > 0x0602
if (QSysInfo::WindowsVersion < QSysInfo::WV_WINDOWS8)
result &= ~(QS_TOUCH | QS_POINTER);
-#endif // _MSC_VER >= 1700
+#endif // WINVER > 0x0602
return result;
}
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 623662a628..437205bf92 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -44,6 +44,7 @@
#include <QtCore/qthreadstorage.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
+#include <QtCore/QThread>
QT_BEGIN_NAMESPACE
@@ -52,6 +53,11 @@ static inline QString keyBase()
return QStringLiteral("%1%2%3");
}
+static inline QByteArray threadBaseName()
+{
+ return QByteArrayLiteral("QtThread-");
+}
+
static QString qt_convertJString(jstring string)
{
QJNIEnvironmentPrivate env;
@@ -179,7 +185,10 @@ QJNIEnvironmentPrivate::QJNIEnvironmentPrivate()
{
JavaVM *vm = QtAndroidPrivate::javaVM();
if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
- if (vm->AttachCurrentThread(&jniEnv, 0) != JNI_OK)
+ const qulonglong id = reinterpret_cast<qulonglong>(QThread::currentThreadId());
+ const QByteArray threadName = threadBaseName() + QByteArray::number(id);
+ JavaVMAttachArgs args = { JNI_VERSION_1_6, threadName, Q_NULLPTR };
+ if (vm->AttachCurrentThread(&jniEnv, &args) != JNI_OK)
return;
}
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index e89d6396f6..43e2b5c15b 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -273,7 +273,15 @@ bool QLibraryPrivate::unload_sys()
# else
if (dlclose(pHnd)) {
# endif
+# if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in
+ char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance
+ if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative"
+ return true;
+ errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName)
+ .arg(QLatin1String(error));
+# else
errorString = QLibrary::tr("Cannot unload library %1: %2").arg(fileName).arg(qdlerror());
+# endif
return false;
}
#endif
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index 0f305b79af..fe5beb1c01 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -216,9 +216,9 @@ QMutex::~QMutex()
*/
void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
{
- if (fastTryLock())
+ QMutexData *current;
+ if (fastTryLock(current))
return;
- QMutexData *current = d_ptr.loadAcquire();
if (QT_PREPEND_NAMESPACE(isRecursive)(current))
static_cast<QRecursiveMutexPrivate *>(current)->lock(-1);
else
@@ -250,9 +250,9 @@ void QMutex::lock() QT_MUTEX_LOCK_NOEXCEPT
*/
bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
{
- if (fastTryLock())
+ QMutexData *current;
+ if (fastTryLock(current))
return true;
- QMutexData *current = d_ptr.loadAcquire();
if (QT_PREPEND_NAMESPACE(isRecursive)(current))
return static_cast<QRecursiveMutexPrivate *>(current)->lock(timeout);
else
@@ -268,9 +268,9 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
*/
void QMutex::unlock() Q_DECL_NOTHROW
{
- if (fastTryUnlock())
+ QMutexData *current;
+ if (fastTryUnlock(current))
return;
- QMutexData *current = d_ptr.loadAcquire();
if (QT_PREPEND_NAMESPACE(isRecursive)(current))
static_cast<QRecursiveMutexPrivate *>(current)->unlock();
else
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 0bca0def22..0ecc96a9b1 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -86,6 +86,12 @@ private:
inline bool fastTryUnlock() Q_DECL_NOTHROW {
return d_ptr.testAndSetRelease(dummyLocked(), 0);
}
+ inline bool fastTryLock(QMutexData *&current) Q_DECL_NOTHROW {
+ return d_ptr.testAndSetAcquire(0, dummyLocked(), current);
+ }
+ inline bool fastTryUnlock(QMutexData *&current) Q_DECL_NOTHROW {
+ return d_ptr.testAndSetRelease(dummyLocked(), 0, current);
+ }
void lockInternal() QT_MUTEX_LOCK_NOEXCEPT;
bool lockInternal(int timeout) QT_MUTEX_LOCK_NOEXCEPT;
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index b0a6971964..0a2f7a9e53 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -462,7 +462,7 @@ inline int QByteArray::capacity() const
inline void QByteArray::reserve(int asize)
{
if (d->ref.isShared() || uint(asize) + 1u > d->alloc) {
- reallocData(uint(asize) + 1u, d->detachFlags() | Data::CapacityReserved);
+ reallocData(qMax(uint(size()), uint(asize)) + 1u, d->detachFlags() | Data::CapacityReserved);
} else {
// cannot set unconditionally, since d could be the shared_null or
// otherwise static
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 01faad6f2d..79365b11b1 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -559,11 +559,13 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l)
}
}
- // we'll read uc[offset..offset+7] (16 bytes) and c[offset-8..offset+7] (16 bytes)
+# ifdef Q_PROCESSOR_X86_64
+ enum { MaxTailLength = 7 };
+ // we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes)
if (uc + offset + 7 < e) {
- // same, but we'll throw away half the data
- __m128i chunk = _mm_loadu_si128((__m128i*)(c + offset - 8));
- __m128i secondHalf = _mm_unpackhi_epi8(chunk, nullmask);
+ // same, but we're using an 8-byte load
+ __m128i chunk = _mm_cvtsi64_si128(*(long long *)(c + offset));
+ __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask);
__m128i ucdata = _mm_loadu_si128((__m128i*)(uc + offset));
__m128i result = _mm_cmpeq_epi16(secondHalf, ucdata);
@@ -577,6 +579,10 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l)
// still matched
offset += 8;
}
+# else
+ // 32-bit, we can't do MOVQ to load 8 bytes
+ enum { MaxTailLength = 15 };
+# endif
// reset uc and c
uc += offset;
@@ -584,7 +590,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l)
# ifdef Q_COMPILER_LAMBDA
const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); };
- return UnrollTailLoop<7>::exec(e - uc, 0, lambda, lambda);
+ return UnrollTailLoop<MaxTailLength>::exec(e - uc, 0, lambda, lambda);
# endif
#endif
@@ -5320,7 +5326,7 @@ int QString::localeAwareCompare(const QString &other) const
return localeAwareCompare_helper(constData(), length(), other.constData(), other.length());
}
-#if defined(QT_USE_ICU)
+#if defined(QT_USE_ICU) && !defined(Q_OS_WIN32) && !defined(Q_OS_WINCE) && !defined (Q_OS_MAC)
Q_GLOBAL_STATIC(QThreadStorage<QCollator>, defaultCollator)
#endif
diff --git a/src/gui/accessible/accessible.pri b/src/gui/accessible/accessible.pri
index 615323dbec..86ed4c3a71 100644
--- a/src/gui/accessible/accessible.pri
+++ b/src/gui/accessible/accessible.pri
@@ -16,4 +16,6 @@ contains(QT_CONFIG, accessibility) {
HEADERS += accessible/qaccessiblebridge.h
SOURCES += accessible/qaccessiblebridge.cpp
+
+ OBJECTIVE_SOURCES += accessible/qaccessiblecache_mac.mm
}
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index 7713bcb358..f7a4a53716 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -600,8 +600,6 @@ QAccessible::RootObjectHandler QAccessible::installRootObjectHandler(RootObjectH
return old;
}
-Q_GLOBAL_STATIC(QAccessibleCache, qAccessibleCache)
-
/*!
If a QAccessibleInterface implementation exists for the given \a object,
this function returns a pointer to the implementation; otherwise it
@@ -625,8 +623,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
if (!object)
return 0;
- if (Id id = qAccessibleCache->objectToId.value(object))
- return qAccessibleCache->interfaceForId(id);
+ if (Id id = QAccessibleCache::instance()->objectToId.value(object))
+ return QAccessibleCache::instance()->interfaceForId(id);
// Create a QAccessibleInterface for the object class. Start by the most
// derived class and walk up the class hierarchy.
@@ -638,8 +636,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
for (int i = qAccessibleFactories()->count(); i > 0; --i) {
InterfaceFactory factory = qAccessibleFactories()->at(i - 1);
if (QAccessibleInterface *iface = factory(cn, object)) {
- qAccessibleCache->insert(object, iface);
- Q_ASSERT(qAccessibleCache->objectToId.contains(object));
+ QAccessibleCache::instance()->insert(object, iface);
+ Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(object));
return iface;
}
}
@@ -661,8 +659,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
if (factory) {
QAccessibleInterface *result = factory->create(cn, object);
if (result) { // Need this condition because of QDesktopScreenWidget
- qAccessibleCache->insert(object, result);
- Q_ASSERT(qAccessibleCache->objectToId.contains(object));
+ QAccessibleCache::instance()->insert(object, result);
+ Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(object));
}
return result;
}
@@ -674,8 +672,8 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
#ifndef QT_NO_ACCESSIBILITY
if (object == qApp) {
QAccessibleInterface *appInterface = new QAccessibleApplication;
- qAccessibleCache->insert(object, appInterface);
- Q_ASSERT(qAccessibleCache->objectToId.contains(qApp));
+ QAccessibleCache::instance()->insert(object, appInterface);
+ Q_ASSERT(QAccessibleCache::instance()->objectToId.contains(qApp));
return appInterface;
}
#endif
@@ -700,7 +698,7 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
QAccessible::Id QAccessible::registerAccessibleInterface(QAccessibleInterface *iface)
{
Q_ASSERT(iface);
- return qAccessibleCache->insert(iface->object(), iface);
+ return QAccessibleCache::instance()->insert(iface->object(), iface);
}
/*!
@@ -710,7 +708,7 @@ QAccessible::Id QAccessible::registerAccessibleInterface(QAccessibleInterface *i
*/
void QAccessible::deleteAccessibleInterface(Id id)
{
- qAccessibleCache->deleteInterface(id);
+ QAccessibleCache::instance()->deleteInterface(id);
}
/*!
@@ -718,7 +716,7 @@ void QAccessible::deleteAccessibleInterface(Id id)
*/
QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface)
{
- Id id = qAccessibleCache->idToInterface.key(iface);
+ Id id = QAccessibleCache::instance()->idToInterface.key(iface);
if (!id)
id = registerAccessibleInterface(iface);
return id;
@@ -731,7 +729,7 @@ QAccessible::Id QAccessible::uniqueId(QAccessibleInterface *iface)
*/
QAccessibleInterface *QAccessible::accessibleInterface(Id id)
{
- return qAccessibleCache->idToInterface.value(id);
+ return QAccessibleCache::instance()->idToInterface.value(id);
}
diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp
index fe66c6e19d..09c155515e 100644
--- a/src/gui/accessible/qaccessiblecache.cpp
+++ b/src/gui/accessible/qaccessiblecache.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -49,6 +49,13 @@ QT_BEGIN_NAMESPACE
\brief Maintains a cache of accessible interfaces.
*/
+Q_GLOBAL_STATIC(QAccessibleCache, qAccessibleCache)
+
+QAccessibleCache *QAccessibleCache::instance()
+{
+ return qAccessibleCache;
+}
+
/*
The ID is always in the range [INT_MAX+1, UINT_MAX].
This makes it easy on windows to reserve the positive integer range
@@ -113,6 +120,10 @@ void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj)
if (obj)
objectToId.remove(obj);
delete iface;
+
+#ifdef Q_OS_MACX
+ removeCocoaElement(id);
+#endif
}
QT_END_NAMESPACE
diff --git a/src/gui/accessible/qaccessiblecache_mac.mm b/src/gui/accessible/qaccessiblecache_mac.mm
new file mode 100644
index 0000000000..861423af7d
--- /dev/null
+++ b/src/gui/accessible/qaccessiblecache_mac.mm
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** 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 "qaccessiblecache_p.h"
+
+#ifdef Q_OS_OSX
+
+QT_BEGIN_NAMESPACE
+
+void QAccessibleCache::insertElement(QAccessible::Id axid, QCocoaAccessibleElement *element) const
+{
+ cocoaElements[axid] = element;
+}
+
+void QAccessibleCache::removeCocoaElement(QAccessible::Id axid)
+{
+ QCocoaAccessibleElement *element = elementForId(axid);
+ [element invalidate];
+ cocoaElements.remove(axid);
+}
+
+QCocoaAccessibleElement *QAccessibleCache::elementForId(QAccessible::Id axid) const
+{
+ return cocoaElements.value(axid);
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/accessible/qaccessiblecache_p.h b/src/gui/accessible/qaccessiblecache_p.h
index 32f9c443ba..30b023cfbd 100644
--- a/src/gui/accessible/qaccessiblecache_p.h
+++ b/src/gui/accessible/qaccessiblecache_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -42,24 +42,42 @@
#ifndef QACCESSIBLECACHE_P
#define QACCESSIBLECACHE_P
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qglobal.h>
#include <QtCore/qobject.h>
#include <QtCore/qhash.h>
#include "qaccessible.h"
-QT_BEGIN_NAMESPACE
+Q_FORWARD_DECLARE_OBJC_CLASS(QCocoaAccessibleElement);
+QT_BEGIN_NAMESPACE
-class QAccessibleCache :public QObject
+class Q_GUI_EXPORT QAccessibleCache :public QObject
{
Q_OBJECT
public:
+ static QAccessibleCache *instance();
QAccessibleInterface *interfaceForId(QAccessible::Id id) const;
QAccessible::Id insert(QObject *object, QAccessibleInterface *iface) const;
void deleteInterface(QAccessible::Id id, QObject *obj = 0);
+#ifdef Q_OS_OSX
+ QCocoaAccessibleElement *elementForId(QAccessible::Id axid) const;
+ void insertElement(QAccessible::Id axid, QCocoaAccessibleElement *element) const;
+#endif
+
private Q_SLOTS:
void objectDestroyed(QObject *obj);
@@ -69,6 +87,11 @@ private:
mutable QHash<QAccessible::Id, QAccessibleInterface *> idToInterface;
mutable QHash<QObject *, QAccessible::Id> objectToId;
+#ifdef Q_OS_OSX
+ void removeCocoaElement(QAccessible::Id axid);
+ mutable QHash<QAccessible::Id, QCocoaAccessibleElement *> cocoaElements;
+#endif
+
friend class QAccessible;
friend class QAccessibleInterface;
};
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index e3ec216f9b..b1707e1eef 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -16,7 +16,7 @@ qhp.QtGui.indexTitle = Qt GUI
qhp.QtGui.indexRoot =
qhp.QtGui.filterAttributes = qtgui $QT_VERSION qtrefdoc
-qhp.QtGui.customFilters.Qt.name = Qtgui $QT_VERSION
+qhp.QtGui.customFilters.Qt.name = QtGui $QT_VERSION
qhp.QtGui.customFilters.Qt.filterAttributes = qtgui $QT_VERSION
qhp.QtGui.subprojects = classes
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index d22c380145..0e05a617e1 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -122,22 +122,40 @@
- \section1 OpenGL and OpenGL ES integration
-
- QWindow supports rendering using desktop OpenGL, OpenGL ES 1.1 and
- OpenGL ES 2.0, depending on what the platform supports. OpenGL
- rendering is enabled by setting the QWindow's surface type to
- QSurface::OpenGLSurface, choosing the format attributes with
- QSurfaceFormat, and then creating a QOpenGLContext to manage
- the native OpenGL context. In addition, Qt has QOpenGLPaintDevice,
- which enables the use of OpenGL accelerated QPainter rendering, as well as
- convenience classes that simplify the writing of OpenGL code and hides the
- complexities of extension handling and the differences between OpenGL ES 2
- and desktop OpenGL. The convenience classes include QOpenGLFunctions that
- lets an application use all the OpenGL ES 2 functions on desktop OpenGL
- without having to manually resolve the OpenGL function pointers and some
- classes that wrap native OpenGL resources in a simpler Qt API:
- QOpenGLBuffer, QOpenGLFramebufferObject, and QOpenGLShaderProgram.
+ \section1 OpenGL and OpenGL ES Integration
+
+ QWindow supports rendering using OpenGL and OpenGL ES, depending
+ on what the platform supports. OpenGL rendering is enabled by
+ setting the QWindow's surface type to QSurface::OpenGLSurface,
+ choosing the format attributes with QSurfaceFormat, and then
+ creating a QOpenGLContext to manage the native OpenGL context. In
+ addition, Qt has QOpenGLPaintDevice, which enables the use of
+ OpenGL accelerated QPainter rendering, as well as convenience
+ classes that simplify the writing of OpenGL code and hides the
+ complexities of extension handling and the differences between
+ OpenGL ES 2 and desktop OpenGL. The convenience classes include
+ QOpenGLFunctions that lets an application use all the OpenGL ES 2
+ functions on desktop OpenGL without having to manually resolve the
+ OpenGL function pointers, thus allowing cross-platform development
+ of applications targeting mobile or embedded devices, and some
+ classes that wrap native OpenGL functionality in a simpler Qt API:
+
+ \list
+ \li QOpenGLBuffer
+ \li QOpenGLFramebufferObject
+ \li QOpenGLShaderProgram
+ \li QOpenGLTexture
+ \li QOpenGLDebugLogger
+ \li QOpenGLTimerQuery
+ \li QOpenGLVertexArrayObject
+ \endlist
+
+ Finally, in order to provide better support for the newer versions
+ (3.0 and higher) of OpenGL, a versioned function wrapper mechanism
+ is also available: The QOpenGLFunction_N_N family of classes
+ expose all the functions in a given OpenGL version and profile,
+ allowing easy development of desktop applications relying on
+ modern, desktop-only OpenGL features.
For more information, see the \l {OpenGL Window Example}.
@@ -147,7 +165,7 @@
A \l {QWindow} created with the \l {QSurface::OpenGLSurface} can
be used in combination with \l QPainter and \l QOpenGLPaintDevice
- to have OpenGL hardware accellerated 2D graphics, by sacrificing
+ to have OpenGL hardware accelerated 2D graphics, by sacrificing
some of the visual quality.
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index f083245809..6af692984a 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -10,6 +10,10 @@ QMAKE_DOCS = $$PWD/doc/qtgui.qdocconf
MODULE_PLUGIN_TYPES = \
platforms \
+ platformthemes \
+ platforminputcontexts \
+ generic \
+ iconengines \
imageformats
# This is here only because the platform plugin is no module, obviously.
@@ -67,14 +71,7 @@ contains(QT_CONFIG, angle) {
!isEmpty(QMAKE_LIBDIR_EGL): CMAKE_EGL_LIBDIR += $$cmakeTargetPath($$QMAKE_LIBDIR_EGL)
}
- contains(QT_CONFIG, opengles1) {
- !isEmpty(QMAKE_INCDIR_OPENGL_ES1): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES1)
- CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES1)
- CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES1)
- !isEmpty(QMAKE_LIBDIR_OPENGL_ES1): CMAKE_OPENGL_LIBDIR = $$cmakePortablePaths($$QMAKE_LIBDIR_OPENGL_ES1)
- CMAKE_GL_HEADER_NAME = GLES/gl.h
- CMAKE_QT_OPENGL_IMPLEMENTATION = GLES
- } else:contains(QT_CONFIG, opengles2) {
+ contains(QT_CONFIG, opengles2) {
!isEmpty(QMAKE_INCDIR_OPENGL_ES2): CMAKE_GL_INCDIRS = $$cmakeTargetPaths($$QMAKE_INCDIR_OPENGL_ES2)
CMAKE_OPENGL_INCDIRS = $$cmakePortablePaths($$QMAKE_INCDIR_OPENGL_ES2)
CMAKE_OPENGL_LIBS = $$cmakeProcessLibs($$QMAKE_LIBS_OPENGL_ES2)
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index a19eebfb7c..bdedc9d75f 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1609,14 +1609,17 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv
void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *e)
{
QEvent::Type type;
- // move first
Qt::MouseButtons stateChange = e->buttons ^ buttons;
- const bool frameStrut = e->type == QWindowSystemInterfacePrivate::FrameStrutMouse;
if (e->globalPos != QGuiApplicationPrivate::lastCursorPosition && (stateChange != Qt::NoButton)) {
- QWindowSystemInterfacePrivate::MouseEvent * newMouseEvent =
- new QWindowSystemInterfacePrivate::MouseEvent(e->window.data(), e->timestamp, e->type, e->localPos, e->globalPos, e->buttons, e->modifiers);
- QWindowSystemInterfacePrivate::windowSystemEventQueue.prepend(newMouseEvent); // just in case the move triggers a new event loop
- stateChange = Qt::NoButton;
+ // A mouse event should not change both position and buttons at the same time. Instead we
+ // should first send a move event followed by a button changed event. Since this is not the case
+ // with the current event, we fake a move-only event that we recurse and process first. This
+ // will update the global mouse position and cause the second event to be a button only event.
+ QWindowSystemInterfacePrivate::MouseEvent moveEvent(e->window.data(),
+ e->timestamp, e->type, e->localPos, e->globalPos, buttons, e->modifiers);
+ processMouseEvent(&moveEvent);
+ Q_ASSERT(e->globalPos == QGuiApplicationPrivate::lastCursorPosition);
+ // continue with processing mouse button change event
}
QWindow *window = e->window.data();
@@ -1635,6 +1638,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
Qt::MouseButton button = Qt::NoButton;
bool doubleClick = false;
+ const bool frameStrut = e->type == QWindowSystemInterfacePrivate::FrameStrutMouse;
if (QGuiApplicationPrivate::lastCursorPosition != globalPoint) {
type = frameStrut ? QEvent::NonClientAreaMouseMove : QEvent::MouseMove;
@@ -3002,6 +3006,7 @@ void QGuiApplication::sync()
&& QGuiApplicationPrivate::platform_integration->hasCapability(QPlatformIntegration::SyncState)) {
QGuiApplicationPrivate::platform_integration->sync();
QCoreApplication::processEvents();
+ QWindowSystemInterface::flushWindowSystemEvents();
}
}
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 4569457a20..59cdabbc0f 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -238,9 +238,9 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \li SaveAs \li \li Ctrl+Shift+S \li \li Ctrl+Shift+S
\row \li New \li Ctrl+N \li Ctrl+N \li Ctrl+N \li Ctrl+N
\row \li Delete \li Del \li Del, Meta+D \li Del, Ctrl+D \li Del, Ctrl+D
- \row \li Cut \li Ctrl+X, Shift+Del \li Ctrl+X \li Ctrl+X, F20, Shift+Del \li Ctrl+X, F20, Shift+Del
+ \row \li Cut \li Ctrl+X, Shift+Del \li Ctrl+X, Meta+K \li Ctrl+X, F20, Shift+Del \li Ctrl+X, F20, Shift+Del
\row \li Copy \li Ctrl+C, Ctrl+Ins \li Ctrl+C \li Ctrl+C, F16, Ctrl+Ins \li Ctrl+C, F16, Ctrl+Ins
- \row \li Paste \li Ctrl+V, Shift+Ins \li Ctrl+V \li Ctrl+V, F18, Shift+Ins \li Ctrl+V, F18, Shift+Ins
+ \row \li Paste \li Ctrl+V, Shift+Ins \li Ctrl+V, Meta+Y \li Ctrl+V, F18, Shift+Ins \li Ctrl+V, F18, Shift+Ins
\row \li Preferences \li \li Ctrl+, \li \li
\row \li Undo \li Ctrl+Z, Alt+Backspace \li Ctrl+Z \li Ctrl+Z, F14 \li Ctrl+Z, F14
\row \li Redo \li Ctrl+Y, Shift+Ctrl+Z, Alt+Shift+Backspace \li Ctrl+Shift+Z \li Ctrl+Shift+Z \li Ctrl+Shift+Z
@@ -263,13 +263,13 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \li Bold \li Ctrl+B \li Ctrl+B \li Ctrl+B \li Ctrl+B
\row \li Italic \li Ctrl+I \li Ctrl+I \li Ctrl+I \li Ctrl+I
\row \li Underline \li Ctrl+U \li Ctrl+U \li Ctrl+U \li Ctrl+U
- \row \li MoveToNextChar \li Right \li Right \li Right \li Right
- \row \li MoveToPreviousChar \li Left \li Left \li Left \li Left
+ \row \li MoveToNextChar \li Right \li Right, Meta+F \li Right \li Right
+ \row \li MoveToPreviousChar \li Left \li Left, Meta+B \li Left \li Left
\row \li MoveToNextWord \li Ctrl+Right \li Alt+Right \li Ctrl+Right \li Ctrl+Right
\row \li MoveToPreviousWord \li Ctrl+Left \li Alt+Left \li Ctrl+Left \li Ctrl+Left
- \row \li MoveToNextLine \li Down \li Down \li Down \li Down
- \row \li MoveToPreviousLine \li Up \li Up \li Up \li Up
- \row \li MoveToNextPage \li PgDown \li PgDown, Alt+PgDown, Meta+Down, Meta+PgDown\li PgDown \li PgDown
+ \row \li MoveToNextLine \li Down \li Down, Meta+N \li Down \li Down
+ \row \li MoveToPreviousLine \li Up \li Up, Meta+P \li Up \li Up
+ \row \li MoveToNextPage \li PgDown \li PgDown, Alt+PgDown, Meta+Down, Meta+PgDown, Meta+V \li PgDown \li PgDown
\row \li MoveToPreviousPage \li PgUp \li PgUp, Alt+PgUp, Meta+Up, Meta+PgUp \li PgUp \li PgUp
\row \li MoveToStartOfLine \li Home \li Ctrl+Left, Meta+Left \li Home \li Home
\row \li MoveToEndOfLine \li End \li Ctrl+Right, Meta+Right \li End, Ctrl+E \li End, Ctrl+E
@@ -296,7 +296,7 @@ void Q_GUI_EXPORT qt_set_sequence_auto_mnemonic(bool b) { qt_sequence_no_mnemoni
\row \li DeleteEndOfLine \li (none) \li (none) \li Ctrl+K \li Ctrl+K
\row \li DeleteCompleteLine \li (none) \li (none) \li Ctrl+U \li Ctrl+U
\row \li InsertParagraphSeparator \li Enter \li Enter \li Enter \li Enter
- \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter \li Shift+Enter \li Shift+Enter
+ \row \li InsertLineSeparator \li Shift+Enter \li Meta+Enter, Meta+O \li Shift+Enter \li Shift+Enter
\endtable
Note that, since the key sequences used for the standard shortcuts differ
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index e258218e85..7382d63a06 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -230,6 +230,7 @@ public:
};
static QThreadStorage<QGuiGLThreadContext *> qwindow_context_storage;
+static QOpenGLContext *global_share_context = 0;
#ifndef QT_NO_DEBUG
QHash<QOpenGLContext *, bool> QOpenGLContextPrivate::makeCurrentTracker;
@@ -330,6 +331,25 @@ QOpenGLContext *QOpenGLContextPrivate::setCurrentContext(QOpenGLContext *context
return previous;
}
+/*!
+ \internal
+
+ This function is used by the Qt WebEngine to set up context sharing
+ across multiple windows. Do not use it for any other purpose.
+*/
+void QOpenGLContextPrivate::setGlobalShareContext(QOpenGLContext *context)
+{
+ global_share_context = context;
+}
+
+/*!
+ \internal
+*/
+QOpenGLContext *QOpenGLContextPrivate::globalShareContext()
+{
+ return global_share_context;
+}
+
int QOpenGLContextPrivate::maxTextureSize()
{
if (max_texture_size != -1)
@@ -597,7 +617,8 @@ QOpenGLFunctions *QOpenGLContext::functions() const
Returns a pointer to an object that provides access to all functions for
the version and profile of this context. Before using any of the functions
- they must be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions().
+ they must be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions()
+ with this context being the current context.
Usually one would use the template version of this function to automatically
have the result cast to the correct type.
@@ -609,7 +630,7 @@ QOpenGLFunctions *QOpenGLContext::functions() const
qWarning() << "Could not obtain required OpenGL context version";
exit(1);
}
- funcs->initializeOpenGLFunctions(context);
+ funcs->initializeOpenGLFunctions();
\endcode
It is possible to request a functions object for a different version and profile
@@ -639,8 +660,9 @@ QOpenGLFunctions *QOpenGLContext::functions() const
/*!
Returns a pointer to an object that provides access to all functions for the
- \a versionProfile of the current context. Before using any of the functions they must
- be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions().
+ \a versionProfile of this context. Before using any of the functions they must
+ be initialized by calling QAbstractOpenGLFunctions::initializeOpenGLFunctions()
+ with this context being the current context.
Usually one would use the template version of this function to automatically
have the result cast to the correct type.
@@ -1010,7 +1032,6 @@ void *QOpenGLContext::openGLModuleHandle()
\value DesktopGL Desktop OpenGL
\value GLES2 OpenGL ES 2.0 or higher
- \value GLES1 OpenGL ES 1.x
\since 5.3
*/
@@ -1038,8 +1059,6 @@ QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType()
return QGuiApplicationPrivate::instance()->platformIntegration()->openGLModuleType();
#elif defined(QT_OPENGL_ES_2)
return GLES2;
-#elif defined(QT_OPENGL_ES)
- return GLES1;
#else
return DesktopGL;
#endif
diff --git a/src/gui/kernel/qopenglcontext.h b/src/gui/kernel/qopenglcontext.h
index 06a7b723b4..fce983f975 100644
--- a/src/gui/kernel/qopenglcontext.h
+++ b/src/gui/kernel/qopenglcontext.h
@@ -196,8 +196,7 @@ public:
enum OpenGLModuleType {
DesktopGL,
- GLES2,
- GLES1
+ GLES2
};
static OpenGLModuleType openGLModuleType();
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index 23c13b2e24..b21ff67068 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -244,6 +244,9 @@ public:
static QOpenGLContext *setCurrentContext(QOpenGLContext *context);
+ static void setGlobalShareContext(QOpenGLContext *context);
+ static QOpenGLContext *globalShareContext();
+
int maxTextureSize();
static QOpenGLContextPrivate *get(QOpenGLContext *context)
diff --git a/src/gui/kernel/qplatformmenu.h b/src/gui/kernel/qplatformmenu.h
index 9326a2b3a1..19e2d9bccf 100644
--- a/src/gui/kernel/qplatformmenu.h
+++ b/src/gui/kernel/qplatformmenu.h
@@ -66,7 +66,11 @@ Q_OBJECT
public:
// copied from, and must stay in sync with, QAction menu roles.
enum MenuRole { NoRole = 0, TextHeuristicRole, ApplicationSpecificRole, AboutQtRole,
- AboutRole, PreferencesRole, QuitRole };
+ AboutRole, PreferencesRole, QuitRole,
+ // However these roles are private, perhaps temporarily.
+ // They could be added as public QAction roles if necessary.
+ CutRole, CopyRole, PasteRole, SelectAllRole,
+ RoleCount };
virtual void setTag(quintptr tag) = 0;
virtual quintptr tag()const = 0;
diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp
index 05ab2f15ba..d3d3d3c222 100644
--- a/src/gui/kernel/qplatformtheme.cpp
+++ b/src/gui/kernel/qplatformtheme.cpp
@@ -178,12 +178,13 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::Close, 0, Qt::CTRL | Qt::Key_W, KB_Win | KB_X11},
{QKeySequence::Save, 1, Qt::CTRL | Qt::Key_S, KB_All},
{QKeySequence::New, 1, Qt::CTRL | Qt::Key_N, KB_All},
- {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac},
{QKeySequence::Delete, 0, Qt::CTRL | Qt::Key_D, KB_X11}, //emacs (line edit only)
{QKeySequence::Delete, 1, Qt::Key_Delete, KB_All},
+ {QKeySequence::Delete, 0, Qt::META | Qt::Key_D, KB_Mac},
{QKeySequence::Cut, 1, Qt::CTRL | Qt::Key_X, KB_All},
{QKeySequence::Cut, 0, Qt::SHIFT | Qt::Key_Delete, KB_Win | KB_X11}, //## Check if this should work on mac
{QKeySequence::Cut, 0, Qt::Key_F20, KB_X11}, //Cut on sun keyboards
+ {QKeySequence::Cut, 0, Qt::META | Qt::Key_K, KB_Mac},
{QKeySequence::Copy, 0, Qt::CTRL | Qt::Key_Insert, KB_X11 | KB_Win},
{QKeySequence::Copy, 1, Qt::CTRL | Qt::Key_C, KB_All},
{QKeySequence::Copy, 0, Qt::Key_F16, KB_X11}, //Copy on sun keyboards
@@ -191,6 +192,7 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::Paste, 1, Qt::CTRL | Qt::Key_V, KB_All},
{QKeySequence::Paste, 0, Qt::SHIFT | Qt::Key_Insert, KB_Win | KB_X11},
{QKeySequence::Paste, 0, Qt::Key_F18, KB_X11}, //Paste on sun keyboards
+ {QKeySequence::Paste, 0, Qt::META | Qt::Key_Y, KB_Mac},
{QKeySequence::Undo, 0, Qt::ALT | Qt::Key_Backspace, KB_Win},
{QKeySequence::Undo, 1, Qt::CTRL | Qt::Key_Z, KB_All},
{QKeySequence::Undo, 0, Qt::Key_F14, KB_X11}, //Undo on sun keyboards
@@ -241,16 +243,21 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::Bold, 1, Qt::CTRL | Qt::Key_B, KB_All},
{QKeySequence::Italic, 0, Qt::CTRL | Qt::Key_I, KB_All},
{QKeySequence::Underline, 1, Qt::CTRL | Qt::Key_U, KB_All},
- {QKeySequence::MoveToNextChar, 0, Qt::Key_Right, KB_All},
- {QKeySequence::MoveToPreviousChar, 0, Qt::Key_Left, KB_All},
+ {QKeySequence::MoveToNextChar, 1, Qt::Key_Right, KB_All},
+ {QKeySequence::MoveToNextChar, 0, Qt::META | Qt::Key_F, KB_Mac},
+ {QKeySequence::MoveToPreviousChar, 1, Qt::Key_Left, KB_All},
+ {QKeySequence::MoveToPreviousChar, 0, Qt::META | Qt::Key_B, KB_Mac},
{QKeySequence::MoveToNextWord, 0, Qt::ALT | Qt::Key_Right, KB_Mac},
{QKeySequence::MoveToNextWord, 0, Qt::CTRL | Qt::Key_Right, KB_Win | KB_X11},
{QKeySequence::MoveToPreviousWord, 0, Qt::ALT | Qt::Key_Left, KB_Mac},
{QKeySequence::MoveToPreviousWord, 0, Qt::CTRL | Qt::Key_Left, KB_Win | KB_X11},
- {QKeySequence::MoveToNextLine, 0, Qt::Key_Down, KB_All},
- {QKeySequence::MoveToPreviousLine, 0, Qt::Key_Up, KB_All},
+ {QKeySequence::MoveToNextLine, 1, Qt::Key_Down, KB_All},
+ {QKeySequence::MoveToNextLine, 0, Qt::META | Qt::Key_N, KB_Mac},
+ {QKeySequence::MoveToPreviousLine, 1, Qt::Key_Up, KB_All},
+ {QKeySequence::MoveToPreviousLine, 0, Qt::META | Qt::Key_P, KB_Mac},
{QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_PageDown, KB_Mac},
{QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_Down, KB_Mac},
+ {QKeySequence::MoveToNextPage, 0, Qt::META | Qt::Key_V, KB_Mac},
{QKeySequence::MoveToNextPage, 0, Qt::ALT | Qt::Key_PageDown, KB_Mac },
{QKeySequence::MoveToNextPage, 1, Qt::Key_PageDown, KB_All},
{QKeySequence::MoveToPreviousPage, 0, Qt::META | Qt::Key_PageUp, KB_Mac},
@@ -265,9 +272,9 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::MoveToEndOfLine, 0, Qt::Key_End, KB_Win | KB_X11},
{QKeySequence::MoveToEndOfLine, 0, Qt::CTRL + Qt::Key_E, KB_X11},
{QKeySequence::MoveToStartOfBlock, 0, Qt::META | Qt::Key_A, KB_Mac},
- {QKeySequence::MoveToStartOfBlock, 0, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only
+ {QKeySequence::MoveToStartOfBlock, 1, Qt::ALT | Qt::Key_Up, KB_Mac}, //mac only
{QKeySequence::MoveToEndOfBlock, 0, Qt::META | Qt::Key_E, KB_Mac},
- {QKeySequence::MoveToEndOfBlock, 0, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only
+ {QKeySequence::MoveToEndOfBlock, 1, Qt::ALT | Qt::Key_Down, KB_Mac}, //mac only
{QKeySequence::MoveToStartOfDocument, 1, Qt::CTRL | Qt::Key_Up, KB_Mac},
{QKeySequence::MoveToStartOfDocument, 0, Qt::CTRL | Qt::Key_Home, KB_Win | KB_X11},
{QKeySequence::MoveToStartOfDocument, 0, Qt::Key_Home, KB_Mac},
@@ -290,10 +297,10 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::SelectEndOfLine, 0, Qt::META | Qt::SHIFT | Qt::Key_Right, KB_Mac},
{QKeySequence::SelectEndOfLine, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Right, KB_Mac },
{QKeySequence::SelectEndOfLine, 0, Qt::SHIFT | Qt::Key_End, KB_Win | KB_X11},
+ {QKeySequence::SelectStartOfBlock, 1, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only
{QKeySequence::SelectStartOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_A, KB_Mac},
- {QKeySequence::SelectStartOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Up, KB_Mac}, //mac only
+ {QKeySequence::SelectEndOfBlock, 1, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only
{QKeySequence::SelectEndOfBlock, 0, Qt::META | Qt::SHIFT | Qt::Key_E, KB_Mac},
- {QKeySequence::SelectEndOfBlock, 0, Qt::ALT | Qt::SHIFT | Qt::Key_Down, KB_Mac}, //mac only
{QKeySequence::SelectStartOfDocument, 1, Qt::CTRL | Qt::SHIFT | Qt::Key_Up, KB_Mac},
{QKeySequence::SelectStartOfDocument, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_Home, KB_Win | KB_X11},
{QKeySequence::SelectStartOfDocument, 0, Qt::SHIFT | Qt::Key_Home, KB_Mac},
@@ -311,6 +318,7 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = {
{QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_Return, KB_Mac},
{QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Enter, KB_All},
{QKeySequence::InsertLineSeparator, 0, Qt::SHIFT | Qt::Key_Return, KB_All},
+ {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_O, KB_Mac},
{QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac},
{QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac},
{QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_Gnome | KB_KDE | KB_Mac},
diff --git a/src/gui/kernel/qstylehints.cpp b/src/gui/kernel/qstylehints.cpp
index e1468942af..ac638f4905 100644
--- a/src/gui/kernel/qstylehints.cpp
+++ b/src/gui/kernel/qstylehints.cpp
@@ -163,7 +163,7 @@ void QStyleHints::setStartDragDistance(int startDragDistance)
and the current position (e.g. in the mouse move event) is \c currentPos,
you can find out if a drag should be started with code like this:
- \snippet code/src_gui_kernel_qguiapplication.cpp 6
+ \snippet code/src_gui_kernel_qapplication.cpp 6
\sa startDragTime(), QPoint::manhattanLength(), {Drag and Drop}
*/
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 13da58e391..6dcc3df166 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1751,7 +1751,10 @@ void QWindow::showFullScreen()
{
setWindowState(Qt::WindowFullScreen);
setVisible(true);
+#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen
+ // activating it here before libscreen activates it causes problems
requestActivate();
+#endif
}
/*!
diff --git a/src/gui/opengl/qopenglbuffer.cpp b/src/gui/opengl/qopenglbuffer.cpp
index 2e1a4577f6..a8a2255104 100644
--- a/src/gui/opengl/qopenglbuffer.cpp
+++ b/src/gui/opengl/qopenglbuffer.cpp
@@ -333,20 +333,18 @@ void QOpenGLBuffer::destroy()
bool QOpenGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
- if (QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) {
- Q_D(QOpenGLBuffer);
- if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
- return false;
- while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state.
- d->funcs->glGetBufferSubData(d->type, offset, count, data);
- return d->funcs->glGetError() == GL_NO_ERROR;
- }
+ Q_D(QOpenGLBuffer);
+ if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
+ return false;
+ while (d->funcs->glGetError() != GL_NO_ERROR) ; // Clear error state.
+ d->funcs->glGetBufferSubData(d->type, offset, count, data);
+ return d->funcs->glGetError() == GL_NO_ERROR;
#else
Q_UNUSED(offset);
Q_UNUSED(data);
Q_UNUSED(count);
-#endif
return false;
+#endif
}
/*!
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 55edaf7baf..92a7330d6c 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -890,6 +890,8 @@ QOpenGLFramebufferObject::QOpenGLFramebufferObject(const QSize &size, Attachment
QOpenGLFramebufferObject::~QOpenGLFramebufferObject()
{
Q_D(QOpenGLFramebufferObject);
+ if (isBound())
+ release();
if (d->texture_guard)
d->texture_guard->free();
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index ef0ef6d103..eb2c98e1f5 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -256,7 +256,7 @@ QOpenGLExtensions::QOpenGLExtensions(QOpenGLContext *context)
static int qt_gl_resolve_features()
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
- if (ctx->isES() && QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) {
+ if (ctx->isES()) {
// OpenGL ES 2
int features = QOpenGLFunctions::Multitexture |
QOpenGLFunctions::Shaders |
@@ -277,26 +277,6 @@ static int qt_gl_resolve_features()
features |= QOpenGLFunctions::NPOTTextures |
QOpenGLFunctions::NPOTTextureRepeat;
return features;
- } else if (ctx->isES()) {
- // OpenGL ES 1
- int features = QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_OES_framebuffer_object"))
- features |= QOpenGLFunctions::Framebuffers;
- if (extensions.match("GL_OES_blend_equation_separate"))
- features |= QOpenGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_OES_blend_func_separate"))
- features |= QOpenGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_OES_blend_subtract"))
- features |= QOpenGLFunctions::BlendSubtract;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QOpenGLFunctions::NPOTTextures;
- return features;
} else {
// OpenGL
int features = 0;
diff --git a/src/gui/opengl/qopengltextureblitter.cpp b/src/gui/opengl/qopengltextureblitter.cpp
index 9710f1677c..efe769badf 100644
--- a/src/gui/opengl/qopengltextureblitter.cpp
+++ b/src/gui/opengl/qopengltextureblitter.cpp
@@ -282,6 +282,12 @@ bool QOpenGLTextureBlitter::create()
return true;
}
+bool QOpenGLTextureBlitter::isCreated() const
+{
+ Q_D(const QOpenGLTextureBlitter);
+ return d->program;
+}
+
void QOpenGLTextureBlitter::destroy()
{
Q_D(QOpenGLTextureBlitter);
diff --git a/src/gui/opengl/qopengltextureblitter_p.h b/src/gui/opengl/qopengltextureblitter_p.h
index b2ccc13391..c1dcaf5700 100644
--- a/src/gui/opengl/qopengltextureblitter_p.h
+++ b/src/gui/opengl/qopengltextureblitter_p.h
@@ -62,6 +62,7 @@ public:
};
bool create();
+ bool isCreated() const;
void destroy();
void bind();
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index 22ca35a8c3..9dfd5b2a6f 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -44,6 +44,7 @@
#include <QtCore/private/qobject_p.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglfunctions.h>
+#include <QtGui/qoffscreensurface.h>
#include <QtGui/qopenglfunctions_3_0.h>
#include <QtGui/qopenglfunctions_3_2_core.h>
@@ -359,9 +360,17 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject()
Q_D(QOpenGLVertexArrayObject);
QOpenGLContext *oldContext = 0;
+ QScopedPointer<QOffscreenSurface> offscreenSurface;
if (d->context && ctx && d->context != ctx) {
oldContext = ctx;
- if (d->context->makeCurrent(oldContext->surface())) {
+ // Cannot just make the current surface current again with another context.
+ // The format may be incompatible and some platforms (iOS) may impose
+ // restrictions on using a window with different contexts. Create an
+ // offscreen surface (a pbuffer or a hidden window) instead to be safe.
+ offscreenSurface.reset(new QOffscreenSurface);
+ offscreenSurface->setFormat(d->context->format());
+ offscreenSurface->create();
+ if (d->context->makeCurrent(offscreenSurface.data())) {
ctx = d->context;
} else {
qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to make VAO's context current");
diff --git a/src/gui/painting/qdrawhelper_neon_p.h b/src/gui/painting/qdrawhelper_neon_p.h
index cad6fe22e9..2313664846 100644
--- a/src/gui/painting/qdrawhelper_neon_p.h
+++ b/src/gui/painting/qdrawhelper_neon_p.h
@@ -96,14 +96,14 @@ void qt_alphamapblit_quint16_neon(QRasterBuffer *rasterBuffer,
const QClipData *clip);
void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
int const_alpha);
void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
diff --git a/src/gui/painting/qpagedpaintdevice.cpp b/src/gui/painting/qpagedpaintdevice.cpp
index 18ba964a26..e102b7fae3 100644
--- a/src/gui/painting/qpagedpaintdevice.cpp
+++ b/src/gui/painting/qpagedpaintdevice.cpp
@@ -66,6 +66,15 @@ QPagedPaintDevice::QPagedPaintDevice()
}
/*!
+ \internal
+ Constructs a new paged paint device with the derived private class.
+*/
+QPagedPaintDevice::QPagedPaintDevice(QPagedPaintDevicePrivate *dd)
+ : d(dd)
+{
+}
+
+/*!
Destroys the object.
*/
QPagedPaintDevice::~QPagedPaintDevice()
@@ -74,6 +83,15 @@ QPagedPaintDevice::~QPagedPaintDevice()
}
/*!
+ \internal
+ Returns the QPagedPaintDevicePrivate.
+*/
+QPagedPaintDevicePrivate *QPagedPaintDevice::dd()
+{
+ return d;
+}
+
+/*!
\enum QPagedPaintDevice::PageSize
This enum type lists the available page sizes as defined in the Postscript
@@ -296,6 +314,134 @@ QPagedPaintDevice::Margins QPagedPaintDevice::margins() const
}
/*!
+ \since 5.3
+
+ Sets the 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 QPagedPaintDevice::setPageLayout(const QPageLayout &newPageLayout)
+{
+ return d->setPageLayout(newPageLayout);
+}
+
+/*!
+ \since 5.3
+
+ Sets the 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.
+
+ \sa pageLayout()
+*/
+
+bool QPagedPaintDevice::setPageSize(const QPageSize &pageSize)
+{
+ return d->setPageSize(pageSize);
+}
+
+/*!
+ \since 5.3
+
+ Sets the 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 QPagedPaintDevice::setPageOrientation(QPageLayout::Orientation orientation)
+{
+ return d->setPageOrientation(orientation);
+}
+
+/*!
+ \since 5.3
+
+ Set the 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 QPagedPaintDevice::setPageMargins(const QMarginsF &margins)
+{
+ return d->setPageMargins(margins);
+}
+
+/*!
+ \since 5.3
+
+ Set the 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 QPagedPaintDevice::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
+{
+ return d->setPageMargins(margins, units);
+}
+
+/*!
+ \since 5.3
+
+ 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 QPagedPaintDevice setters or use setPageLayout().
+
+ \sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins()
+*/
+
+QPageLayout QPagedPaintDevice::pageLayout() const
+{
+ return d->pageLayout();
+}
+
+/*!
\internal
Returns the internal device page layout.
diff --git a/src/gui/painting/qpagedpaintdevice.h b/src/gui/painting/qpagedpaintdevice.h
index 6d4c422a95..dec56f9ce8 100644
--- a/src/gui/painting/qpagedpaintdevice.h
+++ b/src/gui/painting/qpagedpaintdevice.h
@@ -43,6 +43,7 @@
#define QPAGEDPAINTDEVICE_H
#include <QtGui/qpaintdevice.h>
+#include <QtGui/qpagelayout.h>
QT_BEGIN_NAMESPACE
@@ -51,7 +52,6 @@ QT_BEGIN_NAMESPACE
#endif
class QPagedPaintDevicePrivate;
-class QPageLayout;
class Q_GUI_EXPORT QPagedPaintDevice : public QPaintDevice
{
@@ -214,6 +214,14 @@ public:
Envelope10 = Comm10E
};
+ // ### Qt6 Make these virtual
+ 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;
+
virtual void setPageSize(PageSize size);
PageSize pageSize() const;
@@ -232,6 +240,8 @@ public:
Margins margins() const;
protected:
+ QPagedPaintDevice(QPagedPaintDevicePrivate *dd);
+ QPagedPaintDevicePrivate *dd();
QPageLayout devicePageLayout() const;
QPageLayout &devicePageLayout();
friend class QPagedPaintDevicePrivate;
diff --git a/src/gui/painting/qpagedpaintdevice_p.h b/src/gui/painting/qpagedpaintdevice_p.h
index da58951dc7..2321494779 100644
--- a/src/gui/painting/qpagedpaintdevice_p.h
+++ b/src/gui/painting/qpagedpaintdevice_p.h
@@ -55,8 +55,6 @@
#include <qpagedpaintdevice.h>
-#include "qpagelayout.h"
-
QT_BEGIN_NAMESPACE
class Q_GUI_EXPORT QPagedPaintDevicePrivate
@@ -71,6 +69,46 @@ public:
{
}
+ virtual ~QPagedPaintDevicePrivate()
+ {
+ }
+
+ // ### Qt6 Remove these and make public class methods virtual
+ virtual bool setPageLayout(const QPageLayout &newPageLayout)
+ {
+ m_pageLayout = newPageLayout;
+ return m_pageLayout.isEquivalentTo(newPageLayout);;
+ }
+
+ virtual bool setPageSize(const QPageSize &pageSize)
+ {
+ m_pageLayout.setPageSize(pageSize);
+ return m_pageLayout.pageSize().isEquivalentTo(pageSize);
+ }
+
+ virtual bool setPageOrientation(QPageLayout::Orientation orientation)
+ {
+ m_pageLayout.setOrientation(orientation);
+ return m_pageLayout.orientation() == orientation;
+ }
+
+ virtual bool setPageMargins(const QMarginsF &margins)
+ {
+ return setPageMargins(margins, m_pageLayout.units());
+ }
+
+ virtual bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
+ {
+ m_pageLayout.setUnits(units);
+ m_pageLayout.setMargins(margins);
+ return m_pageLayout.margins() == margins && m_pageLayout.units() == units;
+ }
+
+ virtual QPageLayout pageLayout() const
+ {
+ return m_pageLayout;
+ }
+
static inline QPagedPaintDevicePrivate *get(QPagedPaintDevice *pd) { return pd->d; }
QPageLayout m_pageLayout;
diff --git a/src/gui/painting/qpagelayout.cpp b/src/gui/painting/qpagelayout.cpp
index 7ae117e423..15d98828bf 100644
--- a/src/gui/painting/qpagelayout.cpp
+++ b/src/gui/painting/qpagelayout.cpp
@@ -50,11 +50,6 @@
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)
{
@@ -221,10 +216,10 @@ bool QPageLayoutPrivate::isValid() const
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()));
+ m_margins = QMarginsF(qBound(m_minMargins.left(), margins.left(), m_maxMargins.left()),
+ qBound(m_minMargins.top(), margins.top(), m_maxMargins.top()),
+ qBound(m_minMargins.right(), margins.right(), m_maxMargins.right()),
+ qBound(m_minMargins.bottom(), margins.bottom(), m_maxMargins.bottom()));
}
QMarginsF QPageLayoutPrivate::margins(QPageLayout::Unit units) const
@@ -380,8 +375,8 @@ QPageLayout::QPageLayout()
margins allowed by the page size.
*/
-QPageLayout::QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation,
- const QMarginsF &margins, QPageLayout::Unit units,
+QPageLayout::QPageLayout(const QPageSize &pageSize, Orientation orientation,
+ const QMarginsF &margins, Unit units,
const QMarginsF &minMargins)
: d(new QPageLayoutPrivate(pageSize, orientation, margins, units, minMargins))
{
@@ -429,24 +424,38 @@ QPageLayout &QPageLayout::operator=(const QPageLayout &other)
*/
/*!
- Returns \c true if this page layout is equal to the \a other page layout,
+ \relates QPageLayout
+
+ Returns \c true if page layout \a lhs is equal to page layout \a rhs,
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()
+ \sa QPageLayout::isEquivalentTo()
*/
-bool QPageLayout::operator==(const QPageLayout &other) const
+bool operator==(const QPageLayout &lhs, const QPageLayout &rhs)
{
- if (d && other.d)
- return (*d == *other.d);
- return (d == other.d);
+ return lhs.d == rhs.d || *lhs.d == *rhs.d;
}
/*!
+ \fn bool operator!=(const QPageLayout &lhs, const QPageLayout &rhs)
+ \relates QPageLayout
+
+ Returns \c true if page layout \a lhs is not equal to page layout \a rhs,
+ i.e. if any of the attributes differ.
+
+ 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 QPageLayout::isEquivalentTo()
+*/
+
+/*!
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.
*/
@@ -469,8 +478,9 @@ bool QPageLayout::isValid() const
Sets a page layout mode to \a mode.
*/
-void QPageLayout::setMode(QPageLayout::Mode mode)
+void QPageLayout::setMode(Mode mode)
{
+ d.detach();
d->m_mode = mode;
}
@@ -499,6 +509,7 @@ void QPageLayout::setPageSize(const QPageSize &pageSize, const QMarginsF &minMar
{
if (!pageSize.isValid())
return;
+ d.detach();
d->m_pageSize = pageSize;
d->m_fullSize = d->fullSizeUnits(d->m_units);
d->setDefaultMargins(minMargins);
@@ -524,9 +535,10 @@ QPageSize QPageLayout::pageSize() const
the minimum margins.
*/
-void QPageLayout::setOrientation(QPageLayout::Orientation orientation)
+void QPageLayout::setOrientation(Orientation orientation)
{
if (orientation != d->m_orientation) {
+ d.detach();
d->m_orientation = orientation;
d->m_fullSize = d->fullSizeUnits(d->m_units);
// Adust the max margins to reflect change in max page size
@@ -551,9 +563,10 @@ QPageLayout::Orientation QPageLayout::orientation() const
Sets the \a units used to define the page layout.
*/
-void QPageLayout::setUnits(QPageLayout::Unit units)
+void QPageLayout::setUnits(Unit units)
{
if (units != d->m_units) {
+ d.detach();
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);
@@ -589,7 +602,8 @@ QPageLayout::Unit QPageLayout::units() const
bool QPageLayout::setMargins(const QMarginsF &margins)
{
- if (d->m_mode == QPageLayout::FullPageMode) {
+ if (d->m_mode == FullPageMode) {
+ d.detach();
d->m_margins = margins;
return true;
} else if (margins.left() >= d->m_minMargins.left()
@@ -600,6 +614,7 @@ bool QPageLayout::setMargins(const QMarginsF &margins)
&& margins.right() <= d->m_maxMargins.right()
&& margins.top() <= d->m_maxMargins.top()
&& margins.bottom() <= d->m_maxMargins.bottom()) {
+ d.detach();
d->m_margins = margins;
return true;
}
@@ -624,8 +639,9 @@ bool QPageLayout::setMargins(const QMarginsF &margins)
bool QPageLayout::setLeftMargin(qreal leftMargin)
{
- if (d->m_mode == QPageLayout::FullPageMode
+ if (d->m_mode == FullPageMode
|| (leftMargin >= d->m_minMargins.left() && leftMargin <= d->m_maxMargins.left())) {
+ d.detach();
d->m_margins.setLeft(leftMargin);
return true;
}
@@ -650,8 +666,9 @@ bool QPageLayout::setLeftMargin(qreal leftMargin)
bool QPageLayout::setRightMargin(qreal rightMargin)
{
- if (d->m_mode == QPageLayout::FullPageMode
+ if (d->m_mode == FullPageMode
|| (rightMargin >= d->m_minMargins.right() && rightMargin <= d->m_maxMargins.right())) {
+ d.detach();
d->m_margins.setRight(rightMargin);
return true;
}
@@ -676,8 +693,9 @@ bool QPageLayout::setRightMargin(qreal rightMargin)
bool QPageLayout::setTopMargin(qreal topMargin)
{
- if (d->m_mode == QPageLayout::FullPageMode
+ if (d->m_mode == FullPageMode
|| (topMargin >= d->m_minMargins.top() && topMargin <= d->m_maxMargins.top())) {
+ d.detach();
d->m_margins.setTop(topMargin);
return true;
}
@@ -702,8 +720,9 @@ bool QPageLayout::setTopMargin(qreal topMargin)
bool QPageLayout::setBottomMargin(qreal bottomMargin)
{
- if (d->m_mode == QPageLayout::FullPageMode
+ if (d->m_mode == FullPageMode
|| (bottomMargin >= d->m_minMargins.bottom() && bottomMargin <= d->m_maxMargins.bottom())) {
+ d.detach();
d->m_margins.setBottom(bottomMargin);
return true;
}
@@ -727,7 +746,7 @@ QMarginsF QPageLayout::margins() const
\sa setMargins(), margins()
*/
-QMarginsF QPageLayout::margins(QPageLayout::Unit units) const
+QMarginsF QPageLayout::margins(Unit units) const
{
return d->margins(units);
}
@@ -769,6 +788,7 @@ QMargins QPageLayout::marginsPixels(int resolution) const
void QPageLayout::setMinimumMargins(const QMarginsF &minMargins)
{
+ d.detach();
d->setDefaultMargins(minMargins);
}
@@ -823,7 +843,7 @@ QRectF QPageLayout::fullRect() const
\sa paintRect()
*/
-QRectF QPageLayout::fullRect(QPageLayout::Unit units) const
+QRectF QPageLayout::fullRect(Unit units) const
{
return isValid() ? d->fullRect(units) : QRect();
}
@@ -881,13 +901,13 @@ QRectF QPageLayout::paintRect() const
the margins must be manually managed.
*/
-QRectF QPageLayout::paintRect(QPageLayout::Unit units) const
+QRectF QPageLayout::paintRect(Unit units) const
{
if (!isValid())
return QRectF();
if (units == d->m_units)
return d->paintRect();
- return d->m_mode == QPageLayout::FullPageMode ? d->fullRect(units)
+ return d->m_mode == FullPageMode ? d->fullRect(units)
: d->fullRect(units) - d->margins(units);
}
@@ -905,7 +925,7 @@ QRect QPageLayout::paintRectPoints() const
{
if (!isValid())
return QRect();
- return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPoints()
+ return d->m_mode == FullPageMode ? d->fullRectPoints()
: d->fullRectPoints() - d->marginsPoints();
}
@@ -923,7 +943,7 @@ QRect QPageLayout::paintRectPixels(int resolution) const
{
if (!isValid())
return QRect();
- return d->m_mode == QPageLayout::FullPageMode ? d->fullRectPixels(resolution)
+ return d->m_mode == FullPageMode ? d->fullRectPixels(resolution)
: d->fullRectPixels(resolution) - d->marginsPixels(resolution);
}
diff --git a/src/gui/painting/qpagelayout.h b/src/gui/painting/qpagelayout.h
index 86e430e311..e63f6f4d39 100644
--- a/src/gui/painting/qpagelayout.h
+++ b/src/gui/painting/qpagelayout.h
@@ -79,8 +79,8 @@ public:
};
QPageLayout();
- QPageLayout(const QPageSize &pageSize, QPageLayout::Orientation orientation,
- const QMarginsF &margins, QPageLayout::Unit units = QPageLayout::Point,
+ QPageLayout(const QPageSize &pageSize, Orientation orientation,
+ const QMarginsF &margins, Unit units = Point,
const QMarginsF &minMargins = QMarginsF(0, 0, 0, 0));
QPageLayout(const QPageLayout &other);
~QPageLayout();
@@ -92,23 +92,23 @@ public:
void swap(QPageLayout &other) { d.swap(other.d); }
- bool operator==(const QPageLayout &other) const;
+ friend Q_GUI_EXPORT bool operator==(const QPageLayout &lhs, const QPageLayout &rhs);
bool isEquivalentTo(const QPageLayout &other) const;
bool isValid() const;
- void setMode(QPageLayout::Mode mode);
- QPageLayout::Mode mode() const;
+ void setMode(Mode mode);
+ 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 setOrientation(Orientation orientation);
+ Orientation orientation() const;
- void setUnits(QPageLayout::Unit units);
- QPageLayout::Unit units() const;
+ void setUnits(Unit units);
+ Unit units() const;
bool setMargins(const QMarginsF &margins);
bool setLeftMargin(qreal leftMargin);
@@ -117,7 +117,7 @@ public:
bool setBottomMargin(qreal bottomMargin);
QMarginsF margins() const;
- QMarginsF margins(QPageLayout::Unit units) const;
+ QMarginsF margins(Unit units) const;
QMargins marginsPoints() const;
QMargins marginsPixels(int resolution) const;
@@ -126,22 +126,26 @@ public:
QMarginsF maximumMargins() const;
QRectF fullRect() const;
- QRectF fullRect(QPageLayout::Unit units) const;
+ QRectF fullRect(Unit units) const;
QRect fullRectPoints() const;
QRect fullRectPixels(int resolution) const;
QRectF paintRect() const;
- QRectF paintRect(QPageLayout::Unit units) const;
+ QRectF paintRect(Unit units) const;
QRect paintRectPoints() const;
QRect paintRectPixels(int resolution) const;
private:
friend class QPageLayoutPrivate;
- QSharedDataPointer<QPageLayoutPrivate> d;
+ QExplicitlySharedDataPointer<QPageLayoutPrivate> d;
};
Q_DECLARE_SHARED(QPageLayout)
+Q_GUI_EXPORT bool operator==(const QPageLayout &lhs, const QPageLayout &rhs);
+inline bool operator!=(const QPageLayout &lhs, const QPageLayout &rhs)
+{ return !operator==(lhs, rhs); }
+
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageLayout &pageLayout);
#endif
diff --git a/src/gui/painting/qpagesize.cpp b/src/gui/painting/qpagesize.cpp
index 6698d77bbd..978aef905a 100644
--- a/src/gui/painting/qpagesize.cpp
+++ b/src/gui/painting/qpagesize.cpp
@@ -389,18 +389,17 @@ static const StandardPageSize qt_pageSizes[] = {
};
static const int pageSizesCount = int(sizeof(qt_pageSizes) / sizeof(qt_pageSizes[0]));
+Q_STATIC_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
// 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;
@@ -422,7 +421,6 @@ static QPageSize::PageSizeId qt_idForPpdKey(const QString &ppdKey, QSize *match
// 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;
@@ -536,7 +534,6 @@ Q_GUI_EXPORT qreal qt_pixelMultiplier(int 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);
@@ -595,7 +592,6 @@ static QSizeF qt_convertPointsToUnits(const QSize &size, QPageSize::Unit units)
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);
@@ -619,7 +615,6 @@ static QPageSize::PageSizeId qt_idForPointSize(const QSize &size, QPageSize::Siz
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)
@@ -687,7 +682,6 @@ static QPageSize::PageSizeId qt_idForSize(const QSizeF &size, QPageSize::Unit un
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) {
@@ -834,7 +828,6 @@ 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;
@@ -1138,7 +1131,7 @@ QPageSize::QPageSize()
be valid. Use the custom size constructor instead.
*/
-QPageSize::QPageSize(QPageSize::PageSizeId pageSize)
+QPageSize::QPageSize(PageSizeId pageSize)
: d(new QPageSizePrivate(pageSize))
{
}
@@ -1181,7 +1174,7 @@ QPageSize::QPageSize(const QSize &pointSize, const QString &name, SizeMatchPolic
"Custom (width x height)" where the size is expressed in units provided.
*/
-QPageSize::QPageSize(const QSizeF &size, QPageSize::Unit units,
+QPageSize::QPageSize(const QSizeF &size, Unit units,
const QString &name, SizeMatchPolicy matchPolicy)
: d(new QPageSizePrivate(size, units, name, matchPolicy))
{
@@ -1262,16 +1255,25 @@ QPageSize &QPageSize::operator=(const QPageSize &other)
*/
/*!
- 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.
+ \relates QPageSize
+
+ Returns \c true if page size \a lhs is equal to page size \a rhs,
+ i.e. if the page sizes have the same attributes. Current
+ attributes are size and name.
*/
-bool QPageSize::operator==(const QPageSize &other) const
+bool operator==(const QPageSize &lhs, const QPageSize &rhs)
{
- if (d == other.d)
- return true;
- return d && other.d && *d == *other.d;
+ return lhs.d == rhs.d || *lhs.d == *rhs.d;
}
+/*!
+ \fn bool operator!=(const QPageSize &lhs, const QPageSize &rhs)
+ \relates QPageSize
+
+ Returns \c true if page size \a lhs is unequal to page size \a
+ rhs, i.e. if the page size has different attributes. Current
+ attributes are size and name.
+*/
/*!
Returns \c true if this page is equivalent to the \a other page, i.e. if the
@@ -1341,7 +1343,7 @@ QString QPageSize::name() const
QPageSize::PageSizeId QPageSize::id() const
{
- return isValid() ? d->m_id : QPageSize::Custom;
+ return isValid() ? d->m_id : Custom;
}
/*!
@@ -1359,7 +1361,7 @@ int QPageSize::windowsId() const
{
if (!isValid())
return 0;
- return d->m_windowsId > 0 ? d->m_windowsId : QPageSize::windowsId(d->m_id);
+ return d->m_windowsId > 0 ? d->m_windowsId : windowsId(d->m_id);
}
/*!
@@ -1399,7 +1401,7 @@ QSizeF QPageSize::definitionSize() const
QPageSize::Unit QPageSize::definitionUnits() const
{
- return isValid() ? d->m_units : QPageSize::Unit(-1);
+ return isValid() ? d->m_units : Unit(-1);
}
/*!
@@ -1408,7 +1410,7 @@ QPageSize::Unit QPageSize::definitionUnits() const
If the QPageSize is invalid then the QSizeF will be invalid.
*/
-QSizeF QPageSize::size(QPageSize::Unit units) const
+QSizeF QPageSize::size(Unit units) const
{
return isValid() ? d->size(units) : QSize();
}
@@ -1441,7 +1443,7 @@ QSize QPageSize::sizePixels(int resolution) const
If the QPageSize is invalid then the QRect will be invalid.
*/
-QRectF QPageSize::rect(QPageSize::Unit units) const
+QRectF QPageSize::rect(Unit units) const
{
return isValid() ? QRectF(QPointF(0, 0), d->size(units)) : QRectF();
}
@@ -1476,11 +1478,10 @@ QRect QPageSize::rectPixels(int resolution) const
If the QPageSize is invalid then the key will be empty.
*/
-QString QPageSize::key(QPageSize::PageSizeId pageSizeId)
+QString QPageSize::key(PageSizeId pageSizeId)
{
- if (pageSizeId < QPageSize::PageSizeId(0) || pageSizeId > QPageSize::LastPageSize)
+ if (pageSizeId < PageSizeId(0) || pageSizeId > LastPageSize)
return QString();
- Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
return QString::fromUtf8(qt_pageSizes[pageSizeId].mediaOption);
}
@@ -1496,249 +1497,249 @@ static QString msgImperialPageSizeInch(int width, int height)
If the QPageSize is invalid then the name will be empty.
*/
-QString QPageSize::name(QPageSize::PageSizeId pageSizeId)
+QString QPageSize::name(PageSizeId pageSizeId)
{
- if (pageSizeId < QPageSize::PageSizeId(0) || pageSizeId > QPageSize::LastPageSize)
+ if (pageSizeId < PageSizeId(0) || pageSizeId > LastPageSize)
return QString();
switch (pageSizeId) {
- case QPageSize::A0:
+ case A0:
return QCoreApplication::translate("QPageSize", "A0");
- case QPageSize::A1:
+ case A1:
return QCoreApplication::translate("QPageSize", "A1");
- case QPageSize::A2:
+ case A2:
return QCoreApplication::translate("QPageSize", "A2");
- case QPageSize::A3:
+ case A3:
return QCoreApplication::translate("QPageSize", "A3");
- case QPageSize::A4:
+ case A4:
return QCoreApplication::translate("QPageSize", "A4");
- case QPageSize::A5:
+ case A5:
return QCoreApplication::translate("QPageSize", "A5");
- case QPageSize::A6:
+ case A6:
return QCoreApplication::translate("QPageSize", "A6");
- case QPageSize::A7:
+ case A7:
return QCoreApplication::translate("QPageSize", "A7");
- case QPageSize::A8:
+ case A8:
return QCoreApplication::translate("QPageSize", "A8");
- case QPageSize::A9:
+ case A9:
return QCoreApplication::translate("QPageSize", "A9");
- case QPageSize::A10:
+ case A10:
return QCoreApplication::translate("QPageSize", "A10");
- case QPageSize::B0:
+ case B0:
return QCoreApplication::translate("QPageSize", "B0");
- case QPageSize::B1:
+ case B1:
return QCoreApplication::translate("QPageSize", "B1");
- case QPageSize::B2:
+ case B2:
return QCoreApplication::translate("QPageSize", "B2");
- case QPageSize::B3:
+ case B3:
return QCoreApplication::translate("QPageSize", "B3");
- case QPageSize::B4:
+ case B4:
return QCoreApplication::translate("QPageSize", "B4");
- case QPageSize::B5:
+ case B5:
return QCoreApplication::translate("QPageSize", "B5");
- case QPageSize::B6:
+ case B6:
return QCoreApplication::translate("QPageSize", "B6");
- case QPageSize::B7:
+ case B7:
return QCoreApplication::translate("QPageSize", "B7");
- case QPageSize::B8:
+ case B8:
return QCoreApplication::translate("QPageSize", "B8");
- case QPageSize::B9:
+ case B9:
return QCoreApplication::translate("QPageSize", "B9");
- case QPageSize::B10:
+ case B10:
return QCoreApplication::translate("QPageSize", "B10");
- case QPageSize::Executive:
+ case Executive:
return QCoreApplication::translate("QPageSize", "Executive (7.5 x 10 in)");
- case QPageSize::ExecutiveStandard:
+ case ExecutiveStandard:
return QCoreApplication::translate("QPageSize", "Executive (7.25 x 10.5 in)");
- case QPageSize::Folio:
+ case Folio:
return QCoreApplication::translate("QPageSize", "Folio (8.27 x 13 in)");
- case QPageSize::Legal:
+ case Legal:
return QCoreApplication::translate("QPageSize", "Legal");
- case QPageSize::Letter:
+ case Letter:
return QCoreApplication::translate("QPageSize", "Letter / ANSI A");
- case QPageSize::Tabloid:
+ case Tabloid:
return QCoreApplication::translate("QPageSize", "Tabloid / ANSI B");
- case QPageSize::Ledger:
+ case Ledger:
return QCoreApplication::translate("QPageSize", "Ledger / ANSI B");
- case QPageSize::Custom:
+ case Custom:
return QCoreApplication::translate("QPageSize", "Custom");
- case QPageSize::A3Extra:
+ case A3Extra:
return QCoreApplication::translate("QPageSize", "A3 Extra");
- case QPageSize::A4Extra:
+ case A4Extra:
return QCoreApplication::translate("QPageSize", "A4 Extra");
- case QPageSize::A4Plus:
+ case A4Plus:
return QCoreApplication::translate("QPageSize", "A4 Plus");
- case QPageSize::A4Small:
+ case A4Small:
return QCoreApplication::translate("QPageSize", "A4 Small");
- case QPageSize::A5Extra:
+ case A5Extra:
return QCoreApplication::translate("QPageSize", "A5 Extra");
- case QPageSize::B5Extra:
+ case B5Extra:
return QCoreApplication::translate("QPageSize", "B5 Extra");
- case QPageSize::JisB0:
+ case JisB0:
return QCoreApplication::translate("QPageSize", "JIS B0");
- case QPageSize::JisB1:
+ case JisB1:
return QCoreApplication::translate("QPageSize", "JIS B1");
- case QPageSize::JisB2:
+ case JisB2:
return QCoreApplication::translate("QPageSize", "JIS B2");
- case QPageSize::JisB3:
+ case JisB3:
return QCoreApplication::translate("QPageSize", "JIS B3");
- case QPageSize::JisB4:
+ case JisB4:
return QCoreApplication::translate("QPageSize", "JIS B4");
- case QPageSize::JisB5:
+ case JisB5:
return QCoreApplication::translate("QPageSize", "JIS B5");
- case QPageSize::JisB6:
+ case JisB6:
return QCoreApplication::translate("QPageSize", "JIS B6");
- case QPageSize::JisB7:
+ case JisB7:
return QCoreApplication::translate("QPageSize", "JIS B7");
- case QPageSize::JisB8:
+ case JisB8:
return QCoreApplication::translate("QPageSize", "JIS B8");
- case QPageSize::JisB9:
+ case JisB9:
return QCoreApplication::translate("QPageSize", "JIS B9");
- case QPageSize::JisB10:
+ case JisB10:
return QCoreApplication::translate("QPageSize", "JIS B10");
- case QPageSize::AnsiC:
+ case AnsiC:
return QCoreApplication::translate("QPageSize", "ANSI C");
- case QPageSize::AnsiD:
+ case AnsiD:
return QCoreApplication::translate("QPageSize", "ANSI D");
- case QPageSize::AnsiE:
+ case AnsiE:
return QCoreApplication::translate("QPageSize", "ANSI E");
- case QPageSize::LegalExtra:
+ case LegalExtra:
return QCoreApplication::translate("QPageSize", "Legal Extra");
- case QPageSize::LetterExtra:
+ case LetterExtra:
return QCoreApplication::translate("QPageSize", "Letter Extra");
- case QPageSize::LetterPlus:
+ case LetterPlus:
return QCoreApplication::translate("QPageSize", "Letter Plus");
- case QPageSize::LetterSmall:
+ case LetterSmall:
return QCoreApplication::translate("QPageSize", "Letter Small");
- case QPageSize::TabloidExtra:
+ case TabloidExtra:
return QCoreApplication::translate("QPageSize", "Tabloid Extra");
- case QPageSize::ArchA:
+ case ArchA:
return QCoreApplication::translate("QPageSize", "Architect A");
- case QPageSize::ArchB:
+ case ArchB:
return QCoreApplication::translate("QPageSize", "Architect B");
- case QPageSize::ArchC:
+ case ArchC:
return QCoreApplication::translate("QPageSize", "Architect C");
- case QPageSize::ArchD:
+ case ArchD:
return QCoreApplication::translate("QPageSize", "Architect D");
- case QPageSize::ArchE:
+ case ArchE:
return QCoreApplication::translate("QPageSize", "Architect E");
- case QPageSize::Imperial7x9:
+ case Imperial7x9:
return msgImperialPageSizeInch(7, 9);
- case QPageSize::Imperial8x10:
+ case Imperial8x10:
return msgImperialPageSizeInch(8, 10);
- case QPageSize::Imperial9x11:
+ case Imperial9x11:
return msgImperialPageSizeInch(9, 11);
- case QPageSize::Imperial9x12:
+ case Imperial9x12:
return msgImperialPageSizeInch(9, 12);
- case QPageSize::Imperial10x11:
+ case Imperial10x11:
return msgImperialPageSizeInch(10, 11);
- case QPageSize::Imperial10x13:
+ case Imperial10x13:
return msgImperialPageSizeInch(10, 13);
- case QPageSize::Imperial10x14:
+ case Imperial10x14:
return msgImperialPageSizeInch(10, 14);
- case QPageSize::Imperial12x11:
+ case Imperial12x11:
return msgImperialPageSizeInch(12, 11);
- case QPageSize::Imperial15x11:
+ case Imperial15x11:
return msgImperialPageSizeInch(15, 11);
- case QPageSize::Note:
+ case Note:
return QCoreApplication::translate("QPageSize", "Note");
- case QPageSize::Quarto:
+ case Quarto:
return QCoreApplication::translate("QPageSize", "Quarto");
- case QPageSize::Statement:
+ case Statement:
return QCoreApplication::translate("QPageSize", "Statement");
- case QPageSize::SuperA:
+ case SuperA:
return QCoreApplication::translate("QPageSize", "Super A");
- case QPageSize::SuperB:
+ case SuperB:
return QCoreApplication::translate("QPageSize", "Super B");
- case QPageSize::Postcard:
+ case Postcard:
return QCoreApplication::translate("QPageSize", "Postcard");
- case QPageSize::DoublePostcard:
+ case DoublePostcard:
return QCoreApplication::translate("QPageSize", "Double Postcard");
- case QPageSize::Prc16K:
+ case Prc16K:
return QCoreApplication::translate("QPageSize", "PRC 16K");
- case QPageSize::Prc32K:
+ case Prc32K:
return QCoreApplication::translate("QPageSize", "PRC 32K");
- case QPageSize::Prc32KBig:
+ case Prc32KBig:
return QCoreApplication::translate("QPageSize", "PRC 32K Big");
- case QPageSize::FanFoldUS:
+ case FanFoldUS:
return QCoreApplication::translate("QPageSize", "Fan-fold US (14.875 x 11 in)");
- case QPageSize::FanFoldGerman:
+ case FanFoldGerman:
return QCoreApplication::translate("QPageSize", "Fan-fold German (8.5 x 12 in)");
- case QPageSize::FanFoldGermanLegal:
+ case FanFoldGermanLegal:
return QCoreApplication::translate("QPageSize", "Fan-fold German Legal (8.5 x 13 in)");
- case QPageSize::EnvelopeB4:
+ case EnvelopeB4:
return QCoreApplication::translate("QPageSize", "Envelope B4");
- case QPageSize::EnvelopeB5:
+ case EnvelopeB5:
return QCoreApplication::translate("QPageSize", "Envelope B5");
- case QPageSize::EnvelopeB6:
+ case EnvelopeB6:
return QCoreApplication::translate("QPageSize", "Envelope B6");
- case QPageSize::EnvelopeC0:
+ case EnvelopeC0:
return QCoreApplication::translate("QPageSize", "Envelope C0");
- case QPageSize::EnvelopeC1:
+ case EnvelopeC1:
return QCoreApplication::translate("QPageSize", "Envelope C1");
- case QPageSize::EnvelopeC2:
+ case EnvelopeC2:
return QCoreApplication::translate("QPageSize", "Envelope C2");
- case QPageSize::EnvelopeC3:
+ case EnvelopeC3:
return QCoreApplication::translate("QPageSize", "Envelope C3");
- case QPageSize::EnvelopeC4:
+ case EnvelopeC4:
return QCoreApplication::translate("QPageSize", "Envelope C4");
- case QPageSize::EnvelopeC5: // C5E
+ case EnvelopeC5: // C5E
return QCoreApplication::translate("QPageSize", "Envelope C5");
- case QPageSize::EnvelopeC6:
+ case EnvelopeC6:
return QCoreApplication::translate("QPageSize", "Envelope C6");
- case QPageSize::EnvelopeC65:
+ case EnvelopeC65:
return QCoreApplication::translate("QPageSize", "Envelope C65");
- case QPageSize::EnvelopeC7:
+ case EnvelopeC7:
return QCoreApplication::translate("QPageSize", "Envelope C7");
- case QPageSize::EnvelopeDL: // DLE:
+ case EnvelopeDL: // DLE:
return QCoreApplication::translate("QPageSize", "Envelope DL");
- case QPageSize::Envelope9:
+ case Envelope9:
return QCoreApplication::translate("QPageSize", "Envelope US 9");
- case QPageSize::Envelope10: // Comm10E
+ case Envelope10: // Comm10E
return QCoreApplication::translate("QPageSize", "Envelope US 10");
- case QPageSize::Envelope11:
+ case Envelope11:
return QCoreApplication::translate("QPageSize", "Envelope US 11");
- case QPageSize::Envelope12:
+ case Envelope12:
return QCoreApplication::translate("QPageSize", "Envelope US 12");
- case QPageSize::Envelope14:
+ case Envelope14:
return QCoreApplication::translate("QPageSize", "Envelope US 14");
- case QPageSize::EnvelopeMonarch:
+ case EnvelopeMonarch:
return QCoreApplication::translate("QPageSize", "Envelope Monarch");
- case QPageSize::EnvelopePersonal:
+ case EnvelopePersonal:
return QCoreApplication::translate("QPageSize", "Envelope Personal");
- case QPageSize::EnvelopeChou3:
+ case EnvelopeChou3:
return QCoreApplication::translate("QPageSize", "Envelope Chou 3");
- case QPageSize::EnvelopeChou4:
+ case EnvelopeChou4:
return QCoreApplication::translate("QPageSize", "Envelope Chou 4");
- case QPageSize::EnvelopeInvite:
+ case EnvelopeInvite:
return QCoreApplication::translate("QPageSize", "Envelope Invite");
- case QPageSize::EnvelopeItalian:
+ case EnvelopeItalian:
return QCoreApplication::translate("QPageSize", "Envelope Italian");
- case QPageSize::EnvelopeKaku2:
+ case EnvelopeKaku2:
return QCoreApplication::translate("QPageSize", "Envelope Kaku 2");
- case QPageSize::EnvelopeKaku3:
+ case EnvelopeKaku3:
return QCoreApplication::translate("QPageSize", "Envelope Kaku 3");
- case QPageSize::EnvelopePrc1:
+ case EnvelopePrc1:
return QCoreApplication::translate("QPageSize", "Envelope PRC 1");
- case QPageSize::EnvelopePrc2:
+ case EnvelopePrc2:
return QCoreApplication::translate("QPageSize", "Envelope PRC 2");
- case QPageSize::EnvelopePrc3:
+ case EnvelopePrc3:
return QCoreApplication::translate("QPageSize", "Envelope PRC 3");
- case QPageSize::EnvelopePrc4:
+ case EnvelopePrc4:
return QCoreApplication::translate("QPageSize", "Envelope PRC 4");
- case QPageSize::EnvelopePrc5:
+ case EnvelopePrc5:
return QCoreApplication::translate("QPageSize", "Envelope PRC 5");
- case QPageSize::EnvelopePrc6:
+ case EnvelopePrc6:
return QCoreApplication::translate("QPageSize", "Envelope PRC 6");
- case QPageSize::EnvelopePrc7:
+ case EnvelopePrc7:
return QCoreApplication::translate("QPageSize", "Envelope PRC 7");
- case QPageSize::EnvelopePrc8:
+ case EnvelopePrc8:
return QCoreApplication::translate("QPageSize", "Envelope PRC 8");
- case QPageSize::EnvelopePrc9:
+ case EnvelopePrc9:
return QCoreApplication::translate("QPageSize", "Envelope PRC 9");
- case QPageSize::EnvelopePrc10:
+ case EnvelopePrc10:
return QCoreApplication::translate("QPageSize", "Envelope PRC 10");
- case QPageSize::EnvelopeYou4:
+ case EnvelopeYou4:
return QCoreApplication::translate("QPageSize", "Envelope You 4");
}
return QString();
@@ -1754,7 +1755,7 @@ QString QPageSize::name(QPageSize::PageSizeId pageSizeId)
point size of the PageSizeId before using it in any calculations.
*/
-QPageSize::PageSizeId QPageSize::id(const QSize &pointSize, QPageSize::SizeMatchPolicy matchPolicy)
+QPageSize::PageSizeId QPageSize::id(const QSize &pointSize, SizeMatchPolicy matchPolicy)
{
return qt_idForPointSize(pointSize, matchPolicy, 0);
}
@@ -1769,8 +1770,8 @@ QPageSize::PageSizeId QPageSize::id(const QSize &pointSize, QPageSize::SizeMatch
unit size of the PageSizeId before using it in any calculations.
*/
-QPageSize::PageSizeId QPageSize::id(const QSizeF &size, QPageSize::Unit units,
- QPageSize::SizeMatchPolicy matchPolicy)
+QPageSize::PageSizeId QPageSize::id(const QSizeF &size, Unit units,
+ SizeMatchPolicy matchPolicy)
{
return qt_idForSize(size, units, matchPolicy, 0);
}
@@ -1793,9 +1794,8 @@ QPageSize::PageSizeId QPageSize::id(int windowsId)
will be returned.
*/
-int QPageSize::windowsId(QPageSize::PageSizeId pageSizeId)
+int QPageSize::windowsId(PageSizeId pageSizeId)
{
- Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
return qt_pageSizes[pageSizeId].windowsId;
}
@@ -1805,9 +1805,9 @@ int QPageSize::windowsId(QPageSize::PageSizeId pageSizeId)
To obtain the definition units, call QPageSize::definitionUnits().
*/
-QSizeF QPageSize::definitionSize(QPageSize::PageSizeId pageSizeId)
+QSizeF QPageSize::definitionSize(PageSizeId pageSizeId)
{
- if (pageSizeId == QPageSize::Custom)
+ if (pageSizeId == Custom)
return QSizeF();
return qt_definitionSize(pageSizeId);
}
@@ -1818,11 +1818,10 @@ QSizeF QPageSize::definitionSize(QPageSize::PageSizeId pageSizeId)
To obtain the definition size, call QPageSize::definitionSize().
*/
-QPageSize::Unit QPageSize::definitionUnits(QPageSize::PageSizeId pageSizeId)
+QPageSize::Unit QPageSize::definitionUnits(PageSizeId pageSizeId)
{
- if (pageSizeId == QPageSize::Custom)
- return QPageSize::Unit(-1);
- Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
+ if (pageSizeId == Custom)
+ return Unit(-1);
return qt_pageSizes[pageSizeId].definitionUnits;
}
@@ -1830,9 +1829,9 @@ QPageSize::Unit QPageSize::definitionUnits(QPageSize::PageSizeId pageSizeId)
Returns the size of the standard \a pageSizeId in the requested \a units.
*/
-QSizeF QPageSize::size(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units)
+QSizeF QPageSize::size(PageSizeId pageSizeId, Unit units)
{
- if (pageSizeId == QPageSize::Custom)
+ if (pageSizeId == Custom)
return QSizeF();
return qt_unitSize(pageSizeId, units);
}
@@ -1841,11 +1840,10 @@ QSizeF QPageSize::size(QPageSize::PageSizeId pageSizeId, QPageSize::Unit units)
Returns the size of the standard \a pageSizeId in Points.
*/
-QSize QPageSize::sizePoints(QPageSize::PageSizeId pageSizeId)
+QSize QPageSize::sizePoints(PageSizeId pageSizeId)
{
- if (pageSizeId == QPageSize::Custom)
+ if (pageSizeId == Custom)
return QSize();
- Q_ASSERT(pageSizesCount == QPageSize::LastPageSize + 1);
return QSize(qt_pageSizes[pageSizeId].widthPoints, qt_pageSizes[pageSizeId].heightPoints);
}
@@ -1854,11 +1852,11 @@ QSize QPageSize::sizePoints(QPageSize::PageSizeId pageSizeId)
for the given \a resolution.
*/
-QSize QPageSize::sizePixels(QPageSize::PageSizeId pageSizeId, int resolution)
+QSize QPageSize::sizePixels(PageSizeId pageSizeId, int resolution)
{
- if (pageSizeId == QPageSize::Custom)
+ if (pageSizeId == Custom)
return QSize();
- return qt_convertPointsToPixels(QPageSize::sizePoints(pageSizeId), resolution);
+ return qt_convertPointsToPixels(sizePoints(pageSizeId), resolution);
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/painting/qpagesize.h b/src/gui/painting/qpagesize.h
index c8a472747d..ae337a2438 100644
--- a/src/gui/painting/qpagesize.h
+++ b/src/gui/painting/qpagesize.h
@@ -229,13 +229,13 @@ public:
};
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);
+ explicit QPageSize(PageSizeId pageSizeId);
+ explicit QPageSize(const QSize &pointSize,
+ const QString &name = QString(),
+ SizeMatchPolicy matchPolicy = FuzzyMatch);
+ explicit QPageSize(const QSizeF &size, Unit units,
+ const QString &name = QString(),
+ SizeMatchPolicy matchPolicy = FuzzyMatch);
QPageSize(const QPageSize &other);
~QPageSize();
@@ -246,7 +246,7 @@ public:
void swap(QPageSize &other) { d.swap(other.d); }
- bool operator==(const QPageSize &other) const;
+ friend Q_GUI_EXPORT bool operator==(const QPageSize &lhs, const QPageSize &rhs);
bool isEquivalentTo(const QPageSize &other) const;
bool isValid() const;
@@ -254,38 +254,38 @@ public:
QString key() const;
QString name() const;
- QPageSize::PageSizeId id() const;
+ PageSizeId id() const;
int windowsId() const;
QSizeF definitionSize() const;
- QPageSize::Unit definitionUnits() const;
+ Unit definitionUnits() const;
- QSizeF size(QPageSize::Unit units) const;
+ QSizeF size(Unit units) const;
QSize sizePoints() const;
QSize sizePixels(int resolution) const;
- QRectF rect(QPageSize::Unit units) const;
+ QRectF rect(Unit units) const;
QRect rectPoints() const;
QRect rectPixels(int resolution) const;
- static QString key(QPageSize::PageSizeId pageSizeId);
- static QString name(QPageSize::PageSizeId pageSizeId);
+ static QString key(PageSizeId pageSizeId);
+ static QString name(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 PageSizeId id(const QSize &pointSize,
+ SizeMatchPolicy matchPolicy = FuzzyMatch);
+ static PageSizeId id(const QSizeF &size, Unit units,
+ SizeMatchPolicy matchPolicy = FuzzyMatch);
- static QPageSize::PageSizeId id(int windowsId);
- static int windowsId(QPageSize::PageSizeId pageSizeId);
+ static PageSizeId id(int windowsId);
+ static int windowsId(PageSizeId pageSizeId);
- static QSizeF definitionSize(QPageSize::PageSizeId pageSizeId);
- static QPageSize::Unit definitionUnits(QPageSize::PageSizeId pageSizeId);
+ static QSizeF definitionSize(PageSizeId pageSizeId);
+ static Unit definitionUnits(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);
+ static QSizeF size(PageSizeId pageSizeId, Unit units);
+ static QSize sizePoints(PageSizeId pageSizeId);
+ static QSize sizePixels(PageSizeId pageSizeId, int resolution);
private:
friend class QPageSizePrivate;
@@ -298,6 +298,10 @@ private:
Q_DECLARE_SHARED(QPageSize)
+Q_GUI_EXPORT bool operator==(const QPageSize &lhs, const QPageSize &rhs);
+inline bool operator!=(const QPageSize &lhs, const QPageSize &rhs)
+{ return !operator==(lhs, rhs); }
+
#ifndef QT_NO_DEBUG_STREAM
Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QPageSize &pageSize);
#endif
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index 08c8f42fd9..b856d6625c 100644
--- a/src/gui/painting/qpdfwriter.cpp
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -43,6 +43,7 @@
#ifndef QT_NO_PDF
+#include "qpagedpaintdevice_p.h"
#include <QtCore/private/qobject_p.h>
#include "private/qpdf_p.h"
#include <QtCore/qfile.h>
@@ -68,6 +69,64 @@ public:
QFile *output;
};
+class QPdfPagedPaintDevicePrivate : public QPagedPaintDevicePrivate
+{
+public:
+ QPdfPagedPaintDevicePrivate(QPdfWriterPrivate *d)
+ : QPagedPaintDevicePrivate(), pd(d)
+ {}
+
+ virtual ~QPdfPagedPaintDevicePrivate()
+ {}
+
+ bool setPageLayout(const QPageLayout &newPageLayout) Q_DECL_OVERRIDE
+ {
+ // Try to set the paint engine page layout
+ pd->engine->setPageLayout(newPageLayout);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ m_pageLayout = pd->engine->pageLayout();
+ return m_pageLayout.isEquivalentTo(newPageLayout);
+ }
+
+ bool setPageSize(const QPageSize &pageSize) Q_DECL_OVERRIDE
+ {
+ // Try to set the paint engine page size
+ pd->engine->setPageSize(pageSize);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ m_pageLayout = pd->engine->pageLayout();
+ return m_pageLayout.pageSize().isEquivalentTo(pageSize);
+ }
+
+ bool setPageOrientation(QPageLayout::Orientation orientation) Q_DECL_OVERRIDE
+ {
+ // Set the print engine value
+ pd->engine->setPageOrientation(orientation);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ m_pageLayout = pd->engine->pageLayout();
+ return m_pageLayout.orientation() == orientation;
+ }
+
+ bool setPageMargins(const QMarginsF &margins) Q_DECL_OVERRIDE
+ {
+ return setPageMargins(margins, pageLayout().units());
+ }
+
+ bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) Q_DECL_OVERRIDE
+ {
+ // Try to set engine margins
+ pd->engine->setPageMargins(margins, units);
+ // Set QPagedPaintDevice layout to match the current paint engine layout
+ m_pageLayout = pd->engine->pageLayout();
+ return m_pageLayout.margins() == margins && m_pageLayout.units() == units;
+ }
+
+ QPageLayout pageLayout() const Q_DECL_OVERRIDE
+ {
+ return pd->engine->pageLayout();
+ }
+
+ QPdfWriterPrivate *pd;
+};
/*! \class QPdfWriter
\inmodule QtGui
@@ -85,7 +144,8 @@ public:
Constructs a PDF writer that will write the pdf to \a filename.
*/
QPdfWriter::QPdfWriter(const QString &filename)
- : QObject(*new QPdfWriterPrivate)
+ : QObject(*new QPdfWriterPrivate),
+ QPagedPaintDevice(new QPdfPagedPaintDevicePrivate(d_func()))
{
Q_D(QPdfWriter);
@@ -195,7 +255,10 @@ int QPdfWriter::resolution() const
return d->engine->resolution();
}
+// Defined in QPagedPaintDevice but non-virtual, add QPdfWriter specific doc here
+#ifdef Q_QDOC
/*!
+ \fn bool QPdfWriter::setPageLayout(const QPageLayout &newPageLayout)
\since 5.3
Sets the PDF page layout to \a newPageLayout.
@@ -210,17 +273,8 @@ int QPdfWriter::resolution() const
\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);
-}
-
/*!
+ \fn bool QPdfWriter::setPageSize(const QPageSize &pageSize)
\since 5.3
Sets the PDF page size to \a pageSize.
@@ -237,17 +291,8 @@ bool QPdfWriter::setPageLayout(const QPageLayout &newPageLayout)
\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);
-}
-
/*!
+ \fn bool QPdfWriter::setPageOrientation(QPageLayout::Orientation orientation)
\since 5.3
Sets the PDF page \a orientation.
@@ -267,17 +312,8 @@ bool QPdfWriter::setPageSize(const QPageSize &pageSize)
\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;
-}
-
/*!
+ \fn bool QPdfWriter::setPageMargins(const QMarginsF &margins)
\since 5.3
Set the PDF page \a margins in the current page layout units.
@@ -294,17 +330,8 @@ bool QPdfWriter::setPageOrientation(QPageLayout::Orientation orientation)
\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;
-}
-
/*!
+ \fn bool QPdfWriter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
\since 5.3
Set the PDF page \a margins defined in the given \a units.
@@ -321,17 +348,10 @@ bool QPdfWriter::setPageMargins(const QMarginsF &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;
-}
-
/*!
+ \fn QPageLayout QPdfWriter::pageLayout() const
+ \since 5.3
+
Returns the current page layout. Use this method to access the current
QPageSize, QPageLayout::Orientation, QMarginsF, fullRect() and paintRect().
@@ -340,12 +360,7 @@ bool QPdfWriter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit unit
\sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins()
*/
-
-QPageLayout QPdfWriter::pageLayout() const
-{
- Q_D(const QPdfWriter);
- return d->engine->pageLayout();
-}
+#endif
/*!
\reimp
diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h
index fce0b88ea8..747ce380e7 100644
--- a/src/gui/painting/qpdfwriter.h
+++ b/src/gui/painting/qpdfwriter.h
@@ -74,13 +74,16 @@ public:
void setResolution(int resolution);
int resolution() const;
+#ifdef Q_QDOC
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;
+#else
+ using QPagedPaintDevice::setPageSize;
+#endif
void setPageSize(PageSize size);
void setPageSizeMM(const QSizeF &size);
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index 710d84e3aa..6425aa065e 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -247,14 +247,14 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft);
}
- GLuint textureId = toTexture(deviceRegion(region, window));
+ GLuint textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize);
if (!textureId)
return;
funcs->glEnable(GL_BLEND);
funcs->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
+ QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect);
d_ptr->blitter->setSwizzleRB(true);
d_ptr->blitter->blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft);
d_ptr->blitter->setSwizzleRB(false);
@@ -282,6 +282,7 @@ QImage QPlatformBackingStore::toImage() const
backingstore as an OpenGL texture. \a dirtyRegion is the part of the
backingstore which may have changed since the last call to this function. The
caller of this function must ensure that there is a current context.
+ The size of the texture is returned in \a textureSize.
The ownership of the texture is not transferred. The caller must not store
the return value between calls, but instead call this function before each use.
@@ -291,7 +292,7 @@ QImage QPlatformBackingStore::toImage() const
content using toImage() and performs a texture upload.
*/
-GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const
+GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize) const
{
QImage image = toImage();
QSize imageSize = image.size();
@@ -325,7 +326,8 @@ GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion) const
funcs->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageSize.width(), imageSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE,
const_cast<uchar*>(image.constBits()));
- d_ptr->textureSize = imageSize;
+ if (textureSize)
+ *textureSize = imageSize;
} else {
funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
QRect imageRect = image.rect();
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 76fd3d40b4..4728622cac 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -111,7 +111,7 @@ public:
#ifndef QT_NO_OPENGL
virtual void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset, QPlatformTextureList *textures, QOpenGLContext *context);
virtual QImage toImage() const;
- virtual GLuint toTexture(const QRegion &dirtyRegion) const;
+ virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize) const;
#endif
virtual void resize(const QSize &size, const QRegion &staticContents) = 0;
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index a72ac23418..b2254c4826 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -280,6 +280,7 @@ QFixed QFontEngine::underlinePosition() const
void *QFontEngine::harfbuzzFont() const
{
+ Q_ASSERT(type() != QFontEngine::Multi);
#ifdef QT_ENABLE_HARFBUZZ_NG
if (useHarfbuzzNG)
return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this));
@@ -312,6 +313,7 @@ void *QFontEngine::harfbuzzFont() const
void *QFontEngine::harfbuzzFace() const
{
+ Q_ASSERT(type() != QFontEngine::Multi);
#ifdef QT_ENABLE_HARFBUZZ_NG
if (useHarfbuzzNG)
return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this));
@@ -329,6 +331,9 @@ void *QFontEngine::harfbuzzFace() const
bool QFontEngine::supportsScript(QChar::Script script) const
{
+ if (type() <= QFontEngine::Multi)
+ return true;
+
// ### TODO: This only works for scripts that require OpenType. More generally
// for scripts that do not require OpenType we should just look at the list of
// supported writing systems in the font's OS/2 table.
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index b0bade83ee..e87747fd1b 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -605,8 +605,6 @@ _hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data)
static inline hb_face_t *
_hb_qt_face_create(QFontEngine *fe)
{
- Q_ASSERT(fe);
-
QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData));
Q_CHECK_PTR(data);
data->user_data = fe->faceData.user_data;
@@ -633,6 +631,8 @@ _hb_qt_face_release(void *user_data)
hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe)
{
+ Q_ASSERT(fe && fe->type() != QFontEngine::Multi);
+
if (Q_UNLIKELY(!fe->face_)) {
fe->face_ = _hb_qt_face_create(fe);
if (Q_UNLIKELY(!fe->face_))
@@ -647,8 +647,6 @@ hb_face_t *hb_qt_face_get_for_engine(QFontEngine *fe)
static inline hb_font_t *
_hb_qt_font_create(QFontEngine *fe)
{
- Q_ASSERT(fe);
-
hb_face_t *face = hb_qt_face_get_for_engine(fe);
if (Q_UNLIKELY(!face))
return NULL;
@@ -685,6 +683,8 @@ _hb_qt_font_release(void *user_data)
hb_font_t *hb_qt_font_get_for_engine(QFontEngine *fe)
{
+ Q_ASSERT(fe && fe->type() != QFontEngine::Multi);
+
if (Q_UNLIKELY(!fe->font_)) {
fe->font_ = _hb_qt_font_create(fe);
if (Q_UNLIKELY(!fe->font_))
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 3b079b7ee3..35950c709b 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -3138,11 +3138,12 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end,
int QTextEngine::previousLogicalPosition(int oldPos) const
{
const QCharAttributes *attrs = attributes();
- if (!attrs || oldPos < 0)
+ int len = block.isValid() ? block.length() - 1
+ : layoutData->string.length();
+ Q_ASSERT(len <= layoutData->string.length());
+ if (!attrs || oldPos <= 0 || oldPos > len)
return oldPos;
- if (oldPos <= 0)
- return 0;
oldPos--;
while (oldPos && !attrs[oldPos].graphemeBoundary)
oldPos--;
@@ -3181,23 +3182,22 @@ int QTextEngine::lineNumberForTextPosition(int pos)
void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints)
{
QTextLineItemIterator iterator(this, lineNum);
- bool rtl = isRightToLeft();
+
+ insertionPoints.reserve(iterator.line.length);
+
bool lastLine = lineNum >= lines.size() - 1;
while (!iterator.atEnd()) {
- iterator.next();
- const QScriptItem *si = &layoutData->items[iterator.item];
- if (si->analysis.bidiLevel % 2) {
- int i = iterator.itemEnd - 1, min = iterator.itemStart;
- if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
- i++;
- for (; i >= min; i--)
+ const QScriptItem &si = iterator.next();
+
+ int end = iterator.itemEnd;
+ if (lastLine && iterator.item == iterator.lastItem)
+ ++end; // the last item in the last line -> insert eol position
+ if (si.analysis.bidiLevel % 2) {
+ for (int i = end - 1; i >= iterator.itemStart; --i)
insertionPoints.push_back(i);
} else {
- int i = iterator.itemStart, max = iterator.itemEnd;
- if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd()))
- max++;
- for (; i < max; i++)
+ for (int i = iterator.itemStart; i < end; ++i)
insertionPoints.push_back(i);
}
}
@@ -3225,8 +3225,7 @@ int QTextEngine::beginningOfLine(int lineNum)
int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op)
{
- if (!layoutData)
- itemize();
+ itemize();
bool moveRight = (op == QTextCursor::Right);
bool alignRight = isRightToLeft();
@@ -3234,7 +3233,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation
return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos);
int lineNum = lineNumberForTextPosition(pos);
- Q_ASSERT(lineNum >= 0);
+ if (lineNum < 0)
+ return pos;
QVector<int> insertionPoints;
insertionPointsForLine(lineNum, insertionPoints);
@@ -3257,6 +3257,8 @@ int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation
if (lineNum > 0)
return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1);
}
+
+ break;
}
return pos;
@@ -3520,7 +3522,12 @@ QScriptItem &QTextLineItemIterator::next()
if (!si->num_glyphs)
eng->shape(item);
+ itemStart = qMax(line.from, si->position);
+ itemEnd = qMin(lineEnd, si->position + itemLength);
+
if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
+ glyphsStart = 0;
+ glyphsEnd = 1;
itemWidth = si->width;
return *si;
}
@@ -3528,15 +3535,9 @@ QScriptItem &QTextLineItemIterator::next()
unsigned short *logClusters = eng->logClusters(si);
QGlyphLayout glyphs = eng->shapedGlyphs(si);
- itemStart = qMax(line.from, si->position);
glyphsStart = logClusters[itemStart - si->position];
- if (lineEnd < si->position + itemLength) {
- itemEnd = lineEnd;
- glyphsEnd = logClusters[itemEnd-si->position];
- } else {
- itemEnd = si->position + itemLength;
- glyphsEnd = si->num_glyphs;
- }
+ glyphsEnd = (itemEnd == si->position + itemLength) ? si->num_glyphs : logClusters[itemEnd - si->position];
+
// show soft-hyphen at line-break
if (si->position + itemLength >= lineEnd
&& eng->layoutData->string.at(lineEnd - 1).unicode() == QChar::SoftHyphen)
diff --git a/src/gui/text/qtextimagehandler.cpp b/src/gui/text/qtextimagehandler.cpp
index 9704f7a9dc..02a1091506 100644
--- a/src/gui/text/qtextimagehandler.cpp
+++ b/src/gui/text/qtextimagehandler.cpp
@@ -42,7 +42,7 @@
#include "qtextimagehandler_p.h"
-#include <qcoreapplication.h>
+#include <qguiapplication.h>
#include <qtextformat.h>
#include <qpainter.h>
#include <qdebug.h>
@@ -52,6 +52,21 @@
QT_BEGIN_NAMESPACE
+static QString resolve2xFile(const QString &fileName, qreal targetDevicePixelRatio)
+{
+ if (targetDevicePixelRatio <= 1.0)
+ return fileName;
+
+ int dotIndex = fileName.lastIndexOf(QLatin1Char('.'));
+ if (dotIndex != -1) {
+ QString at2xfileName = fileName;
+ at2xfileName.insert(dotIndex, QStringLiteral("@2x"));
+ if (QFile::exists(at2xfileName))
+ return at2xfileName;
+ }
+ return fileName;
+}
+
static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
{
QPixmap pm;
@@ -59,6 +74,8 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
QString name = format.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc"));
+ QPaintDevice *pdev = doc->documentLayout()->paintDevice();
+ name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio());
QUrl url = QUrl(name);
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Pixmap || data.type() == QVariant::Image) {
@@ -85,6 +102,9 @@ static QPixmap getPixmap(QTextDocument *doc, const QTextImageFormat &format)
doc->addResource(QTextDocument::ImageResource, url, pm);
}
+ if (name.contains(QStringLiteral("@2x")))
+ pm.setDevicePixelRatio(2.0);
+
return pm;
}
@@ -100,17 +120,20 @@ static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format)
QSize size(width, height);
if (!hasWidth || !hasHeight) {
pm = getPixmap(doc, format);
+ const int pmWidth = pm.width() / pm.devicePixelRatio();
+ const int pmHeight = pm.height() / pm.devicePixelRatio();
+
if (!hasWidth) {
if (!hasHeight)
- size.setWidth(pm.width());
+ size.setWidth(pmWidth);
else
- size.setWidth(qRound(height * (pm.width() / (qreal) pm.height())));
+ size.setWidth(qRound(height * (pmWidth / (qreal) pmHeight)));
}
if (!hasHeight) {
if (!hasWidth)
- size.setHeight(pm.height());
+ size.setHeight(pmHeight);
else
- size.setHeight(qRound(width * (pm.height() / (qreal) pm.width())));
+ size.setHeight(qRound(width * (pmHeight / (qreal) pmWidth)));
}
}
@@ -134,6 +157,8 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format)
QString name = format.name();
if (name.startsWith(QLatin1String(":/"))) // auto-detect resources
name.prepend(QLatin1String("qrc"));
+ QPaintDevice *pdev = doc->documentLayout()->paintDevice();
+ name = resolve2xFile(name, pdev ? pdev->devicePixelRatio() : qApp->devicePixelRatio());
QUrl url = QUrl(name);
const QVariant data = doc->resource(QTextDocument::ImageResource, url);
if (data.type() == QVariant::Image) {
@@ -159,6 +184,9 @@ static QImage getImage(QTextDocument *doc, const QTextImageFormat &format)
doc->addResource(QTextDocument::ImageResource, url, image);
}
+ if (name.contains(QStringLiteral("@2x")))
+ image.setDevicePixelRatio(2.0);
+
return image;
}
@@ -175,9 +203,9 @@ static QSize getImageSize(QTextDocument *doc, const QTextImageFormat &format)
if (!hasWidth || !hasHeight) {
image = getImage(doc, format);
if (!hasWidth)
- size.setWidth(image.width());
+ size.setWidth(image.width() / image.devicePixelRatio());
if (!hasHeight)
- size.setHeight(image.height());
+ size.setHeight(image.height() / image.devicePixelRatio());
}
qreal scale = 1.0;
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index 0c9866c6cf..c3cf2e56bb 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -674,7 +674,10 @@ int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
{
const QCharAttributes *attributes = d->attributes();
- if (!attributes || oldPos <= 0 || oldPos > d->layoutData->string.length())
+ int len = d->block.isValid() ? d->block.length() - 1
+ : d->layoutData->string.length();
+ Q_ASSERT(len <= d->layoutData->string.length());
+ if (!attributes || oldPos <= 0 || oldPos > len)
return oldPos;
if (mode == SkipCharacters) {
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index fb40958178..169124e9f4 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -873,18 +873,23 @@ void QHttpNetworkConnectionChannel::_q_error(QAbstractSocket::SocketError socket
if (!connection->d_func()->shouldEmitChannelError(socket))
return;
- // Need to dequeu the request so that we can emit the error.
- if (!reply)
- connection->d_func()->dequeueRequest(socket);
- if (reply) {
- reply->d_func()->errorString = errorString;
- emit reply->finishedWithError(errorCode, errorString);
- reply = 0;
- if (protocolHandler)
- protocolHandler->setReply(0);
- }
+ // emit error for all waiting replies
+ do {
+ // Need to dequeu the request so that we can emit the error.
+ if (!reply)
+ connection->d_func()->dequeueRequest(socket);
+
+ if (reply) {
+ reply->d_func()->errorString = errorString;
+ emit reply->finishedWithError(errorCode, errorString);
+ reply = 0;
+ if (protocolHandler)
+ protocolHandler->setReply(0);
+ }
+ } while (!connection->d_func()->highPriorityQueue.isEmpty()
+ || !connection->d_func()->lowPriorityQueue.isEmpty());
#ifndef QT_NO_SSL
- else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) {
+ if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeSPDY) {
QList<HttpMessagePair> spdyPairs = spdyRequestsToSend.values();
for (int a = 0; a < spdyPairs.count(); ++a) {
// emit error for all replies
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index bf49b97b30..f56c77505a 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -560,8 +560,7 @@ bool QNetworkReplyHttpImplPrivate::loadFromCacheIfAllowed(QHttpNetworkRequest &h
if (!expirationDate.isValid()) {
if (lastModified.isValid()) {
int diff = currentDateTime.secsTo(lastModified);
- expirationDate = lastModified;
- expirationDate.addSecs(diff / 10);
+ expirationDate = lastModified.addSecs(diff / 10);
if (httpRequest.headerField("Warning").isEmpty()) {
QDateTime dt;
dt.setTime_t(current_age);
diff --git a/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp b/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp
index 53eadda7e9..61e7cf0ea3 100644
--- a/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp
+++ b/src/network/doc/snippets/code/src_network_access_qnetworkrequest.cpp
@@ -39,5 +39,5 @@
****************************************************************************/
//! [0]
-request.setRawHeader("Last-Modified", "Sun, 06 Nov 1994 08:49:37 GMT");
+request.setRawHeader(QByteArray("Last-Modified"), QByteArray("Sun, 06 Nov 1994 08:49:37 GMT"));
//! [0]
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index 1634ba0649..9c68218062 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -55,6 +55,53 @@ QT_BEGIN_NAMESPACE
extern int q_X509Callback(int ok, X509_STORE_CTX *ctx);
extern QString getErrorsFromOpenSsl();
+// Default DH params
+// 1024-bit MODP Group with 160-bit Prime Order Subgroup
+// From RFC 5114
+static unsigned const char dh1024_p[]={
+ 0xB1,0x0B,0x8F,0x96,0xA0,0x80,0xE0,0x1D,0xDE,0x92,0xDE,0x5E,
+ 0xAE,0x5D,0x54,0xEC,0x52,0xC9,0x9F,0xBC,0xFB,0x06,0xA3,0xC6,
+ 0x9A,0x6A,0x9D,0xCA,0x52,0xD2,0x3B,0x61,0x60,0x73,0xE2,0x86,
+ 0x75,0xA2,0x3D,0x18,0x98,0x38,0xEF,0x1E,0x2E,0xE6,0x52,0xC0,
+ 0x13,0xEC,0xB4,0xAE,0xA9,0x06,0x11,0x23,0x24,0x97,0x5C,0x3C,
+ 0xD4,0x9B,0x83,0xBF,0xAC,0xCB,0xDD,0x7D,0x90,0xC4,0xBD,0x70,
+ 0x98,0x48,0x8E,0x9C,0x21,0x9A,0x73,0x72,0x4E,0xFF,0xD6,0xFA,
+ 0xE5,0x64,0x47,0x38,0xFA,0xA3,0x1A,0x4F,0xF5,0x5B,0xCC,0xC0,
+ 0xA1,0x51,0xAF,0x5F,0x0D,0xC8,0xB4,0xBD,0x45,0xBF,0x37,0xDF,
+ 0x36,0x5C,0x1A,0x65,0xE6,0x8C,0xFD,0xA7,0x6D,0x4D,0xA7,0x08,
+ 0xDF,0x1F,0xB2,0xBC,0x2E,0x4A,0x43,0x71
+};
+
+static unsigned const char dh1024_g[]={
+ 0xA4,0xD1,0xCB,0xD5,0xC3,0xFD,0x34,0x12,0x67,0x65,0xA4,0x42,
+ 0xEF,0xB9,0x99,0x05,0xF8,0x10,0x4D,0xD2,0x58,0xAC,0x50,0x7F,
+ 0xD6,0x40,0x6C,0xFF,0x14,0x26,0x6D,0x31,0x26,0x6F,0xEA,0x1E,
+ 0x5C,0x41,0x56,0x4B,0x77,0x7E,0x69,0x0F,0x55,0x04,0xF2,0x13,
+ 0x16,0x02,0x17,0xB4,0xB0,0x1B,0x88,0x6A,0x5E,0x91,0x54,0x7F,
+ 0x9E,0x27,0x49,0xF4,0xD7,0xFB,0xD7,0xD3,0xB9,0xA9,0x2E,0xE1,
+ 0x90,0x9D,0x0D,0x22,0x63,0xF8,0x0A,0x76,0xA6,0xA2,0x4C,0x08,
+ 0x7A,0x09,0x1F,0x53,0x1D,0xBF,0x0A,0x01,0x69,0xB6,0xA2,0x8A,
+ 0xD6,0x62,0xA4,0xD1,0x8E,0x73,0xAF,0xA3,0x2D,0x77,0x9D,0x59,
+ 0x18,0xD0,0x8B,0xC8,0x85,0x8F,0x4D,0xCE,0xF9,0x7C,0x2A,0x24,
+ 0x85,0x5E,0x6E,0xEB,0x22,0xB3,0xB2,0xE5
+};
+
+static DH *get_dh1024()
+{
+ DH *dh = q_DH_new();
+ if (!dh)
+ return 0;
+
+ dh->p = q_BN_bin2bn(dh1024_p, sizeof(dh1024_p), 0);
+ dh->g = q_BN_bin2bn(dh1024_g, sizeof(dh1024_g), 0);
+ if (!dh->p || !dh->g) {
+ q_DH_free(dh);
+ return 0;
+ }
+
+ return dh;
+}
+
QSslContext::QSslContext()
: ctx(0),
pkey(0),
@@ -261,6 +308,18 @@ init_context:
if (!configuration.sessionTicket().isEmpty())
sslContext->setSessionASN1(configuration.sessionTicket());
+ // Set temp DH params
+ DH *dh = 0;
+ dh = get_dh1024();
+ q_SSL_CTX_set_tmp_dh(sslContext->ctx, dh);
+ q_DH_free(dh);
+
+ // Set temp ECDH params
+ EC_KEY *ecdh = 0;
+ ecdh = q_EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ q_SSL_CTX_set_tmp_ecdh(sslContext->ctx, ecdh);
+ q_EC_KEY_free(ecdh);
+
return sslContext;
}
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index cd64b9ec43..52d8577abe 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -569,6 +569,9 @@ void QSslSocketPrivate::ensureInitialized()
long QSslSocketPrivate::sslLibraryVersionNumber()
{
+ if (!supportsSsl())
+ return 0;
+
return q_SSLeay();
}
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index 3c7402cd26..65f186b9e9 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -362,6 +362,11 @@ DEFINEFUNC3(void, SSL_CTX_set_next_proto_select_cb, SSL_CTX *s, s,
DEFINEFUNC3(void, SSL_get0_next_proto_negotiated, const SSL *s, s,
const unsigned char **data, data, unsigned *len, len, return, DUMMYARG)
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return)
+DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG)
+DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return)
+DEFINEFUNC(EC_KEY *, EC_KEY_new_by_curve_name, int nid, nid, return 0, return)
+DEFINEFUNC(void, EC_KEY_free, EC_KEY *ecdh, ecdh, return, DUMMYARG)
#define RESOLVEFUNC(func) \
if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
@@ -837,6 +842,11 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSL_CTX_set_next_proto_select_cb)
RESOLVEFUNC(SSL_get0_next_proto_negotiated)
#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+ RESOLVEFUNC(DH_new)
+ RESOLVEFUNC(DH_free)
+ RESOLVEFUNC(BN_bin2bn)
+ RESOLVEFUNC(EC_KEY_new_by_curve_name)
+ RESOLVEFUNC(EC_KEY_free)
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index c363694bf6..70d4c25456 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -428,6 +428,17 @@ int q_X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
X509 *q_X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+// Diffie-Hellman support
+DH *q_DH_new();
+void q_DH_free(DH *dh);
+BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
+#define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh)
+
+// EC Diffie-Hellman support
+EC_KEY *q_EC_KEY_new_by_curve_name(int nid);
+void q_EC_KEY_free(EC_KEY *ecdh);
+#define q_SSL_CTX_set_tmp_ecdh(ctx, ecdh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_ECDH, 0, (char *)ecdh)
+
#define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
#define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
#ifdef SSLEAY_MACROS
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index f685c26603..5fef609a2a 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -11,7 +11,6 @@ QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf
load(qt_module)
contains(QT_CONFIG, opengl):CONFIG += opengl
-contains(QT_CONFIG, opengles1):CONFIG += opengles1
contains(QT_CONFIG, opengles2):CONFIG += opengles2
HEADERS += qgl.h \
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index e602a05af9..3cfdcc549c 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -2934,8 +2934,9 @@ void QGLContext::setFormat(const QGLFormat &format)
void QGLContext::setDevice(QPaintDevice *pDev)
{
Q_D(QGLContext);
- if (isValid())
- reset();
+ // Do not touch the valid flag here. The context is either a new one and
+ // valid is not yet set or it is adapted from a valid QOpenGLContext in which
+ // case it must remain valid.
d->paintDevice = pDev;
if (d->paintDevice && (d->paintDevice->devType() != QInternal::Widget
&& d->paintDevice->devType() != QInternal::Pixmap
@@ -4083,6 +4084,11 @@ QPixmap QGLWidget::renderPixmap(int w, int h, bool useContext)
Depending on your hardware, you can explicitly select which color
buffer to grab with a glReadBuffer() call before calling this
function.
+
+ On QNX the back buffer is not preserved when swapBuffers() is called. The back buffer
+ where this function reads from, might thus not contain the same content as the front buffer.
+ In order to retrieve what is currently visible on the screen, swapBuffers()
+ has to be executed prior to this function call.
*/
QImage QGLWidget::grabFrameBuffer(bool withAlpha)
{
diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp
index fe4d1c363c..10e6ffde46 100644
--- a/src/opengl/qgl_qpa.cpp
+++ b/src/opengl/qgl_qpa.cpp
@@ -109,6 +109,11 @@ QSurfaceFormat QGLFormat::toSurfaceFormat(const QGLFormat &format)
retFormat.setMajorVersion(format.majorVersion());
retFormat.setMinorVersion(format.minorVersion());
retFormat.setProfile(static_cast<QSurfaceFormat::OpenGLContextProfile>(format.profile()));
+ // QGLFormat has no way to set DeprecatedFunctions, that is, to tell that forward
+ // compatibility should not be requested. Some drivers fail to ignore the fwdcompat
+ // bit with compatibility profiles so make sure it is not set.
+ if (format.profile() == QGLFormat::CompatibilityProfile)
+ retFormat.setOption(QSurfaceFormat::DeprecatedFunctions);
return retFormat;
}
diff --git a/src/opengl/qglbuffer.cpp b/src/opengl/qglbuffer.cpp
index 0bcb9d4f1f..1c9545990f 100644
--- a/src/opengl/qglbuffer.cpp
+++ b/src/opengl/qglbuffer.cpp
@@ -344,20 +344,18 @@ void QGLBuffer::destroy()
bool QGLBuffer::read(int offset, void *data, int count)
{
#if !defined(QT_OPENGL_ES)
- if (QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) {
- Q_D(QGLBuffer);
- if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
- return false;
- while (glGetError() != GL_NO_ERROR) ; // Clear error state.
- d->funcs->glGetBufferSubData(d->type, offset, count, data);
- return glGetError() == GL_NO_ERROR;
- }
+ Q_D(QGLBuffer);
+ if (!d->funcs->hasOpenGLFeature(QOpenGLFunctions::Buffers) || !d->guard->id())
+ return false;
+ while (glGetError() != GL_NO_ERROR) ; // Clear error state.
+ d->funcs->glGetBufferSubData(d->type, offset, count, data);
+ return glGetError() == GL_NO_ERROR;
#else
Q_UNUSED(offset);
Q_UNUSED(data);
Q_UNUSED(count);
-#endif
return false;
+#endif
}
/*!
diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp
index d636da91b5..bd8bc2f64a 100644
--- a/src/opengl/qglframebufferobject.cpp
+++ b/src/opengl/qglframebufferobject.cpp
@@ -1114,6 +1114,9 @@ QGLFramebufferObjectFormat QGLFramebufferObject::format() const
\fn QImage QGLFramebufferObject::toImage() const
Returns the contents of this framebuffer object as a QImage.
+
+ On QNX the back buffer is not preserved when a buffer swap occures. So this function
+ might return old content.
*/
QImage QGLFramebufferObject::toImage() const
{
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
index d6d77d0568..42b3b47f7f 100644
--- a/src/opengl/qglfunctions.cpp
+++ b/src/opengl/qglfunctions.cpp
@@ -223,7 +223,7 @@ QGLFunctions::QGLFunctions(const QGLContext *context)
static int qt_gl_resolve_features()
{
QOpenGLContext *ctx = QOpenGLContext::currentContext();
- if (ctx->isES() && QOpenGLContext::openGLModuleType() != QOpenGLContext::GLES1) {
+ if (ctx->isES()) {
// OpenGL ES 2
int features = QGLFunctions::Multitexture |
QGLFunctions::Shaders |
@@ -243,26 +243,6 @@ static int qt_gl_resolve_features()
if (extensions.match("GL_IMG_texture_npot"))
features |= QGLFunctions::NPOTTextures;
return features;
- } else if (ctx->isES()) {
- // OpenGL ES 1
- int features = QGLFunctions::Multitexture |
- QGLFunctions::Buffers |
- QGLFunctions::CompressedTextures |
- QGLFunctions::Multisample;
- QOpenGLExtensionMatcher extensions;
- if (extensions.match("GL_OES_framebuffer_object"))
- features |= QGLFunctions::Framebuffers;
- if (extensions.match("GL_OES_blend_equation_separate"))
- features |= QGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_OES_blend_func_separate"))
- features |= QGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_OES_blend_subtract"))
- features |= QGLFunctions::BlendSubtract;
- if (extensions.match("GL_OES_texture_npot"))
- features |= QGLFunctions::NPOTTextures;
- if (extensions.match("GL_IMG_texture_npot"))
- features |= QGLFunctions::NPOTTextures;
- return features;
} else {
// OpenGL
int features = 0;
diff --git a/src/openglextensions/openglextensions.pro b/src/openglextensions/openglextensions.pro
index e303dea5e8..948465165e 100644
--- a/src/openglextensions/openglextensions.pro
+++ b/src/openglextensions/openglextensions.pro
@@ -2,7 +2,6 @@ TARGET = QtOpenGLExtensions
CONFIG += static
contains(QT_CONFIG, opengl):CONFIG += opengl
-contains(QT_CONFIG, opengles1):CONFIG += opengles1
contains(QT_CONFIG, opengles2):CONFIG += opengles2
load(qt_module)
diff --git a/src/platformsupport/fbconvenience/qfbcursor.cpp b/src/platformsupport/fbconvenience/qfbcursor.cpp
index b86f5830ea..bff663c13b 100644
--- a/src/platformsupport/fbconvenience/qfbcursor.cpp
+++ b/src/platformsupport/fbconvenience/qfbcursor.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
QFbCursor::QFbCursor(QFbScreen *screen)
- : mScreen(screen), mCurrentRect(QRect()), mPrevRect(QRect())
+ : mScreen(screen), mDirty(false), mOnScreen(false)
{
mGraphic = new QPlatformCursorImage(0, 0, 0, 0, 0, 0);
setCursor(Qt::ArrowCursor);
diff --git a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro
index 281515145f..101ea30bcc 100644
--- a/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro
+++ b/src/plugins/generic/evdevkeyboard/evdevkeyboard.pro
@@ -1,6 +1,7 @@
TARGET = qevdevkeyboardplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevKeyboardPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro
index 9a3cc839cc..57a67ead8d 100644
--- a/src/plugins/generic/evdevmouse/evdevmouse.pro
+++ b/src/plugins/generic/evdevmouse/evdevmouse.pro
@@ -1,6 +1,7 @@
TARGET = qevdevmouseplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevMousePlugin
load(qt_plugin)
diff --git a/src/plugins/generic/evdevtablet/evdevtablet.pro b/src/plugins/generic/evdevtablet/evdevtablet.pro
index ee3fbb3ec1..8ffc0db84d 100644
--- a/src/plugins/generic/evdevtablet/evdevtablet.pro
+++ b/src/plugins/generic/evdevtablet/evdevtablet.pro
@@ -1,6 +1,7 @@
TARGET = qevdevtabletplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevTabletPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/evdevtouch/evdevtouch.pro b/src/plugins/generic/evdevtouch/evdevtouch.pro
index 3d1c481c36..1f4d1b7e93 100644
--- a/src/plugins/generic/evdevtouch/evdevtouch.pro
+++ b/src/plugins/generic/evdevtouch/evdevtouch.pro
@@ -1,6 +1,7 @@
TARGET = qevdevtouchplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QEvdevTouchScreenPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/meego/meego.pro b/src/plugins/generic/meego/meego.pro
index c428517cd5..4baaa43a4c 100644
--- a/src/plugins/generic/meego/meego.pro
+++ b/src/plugins/generic/meego/meego.pro
@@ -1,6 +1,7 @@
TARGET = qmeegointegration
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QMeeGoIntegrationPlugin
load(qt_plugin)
diff --git a/src/plugins/generic/tslib/tslib.pro b/src/plugins/generic/tslib/tslib.pro
index 035857bb73..bc05efcc32 100644
--- a/src/plugins/generic/tslib/tslib.pro
+++ b/src/plugins/generic/tslib/tslib.pro
@@ -1,6 +1,7 @@
TARGET = qtslibplugin
PLUGIN_TYPE = generic
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QTsLibPlugin
load(qt_plugin)
diff --git a/src/plugins/platforminputcontexts/compose/compose.pro b/src/plugins/platforminputcontexts/compose/compose.pro
index 7182c458fc..10e50a7a7e 100644
--- a/src/plugins/platforminputcontexts/compose/compose.pro
+++ b/src/plugins/platforminputcontexts/compose/compose.pro
@@ -1,6 +1,7 @@
TARGET = composeplatforminputcontextplugin
PLUGIN_TYPE = platforminputcontexts
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QComposePlatformInputContextPlugin
load(qt_plugin)
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index 8bbb490022..ea0b5261c4 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -430,8 +430,10 @@ void TableGenerator::parseKeySequence(char *line)
elem.keys[i] = XKB_KEY_dead_invertedbreve;
else if (!strcmp(sym, "dead_double_grave"))
elem.keys[i] = XKB_KEY_dead_doublegrave;
+#ifdef DEBUG_GENERATOR
else
qWarning() << QString("Qt Warning - invalid keysym: %1").arg(sym);
+#endif
}
} else {
elem.keys[i] = 0;
diff --git a/src/plugins/platforminputcontexts/ibus/ibus.pro b/src/plugins/platforminputcontexts/ibus/ibus.pro
index 75a5b5838f..401be6d42f 100644
--- a/src/plugins/platforminputcontexts/ibus/ibus.pro
+++ b/src/plugins/platforminputcontexts/ibus/ibus.pro
@@ -1,6 +1,7 @@
TARGET = ibusplatforminputcontextplugin
PLUGIN_TYPE = platforminputcontexts
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QIbusPlatformInputContextPlugin
load(qt_plugin)
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 9efdcad158..760da7a767 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -47,9 +47,7 @@
#include <QTouchEvent>
#include <QPointer>
-#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
-# include <QDebug>
-#endif
+#include <QDebug>
using namespace QtAndroid;
@@ -277,226 +275,393 @@ namespace QtAndroidInput
if (key >= 0x0000001d && key <= 0x00000036)
return Qt::Key_A + key - 0x0000001d;
+ // F1--F12 0x00000083 -- 0x0000008e
+ if (key >= 0x00000083 && key <= 0x0000008e)
+ return Qt::Key_F1 + key - 0x00000083;
+
+ // NUMPAD_0--NUMPAD_9 0x00000090 -- 0x00000099
+ if (key >= 0x00000090 && key <= 0x00000099)
+ return Qt::KeypadModifier + Qt::Key_0 + key - 0x00000090;
+
+ // BUTTON_1--KEYCODE_BUTTON_16 0x000000bc -- 0x000000cb
+
switch (key) {
- case 0x00000039:
- case 0x0000003a:
- return Qt::Key_Alt;
+ case 0x00000000: // KEYCODE_UNKNOWN
+ return Qt::Key_unknown;
+
+ case 0x00000001: // KEYCODE_SOFT_LEFT
+ return Qt::Key_Left;
+
+ case 0x00000002: // KEYCODE_SOFT_RIGHT
+ return Qt::Key_Right;
+
+ // 0x00000003: // KEYCODE_HOME is never delivered to applications.
+
+ case 0x00000004: // KEYCODE_BACK
+ return Qt::Key_Back;
+
+ case 0x00000005: // KEYCODE_CALL
+ return Qt::Key_Call;
+
+ case 0x00000006: // KEYCODE_ENDCALL
+ return Qt::Key_Hangup;
+
+ // 0--9 0x00000007 -- 0x00000010
+
+ case 0x00000011: // KEYCODE_STAR
+ return Qt::Key_Asterisk;
+
+ case 0x00000012: // KEYCODE_POUND
+ return Qt::Key_NumberSign;
+
+ case 0x00000013: //KEYCODE_DPAD_UP
+ return Qt::Key_Up;
+
+ case 0x00000014: // KEYCODE_DPAD_DOWN
+ return Qt::Key_Down;
+
+ case 0x00000015: //KEYCODE_DPAD_LEFT
+ return Qt::Key_Left;
+
+ case 0x00000016: //KEYCODE_DPAD_RIGHT
+ return Qt::Key_Right;
+
+ case 0x00000017: // KEYCODE_DPAD_CENTER
+ return Qt::Key_Enter;
+
+ case 0x00000018: // KEYCODE_VOLUME_UP
+ return Qt::Key_VolumeUp;
+
+ case 0x00000019: // KEYCODE_VOLUME_DOWN
+ return Qt::Key_VolumeDown;
+
+ case 0x0000001a:
+ return Qt::Key_PowerOff;
+
+ case 0x0000001b: // KEYCODE_CAMERA
+ return Qt::Key_Camera;
+
+ case 0x0000001c: // KEYCODE_CLEAR
+ return Qt::Key_Clear;
+
+ // A--Z 0x0000001d -- 0x00000036
+
+ case 0x00000037: // KEYCODE_COMMA
+ return Qt::Key_Comma;
+
+ case 0x00000038: // KEYCODE_PERIOD
+ return Qt::Key_Period;
+
+ case 0x00000039: // KEYCODE_ALT_LEFT
+ case 0x0000003a: // KEYCODE_ALT_RIGHT
+ return Qt::Key_Alt;
+
+ case 0x0000003b: // KEYCODE_SHIFT_LEFT
+ case 0x0000003c: // KEYCODE_SHIFT_RIGHT
+ return Qt::Key_Shift;
+
+ case 0x0000003d: // KEYCODE_TAB
+ return Qt::Key_Tab;
+
+ case 0x0000003e: // KEYCODE_SPACE
+ return Qt::Key_Space;
+
+ case 0x0000003f: // KEYCODE_SYM
+ return Qt::Key_Meta;
+
+ case 0x00000040: // KEYCODE_EXPLORER
+ return Qt::Key_Explorer;
+
+ case 0x00000041: //KEYCODE_ENVELOPE
+ return Qt::Key_LaunchMail;
+
+ case 0x00000042: // KEYCODE_ENTER
+ return Qt::Key_Return;
+
+ case 0x00000043: // KEYCODE_DEL
+ return Qt::Key_Backspace;
+
+ case 0x00000044: // KEYCODE_GRAVE
+ return Qt::Key_QuoteLeft;
+
+ case 0x00000045: // KEYCODE_MINUS
+ return Qt::Key_Minus;
+
+ case 0x00000046: // KEYCODE_EQUALS
+ return Qt::Key_Equal;
+
+ case 0x00000047: // KEYCODE_LEFT_BRACKET
+ return Qt::Key_BracketLeft;
+
+ case 0x00000048: // KEYCODE_RIGHT_BRACKET
+ return Qt::Key_BracketRight;
+
+ case 0x00000049: // KEYCODE_BACKSLASH
+ return Qt::Key_Backslash;
+
+ case 0x0000004a: // KEYCODE_SEMICOLON
+ return Qt::Key_Semicolon;
+
+ case 0x0000004b: // KEYCODE_APOSTROPHE
+ return Qt::Key_Apostrophe;
+
+ case 0x0000004c: // KEYCODE_SLASH
+ return Qt::Key_Slash;
+
+ case 0x0000004d: // KEYCODE_AT
+ return Qt::Key_At;
+
+ case 0x0000004e: // KEYCODE_NUM
+ return Qt::Key_Alt;
+
+ case 0x0000004f: // KEYCODE_HEADSETHOOK
+ return 0;
+
+ case 0x00000050: // KEYCODE_FOCUS
+ return Qt::Key_CameraFocus;
+
+ case 0x00000051: // KEYCODE_PLUS
+ return Qt::Key_Plus;
+
+ case 0x00000052: // KEYCODE_MENU
+ return Qt::Key_Menu;
+
+ case 0x00000053: // KEYCODE_NOTIFICATION
+ return 0;
- case 0x0000004b:
- return Qt::Key_Apostrophe;
+ case 0x00000054: // KEYCODE_SEARCH
+ return Qt::Key_Search;
- case 0x00000004: // KEYCODE_BACK
- return Qt::Key_Back;
+ case 0x00000055: // KEYCODE_MEDIA_PLAY_PAUSE
+ return Qt::Key_MediaPlay;
- case 0x00000049:
- return Qt::Key_Backslash;
+ case 0x00000056: // KEYCODE_MEDIA_STOP
+ return Qt::Key_MediaStop;
- case 0x00000005:
- return Qt::Key_Call;
+ case 0x00000057: // KEYCODE_MEDIA_NEXT
+ return Qt::Key_MediaNext;
- case 0x0000001b: // KEYCODE_CAMERA
- return Qt::Key_Camera;
+ case 0x00000058: // KEYCODE_MEDIA_PREVIOUS
+ return Qt::Key_MediaPrevious;
- case 0x0000001c:
- return Qt::Key_Clear;
+ case 0x00000059: // KEYCODE_MEDIA_REWIND
+ return Qt::Key_AudioRewind;
- case 0x00000037:
- return Qt::Key_Comma;
+ case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD
+ return Qt::Key_AudioForward;
- case 0x00000043: // KEYCODE_DEL
- return Qt::Key_Backspace;
+ case 0x0000005b: // KEYCODE_MUTE
+ return Qt::Key_MicMute;
- case 0x00000017: // KEYCODE_DPAD_CENTER
- return Qt::Key_Enter;
+ case 0x0000005c: // KEYCODE_PAGE_UP
+ return Qt::Key_PageUp;
- case 0x00000014: // KEYCODE_DPAD_DOWN
- return Qt::Key_Down;
+ case 0x0000005d: // KEYCODE_PAGE_DOWN
+ return Qt::Key_PageDown;
- case 0x00000015: //KEYCODE_DPAD_LEFT
- return Qt::Key_Left;
+ case 0x0000005e: // KEYCODE_PICTSYMBOLS
+ return 0;
- case 0x00000016: //KEYCODE_DPAD_RIGHT
- return Qt::Key_Right;
+ case 0x00000060: // KEYCODE_BUTTON_A
+ case 0x00000061: // KEYCODE_BUTTON_B
+ case 0x00000062: // KEYCODE_BUTTON_B
+ case 0x00000063: // KEYCODE_BUTTON_X
+ case 0x00000064: // KEYCODE_BUTTON_Y
+ case 0x00000065: // KEYCODE_BUTTON_Z
+ case 0x00000066: // KEYCODE_BUTTON_L1
+ case 0x00000067: // KEYCODE_BUTTON_R1
+ case 0x00000068: // KEYCODE_BUTTON_L2
+ case 0x00000069: // KEYCODE_BUTTON_R2
+ case 0x0000006a: // KEYCODE_BUTTON_THUMBL
+ case 0x0000006b: // KEYCODE_BUTTON_THUMBR
+ case 0x0000006c: // KEYCODE_BUTTON_START
+ case 0x0000006d: // KEYCODE_BUTTON_SELECT
+ case 0x0000006e: // KEYCODE_BUTTON_MODE
+ return 0;
- case 0x00000013: //KEYCODE_DPAD_UP
- return Qt::Key_Up;
+ case 0x0000006f: // KEYCODE_ESCAPE
+ return Qt::Key_Escape;
- case 0x00000006: //KEYCODE_ENDCALL
- return Qt::Key_Hangup;
+ case 0x00000070: // KEYCODE_FORWARD_DEL
+ return Qt::Key_Delete;
- case 0x00000042:
- return Qt::Key_Return;
+ case 0x00000071: // KEYCODE_CTRL_LEFT
+ case 0x00000072: // KEYCODE_CTRL_RIGHT
+ return Qt::Key_Control;
- case 0x00000041: //KEYCODE_ENVELOPE
- return Qt::Key_LaunchMail;
+ case 0x00000073: // KEYCODE_CAPS_LOCK
+ return Qt::Key_CapsLock;
- case 0x00000046:
- return Qt::Key_Equal;
+ case 0x00000074: // KEYCODE_SCROLL_LOCK
+ return Qt::Key_ScrollLock;
- case 0x00000040:
- return Qt::Key_Explorer;
+ case 0x00000075: // KEYCODE_META_LEFT
+ case 0x00000076: // KEYCODE_META_RIGHT
+ return Qt::Key_Meta;
- case 0x00000003:
- return Qt::Key_Home;
+ case 0x00000077: // KEYCODE_FUNCTION
+ return 0;
- case 0x00000047:
- return Qt::Key_BracketLeft;
+ case 0x00000078: // KEYCODE_SYSRQ
+ return Qt::Key_Print;
- case 0x0000005a: // KEYCODE_MEDIA_FAST_FORWARD
- return Qt::Key_AudioForward;
+ case 0x00000079: // KEYCODE_BREAK
+ return Qt::Key_Pause;
- case 0x00000057:
- return Qt::Key_MediaNext;
+ case 0x0000007a: // KEYCODE_MOVE_HOME
+ return Qt::Key_Home;
- case 0x00000055:
- return Qt::Key_MediaPlay;
+ case 0x0000007b: // KEYCODE_MOVE_END
+ return Qt::Key_End;
- case 0x00000058:
- return Qt::Key_MediaPrevious;
+ case 0x0000007c: // KEYCODE_MOVE_INSERT
+ return Qt::Key_Insert;
- case 0x00000059: // KEYCODE_MEDIA_REWIND
- return Qt::Key_AudioRewind;
+ case 0x0000007d: // KEYCODE_FORWARD
+ return Qt::Key_Forward;
- case 0x00000056:
- return Qt::Key_MediaStop;
+ case 0x0000007e: // KEYCODE_MEDIA_PLAY
+ return Qt::Key_MediaPlay;
- case 0x00000052: //KEYCODE_MENU
- return Qt::Key_Menu;
+ case 0x0000007f: // KEYCODE_MEDIA_PAUSE
+ return Qt::Key_MediaPause;
- case 0x00000045:
- return Qt::Key_Minus;
+ case 0x00000080: // KEYCODE_MEDIA_CLOSE
+ case 0x00000081: // KEYCODE_MEDIA_EJECT
+ return Qt::Key_Eject;
- case 0x0000005b: // KEYCODE_MUTE
- return Qt::Key_MicMute;
+ case 0x00000082: // KEYCODE_MEDIA_RECORD
+ return Qt::Key_MediaRecord;
- case 0x0000004e:
- return Qt::Key_NumLock;
+ // F1--F12 0x00000083 -- 0x0000008e
- case 0x00000038:
- return Qt::Key_Period;
+ case 0x0000008f: // KEYCODE_NUM_LOCK
+ return Qt::Key_NumLock;
- case 0x00000051:
- return Qt::Key_Plus;
+ // NUMPAD_0--NUMPAD_9 0x00000090 -- 0x00000099
- case 0x0000001a:
- return Qt::Key_PowerOff;
+ case 0x0000009a: // KEYCODE_NUMPAD_DIVIDE
+ return Qt::KeypadModifier + Qt::Key_Slash;
- case 0x00000048:
- return Qt::Key_BracketRight;
+ case 0x0000009b: // KEYCODE_NUMPAD_MULTIPLY
+ return Qt::KeypadModifier + Qt::Key_Asterisk;
- case 0x00000054:
- return Qt::Key_Search;
+ case 0x0000009c: // KEYCODE_NUMPAD_SUBTRACT
+ return Qt::KeypadModifier + Qt::Key_Minus;
- case 0x0000004a:
- return Qt::Key_Semicolon;
+ case 0x0000009d: // KEYCODE_NUMPAD_ADD
+ return Qt::KeypadModifier + Qt::Key_Plus;
- case 0x0000003b:
- case 0x0000003c:
- return Qt::Key_Shift;
+ case 0x0000009e: // KEYCODE_NUMPAD_DOT
+ return Qt::KeypadModifier + Qt::Key_Period;
- case 0x0000004c:
- return Qt::Key_Slash;
+ case 0x0000009f: // KEYCODE_NUMPAD_COMMA
+ return Qt::KeypadModifier + Qt::Key_Comma;
- case 0x00000001:
- return Qt::Key_Left;
+ case 0x000000a0: // KEYCODE_NUMPAD_ENTER
+ return Qt::Key_Enter;
- case 0x00000002:
- return Qt::Key_Right;
+ case 0x000000a1: // KEYCODE_NUMPAD_EQUALS
+ return Qt::KeypadModifier + Qt::Key_Equal;
- case 0x0000003e:
- return Qt::Key_Space;
+ case 0x000000a2: // KEYCODE_NUMPAD_LEFT_PAREN
+ return Qt::Key_ParenLeft;
- case 0x0000003f: // KEYCODE_SYM
- return Qt::Key_Meta;
+ case 0x000000a3: // KEYCODE_NUMPAD_RIGHT_PAREN
+ return Qt::Key_ParenRight;
- case 0x0000003d:
- return Qt::Key_Tab;
+ case 0x000000a4: // KEYCODE_VOLUME_MUTE
+ return Qt::Key_VolumeMute;
- case 0x00000019:
- return Qt::Key_VolumeDown;
+ case 0x000000a5: // KEYCODE_INFO
+ return Qt::Key_Info;
- case 0x000000a4: // KEYCODE_VOLUME_MUTE
- return Qt::Key_VolumeMute;
+ case 0x000000a6: // KEYCODE_CHANNEL_UP
+ return Qt::Key_ChannelUp;
- case 0x00000018:
- return Qt::Key_VolumeUp;
+ case 0x000000a7: // KEYCODE_CHANNEL_DOWN
+ return Qt::Key_ChannelDown;
- case 0x00000011: // KEYCODE_STAR
- return Qt::Key_Asterisk;
+ case 0x000000a8: // KEYCODE_ZOOM_IN
+ return Qt::Key_ZoomIn;
- case 0x00000012: // KEYCODE_POUND
- return Qt::Key_NumberSign;
+ case 0x000000a9: // KEYCODE_ZOOM_OUT
+ return Qt::Key_ZoomOut;
- case 0x00000050: // KEYCODE_FOCUS
- return Qt::Key_CameraFocus;
+ case 0x000000aa: // KEYCODE_TV
+ case 0x000000ab: // KEYCODE_WINDOW
+ return 0;
- case 0x00000070: // KEYCODE_FORWARD_DEL
- return Qt::Key_Delete;
+ case 0x000000ac: // KEYCODE_GUIDE
+ return Qt::Key_Guide;
- case 0x00000080: // KEYCODE_MEDIA_CLOSE
- return Qt::Key_Close;
+ case 0x000000ad: // KEYCODE_DVR
+ return 0;
- case 0x00000081: // KEYCODE_MEDIA_EJECT
- return Qt::Key_Eject;
+ case 0x000000ae: // KEYCODE_BOOKMARK
+ return Qt::Key_AddFavorite;
- case 0x00000082: // KEYCODE_MEDIA_RECORD
- return Qt::Key_MediaRecord;
+ case 0x000000af: // KEYCODE_CAPTIONS
+ return Qt::Key_Subtitle;
- case 0x000000b7: // KEYCODE_PROG_RED
- return Qt::Key_Red;
+ case 0x000000b0: // KEYCODE_SETTINGS
+ return Qt::Key_Settings;
- case 0x000000b8: // KEYCODE_PROG_GREEN
- return Qt::Key_Green;
+ case 0x000000b1: // KEYCODE_TV_POWER
+ case 0x000000b2: // KEYCODE_TV_INPUT
+ case 0x000000b3: // KEYCODE_STB_POWER
+ case 0x000000b4: // KEYCODE_STB_INPUT
+ case 0x000000b5: // KEYCODE_AVR_POWER
+ case 0x000000b6: // KEYCODE_AVR_INPUT
+ return 0;
- case 0x000000b9: // KEYCODE_PROG_YELLOW
- return Qt::Key_Yellow;
+ case 0x000000b7: // KEYCODE_PROG_RED
+ return Qt::Key_Red;
- case 0x000000ba: // KEYCODE_PROG_BLUE
- return Qt::Key_Blue;
+ case 0x000000b8: // KEYCODE_PROG_GREEN
+ return Qt::Key_Green;
- case 0x000000a5: // KEYCODE_INFO
- return Qt::Key_Info;
+ case 0x000000b9: // KEYCODE_PROG_YELLOW
+ return Qt::Key_Yellow;
- case 0x000000a6: // KEYCODE_CHANNEL_UP
- return Qt::Key_ChannelUp;
+ case 0x000000ba: // KEYCODE_PROG_BLUE
+ return Qt::Key_Blue;
- case 0x000000a7: // KEYCODE_CHANNEL_DOWN
- return Qt::Key_ChannelDown;
+ // 0x000000bb: // KEYCODE_APP_SWITCH is not sent by the Android O.S.
- case 0x000000a8: // KEYCODE_ZOOM_IN
- return Qt::Key_ZoomIn;
+ // BUTTON_1--KEYCODE_BUTTON_16 0x000000bc -- 0x000000cb
- case 0x000000a9: // KEYCODE_ZOOM_OUT
- return Qt::Key_ZoomOut;
+ case 0x000000cc: // KEYCODE_LANGUAGE_SWITCH
+ case 0x000000cd: // KEYCODE_MANNER_MODE do we need such a thing?
+ case 0x000000ce: // KEYCODE_3D_MODE
+ case 0x000000cf: // KEYCODE_CONTACTS
+ return 0;
- case 0x000000ac: // KEYCODE_GUIDE
- return Qt::Key_Guide;
+ case 0x000000d0: // KEYCODE_CALENDAR
+ return Qt::Key_Calendar;
- case 0x000000af: // KEYCODE_CAPTIONS
- return Qt::Key_Subtitle;
+ case 0x000000d1: // KEYCODE_MUSIC
+ return Qt::Key_Music;
- case 0x000000b0: // KEYCODE_SETTINGS
- return Qt::Key_Settings;
+ case 0x000000d2: // KEYCODE_CALCULATOR
+ return Qt::Key_Calculator;
- case 0x000000d0: // KEYCODE_CALENDAR
- return Qt::Key_Calendar;
+ // 0x000000d3 -- 0x000000da some japanese specific keys, someone who understand what is about should check !
- case 0x000000d1: // KEYCODE_MUSIC
- return Qt::Key_Music;
+ // 0x000000db: // KEYCODE_ASSIST not delivered to applications.
- case 0x000000d2: // KEYCODE_CALCULATOR
- return Qt::Key_Calculator;
+ case 0x000000dc: // KEYCODE_BRIGHTNESS_DOWN
+ return Qt::Key_KeyboardBrightnessDown;
- case 0x00000000: // KEYCODE_UNKNOWN
- return Qt::Key_unknown;
+ case 0x000000dd: // KEYCODE_BRIGHTNESS_UP
+ return Qt::Key_KeyboardBrightnessUp;
- case 0x00000053: // KEYCODE_NOTIFICATION ?!?!?
- case 0x0000004f: // KEYCODE_HEADSETHOOK ?!?!?
- case 0x00000044: // KEYCODE_GRAVE ?!?!?
- return Qt::Key_Any;
+ case 0x000000de: // KEYCODE_MEDIA_AUDIO_TRACK
+ return Qt::Key_AudioCycleTrack;
- default:
- return 0;
+ default:
+ qWarning() << "Unhandled key code " << key << "!";
+ return 0;
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index 289480c625..152a06c99d 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -71,7 +71,8 @@ bool QAndroidPlatformOpenGLContext::needsFBOReadBackWorkaroud()
const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
needsWorkaround =
qstrcmp(rendererString, "Mali-400 MP") == 0
- || qstrcmp(rendererString, "Adreno (TM) 200") == 0;
+ || qstrcmp(rendererString, "Adreno (TM) 200") == 0
+ || qstrcmp(rendererString, "GC1000 core") == 0;
set = true;
}
diff --git a/src/plugins/platforms/cocoa/messages.cpp b/src/plugins/platforms/cocoa/messages.cpp
index 1fe80b28b1..8fc8b312f5 100644
--- a/src/plugins/platforms/cocoa/messages.cpp
+++ b/src/plugins/platforms/cocoa/messages.cpp
@@ -90,6 +90,14 @@ QPlatformMenuItem::MenuRole detectMenuRole(const QString &caption)
|| caption.startsWith(QCoreApplication::translate("QCocoaMenuItem", "Exit"), Qt::CaseInsensitive)) {
return QPlatformMenuItem::QuitRole;
}
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Cut"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::CutRole;
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Copy"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::CopyRole;
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Paste"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::PasteRole;
+ if (!caption.compare(QCoreApplication::translate("QCocoaMenuItem", "Select All"), Qt::CaseInsensitive))
+ return QPlatformMenuItem::SelectAllRole;
return QPlatformMenuItem::NoRole;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index 86bb5323a7..a78901bfb1 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -79,7 +79,7 @@ namespace QCocoaAccessible {
NSString *macRole(QAccessibleInterface *interface);
bool shouldBeIgnored(QAccessibleInterface *interface);
-NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface);
+NSArray *unignoredChildren(QAccessibleInterface *interface);
NSString *getTranslatedAction(const QString &qtAction);
NSMutableArray *createTranslatedActionsList(const QStringList &qtActions);
QString translateAction(NSString *nsAction);
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 990acd5301..72045a1bbb 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -55,19 +55,31 @@ QCocoaAccessibility::~QCocoaAccessibility()
void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
- QAccessible::Id interfaceId = event->uniqueId();
- if (!interfaceId)
+ QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: event->uniqueId()];
+ if (!element) {
+ qWarning() << "QCocoaAccessibility::notifyAccessibilityUpdate: invalid element";
return;
+ }
switch (event->type()) {
- case QAccessible::ValueChanged:
- case QAccessible::TextInserted :
- case QAccessible::TextRemoved :
- case QAccessible::TextUpdated : {
- QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId : interfaceId parent : nil];
- [element autorelease];
- NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification);
- break; }
+ case QAccessible::Focus: {
+ NSAccessibilityPostNotification(element, NSAccessibilityFocusedUIElementChangedNotification);
+ break;
+ }
+ case QAccessible::StateChanged:
+ case QAccessible::ValueChanged:
+ case QAccessible::TextInserted:
+ case QAccessible::TextRemoved:
+ case QAccessible::TextUpdated:
+ NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification);
+ break;
+ case QAccessible::TextCaretMoved:
+ case QAccessible::TextSelectionChanged:
+ NSAccessibilityPostNotification(element, NSAccessibilitySelectedTextChangedNotification);
+ break;
+ case QAccessible::NameChanged:
+ NSAccessibilityPostNotification(element, NSAccessibilityTitleChangedNotification);
+ break;
default:
break;
}
@@ -218,7 +230,7 @@ bool shouldBeIgnored(QAccessibleInterface *interface)
return false;
}
-NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface)
+NSArray *unignoredChildren(QAccessibleInterface *interface)
{
int numKids = interface->childCount();
// qDebug() << "Children for: " << axid << iface << " are: " << numKids;
@@ -231,9 +243,12 @@ NSArray *unignoredChildren(id parentObject, QAccessibleInterface *interface)
QAccessible::Id childId = QAccessible::uniqueId(child);
//qDebug() << " kid: " << childId << child;
- QCocoaAccessibleElement *element = [QCocoaAccessibleElement createElementWithId:childId parent:parentObject];
- [kids addObject: element];
- [element release];
+
+ QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: childId];
+ if (element)
+ [kids addObject: element];
+ else
+ qWarning() << "QCocoaAccessibility: invalid child";
}
return NSAccessibilityUnignoredChildren(kids);
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
index c207cbee2d..babaab5ae2 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
@@ -52,12 +52,11 @@
@interface QCocoaAccessibleElement : NSObject {
NSString *role;
- NSObject *parent;
QAccessible::Id axid;
}
-- (id)initWithId:(QAccessible::Id)anId parent:(id)aParent;
-+ (QCocoaAccessibleElement *)createElementWithId:(QAccessible::Id)anId parent:(id)aParent;
+- (id)initWithId:(QAccessible::Id)anId;
++ (QCocoaAccessibleElement *)elementWithId:(QAccessible::Id)anId;
@end
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 0b674b8d2f..1df4230385 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -41,6 +41,8 @@
#include "qcocoaaccessibilityelement.h"
#include "qcocoaaccessibility.h"
#include "qcocoahelpers.h"
+#include "qcocoawindow.h"
+#include "private/qaccessiblecache_p.h"
#include <QtGui/qaccessible.h>
@@ -48,7 +50,7 @@
@implementation QCocoaAccessibleElement
-- (id)initWithId:(QAccessible::Id)anId parent:(id)aParent
+- (id)initWithId:(QAccessible::Id)anId
{
Q_ASSERT((int)anId < 0);
self = [super init];
@@ -57,15 +59,35 @@
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
Q_ASSERT(iface);
role = QCocoaAccessible::macRole(iface);
- parent = aParent;
}
return self;
}
-+ (QCocoaAccessibleElement *)createElementWithId:(QAccessible::Id)anId parent:(id)aParent
++ (id)elementWithId:(QAccessible::Id)anId
{
- return [[self alloc] initWithId:anId parent:aParent];
+ Q_ASSERT(anId);
+ if (!anId)
+ return nil;
+
+ QAccessibleCache *cache = QAccessibleCache::instance();
+
+ QCocoaAccessibleElement *element = cache->elementForId(anId);
+ if (!element) {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(anId);
+ Q_ASSERT(iface);
+ if (!iface)
+ return nil;
+ element = [[self alloc] initWithId:anId];
+ cache->insertElement(anId, element);
+ }
+ return element;
+}
+
+- (void)invalidate {
+ axid = 0;
+ NSAccessibilityPostNotification(self, NSAccessibilityUIElementDestroyedNotification);
+ [self release];
}
- (void)dealloc {
@@ -98,6 +120,10 @@
return [NSNumber numberWithInt: newlines];
}
+- (BOOL) accessibilityNotifiesWhenDestroyed {
+ return YES;
+}
+
- (NSArray *)accessibilityAttributeNames {
static NSArray *defaultAttributes = nil;
@@ -116,6 +142,7 @@
NSAccessibilityTopLevelUIElementAttribute,
NSAccessibilityPositionAttribute,
NSAccessibilitySizeAttribute,
+ NSAccessibilityTitleAttribute,
NSAccessibilityDescriptionAttribute,
NSAccessibilityEnabledAttribute,
nil];
@@ -144,6 +171,26 @@
return [attributes autorelease];
}
+- (id)parentElement {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+ if (!iface)
+ return nil;
+
+ if (QWindow *window = iface->window()) {
+ QCocoaWindow *win = static_cast<QCocoaWindow*>(window->handle());
+ return win->qtView();
+ }
+
+ QAccessibleInterface *parent = iface->parent();
+ if (!parent) {
+ qWarning() << "INVALID PARENT FOR INTERFACE: " << iface;
+ return nil;
+ }
+
+ QAccessible::Id parentId = QAccessible::uniqueId(parent);
+ return [QCocoaAccessibleElement elementWithId: parentId];
+}
+
- (id)accessibilityAttributeValue:(NSString *)attribute {
QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
if (!iface) {
@@ -156,19 +203,19 @@
} else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
return NSAccessibilityRoleDescription(role, nil);
} else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
- return QCocoaAccessible::unignoredChildren(self, iface);
+ return QCocoaAccessible::unignoredChildren(iface);
} else if ([attribute isEqualToString:NSAccessibilityFocusedAttribute]) {
// Just check if the app thinks we're focused.
id focusedElement = [NSApp accessibilityAttributeValue:NSAccessibilityFocusedUIElementAttribute];
return [NSNumber numberWithBool:[focusedElement isEqual:self]];
} else if ([attribute isEqualToString:NSAccessibilityParentAttribute]) {
- return NSAccessibilityUnignoredAncestor(parent);
+ return NSAccessibilityUnignoredAncestor([self parentElement]);
} else if ([attribute isEqualToString:NSAccessibilityWindowAttribute]) {
// We're in the same window as our parent.
- return [parent accessibilityAttributeValue:NSAccessibilityWindowAttribute];
+ return [[self parentElement] accessibilityAttributeValue:NSAccessibilityWindowAttribute];
} else if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute]) {
// We're in the same top level element as our parent.
- return [parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
+ return [[self parentElement] accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute];
} else if ([attribute isEqualToString:NSAccessibilityPositionAttribute]) {
QPoint qtPosition = iface->rect().topLeft();
QSize qtSize = iface->rect().size();
@@ -176,8 +223,10 @@
} else if ([attribute isEqualToString:NSAccessibilitySizeAttribute]) {
QSize qtSize = iface->rect().size();
return [NSValue valueWithSize: NSMakeSize(qtSize.width(), qtSize.height())];
- } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
+ } else if ([attribute isEqualToString:NSAccessibilityTitleAttribute]) {
return QCFString::toNSString(iface->text(QAccessible::Name));
+ } else if ([attribute isEqualToString:NSAccessibilityDescriptionAttribute]) {
+ return QCFString::toNSString(iface->text(QAccessible::Description));
} else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) {
return [NSNumber numberWithBool:!iface->state().disabled];
} else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
@@ -400,20 +449,26 @@
return NSAccessibilityUnignoredAncestor(self);
}
- QAccessibleInterface *childInterface = iface->childAt(point.x, qt_mac_flipYCoordinate(point.y));
-
+ int y = qt_mac_flipYCoordinate(point.y);
+ QAccessibleInterface *childInterface = iface->childAt(point.x, y);
// No child found, meaning we hit this element.
- if (!childInterface) {
-// qDebug() << "Hit test returns: " << id << iface;
+ if (!childInterface)
return NSAccessibilityUnignoredAncestor(self);
- }
+
+ // find the deepest child at the point
+ QAccessibleInterface *childOfChildInterface = 0;
+ do {
+ childOfChildInterface = childInterface->childAt(point.x, y);
+ if (childOfChildInterface)
+ childInterface = childOfChildInterface;
+ } while (childOfChildInterface);
QAccessible::Id childId = QAccessible::uniqueId(childInterface);
// hit a child, forward to child accessible interface.
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childId parent:self];
- [accessibleElement autorelease];
-
- return [accessibleElement accessibilityHitTest:point];
+ QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childId];
+ if (accessibleElement)
+ return NSAccessibilityUnignoredAncestor(accessibleElement);
+ return NSAccessibilityUnignoredAncestor(self);
}
- (id)accessibilityFocusedUIElement {
@@ -423,17 +478,15 @@
qWarning() << "FocusedUIElement for INVALID";
return nil;
}
+
QAccessibleInterface *childInterface = iface->focusChild();
if (childInterface) {
QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
- // FIXME: parent could be wrong
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self];
- [accessibleElement autorelease];
- return accessibleElement;
+ QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childAxid];
+ return NSAccessibilityUnignoredAncestor(accessibleElement);
}
- // no focus found
- return nil;
+ return NSAccessibilityUnignoredAncestor(self);
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index 592bfc8e50..b81b9a0b1c 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -308,8 +308,7 @@ NSCursor *QCocoaCursor::createCursorFromBitmap(const QBitmap *bitmap, const QBit
NSCursor *QCocoaCursor::createCursorFromPixmap(const QPixmap pixmap, const QPoint hotspot)
{
- NSPoint hotSpot = NSMakePoint(hotspot.x() / pixmap.devicePixelRatio(),
- hotspot.y() / pixmap.devicePixelRatio());
+ NSPoint hotSpot = NSMakePoint(hotspot.x(), hotspot.y());
NSImage *nsimage;
if (pixmap.devicePixelRatio() > 1.0) {
QSize layoutSize = pixmap.size() / pixmap.devicePixelRatio();
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 8728ab8764..2b7b8109ad 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -52,6 +52,7 @@
#include <private/qguiapplication_p.h>
#include "qt_mac_p.h"
#include "qcocoahelpers.h"
+#include "qcocoamenubar.h"
#include <qregexp.h>
#include <qbuffer.h>
#include <qdebug.h>
@@ -225,6 +226,7 @@ static QString strippedText(QString s)
|| [self panel:nil shouldShowFilename:filepath];
[self updateProperties];
+ QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mOpenPanel setAllowedFileTypes:nil];
[mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
@@ -250,7 +252,9 @@ static QString strippedText(QString s)
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
// close down during the cleanup.
qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
+ QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
mReturnCode = [mSavePanel runModal];
+ QCocoaMenuBar::resetKnownMenuItemsToQt();
QAbstractEventDispatcher::instance()->interrupt();
return (mReturnCode == NSOKButton);
@@ -269,6 +273,7 @@ static QString strippedText(QString s)
|| [self panel:nil shouldShowFilename:filepath];
[self updateProperties];
+ QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder();
[mSavePanel setDirectoryURL: [NSURL fileURLWithPath:mCurrentDir]];
[mSavePanel setNameFieldStringValue:selectable ? QCFString::toNSString(info.fileName()) : @""];
@@ -583,6 +588,7 @@ void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_selectionChanged(const QSt
void QCocoaFileDialogHelper::QNSOpenSavePanelDelegate_panelClosed(bool accepted)
{
+ QCocoaMenuBar::resetKnownMenuItemsToQt();
if (accepted) {
emit accept();
} else {
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index a73944c07c..9850f83dea 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -74,7 +74,7 @@ void *qt_mac_QStringListToNSMutableArrayVoid(const QStringList &list)
{
NSMutableArray *result = [NSMutableArray arrayWithCapacity:list.size()];
for (int i=0; i<list.size(); ++i){
- [result addObject:reinterpret_cast<const NSString *>(QCFString::toCFStringRef(list[i]))];
+ [result addObject:list[i].toNSString()];
}
return result;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 24adc7a95b..9c4f86d893 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -80,6 +80,7 @@ public:
qreal refreshRate() const { return m_refreshRate; }
QString name() const { return m_name; }
QPlatformCursor *cursor() const { return m_cursor; }
+ QWindow *topLevelAt(const QPoint &point) const;
QList<QPlatformScreen *> virtualSiblings() const { return m_siblings; }
// ----------------------------------------------------
@@ -138,6 +139,8 @@ public:
void setToolbar(QWindow *window, NSToolbar *toolbar);
NSToolbar *toolbar(QWindow *window) const;
void clearToolbars();
+ void setWindow(NSWindow* nsWindow, QCocoaWindow *window);
+ QCocoaWindow *window(NSWindow *window);
private:
static QCocoaIntegration *mInstance;
@@ -156,6 +159,7 @@ private:
QScopedPointer<QCocoaKeyMapper> mKeyboardMapper;
QHash<QWindow *, NSToolbar *> mToolbars;
+ QHash<NSWindow *, QCocoaWindow*> mWindows;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 412818ae47..c4398622e8 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -81,12 +81,16 @@ QCocoaScreen::~QCocoaScreen()
NSScreen *QCocoaScreen::osScreen() const
{
- return [[NSScreen screens] objectAtIndex:m_screenIndex];
+ NSArray *screens = [NSScreen screens];
+ return ((NSUInteger)m_screenIndex < [screens count]) ? [screens objectAtIndex:m_screenIndex] : nil;
}
void QCocoaScreen::updateGeometry()
{
NSScreen *nsScreen = osScreen();
+ if (!nsScreen)
+ return;
+
NSRect frameRect = [nsScreen frame];
if (m_screenIndex == 0) {
@@ -143,7 +147,8 @@ qreal QCocoaScreen::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
- return qreal([osScreen() backingScaleFactor]);
+ NSScreen * screen = osScreen();
+ return qreal(screen ? [screen backingScaleFactor] : 1.0);
} else
#endif
{
@@ -151,6 +156,24 @@ qreal QCocoaScreen::devicePixelRatio() const
}
}
+QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
+{
+ // Get a z-ordered list of windows. Iterate through it until
+ // we find a window which contains the point.
+ for (NSWindow *nsWindow in [NSApp orderedWindows]) {
+ QCocoaWindow *cocoaWindow = QCocoaIntegration::instance()->window(nsWindow);
+ if (!cocoaWindow)
+ continue;
+ QWindow *window = cocoaWindow->window();
+ if (!window->isTopLevel())
+ continue;
+ if (window->geometry().contains(point))
+ return window;
+ }
+
+ return QPlatformScreen::topLevelAt(point);
+}
+
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height) const
@@ -495,6 +518,16 @@ NSToolbar *QCocoaIntegration::toolbar(QWindow *window) const
return mToolbars.value(window);
}
+void QCocoaIntegration::setWindow(NSWindow* nsWindow, QCocoaWindow *window)
+{
+ mWindows.insert(nsWindow, window);
+}
+
+QCocoaWindow *QCocoaIntegration::window(NSWindow *window)
+{
+ return mWindows.value(window);
+}
+
void QCocoaIntegration::clearToolbars()
{
QHash<QWindow *, NSToolbar *>::const_iterator it = mToolbars.constBegin();
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 35e8fdebb4..6acc062eb9 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -269,7 +269,6 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
QCocoaMenuItem *cocoaItem = static_cast<QCocoaMenuItem *>(menuItem);
QCocoaMenuItem *beforeItem = static_cast<QCocoaMenuItem *>(before);
- SET_COCOA_MENU_ANCESTOR(menuItem, this);
cocoaItem->sync();
if (beforeItem) {
int index = m_menuItems.indexOf(beforeItem);
@@ -315,6 +314,7 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
} else {
[m_nativeMenu addItem: item->nsItem()];
}
+ SET_COCOA_MENU_ANCESTOR(item, this);
}
void QCocoaMenu::removeMenuItem(QPlatformMenuItem *menuItem)
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.h b/src/plugins/platforms/cocoa/qcocoamenubar.h
index 7a1bda74a4..fa02a7870b 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.h
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.h
@@ -67,9 +67,13 @@ public:
inline NSMenu *nsMenu() const
{ return m_nativeMenu; }
+ static void redirectKnownMenuItemsToFirstResponder();
+ static void resetKnownMenuItemsToQt();
static void updateMenuBarImmediately();
QList<QCocoaMenuItem*> merged() const;
+ NSMenuItem *itemForRole(QPlatformMenuItem::MenuRole r);
+
private:
static QCocoaWindow *findWindowForMenubar();
static QCocoaMenuBar *findGlobalMenubar();
diff --git a/src/plugins/platforms/cocoa/qcocoamenubar.mm b/src/plugins/platforms/cocoa/qcocoamenubar.mm
index 7335deb800..ffc0fabdce 100644
--- a/src/plugins/platforms/cocoa/qcocoamenubar.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenubar.mm
@@ -205,6 +205,59 @@ QCocoaMenuBar *QCocoaMenuBar::findGlobalMenubar()
return NULL;
}
+void QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder()
+{
+ // QTBUG-17291: http://forums.macrumors.com/showthread.php?t=1249452
+ // When a dialog is opened, shortcuts for actions inside the dialog (cut, paste, ...)
+ // continue to go through the same menu items which claimed those shortcuts.
+ // They are not keystrokes which we can intercept in any other way; the OS intercepts them.
+ // The menu items had to be created by the application. That's why we need roles
+ // to identify those "special" menu items which can be useful even when non-Qt
+ // native widgets are in focus. When the native widget is focused it will be the
+ // first responder, so the menu item needs to have its target be the first responder;
+ // this is done by setting it to nil.
+
+ // This function will find all menu items on all menus which have
+ // "special" roles, set the target and also set the standard actions which
+ // apply to those roles. But afterwards it is necessary to call
+ // resetKnownMenuItemsToQt() to put back the target and action so that
+ // those menu items will go back to invoking their associated QActions.
+ foreach (QCocoaMenuBar *mb, static_menubars)
+ foreach (QCocoaMenu *m, mb->m_menus)
+ foreach (QCocoaMenuItem *i, m->items()) {
+ bool known = true;
+ switch (i->effectiveRole()) {
+ case QPlatformMenuItem::CutRole:
+ [i->nsItem() setAction:@selector(cut:)];
+ break;
+ case QPlatformMenuItem::CopyRole:
+ [i->nsItem() setAction:@selector(copy:)];
+ break;
+ case QPlatformMenuItem::PasteRole:
+ [i->nsItem() setAction:@selector(paste:)];
+ break;
+ case QPlatformMenuItem::SelectAllRole:
+ [i->nsItem() setAction:@selector(selectAll:)];
+ break;
+ // We may discover later that there are other roles/actions which
+ // are meaningful to standard native widgets; they can be added.
+ default:
+ known = false;
+ break;
+ }
+ if (known)
+ [i->nsItem() setTarget:nil];
+ }
+}
+
+void QCocoaMenuBar::resetKnownMenuItemsToQt()
+{
+ // Undo the effect of redirectKnownMenuItemsToFirstResponder():
+ // set the menu items' actions to itemFired and their targets to
+ // the QCocoaMenuDelegate.
+ updateMenuBarImmediately();
+}
+
void QCocoaMenuBar::updateMenuBarImmediately()
{
QCocoaAutoReleasePool pool;
@@ -321,3 +374,13 @@ QPlatformMenu *QCocoaMenuBar::menuForTag(quintptr tag) const
return 0;
}
+
+NSMenuItem *QCocoaMenuBar::itemForRole(QPlatformMenuItem::MenuRole r)
+{
+ foreach (QCocoaMenu *m, m_menus)
+ foreach (QCocoaMenuItem *i, m->items())
+ if (i->effectiveRole() == r)
+ return i->nsItem();
+ return Q_NULLPTR;
+}
+
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.h b/src/plugins/platforms/cocoa/qcocoamenuitem.h
index b0169b9746..61706c19bc 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.h
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.h
@@ -98,6 +98,8 @@ public:
inline bool isSeparator() const { return m_isSeparator; }
QCocoaMenu *menu() const { return m_menu; }
+ MenuRole effectiveRole() const;
+
private:
QString mergeText();
QKeySequence mergeAccel();
@@ -112,6 +114,7 @@ private:
bool m_isSeparator;
QFont m_font;
MenuRole m_role;
+ MenuRole m_detectedRole;
QKeySequence m_shortcut;
bool m_checked;
bool m_merged;
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 2246d2ce46..58fe07bc62 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -227,7 +227,8 @@ NSMenuItem *QCocoaMenuItem::sync()
if (depth == 3 || !menubar)
break; // Menu item too deep in the hierarchy, or not connected to any menubar
- switch (detectMenuRole(m_text)) {
+ m_detectedRole = detectMenuRole(m_text);
+ switch (m_detectedRole) {
case QPlatformMenuItem::AboutRole:
if (m_text.indexOf(QRegExp(QString::fromLatin1("qt$"), Qt::CaseInsensitive)) == -1)
mergeItem = [loader aboutMenuItem];
@@ -241,6 +242,8 @@ NSMenuItem *QCocoaMenuItem::sync()
mergeItem = [loader quitMenuItem];
break;
default:
+ if (m_detectedRole >= CutRole && m_detectedRole < RoleCount && menubar)
+ mergeItem = menubar->itemForRole(m_detectedRole);
if (!m_text.isEmpty())
m_textSynced = true;
break;
@@ -249,7 +252,7 @@ NSMenuItem *QCocoaMenuItem::sync()
}
default:
- qWarning() << Q_FUNC_INFO << "unsupported role" << (int) m_role;
+ qWarning() << Q_FUNC_INFO << "menu item" << m_text << "has unsupported role" << (int)m_role;
}
if (mergeItem) {
@@ -374,3 +377,11 @@ void QCocoaMenuItem::syncModalState(bool modal)
else
[m_native setEnabled:m_enabled];
}
+
+QPlatformMenuItem::MenuRole QCocoaMenuItem::effectiveRole() const
+{
+ if (m_role > TextHeuristicRole)
+ return m_role;
+ else
+ return m_detectedRole;
+}
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 29fc0fb674..60bc3b5a55 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -115,14 +115,13 @@ QT_END_NAMESPACE
showAllItem = [[appMenu itemWithTitle:@"Show All"] retain];
// Get the names in the nib to match the app name set by Qt.
- const NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qt_mac_applicationName()));
+ const NSString *appName = qt_mac_applicationName().toNSString();
[quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
withString:const_cast<NSString *>(appName)]];
[hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
withString:const_cast<NSString *>(appName)]];
[aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
withString:const_cast<NSString *>(appName)]];
- [appName release];
// Disable the items that don't do anything. If someone associates a QAction with them
// They should get synced back in.
[preferencesItem setEnabled:NO];
diff --git a/src/plugins/platforms/cocoa/qcocoamimetypes.mm b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
index 05d4c19112..8151d31449 100644
--- a/src/plugins/platforms/cocoa/qcocoamimetypes.mm
+++ b/src/plugins/platforms/cocoa/qcocoamimetypes.mm
@@ -136,9 +136,76 @@ QList<QByteArray> QMacPasteboardMimeTiff::convertFromMime(const QString &mime, Q
return ret;
}
+// This handler is special: It supports converting public.rtf top text/html,
+// but not the other way around.
+class QMacPasteboardMimeRtfText : public QMacInternalPasteboardMime {
+public:
+ QMacPasteboardMimeRtfText() : QMacInternalPasteboardMime(MIME_ALL) { }
+ QString convertorName();
+
+ QString flavorFor(const QString &mime);
+ QString mimeFor(QString flav);
+ bool canConvert(const QString &mime, QString flav);
+ QVariant convertToMime(const QString &mime, QList<QByteArray> data, QString flav);
+ QList<QByteArray> convertFromMime(const QString &mime, QVariant data, QString flav);
+};
+
+QString QMacPasteboardMimeRtfText::convertorName()
+{
+ return QLatin1String("Rtf");
+}
+
+QString QMacPasteboardMimeRtfText::flavorFor(const QString &mime)
+{
+ if (mime == QLatin1String("text/html"))
+ return QLatin1String("public.rtf");
+ return QString();
+}
+
+QString QMacPasteboardMimeRtfText::mimeFor(QString flav)
+{
+ if (flav == QLatin1String("public.rtf"))
+ return QLatin1String("text/html");
+ return QString();
+}
+
+bool QMacPasteboardMimeRtfText::canConvert(const QString &mime, QString flav)
+{
+ return flavorFor(mime) == flav;
+}
+
+QVariant QMacPasteboardMimeRtfText::convertToMime(const QString &mimeType, QList<QByteArray> data, QString flavor)
+{
+ if (!canConvert(mimeType, flavor))
+ return QVariant();
+ if (data.count() > 1)
+ qWarning("QMacPasteboardMimeHTMLText: Cannot handle multiple member data");
+
+ // Convert Rtf to Html.
+ NSAttributedString *string = [[NSAttributedString alloc] initWithRTF:data.at(0).toNSData() documentAttributes:NULL];
+ NSError *error;
+ NSRange range = NSMakeRange(0,[string length]);
+ NSDictionary *dict = [NSDictionary dictionaryWithObject:NSHTMLTextDocumentType forKey:NSDocumentTypeDocumentAttribute];
+ NSData *htmldata = [string dataFromRange:range documentAttributes:dict error:&error];
+ [string release];
+ return QByteArray::fromNSData(htmldata);
+}
+
+QList<QByteArray> QMacPasteboardMimeRtfText::convertFromMime(const QString &mime, QVariant data, QString flavor)
+{
+ Q_UNUSED(mime);
+ Q_UNUSED(data);
+ Q_UNUSED(flavor);
+
+ qWarning("QMacPasteboardMimeRtfText: Conversion from Html to Rtf is not supported");
+ QList<QByteArray> ret;
+ return ret;
+}
+
void QCocoaMimeTypes::initializeMimeTypes()
{
new QMacPasteboardMimeTiff;
+ new QMacPasteboardMimeRtfText;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index efdd433d8f..54e45a1d99 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -133,16 +133,23 @@ private:
// deregisters.
static void registerTouchWindow(QWindow *window, bool enable);
- // Request a unified title and toolbar look for the window.
+ // Enable the unified title and toolbar area for a window.
+ static void setContentBorderEnabled(QWindow *window, bool enable);
+
+ // Set the size of the unified title and toolbar area.
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
+ // Set the size for a unified toolbar content border 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);
+ // Enables or disiables a content border area.
+ static void setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable);
+
+ // Returns true if the given coordinate is inside the current
+ // content border.
+ static bool testContentBorderPosition(QWindow *window, int position);
// Sets a NSToolbar instance for the given QWindow. The
// toolbar will be attached to the native NSWindow when
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index d6a5be8d52..e09c31231d 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -127,10 +127,14 @@ QPlatformNativeInterface::NativeResourceForIntegrationFunction QCocoaNativeInter
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderThickness);
if (resource.toLower() == "registercontentborderarea")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::registerContentBorderArea);
- if (resource.toLower() == "enablecontentborderarea")
- return NativeResourceForIntegrationFunction(QCocoaNativeInterface::enableContentBorderArea);
+ if (resource.toLower() == "setcontentborderareaenabled")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderAreaEnabled);
+ if (resource.toLower() == "setcontentborderenabled")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setContentBorderEnabled);
if (resource.toLower() == "setnstoolbar")
return NativeResourceForIntegrationFunction(QCocoaNativeInterface::setNSToolbar);
+ if (resource.toLower() == "testcontentborderposition")
+ return NativeResourceForIntegrationFunction(QCocoaNativeInterface::testContentBorderPosition);
return 0;
}
@@ -301,14 +305,24 @@ void QCocoaNativeInterface::registerContentBorderArea(QWindow *window, quintptr
cocoaWindow->registerContentBorderArea(identifier, upper, lower);
}
-void QCocoaNativeInterface::enableContentBorderArea(QWindow *window, bool enable)
+void QCocoaNativeInterface::setContentBorderAreaEnabled(QWindow *window, quintptr identifier, bool enable)
{
if (!window)
return;
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
if (cocoaWindow)
- cocoaWindow->enableContentBorderArea(enable);
+ cocoaWindow->setContentBorderAreaEnabled(identifier, enable);
+}
+
+void QCocoaNativeInterface::setContentBorderEnabled(QWindow *window, bool enable)
+{
+ if (!window)
+ return;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ cocoaWindow->setContentBorderEnabled(enable);
}
void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
@@ -320,4 +334,15 @@ void QCocoaNativeInterface::setNSToolbar(QWindow *window, void *nsToolbar)
cocoaWindow->updateNSToolbar();
}
+bool QCocoaNativeInterface::testContentBorderPosition(QWindow *window, int position)
+{
+ if (!window)
+ return false;
+
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (cocoaWindow)
+ return cocoaWindow->testContentBorderAreaPosition(position);
+ return false;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
index 3061e84470..57d5c800e0 100644
--- a/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
+++ b/src/plugins/platforms/cocoa/qcocoaprintdevice.mm
@@ -171,15 +171,18 @@ QPrint::DeviceState QCocoaPrintDevice::state() const
QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const
{
- QCFString key;
+ CFStringRef key;
double width;
double height;
- QCFString localizedName;
+ CFStringRef 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));
+ QPageSize pageSize = QPlatformPrintDevice::createPageSize(QString::fromCFString(key),QSize(width, height),
+ QString::fromCFString(localizedName));
+ CFRelease(localizedName);
+ return pageSize;
}
return QPageSize();
}
@@ -216,10 +219,11 @@ 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);
+ if (PMCreatePageFormat(&pageFormat) == noErr) {
+ if (PMSessionDefaultPageFormat(m_session, pageFormat) == noErr
+ && PMGetPageFormatPaper(pageFormat, &paper) == noErr) {
+ pageSize = createPageSize(paper);
+ }
PMRelease(pageFormat);
}
return pageSize;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index b7a6a14d4a..bb5c0c1974 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -211,7 +211,9 @@ public:
void registerTouch(bool enable);
void setContentBorderThickness(int topThickness, int bottomThickness);
void registerContentBorderArea(quintptr identifier, int upper, int lower);
- void enableContentBorderArea(bool enable);
+ void setContentBorderAreaEnabled(quintptr identifier, bool enable);
+ void setContentBorderEnabled(bool enable);
+ bool testContentBorderAreaPosition(int position) const;
void applyContentBorderThickness(NSWindow *window);
void updateNSToolbar();
@@ -270,6 +272,7 @@ public: // for QNSView
bool m_geometryUpdateExposeAllowed;
bool m_isExposed;
QRect m_exposedGeometry;
+ qreal m_exposedDevicePixelRatio;
int m_registerTouchCount;
bool m_resizableTransientParent;
bool m_hiddenByClipping;
@@ -289,7 +292,8 @@ public: // for QNSView
NSApplicationPresentationOptions m_presentationOptions;
struct BorderRange {
- BorderRange(int u, int l) : upper(u), lower(l) { }
+ BorderRange(quintptr i, int u, int l) : identifier(i), upper(u), lower(l) { }
+ quintptr identifier;
int upper;
int lower;
bool operator<(BorderRange const& right) const {
@@ -297,6 +301,7 @@ public: // for QNSView
}
};
QHash<quintptr, BorderRange> m_contentBorderAreas; // identifer -> uppper/lower
+ QHash<quintptr, bool> m_enabledContentBorderAreas; // identifer -> enabled state (true/false)
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index b27e1b03db..5def64ee0a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -261,6 +261,8 @@ static bool isMouseEvent(NSEvent *ev)
{
[self close];
+ QCocoaIntegration::instance()->setWindow(self, 0);
+
if (self.helper.grabbingMouse) {
self.helper.releaseOnMouseUp = YES;
} else {
@@ -327,6 +329,7 @@ static bool isMouseEvent(NSEvent *ev)
{
[self.helper detachFromPlatformWindow];
[self close];
+ QCocoaIntegration::instance()->setWindow(self, 0);
[self release];
}
@@ -619,11 +622,13 @@ void QCocoaWindow::setVisible(bool visible)
// update the window geometry if there is a parent.
setGeometry(window()->geometry());
- // Register popup windows so that the parent window can
- // close them when needed.
- if (window()->type() == Qt::Popup) {
+ // Register popup windows so that the parent window can close them when needed.
+ if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip) {
// qDebug() << "transientParent and popup" << window()->type() << Qt::Popup << (window()->type() & Qt::Popup);
parentCocoaWindow->m_activePopupWindow = window();
+ }
+
+ if (window()->type() == Qt::Popup) {
// QTBUG-30266: a window should not be resizable while a transient popup is open
// Since this isn't a native popup, the window manager doesn't close the popup when you click outside
NSUInteger parentStyleMask = [parentCocoaWindow->m_nsWindow styleMask];
@@ -1210,11 +1215,18 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
{
bool wasNSWindowChild = m_isNSWindowChild;
- // TODO Set value for m_isNSWindowChild here
+ m_isNSWindowChild = parentWindow && (window()->property("_q_platform_MacUseNSWindow").toBool());
bool needsNSWindow = m_isNSWindowChild || !parentWindow;
QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow;
m_parentCocoaWindow = const_cast<QCocoaWindow *>(static_cast<const QCocoaWindow *>(parentWindow));
+ if (m_parentCocoaWindow && m_isNSWindowChild) {
+ QWindow *parentQWindow = m_parentCocoaWindow->window();
+ if (!parentQWindow->property("_q_platform_MacUseNSWindow").toBool()) {
+ parentQWindow->setProperty("_q_platform_MacUseNSWindow", QVariant(true));
+ m_parentCocoaWindow->recreateWindow(m_parentCocoaWindow->m_parentCocoaWindow);
+ }
+ }
bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
@@ -1400,6 +1412,8 @@ QCocoaNSWindow * QCocoaWindow::createNSWindow()
applyContentBorderThickness(createdWindow);
+ QCocoaIntegration::instance()->setWindow(createdWindow, this);
+
return createdWindow;
}
@@ -1466,7 +1480,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) {
if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) {
- [m_nsWindow performZoom : m_nsWindow]; // toggles
+ [m_nsWindow zoom : m_nsWindow]; // toggles
m_effectivelyMaximized = !m_effectivelyMaximized;
} else if (!(newState & Qt::WindowMaximized)) {
// it would be nice to change the target geometry that toggleFullScreen will animate toward
@@ -1582,28 +1596,17 @@ void QCocoaWindow::setContentBorderThickness(int topThickness, int bottomThickne
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_contentBorderAreas.insert(identifier, BorderRange(identifier, upper, lower));
+ applyContentBorderThickness(m_nsWindow);
+}
- m_bottomContentBorderThickness = 0; // (not supported)
- if (m_drawContentBorderGradient)
- applyContentBorderThickness(m_nsWindow);
+void QCocoaWindow::setContentBorderAreaEnabled(quintptr identifier, bool enable)
+{
+ m_enabledContentBorderAreas.insert(identifier, enable);
+ applyContentBorderThickness(m_nsWindow);
}
-void QCocoaWindow::enableContentBorderArea(bool enable)
+void QCocoaWindow::setContentBorderEnabled(bool enable)
{
m_drawContentBorderGradient = enable;
applyContentBorderThickness(m_nsWindow);
@@ -1619,17 +1622,33 @@ void QCocoaWindow::applyContentBorderThickness(NSWindow *window)
return;
}
- [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
+ // Find consecutive registered border areas, starting from the top.
+ QList<BorderRange> ranges = m_contentBorderAreas.values();
+ std::sort(ranges.begin(), ranges.end());
+ int effectiveTopContentBorderThickness = m_topContentBorderThickness;
+ foreach (BorderRange range, ranges) {
+ // Skip disiabled ranges (typically hidden tool bars)
+ if (!m_enabledContentBorderAreas.value(range.identifier, false))
+ continue;
- if (m_topContentBorderThickness > 0) {
- [window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMaxYEdge];
- [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
+ // 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 <= (effectiveTopContentBorderThickness + 1))
+ effectiveTopContentBorderThickness = qMax(effectiveTopContentBorderThickness, range.lower);
+ else
+ break;
}
- if (m_bottomContentBorderThickness > 0) {
- [window setContentBorderThickness:m_topContentBorderThickness forEdge:NSMinYEdge];
- [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
- }
+ int effectiveBottomContentBorderThickness = m_bottomContentBorderThickness;
+
+ [window setStyleMask:[window styleMask] | NSTexturedBackgroundWindowMask];
+
+ [window setContentBorderThickness:effectiveTopContentBorderThickness forEdge:NSMaxYEdge];
+ [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge];
+
+ [window setContentBorderThickness:effectiveBottomContentBorderThickness forEdge:NSMinYEdge];
+ [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMinYEdge];
}
void QCocoaWindow::updateNSToolbar()
@@ -1646,6 +1665,12 @@ void QCocoaWindow::updateNSToolbar()
[m_nsWindow setShowsToolbarButton:YES];
}
+bool QCocoaWindow::testContentBorderAreaPosition(int position) const
+{
+ return m_nsWindow && m_drawContentBorderGradient &&
+ 0 <= position && position < [m_nsWindow contentBorderThicknessForEdge: NSMaxYEdge];
+}
+
qreal QCocoaWindow::devicePixelRatio() const
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
@@ -1685,6 +1710,7 @@ void QCocoaWindow::exposeWindow()
if (!m_isExposed) {
m_isExposed = true;
m_exposedGeometry = geometry();
+ m_exposedDevicePixelRatio = devicePixelRatio();
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
}
@@ -1710,11 +1736,12 @@ void QCocoaWindow::updateExposedGeometry()
if (!isWindowExposable())
return;
- if (m_exposedGeometry == geometry())
+ if (m_exposedGeometry == geometry() && m_exposedDevicePixelRatio == devicePixelRatio())
return;
m_isExposed = true;
m_exposedGeometry = geometry();
+ m_exposedDevicePixelRatio = devicePixelRatio();
QWindowSystemInterface::handleExposeEvent(window(), QRegion(geometry()));
}
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index 9368b65866..6549f127b6 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -305,6 +305,11 @@ QMacPasteboard::setMimeData(QMimeData *mime_src)
QString mimeType = formats.at(f);
for (QList<QMacInternalPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) {
QMacInternalPasteboardMime *c = (*it);
+ // Hack: The Rtf handler converts incoming Rtf to Html. We do
+ // not want to convert outgoing Html to Rtf but instead keep
+ // posting it as Html. Skip the Rtf handler here.
+ if (c->convertorName() == QStringLiteral("Rtf"))
+ continue;
QString flavor(c->flavorFor(mimeType));
if (!flavor.isEmpty()) {
QVariant mimeData = static_cast<QMacMimeData*>(mime_src)->variantData(mimeType);
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 1197aa9148..0b9683a3ef 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -329,6 +329,7 @@ static QTouchDevice *touchDevice = 0;
if (m_window) {
NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
if (screenIndex != NSNotFound) {
+ m_platformWindow->updateExposedGeometry();
QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
QWindowSystemInterface::handleWindowScreenChanged(m_window, cocoaScreen->screen());
}
@@ -371,8 +372,9 @@ static QTouchDevice *touchDevice = 0;
{
m_backingStore = backingStore;
m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio();
- QRect br = region.boundingRect();
- [self setNeedsDisplayInRect:NSMakeRect(br.x(), br.y(), br.width(), br.height())];
+ foreach (QRect rect, region.rects()) {
+ [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
+ }
}
- (BOOL) hasMask
@@ -1647,6 +1649,21 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
}
}
+static QWindow *findEventTargetWindow(QWindow *candidate)
+{
+ while (candidate) {
+ if (!(candidate->flags() & Qt::WindowTransparentForInput))
+ return candidate;
+ candidate = candidate->parent();
+ }
+ return candidate;
+}
+
+static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint point)
+{
+ return target->mapFromGlobal(source->mapToGlobal(point));
+}
+
- (NSDragOperation) draggingSourceOperationMaskForLocal:(BOOL)isLocal
{
Q_UNUSED(isLocal);
@@ -1676,16 +1693,18 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
+ QWindow *target = findEventTargetWindow(m_window);
+
// update these so selecting move/copy/link works
QGuiApplicationPrivate::modifier_buttons = [QNSView convertKeyModifiers: [[NSApp currentEvent] modifierFlags]];
QPlatformDragQtResponse response(false, Qt::IgnoreAction, QRect());
if ([sender draggingSource] != nil) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- response = QWindowSystemInterface::handleDrag(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrag(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
- response = QWindowSystemInterface::handleDrag(m_window, &mimeData, qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrag(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
}
return qt_mac_mapDropAction(response.acceptedAction());
@@ -1693,16 +1712,20 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
+ QWindow *target = findEventTargetWindow(m_window);
+
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
// Send 0 mime data to indicate drag exit
- QWindowSystemInterface::handleDrag(m_window, 0 ,qt_windowPoint, Qt::IgnoreAction);
+ QWindowSystemInterface::handleDrag(target, 0, mapWindowCoordinates(m_window, target, qt_windowPoint), Qt::IgnoreAction);
}
// called on drop, send the drop to Qt and return if it was accepted.
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
+ QWindow *target = findEventTargetWindow(m_window);
+
NSPoint windowPoint = [self convertPoint: [sender draggingLocation] fromView: nil];
QPoint qt_windowPoint(windowPoint.x, windowPoint.y);
Qt::DropActions qtAllowed = qt_mac_mapNSDragOperations([sender draggingSourceOperationMask]);
@@ -1710,10 +1733,10 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QPlatformDropQtResponse response(false, Qt::IgnoreAction);
if ([sender draggingSource] != nil) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
- response = QWindowSystemInterface::handleDrop(m_window, nativeDrag->platformDropData(), qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrop(target, nativeDrag->platformDropData(), mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
} else {
QCocoaDropData mimeData([sender draggingPasteboard]);
- response = QWindowSystemInterface::handleDrop(m_window, &mimeData, qt_windowPoint, qtAllowed);
+ response = QWindowSystemInterface::handleDrop(target, &mimeData, mapWindowCoordinates(m_window, target, qt_windowPoint), qtAllowed);
}
if (response.isAccepted()) {
QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag();
@@ -1726,6 +1749,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
{
Q_UNUSED(img);
Q_UNUSED(operation);
+ QWindow *target = findEventTargetWindow(m_window);
// keep our state, and QGuiApplication state (buttons member) in-sync,
// or future mouse events will be processed incorrectly
@@ -1738,7 +1762,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
NSPoint screenPoint = [window convertBaseToScreen :point];
QPoint qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
- QWindowSystemInterface::handleMouseEvent(m_window, qtWindowPoint, qtScreenPoint, m_buttons);
+ QWindowSystemInterface::handleMouseEvent(target, mapWindowCoordinates(m_window, target, qtWindowPoint), qtScreenPoint, m_buttons);
}
@end
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index 31e3e343b9..d18a01b11c 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -59,8 +59,7 @@
return nil;
QAccessible::Id childId = QAccessible::uniqueId(m_window->accessibleRoot());
- QCocoaAccessibleElement *child = [QCocoaAccessibleElement createElementWithId: childId parent: self];
- return [child autorelease];
+ return [QCocoaAccessibleElement elementWithId: childId];
}
// The QNSView is a container that the user does not interact directly with:
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index f1f9f5469c..9d40d166af 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -81,15 +81,14 @@ QQnxEglWindow::~QQnxEglWindow()
void QQnxEglWindow::createEGLSurface()
{
- // Fetch the surface size from the window and update
- // the window's buffers before we create the EGL surface
- const QSize surfaceSize = requestedBufferSize();
- if (!surfaceSize.isValid()) {
+ if (!m_requestedBufferSize.isValid()) {
qWarning("QQNX: Trying to create 0 size EGL surface. "
"Please set a valid window size before calling QOpenGLContext::makeCurrent()");
return;
}
- setBufferSize(surfaceSize);
+
+ // update the window's buffers before we create the EGL surface
+ setBufferSize(m_requestedBufferSize);
const EGLint eglSurfaceAttrs[] =
{
@@ -99,9 +98,10 @@ void QQnxEglWindow::createEGLSurface()
qEglWindowDebug() << "Creating EGL surface" << platformOpenGLContext()->getEglDisplay()
<< platformOpenGLContext()->getEglConfig();
+
// Create EGL surface
- m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay()
- , platformOpenGLContext()->getEglConfig(),
+ m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay(),
+ platformOpenGLContext()->getEglConfig(),
(EGLNativeWindowType) nativeHandle(), eglSurfaceAttrs);
if (m_eglSurface == EGL_NO_SURFACE) {
const EGLenum error = QQnxGLContext::checkEGLError("eglCreateWindowSurface");
@@ -171,11 +171,6 @@ void QQnxEglWindow::setGeometry(const QRect &rect)
QQnxWindow::setGeometry(newGeometry);
}
-QSize QQnxEglWindow::requestedBufferSize() const
-{
- return m_requestedBufferSize;
-}
-
void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
{
// This function does not take ownership of the platform gl context.
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h
index a6a223c58e..cd98f9369d 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.h
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.h
@@ -65,9 +65,6 @@ public:
void setGeometry(const QRect &rect);
- // Called by QQnxGLContext::createSurface()
- QSize requestedBufferSize() const;
-
protected:
int pixelFormat() const;
void resetBuffers();
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index 42318729b1..2e0febff20 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -353,37 +353,39 @@ void QQnxWindow::setBufferSize(const QSize &size)
{
qWindowDebug() << Q_FUNC_INFO << "window =" << window() << "size =" << size;
- // Set window buffer size
// libscreen fails when creating empty buffers
const QSize nonEmptySize = size.isEmpty() ? QSize(1, 1) : size;
+ int format = pixelFormat();
+
+ if (nonEmptySize == m_bufferSize || format == -1)
+ return;
+
+ Q_SCREEN_CRITICALERROR(
+ screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, &format),
+ "Failed to set window format");
+
+ if (m_bufferSize.isValid()) {
+ // destroy buffers first, if resized
+ Q_SCREEN_CRITICALERROR(screen_destroy_window_buffers(m_window),
+ "Failed to destroy window buffers");
+ }
int val[2] = { nonEmptySize.width(), nonEmptySize.height() };
Q_SCREEN_CHECKERROR(screen_set_window_property_iv(m_window, SCREEN_PROPERTY_BUFFER_SIZE, val),
"Failed to set window buffer size");
- // Create window buffers if they do not exist
- if (m_bufferSize.isEmpty()) {
- val[0] = pixelFormat();
- if (val[0] == -1) // The platform GL context was not set yet on the window, so we can't procede
- return;
-
- Q_SCREEN_CRITICALERROR(
- screen_set_window_property_iv(m_window, SCREEN_PROPERTY_FORMAT, val),
- "Failed to set window format");
+ Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
+ "Failed to create window buffers");
- Q_SCREEN_CRITICALERROR(screen_create_window_buffers(m_window, MAX_BUFFER_COUNT),
- "Failed to create window buffers");
+ // check if there are any buffers available
+ int bufferCount = 0;
+ Q_SCREEN_CRITICALERROR(
+ screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
+ "Failed to query render buffer count");
- // check if there are any buffers available
- int bufferCount = 0;
- Q_SCREEN_CRITICALERROR(
- screen_get_window_property_iv(m_window, SCREEN_PROPERTY_RENDER_BUFFER_COUNT, &bufferCount),
- "Failed to query render buffer count");
-
- if (bufferCount != MAX_BUFFER_COUNT) {
- qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d. You might experience problems.",
- MAX_BUFFER_COUNT, bufferCount);
- }
+ if (bufferCount != MAX_BUFFER_COUNT) {
+ qFatal("QQnxWindow: invalid buffer count. Expected = %d, got = %d.",
+ MAX_BUFFER_COUNT, bufferCount);
}
// Set the transparency. According to QNX technical support, setting the window
diff --git a/src/plugins/platforms/windows/qplatformfunctions_wince.h b/src/plugins/platforms/windows/qplatformfunctions_wince.h
index 30fc66563e..65ce466086 100644
--- a/src/plugins/platforms/windows/qplatformfunctions_wince.h
+++ b/src/plugins/platforms/windows/qplatformfunctions_wince.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 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.
@@ -293,8 +293,8 @@ inline void OleUninitialize()
inline DWORD GetGlyphOutline( HDC /*hdc*/, UINT /*uChar*/, INT /*fuFormat*/, GLYPHMETRICS * /*lpgm*/,
DWORD /*cjBuffer*/, LPVOID /*pvBuffer*/, CONST MAT2 * /*lpmat2*/ )
{
- qFatal("GetGlyphOutline not supported under Windows CE. Please try using freetype fontrendering, by"
- "passing -platform windows:freetype as arguments to the application.");
+ qFatal("GetGlyphOutline() not supported under Windows CE. Please try using freetype font-rendering, by "
+ "passing the command line argument -platform windows:fontengine=freetype to the application.");
return GDI_ERROR;
}
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index e7e4028079..eaa4eca84e 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -711,6 +711,8 @@ QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
minorDot = version.size();
result.version = (version.mid(0, majorDot).toInt() << 8)
+ version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
+ } else {
+ result.version = 0x0200;
}
result.profile = QSurfaceFormat::NoProfile;
if (result.version < 0x0300) {
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 1579797f85..57d6bc580b 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -94,14 +94,23 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI
, m_gc_window(0)
{
Q_XCB_NOOP(connection());
- m_xcb_image = xcb_image_create_native(xcb_connection(),
- size.width(),
- size.height(),
- XCB_IMAGE_FORMAT_Z_PIXMAP,
- depth,
- 0,
- ~0,
- 0);
+
+ const xcb_setup_t *setup = xcb_get_setup(xcb_connection());
+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
+ for (; fmt != fmtend; ++fmt)
+ if (fmt->depth == depth)
+ break;
+
+ Q_ASSERT(fmt != fmtend);
+
+ m_xcb_image = xcb_image_create(size.width(), size.height(),
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ fmt->scanline_pad,
+ fmt->depth, fmt->bits_per_pixel, 0,
+ QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST,
+ XCB_IMAGE_ORDER_MSB_FIRST,
+ 0, ~0, 0);
const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
if (!segmentSize)
@@ -209,10 +218,13 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
// at least 16384 bytes. That should be enough for quite large images.
Q_ASSERT(rows_per_put > 0);
+ // Convert the image to the native byte order.
+ xcb_image_t *converted_image = xcb_image_native(xcb_connection(), m_xcb_image, 1);
+
while (height > 0) {
int rows = std::min(height, rows_per_put);
- xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows,
+ xcb_image_t *subimage = xcb_image_subimage(converted_image, src_x, src_y, width, rows,
0, 0, 0);
xcb_image_put(xcb_connection(),
window,
@@ -228,6 +240,9 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s
target_y += rows;
height -= rows;
}
+
+ if (converted_image != m_xcb_image)
+ xcb_image_destroy(converted_image);
}
Q_XCB_NOOP(connection());
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 66b8401ea2..f5f6c712c5 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -93,10 +93,37 @@
QT_BEGIN_NAMESPACE
#ifdef XCB_USE_XLIB
+static const char * const xcbConnectionErrors[] = {
+ "No error", /* Error 0 */
+ "I/O error", /* XCB_CONN_ERROR */
+ "Unsupported extension used", /* XCB_CONN_CLOSED_EXT_NOTSUPPORTED */
+ "Out of memory", /* XCB_CONN_CLOSED_MEM_INSUFFICIENT */
+ "Maximum allowed requested length exceeded", /* XCB_CONN_CLOSED_REQ_LEN_EXCEED */
+ "Failed to parse display string", /* XCB_CONN_CLOSED_PARSE_ERR */
+ "No such screen on display", /* XCB_CONN_CLOSED_INVALID_SCREEN */
+ "Error during FD passing" /* XCB_CONN_CLOSED_FDPASSING_FAILED */
+};
+
static int nullErrorHandler(Display *, XErrorEvent *)
{
return 0;
}
+
+static int ioErrorHandler(Display *dpy)
+{
+ xcb_connection_t *conn = XGetXCBConnection(dpy);
+ if (conn != NULL) {
+ /* Print a message with a textual description of the error */
+ int code = xcb_connection_has_error(conn);
+ const char *str = "Unknown error";
+ int arrayLength = sizeof(xcbConnectionErrors) / sizeof(xcbConnectionErrors[0]);
+ if (code >= 0 && code < arrayLength)
+ str = xcbConnectionErrors[code];
+
+ qWarning("The X11 connection broke: %s (code %d)", str, code);
+ }
+ return _XDefaultIOError(dpy);
+}
#endif
QXcbScreen* QXcbConnection::findOrCreateScreen(QList<QXcbScreen *>& newScreens,
@@ -284,6 +311,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
m_connection = XGetXCBConnection(dpy);
XSetEventQueueOwner(dpy, XCBOwnsEventQueue);
XSetErrorHandler(nullErrorHandler);
+ XSetIOErrorHandler(ioErrorHandler);
m_xlib_display = dpy;
}
#else
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 92b24f4722..69601f44d4 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -663,23 +663,17 @@ void QXcbKeyboard::clearXKBConfig()
memset(&xkb_names, 0, sizeof(xkb_names));
}
-void QXcbKeyboard::printKeymapError(const QString &error) const
+void QXcbKeyboard::printKeymapError(const char *error) const
{
- qWarning() << "Qt: " << error;
- // check if XKB config root is a valid path
- const QDir xkbRoot = qEnvironmentVariableIsSet("QT_XKB_CONFIG_ROOT")
- ? QString::fromLocal8Bit(qgetenv("QT_XKB_CONFIG_ROOT"))
- : DFLT_XKB_CONFIG_ROOT;
- if (!xkbRoot.exists() || xkbRoot.dirName() != "xkb") {
- qWarning() << "Set QT_XKB_CONFIG_ROOT to provide a valid XKB configuration data path, current search paths: "
- << xkbRoot.path() << ". Use ':' as separator to provide several search paths.";
- return;
+ qWarning() << error;
+ if (xkb_context) {
+ qWarning() << "Current XKB configuration data search paths are: ";
+ for (unsigned int i = 0; i < xkb_context_num_include_paths(xkb_context); ++i)
+ qWarning() << xkb_context_include_path_get(xkb_context, i);
}
- qWarning() << "_XKB_RULES_NAMES property contains:" << "\nrules : " << xkb_names.rules <<
- "\nmodel : " << xkb_names.model << "\nlayout : " << xkb_names.layout <<
- "\nvariant : " << xkb_names.variant << "\noptions : " << xkb_names.options <<
- "\nIf this looks like a valid keyboard layout information then you might need to "
- "update XKB configuration data on the system (http://cgit.freedesktop.org/xkeyboard-config/).";
+ qWarning() << "Use QT_XKB_CONFIG_ROOT environmental variable to provide an additional search path, "
+ "add ':' as separator to provide several search paths and/or make sure that XKB configuration data "
+ "directory contains recent enough contents, to update please see http://cgit.freedesktop.org/xkeyboard-config/ .";
}
void QXcbKeyboard::updateKeymap()
@@ -696,7 +690,7 @@ void QXcbKeyboard::updateKeymap()
xkb_context = xkb_context_new((xkb_context_flags)0);
}
if (!xkb_context) {
- printKeymapError("Failed to create XKB context!");
+ printKeymapError("Qt: Failed to create XKB context!");
m_config = false;
return;
}
@@ -731,8 +725,7 @@ void QXcbKeyboard::updateKeymap()
if (xkb_keymap) {
new_state = xkb_state_new(xkb_keymap);
} else {
- // failed to compile from RMLVO, give a verbose error message
- printKeymapError("Qt: Failed to compile a keymap!");
+ printKeymapError("Failed to compile a keymap!");
m_config = false;
return;
}
@@ -863,7 +856,7 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
return QList<int>();
QList<int> result;
- int baseQtKey = keysymToQtKey(sym, modifiers, keysymToUnicode(sym));
+ int baseQtKey = keysymToQtKey(sym, modifiers, lookupString(kb_state, event->nativeScanCode()));
result += (baseQtKey + modifiers); // The base key is _always_ valid, of course
xkb_mod_index_t shiftMod = xkb_keymap_mod_get_index(xkb_keymap, "Shift");
@@ -910,7 +903,7 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
continue;
Qt::KeyboardModifiers mods = modifiers & ~neededMods;
- qtKey = keysymToQtKey(sym, mods, keysymToUnicode(sym));
+ qtKey = keysymToQtKey(sym, mods, lookupString(kb_state, event->nativeScanCode()));
if (qtKey == baseQtKey)
continue;
@@ -986,10 +979,10 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
, xkb_context(0)
, xkb_keymap(0)
, xkb_state(0)
- , core_device_id(0)
{
memset(&xkb_names, 0, sizeof(xkb_names));
#ifndef QT_NO_XKB
+ core_device_id = 0;
if (connection->hasXKB()) {
updateVModMapping();
updateVModToRModMapping();
@@ -1326,7 +1319,8 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
}
Qt::KeyboardModifiers modifiers = translateModifiers(state);
- QString string = keysymToUnicode(sym);
+
+ QString string = lookupString(xkb_state, code);
int count = string.size();
string.truncate(count);
@@ -1389,16 +1383,12 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
}
}
-QString QXcbKeyboard::keysymToUnicode(xcb_keysym_t sym) const
+QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const
{
QByteArray chars;
- int bytes;
- chars.resize(7);
- bytes = xkb_keysym_to_utf8(sym, chars.data(), chars.size());
- if (bytes == -1)
- qWarning("QXcbKeyboard::handleKeyEvent - buffer too small");
- chars.resize(bytes-1);
-
+ chars.resize(1 + xkb_state_key_get_utf8(state, code, 0, 0));
+ // equivalent of XLookupString
+ xkb_state_key_get_utf8(state, code, chars.data(), chars.size());
return QString::fromUtf8(chars);
}
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index 36ce1ea2f0..11b7429aca 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -48,10 +48,7 @@
#include <xkbcommon/xkbcommon.h>
#ifndef QT_NO_XKB
-// note: extern won't be needed from libxkbcommon 0.4.1 and above
-extern "C" {
#include <xkbcommon/xkbcommon-x11.h>
-}
#endif
#include <QEvent>
@@ -79,9 +76,9 @@ public:
void updateXKBMods();
quint32 xkbModMask(quint16 state);
void updateXKBStateFromCore(quint16 state);
+#ifndef QT_NO_XKB
// when XKEYBOARD is present on the X server
int coreDeviceId() const { return core_device_id; }
-#ifndef QT_NO_XKB
void updateXKBState(xcb_xkb_state_notify_event_t *state);
#endif
@@ -89,10 +86,10 @@ protected:
void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
void resolveMaskConflicts();
- QString keysymToUnicode(xcb_keysym_t sym) const;
+ QString lookupString(struct xkb_state *state, xcb_keycode_t code) const;
int keysymToQtKey(xcb_keysym_t keysym) const;
int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const;
- void printKeymapError(const QString &error) const;
+ void printKeymapError(const char *error) const;
void readXKBConfig();
void clearXKBConfig();
@@ -134,9 +131,11 @@ private:
xkb_mod_index_t mod5;
};
_xkb_mods xkb_mods;
+#ifndef QT_NO_XKB
// when XKEYBOARD is present on the X server
_mod_masks vmod_masks;
int core_device_id;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index bed6eb59dc..5a2002f1d4 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1174,7 +1174,7 @@ void QXcbWindow::updateNetWmUserTime(xcb_timestamp_t timestamp)
void QXcbWindow::setTransparentForMouseEvents(bool transparent)
{
- if (transparent == m_transparent)
+ if (!connection()->hasXFixes() || transparent == m_transparent)
return;
xcb_rectangle_t rectangle;
diff --git a/src/plugins/platformthemes/gtk2/gtk2.pro b/src/plugins/platformthemes/gtk2/gtk2.pro
index bb02192f91..73c156f82b 100644
--- a/src/plugins/platformthemes/gtk2/gtk2.pro
+++ b/src/plugins/platformthemes/gtk2/gtk2.pro
@@ -1,6 +1,7 @@
TARGET = qgtk2
PLUGIN_TYPE = platformthemes
+PLUGIN_EXTENDS = -
PLUGIN_CLASS_NAME = QGtk2ThemePlugin
load(qt_plugin)
diff --git a/src/printsupport/kernel/qcups.cpp b/src/printsupport/kernel/qcups.cpp
index 288ad16da0..3a92f9b6db 100644
--- a/src/printsupport/kernel/qcups.cpp
+++ b/src/printsupport/kernel/qcups.cpp
@@ -88,7 +88,7 @@ static inline QString jobHoldToString(const QCUPSSupport::JobHoldUntil jobHold,
QDateTime localDateTime = QDateTime::currentDateTime();
// Check if time is for tomorrow in case of DST change overnight
if (holdUntilTime < localDateTime.time())
- localDateTime.addDays(1);
+ localDateTime = localDateTime.addDays(1);
localDateTime.setTime(holdUntilTime);
return localDateTime.toUTC().time().toString(QStringLiteral("HH:mm"));
}
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index 153fb23d36..bdc9a98f2e 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -220,6 +220,87 @@ void QPrinterPrivate::setProperty(QPrintEngine::PrintEnginePropertyKey key, cons
}
+class QPrinterPagedPaintDevicePrivate : public QPagedPaintDevicePrivate
+{
+public:
+ QPrinterPagedPaintDevicePrivate(QPrinterPrivate *d)
+ : QPagedPaintDevicePrivate(), pd(d)
+ {}
+
+ virtual ~QPrinterPagedPaintDevicePrivate()
+ {}
+
+ bool setPageLayout(const QPageLayout &newPageLayout) Q_DECL_OVERRIDE
+ {
+ if (pd->paintEngine->type() != QPaintEngine::Pdf
+ && pd->printEngine->printerState() == QPrinter::Active) {
+ qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active");
+ return false;
+ }
+
+ // Try to set the print engine page layout
+ pd->setProperty(QPrintEngine::PPK_QPageLayout, QVariant::fromValue(newPageLayout));
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ m_pageLayout = pageLayout();
+
+ return pageLayout().isEquivalentTo(newPageLayout);
+ }
+
+ bool setPageSize(const QPageSize &pageSize) Q_DECL_OVERRIDE
+ {
+ if (pd->paintEngine->type() != QPaintEngine::Pdf
+ && pd->printEngine->printerState() == QPrinter::Active) {
+ qWarning("QPrinter::setPageLayout: Cannot be changed while printer is active");
+ return false;
+ }
+
+
+ // Try to set the print engine page size
+ pd->setProperty(QPrintEngine::PPK_QPageSize, QVariant::fromValue(pageSize));
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ m_pageLayout = pageLayout();
+
+ return pageLayout().pageSize().isEquivalentTo(pageSize);
+ }
+
+ bool setPageOrientation(QPageLayout::Orientation orientation) Q_DECL_OVERRIDE
+ {
+ // Set the print engine value
+ pd->setProperty(QPrintEngine::PPK_Orientation, orientation);
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ m_pageLayout = pageLayout();
+
+ return pageLayout().orientation() == orientation;
+ }
+
+ bool setPageMargins(const QMarginsF &margins) Q_DECL_OVERRIDE
+ {
+ return setPageMargins(margins, pageLayout().units());
+ }
+
+ bool setPageMargins(const QMarginsF &margins, QPageLayout::Unit units) Q_DECL_OVERRIDE
+ {
+ // Try to set print engine margins
+ QPair<QMarginsF, QPageLayout::Unit> pair = qMakePair(margins, units);
+ pd->setProperty(QPrintEngine::PPK_QPageMargins, QVariant::fromValue(pair));
+
+ // Set QPagedPaintDevice layout to match the current print engine value
+ m_pageLayout = pageLayout();
+
+ return pageLayout().margins() == margins && pageLayout().units() == units;
+ }
+
+ QPageLayout pageLayout() const Q_DECL_OVERRIDE
+ {
+ return pd->printEngine->property(QPrintEngine::PPK_QPageLayout).value<QPageLayout>();
+ }
+
+ QPrinterPrivate *pd;
+};
+
/*!
\class QPrinter
@@ -601,6 +682,8 @@ QPrinter::QPrinter(PrinterMode mode)
: QPagedPaintDevice(),
d_ptr(new QPrinterPrivate(this))
{
+ delete d;
+ d = new QPrinterPagedPaintDevicePrivate(d_func());
d_ptr->init(QPrinterInfo(), mode);
}
@@ -613,6 +696,8 @@ QPrinter::QPrinter(const QPrinterInfo& printer, PrinterMode mode)
: QPagedPaintDevice(),
d_ptr(new QPrinterPrivate(this))
{
+ delete d;
+ d = new QPrinterPagedPaintDevicePrivate(d_func());
d_ptr->init(printer, mode);
}
@@ -947,7 +1032,10 @@ void QPrinter::setCreator(const QString &creator)
d->setProperty(QPrintEngine::PPK_Creator, creator);
}
+// Defined in QPagedPaintDevice but non-virtual, add QPrinter specific doc here
+#ifdef Q_QDOC
/*!
+ \fn bool QPrinter::setPageLayout(const QPageLayout &newLayout)
\since 5.3
Sets the page layout to \a newLayout.
@@ -961,23 +1049,8 @@ void QPrinter::setCreator(const QString &creator)
\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);
-}
-
/*!
+ \fn bool QPrinter::setPageSize(const QPageSize &pageSize)
\since 5.3
Sets the page size to \a pageSize.
@@ -995,23 +1068,8 @@ bool QPrinter::setPageLayout(const QPageLayout &newLayout)
\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);
-}
-
/*!
+ \fn bool QPrinter::setPageOrientation(QPageLayout::Orientation orientation)
\since 5.3
Sets the page \a orientation to QPageLayout::Portrait or QPageLayout::Landscape.
@@ -1029,20 +1087,8 @@ bool QPrinter::setPageSize(const QPageSize &pageSize)
\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;
-}
-
/*!
+ \fn bool QPrinter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
\since 5.3
Set the page margins to \a margins in the given \a units. If \a units are
@@ -1059,21 +1105,10 @@ bool QPrinter::setPageOrientation(QPageLayout::Orientation orientation)
\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;
-}
-
/*!
+ \fn QPageLayout QPrinter::pageLayout() const
+ \since 5.3
+
Returns the current page layout. Use this method to access the current
QPageSize, QPageLayout::Orientation, QMarginsF, fullPageRect() and paintRect().
@@ -1082,12 +1117,7 @@ bool QPrinter::setPageMargins(const QMarginsF &margins, QPageLayout::Unit units)
\sa setPageLayout(), setPageSize(), setPageOrientation(), setPageMargins()
*/
-
-QPageLayout QPrinter::pageLayout() const
-{
- Q_D(const QPrinter);
- return d->printEngine->property(QPrintEngine::PPK_QPageLayout).value<QPageLayout>();
-}
+#endif
/*!
\obsolete Use pageLayout().pageOrientation() instead.
diff --git a/src/printsupport/kernel/qprinter.h b/src/printsupport/kernel/qprinter.h
index 1f0639d81f..fa102d0fe3 100644
--- a/src/printsupport/kernel/qprinter.h
+++ b/src/printsupport/kernel/qprinter.h
@@ -307,11 +307,17 @@ public:
void setCreator(const QString &);
QString creator() const;
+#ifdef Q_QDOC
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;
+#else
+ using QPagedPaintDevice::setPageSize;
+ using QPagedPaintDevice::setPageMargins;
+#endif
void setOrientation(Orientation);
Orientation orientation() const;
diff --git a/src/printsupport/printsupport.pro b/src/printsupport/printsupport.pro
index a92d36f7bc..b32ba91c07 100644
--- a/src/printsupport/printsupport.pro
+++ b/src/printsupport/printsupport.pro
@@ -4,6 +4,9 @@ QT = core-private gui-private widgets-private
MODULE_CONFIG = needs_printsupport_plugin
DEFINES += QT_NO_USING_NAMESPACE
+MODULE_PLUGIN_TYPES = \
+ printsupport
+
QMAKE_DOCS = $$PWD/doc/qtprintsupport.qdocconf
load(qt_module)
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index ac6d677d54..c950d2c2ef 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtSql module of the Qt Toolkit.
@@ -1323,12 +1323,12 @@ bool QODBCResult::exec()
if (isSelect())
SQLCloseCursor(d->hStmt);
- QList<QByteArray> tmpStorage; // holds temporary buffers
- QVarLengthArray<SQLLEN, 32> indicators(boundValues().count());
+ QVector<QVariant>& values = boundValues();
+ QVector<QByteArray> tmpStorage(values.count(), QByteArray()); // holds temporary buffers
+ QVarLengthArray<SQLLEN, 32> indicators(values.count());
memset(indicators.data(), 0, indicators.size() * sizeof(SQLLEN));
// bind parameters - only positional binding allowed
- QVector<QVariant>& values = boundValues();
int i;
SQLRETURN r;
for (i = 0; i < values.count(); ++i) {
@@ -1340,7 +1340,7 @@ bool QODBCResult::exec()
*ind = SQL_NULL_DATA;
switch (val.type()) {
case QVariant::Date: {
- QByteArray ba;
+ QByteArray &ba = tmpStorage[i];
ba.resize(sizeof(DATE_STRUCT));
DATE_STRUCT *dt = (DATE_STRUCT *)ba.constData();
QDate qdt = val.toDate();
@@ -1357,10 +1357,9 @@ bool QODBCResult::exec()
(void *) dt,
0,
*ind == SQL_NULL_DATA ? ind : NULL);
- tmpStorage.append(ba);
break; }
case QVariant::Time: {
- QByteArray ba;
+ QByteArray &ba = tmpStorage[i];
ba.resize(sizeof(TIME_STRUCT));
TIME_STRUCT *dt = (TIME_STRUCT *)ba.constData();
QTime qdt = val.toTime();
@@ -1377,10 +1376,9 @@ bool QODBCResult::exec()
(void *) dt,
0,
*ind == SQL_NULL_DATA ? ind : NULL);
- tmpStorage.append(ba);
break; }
case QVariant::DateTime: {
- QByteArray ba;
+ QByteArray &ba = tmpStorage[i];
ba.resize(sizeof(TIMESTAMP_STRUCT));
TIMESTAMP_STRUCT * dt = (TIMESTAMP_STRUCT *)ba.constData();
QDateTime qdt = val.toDateTime();
@@ -1412,7 +1410,6 @@ bool QODBCResult::exec()
(void *) dt,
0,
*ind == SQL_NULL_DATA ? ind : NULL);
- tmpStorage.append(ba);
break; }
case QVariant::Int:
r = SQLBindParameter(d->hStmt,
@@ -1503,6 +1500,7 @@ bool QODBCResult::exec()
break;
case QVariant::String:
if (d->unicode) {
+ QByteArray &ba = tmpStorage[i];
QString str = val.toString();
if (*ind != SQL_NULL_DATA)
*ind = str.length() * sizeof(SQLTCHAR);
@@ -1510,7 +1508,7 @@ bool QODBCResult::exec()
if (bindValueType(i) & QSql::Out) {
const QVarLengthArray<SQLTCHAR> a(toSQLTCHAR(str));
- QByteArray ba((const char *)a.constData(), a.size() * sizeof(SQLTCHAR));
+ ba = QByteArray((const char *)a.constData(), a.size() * sizeof(SQLTCHAR));
r = SQLBindParameter(d->hStmt,
i + 1,
qParamType[bindValueType(i) & QSql::InOut],
@@ -1521,10 +1519,9 @@ bool QODBCResult::exec()
(void *)ba.data(),
ba.size(),
ind);
- tmpStorage.append(ba);
break;
}
- QByteArray strba((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR));
+ ba = QByteArray ((const char *)toSQLTCHAR(str).constData(), str.size()*sizeof(SQLTCHAR));
r = SQLBindParameter(d->hStmt,
i + 1,
qParamType[bindValueType(i) & QSql::InOut],
@@ -1532,15 +1529,15 @@ bool QODBCResult::exec()
strSize > 254 ? SQL_WLONGVARCHAR : SQL_WVARCHAR,
strSize,
0,
- (SQLPOINTER)strba.constData(),
- strba.size(),
+ (SQLPOINTER)ba.constData(),
+ ba.size(),
ind);
- tmpStorage.append(strba);
break;
}
else
{
- QByteArray str = val.toString().toUtf8();
+ QByteArray &str = tmpStorage[i];
+ str = val.toString().toUtf8();
if (*ind != SQL_NULL_DATA)
*ind = str.length();
int strSize = str.length();
@@ -1555,12 +1552,11 @@ bool QODBCResult::exec()
(void *)str.constData(),
strSize,
ind);
- tmpStorage.append(str);
break;
}
// fall through
default: {
- QByteArray ba = val.toByteArray();
+ QByteArray &ba = tmpStorage[i];
if (*ind != SQL_NULL_DATA)
*ind = ba.size();
r = SQLBindParameter(d->hStmt,
@@ -1573,7 +1569,6 @@ bool QODBCResult::exec()
(void *) ba.constData(),
ba.length() + 1,
ind);
- tmpStorage.append(ba);
break; }
}
if (r != SQL_SUCCESS) {
@@ -1617,16 +1612,16 @@ bool QODBCResult::exec()
for (i = 0; i < values.count(); ++i) {
switch (values.at(i).type()) {
case QVariant::Date: {
- DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.takeFirst().constData());
+ DATE_STRUCT ds = *((DATE_STRUCT *)tmpStorage.at(i).constData());
values[i] = QVariant(QDate(ds.year, ds.month, ds.day));
break; }
case QVariant::Time: {
- TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.takeFirst().constData());
+ TIME_STRUCT dt = *((TIME_STRUCT *)tmpStorage.at(i).constData());
values[i] = QVariant(QTime(dt.hour, dt.minute, dt.second));
break; }
case QVariant::DateTime: {
TIMESTAMP_STRUCT dt = *((TIMESTAMP_STRUCT*)
- tmpStorage.takeFirst().constData());
+ tmpStorage.at(i).constData());
values[i] = QVariant(QDateTime(QDate(dt.year, dt.month, dt.day),
QTime(dt.hour, dt.minute, dt.second, dt.fraction / 1000000)));
break; }
@@ -1642,7 +1637,7 @@ bool QODBCResult::exec()
case QVariant::String:
if (d->unicode) {
if (bindValueType(i) & QSql::Out) {
- QByteArray first = tmpStorage.takeFirst();
+ const QByteArray &first = tmpStorage.at(i);
QVarLengthArray<SQLTCHAR> array;
array.append((SQLTCHAR *)first.constData(), first.size());
values[i] = fromSQLTCHAR(array, first.size()/sizeof(SQLTCHAR));
@@ -1652,7 +1647,7 @@ bool QODBCResult::exec()
// fall through
default: {
if (bindValueType(i) & QSql::Out)
- values[i] = tmpStorage.takeFirst();
+ values[i] = tmpStorage.at(i);
break; }
}
if (indicators[i] == SQL_NULL_DATA)
diff --git a/src/src.pro b/src/src.pro
index 0d854a85c1..6a805a6a06 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -142,13 +142,13 @@ contains(QT_CONFIG, concurrent):SUBDIRS += src_concurrent
src_gui.depends += src_angle
}
SUBDIRS += src_gui src_platformsupport
- contains(QT_CONFIG, opengl(es1|es2)?):SUBDIRS += src_openglextensions
+ contains(QT_CONFIG, opengl(es2)?):SUBDIRS += src_openglextensions
src_plugins.depends += src_gui src_platformsupport
!contains(QT_CONFIG, no-widgets) {
SUBDIRS += src_tools_uic src_widgets
TOOLS += src_tools_uic
src_plugins.depends += src_widgets
- contains(QT_CONFIG, opengl(es1|es2)?):!contains(QT_CONFIG, dynamicgl) {
+ contains(QT_CONFIG, opengl(es2)?):!contains(QT_CONFIG, dynamicgl) {
SUBDIRS += src_opengl
src_plugins.depends += src_opengl
}
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 3ab3fcc44c..cbf479f1d2 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -2878,7 +2878,12 @@ void QTest::qSleep(int ms)
// requested time.
qint64 requested = 1000000 * (qint64)ms;
qint64 diff = timer.nsecsElapsed() - requested;
- if (diff * 2 > requested || diff * 10 < -requested) {
+#ifndef Q_OS_WIN
+ const qint64 factor = 2; // more than 50% longer
+#else
+ const qint64 factor = 1; // Windows: 50% is quite common, warn about 100%
+#endif
+ if (diff * factor > 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__);
diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h
index b715d83383..d9c8a43a2a 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -140,7 +140,7 @@ do {\
#define QTRY_TIMEOUT_DEBUG_IMPL(__expr, __timeoutValue, __step)\
if (!(__expr)) { \
- QTRY_LOOP_IMPL(__expr, (2 * __timeoutValue), __step);\
+ QTRY_LOOP_IMPL((__expr), (2 * __timeoutValue), __step);\
if (__expr) { \
QString msg = QString::fromUtf8("QTestLib: This test case check (\"%1\") failed because the requested timeout (%2 ms) was too short, %3 ms would have been sufficient this time."); \
msg = msg.arg(QString::fromUtf8(#__expr)).arg(__timeoutValue).arg(__timeoutValue + __i); \
@@ -151,26 +151,26 @@ do {\
#define QTRY_IMPL(__expr, __timeout)\
const int __step = 50; \
const int __timeoutValue = __timeout; \
- QTRY_LOOP_IMPL(__expr, __timeoutValue, __step); \
- QTRY_TIMEOUT_DEBUG_IMPL(__expr, __timeoutValue, __step)\
+ QTRY_LOOP_IMPL((__expr), __timeoutValue, __step); \
+ QTRY_TIMEOUT_DEBUG_IMPL((__expr), __timeoutValue, __step)\
// Will try to wait for the expression to become true while allowing event processing
#define QTRY_VERIFY_WITH_TIMEOUT(__expr, __timeout) \
do { \
- QTRY_IMPL(__expr, __timeout);\
+ QTRY_IMPL((__expr), __timeout);\
QVERIFY(__expr); \
} while (0)
-#define QTRY_VERIFY(__expr) QTRY_VERIFY_WITH_TIMEOUT(__expr, 5000)
+#define QTRY_VERIFY(__expr) QTRY_VERIFY_WITH_TIMEOUT((__expr), 5000)
// Will try to wait for the comparison to become successful while allowing event processing
#define QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, __timeout) \
do { \
QTRY_IMPL(((__expr) == (__expected)), __timeout);\
- QCOMPARE(__expr, __expected); \
+ QCOMPARE((__expr), __expected); \
} while (0)
-#define QTRY_COMPARE(__expr, __expected) QTRY_COMPARE_WITH_TIMEOUT(__expr, __expected, 5000)
+#define QTRY_COMPARE(__expr, __expected) QTRY_COMPARE_WITH_TIMEOUT((__expr), __expected, 5000)
#define QSKIP_INTERNAL(statement) \
do {\
diff --git a/src/widgets/accessible/widgets.pro b/src/widgets/accessible/widgets.pro
index aff60d9781..c6af6d3f71 100644
--- a/src/widgets/accessible/widgets.pro
+++ b/src/widgets/accessible/widgets.pro
@@ -1,6 +1,7 @@
TARGET = qtaccessiblewidgets
PLUGIN_TYPE = accessible
+PLUGIN_EXTENDS = widgets
PLUGIN_CLASS_NAME = AccessibleFactory
load(qt_plugin)
diff --git a/src/widgets/kernel/qapplication_qpa.cpp b/src/widgets/kernel/qapplication_qpa.cpp
index 1c40ca01be..ccd6c2b03c 100644
--- a/src/widgets/kernel/qapplication_qpa.cpp
+++ b/src/widgets/kernel/qapplication_qpa.cpp
@@ -93,7 +93,6 @@ bool qt_try_modal(QWidget *widget, QEvent::Type type)
return true;
bool block_event = false;
- bool paint_event = false;
switch (type) {
#if 0
@@ -113,7 +112,7 @@ bool qt_try_modal(QWidget *widget, QEvent::Type type)
break;
}
- if ((block_event || paint_event) && top->parentWidget() == 0)
+ if (block_event && top && top->parentWidget() == 0)
top->raise();
return !block_event;
@@ -126,8 +125,15 @@ bool QApplicationPrivate::modalState()
QWidget *qt_tlw_for_window(QWindow *wnd)
{
- while (wnd && !wnd->isTopLevel()) // QTBUG-32177, wnd might be a QQuickView embedded via window container.
- wnd = wnd->parent();
+ // QTBUG-32177, wnd might be a QQuickView embedded via window container.
+ while (wnd && !wnd->isTopLevel()) {
+ QWindow *parent = wnd->parent();
+ // Don't end up in windows not belonging to this application
+ if (parent && parent->type() != Qt::ForeignWindow)
+ wnd = wnd->parent();
+ else
+ break;
+ }
if (wnd)
foreach (QWidget *tlw, qApp->topLevelWidgets())
if (tlw->windowHandle() == wnd)
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 66aacadb28..10be5aef16 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -60,7 +60,6 @@ public:
QOpenGLWidgetPrivate()
: fbo(0), uninitialized(true)
{
- setRenderToTexture();
}
GLuint textureId() const { return fbo ? fbo->texture() : 0; }
@@ -91,6 +90,8 @@ void QOpenGLWidgetPrivate::initialize()
QOpenGLWidget::QOpenGLWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(*(new QOpenGLWidgetPrivate), parent, f)
{
+ Q_D(QOpenGLWidget);
+ d->setRenderToTexture();
}
QOpenGLWidget::~QOpenGLWidget()
@@ -146,6 +147,9 @@ void QOpenGLWidget::paintGL()
void QOpenGLWidget::updateGL()
{
Q_D(QOpenGLWidget);
+ if (d->uninitialized)
+ return;
+
makeCurrent();
paintGL();
d->context.functions()->glFlush();
@@ -163,7 +167,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *)
d->context.makeCurrent(d->surface());
delete d->fbo; // recreate when resized
- d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio());
+ d->fbo = new QOpenGLFramebufferObject(size() * devicePixelRatio(), QOpenGLFramebufferObject::CombinedDepthStencil);
d->fbo->bind();
QOpenGLFunctions *funcs = d->context.functions();
funcs->glBindTexture(GL_TEXTURE_2D, d->fbo->texture());
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 569828c44d..926db7febf 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -79,6 +79,7 @@
#include "qfileinfo.h"
#include <QtGui/qinputmethod.h>
#include <QtGui/qopenglcontext.h>
+#include <QtGui/private/qopenglcontext_p.h>
#include <private/qgraphicseffect_p.h>
#include <qbackingstore.h>
@@ -2840,7 +2841,10 @@ void QWidget::showFullScreen()
setWindowState((windowState() & ~(Qt::WindowMinimized | Qt::WindowMaximized))
| Qt::WindowFullScreen);
setVisible(true);
+#if !defined Q_OS_QNX // On QNX this window will be activated anyway from libscreen
+ // activating it here before libscreen activates it causes problems
activateWindow();
+#endif
}
/*!
@@ -8359,6 +8363,8 @@ bool QWidget::event(QEvent *event)
d->extra->customDpiY = value;
d->updateFont(d->data.fnt);
}
+ if (windowHandle() && !qstrncmp(propName, "_q_platform_", 12))
+ windowHandle()->setProperty(propName, property(propName));
// fall through
}
#endif
@@ -11153,6 +11159,7 @@ QOpenGLContext *QWidgetPrivate::shareContext() const
QWidgetPrivate *that = const_cast<QWidgetPrivate *>(this);
if (!extra->topextra->shareContext) {
QOpenGLContext *ctx = new QOpenGLContext();
+ ctx->setShareContext(QOpenGLContextPrivate::globalShareContext());
ctx->setFormat(extra->topextra->window->format());
ctx->create();
that->extra->topextra->shareContext = ctx;
diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp
index 85ae55b8ac..5ba0a90d3d 100644
--- a/src/widgets/kernel/qwidget_qpa.cpp
+++ b/src/widgets/kernel/qwidget_qpa.cpp
@@ -110,6 +110,11 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
win = topData()->window;
}
+ foreach (const QByteArray &propertyName, q->dynamicPropertyNames()) {
+ if (!qstrncmp(propertyName, "_q_platform_", 12))
+ win->setProperty(propertyName, q->property(propertyName));
+ }
+
win->setFlags(data.window_flags);
fixPosIncludesFrame();
if (q->testAttribute(Qt::WA_Moved)
@@ -834,13 +839,16 @@ int QWidget::metric(PaintDeviceMetric m) const
{
Q_D(const QWidget);
+ QWindow *topLevelWindow = 0;
QScreen *screen = 0;
if (QWidget *topLevel = window())
- if (QWindow *topLevelWindow = topLevel->windowHandle()) {
- QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
- if (platformScreen)
- screen = platformScreen->screen();
- }
+ topLevelWindow = topLevel->windowHandle();
+
+ if (topLevelWindow) {
+ QPlatformScreen *platformScreen = QPlatformScreen::platformScreenForWindow(topLevelWindow);
+ if (platformScreen)
+ screen = platformScreen->screen();
+ }
if (!screen && QGuiApplication::primaryScreen())
screen = QGuiApplication::primaryScreen();
@@ -877,7 +885,7 @@ int QWidget::metric(PaintDeviceMetric m) const
} else if (m == PdmPhysicalDpiY) {
return qRound(screen->physicalDotsPerInchY());
} else if (m == PdmDevicePixelRatio) {
- return screen->devicePixelRatio();
+ return topLevelWindow ? topLevelWindow->devicePixelRatio() : qApp->devicePixelRatio();
} else {
val = QPaintDevice::metric(m);// XXX
}
diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp
index ef138267bb..0031d8e965 100644
--- a/src/widgets/kernel/qwidgetwindow.cpp
+++ b/src/widgets/kernel/qwidgetwindow.cpp
@@ -58,8 +58,7 @@ QT_BEGIN_NAMESPACE
Q_WIDGETS_EXPORT extern bool qt_tab_all_widgets();
QWidget *qt_button_down = 0; // widget got last button-down
-static QWidget *qt_tablet_target = 0;
-static QWidget *qt_tablet_target_window = 0;
+static QPointer<QWidget> qt_tablet_target = 0;
// popup control
QWidget *qt_popup_down = 0; // popup that contains the pressed widget
@@ -105,10 +104,6 @@ QWidgetWindow::QWidgetWindow(QWidget *widget)
QWidgetWindow::~QWidgetWindow()
{
- if (m_widget == qt_tablet_target_window) {
- qt_tablet_target = 0;
- qt_tablet_target_window = 0;
- }
}
#ifndef QT_NO_ACCESSIBILITY
@@ -486,7 +481,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event)
if (!widget)
widget = m_widget;
- if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick)
+ if (event->type() == QEvent::MouseButtonPress)
qt_button_down = widget;
QWidget *receiver = QApplicationPrivate::pickMouseReceiver(m_widget, event->windowPos().toPoint(), &mapped, event->type(), event->buttons(),
@@ -791,7 +786,6 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
widget = m_widget;
qt_tablet_target = widget;
- qt_tablet_target_window = m_widget;
}
if (qt_tablet_target) {
@@ -804,10 +798,8 @@ void QWidgetWindow::handleTabletEvent(QTabletEvent *event)
QGuiApplication::sendSpontaneousEvent(qt_tablet_target, &ev);
}
- if (event->type() == QEvent::TabletRelease) {
+ if (event->type() == QEvent::TabletRelease)
qt_tablet_target = 0;
- qt_tablet_target_window = 0;
- }
}
#endif // QT_NO_TABLETEVENT
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 55e808e9ba..d35dd16f85 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -179,6 +179,19 @@ static bool isVerticalTabs(const QTabBar::Shape shape) {
|| shape == QTabBar::TriangularWest);
}
+static bool isInMacUnifiedToolbarArea(QWindow *window, int windowY)
+{
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("testContentBorderPosition");
+ if (!function)
+ return false; // Not Cocoa platform plugin.
+
+ typedef bool (*TestContentBorderPositionFunction)(QWindow *, int);
+ return (reinterpret_cast<TestContentBorderPositionFunction>(function))(window, windowY);
+}
+
+
void drawTabCloseButton(QPainter *p, bool hover, bool active, bool selected)
{
// draw background circle
@@ -239,7 +252,7 @@ QRect rotateTabPainter(QPainter *p, QTabBar::Shape shape, QRect tabRect)
return tabRect;
}
-void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
+void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt, bool isUnified)
{
QRect r = tabOpt->rect;
p->translate(tabOpt->rect.x(), tabOpt->rect.y());
@@ -256,7 +269,12 @@ void drawTabShape(QPainter *p, const QStyleOptionTabV3 *tabOpt)
QRect rect(1, 0, width - 2, height);
// fill body
- if (active) {
+ if (tabOpt->documentMode && isUnified) {
+ p->save();
+ p->setCompositionMode(QPainter::CompositionMode_Source);
+ p->fillRect(rect, QColor(Qt::transparent));
+ p->restore();
+ } else if (active) {
int d = (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) ? 16 : 0;
p->fillRect(rect, QColor(151 + d, 151 + d, 151 + d));
} else {
@@ -3721,7 +3739,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
QStyleOptionComboBox comboCopy = *cb;
comboCopy.direction = Qt::LeftToRight;
if ((opt->state & QStyle::State_Small) && QSysInfo::macVersion() > QSysInfo::MV_10_6)
- comboCopy.rect.translate(0, w ? -1 : -2); // Supports Qt Quick Controls
+ comboCopy.rect.translate(0, w ? (QSysInfo::macVersion() > QSysInfo::MV_10_8 ? 0 : -1) : -2); // Supports Qt Quick Controls
else if (QSysInfo::macVersion() > QSysInfo::MV_10_8)
comboCopy.rect.translate(0, 1);
QCommonStyle::drawControl(CE_ComboBoxLabel, &comboCopy, p, w);
@@ -3733,8 +3751,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (const QStyleOptionTabV3 *tabOptV3 = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
if (tabOptV3->documentMode) {
p->save();
- // QRect tabRect = tabOptV3->rect;
- drawTabShape(p, tabOptV3);
+ bool isUnified = false;
+ if (w) {
+ QRect tabRect = tabOptV3->rect;
+ QPoint windowTabStart = w->mapTo(w->window(), tabRect.topLeft());
+ isUnified = isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowTabStart.y());
+ }
+
+ drawTabShape(p, tabOptV3, isUnified);
p->restore();
return;
}
@@ -4414,7 +4438,9 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
QPen pen(strokeColor);
p->setPen(pen);
p->setBrush(fillColor);
- p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ QRect adjusted = opt->rect.adjusted(1, 1, -1, -1);
+ if (adjusted.isValid())
+ p->drawRect(adjusted);
p->setPen(oldPen);
p->setBrush(oldBrush);
}
@@ -4440,15 +4466,22 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
p->fillRect(opt->rect, Qt::transparent);
p->restore();
- // drow horizontal sepearator line at toolBar bottom.
- SInt32 margin;
- GetThemeMetric(kThemeMetricSeparatorSize, &margin);
- CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
- HIThemeSeparatorDrawInfo separatorDrawInfo;
- separatorDrawInfo.version = 0;
- separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive;
- QMacCGContext cg(p);
- HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal);
+ // Drow a horizontal sepearator line at the toolBar bottom if the "unified" area ends here.
+ // There might be additional toolbars or other widgets such as tab bars in document
+ // mode below. Determine this by making a unified toolbar area test for the row below
+ // this toolbar.
+ QPoint windowToolbarEnd = w->mapTo(w->window(), opt->rect.bottomLeft());
+ bool isEndOfUnifiedArea = !isInMacUnifiedToolbarArea(w->window()->windowHandle(), windowToolbarEnd.y() + 1);
+ if (isEndOfUnifiedArea) {
+ SInt32 margin;
+ GetThemeMetric(kThemeMetricSeparatorSize, &margin);
+ CGRect separatorRect = CGRectMake(opt->rect.left(), opt->rect.bottom(), opt->rect.width(), margin);
+ HIThemeSeparatorDrawInfo separatorDrawInfo;
+ separatorDrawInfo.version = 0;
+ separatorDrawInfo.state = qt_macWindowMainWindow(mainWindow) ? kThemeStateActive : kThemeStateInactive;
+ QMacCGContext cg(p);
+ HIThemeDrawSeparator(&separatorRect, &separatorDrawInfo, cg, kHIThemeOrientationNormal);
+ }
break;
}
}
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 37c0a41227..8774d71c0c 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1750,6 +1750,9 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_ComboBox_Popup Allows popups as a combobox drop-down
menu.
+ \omitvalue SH_ComboBox_UseNativePopup Whether we should use a native popup.
+ Only supported for non-editable combo boxes on Mac OS X so far.
+
\value SH_Workspace_FillSpaceOnMaximize The workspace should
maximize the client area.
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 82c40a954c..ea012faf46 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -702,6 +702,7 @@ public:
SH_ToolTip_FallAsleepDelay,
SH_Widget_Animate,
SH_Splitter_OpaqueResize,
+ SH_ComboBox_UseNativePopup,
SH_LineEdit_PasswordMaskDelay,
// Add new style hint values here
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index e0f5ac1050..06258cb4a6 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -44,6 +44,7 @@
#ifndef QT_NO_COMBOBOX
#include <qstylepainter.h>
#include <qpa/qplatformtheme.h>
+#include <qpa/qplatformmenu.h>
#include <qlineedit.h>
#include <qapplication.h>
#include <qdesktopwidget.h>
@@ -205,7 +206,7 @@ void QComboBoxPrivate::updateArrow(QStyle::StateFlag state)
arrowState = state;
QStyleOptionComboBox opt;
q->initStyleOption(&opt);
- q->update(q->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxArrow, q));
+ q->update(q->rect());
}
void QComboBoxPrivate::_q_modelReset()
@@ -2375,6 +2376,79 @@ QSize QComboBox::sizeHint() const
return d->recomputeSizeHint(d->sizeHint);
}
+#ifdef Q_OS_OSX
+/*!
+ * \internal
+ *
+ * Tries to show a native popup. Returns true if it could, false otherwise.
+ *
+ */
+bool QComboBoxPrivate::showNativePopup()
+{
+ Q_Q(QComboBox);
+
+ QPlatformTheme *theme = QGuiApplicationPrivate::instance()->platformTheme();
+ if (QPlatformMenu *menu = theme->createPlatformMenu()) {
+ int itemsCount = q->count();
+
+ struct IndexSetter {
+ int index;
+ QComboBox *cb;
+
+ void operator()(void) { cb->setCurrentIndex(index); }
+ };
+
+ QList<QPlatformMenuItem *> items;
+ items.reserve(itemsCount);
+ QPlatformMenuItem *currentItem = 0;
+ int currentIndex = q->currentIndex();
+
+ for (int i = 0; i < itemsCount; ++i) {
+ QPlatformMenuItem *item = theme->createPlatformMenuItem();
+ QModelIndex rowIndex = model->index(i, modelColumn, root);
+ QVariant textVariant = model->data(rowIndex, Qt::EditRole);
+ item->setText(textVariant.toString());
+ QVariant iconVariant = model->data(rowIndex, Qt::DecorationRole);
+ if (iconVariant.canConvert<QIcon>())
+ item->setIcon(iconVariant.value<QIcon>());
+ item->setCheckable(true);
+ item->setChecked(i == currentIndex);
+ if (!currentItem || i == currentIndex)
+ currentItem = item;
+
+ IndexSetter setter = { i, q };
+ QObject::connect(item, &QPlatformMenuItem::activated, setter);
+
+ menu->insertMenuItem(item, 0);
+ menu->syncMenuItem(item);
+ }
+
+ QWindow *tlw = q->window()->windowHandle();
+ menu->setFont(q->font());
+ menu->setMinimumWidth(q->rect().width());
+ QPoint offset = QPoint(0, 7);
+ if (q->testAttribute(Qt::WA_MacSmallSize))
+ offset = QPoint(-1, 7);
+ else if (q->testAttribute(Qt::WA_MacMiniSize))
+ offset = QPoint(-2, 6);
+ menu->showPopup(tlw, tlw->mapFromGlobal(q->mapToGlobal(offset)), currentItem);
+ menu->deleteLater();
+ Q_FOREACH (QPlatformMenuItem *item, items)
+ item->deleteLater();
+
+ // The Cocoa popup will swallow any mouse release event.
+ // We need to fake one here to un-press the button.
+ QMouseEvent mouseReleased(QEvent::MouseButtonRelease, q->pos(), Qt::LeftButton,
+ Qt::MouseButtons(Qt::LeftButton), Qt::KeyboardModifiers());
+ qApp->sendEvent(q, &mouseReleased);
+
+ return true;
+ }
+
+ return false;
+}
+#endif // Q_OS_OSX
+
/*!
Displays the list of items in the combobox. If the list is empty
then the no items will be shown.
@@ -2390,6 +2464,21 @@ void QComboBox::showPopup()
if (count() <= 0)
return;
+ QStyle * const style = this->style();
+ QStyleOptionComboBox opt;
+ initStyleOption(&opt);
+ const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this);
+
+#ifdef Q_OS_OSX
+ if (usePopup
+ && (!d->container
+ || (view()->metaObject()->className() == QByteArray("QComboBoxListView")
+ && view()->itemDelegate()->metaObject()->className() == QByteArray("QComboMenuDelegate")))
+ && style->styleHint(QStyle::SH_ComboBox_UseNativePopup, &opt, this)
+ && d->showNativePopup())
+ return;
+#endif // Q_OS_OSX
+
#ifdef QT_KEYPAD_NAVIGATION
#ifndef QT_NO_COMPLETER
if (QApplication::keypadNavigationEnabled() && d->completer) {
@@ -2401,14 +2490,10 @@ void QComboBox::showPopup()
#endif
#endif
- QStyle * const style = this->style();
-
// set current item and select it
view()->selectionModel()->setCurrentIndex(d->currentIndex,
QItemSelectionModel::ClearAndSelect);
QComboBoxPrivateContainer* container = d->viewContainer();
- QStyleOptionComboBox opt;
- initStyleOption(&opt);
QRect listRect(style->subControlRect(QStyle::CC_ComboBox, &opt,
QStyle::SC_ComboBoxListBoxPopup, this));
QRect screen = d->popupGeometry(QApplication::desktop()->screenNumber(this));
@@ -2419,7 +2504,6 @@ void QComboBox::showPopup()
int aboveHeight = above.y() - screen.y();
bool boundToScreen = !window()->testAttribute(Qt::WA_DontShowOnScreen);
- const bool usePopup = style->styleHint(QStyle::SH_ComboBox_Popup, &opt, this);
{
int listHeight = 0;
int count = 0;
@@ -2750,6 +2834,18 @@ void QComboBox::changeEvent(QEvent *e)
d->updateLineEditGeometry();
d->setLayoutItemMargins(QStyle::SE_ComboBoxLayoutItem);
+ if (e->type() == QEvent::MacSizeChange){
+ QPlatformTheme::Font f = QPlatformTheme::SystemFont;
+ if (testAttribute(Qt::WA_MacSmallSize))
+ f = QPlatformTheme::SmallFont;
+ else if (testAttribute(Qt::WA_MacMiniSize))
+ f = QPlatformTheme::MiniFont;
+ if (const QFont *platformFont = QApplicationPrivate::platformTheme()->font(f)) {
+ QFont f = font();
+ f.setPointSizeF(platformFont->pointSizeF());
+ setFont(f);
+ }
+ }
// ### need to update scrollers etc. as well here
break;
case QEvent::EnabledChange:
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index 1ad2aa455a..dceffe8d35 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -377,6 +377,10 @@ public:
void modelChanged();
void updateViewContainerPaletteAndOpacity();
+#ifdef Q_OS_OSX
+ bool showNativePopup();
+#endif
+
QAbstractItemModel *model;
QLineEdit *lineEdit;
QComboBoxPrivateContainer *container;
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 1d0268a244..90cfb1d7cb 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1513,12 +1513,12 @@ void QMainWindow::setUnifiedTitleAndToolBarOnMac(bool set)
QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
- nativeInterface->nativeResourceFunctionForIntegration("enableContentBorderArea");
+ nativeInterface->nativeResourceFunctionForIntegration("setContentBorderEnabled");
if (!function)
return; // Not Cocoa platform plugin.
- typedef void (*EnableContentBorderAreaFunction)(QWindow *window, bool enable);
- (reinterpret_cast<EnableContentBorderAreaFunction>(function))(window()->windowHandle(), set);
+ typedef void (*SetContentBorderEnabledFunction)(QWindow *window, bool enable);
+ (reinterpret_cast<SetContentBorderEnabledFunction>(function))(window()->windowHandle(), set);
}
#endif
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index 92a1274d7c..c026b79103 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -508,8 +508,11 @@ QLayoutItem *QMainWindowLayoutState::item(const QList<int> &path)
int i = path.first();
#ifndef QT_NO_TOOLBAR
- if (i == 0)
- return toolBarAreaLayout.item(path.mid(1)).widgetItem;
+ if (i == 0) {
+ const QToolBarAreaLayoutItem *tbItem = toolBarAreaLayout.item(path.mid(1));
+ Q_ASSERT(tbItem);
+ return tbItem->widgetItem;
+ }
#endif
#ifndef QT_NO_DOCKWIDGET
@@ -1567,9 +1570,10 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem)
QList<int> previousPath = layoutState.indexOf(widget);
- QLayoutItem *it = layoutState.plug(currentGapPos);
+ const QLayoutItem *it = layoutState.plug(currentGapPos);
+ if (!it)
+ return false;
Q_ASSERT(it == widgetItem);
- Q_UNUSED(it);
if (!previousPath.isEmpty())
layoutState.remove(previousPath);
diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp
index 94674319bc..b1adb3f760 100644
--- a/src/widgets/widgets/qmdisubwindow.cpp
+++ b/src/widgets/widgets/qmdisubwindow.cpp
@@ -1761,11 +1761,13 @@ bool QMdiSubWindowPrivate::drawTitleBarWhenMaximized() const
return false;
#if defined(Q_OS_MAC) && !defined(QT_NO_STYLE_MAC) || defined(Q_OS_WINCE_WM)
+ Q_UNUSED(isChildOfQMdiSubWindow);
return true;
#else
if (q->style()->styleHint(QStyle::SH_Workspace_FillSpaceOnMaximize, 0, q))
return true;
#if defined(QT_NO_MENUBAR) || defined(QT_NO_MAINWINDOW)
+ Q_UNUSED(isChildOfQMdiSubWindow);
return true;
#else
QMainWindow *mainWindow = qobject_cast<QMainWindow *>(q->window());
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index b47d65f561..789ec2f6fd 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -56,6 +56,9 @@
#ifndef QT_NO_ACCESSIBILITY
#include "qaccessible.h"
#endif
+#ifdef Q_OS_OSX
+#include <qpa/qplatformnativeinterface.h>
+#endif
#include "qdebug.h"
#include "private/qtabbar_p.h"
@@ -80,35 +83,44 @@ inline static bool verticalTabs(QTabBar::Shape shape)
void QTabBarPrivate::updateMacBorderMetrics()
{
-#if defined(Q_WS_MAC)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- Q_Q(QTabBar);
- ::HIContentBorderMetrics metrics;
-
- // TODO: get metrics to preserve the bottom value
- // TODO: test tab bar position
-
- OSWindowRef window = qt_mac_window_for(q);
-
- // push base line separator down to the client are so we can paint over it (Carbon)
- metrics.top = (documentMode && q->isVisible()) ? 1 : 0;
- metrics.bottom = 0;
- metrics.left = 0;
- metrics.right = 0;
- qt_mac_updateContentBorderMetricts(window, metrics);
- // In Cocoa we need to keep track of the drawRect method.
- // If documentMode is enabled we need to change it, unless
- // a toolbar is present.
- // Notice that all the information is kept in the window,
- // that's why we get the private widget for it instead of
- // the private widget for this widget.
- QWidgetPrivate *privateWidget = qt_widget_private(q->window());
- if(privateWidget)
- privateWidget->changeMethods = documentMode;
- // Since in Cocoa there is no simple way to remove the baseline, so we just ask the
- // top level to do the magic for us.
- privateWidget->syncUnifiedMode();
+#if defined(Q_OS_OSX)
+ Q_Q(QTabBar);
+ // Extend the unified title and toolbar area to cover the tab bar iff
+ // 1) the tab bar is in document mode
+ // 2) the tab bar is directly below an "unified" area.
+ // The extending itself is done in the Cocoa platform plugin and Mac style,
+ // this function registers geometry and visibility state for the tab bar.
+
+ // Calculate geometry
+ int upper, lower;
+ if (documentMode) {
+ QPoint windowPos = q->mapTo(q->window(), QPoint(0,0));
+ upper = windowPos.y();
+ int tabStripHeight = q->tabSizeHint(0).height();
+ int pixelTweak = -3;
+ lower = upper + tabStripHeight + pixelTweak;
+ } else {
+ upper = 0;
+ lower = 0;
}
+
+ QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface();
+ quintptr identifier = reinterpret_cast<quintptr>(q);
+
+ // Set geometry
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("registerContentBorderArea");
+ if (!function)
+ return; // Not Cocoa platform plugin.
+ typedef void (*RegisterContentBorderAreaFunction)(QWindow *window, quintptr identifier, int upper, int lower);
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(q->window()->windowHandle(), identifier, upper, lower);
+
+ // Set visibility state
+ function = nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
+ if (!function)
+ return;
+ typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, quintptr identifier, bool enable);
+ (reinterpret_cast<SetContentBorderAreaEnabledFunction>(function))(q->window()->windowHandle(), identifier, q->isVisible());
#endif
}
@@ -1502,6 +1514,9 @@ bool QTabBar::event(QEvent *event)
|| (!d->rightB->isHidden() && d->rightB->geometry().contains(pos));
if (!isEventInCornerButtons)
emit tabBarDoubleClicked(tabAt(pos));
+ } else if (event->type() == QEvent::Move) {
+ d->updateMacBorderMetrics();
+ return QWidget::event(event);
}
return QWidget::event(event);
}
diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h
index b7b6998ca3..3228308bc6 100644
--- a/src/widgets/widgets/qtabbar_p.h
+++ b/src/widgets/widgets/qtabbar_p.h
@@ -182,6 +182,7 @@ public:
void layoutWidgets(int start = 0);
void layoutTab(int index);
void updateMacBorderMetrics();
+ bool isTabInMacUnifiedToolbarArea() const;
void setupMovableTab();
void makeVisible(int index);
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
index d20b7a380d..3fd615c3c7 100644
--- a/src/widgets/widgets/qtoolbar.cpp
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -83,6 +83,7 @@ void QToolBarPrivate::init()
q->setBackgroundRole(QPalette::Button);
q->setAttribute(Qt::WA_Hover);
q->setAttribute(Qt::WA_X11NetWmWindowTypeToolBar);
+ q->setProperty("_q_platform_MacUseNSWindow", QVariant(true));
QStyle *style = q->style();
int e = style->pixelMetric(QStyle::PM_ToolBarIconSize, 0, q);
@@ -1039,6 +1040,21 @@ static bool waitForPopup(QToolBar *tb, QWidget *popup)
return false;
}
+#ifdef Q_OS_OSX
+static void enableMacToolBar(QToolBar *toolbar, bool enable)
+{
+ QPlatformNativeInterface *nativeInterface = QApplication::platformNativeInterface();
+ QPlatformNativeInterface::NativeResourceForIntegrationFunction function =
+ nativeInterface->nativeResourceFunctionForIntegration("setContentBorderAreaEnabled");
+ if (!function)
+ return; // Not Cocoa platform plugin.
+
+ typedef void (*SetContentBorderAreaEnabledFunction)(QWindow *window, void *identifier, bool enabled);
+ (reinterpret_cast<SetContentBorderAreaEnabledFunction>(function))(toolbar->window()->windowHandle(), toolbar, enable);
+}
+#endif
+
+
/*! \reimp */
bool QToolBar::event(QEvent *event)
{
@@ -1061,6 +1077,9 @@ bool QToolBar::event(QEvent *event)
// fallthrough intended
case QEvent::Show:
d->toggleViewAction->setChecked(event->type() == QEvent::Show);
+#ifdef Q_OS_OSX
+ enableMacToolBar(this, event->type() == QEvent::Show);
+#endif
emit visibilityChanged(event->type() == QEvent::Show);
break;
case QEvent::ParentChange:
diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp
index 5ec76569aa..4591c2ac5f 100644
--- a/src/widgets/widgets/qtoolbararealayout.cpp
+++ b/src/widgets/widgets/qtoolbararealayout.cpp
@@ -1107,16 +1107,19 @@ void QToolBarAreaLayout::clear()
rect = QRect();
}
-QToolBarAreaLayoutItem &QToolBarAreaLayout::item(const QList<int> &path)
+QToolBarAreaLayoutItem *QToolBarAreaLayout::item(const QList<int> &path)
{
Q_ASSERT(path.count() == 3);
- Q_ASSERT(path.at(0) >= 0 && path.at(0) < QInternal::DockCount);
+ if (path.at(0) < 0 || path.at(0) >= QInternal::DockCount)
+ return 0;
QToolBarAreaLayoutInfo &info = docks[path.at(0)];
- Q_ASSERT(path.at(1) >= 0 && path.at(1) < info.lines.count());
+ if (path.at(1) < 0 || path.at(1) >= info.lines.count())
+ return 0;
QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
- Q_ASSERT(path.at(2) >= 0 && path.at(2) < line.toolBarItems.count());
- return line.toolBarItems[path.at(2)];
+ if (path.at(2) < 0 || path.at(2) >= line.toolBarItems.count())
+ return 0;
+ return &(line.toolBarItems[path.at(2)]);
}
QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const
@@ -1132,23 +1135,28 @@ QRect QToolBarAreaLayout::itemRect(const QList<int> &path) const
QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path)
{
- QToolBarAreaLayoutItem &item = this->item(path);
- Q_ASSERT(item.gap);
- Q_ASSERT(item.widgetItem != 0);
- item.gap = false;
- return item.widgetItem;
+ QToolBarAreaLayoutItem *item = this->item(path);
+ if (!item) {
+ qWarning() << Q_FUNC_INFO << "No item at" << path;
+ return 0;
+ }
+ Q_ASSERT(item->gap);
+ Q_ASSERT(item->widgetItem != 0);
+ item->gap = false;
+ return item->widgetItem;
}
QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayout *other)
{
//other needs to be update as well
Q_ASSERT(path.count() == 3);
- QToolBarAreaLayoutItem &item = this->item(path);
+ QToolBarAreaLayoutItem *item = this->item(path);
+ Q_ASSERT(item);
//update the leading space here
QToolBarAreaLayoutInfo &info = docks[path.at(0)];
QToolBarAreaLayoutLine &line = info.lines[path.at(1)];
- if (item.size != pick(line.o, item.realSizeHint())) {
+ if (item->size != pick(line.o, item->realSizeHint())) {
//the item doesn't have its default size
//so we'll give this to the next item
int newExtraSpace = 0;
@@ -1185,9 +1193,9 @@ QLayoutItem *QToolBarAreaLayout::unplug(const QList<int> &path, QToolBarAreaLayo
}
}
- Q_ASSERT(!item.gap);
- item.gap = true;
- return item.widgetItem;
+ Q_ASSERT(!item->gap);
+ item->gap = true;
+ return item->widgetItem;
}
static QRect unpackRect(uint geom0, uint geom1, bool *floating)
diff --git a/src/widgets/widgets/qtoolbararealayout_p.h b/src/widgets/widgets/qtoolbararealayout_p.h
index ec7d1f26f1..6ba9768467 100644
--- a/src/widgets/widgets/qtoolbararealayout_p.h
+++ b/src/widgets/widgets/qtoolbararealayout_p.h
@@ -232,7 +232,7 @@ public:
void remove(const QList<int> &path);
void remove(QLayoutItem *item);
void clear();
- QToolBarAreaLayoutItem &item(const QList<int> &path);
+ QToolBarAreaLayoutItem *item(const QList<int> &path);
QRect itemRect(const QList<int> &path) const;
QLayoutItem *plug(const QList<int> &path);
QLayoutItem *unplug(const QList<int> &path, QToolBarAreaLayout *other);
diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp
index 020d180778..efd33da7fc 100644
--- a/src/widgets/widgets/qtoolbarlayout.cpp
+++ b/src/widgets/widgets/qtoolbarlayout.cpp
@@ -369,9 +369,9 @@ void QToolBarLayout::updateMacBorderMetrics()
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());
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), tb, upper.y(), lower.y());
} else {
- (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), this, 0, 0);
+ (reinterpret_cast<RegisterContentBorderAreaFunction>(function))(tb->window()->windowHandle(), tb, 0, 0);
}
#endif
}
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 3740f3e698..9cc62fd10a 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -438,6 +438,7 @@ void QWidgetTextControlPrivate::setContent(Qt::TextFormat format, const QString
QObject::connect(doc, SIGNAL(contentsChanged()), q, SLOT(_q_updateCurrentCharFormatAndSelection()));
QObject::connect(doc, SIGNAL(cursorPositionChanged(QTextCursor)), q, SLOT(_q_emitCursorPosChanged(QTextCursor)));
+ QObject::connect(doc, SIGNAL(contentsChange(int,int,int)), q, SLOT(_q_contentsChanged(int,int,int)));
QObject::connect(doc, SIGNAL(documentLayoutChanged()), q, SLOT(_q_documentLayoutChanged()));
// convenience signal forwards
@@ -641,6 +642,33 @@ void QWidgetTextControlPrivate::_q_emitCursorPosChanged(const QTextCursor &someC
}
}
+void QWidgetTextControlPrivate::_q_contentsChanged(int from, int charsRemoved, int charsAdded)
+{
+ Q_Q(QWidgetTextControl);
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ QTextCursor tmp(doc);
+ tmp.setPosition(from);
+ tmp.setPosition(from + charsAdded, QTextCursor::KeepAnchor);
+ QString newText = tmp.selectedText();
+
+ // always report the right number of removed chars, but in lack of the real string use spaces
+ QString oldText = QString(charsRemoved, QLatin1Char(' '));
+
+ QAccessibleEvent *ev = 0;
+ if (charsRemoved == 0) {
+ ev = new QAccessibleTextInsertEvent(q->parent(), from, newText);
+ } else if (charsAdded == 0) {
+ ev = new QAccessibleTextRemoveEvent(q->parent(), from, oldText);
+ } else {
+ ev = new QAccessibleTextUpdateEvent(q->parent(), from, oldText, newText);
+ }
+ QAccessible::updateAccessibility(ev);
+ delete ev;
+ }
+#endif
+}
+
void QWidgetTextControlPrivate::_q_documentLayoutChanged()
{
Q_Q(QWidgetTextControl);
diff --git a/src/widgets/widgets/qwidgettextcontrol_p.h b/src/widgets/widgets/qwidgettextcontrol_p.h
index 0c76355ca1..867b55fe32 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p.h
@@ -262,6 +262,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_copyLink())
Q_PRIVATE_SLOT(d_func(), void _q_updateBlock(const QTextBlock &))
Q_PRIVATE_SLOT(d_func(), void _q_documentLayoutChanged())
+ Q_PRIVATE_SLOT(d_func(), void _q_contentsChanged(int, int, int))
};
diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h
index 727821015e..4d578c76f8 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h
@@ -111,6 +111,7 @@ public:
#endif
void _q_emitCursorPosChanged(const QTextCursor &someCursor);
+ void _q_contentsChanged(int from, int charsRemoved, int charsAdded);
void setBlinkingCursorEnabled(bool enable);
diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp
index 22d3f5bd91..eef23130f9 100644
--- a/src/winmain/qtmain_winrt.cpp
+++ b/src/winmain/qtmain_winrt.cpp
@@ -105,15 +105,29 @@ static void devMessageHandler(QtMsgType type, const QMessageLogContext &context,
class AppContainer : public Microsoft::WRL::RuntimeClass<Core::IFrameworkView>
{
public:
- AppContainer(int argc, char *argv[]) : m_argc(argc)
+ AppContainer(int argc, char *argv[]) : m_argc(argc), m_deleteArgv0(false)
{
m_argv.reserve(argc);
- for (int i = 0; i < argc; ++i)
+ for (int i = 0; i < argc; ++i) {
+ // Workaround for empty argv[0] which occurs when WMAppManifest's ImageParams is used
+ // The second argument is taken to be the executable
+ if (i == 0 && argc >= 2 && !qstrlen(argv[0])) {
+ const QByteArray argv0 = QDir::current()
+ .absoluteFilePath(QString::fromLatin1(argv[1])).toUtf8();
+ m_argv.append(qstrdup(argv0.constData()));
+ m_argc -= 1;
+ m_deleteArgv0 = true;
+ ++i;
+ continue;
+ }
m_argv.append(argv[i]);
+ }
}
~AppContainer()
{
+ if (m_deleteArgv0)
+ delete[] m_argv[0];
for (int i = m_argc; i < m_argv.size(); ++i)
delete[] m_argv[i];
}
@@ -186,6 +200,7 @@ private:
int m_argc;
QVector<char *> m_argv;
+ bool m_deleteArgv0;
EventRegistrationToken m_activationToken;
};