[Xquartz-changes] xserver: Branch 'master' - 15 commits

Jeremy Huddleston jeremyhu at freedesktop.org
Wed May 2 21:07:04 PDT 2012


 Xi/xiquerypointer.c                |   25 +++++---
 Xi/xiqueryversion.c                |   41 ++++++-------
 configure.ac                       |   15 +++-
 dix/devices.c                      |    1 
 dix/getevents.c                    |    3 
 dix/globals.c                      |    1 
 dix/touch.c                        |    5 +
 hw/dmx/dmxlog.c                    |   13 +++-
 hw/dmx/dmxlog.h                    |   19 +++---
 include/opaque.h                   |    1 
 man/Xserver.man                    |    7 ++
 os/WaitFor.c                       |   18 +++++
 os/connection.c                    |   68 +++++++++++++++-------
 os/utils.c                         |    9 ++
 test/Makefile.am                   |    2 
 test/xi2/protocol-xiqueryversion.c |  113 +++++++++++++++++++++++++++++++++++++
 16 files changed, 276 insertions(+), 65 deletions(-)

New commits:
commit 97041364a6acb2b66b5cfd06757c90a006ad50e9
Merge: 1908272 ee542b8
Author: Keith Packard <keithp at keithp.com>
Date:   Wed May 2 20:47:25 2012 -0700

    Merge remote-tracking branch 'whot/for-keith'
    
    No conflicts here

commit ee542b85590814ee25369babce1ad14feeb137af
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>

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 19082726cb2c69f53e9720904521e3c98f788bff
Author: Ryan Pavlik <rpavlik at iastate.edu>
Date:   Fri Oct 21 12:47:38 2011 -0500

    configure.ac: on MinGW, link with ws2_32 instead of winsock2
    
    ws2_32 is the correct name for the libary (even on 64 bit Windows :-))
    
    Signed-off-by: Ryan Pavlik <rpavlik at iastate.edu>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>

diff --git a/configure.ac b/configure.ac
index 485fd18..6a41ea8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1863,7 +1863,7 @@ if test "x$XWIN" = xyes; then
 			XWIN_SERVER_NAME=Xming
 			AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location])
 			AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets])
-			XWIN_SYS_LIBS=-lwinsock2
+			XWIN_SYS_LIBS=-lws2_32
 			;;
 	esac
 	XWIN_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $RANDR_LIB $RENDER_LIB $DBE_LIB $RECORD_LIB $GLX_LIBS $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $DAMAGE_LIB $MIEXT_SYNC_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $OS_LIB"
commit ad9605a3e21b20fa8565dc6701610712ac6dd9e1
Author: Ryan Pavlik <rpavlik at iastate.edu>
Date:   Fri Nov 4 13:26:14 2011 -0500

    configure.ac: MinGW doesn't have setuid binaries either.
    
    If the target platform isn't in a list of platforms we know don't use a
    setuid binary, we try to test if we can chown something to root.
    
    This test possibly won't give the right answer if we are cross-compiling,
    which is common for the MinGW target.  This patch adds MinGW to the list
    of platforms we know don't use a setuid binary.
    
    Signed-off-by: Ryan Pavlik <rpavlik at iastate.edu>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>

diff --git a/configure.ac b/configure.ac
index a9360cb..485fd18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -657,6 +657,7 @@ AC_MSG_CHECKING([to see if we can install the Xorg server as root])
 if test "x$SETUID" = "xauto" ; then
 	case $host_os in
 	    cygwin*)		SETUID="no"  ;;
+	    mingw*)		SETUID="no"  ;;
 	    darwin*)		SETUID="no"  ;;
 	    *)
 	   	case $host_cpu in
