xserver: Branch 'server-1.12-branch' - 7 commits

Jeremy Huddleston jeremyhu at kemper.freedesktop.org
Thu May 17 09:57:38 PDT 2012


 Xi/xiquerypointer.c |   25 ++++++++----
 include/Xprintf.h   |   12 +++++
 os/log.c            |  105 ++++++++++++++++++++++++----------------------------
 os/xprintf.c        |   44 +++++++++++++++++++++
 4 files changed, 123 insertions(+), 63 deletions(-)

New commits:
commit 32235e978685d3ebe9c418fecfe3ec584c402008
Merge: 58dfb13... dab90b6...
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu May 17 09:56:29 2012 -0700

    Merge remote-tracking branch 'whot/server-1.12-branch' into server-1.12-branch

commit dab90b60f3b2ebfd8df4fa761f3f34859250f4db
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue May 1 10:21:12 2012 -0700

    Report touch emulated buttons in XIQueryPointer for XI 2.1 and earlier
    
    XInput 2.1 and earlier clients do not know about touches. We must report
    touch emulated button presses for these clients. For later clients, we
    only report true pointer button presses.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit ee542b85590814ee25369babce1ad14feeb137af)

diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
index ba99752..169436e 100644
--- a/Xi/xiquerypointer.c
+++ b/Xi/xiquerypointer.c
@@ -79,10 +79,21 @@ ProcXIQueryPointer(ClientPtr client)
     XkbStatePtr state;
     char *buttons = NULL;
     int buttons_size = 0;       /* size of buttons array */
+    XIClientPtr xi_client;
+    Bool have_xi22 = FALSE;
 
     REQUEST(xXIQueryPointerReq);
     REQUEST_SIZE_MATCH(xXIQueryPointerReq);
 
+    /* Check if client is compliant with XInput 2.2 or later. Earlier clients
+     * do not know about touches, so we must report emulated button presses. 2.2
+     * and later clients are aware of touches, so we don't include emulated
+     * button presses in the reply. */
+    xi_client = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
+    if (version_compare(xi_client->major_version,
+                        xi_client->minor_version, 2, 2) >= 0)
+        have_xi22 = TRUE;
+
     rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
     if (rc != Success) {
         client->errorValue = stuff->deviceid;
@@ -145,6 +156,9 @@ ProcXIQueryPointer(ClientPtr client)
         for (i = 1; i < pDev->button->numButtons; i++)
             if (BitIsOn(pDev->button->down, i))
                 SetBit(buttons, pDev->button->map[i]);
+
+        if (!have_xi22 && pDev->touch && pDev->touch->buttonsDown > 0)
+            SetBit(buttons, pDev->button->map[1]);
     }
     else
         rep.buttons_len = 0;
commit 04474fc6a4c21a06c1a65c7afcbc4e0a27e3d0f7
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Tue May 1 10:21:11 2012 -0700

    Report logical button state in ProcXIQueryPointer
    
    Physical button state is usually meaningless to an X client.
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 1e7b500a8e1d79b91a4e857a2da06194efe8cf69)

diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c
index a2e7442..ba99752 100644
--- a/Xi/xiquerypointer.c
+++ b/Xi/xiquerypointer.c
@@ -132,7 +132,7 @@ ProcXIQueryPointer(ClientPtr client)
     }
 
     if (pDev->button) {
-        int i, down;
+        int i;
 
         rep.buttons_len =
             bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
@@ -142,14 +142,9 @@ ProcXIQueryPointer(ClientPtr client)
         if (!buttons)
             return BadAlloc;
 
-        down = pDev->button->buttonsDown;
-
-        for (i = 0; i < pDev->button->numButtons && down; i++) {
-            if (BitIsOn(pDev->button->down, i)) {
-                SetBit(buttons, i);
-                down--;
-            }
-        }
+        for (i = 1; i < pDev->button->numButtons; i++)
+            if (BitIsOn(pDev->button->down, i))
+                SetBit(buttons, pDev->button->map[i]);
     }
     else
         rep.buttons_len = 0;
