[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

xorg-server: Changes to 'upstream-experimental'



 Xext/sync.c                              |   19 +--
 Xi/extinit.c                             |    1 
 Xi/xiproperty.c                          |    9 +
 Xi/xiproperty.h                          |    3 
 configure.ac                             |    2 
 dix/devices.c                            |    9 -
 dix/events.c                             |   20 ++-
 doc/Xserver.man.pre                      |   26 +---
 glx/glxdri2.c                            |   23 +---
 hw/dmx/dmxextension.c                    |    2 
 hw/xfree86/common/xf86DGA.c              |    4 
 hw/xfree86/common/xf86Xinput.c           |    6 -
 hw/xfree86/doc/Makefile.am               |    1 
 hw/xfree86/dri2/dri2.c                   |  174 +++++++++++++++++++++----------
 hw/xfree86/dri2/dri2.h                   |    6 +
 hw/xfree86/dri2/dri2ext.c                |   11 +
 hw/xfree86/modes/xf86Cursors.c           |    2 
 hw/xfree86/os-support/solaris/sun_init.c |  102 ++++++++++++++----
 hw/xfree86/ramdac/xf86Cursor.c           |    2 
 hw/xquartz/X11Application.m              |   28 +++-
 hw/xquartz/mach-startup/bundle-main.c    |    5 
 include/eventstr.h                       |    4 
 include/protocol-versions.h              |    4 
 mi/miarc.c                               |    2 
 mi/midispcur.c                           |    2 
 mi/mipolypnt.c                           |    5 
 os/access.c                              |    9 -
 os/log.c                                 |    7 +
 render/render.c                          |    7 +
 test/xi2/protocol-common.c               |    1 
 xfixes/cursor.c                          |   23 ++--
 31 files changed, 347 insertions(+), 172 deletions(-)

New commits:
commit b65c5be170835db2282192381ef411997e61a6f1
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Wed Jun 2 09:27:33 2010 +1000

    xserver 1.8.1.901
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/configure.ac b/configure.ac
index 637e610..73a7b62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,7 +26,7 @@ dnl
 dnl Process this file with autoconf to create configure.
 
 AC_PREREQ(2.57)
-AC_INIT([xorg-server], 1.8.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
+AC_INIT([xorg-server], 1.8.1.901, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server)
 RELEASE_DATE="2010-05-11"
 AC_CONFIG_SRCDIR([Makefile.am])
 AM_INIT_AUTOMAKE([foreign dist-bzip2])

commit 1b71e0a8b9e915c806f6c3596b6ee5913d62fdc3
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Mon May 24 12:25:15 2010 +1000

    xfree86: fix multiple InputAttributes tag matching.
    
    attr->tags is an array of strings (null-terminated). When matching, match
    against each string instead of each [i,end] substring in the first tag.
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Jamey Sharp <jamey@minilop.net>
    Signed-off-by: Keith Packard <keithp@keithp.com>
    (cherry picked from commit b5e0f6d8f45c5b24eb50b305c66fa80c783ef488)

diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index a1a5527..bfa8dc0 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -551,9 +551,9 @@ InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
             return FALSE;
 
         for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
-            const char *tag;
-            for(tag = *attrs->tags; *tag; tag++) {
-                if (!strcmp(tag, *cur)) {
+            char * const *tag;
+            for(tag = attrs->tags; *tag; tag++) {
+                if (!strcmp(*tag, *cur)) {
                     match = TRUE;
                     break;
                 }

commit 354e4ce3774d6b7f0c571f426bd2db1c8ab272ea
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Sat May 22 10:29:00 2010 -0700

    Add RandR 1.2 README.modes doc to EXTRA_DIST
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Reviewed-by: Julien Cristau <jcristau@debian.org>
    (cherry picked from commit 1805c74d9b0ed46802481bcd6beea5feeb60212c)

diff --git a/hw/xfree86/doc/Makefile.am b/hw/xfree86/doc/Makefile.am
index 5809fa0..72bc5d9 100644
--- a/hw/xfree86/doc/Makefile.am
+++ b/hw/xfree86/doc/Makefile.am
@@ -6,4 +6,5 @@ endif
 
 EXTRA_DIST = \
 	README.DRI \
+	README.modes \
 	README.rapidaccess

commit 9a71d21cc27c7b0d35bae9d6dc4eed591dea99a4
Author: Aaron Zang <Aaron.Zang@Sun.COM>
Date:   Thu May 20 17:56:28 2010 -0700

    Solaris: Use VT_SET_CONSUSER ioctl to set Console User rights profile
    
    When Xorg is started on display :0, this ioctl is called to grant the
    user the rights traditionally associated with /dev/console (before VT
    support was added), such as access to local peripheral devices.
    
    Also adds a Solaris-specific -C flag to force starting on /dev/console
    instead of /dev/vt*, allowing programs like xterm -C to access the
    console device.
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Signed-off-by: Keith Packard <keithp@keithp.com>
    (cherry picked from commit 989db930d739483759087b13b8d9a043299feafb)

diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c
index 5846866..edcc60b 100644
--- a/hw/xfree86/os-support/solaris/sun_init.c
+++ b/hw/xfree86/os-support/solaris/sun_init.c
@@ -33,8 +33,21 @@
 # include <sys/kd.h>
 #endif
 
+/*
+ * Applications see VT number as consecutive integers starting from 1.
+ * VT number			VT device
+ * -------------------------------------------------------
+ *     1             :          /dev/vt/0 (Alt + Ctrl + F1)
+ *     2             :          /dev/vt/2 (Alt + Ctrl + F2)
+ *     3             :          /dev/vt/3 (Alt + Ctrl + F3)
+ *  ... ...
+ */
+#define	CONSOLE_VTNO	1
+#define	SOL_CONSOLE_DEV	"/dev/console"
+
 static Bool KeepTty = FALSE;
 static Bool Protect0 = FALSE;
+static Bool UseConsole = FALSE;
 #ifdef HAS_USL_VTS
 static int VTnum = -1;
 static int xf86StartVT = -1;
@@ -112,8 +125,30 @@ xf86OpenConsole(void)
 		vtEnabled = 0;
 	    }
 	}
+#endif /*  HAS_USL_VTS */
 
+	if (UseConsole)
+	{
+	    strlcpy(consoleDev, SOL_CONSOLE_DEV, sizeof(consoleDev));
+
+#ifdef HAS_USL_VTS
+	    xf86Info.vtno = CONSOLE_VTNO;
 
+	    if (vtEnabled == 0)
+	    {
+		xf86StartVT = 0;
+	    }
+	    else
+	    {
+		if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0)
+		    FatalError("xf86OpenConsole: Cannot determine current VT\n");
+		xf86StartVT = vtinfo.v_active;
+	    }
+#endif /*  HAS_USL_VTS */
+	    goto OPENCONSOLE;
+	}
+
+#ifdef HAS_USL_VTS
 	if (vtEnabled == 0)
 	{
 	    /* VT not enabled - kernel too old or Sparc platforms
@@ -123,32 +158,31 @@ xf86OpenConsole(void)
 	    xf86StartVT = 0;
 	    xf86Info.vtno = 0;
 	    strlcpy(consoleDev, xf86SolarisFbDev, sizeof(consoleDev));
+	    goto OPENCONSOLE;
 	}
-	else
-	{
-	    if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0)
-		FatalError("xf86OpenConsole: Cannot determine current VT\n");
 
-	    xf86StartVT = vtinfo.v_active;
+	if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0)
+	    FatalError("xf86OpenConsole: Cannot determine current VT\n");
 
-	    if (VTnum != -1)
-	    {
-		xf86Info.vtno = VTnum;
-		from = X_CMDLINE;
-	    }
-	    else
+	xf86StartVT = vtinfo.v_active;
+
+	if (VTnum != -1)
+	{
+	    xf86Info.vtno = VTnum;
+	    from = X_CMDLINE;
+	}
+	else
+	{
+	    if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
+		(xf86Info.vtno == -1))
 	    {
-		if ((ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) ||
-		    (xf86Info.vtno == -1))
-		{
-		    FatalError("xf86OpenConsole: Cannot find a free VT\n");
-		}
+		FatalError("xf86OpenConsole: Cannot find a free VT\n");
 	    }
-
-	    xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
-	    snprintf(consoleDev, PATH_MAX, "/dev/vt/%d", xf86Info.vtno);
 	}
 
+	xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno);
+	snprintf(consoleDev, PATH_MAX, "/dev/vt/%d", xf86Info.vtno);
+
 	if (fd != -1)
 	{
 	    close(fd);
@@ -156,6 +190,7 @@ xf86OpenConsole(void)
 
 #endif /* HAS_USL_VTS */
 
+OPENCONSOLE:
 	if (!KeepTty)
 	    setpgrp();
 
@@ -163,11 +198,10 @@ xf86OpenConsole(void)
 	    FatalError("xf86OpenConsole: Cannot open %s (%s)\n",
 		       consoleDev, strerror(errno));
 
-#ifdef HAS_USL_VTS
-
-	/* Change ownership of the vt */
+	/* Change ownership of the vt or console */
 	chown(consoleDev, getuid(), getgid());
 
+#ifdef HAS_USL_VTS
 	if (vtEnabled)
 	{
 	    /*
@@ -179,6 +213,13 @@ xf86OpenConsole(void)
 	    if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
 		xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
 
+#ifdef VT_SET_CONSUSER /* added in snv_139 */
+	    if (strcmp(display, "0") == 0)
+		if (ioctl(xf86Info.consoleFd, VT_SET_CONSUSER) != 0)
+		    xf86Msg(X_WARNING,
+			"xf86OpenConsole: VT_SET_CONSUSER failed\n");
+#endif
+
 	    if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) < 0)
 		FatalError("xf86OpenConsole: VT_GETMODE failed\n");
 
@@ -220,6 +261,13 @@ xf86OpenConsole(void)
 	    if (ioctl(xf86Info.consoleFd, VT_WAITACTIVE, xf86Info.vtno) != 0)
 		xf86Msg(X_WARNING, "xf86OpenConsole: VT_WAITACTIVE failed\n");
 
+#ifdef VT_SET_CONSUSER /* added in snv_139 */
+	    if (strcmp(display, "0") == 0)
+		if (ioctl(xf86Info.consoleFd, VT_SET_CONSUSER) != 0)
+		    xf86Msg(X_WARNING,
+			"xf86OpenConsole: VT_SET_CONSUSER failed\n");
+#endif
+
 	    /*
 	     * If the server doesn't have the VT when the reset occurs,
 	     * this is to make sure we don't continue until the activate
@@ -330,6 +378,15 @@ xf86ProcessArgument(int argc, char **argv, int i)
 	return 1;
     }
 
+    /*
+     * Use /dev/console as the console device.
+     */
+    if (!strcmp(argv[i], "-C"))
+    {
+	UseConsole = TRUE;
+	return 1;
+    }
+
 #ifdef HAS_USL_VTS
 
     if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
@@ -364,4 +421,5 @@ void xf86UseMsg()
     ErrorF("-dev <fb>              Framebuffer device\n");
     ErrorF("-keeptty               Don't detach controlling tty\n");
     ErrorF("                       (for debugging only)\n");
+    ErrorF("-C                     Use /dev/console as the console device\n");
 }

commit a8d40f61bf42a55fbd4fcd6468c94cb595e490cc
Author: Alan Coopersmith <alan.coopersmith@oracle.com>
Date:   Thu May 20 17:56:26 2010 -0700

    Xserver(1) man page updates
    
    - Note that -br is now default.
    - Move -bs after -br for alphabetical ordering.
    - Remove -config option that's been hidden in "ignore" section,
      since ajax removed the -config code a couple years back.
    - Add -nocursor option.
    - Add xinput & xrandr to list of runtime server control programs
    - Replace XDarwin with Xquartz in list of Xservers
    
    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
    Reviewed-by: Adam Jackson <ajax@redhat.com>
    Signed-off-by: Keith Packard <keithp@keithp.com>
    (cherry picked from commit 7b09335a46f9428141811230c69eef7968531359)

diff --git a/doc/Xserver.man.pre b/doc/Xserver.man.pre
index 8144c8a..ce3b3a1 100644
--- a/doc/Xserver.man.pre
+++ b/doc/Xserver.man.pre
@@ -100,12 +100,12 @@ specifies a file which contains a collection of authorization records used
 to authenticate access.  See also the \fIxdm\fP(1) and 
 \fIXsecurity\fP(__miscmansuffix__) manual pages.
 .TP 8
-.B \-bs
-disables backing store support on all screens.
-.TP 8
 .B \-br
 sets the default root window to solid black instead of the standard root weave
-pattern.
+pattern.   This is the default unless -retro or -wr is specified.
+.TP 8
+.B \-bs
+disables backing store support on all screens.
 .TP 8
 .B \-c
 turns off key-click.
@@ -117,17 +117,6 @@ sets key-click volume (allowable range: 0-100).
 sets the visual class for the root window of color screens.
 The class numbers are as specified in the X protocol.
 Not obeyed by all servers.
-.ig
-.TP 8
-.B \-config \fIfilename\fP
-reads more options from the given file.  Options in the file may be separated
-by newlines if desired.  If a '#' character appears on a line, all characters
-between it and the next newline are ignored, providing a simple commenting
-facility.  The \fB\-config\fP option itself may appear in the file.
-.BR NOTE :
-This option is disabled when the Xserver is run with an effective uid
-different from the user's real uid.
-..
 .TP 8
 .B \-core
 causes the server to generate a core dump on fatal errors.
@@ -184,6 +173,9 @@ sets the maximum big request to
 .I size
 MB.
 .TP 8
+.B \-nocursor
+disable the display of the pointer cursor.
+.TP 8
 .B \-nolisten \fItrans-type\fP
 disables a transport type.  For example, TCP/IP connections can be disabled
 with
@@ -584,11 +576,11 @@ Security: \fIXsecurity\fP(__miscmansuffix__), \fIxauth\fP(1), \fIXau\fP(1),
 Starting the server: \fIstartx\fP(1), \fIxdm\fP(1), \fIxinit\fP(1)
 .PP
 Controlling the server once started: \fIxset\fP(1), \fIxsetroot\fP(1),
-\fIxhost\fP(1)
+\fIxhost\fP(1), \fIxinput\fP(1), \fIxrandr\fP(1)
 .PP
 Server-specific man pages:
 \fIXorg\fP(1), \fIXdmx\fP(1), \fIXephyr\fP(1), \fIXnest\fP(1),
-\fIXvfb\fP(1), \fIXDarwin\fP(1), \fIXWin\fP(1).
+\fIXvfb\fP(1), \fIXquartz\fP(1), \fIXWin\fP(1).
 .PP
 Server internal documentation:
 .I "Definition of the Porting Layer for the X v11 Sample Server"

commit 2ab11e09734dec4f119166fa6512eb25b4572e48
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Fri May 21 13:30:25 2010 +1000

    dix: remove obsolete comment.from EnableDevice.
    
    The code this comment was referring to was removed in
    8b5086250aa5dae8de8b763408ff480d7beac819 "Eliminate bogus event resizing."
    
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Daniel Stone <daniel@fooishbar.org>
    Signed-off-by: Keith Packard <keithp@keithp.com>
    (cherry picked from commit cf4f3d051858aadedd6e333bb317a1daa3987ad7)

diff --git a/dix/devices.c b/dix/devices.c
index 042f12f..b55df16 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -318,10 +318,6 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent)
         }
     }
 
