? sys/ximage/gst-launch-0.10.core
Index: sys/ximage/gstximagesrc.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-good/sys/ximage/gstximagesrc.c,v
retrieving revision 1.14
diff -u -r1.14 gstximagesrc.c
--- sys/ximage/gstximagesrc.c	28 Apr 2006 18:57:09 -0000	1.14
+++ sys/ximage/gstximagesrc.c	21 May 2006 06:27:05 -0000
@@ -153,7 +153,7 @@
             &error_base)) {
       s->damage =
           XDamageCreate (s->xcontext->disp, s->xwindow,
-          XDamageReportRawRectangles);
+          XDamageReportNonEmpty);
       if (s->damage != None) {
         s->damage_region = XFixesCreateRegion (s->xcontext->disp, NULL, 0);
         if (s->damage_region != None) {
@@ -391,35 +391,34 @@
     do {
       XNextEvent (ximagesrc->xcontext->disp, &ev);
       if (ev.type == ximagesrc->damage_event_base + XDamageNotify) {
-        XDamageNotifyEvent *dev = (XDamageNotifyEvent *) & ev;
-
-#ifdef HAVE_XSHM
-        if (ximagesrc->xcontext->use_xshm &&
-            dev->area.width == ximagesrc->width &&
-            dev->area.height == ximagesrc->height) {
-          GST_DEBUG_OBJECT (ximagesrc, "Entire screen was damaged");
-          XShmGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
-              ximage->ximage, 0, 0, AllPlanes);
-          /* No need to collect more events */
-          while (XPending (ximagesrc->xcontext->disp)) {
-            XNextEvent (ximagesrc->xcontext->disp, &ev);
-          }
-          break;
-        } else
-#endif
-        {
-          GST_LOG_OBJECT (ximagesrc,
-              "Retrieving damaged sub-region @ %d,%d size %dx%d",
-              dev->area.x, dev->area.y, dev->area.width, dev->area.height);
-
-          XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
-              dev->area.x, dev->area.y,
-              dev->area.width, dev->area.height,
-              AllPlanes, ZPixmap, ximage->ximage, dev->area.x, dev->area.y);
-        }
+	XserverRegion parts;
+	XRectangle *rects;
+	int nrects;
+
+	parts = XFixesCreateRegion (ximagesrc->xcontext->disp, 0, 0);
+	/* The following XDamageSubtract atomically takes the current damaged area
+	 * and copies it to parts, then clears the recorded damage.
+	 */
+	XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None,
+	      parts);
+
+	/* Now copy out all of the damaged rectangles. */
+	rects = XFixesFetchRegion (ximagesrc->xcontext->disp, parts, &nrects);
+	if (rects != NULL) {
+	  int i;
+
+	  for (i = 0; i < nrects; i++) {
+	    GST_LOG_OBJECT (ximagesrc,
+		"Retrieving damaged sub-region @ %d,%d size %dx%d",
+		rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+	    XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+		rects[i].x, rects[i].y, rects[i].width, rects[i].height, AllPlanes,
+		ZPixmap, ximage->ximage, rects[i].x, rects[i].y);
+	  }
+	  free (rects);
+	}
       }
     } while (XPending (ximagesrc->xcontext->disp));
-    XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None, None);
 #ifdef HAVE_XFIXES
     /* re-get area where last mouse pointer was */
     if (ximagesrc->cursor_image) {