commit 3b25ed442ca9152841fa821ac3b01c2c9cb4e0d1
Author: Daniel Kurtz <djkurtz at chromium.org>
Date:   Wed Apr 18 17:51:53 2012 +0800

    os/log: refactor logging
    
    It is not safe to ever use an arbitrary (possibly user supplied) string as
    part of the format for a *sprintf() call.
    
    For example:
      1. Name a Bluetooth keyboard "%n%n%n%n%n%n%n%n"
      2. Pair it with a computer running X and try to use it
      3. X is not happy when trying to do the following in xf86-input-evdev:
         xf86IDrvMsg(pInfo, X_CONFIG, "Device: \"%s\"\n", device);
         because LogVHdrMessageVerb() has put the %n from the device name
         into a format string of the form:
            "evdev: %n%n%n%n%n%n%n%n: Device: \"%s\"\n"
    
    Instead, build up a log message in place by appending successive formatted
    strings by sncprintf'ing to the end of the previous.
    
    Signed-off-by: Daniel Kurtz <djkurtz at chromium.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit c91d00e0f330b9de604068e1bfcb0a307096434f)

diff --git a/os/log.c b/os/log.c
index b790306..0e49572 100644
--- a/os/log.c
+++ b/os/log.c
@@ -265,36 +265,19 @@ LogSetParameter(LogParameter param, int value)
 }
 
 /* This function does the actual log message writes. */
-
-void
-LogVWrite(int verb, const char *f, va_list args)
+static void
+LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
 {
-    static char tmpBuffer[1024];
-    int len = 0;
     static Bool newline = TRUE;
 
-    if (verb > logFileVerbosity && verb > logVerbosity)
-        return;
-
-    /*
-     * Since a va_list can only be processed once, write the string to a
-     * buffer, and then write the buffer out to the appropriate output
-     * stream(s).
-     */
-    if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
-        len = Xvscnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
-        /* If message is truncated, terminate with '\n' */
-        if (sizeof(tmpBuffer) - len == 1)
-            tmpBuffer[len - 1] = '\n';
-    }
-    if ((verb < 0 || logVerbosity >= verb) && len > 0)
-        fwrite(tmpBuffer, len, 1, stderr);
-    if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
+    if (verb < 0 || logVerbosity >= verb)
+        fwrite(buf, len, 1, stderr);
+    if (verb < 0 || logFileVerbosity >= verb) {
         if (logFile) {
             if (newline)
                 fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
-            newline = (tmpBuffer[len - 1] == '\n');
-            fwrite(tmpBuffer, len, 1, logFile);
+            newline = end_line;
+            fwrite(buf, len, 1, logFile);
             if (logFlush) {
                 fflush(logFile);
 #ifndef WIN32
@@ -312,13 +295,19 @@ LogVWrite(int verb, const char *f, va_list args)
                     FatalError("realloc() failed while saving log messages\n");
             }
             bufferUnused -= len;
-            memcpy(saveBuffer + bufferPos, tmpBuffer, len);
+            memcpy(saveBuffer + bufferPos, buf, len);
             bufferPos += len;
         }
     }
 }
 
 void
+LogVWrite(int verb, const char *f, va_list args)
+{
+    return LogVMessageVerb(X_NONE, verb, f, args);
+}
+
+void
 LogWrite(int verb, const char *f, ...)
 {
     va_list args;
@@ -371,22 +360,28 @@ void
 LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
 {
     const char *type_str;
-    char tmpFormat[1024];
-    const char *new_format;
+    char buf[1024];
+    const size_t size = sizeof(buf);
+    Bool newline;
+    size_t len = 0;
 
     type_str = LogMessageTypeVerbString(type, verb);
     if (!type_str)
         return;
 
-    /* if type_str is not "", prepend it and ' ', to format */
-    if (type_str[0] == '\0')
-        new_format = format;
-    else {
-        new_format = tmpFormat;
-        snprintf(tmpFormat, sizeof(tmpFormat), "%s %s", type_str, format);
-    }
+    /* if type_str is not "", prepend it and ' ', to message */
+    if (type_str[0] != '\0')
+        len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
+
+    if (size - len > 1)
+        len += Xvscnprintf(&buf[len], size - len, format, args);
+
+    /* Force '\n' at end of truncated line */
+    if (size - len == 1)
+        buf[len - 1] = '\n';
 
-    LogVWrite(verb, new_format, args);
+    newline = (buf[len - 1] == '\n');
+    LogSWrite(verb, buf, len, newline);
 }
 
 /* Log message with verbosity level specified. */
@@ -416,31 +411,31 @@ LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
                    va_list msg_args, const char *hdr_format, va_list hdr_args)
 {
     const char *type_str;
-    char tmpFormat[1024];
-    char *tmpFormat_end = &tmpFormat[sizeof(tmpFormat)];
-    char *p;
-    int left;
+    char buf[1024];
+    const size_t size = sizeof(buf);
+    Bool newline;
+    size_t len = 0;
 
     type_str = LogMessageTypeVerbString(type, verb);
     if (!type_str)
         return;
 
-    /* if type_str != "", copy it and ' ' to tmpFormat; set p after ' ' */
-    p = tmpFormat;
+    /* if type_str is not "", prepend it and ' ', to message */
     if (type_str[0] != '\0')
-        p += snprintf(tmpFormat, sizeof(tmpFormat), "%s ", type_str);
+        len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
+
+    if (hdr_format && size - len > 1)
+        len += Xvscnprintf(&buf[len], size - len, hdr_format, hdr_args);
 
-    /* append as much of hdr as fits after type_str (if there was one) */
-    left = tmpFormat_end - p;
-    if (left > 1)
-        p += vsnprintf(p, left, hdr_format, hdr_args);
+    if (msg_format && size - len > 1)
+        len += Xvscnprintf(&buf[len], size - len, msg_format, msg_args);
 
-    /* append as much of msg_format as will fit after hdr */
-    left = tmpFormat_end - p;
-    if (left > 1)
-        snprintf(p, left, "%s", msg_format);
+    /* Force '\n' at end of truncated line */
+    if (size - len == 1)
+        buf[len - 1] = '\n';
 
-    LogVWrite(verb, tmpFormat, msg_args);
+    newline = (buf[len - 1] == '\n');
+    LogSWrite(verb, buf, len, newline);
 }
 
 void