-    /* Before actually enabling the device, we need to make sure the event
-     * list's events have enough memory for a ClassesChangedEvent from the
-     * device
-     */
     if ((*prev != dev) || !dev->inited ||
 	((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
         ErrorF("[dix] couldn't enable device %d\n", dev->id);

commit 869d37721425d219c50962b694c3326407d1d2e6
Author: Jamey Sharp <jamey@minilop.net>
Date:   Wed May 19 10:44:33 2010 -0700

    Device init: Don't crash when CreateGC fails.
    
    ActivateDevice was ignoring errors from DeviceCursorInitialize, so
    cursor-related calls failed later. Jeremy Huddleston saw that crash in
    miPointerConstrainCursor, while with Xvfb I saw it in
    miSpriteRealizeCursor.
    
    miDCDeviceCleanup frees any non-NULL GCs. miDCDeviceInitialize calls
    Cleanup on any failure, but if it failed early then some of the pointers
    in the miDCBufferPtr were garbage. Switch from malloc to calloc to
    ensure everything's initialized safely first.
    
    With these two fixes, if CreateGC fails then the server gracefully fails
    in FatalError instead of segfaulting.
    
    Signed-off-by: Jamey Sharp <jamey@minilop.net>
    Cc: Peter Hutterer <peter.hutterer@who-t.net>
    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
    Signed-off-by: Keith Packard <keithp@keithp.com>
    
    (cherry-picked from commit b9f48d60bc0c839bd323c582231e8e7e2b810af6)

diff --git a/dix/devices.c b/dix/devices.c
index 32e067b..042f12f 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -474,7 +474,8 @@ ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
 
     /* Initialize memory for sprites. */
     if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
-        pScreen->DeviceCursorInitialize(dev, pScreen);
+        if (!pScreen->DeviceCursorInitialize(dev, pScreen))
+            ret = BadAlloc;
 
     SendDevicePresenceEvent(dev->id, DeviceAdded);
     if (sendevent)
diff --git a/mi/midispcur.c b/mi/midispcur.c
index 9041630..54a6787 100644
--- a/mi/midispcur.c
+++ b/mi/midispcur.c
@@ -780,7 +780,7 @@ miDCDeviceInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
     {
         pScreen = screenInfo.screens[i];
 
-        pBuffer = xalloc(sizeof(miDCBufferRec));
+        pBuffer = xcalloc(1, sizeof(miDCBufferRec));
         if (!pBuffer)
             goto failure;
 

commit a8de0866130df62c2b1e4653e028a0fe365e0e3a
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Tue Mar 23 09:47:08 2010 -0700

    GLX/DRI2: expose swap control extensions if DDX support is present
    
    Export DDX swap control status from the DRI2 module and check for it in
    GLX when initializing extensions.
    
    Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    (cherry picked from commit 165a4a9c7de0fcc6ef6a6421736b412ccb35965e)

diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index edd29b0..e791bf6 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -616,6 +616,7 @@ glxDRILeaveVT (int index, int flags)
 static void
 initializeExtensions(__GLXDRIscreen *screen)
 {
+    ScreenPtr pScreen = screen->base.pScreen;
     const __DRIextension **extensions;
     int i;
 
@@ -625,10 +626,17 @@ initializeExtensions(__GLXDRIscreen *screen)
 			 "GLX_MESA_copy_sub_buffer");
     LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
 
-    /* FIXME: only if DDX supports it */
     __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
     LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
 
+    if (DRI2HasSwapControl(pScreen)) {
+	__glXEnableExtension(screen->glx_enable_bits,
+			     "GLX_SGI_swap_control");
+	__glXEnableExtension(screen->glx_enable_bits,
+			     "GLX_MESA_swap_control");
+	LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+    }
+
     for (i = 0; extensions[i]; i++) {
 #ifdef __DRI_READ_DRAWABLE
 	if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
@@ -639,19 +647,6 @@ initializeExtensions(__GLXDRIscreen *screen)
 	}
 #endif
 
-#ifdef __DRI_SWAP_CONTROL
-	if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
-	    screen->swapControl =
-		(const __DRIswapControlExtension *) extensions[i];
-	    __glXEnableExtension(screen->glx_enable_bits,
-				 "GLX_SGI_swap_control");
-	    __glXEnableExtension(screen->glx_enable_bits,
-				 "GLX_MESA_swap_control");
-	    
-	    LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
-	}
-#endif
-
 #ifdef __DRI_TEX_BUFFER
 	if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
 	    screen->texBuffer =
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 8b4c36f..2bdb733 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -831,6 +831,14 @@ DRI2DestroyDrawable(DrawablePtr pDraw)
 }
 
 Bool
+DRI2HasSwapControl(ScreenPtr pScreen)
+{
+    DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+
+    return (ds->ScheduleSwap && ds->GetMSC);
+}
+
+Bool
 DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
 	    const char **driverName, const char **deviceName)
 {
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index e1881ba..ce8a5df 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -188,6 +188,8 @@ extern _X_EXPORT Bool DRI2ScreenInit(ScreenPtr	pScreen,
 
 extern _X_EXPORT void DRI2CloseScreen(ScreenPtr pScreen);
 
+extern _X_EXPORT Bool DRI2HasSwapControl(ScreenPtr pScreen);
+
 extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
 		 unsigned int driverType,
 		 int *fd,

commit b24856626e1836657ebf35ad4c61984e0a407c5b
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Mon Mar 8 15:10:47 2010 -0800

    DRI2: prevent swap wakes from waking MSC waiters
    
    If a few swaps were queued leading to a throttle related block on the
    client, and then the client submitted an MSC wait, one of the previous
    swap wakeups could have caused the MSC wait to complete early.  Add a
    flag for this to prevent a swap wake from prematurely waking an MSC
    waiter.
    
    Reported-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    (cherry picked from commit 5933b0abc6a76aaea84aa534df89900cd795c888)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 8a67122..8b4c36f 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -63,6 +63,7 @@ typedef struct _DRI2Drawable {
     int			 bufferCount;
     unsigned int	 swapsPending;
     ClientPtr		 blockedClient;
+    Bool		 blockedOnMsc;
     int			 swap_interval;
     CARD64		 swap_count;
     int64_t		 target_sbc; /* -1 means no SBC wait outstanding */
@@ -145,6 +146,7 @@ DRI2CreateDrawable(DrawablePtr pDraw)
     pPriv->bufferCount = 0;
     pPriv->swapsPending = 0;
     pPriv->blockedClient = NULL;
+    pPriv->blockedOnMsc = FALSE;
     pPriv->swap_count = 0;
     pPriv->target_sbc = -1;
     pPriv->swap_interval = 1;
@@ -402,6 +404,15 @@ DRI2ThrottleClient(ClientPtr client, DrawablePtr pDraw)
     return FALSE;
 }
 
+static void
+__DRI2BlockClient(ClientPtr client, DRI2DrawablePtr pPriv)
+{
+    if (pPriv->blockedClient == NULL) {
+	IgnoreClient(client);
+	pPriv->blockedClient = client;
+    }
+}
+
 void
 DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
 {
@@ -411,10 +422,8 @@ DRI2BlockClient(ClientPtr client, DrawablePtr pDraw)
     if (pPriv == NULL)
 	return;
 
-    if (pPriv->blockedClient == NULL) {
-	IgnoreClient(client);
-	pPriv->blockedClient = client;
-    }
+    __DRI2BlockClient(client, pPriv);
+    pPriv->blockedOnMsc = TRUE;
 }
 
 int
@@ -495,6 +504,7 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 	AttendClient(pPriv->blockedClient);
 
     pPriv->blockedClient = NULL;
+    pPriv->blockedOnMsc = FALSE;
 
     /* If there's still a swap pending, let DRI2SwapComplete free it */
     if (pPriv->refCount == 0 && pPriv->swapsPending == 0)
@@ -516,8 +526,12 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
     }
 
     /*
-     * Swap completed.  Either wake up an SBC waiter or a client that was
-     * blocked due to GLX activity during a swap.
+     * Swap completed.
+     * Wake the client iff:
+     *   - it was waiting on SBC
+     *   - was blocked due to GLX make current
+     *   - was blocked due to swap throttling
+     *   - is not blocked due to an MSC wait
      */
     if (pPriv->target_sbc != -1 &&
 	pPriv->target_sbc <= pPriv->swap_count) {
@@ -527,10 +541,11 @@ DRI2WakeClient(ClientPtr client, DrawablePtr pDraw, int frame,
 
 	AttendClient(pPriv->blockedClient);
 	pPriv->blockedClient = NULL;
-    } else if (pPriv->target_sbc == -1) {
-	if (pPriv->blockedClient)
+    } else if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
+	if (pPriv->blockedClient) {
 	    AttendClient(pPriv->blockedClient);
-	pPriv->blockedClient = NULL;
+	    pPriv->blockedClient = NULL;
+	}
     }
 }
 
@@ -582,7 +597,7 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
 	pPriv->blockedClient == NULL) {
 	ResetCurrentRequest(client);
 	client->sequence--;
-	DRI2BlockClient(client, pDrawable);
+	__DRI2BlockClient(client, pPriv);
 	return TRUE;
     }
 
