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

Jeremy Huddleston jeremyhu at freedesktop.org
Thu Apr 21 23:57:53 PDT 2011


 configure.ac                          |   10 ++-
 damageext/damageext.c                 |    2 
 dix/cursor.c                          |    5 -
 dix/dispatch.c                        |   12 +++-
 hw/xfree86/common/xf86xv.c            |    9 ++-
 hw/xfree86/dri2/dri2.c                |   22 ++++---
 hw/xfree86/loader/loadmod.c           |   32 ++++------
 hw/xquartz/X11Application.m           |    2 
 hw/xquartz/darwinEvents.c             |   28 ++++++++-
 hw/xquartz/mach-startup/bundle-main.c |   47 +++++++++------
 include/dix-config.h.in               |    3 +
 miext/damage/damage.c                 |  101 +++++++++++++++++-----------------
 miext/damage/damage.h                 |    4 +
 os/connection.c                       |    7 +-
 randr/rrdispatch.c                    |   32 ++++++++++
 render/render.c                       |   12 +++-
 16 files changed, 205 insertions(+), 123 deletions(-)

New commits:
commit 034538ea9b4770025e3573bc708039cabbe1e10d
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu Apr 21 16:31:58 2011 -0700

    XQuartz: Use dispatch_async to handoff the FD
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index d55d1ed..6a6c01c 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -40,10 +40,15 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <pthread.h>
 #include <stdbool.h>
 #include <signal.h>
 
+#ifdef HAVE_LIBDISPATCH
+#include <dispatch/dispatch.h>
+#else
+#include <pthread.h>
+#endif
+
 #include <sys/socket.h>
 #include <sys/un.h>
 
@@ -94,6 +99,7 @@ int server_main(int argc, char **argv, char **envp);
 static int execute(const char *command);
 static char *command_from_prefs(const char *key, const char *default_value);
 
+#ifndef HAVE_LIBDISPATCH
 /*** Pthread Magics ***/
 static pthread_t create_thread(void *(*func)(void *), void *arg) {
     pthread_attr_t attr;
@@ -107,6 +113,7 @@ static pthread_t create_thread(void *(*func)(void *), void *arg) {
 	
     return tid;
 }
+#endif
 
 /*** Mach-O IPC Stuffs ***/
 
@@ -199,8 +206,13 @@ typedef struct {
 /* This thread accepts an incoming connection and hands off the file
  * descriptor for the new connection to accept_fd_handoff()
  */
+#ifdef HAVE_LIBDISPATCH
+static void socket_handoff(socket_handoff_t *handoff_data) {
+#else
 static void *socket_handoff_thread(void *arg) {
     socket_handoff_t *handoff_data = (socket_handoff_t *)arg;
+#endif
+
     int launchd_fd = -1;
     int connected_fd;
 
@@ -229,7 +241,9 @@ static void *socket_handoff_thread(void *arg) {
     fprintf(stderr, "X11.app Handing off fd to server thread via DarwinListenOnOpenFD(%d)\n", launchd_fd);
     DarwinListenOnOpenFD(launchd_fd);
 
+#ifndef HAVE_LIBDISPATCH
     return NULL;
+#endif
 }
 
 static int create_socket(char *filename_out) {
@@ -298,8 +312,14 @@ kern_return_t do_request_fd_handoff_socket(mach_port_t port, string_t filename)
     }
 
     strlcpy(filename, handoff_data->filename, STRING_T_SIZE);
-    
+
+#ifdef HAVE_LIBDISPATCH
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
+        socket_handoff(handoff_data);
+    });
+#else
     create_thread(socket_handoff_thread, handoff_data);
+#endif
     
 #ifdef DEBUG
     fprintf(stderr, "X11.app: Thread created for handoff.  Returning success to tell caller to connect and push the fd.\n");
commit ca7b9e6c817681b9cec738e43cf020ac19b5e732
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu Apr 21 15:51:32 2011 -0700

    configure.ac: Add check for libdispatch when building for darwin
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/configure.ac b/configure.ac
index 9e04ff0..887dae5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -726,9 +726,9 @@ case $host_os in
 		 		save_LDFLAGS=$LDFLAGS
 				LDFLAGS="$LDFLAGS -framework Carbon"
 				AC_LINK_IFELSE([char FSFindFolder(); int main() { FSFindFolder(); return 0;}],
-				[xorg_cv_Carbon_framework=yes],
-				[xorg_cv_Carbon_framework=no])
-			LDFLAGS=$save_LDFLAGS])
+				               [xorg_cv_Carbon_framework=yes],
+				               [xorg_cv_Carbon_framework=no])
+			        LDFLAGS=$save_LDFLAGS])
                 
 			if test "X$xorg_cv_Carbon_framework" = Xyes; then
 				XQUARTZ=yes