commit 34a82b393a037788fbebbc423bfdcdd6f94f3577
Author: Daniel Kurtz <djkurtz at chromium.org>
Date:   Wed Apr 18 17:51:52 2012 +0800

    os/log: only write timestamp if a message is actually written to logfile
    
    The current code will write a timestamps into the logFile whenever
    the last message ended with a '\n' - even if the verb for that timestamp
    is at too high a level.  This timestamp will sit there with no matching
    message until the next call to LogVWrite with a valid verb.
    
    In other words, in some cases, timestamps in the X.org.log are for some
    completely unrelated message that was previously ignored due to
    insufficient verbosity, and not for the message that appears next to it
    in the log file.
    
    We keep the current policy which appears to be to only apply timestamps if
    a message is actually written to a log file.  That is, no timestamps on
    stderr, or in the mem buffer.  Therefore, the timestamp stringification
    is moved to the conditional where it is used.
    
    Since logging uses a fixed length buffer, this patch also forces a '\n'
    whenever a buffer is terminated due to a too-long write request.  This
    allows the newline detection to work even on overflow, and also cleans up
    the log a bit in the overflow case.
    
    Signed-off-by: Daniel Kurtz <djkurtz at chromium.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 6ce0eac4f8a05f6d7401445cab95027709d3a479)

diff --git a/os/log.c b/os/log.c
index 297b46a..b790306 100644
--- a/os/log.c
+++ b/os/log.c
@@ -273,12 +273,8 @@ LogVWrite(int verb, const char *f, va_list args)
     int len = 0;
     static Bool newline = TRUE;
 
-    if (newline) {
-        sprintf(tmpBuffer, "[%10.3f] ", GetTimeInMillis() / 1000.0);
-        len = strlen(tmpBuffer);
-        if (logFile)
-            fwrite(tmpBuffer, len, 1, logFile);
-    }
+    if (verb > logFileVerbosity && verb > logVerbosity)
+        return;
 
     /*
      * Since a va_list can only be processed once, write the string to a
@@ -286,14 +282,18 @@ LogVWrite(int verb, const char *f, va_list args)
      * stream(s).
      */
     if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
-        vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
-        len = strlen(tmpBuffer);
+        len = Xvscnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
+        /* If message is truncated, terminate with '\n' */
+        if (sizeof(tmpBuffer) - len == 1)
+            tmpBuffer[len - 1] = '\n';
     }