@@ -780,7 +795,7 @@ DRI2WaitSBC(ClientPtr client, DrawablePtr pDraw, CARD64 target_sbc,
     }
 
     pPriv->target_sbc = target_sbc;
-    DRI2BlockClient(client, pDraw);
+    __DRI2BlockClient(client, pPriv);
 
     return Success;
 }
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 066cc39..e1881ba 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -257,6 +257,7 @@ extern _X_EXPORT Bool DRI2CanFlip(DrawablePtr pDraw);
 
 extern _X_EXPORT Bool DRI2CanExchange(DrawablePtr pDraw);
 
+/* Note: use *only* for MSC related waits */
 extern _X_EXPORT void DRI2BlockClient(ClientPtr client, DrawablePtr pDraw);
 
 extern _X_EXPORT void DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw,

commit 5c54e7fa004532d595160a815177dda467b3cc9c
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Mon Mar 8 12:41:25 2010 -0800

    DRI2: handle swapsPending better
    
    Avoid a potential swapsPending underflow by incrementing it before
    ScheduleSwap, which may complete it immediately.  And be sure to
    decrement it again in case the schedule failed.
    
    Reported-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    (cherry picked from commit b00d435ddf2e9817e33bfd5f7e9b905442dc23c7)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 3fc7f4e..8a67122 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -654,15 +654,16 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
 	*swap_target = target_msc;
     }
 