commit 2225208c2ef9857f14813376ce85d305f19263dd
Author: Ryan Pavlik <rpavlik at iastate.edu>
Date:   Fri Nov 4 13:30:43 2011 -0500

    configure.ac: auto-disable MITSHM if we lack IPC
    
    The MITSHM extension uses SYSV IPC, but even if configure's test
    for IPC failed, MITSHM was still enabled by default, breaking
    MinGW builds by default.
    
    Unfortunately, fixing this exposes the fact that the HAVE_SYSV_IPC
    test wasn't being used for anything before and so we hadn't noticed it
    was failing on Cygwin.
    
    Change from using SHM_W|SHM_R flags (which aren't required by POSIX) to
    S_IRUSR|S_IWUSR flags (which are)
    
    Signed-off-by: Ryan Pavlik <rpavlik at iastate.edu>
    Reviewed-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>

diff --git a/configure.ac b/configure.ac
index f81349b..a9360cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -271,10 +271,11 @@ AC_CACHE_CHECK([for SYSV IPC],
 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/shm.h>
+#include <sys/stat.h>
 ],[
 { 
     int id;
-    id = shmget(IPC_PRIVATE, 512, SHM_W | SHM_R);
+    id = shmget(IPC_PRIVATE, 512, S_IRUSR | S_IWUSR);
     if (id < 0) return -1;
     return shmctl(id, IPC_RMID, 0);
 }],
@@ -592,7 +593,7 @@ AC_ARG_WITH(khronos-spec-dir, AS_HELP_STRING([--with-khronos-spec-dir=PATH], [Pa
 dnl Extensions.
 AC_ARG_ENABLE(registry,       AS_HELP_STRING([--disable-registry], [Build string registry module (default: enabled)]), [XREGISTRY=$enableval], [XREGISTRY=yes])
 AC_ARG_ENABLE(composite,      AS_HELP_STRING([--disable-composite], [Build Composite extension (default: enabled)]), [COMPOSITE=$enableval], [COMPOSITE=yes])
-AC_ARG_ENABLE(mitshm,         AS_HELP_STRING([--disable-mitshm], [Build SHM extension (default: enabled)]), [MITSHM=$enableval], [MITSHM=yes])
+AC_ARG_ENABLE(mitshm,         AS_HELP_STRING([--disable-mitshm], [Build SHM extension (default: auto)]), [MITSHM=$enableval], [MITSHM=auto])
 AC_ARG_ENABLE(xres,           AS_HELP_STRING([--disable-xres], [Build XRes extension (default: enabled)]), [RES=$enableval], [RES=yes])
 AC_ARG_ENABLE(record,         AS_HELP_STRING([--disable-record], [Build Record extension (default: enabled)]), [RECORD=$enableval], [RECORD=yes])
 AC_ARG_ENABLE(xv,             AS_HELP_STRING([--disable-xv], [Build Xv extension (default: enabled)]), [XV=$enableval], [XV=yes])
@@ -1000,6 +1001,9 @@ if test "x$COMPOSITE" = xyes; then
 	COMPOSITE_INC='-I$(top_srcdir)/composite'
 fi
 
+if test "x$MITSHM" = xauto; then
+	MITSHM="$ac_cv_sysv_ipc"
+fi
 AM_CONDITIONAL(MITSHM, [test "x$MITSHM" = xyes])
 if test "x$MITSHM" = xyes; then
 	AC_DEFINE(MITSHM, 1, [Support MIT-SHM extension])
commit 1e7b500a8e1d79b91a4e857a2da06194efe8cf69
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>

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 0426e6d65b6598edfbcb2fc66ee65fb08256469e
Author: Jon TURNEY <jon.turney at dronecode.org.uk>
Date:   Tue Jan 3 00:14:32 2012 +0000

    configure.ac: Make default configuration for MinGW disable unsupported extensions and DDXs
    
    Same as the default configuration for Cygwin, --disable-xorg and --disable-dmx DDX by default,
    and force --disable-xv and other unsupported extensions
    
    Signed-off-by: Jon TURNEY <jon.turney at dronecode.org.uk>
    Reviewed-by: Yaakov Selkowitz <yselkowitz at users.sourceforge.net>

diff --git a/configure.ac b/configure.ac
index 4afac82..f81349b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -698,7 +698,7 @@ AM_CONDITIONAL(INSTALL_LIBXF86CONFIG, [test "x$INSTALL_LIBXF86CONFIG" = xyes])
 dnl DDX Detection... Yes, it's ugly to have it here... but we need to
 dnl handle this early on so that we don't require unsupported extensions
 case $host_os in
-	cygwin*)
+	cygwin* | mingw*)
 		CONFIG_DBUS_API=no
 		CONFIG_HAL=no
 		CONFIG_UDEV=no
@@ -1547,6 +1547,7 @@ if test "x$XORG" = xauto; then
 	XORG="yes"
 	case $host_os in
 		cygwin*) XORG="no" ;;
+		mingw*)  XORG="no" ;;
 		darwin*) XORG="no" ;;
 	esac
 fi
