From d5587cf3acb7ad6f81e1c095f1b88f8fb25ee953 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 14 May 2014 10:32:30 +1000 Subject: [PATCH 1/6] config: revert quirk for the Evoluent Vertical Mouse This quick makes the mouse behaviour more obvious (LMR buttons generate LMR events) but goes against the manufacturer's intended defaults: Top button - left click. Wheel button - .middle click (e.g., for pan and rotate in CAD programs). Middle button - right click. Bottom button - back. Thumb button - forward. from http://www.evoluent.com/vm3.html Signed-off-by: Peter Hutterer --- config/10-quirks.conf | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/config/10-quirks.conf b/config/10-quirks.conf index c9b823ceb..47907d82d 100644 --- a/config/10-quirks.conf +++ b/config/10-quirks.conf @@ -19,22 +19,6 @@ Section "InputClass" Option "IgnoreRelativeAxes" "off" EndSection -# https://bugzilla.redhat.com/show_bug.cgi?id=612140 -# please make Evoluent VerticalMouse 3 work out of the box -# Button mapping on this mouse is quirky -Section "InputClass" - Identifier "Evoluent VerticalMouse 3" - MatchProduct "Evoluent VerticalMouse 3" - # Sets following configuration: - # top button: left - # middle button: middle - # bottom button: right - # wheel click: middle - # thumb button: 8 (back) - Option "ButtonMapping" "1 2 2 4 5 6 7 3 8" -EndSection - - # https://bugs.freedesktop.org/show_bug.cgi?id=55867 # Bug 55867 - Doesn't know how to tag XI_TRACKBALL Section "InputClass" From d3a3ee7a0e5cbd3fcaba77d2d5664e1524eda11c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 8 May 2014 09:39:36 +1000 Subject: [PATCH 2/6] os: automatically switch to sigsafe logging when needed If we're smart enough to warn, we should be smart enough to just pass it through to the right function. Worst case we lose some formatting specifiers which pnprintf will complain about anyway. And in most cases it won't matter. This requires renaming pnprintf to vpnprintf and changing the size_t to int to be compatible with Xvscnprintf. pnprintf is internal only, the others are exported API so we can't change them as easily. Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- os/log.c | 65 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/os/log.c b/os/log.c index a0f2a81f3..a368569d0 100644 --- a/os/log.c +++ b/os/log.c @@ -342,7 +342,7 @@ out: * which directives you use. */ static int -pnprintf(char *string, size_t size, const char *f, va_list args) +vpnprintf(char *string, int size_in, const char *f, va_list args) { int f_idx = 0; int s_idx = 0; @@ -353,6 +353,7 @@ pnprintf(char *string, size_t size, const char *f, va_list args) int i; uint64_t ui; int64_t si; + size_t size = size_in; for (; f_idx < f_len && s_idx < size - 1; f_idx++) { int length_modifier = 0; @@ -484,6 +485,19 @@ pnprintf(char *string, size_t size, const char *f, va_list args) return s_idx; } +static int +pnprintf(char *string, int size, const char *f, ...) +{ + int rc; + va_list args; + + va_start(args, f); + rc = vpnprintf(string, size, f, args); + va_end(args); + + return rc; +} + /* This function does the actual log message writes. It must be signal safe. * When attempting to call non-signal-safe functions, guard them with a check * of the inSignalContext global variable. */ @@ -597,7 +611,6 @@ LogMessageTypeVerbString(MessageType type, int verb) void LogVMessageVerb(MessageType type, int verb, const char *format, va_list args) { - static unsigned int warned; const char *type_str; char buf[1024]; const size_t size = sizeof(buf); @@ -605,17 +618,8 @@ LogVMessageVerb(MessageType type, int verb, const char *format, va_list args) size_t len = 0; if (inSignalContext) { - if (warned < 3) { - BUG_WARN_MSG(inSignalContext, - "Warning: attempting to log data in a signal unsafe " - "manner while in signal context.\nPlease update to check " - "inSignalContext and/or use LogMessageVerbSigSafe() or " - "ErrorFSigSafe().\nThe offending log format message is:\n" - "%s\n", format); - warned++; - if (warned == 3) - LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned); - } + LogVMessageVerbSigSafe(type, verb, format, args); + return; } type_str = LogMessageTypeVerbString(type, verb); @@ -687,7 +691,7 @@ LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list a LogSWrite(verb, " ", 1, FALSE); } - len = pnprintf(buf, sizeof(buf), format, args); + len = vpnprintf(buf, sizeof(buf), format, args); /* Force '\n' at end of truncated line */ if (sizeof(buf) - len == 1) @@ -701,40 +705,37 @@ void LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format, va_list msg_args, const char *hdr_format, va_list hdr_args) { - static unsigned int warned; const char *type_str; char buf[1024]; const size_t size = sizeof(buf); Bool newline; size_t len = 0; - - if (inSignalContext) { - if (warned < 3) { - BUG_WARN_MSG(inSignalContext, - "Warning: attempting to log data in a signal unsafe " - "manner while in signal context.\nPlease update to check " - "inSignalContext and/or use LogMessageVerbSigSafe().\nThe " - "offending header and log message formats are:\n%s %s\n", - hdr_format, msg_format); - warned++; - if (warned == 3) - LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned); - } - } + int (*vprintf_func)(char *, int, const char* _X_RESTRICT_KYWD f, va_list args) + _X_ATTRIBUTE_PRINTF(3, 0); + int (*printf_func)(char *, int, const char* _X_RESTRICT_KYWD f, ...) + _X_ATTRIBUTE_PRINTF(3, 4); type_str = LogMessageTypeVerbString(type, verb); if (!type_str) return; + if (inSignalContext) { + vprintf_func = vpnprintf; + printf_func = pnprintf; + } else { + vprintf_func = Xvscnprintf; + printf_func = Xscnprintf; + } + /* if type_str is not "", prepend it and ' ', to message */ if (type_str[0] != '\0') - len += Xscnprintf(&buf[len], size - len, "%s ", type_str); + len += printf_func(&buf[len], size - len, "%s ", type_str); if (hdr_format && size - len > 1) - len += Xvscnprintf(&buf[len], size - len, hdr_format, hdr_args); + len += vprintf_func(&buf[len], size - len, hdr_format, hdr_args); if (msg_format && size - len > 1) - len += Xvscnprintf(&buf[len], size - len, msg_format, msg_args); + len += vprintf_func(&buf[len], size - len, msg_format, msg_args); /* Force '\n' at end of truncated line */ if (size - len == 1) From d7a2df0a7499864cb005b098b79c1bdf884f6600 Mon Sep 17 00:00:00 2001 From: Steven McDonald Date: Sun, 18 May 2014 13:42:08 +0200 Subject: [PATCH 3/6] Xi: block SIGIOs while copying device classes around I've been seeing sporadic (anywhere from once every few days to 3-4 times a day) crashes and freezes in X. The problematic behaviour isn't always the same, but I chose a particular incident to debug, and found that X was segfaulting in updateMotionHistory, on line 575 of dix/getevents.c. After some further investigation, I found that the bug was being triggered when a SIGIO was received in DeepCopyPointerClasses, between the AllocValuatorClass call (line 540) and updating the to->valuator pointer (line 545). AllocValuatorClass calls realloc() on to->valuator, so between these lines, it's not guaranteed to point to allocated memory. It seems the SIGIO handler is calling updateMotionHistory, which is reading the memory pointed to by to->valuator and getting a wrong value for last_motion, which updates buff to point to wildly the wrong place and thus generates a segfault when a memcpy() is done into buff. I am attaching a patch which I've been running on that machine for the past three days, and haven't yet observed any more crashing or freezing behaviour. The patch simply calls OsBlockSIGIO while DeepCopyDeviceClasses is in progress, as the state of the X server's device data structures is not guaranteed to be in a consistent state during that time. Debian bug#744303 Signed-off-by: Julien Cristau Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- Xi/exevents.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Xi/exevents.c b/Xi/exevents.c index 02530bdee..b0bc47e6d 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -661,6 +661,8 @@ void DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) { + OsBlockSIGIO(); + /* generic feedback classes, not tied to pointer and/or keyboard */ DeepCopyFeedbackClasses(from, to); @@ -668,6 +670,8 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeepCopyKeyboardClasses(from, to); if ((dce->flags & DEVCHANGE_POINTER_EVENT)) DeepCopyPointerClasses(from, to); + + OsReleaseSIGIO(); } /** From 548fc937b22d4dfe7f96e0bd77522261603a2c2f Mon Sep 17 00:00:00 2001 From: Robert Ancell Date: Thu, 22 May 2014 10:43:52 +1200 Subject: [PATCH 4/6] Fix overflow checking extension versions The easiest way to check for the version of an extension is to send the maximum possible version numbers in the QueryVersion request. The X server overflows on these as it assumes you will send a reasonable version number. Signed-off-by: Peter Hutterer Reviewed-by: Keith Packard --- include/misc.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/include/misc.h b/include/misc.h index 17de71041..9c2f573b9 100644 --- a/include/misc.h +++ b/include/misc.h @@ -259,15 +259,19 @@ extern void FormatDouble(double dbl, char *string); * or a value greater than 0 */ static inline int -version_compare(uint16_t a_major, uint16_t a_minor, - uint16_t b_major, uint16_t b_minor) +version_compare(uint32_t a_major, uint32_t a_minor, + uint32_t b_major, uint32_t b_minor) { - int a, b; + if (a_major > b_major) + return 1; + if (a_major < b_major) + return -1; + if (a_minor > b_minor) + return 1; + if (a_minor < b_minor) + return -1; - a = a_major << 16 | a_minor; - b = b_major << 16 | b_minor; - - return (a - b); + return 0; } /* some macros to help swap requests, replies, and events */ From e48a132b6d187f355abd7021be47edde972e7091 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sat, 24 May 2014 20:02:56 +1000 Subject: [PATCH 5/6] xfree86: fix wrong DontZap documentation (#71113) X.Org Bug 71113 Signed-off-by: Peter Hutterer --- hw/xfree86/xorgconf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/xorgconf.cpp b/hw/xfree86/xorgconf.cpp index cd6d4a983..a903438b6 100644 --- a/hw/xfree86/xorgconf.cpp +++ b/hw/xfree86/xorgconf.cpp @@ -97,7 +97,7 @@ Section "ServerFlags" # Uncomment this to disable the server abort sequence # This allows clients to receive this key event. -# Option "DontZap" "false" +# Option "DontZap" "true" # Uncomment this to disable the / mode switching # sequences. This allows clients to receive these key events. From cfaf2abbac3f01e57d00845d8908bf01559263f9 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sat, 24 May 2014 20:05:53 +1000 Subject: [PATCH 6/6] man: drop specific mention of DontZap in -retro (#71113) DontZap off is the default anyway, don't mention it specifically to avoid confusion X.Org Bug 71113 Signed-off-by: Peter Hutterer --- man/Xserver.man | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/man/Xserver.man b/man/Xserver.man index b103551fa..7a74e8541 100644 --- a/man/Xserver.man +++ b/man/Xserver.man @@ -223,9 +223,8 @@ turns on auto-repeat. .B -retro starts the stipple with the classic stipple and cursor visible. The default is to start with a black root window, and to suppress display of the cursor -until the first time an application calls XDefineCursor(). For the Xorg -server, this also sets the default for the DontZap option to FALSE. For -kdrive servers, this implies -zap. +until the first time an application calls XDefineCursor(). For kdrive +servers, this implies -zap. .TP 8 .B \-s \fIminutes\fP sets screen-saver timeout time in minutes.