+    pPriv->swapsPending++;
     ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
 			      swap_target, divisor, remainder, func, data);
     if (!ret) {
+	pPriv->swapsPending--; /* didn't schedule */
         xf86DrvMsg(pScreen->myNum, X_ERROR,
 		   "[DRI2] %s: driver failed to schedule swap\n", __func__);
 	return BadDrawable;
     }
 
-    pPriv->swapsPending++;
     pPriv->last_swap_target = *swap_target;
 
     /* According to spec, return expected swapbuffers count SBC after this swap

commit fcd76ddfc59de6a1d37ca2aa6e6e91cb8d814744
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Mon Mar 8 12:39:54 2010 -0800

    DRI2: throttle swaps at submission time too
    
    We need to throttle swaps here in addition to when the context is made
    current to avoid causing problems with clients that just swap.
    Throttling here also ensures our swaps get ordered as long as we block
    the client occasionally.
    
    Reported-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    (cherry picked from commit 0294ff2a5cadddc8fcc77ba9a851f979f0b91fc3)

diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index 7a9f8ca..094d54d 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -384,6 +384,13 @@ ProcDRI2SwapBuffers(ClientPtr client)
 		       DixReadAccess | DixWriteAccess, &pDrawable, &status))
 	return status;
 
+    /*
+     * Ensures an out of control client can't exhaust our swap queue, and
+     * also orders swaps.
+     */
+    if (DRI2ThrottleClient(client, pDrawable))
+	return client->noClientException;
+
     target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
     divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
     remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);