@@ -1948,6 +1949,7 @@ if test "x$DMX" = xauto; then
 	DMX="$have_dmx"
 	case $host_os in
 		cygwin*) DMX="no" ;;
+		mingw*)  DMX="no" ;;
 		darwin*) DMX="no" ;;
 	esac
 fi
commit f3410b97cf9b48a47bee3d15d232f8a88e75f4ef
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Apr 30 10:01:48 2012 +1000

    dix: when disabling a device, release all buttons and keys
    
    A suspend-induced device disable may happen before the device gets to see
    the button release event. On resume, the server's internal state still has
    some buttons pressed, causing inconsistent behaviour.
    
    Force the release and the matching events to be sent to the client.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/devices.c b/dix/devices.c
index 600f8b7..7f38865 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -437,6 +437,7 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
     if (*prev != dev)
         return FALSE;
 
+    ReleaseButtonsAndKeys(dev);
     SyncRemoveDeviceIdleTime(dev->idle_counter);
     dev->idle_counter = NULL;
 
commit af88b43f9e604157b74270d609c08bdfa256a792
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 27 16:31:17 2012 +1000

    dix: don't emulate scroll events for non-existing axes (#47281)
    
    Test case:
    - create a device with REL_HWHEEL and ABS_X and ABS_Y. evdev 2.7.0 will set
      that up as device with 1 relative axis
    - move pointer to VGA1
    - xrandr --output VGA1 --off
    
    Warps the pointer to the new spot and calls GPE with the x/y mask bits set.
    When running through the loop to check for scroll event, this overruns the
    axes and may try to emulate scroll events based on random garbage in the
    memory. If that memory contained non-zero for the scroll type but near-zero
    for the increment field, the server would hang in an infinite loop.
    
    This was the trigger for this suggested, never-merged, patch here:
    http://patchwork.freedesktop.org/patch/9543/
    
    X.Org Bug 47281 <http://bugs.freedesktop.org/show_bug.cgi?id=47281>
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/dix/getevents.c b/dix/getevents.c
index 23bbe06..c960d44 100644
--- a/dix/getevents.c
+++ b/dix/getevents.c
@@ -1598,6 +1598,9 @@ GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
     /* Now turn the smooth-scrolling axes back into emulated button presses
      * for legacy clients, based on the integer delta between before and now */
     for (i = 0; i < valuator_mask_size(&mask); i++) {
+        if (i >= pDev->valuator->numAxes)
+            break;
+
         if (!valuator_mask_isset(&mask, i))
             continue;
 
commit 08962951de969b9d8c870af8b6e47303dc0decfd
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Fri Apr 27 10:52:39 2012 +1000

    os: make timers signal-safe
    
    If TimerSet() is called from a signal handler (synaptics tap handling code)
    may result in list corruption if we're currently inside TimerSet().
    
    See backtrace in
    https://bugzilla.redhat.com/show_bug.cgi?id=814869
    
    Block signals for all list manipulations in the timers.
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Chase Douglas <chase.douglas at canonical.com>

diff --git a/os/WaitFor.c b/os/WaitFor.c
index 95e64ba..393890f 100644
--- a/os/WaitFor.c
+++ b/os/WaitFor.c
@@ -382,6 +382,7 @@ CheckAllTimers(void)
     OsTimerPtr timer;
     CARD32 now;
 
+    OsBlockSignals();
  start:
     now = GetTimeInMillis();
 
@@ -391,6 +392,7 @@ CheckAllTimers(void)
             goto start;
         }
     }
+    OsReleaseSignals();
 }
 
 static void
@@ -398,11 +400,13 @@ DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev)
 {
     CARD32 newTime;
 
+    OsBlockSignals();
     *prev = timer->next;
     timer->next = NULL;
     newTime = (*timer->callback) (timer, now, timer->arg);
     if (newTime)
         TimerSet(timer, 0, newTime, timer->callback, timer->arg);
+    OsReleaseSignals();
 }
 
 OsTimerPtr
@@ -418,6 +422,7 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
             return NULL;
     }
     else {
+        OsBlockSignals();
         for (prev = &timers; *prev; prev = &(*prev)->next) {
             if (*prev == timer) {
                 *prev = timer->next;
@@ -426,6 +431,7 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
                 break;
             }
         }
+        OsReleaseSignals();
     }
     if (!millis)
         return timer;
@@ -445,26 +451,32 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis,
         if (!millis)
             return timer;
     }