-    newline = (tmpBuffer[len - 1] == '\n');
     if ((verb < 0 || logVerbosity >= verb) && len > 0)
         fwrite(tmpBuffer, len, 1, stderr);
     if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
         if (logFile) {
+            if (newline)
+                fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
+            newline = (tmpBuffer[len - 1] == '\n');
             fwrite(tmpBuffer, len, 1, logFile);
             if (logFlush) {
                 fflush(logFile);
commit 8998037f183fd1f73fe0d272b4e072e53c7f3bcc
Author: Daniel Kurtz <djkurtz at chromium.org>
Date:   Wed Apr 18 09:51:51 2012 +0000

    os/xprintf: add Xvscnprintf and Xscnprintf
    
    Normal snprintf() usually returns the number of bytes that would have been
    written into a buffer had the buffer been long enough.
    
    The scnprintf() variants return the actual number of bytes written,
    excluding the trailing '\0'.
    
    Signed-off-by: Daniel Kurtz <djkurtz at chromium.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit 5c2e2a164d615ab06be28a663734e782614b5cc7)

diff --git a/include/Xprintf.h b/include/Xprintf.h
index 414fd46..9e8cdc5 100644
--- a/include/Xprintf.h
+++ b/include/Xprintf.h
@@ -66,4 +66,16 @@ _X_ATTRIBUTE_PRINTF(2, 0);
 #define vasprintf Xvasprintf
 #endif
 
+/*
+ * These functions provide a portable implementation of the linux kernel
+ * scnprintf & vscnprintf routines that return the number of bytes actually
+ * copied during a snprintf, (excluding the final '\0').
+ */
+extern _X_EXPORT int
+Xscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, ...)
+_X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT int
+Xvscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, va_list va)
+_X_ATTRIBUTE_PRINTF(3,0);
+
 #endif                          /* XPRINTF_H */
diff --git a/os/xprintf.c b/os/xprintf.c
index 17fea2e..80caa57 100644
--- a/os/xprintf.c
+++ b/os/xprintf.c
@@ -186,6 +186,50 @@ XNFasprintf(char **ret, const char *_X_RESTRICT_KYWD format, ...)
     return size;
 }
 
+/**
+ * Varargs snprintf that returns the actual number of bytes (excluding final
+ * '\0') that were copied into the buffer.
+ * This is opposed to the normal sprintf() usually returns the number of bytes
+ * that would have been written.
+ *
+ * @param s       buffer to copy into
+ * @param n       size of buffer s
+ * @param format  printf style format string
+ * @param va      variable argument list
+ * @return        number of bytes actually copied, excluding final '\0'
+ */
+int
+Xvscnprintf(char *s, int n, const char *format, va_list args)
+{
+    int x;
+    if (n == 0)
+        return 0;
+    x = vsnprintf(s, n , format, args);
+    return (x >= n) ? (n - 1) : x;
+}
+
+/**
+ * snprintf that returns the actual number of bytes (excluding final '\0') that
+ * were copied into the buffer.
+ * This is opposed to the normal sprintf() usually returns the number of bytes
+ * that would have been written.
+ *
+ * @param s       buffer to copy into
+ * @param n       size of buffer s
+ * @param format  printf style format string
+ * @param ...     arguments for specified format
+ * @return        number of bytes actually copied, excluding final '\0'
+ */
+int Xscnprintf(char *s, int n, const char *format, ...)
+{
+    int x;
+    va_list ap;
+    va_start(ap, format);
+    x = Xvscnprintf(s, n, format, ap);
+    va_end(ap);
+    return x;
+}
+
 /* Old api, now deprecated, may be removed in the future */
 char *
 Xvprintf(const char *format, va_list va)
commit 9a2030ea26a2a0821d87afea502f5446ae002a6d
Author: Daniel Kurtz <djkurtz at chromium.org>
Date:   Wed Apr 18 17:51:50 2012 +0800

    os/log: trivial cleanups
    
     * space->tab
     * remove comment that doesn't make any sense
    
    Signed-off-by: Daniel Kurtz <djkurtz at chromium.org>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    (cherry picked from commit c30862879d2c766519780bb7f353f35edf0daa9b)

diff --git a/os/log.c b/os/log.c
index 0ccd126..297b46a 100644
--- a/os/log.c
+++ b/os/log.c
@@ -165,7 +165,7 @@ asm(".desc ___crashreporter_info__, 0x10");
 #define X_NOT_IMPLEMENTED_STRING	"(NI)"
 #endif
 #ifndef X_NONE_STRING
-#define X_NONE_STRING                   ""
+#define X_NONE_STRING			""
 #endif
 
 /*
@@ -223,7 +223,7 @@ LogInit(const char *fname, const char *backup)
      * needed.
      */
     if (saveBuffer && bufferSize > 0) {
-        free(saveBuffer);       /* Must be free(), not free() */
+        free(saveBuffer);
         saveBuffer = NULL;
         bufferSize = 0;
     }


More information about the xorg-commit mailing list