@@ -737,6 +737,10 @@ case $host_os in
 			fi
 		fi
 
+		AC_CHECK_FUNC(dispatch_async,
+		              AC_DEFINE([HAVE_LIBDISPATCH], 1, [Define to 1 if you have the libdispatch (GCD) available]),
+		              [])
+
 		if test "x$XQUARTZ" = xyes ; then
 			XQUARTZ=yes
 			XVFB=no
diff --git a/include/dix-config.h.in b/include/dix-config.h.in
index fd9ecce..14229b4 100644
--- a/include/dix-config.h.in
+++ b/include/dix-config.h.in
@@ -136,6 +136,9 @@
 /* Define to 1 if you have the `m' library (-lm). */
 #undef HAVE_LIBM
 
+/* Define to 1 if you have the libdispatch (GCD) available */
+#undef HAVE_LIBDISPATCH
+
 /* Define to 1 if you have the `link' function. */
 #undef HAVE_LINK
 
commit 3960115dbc83ec1eb8d9c8e90466af3fa0b32abd
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu Apr 21 15:19:12 2011 -0700

    XQuartz: Fix prototypes for thread functions
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m
index 3521517..988a86b 100644
--- a/hw/xquartz/X11Application.m
+++ b/hw/xquartz/X11Application.m
@@ -950,7 +950,7 @@ environment the next time you start X11?", @"Startup xinitrc dialog");
     [X11App prefs_synchronize];
 }
 