+    OsBlockSignals();
     for (prev = &timers;
          *prev && (int) ((*prev)->expires - millis) <= 0;
          prev = &(*prev)->next);
     timer->next = *prev;
     *prev = timer;
+    OsReleaseSignals();
     return timer;
 }
 
 Bool
 TimerForce(OsTimerPtr timer)
 {
+    int rc = FALSE;
     OsTimerPtr *prev;
 
+    OsBlockSignals();
     for (prev = &timers; *prev; prev = &(*prev)->next) {
         if (*prev == timer) {
             DoTimer(timer, GetTimeInMillis(), prev);
-            return TRUE;
+            rc = TRUE;
+            break;
         }
     }
-    return FALSE;
+    OsReleaseSignals();
+    return rc;
 }
 
 void
@@ -474,12 +486,14 @@ TimerCancel(OsTimerPtr timer)
 
     if (!timer)
         return;
+    OsBlockSignals();
     for (prev = &timers; *prev; prev = &(*prev)->next) {
         if (*prev == timer) {
             *prev = timer->next;
             break;
         }
     }
+    OsReleaseSignals();
 }
 
 void
commit d662fa2450856777b59c4b62b912395a8bfd52fd
Author: Michal Suchanek <hramrach at gmail.com>
Date:   Thu Apr 26 15:11:20 2012 +0200

    dmx: Annotate dmxlog.c with _X_ATTRIBUTE_PRINTF and _X_NORETURN
    
    and fix resulting printf warning in dmxLogVisual
    
    Signed-off-by: Michal Suchanek <hramrach at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/hw/dmx/dmxlog.c b/hw/dmx/dmxlog.c
index 33aee59..3249c48 100644
--- a/hw/dmx/dmxlog.c
+++ b/hw/dmx/dmxlog.c
@@ -86,6 +86,8 @@ ErrorF(const char *format, ...)
 
 /** Provide an VFatalError function when used stand-alone. */
 static void