commit c7e9e36fd3cdb889704d3b0e1333653d06ef9069
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Mon Mar 8 12:38:37 2010 -0800

    DRI2: advertise lowest supported DRI2 protocol version
    
    Update our supported DRI2 protocol version as each driver does
    DRI2ScreenInit, since depending on available kernel features, each DDX
    may support different callbacks and therefore protocol.
    
    Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    (cherry picked from commit db1c7cb604167baf49e61be4c09ccf7b592c4af3)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 9825a55..3fc7f4e 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -45,6 +45,9 @@
 
 #include "xf86.h"
 
+CARD8 dri2_major; /* version of DRI2 supported by DDX */
+CARD8 dri2_minor;
+
 static int dri2ScreenPrivateKeyIndex;
 static DevPrivateKey dri2ScreenPrivateKey = &dri2ScreenPrivateKeyIndex;
 static int dri2WindowPrivateKeyIndex;
@@ -848,6 +851,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
 	"VDPAU", /* DRI2DriverVDPAU */
     };
     unsigned int i;
+    CARD8 cur_minor;
 
     if (info->version < 3)
 	return FALSE;
@@ -864,6 +868,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
 
     ds->fd	       = info->fd;
     ds->deviceName     = info->deviceName;
+    dri2_major         = 1;
 
     ds->CreateBuffer   = info->CreateBuffer;
     ds->DestroyBuffer  = info->DestroyBuffer;