-static inline pthread_t create_thread(void *func, void *arg) {
+static inline pthread_t create_thread(void *(*func)(void *), void *arg) {
     pthread_attr_t attr;
     pthread_t tid;
     
diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 0853b71..edf60c8 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -94,7 +94,7 @@ static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER;
 static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER;
 
 /*** Pthread Magics ***/
-static pthread_t create_thread(void *func, void *arg) {
+static pthread_t create_thread(void *(*func)(void *), void *arg) {
     pthread_attr_t attr;
     pthread_t tid;
 
@@ -305,7 +305,7 @@ void DarwinListenOnOpenFD(int fd) {
     pthread_mutex_unlock(&fd_add_lock);
 }
 
-static void DarwinProcessFDAdditionQueue_thread(void *args) {
+static void *DarwinProcessFDAdditionQueue_thread(void *args) {
     /* TODO: Possibly adjust this to no longer be a race... maybe trigger this
      *       once a client connects and claims to be the WM.
      *
@@ -334,6 +334,8 @@ static void DarwinProcessFDAdditionQueue_thread(void *args) {
         }
         pthread_cond_wait(&fd_add_ready_cond, &fd_add_lock);
     }
+
+    return NULL;
 }
 
 Bool DarwinEQInit(void) { 
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index 4c79cfb..d55d1ed 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -95,7 +95,7 @@ static int execute(const char *command);
 static char *command_from_prefs(const char *key, const char *default_value);
 
 /*** Pthread Magics ***/
-static pthread_t create_thread(void *func, void *arg) {
+static pthread_t create_thread(void *(*func)(void *), void *arg) {
     pthread_attr_t attr;
     pthread_t tid;
 	
@@ -199,7 +199,7 @@ typedef struct {
 /* This thread accepts an incoming connection and hands off the file
  * descriptor for the new connection to accept_fd_handoff()
  */
-static void socket_handoff_thread(void *arg) {
+static void *socket_handoff_thread(void *arg) {
     socket_handoff_t *handoff_data = (socket_handoff_t *)arg;
     int launchd_fd = -1;
     int connected_fd;
@@ -228,6 +228,8 @@ static void socket_handoff_thread(void *arg) {
         
     fprintf(stderr, "X11.app Handing off fd to server thread via DarwinListenOnOpenFD(%d)\n", launchd_fd);
     DarwinListenOnOpenFD(launchd_fd);
+
+    return NULL;
 }
 
 static int create_socket(char *filename_out) {
commit 7524dbd06113ec081eaa882aa54e03553ccf96aa
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Thu Apr 21 15:11:52 2011 -0700

    XQuartz: Make the DarwinProcessFDAdditionQueue_thread wait 3 seconds to allow xinitrc to catch up
    
    Previously, we weren't always waiting the full three seconds.  This should
    be better, but is still sub-optimal.  We really want to start processing
    these once a WM has been started.
    
    http://xquartz.macosforge.org/trac/ticket/416
    
    Signed-off-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c
index 16fec4a..0853b71 100644
--- a/hw/xquartz/darwinEvents.c
+++ b/hw/xquartz/darwinEvents.c
@@ -61,6 +61,7 @@ in this Software without prior written authorization from The Open Group.
 #include <unistd.h>
 #include <pthread.h>
 #include <errno.h>
+#include <time.h>
 
 #include <IOKit/hidsystem/IOLLEvent.h>
 
@@ -305,6 +306,27 @@ void DarwinListenOnOpenFD(int fd) {
 }
 
 static void DarwinProcessFDAdditionQueue_thread(void *args) {
+    /* TODO: Possibly adjust this to no longer be a race... maybe trigger this
+     *       once a client connects and claims to be the WM.
+     *
+     * From ajax:
+     * There's already an internal callback chain for setting selection [in 1.5]
+     * ownership.  See the CallSelectionCallback at the bottom of
+     * ProcSetSelectionOwner, and xfixes/select.c for an example of how to hook
+     * into it.
+     */
+
+    struct timespec sleep_for;
+    struct timespec sleep_remaining;
+
+    sleep_for.tv_sec = 3;
+    sleep_for.tv_nsec = 0;
+
+    ErrorF("X11.app: DarwinProcessFDAdditionQueue_thread: Sleeping to allow xinitrc to catchup.\n");
+    while(nanosleep(&sleep_for, &sleep_remaining) != 0) {
+        sleep_for = sleep_remaining;
+    }
+
     pthread_mutex_lock(&fd_add_lock);
     while(true) {
         while(fd_add_count) {
diff --git a/hw/xquartz/mach-startup/bundle-main.c b/hw/xquartz/mach-startup/bundle-main.c
index 75b3939..4c79cfb 100644
--- a/hw/xquartz/mach-startup/bundle-main.c
+++ b/hw/xquartz/mach-startup/bundle-main.c
@@ -47,7 +47,6 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
-#include <sys/time.h>
 #include <fcntl.h>
 
 #include <mach/mach.h>
@@ -204,7 +203,6 @@ static void socket_handoff_thread(void *arg) {
     socket_handoff_t *handoff_data = (socket_handoff_t *)arg;
     int launchd_fd = -1;
     int connected_fd;
-    unsigned remain;
 
     /* Now actually get the passed file descriptor from this connection
      * If we encounter an error, keep listening.
@@ -227,20 +225,7 @@ static void socket_handoff_thread(void *arg) {
     close(handoff_data->fd);
     unlink(handoff_data->filename);
     free(handoff_data);
-    
-    /* TODO: Clean up this race better... giving xinitrc time to run... need to wait for 1.5 branch:
-     *
-     * From ajax:
-     * There's already an internal callback chain for setting selection [in 1.5]
-     * ownership.  See the CallSelectionCallback at the bottom of
-     * ProcSetSelectionOwner, and xfixes/select.c for an example of how to hook
-     * into it.
-     */
-    
-    remain = 3000000;
-    fprintf(stderr, "X11.app: Received new $DISPLAY fd: %d ... sleeping to allow xinitrc to catchup.\n", launchd_fd);
-    while((remain = usleep(remain)) > 0);
-    
+        
     fprintf(stderr, "X11.app Handing off fd to server thread via DarwinListenOnOpenFD(%d)\n", launchd_fd);
     DarwinListenOnOpenFD(launchd_fd);
 }
commit b3d2164a0361f636bfe77b51456bee9213af4f13
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Tue Apr 12 17:16:50 2011 +0300

    dri2: Pass out_count by value to update_dri2_drawable_buffers()
    
    update_dri2_drawable_buffers() doesn't modify out_count, so pass it
    by value.
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 23b6594..5c42a51 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -358,7 +358,7 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
 
 static void
 update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
-			     DRI2BufferPtr *buffers, int *out_count, int *width, int *height)
+			     DRI2BufferPtr *buffers, int out_count, int *width, int *height)
 {
     DRI2ScreenPtr   ds = DRI2GetScreen(pDraw->pScreen);
     int i;
@@ -374,7 +374,7 @@ update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
     }
 
     pPriv->buffers = buffers;
-    pPriv->bufferCount = *out_count;
+    pPriv->bufferCount = out_count;
     pPriv->width = pDraw->width;
     pPriv->height = pDraw->height;
     *width = pPriv->width;
@@ -477,7 +477,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
 
     *out_count = i;
 
-    update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
+    update_dri2_drawable_buffers(pPriv, pDraw, buffers, *out_count, width, height);
 
     /* If the client is getting a fake front-buffer, pre-fill it with the
      * contents of the real front-buffer.  This ensures correct operation of
@@ -513,7 +513,7 @@ err_out:
 	buffers = NULL;
     }
 
-    update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
+    update_dri2_drawable_buffers(pPriv, pDraw, buffers, *out_count, width, height);
 
     return buffers;
 }
commit 93c833ee84a3465ec5d251e622ba26434cb532f8
Author: Ville Syrjälä <ville.syrjala at nokia.com>
Date:   Tue Apr 12 17:13:28 2011 +0300

    dri2: Handle calloc() failure
    
    Don't access invalid memory if calloc() fails to allocate the buffers
    array.
    
    Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
    Reviewed-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 10be599..23b6594 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -409,6 +409,8 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
 	&& (pPriv->serialNumber == DRI2DrawableSerial(pDraw));
 
     buffers = calloc((count + 1), sizeof(buffers[0]));
+    if (!buffers)
+	goto err_out;
 
     for (i = 0; i < count; i++) {
 	const unsigned attachment = *(attachments++);
@@ -501,13 +503,15 @@ err_out:
 
     *out_count = 0;
 
-    for (i = 0; i < count; i++) {
+    if (buffers) {
+	for (i = 0; i < count; i++) {
 	    if (buffers[i] != NULL)
-		    (*ds->DestroyBuffer)(pDraw, buffers[i]);
-    }
+		(*ds->DestroyBuffer)(pDraw, buffers[i]);
+	}
 
-    free(buffers);
-    buffers = NULL;
+	free(buffers);
+	buffers = NULL;
+    }
 
     update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
 
commit b2997431fd426ab318bc5dfd2cd43956d733ebec
Author: Jeremy Huddleston <jeremyhu at apple.com>
Date:   Wed Apr 13 11:51:30 2011 -0700

    Send events that were missing from RRSelectInput
    
    The RANDR spec (randrproto.txt) specifies that RRSelectInput will send out
    events corresponding to the event mask, if there have been changes to
    CRTCs or outputs.  Only screen events were being generated, however.
    
    Fixes http://bugs.freedesktop.org/21760
    
    Signed-off-by: Federico Mena Quintero <federico at novell.com>
    Reviewd-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index ac4d2ac..2135504 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -146,7 +146,7 @@ ProcRRSelectInput (ClientPtr client)
 	/*
 	 * Now see if the client needs an event
 	 */
-	if (pScrPriv && (pRREvent->mask & RRScreenChangeNotifyMask))
+	if (pScrPriv)
 	{
 	    pTimes = &((RRTimesPtr) (pRRClient + 1))[pScreen->myNum];
 	    if (CompareTimeStamps (pTimes->setTime, 
@@ -154,7 +154,35 @@ ProcRRSelectInput (ClientPtr client)
 		CompareTimeStamps (pTimes->configTime, 
 				   pScrPriv->lastConfigTime) != 0)
 	    {
-		RRDeliverScreenEvent (client, pWin, pScreen);
+		if (pRREvent->mask & RRScreenChangeNotifyMask)
+		{
+		    RRDeliverScreenEvent (client, pWin, pScreen);
+		}
+
+		if (pRREvent->mask & RRCrtcChangeNotifyMask)
+		{
+		    int i;
+
+		    for (i = 0; i < pScrPriv->numCrtcs; i++)
+		    {
+			RRDeliverCrtcEvent (client, pWin, pScrPriv->crtcs[i]);
+		    }
+		}
+
+		if (pRREvent->mask & RROutputChangeNotifyMask)
+		{
+		    int i;
+
+		    for (i = 0; i < pScrPriv->numOutputs; i++)
+		    {
+			RRDeliverOutputEvent (client, pWin, pScrPriv->outputs[i]);
+		    }
+		}
+
+		/* We don't check for RROutputPropertyNotifyMask, as randrproto.txt doesn't
+		 * say if there ought to be notifications of changes to output properties
+		 * if those changes occurred before the time RRSelectInput is called.
+		 */
 	    }
 	}
     }
commit e409fb32b97033718f270a273f29f24c0b562b84
Author: Erkki Seppälä <erkki.seppala at vincit.fi>
Date:   Tue Apr 12 12:55:56 2011 +0300

    damage: use DamageReportDamage for the initial borderClip damage report
    
    Instead of using DamageDamageRegion for reporting the first (virtual)
    damage in ProcDamageCreate that covers the borderClip of the drawable
    window, use a function DamageReportDamage directly (previously called
    damageReportDamage). This avoids sending all other damage listeners a
    full window update when a new damage object is created.
    
    As this patch makes DamageReportDamage a public interface, the
    function has been moved into the part of the file that contains all
    the other public functions. The function has not been otherwise
    modified.
    
    Signed-off-by: Erkki Seppälä <erkki.seppala at vincit.fi>
    Reviewed-by: Keith Packard <keithp at keithp.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/damageext/damageext.c b/damageext/damageext.c
index 754383d..02db88a 100644
--- a/damageext/damageext.c
+++ b/damageext/damageext.c
@@ -223,7 +223,7 @@ ProcDamageCreate (ClientPtr client)
     if (pDrawable->type == DRAWABLE_WINDOW)
     {
 	pRegion = &((WindowPtr) pDrawable)->borderClip;
-	DamageDamageRegion(pDrawable, pRegion);
+	DamageReportDamage(pDamageExt->pDamage, pRegion);
     }
 
     return Success;
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index 0fe1fb6..d791211 100644
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -121,54 +121,6 @@ getDrawableDamageRef (DrawablePtr pDrawable)
 	dixLookupPrivateAddr(&(pWindow)->devPrivates, damageWinPrivateKey)
 
 static void
-damageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion)
-{
-    BoxRec tmpBox;
-    RegionRec tmpRegion;
-    Bool was_empty;
-
-    switch (pDamage->damageLevel) {
-    case DamageReportRawRegion:
-	RegionUnion(&pDamage->damage, &pDamage->damage,
-			 pDamageRegion);
-	(*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
-	break;
-    case DamageReportDeltaRegion:
-	RegionNull(&tmpRegion);
-	RegionSubtract(&tmpRegion, pDamageRegion, &pDamage->damage);
-	if (RegionNotEmpty(&tmpRegion)) {
-	    RegionUnion(&pDamage->damage, &pDamage->damage,
-			 pDamageRegion);
-	    (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
-	}
-	RegionUninit(&tmpRegion);
-	break;
-    case DamageReportBoundingBox:
-	tmpBox = *RegionExtents(&pDamage->damage);
-	RegionUnion(&pDamage->damage, &pDamage->damage,
-		     pDamageRegion);
-	if (!BOX_SAME (&tmpBox, RegionExtents(&pDamage->damage))) {
-	    (*pDamage->damageReport) (pDamage, &pDamage->damage,
-				      pDamage->closure);
-	}
-	break;
-    case DamageReportNonEmpty:
-	was_empty = !RegionNotEmpty(&pDamage->damage);
-	RegionUnion(&pDamage->damage, &pDamage->damage,
-		     pDamageRegion);
-	if (was_empty && RegionNotEmpty(&pDamage->damage)) {
-	    (*pDamage->damageReport) (pDamage, &pDamage->damage,
-				      pDamage->closure);
-	}
-	break;
-    case DamageReportNone:
-	RegionUnion(&pDamage->damage, &pDamage->damage,
-		     pDamageRegion);
-	break;
-    }
-}
-
-static void
 damageReportDamagePostRendering (DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pDamageRegion)
 {
     BoxRec tmpBox;
@@ -360,7 +312,7 @@ damageRegionAppend (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
 	/* Report damage now, if desired. */
 	if (!pDamage->reportAfter) {
 	    if (pDamage->damageReport)
-		damageReportDamage (pDamage, pDamageRegion);
+		DamageReportDamage (pDamage, pDamageRegion);
 	    else
 		RegionUnion(&pDamage->damage,
 			 &pDamage->damage, pDamageRegion);
@@ -393,7 +345,7 @@ damageRegionProcessPending (DrawablePtr pDrawable)
 	if (pDamage->reportAfter) {
 	    /* It's possible that there is only interest in postRendering reporting. */
 	    if (pDamage->damageReport)
-		damageReportDamage (pDamage, &pDamage->pendingDamage);
+		DamageReportDamage (pDamage, &pDamage->pendingDamage);
 	    else
 		RegionUnion(&pDamage->damage, &pDamage->damage,
 			&pDamage->pendingDamage);
@@ -2125,3 +2077,52 @@ DamageGetScreenFuncs (ScreenPtr pScreen)
     damageScrPriv(pScreen);
     return &pScrPriv->funcs;
 }
+
+void
+DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion)
+{
+    BoxRec tmpBox;
+    RegionRec tmpRegion;
+    Bool was_empty;
+
+    switch (pDamage->damageLevel) {
+    case DamageReportRawRegion:
+	RegionUnion(&pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	(*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+	break;
+    case DamageReportDeltaRegion:
+	RegionNull(&tmpRegion);
+	RegionSubtract(&tmpRegion, pDamageRegion, &pDamage->damage);
+	if (RegionNotEmpty(&tmpRegion)) {
+	    RegionUnion(&pDamage->damage, &pDamage->damage,
+			 pDamageRegion);
+	    (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+	}
+	RegionUninit(&tmpRegion);
+	break;
+    case DamageReportBoundingBox:
+	tmpBox = *RegionExtents(&pDamage->damage);
+	RegionUnion(&pDamage->damage, &pDamage->damage,
+		     pDamageRegion);
+	if (!BOX_SAME (&tmpBox, RegionExtents(&pDamage->damage))) {
+	    (*pDamage->damageReport) (pDamage, &pDamage->damage,
+				      pDamage->closure);
+	}
+	break;
+    case DamageReportNonEmpty:
+	was_empty = !RegionNotEmpty(&pDamage->damage);
+	RegionUnion(&pDamage->damage, &pDamage->damage,
+		     pDamageRegion);
+	if (was_empty && RegionNotEmpty(&pDamage->damage)) {
+	    (*pDamage->damageReport) (pDamage, &pDamage->damage,
+				      pDamage->closure);
+	}
+	break;
+    case DamageReportNone:
+	RegionUnion(&pDamage->damage, &pDamage->damage,
+		     pDamageRegion);
+	break;
+    }
+}
+
diff --git a/miext/damage/damage.h b/miext/damage/damage.h
index 067016f..0c7fc31 100644
--- a/miext/damage/damage.h
+++ b/miext/damage/damage.h
@@ -110,6 +110,10 @@ DamageRegionProcessPending (DrawablePtr pDrawable);
 extern _X_EXPORT void
 DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDamage, RegionPtr pRegion);
 
+/* Call this when you create a new Damage and you wish to send an initial damage message (to it). */
+extern _X_EXPORT void
+DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion);
+
 /* Avoid using this call, it only exists for API compatibility. */
 extern _X_EXPORT void
 DamageDamageRegion (DrawablePtr	    pDrawable,
commit 274dca8f2c6707121d45df8015fe7eddb129dec9
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Mon Apr 4 22:31:42 2011 +0300

    dix: don't free stranger pointers inside AllocARGBCursor
    
    This seems a good convention to follow: if pointers are allocate outside a
    given function, then free there as well when a failure occurs.
    
    AllocARGBCursor and its callers were mixing up the freeing of resources and
    causing a particular double free inside TileScreenSaver (srcbits and mskbits).
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan-de-oliveira at nokia.com>

diff --git a/dix/cursor.c b/dix/cursor.c
index 72a7609..c191c1e 100644
--- a/dix/cursor.c
+++ b/dix/cursor.c
@@ -241,11 +241,8 @@ AllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits,
     *ppCurs = NULL;
     pCurs = (CursorPtr)calloc(CURSOR_REC_SIZE + CURSOR_BITS_SIZE, 1);
     if (!pCurs)
-    {
-	free(psrcbits);
-	free(pmaskbits);
 	return BadAlloc;
-    }
+
     bits = (CursorBitsPtr)((char *)pCurs + CURSOR_REC_SIZE);
     dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR);
     dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS)
diff --git a/dix/dispatch.c b/dix/dispatch.c
index 601b14a..192c8c3 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -2976,11 +2976,17 @@ ProcCreateCursor (ClientPtr client)
 			 &pCursor, client, stuff->cid);
 
     if (rc != Success)
-	return rc;
-    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
-	return BadAlloc;
+	goto bail;
+    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) {
+	rc = BadAlloc;
+	goto bail;
+    }
 
     return Success;
+bail:
+    free(srcbits);
+    free(mskbits);
+    return rc;
 }
 
 int
diff --git a/render/render.c b/render/render.c
index c5da6d7..ebb1d63 100644
--- a/render/render.c
+++ b/render/render.c
@@ -1705,11 +1705,17 @@ ProcRenderCreateCursor (ClientPtr client)
 			 GetColor(twocolor[1], 0),
 			 &pCursor, client, stuff->cid);
     if (rc != Success)
-	return rc;
-    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
-	return BadAlloc;
+	goto bail;
+    if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) {
+	rc = BadAlloc;
+	goto bail;
+    }
 
     return Success;
+bail:
+    free(srcbits);
+    free(mskbits);
+    return rc;
 }
 
 static int
commit f603061e9482ad5caf1975ba5395b3294852d072
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Mon Apr 4 21:40:06 2011 +0300

    os: fix use after free in EstablishNewConnections
    
    In the case of failure on AllocNewConnection, new_trans_conn cannot be
    dereferenced because it's already freed. Swapping the order of this logic fix
    the changes introduced in 04956b80431169e0ae713a3e6ba4cdc157ce3a66.
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    CC: Jeremy Huddleston <jeremyhu at freedesktop.org>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/os/connection.c b/os/connection.c
index 5580fab..0c580ab 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -852,15 +852,14 @@ EstablishNewConnections(ClientPtr clientUnused, pointer closure)
 
 	_XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
 
+	if(trans_conn->flags & TRANS_NOXAUTH)
+	    new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
+
 	if (!AllocNewConnection (new_trans_conn, newconn, connect_time))
 	{
 	    ErrorConnMax(new_trans_conn);
 	    _XSERVTransClose(new_trans_conn);
 	}
-
-	if(trans_conn->flags & TRANS_NOXAUTH)
-	    new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH;
-
       }
 #ifndef WIN32
     }
commit 82498e3c2cce6f515063ecb4b6ae9303e828da00
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Mon Apr 4 20:25:32 2011 +0300

    xfree86: xv: set pointers to NULL in xf86XVFreeAdaptor
    
    As a good practice and for eventual double frees.
    
    The reason of this patch is due the resilience of xf86XVInitAdaptors, where
    for any adaptor failure it's able to keep trying registering the following
    ones.
    
    I discussed briefly with Pauli and Ville about a bigger refactoring of such
    function, doing it in a way to return instantly when a failure happens; after
    all that's how mostly of the other driver functions work. Instead, we just
    thought that xf86XVInitAdaptors is wise and cool, and eventually other driver
    functions should be even following the main idea of resilience.
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index f87af4c..b46dfef 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -313,6 +313,7 @@ xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
    int i;
 
    free(pAdaptor->name);
+   pAdaptor->name = NULL;
 
    if(pAdaptor->pEncodings) {
       XvEncodingPtr pEncode = pAdaptor->pEncodings;
@@ -320,9 +321,11 @@ xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
       for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++)
 	  free(pEncode->name);
       free(pAdaptor->pEncodings);
+      pAdaptor->pEncodings = NULL;
    }
 
    free(pAdaptor->pFormats);
+   pAdaptor->pFormats = NULL;
 
    if(pAdaptor->pPorts) {
       XvPortPtr pPort = pAdaptor->pPorts;
@@ -341,6 +344,7 @@ xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
 	  }
       }
       free(pAdaptor->pPorts);
+      pAdaptor->pPorts = NULL;
    }
 
    if(pAdaptor->pAttributes) {
@@ -354,6 +358,8 @@ xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
 
    free(pAdaptor->pImages);
    free(pAdaptor->devPriv.ptr);
+   pAdaptor->pImages = NULL;
+   pAdaptor->devPriv.ptr = NULL;
 }
 
 static Bool
commit 81414c1c836ae30628606545edbf7392d9b3d009
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Thu Mar 31 23:44:03 2011 +0300

    xfree86: xv: fix double free in xf86XVFreeAdaptor
    
    When xf86XVFreeAdaptor is called more than once in xf86XVInitAdaptors (it may,
    but not often), the conditional being changed in this patch will always take
    true path and will keep freeing pAdaptor->pAttributes, thus letting the system
    error-prone.
    
    This patch fix such problem checking for a pointer instead the number of
    attributes. Such pointer will be deallocated when xf86XVFreeAdaptor is called
    first and will not let the code re-run in the following calls. This is a bit
    similar how the surroundings code is already doing.
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Jeremy Huddleston <jeremyhu at apple.com>

diff --git a/hw/xfree86/common/xf86xv.c b/hw/xfree86/common/xf86xv.c
index 53ebe8f..f87af4c 100644
--- a/hw/xfree86/common/xf86xv.c
+++ b/hw/xfree86/common/xf86xv.c
@@ -343,12 +343,13 @@ xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
       free(pAdaptor->pPorts);
    }
 
-   if(pAdaptor->nAttributes) {
+   if(pAdaptor->pAttributes) {
       XvAttributePtr pAttribute = pAdaptor->pAttributes;
 
       for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++)
 	  free(pAttribute->name);
       free(pAdaptor->pAttributes);
+      pAdaptor->pAttributes = NULL;
    }
 
    free(pAdaptor->pImages);
commit 74476b700f1e499a731ba2ddbba87b12b9b5139b
Author: Tiago Vignatti <tiago.vignatti at nokia.com>
Date:   Thu Mar 31 17:46:42 2011 +0300

    xfree86: loader: use one exit code only for readability
    
    No functional changes. Spaghetti code for the win! \o/
    
    Signed-off-by: Tiago Vignatti <tiago.vignatti at nokia.com>
    Reviewed-by: Nicolas Peninguy <nico at lostgeeks.org>

diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index 46ce68b..9f82099 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -483,19 +483,15 @@ LoaderListDirs(const char **subdirlist, const char **patternlist)
     char *fp;
     char **listing = NULL;
     char **save;
+    char **ret = NULL;
     int n = 0;
 
     if (!(pathlist = InitPathList(NULL)))
 	return NULL;
-    if (!(subdirs = InitSubdirs(subdirlist))) {
-	FreePathList(pathlist);
-	return NULL;
-    }
-    if (!(patterns = InitPatterns(patternlist))) {
-	FreePathList(pathlist);
-	FreeSubdirs(subdirs);
-	return NULL;
-    }
+    if (!(subdirs = InitSubdirs(subdirlist)))
+	goto bail;
+    if (!(patterns = InitPatterns(patternlist)))
+	goto bail;
 
     for (elem = pathlist; *elem; elem++) {
 	for (s = subdirs; *s; s++) {
@@ -529,20 +525,14 @@ LoaderListDirs(const char **subdirlist, const char **patternlist)
 				    save[n] = NULL;
 				    FreeStringList(save);
 				}
-				FreePathList(pathlist);
-				FreeSubdirs(subdirs);
-				FreePatterns(patterns);
 				closedir(d);
-				return NULL;
+				goto bail;
 			    }
 			    listing[n] = malloc(len + 1);
 			    if (!listing[n]) {
 				FreeStringList(listing);
-				FreePathList(pathlist);
-				FreeSubdirs(subdirs);
-				FreePatterns(patterns);
 				closedir(d);
-				return NULL;
+				goto bail;
 			    }
 			    strncpy(listing[n], dp->d_name + match[1].rm_so,
 				    len);
@@ -558,11 +548,13 @@ LoaderListDirs(const char **subdirlist, const char **patternlist)
     }
     if (listing)
 	listing[n] = NULL;
+    ret = listing;
 
-    FreePathList(pathlist);
-    FreeSubdirs(subdirs);
+bail:
     FreePatterns(patterns);
-    return listing;
+    FreeSubdirs(subdirs);
+    FreePathList(pathlist);
+    return ret;
 }
 
 void


More information about the Xquartz-changes mailing list