+VFatalError(const char *format, va_list args) _X_ATTRIBUTE_PRINTF(1, 0) _X_NORETURN;
+static void
 VFatalError(const char *format, va_list args)
 {
     vfprintf(stderr, format, args);     /* RATS: We assume the format string
@@ -104,7 +106,9 @@ VErrorF(const char *format, va_list args)
 }
 #else
 /** This function was removed between XFree86 4.3.0 and XFree86 4.4.0. */
-extern void AbortServer(void);
+extern void AbortServer(void) _X_NORETURN;
+static void
+VFatalError(const char *format, va_list args) _X_ATTRIBUTE_PRINTF(1, 0) _X_NORETURN;
 static void
 VFatalError(const char *format, va_list args)
 {
@@ -163,6 +167,8 @@ dmxHeader(dmxLogLevel logLevel, DMXInputInfo * dmxInput,
 /* Prints the error message with the appropriate low-level X output
  * routine. */
 static void
+dmxMessage(dmxLogLevel logLevel, const char *format, va_list args) _X_ATTRIBUTE_PRINTF(2, 0);
+static void
 dmxMessage(dmxLogLevel logLevel, const char *format, va_list args)
 {
     if (logLevel == dmxFatal || logLevel >= dmxCurrentLogLevel) {
@@ -300,10 +306,11 @@ dmxLogVisual(DMXScreenInfo * dmxScreen, XVisualInfo * vi, int defaultVisual)
         class = "DirectColor";
         break;
     }
+#define VisualLogFormat "0x%02lx %s %2db %db/rgb %3d 0x%04lx 0x%04lx 0x%04lx%s\n"
 
     if (dmxScreen) {
         dmxLogOutput(dmxScreen,
-                     "0x%02x %s %2db %db/rgb %3d 0x%04x 0x%04x 0x%04x%s\n",
+                     VisualLogFormat,
                      vi->visualid, class, vi->depth, vi->bits_per_rgb,
                      vi->colormap_size,
                      vi->red_mask, vi->green_mask, vi->blue_mask,
@@ -311,7 +318,7 @@ dmxLogVisual(DMXScreenInfo * dmxScreen, XVisualInfo * vi, int defaultVisual)
     }
     else {
         dmxLog(dmxInfo,
-               "  0x%02x %s %2db %db/rgb %3d 0x%04x 0x%04x 0x%04x%s\n",
+               "  " VisualLogFormat,
                vi->visualid, class, vi->depth, vi->bits_per_rgb,
                vi->colormap_size,
                vi->red_mask, vi->green_mask, vi->blue_mask,
diff --git a/hw/dmx/dmxlog.h b/hw/dmx/dmxlog.h
index 4d4cd26..162484b 100644
--- a/hw/dmx/dmxlog.h
+++ b/hw/dmx/dmxlog.h
@@ -55,18 +55,23 @@ typedef enum {
 /* Logging functions used by Xserver/hw/dmx routines. */
 extern dmxLogLevel dmxSetLogLevel(dmxLogLevel newLevel);
 extern dmxLogLevel dmxGetLogLevel(void);
-extern void dmxLog(dmxLogLevel logLevel, const char *format, ...);
-extern void dmxLogCont(dmxLogLevel logLevel, const char *format, ...);
+extern void dmxLog(dmxLogLevel logLevel, const char *format,
+                             ...) _X_ATTRIBUTE_PRINTF(2, 3);
+extern void dmxLogCont(dmxLogLevel logLevel, const char *format,
+                             ...) _X_ATTRIBUTE_PRINTF(2, 3);
 extern const char *dmxEventName(int type);
 
 #ifndef DMX_LOG_STANDALONE
-extern void dmxLogOutput(DMXScreenInfo * dmxScreen, const char *format, ...);
+extern void dmxLogOutput(DMXScreenInfo * dmxScreen, const char *format,
+                             ...) _X_ATTRIBUTE_PRINTF(2, 3);
 extern void dmxLogOutputCont(DMXScreenInfo * dmxScreen, const char *format,
-                             ...);
+                             ...) _X_ATTRIBUTE_PRINTF(2, 3);
 extern void dmxLogOutputWarning(DMXScreenInfo * dmxScreen, const char *format,
-                                ...);
-extern void dmxLogInput(DMXInputInfo * dmxInput, const char *format, ...);
-extern void dmxLogInputCont(DMXInputInfo * dmxInput, const char *format, ...);
+                             ...) _X_ATTRIBUTE_PRINTF(2, 3);
+extern void dmxLogInput(DMXInputInfo * dmxInput, const char *format,
+                             ...) _X_ATTRIBUTE_PRINTF(2, 3);
+extern void dmxLogInputCont(DMXInputInfo * dmxInput, const char *format,
+                             ...) _X_ATTRIBUTE_PRINTF(2, 3);
 extern void dmxLogArgs(dmxLogLevel logLevel, int argc, char **argv);
 extern void dmxLogVisual(DMXScreenInfo * dmxScreen, XVisualInfo * vi,
                          int defaultVisual);
commit 5c361d59c5031d9b3f7f9093a52d2b1ff4d9ae5f
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Fri Apr 20 11:08:15 2012 -0700

    TouchListenerAcceptReject: Warn and return early on bad listener index
    
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Bryce Harrington <bryce at canonical.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/touch.c b/dix/touch.c
index dd16367..401cb98 100644
--- a/dix/touch.c
+++ b/dix/touch.c
@@ -966,6 +966,11 @@ TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener,
     int nev;
     int i;
 
+    BUG_WARN(listener < 0);
+    BUG_WARN(listener >= ti->num_listeners);
+    if (listener < 0 || listener >= ti->num_listeners)
+        return BadMatch;
+
     if (listener > 0) {
         if (mode == XIRejectTouch)
             TouchRejected(dev, ti, ti->listeners[listener].listener, NULL);
commit 88bacc49f06da5927f716869f5a32672a8297ed0
Author: Chase Douglas <chase.douglas at canonical.com>
Date:   Wed Apr 4 15:29:42 2012 -0700

    os: Add -displayfd option
    
    This option specifies a file descriptor in the launching process.  X
    will scan for an available display number and write that number back to
    the launching process, at the same time as SIGUSR1 generation.  This
    means display managers don't need to guess at available display numbers.
    As a consequence, if X fails to start when using -displayfd, it's not
    because the display was in use, so there's no point in retrying the X
    launch on a higher display number.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Chase Douglas <chase.douglas at canonical.com>
    Reviewed-by: Julien Cristau <jcristau at debian.org>
    Tested-by: Julien Cristau <jcristau at debian.org>
    Reviewed-by: Alan Coopersmith <alan.coopersmith at oracle.com>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/dix/globals.c b/dix/globals.c
index a564575..332b91f 100644
--- a/dix/globals.c
+++ b/dix/globals.c
@@ -128,6 +128,7 @@ int defaultColorVisualClass = -1;
 int monitorResolution = 0;
 
 char *display;
+int displayfd;
 char *ConnectionInfo;
 
 CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
diff --git a/include/opaque.h b/include/opaque.h
index 9ca408a..b76ab6e 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -50,6 +50,7 @@ extern _X_EXPORT int ScreenSaverAllowExposures;
 extern _X_EXPORT int defaultScreenSaverBlanking;
 extern _X_EXPORT int defaultScreenSaverAllowExposures;
 extern _X_EXPORT char *display;
+extern _X_EXPORT int displayfd;
 
 extern _X_EXPORT int defaultBackingStore;
 extern _X_EXPORT Bool disableBackingStore;
diff --git a/man/Xserver.man b/man/Xserver.man
index 0cd9b94..8d243d6 100644
--- a/man/Xserver.man
+++ b/man/Xserver.man
@@ -127,6 +127,13 @@ Not obeyed by all servers.
 .B \-core
 causes the server to generate a core dump on fatal errors.
 .TP 8
+.B \-displayfd \fIfd\fP
+specifies a file descriptor in the launching process.  Rather than specify
+a display number, the X server will attempt to listen on successively higher
+display numbers, and upon finding a free one, will write the port number back
+on this file descriptor as a newline-terminated string.  The \-pn option is
+ignored when using \-displayfd.
+.TP 8
 .B \-deferglyphs \fIwhichfonts\fP
 specifies the types of fonts for which the server should attempt to use
 deferred glyph loading.  \fIwhichfonts\fP can be all (all fonts),
diff --git a/os/connection.c b/os/connection.c
index 1099752..039942f 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -142,6 +142,7 @@ Bool AnyClientsWriteBlocked;    /* true if some client blocked on write */
 static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
 Bool RunFromSigStopParent;      /* send SIGSTOP to our own process; Upstart (or
                                    equivalent) will send SIGCONT back. */
+static char dynamic_display[7]; /* display name */
 Bool PartialNetwork;            /* continue even if unable to bind all addrs */
 static Pid_t ParentProcess;
 
@@ -350,6 +351,10 @@ void
 NotifyParentProcess(void)
 {
 #if !defined(WIN32)
+    if (dynamic_display[0]) {
+        write(displayfd, dynamic_display, strlen(dynamic_display));
+        close(displayfd);
+    }
     if (RunFromSmartParent) {
         if (ParentProcess > 1) {
             kill(ParentProcess, SIGUSR1);
@@ -360,6 +365,18 @@ NotifyParentProcess(void)
 #endif
 }
 
+static Bool
+TryCreateSocket(int num, int *partial)
+{
+    char port[20];
+
+    snprintf(port, sizeof(port), "%d", num);
+
+    return (_XSERVTransMakeAllCOTSServerListeners(port, partial,
+                                                  &ListenTransCount,
+                                                  &ListenTransConns) >= 0);
+}
+
 /*****************
  * CreateWellKnownSockets
  *    At initialization, create the sockets to listen on for new clients.
@@ -370,7 +387,6 @@ CreateWellKnownSockets(void)
 {
     int i;
     int partial;
-    char port[20];
 
     FD_ZERO(&AllSockets);
     FD_ZERO(&AllClients);
@@ -386,29 +402,41 @@ CreateWellKnownSockets(void)
 
     FD_ZERO(&WellKnownConnections);
 
-    snprintf(port, sizeof(port), "%d", atoi(display));
-
-    if ((_XSERVTransMakeAllCOTSServerListeners(port, &partial,
-                                               &ListenTransCount,
-                                               &ListenTransConns) >= 0) &&
-        (ListenTransCount >= 1)) {
-        if (!PartialNetwork && partial) {
-            FatalError("Failed to establish all listening sockets");
+    /* display is initialized to "0" by main(). It is then set to the display
+     * number if specified on the command line, or to NULL when the -displayfd
+     * option is used. */
+    if (display) {
+        if (TryCreateSocket(atoi(display), &partial) &&
+            ListenTransCount >= 1)
+            if (!PartialNetwork && partial)
+                FatalError ("Failed to establish all listening sockets");
+    }
+    else { /* -displayfd */
+        Bool found = 0;
+        for (i = 0; i < 65535 - X_TCP_PORT; i++) {
+            if (TryCreateSocket(i, &partial) && !partial) {
+                found = 1;
+                break;
+            }
+            else
+                CloseWellKnownConnections();
         }
-        else {
-            ListenTransFds = malloc(ListenTransCount * sizeof(int));
+        if (!found)
+            FatalError("Failed to find a socket to listen on");
+        snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
+        display = dynamic_display;
+    }
 
-            for (i = 0; i < ListenTransCount; i++) {
-                int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
+    ListenTransFds = malloc(ListenTransCount * sizeof (int));
 
-                ListenTransFds[i] = fd;
-                FD_SET(fd, &WellKnownConnections);
+    for (i = 0; i < ListenTransCount; i++) {
+        int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
 
-                if (!_XSERVTransIsLocal(ListenTransConns[i])) {
-                    DefineSelf(fd);
-                }
-            }
-        }
+        ListenTransFds[i] = fd;
+        FD_SET(fd, &WellKnownConnections);
+
+        if (!_XSERVTransIsLocal(ListenTransConns[i]))
+            DefineSelf (fd);
     }
 
     if (!XFD_ANYSET(&WellKnownConnections))
diff --git a/os/utils.c b/os/utils.c
index 30592d2..3a1ef93 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -659,6 +659,15 @@ ProcessCommandLine(int argc, char *argv[])
             else
                 UseMsg();
         }
+        else if (strcmp(argv[i], "-displayfd") == 0) {
+            if (++i < argc) {
+                displayfd = atoi(argv[i]);
+                display = NULL;
+                nolock = TRUE;
+            }
+            else
+                UseMsg();
+        }
 #ifdef DPMSExtension
         else if (strcmp(argv[i], "dpms") == 0)
             /* ignored for compatibility */ ;
commit 1d82ec95942b88dd01f0ac6b883368360a0b5fe6
Author: Michal Suchanek <hramrach at gmail.com>
Date:   Mon Apr 23 13:52:40 2012 +0200

    xserver: Fix out-of-tree build
    
    Fixes regression caused by ccb3e78124fb05defd0c9b438746b79d84dfc3ae
    
    Signed-off-by: Michal Suchanek <hramrach at gmail.com>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/test/Makefile.am b/test/Makefile.am
index 8582397..b2a53aa 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -36,7 +36,7 @@ misc_LDADD=$(TEST_LDADD)
 fixes_LDADD=$(TEST_LDADD)
 xfree86_LDADD=$(TEST_LDADD)
 touch_LDADD=$(TEST_LDADD)
-hashtabletest_LDADD=$(TEST_LDADD) ../Xext/hashtable.c
+hashtabletest_LDADD=$(TEST_LDADD) $(top_srcdir)/Xext/hashtable.c
 
 libxservertest_la_LIBADD = $(XSERVER_LIBS)
 if XORG
commit ea51e9b2877df60135edaf2a8f88d0f2a2b41060
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Mon Apr 23 10:35:53 2012 +1000

    Xi: return BadValue on XIQueryVersion if the version is less than first call
    
    Clients that use plugin systems may require multiple calls to
    XIQueryVersion from different plugins. The current error handling requires
    client-side synchronisation of version numbers.
    
    The first call to XIQueryVersion defines the server behaviour. Once cached,
    always return that version number to any clients. Unless a client requests a
    version lower than the first defined one, then a BadValue must be returned
    to be protocol-compatible.
    
    Introduced in 2c23ef83b0e03e163aeeb06133538606886f4e9c
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c
index fc0ca75..6081c41 100644
--- a/Xi/xiqueryversion.c
+++ b/Xi/xiqueryversion.c
@@ -70,28 +70,29 @@ ProcXIQueryVersion(ClientPtr client)
 
     pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
 
-    if (pXIClient->major_version &&
-           (stuff->major_version != pXIClient->major_version ||
-            stuff->minor_version != pXIClient->minor_version))
-    {
-        client->errorValue = stuff->major_version;
-        return BadValue;
+    if (pXIClient->major_version) {
+        if (version_compare(stuff->major_version, stuff->minor_version,
+                            pXIClient->major_version, pXIClient->minor_version) < 0) {
+            client->errorValue = stuff->major_version;
+            return BadValue;
+        }
+        major = pXIClient->major_version;
+        minor = pXIClient->minor_version;
+    } else {
+        if (version_compare(XIVersion.major_version, XIVersion.minor_version,
+                    stuff->major_version, stuff->minor_version) > 0) {
+            major = stuff->major_version;
+            minor = stuff->minor_version;
+        }
+        else {
+            major = XIVersion.major_version;
+            minor = XIVersion.minor_version;
+        }
+
+        pXIClient->major_version = major;
+        pXIClient->minor_version = minor;
     }
 
-
-    if (version_compare(XIVersion.major_version, XIVersion.minor_version,
-                        stuff->major_version, stuff->minor_version) > 0) {
-        major = stuff->major_version;
-        minor = stuff->minor_version;
-    }
-    else {
-        major = XIVersion.major_version;
-        minor = XIVersion.minor_version;
-    }
-
-    pXIClient->major_version = major;
-    pXIClient->minor_version = minor;
-
     memset(&rep, 0, sizeof(xXIQueryVersionReply));
     rep.repType = X_Reply;
     rep.RepType = X_XIQueryVersion;
diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c
index 2552307..1347e86 100644
--- a/test/xi2/protocol-xiqueryversion.c
+++ b/test/xi2/protocol-xiqueryversion.c
@@ -54,6 +54,8 @@ struct test_data {
     int minor_client;
     int major_server;
     int minor_server;
+    int major_cached;
+    int minor_cached;
 };
 
 static void
@@ -82,6 +84,24 @@ reply_XIQueryVersion(ClientPtr client, int len, char *data, void *userdata)
     assert((sver > cver) ? ver == cver : ver == sver);
 }
 
+static void
+reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *userdata)
+{
+    xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data;
+    struct test_data *versions = (struct test_data *) userdata;
+
+    reply_check_defaults(rep, len, XIQueryVersion);
+    assert(rep->length == 0);
+
+    if (versions->major_cached == -1) {
+        versions->major_cached = rep->major_version;
+        versions->minor_cached = rep->minor_version;
+    }
+
+    assert(versions->major_cached == rep->major_version);
+    assert(versions->minor_cached == rep->minor_version);
+}
+
 /**
  * Run a single test with server version smaj.smin and client
  * version cmaj.cmin. Verify that return code is equal to 'error'.
@@ -173,12 +193,105 @@ test_XIQueryVersion(void)
     reply_handler = NULL;
 }
 
+
+static void
+test_XIQueryVersion_multiple(void)
+{
+    xXIQueryVersionReq request;
+    ClientRec client;
+    struct test_data versions;
+    int rc;
+
+    request_init(&request, XIQueryVersion);
+    client = init_client(request.length, &request);
+
+    /* Change the server to support 2.2 */
+    XIVersion.major_version = 2;
+    XIVersion.minor_version = 2;
+
+    reply_handler = reply_XIQueryVersion_multiple;
+    userdata = (void *) &versions;
+
+    /* run 1 */
+    versions.major_cached = -1;
+    versions.minor_cached = -1;
+
+    /* client is lower than server, noncached */
+    request.major_version = 2;
+    request.minor_version = 1;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == Success);
+
+    /* client is higher than server, cached */
+    request.major_version = 2;
+    request.minor_version = 3;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == Success);
+
+    /* client is equal, cached */
+    request.major_version = 2;
+    request.minor_version = 2;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == Success);
+
+    /* client is low than cached */
+    request.major_version = 2;
+    request.minor_version = 0;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == BadValue);
+
+    /* run 2 */
+    client = init_client(request.length, &request);
+    XIVersion.major_version = 2;
+    XIVersion.minor_version = 2;
+    versions.major_cached = -1;
+    versions.minor_cached = -1;
+
+    request.major_version = 2;
+    request.minor_version = 2;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == Success);
+
+    request.major_version = 2;
+    request.minor_version = 3;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == Success);
+
+    request.major_version = 2;
+    request.minor_version = 1;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == BadValue);
+
+    /* run 3 */
+    client = init_client(request.length, &request);
+    XIVersion.major_version = 2;
+    XIVersion.minor_version = 2;
+    versions.major_cached = -1;
+    versions.minor_cached = -1;
+
+    request.major_version = 2;
+    request.minor_version = 3;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == Success);
+
+    request.major_version = 2;
+    request.minor_version = 2;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == Success);
+
+    request.major_version = 2;
+    request.minor_version = 1;
+    rc = ProcXIQueryVersion(&client);
+    assert(rc == BadValue);
+}
+
 int
 main(int argc, char **argv)
 {
     init_simple();
 
     test_XIQueryVersion();
+    test_XIQueryVersion_multiple();
 
     return 0;
 }


More information about the Xquartz-changes mailing list