@@ -873,8 +878,15 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
 	ds->ScheduleSwap = info->ScheduleSwap;
 	ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
 	ds->GetMSC = info->GetMSC;
+	cur_minor = 2;
+    } else {
+	cur_minor = 1;
     }
 
+    /* Initialize minor if needed and set to minimum provied by DDX */
+    if (!dri2_minor || dri2_minor > cur_minor)
+	dri2_minor = cur_minor;
+
     if (info->version == 3 || info->numDrivers == 0) {
 	/* Driver too old: use the old-style driverName field */
 	ds->numDrivers = 1;
diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h
index 1c8626b..066cc39 100644
--- a/hw/xfree86/dri2/dri2.h
+++ b/hw/xfree86/dri2/dri2.h
@@ -46,6 +46,9 @@ typedef struct {
     void *driverPrivate;
 } DRI2BufferRec, *DRI2BufferPtr;
 
+extern CARD8 dri2_major; /* version of DRI2 supported by DDX */
+extern CARD8 dri2_minor;
+
 typedef DRI2BufferRec DRI2Buffer2Rec, *DRI2Buffer2Ptr;
 typedef void (*DRI2SwapEventPtr)(ClientPtr client, void *data, int type,
 				 CARD64 ust, CARD64 msc, CARD64 sbc);
diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c
index bd92fd3..7a9f8ca 100644
--- a/hw/xfree86/dri2/dri2ext.c
+++ b/hw/xfree86/dri2/dri2ext.c
@@ -80,8 +80,8 @@ ProcDRI2QueryVersion(ClientPtr client)
     rep.type = X_Reply;
     rep.length = 0;
     rep.sequenceNumber = client->sequence;
-    rep.majorVersion = SERVER_DRI2_MAJOR_VERSION;
-    rep.minorVersion = SERVER_DRI2_MINOR_VERSION;
+    rep.majorVersion = dri2_major;
+    rep.minorVersion = dri2_minor;
 
     if (client->swapped) {
     	swaps(&rep.sequenceNumber, n);
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index c74b7fa..97ef5da 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -51,10 +51,6 @@
 #define SERVER_DMX_MINOR_VERSION		2
 #define SERVER_DMX_PATCH_VERSION		20040604
 
-/* DRI2 */
-#define SERVER_DRI2_MAJOR_VERSION		1
-#define SERVER_DRI2_MINOR_VERSION		2
-
 /* Generic event extension */
 #define SERVER_GE_MAJOR_VERSION                 1
 #define SERVER_GE_MINOR_VERSION                 0

commit 20708781d43501f116b4161c1cc96b0eb39e96b1
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Fri Mar 5 09:49:03 2010 -0800

    DRI2: handle swap_interval of 0 correctly
    
    A 0 swap interval means that swaps shouldn't be sync'd to vblank, so
    just complete the swap immediately in that case.
    
    Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    (cherry picked from commit 87ca6320f26eb3129e3c19056e1d8fa5c1784723)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 58f478f..9825a55 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -616,8 +616,8 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
 	return BadDrawable;
     }
 
-    /* Old DDX, just blit */
-    if (!ds->ScheduleSwap) {
+    /* Old DDX or no swap interval, just blit */
+    if (!ds->ScheduleSwap || !pPriv->swap_interval) {
 	BoxRec box;
 	RegionRec region;
 

commit 73fe4a0952b5c8aea90bce6f758546c13d0754b5
Author: Jesse Barnes <jbarnes@virtuousgeek.org>
Date:   Fri Mar 5 09:15:24 2010 -0800

    DRI2: drawable lifetime fixes
    
    Handle drawable destruction and lifetime correctly.
    
    Check whether the drawable priv is valid in DRI2SwapInterval(),
    DRI2WaitSBC() and DRI2WaitMSC(); it may have gone away, so be sure to
    check it before using it.
    
    If more than 1 outstanding swap is queued, we may complete several after
    an app has exited.  If we free it after the first one completes and the
    refcount reaches 0, we'll crash the server on subsequent completions.
    So delay freeing until all swaps complete and remove the error message
    as this is a normal occurence.  To do this properly, we must also avoid
    destroying drawables in DRI2DestroyDrawable() if a swap or wait event is
    pending.
    
    And finally, make sure we free drawables in DRI2WaitMSCComplete() if
    necessary (i.e. if the refcount has reached 0 and this MSC was the last
    pending event on the object).
    
    Reported-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Reviewed-by: Mario Kleiner <mario.kleiner@tuebingen.mpg.de>
    Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
    (cherry picked from commit 8476d99231cb725c090305d60f1c1c889d25c8dc)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 354b724..58f478f 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -492,6 +492,10 @@ DRI2WaitMSCComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 	AttendClient(pPriv->blockedClient);
 
     pPriv->blockedClient = NULL;
+
+    /* If there's still a swap pending, let DRI2SwapComplete free it */
+    if (pPriv->refCount == 0 && pPriv->swapsPending == 0)
+	DRI2FreeDrawable(pDraw);
 }
 
 static void
@@ -543,13 +547,6 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
 	return;
     }
 
-    if (pPriv->refCount == 0) {
-        xf86DrvMsg(pScreen->myNum, X_ERROR,
-		   "[DRI2] %s: bad drawable refcount\n", __func__);
-	DRI2FreeDrawable(pDraw);
-	return;
-    }
-
     pPriv->swapsPending--;
     pPriv->swap_count++;
 
@@ -561,6 +558,13 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
     pPriv->last_swap_ust = ust;
 
     DRI2WakeClient(client, pDraw, frame, tv_sec, tv_usec);
+
+    /*
+     * It's normal for the app to have exited with a swap outstanding, but
+     * don't free the drawable until they're all complete.
+     */
+    if (pPriv->swapsPending == 0 && pPriv->refCount == 0)
+	DRI2FreeDrawable(pDraw);
 }
 
 Bool
@@ -669,10 +673,16 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
 void
 DRI2SwapInterval(DrawablePtr pDrawable, int interval)
 {
+    ScreenPtr       pScreen = pDrawable->pScreen;
     DRI2DrawablePtr pPriv = DRI2GetDrawable(pDrawable);
 
-    /* fixme: check against arbitrary max? */
+    if (pPriv == NULL) {
+        xf86DrvMsg(pScreen->myNum, X_ERROR,
+		   "[DRI2] %s: bad drawable\n", __func__);
+	return;
+    }


Reply to: