? error_handler.patch
Index: sys/ximage/ximagesink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/sys/ximage/ximagesink.c,v
retrieving revision 1.169
diff -u -r1.169 ximagesink.c
--- sys/ximage/ximagesink.c	4 Jan 2007 11:30:53 -0000	1.169
+++ sys/ximage/ximagesink.c	7 Jan 2007 12:05:29 -0000
@@ -301,7 +301,7 @@
   char error_msg[1024];
 
   XGetErrorText (display, xevent->error_code, error_msg, 1024);
-  GST_DEBUG ("ximagesink failed to use XShm calls. error: %s", error_msg);
+  GST_DEBUG ("ximagesink triggered an XError. error: %s", error_msg);
   error_caught = TRUE;
   return 0;
 }
@@ -406,6 +406,7 @@
   GstXImageBuffer *ximage = NULL;
   GstStructure *structure = NULL;
   gboolean succeeded = FALSE;
+  int (*handler) (Display *, XErrorEvent *);
 
   g_return_val_if_fail (GST_IS_XIMAGESINK (ximagesink), NULL);
 
@@ -423,14 +424,22 @@
 
   g_mutex_lock (ximagesink->x_lock);
 
+  /* Setting an error handler to catch failure */
+  error_caught = FALSE;
+  handler = XSetErrorHandler (gst_ximagesink_handle_xerror);
+
 #ifdef HAVE_XSHM
   if (ximagesink->xcontext->use_xshm) {
     ximage->ximage = XShmCreateImage (ximagesink->xcontext->disp,
         ximagesink->xcontext->visual,
         ximagesink->xcontext->depth,
         ZPixmap, NULL, &ximage->SHMInfo, ximage->width, ximage->height);
-    if (!ximage->ximage) {
+    if (!ximage->ximage || error_caught) {
       g_mutex_unlock (ximagesink->x_lock);
+      /* Reset error handler */
+      error_caught = FALSE;
+      XSetErrorHandler (handler);
+      /* Push an error */
       GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
           ("Failed to create output image buffer of %dx%d pixels",
               ximage->width, ximage->height),
@@ -494,8 +503,12 @@
         ximagesink->xcontext->depth,
         ZPixmap, 0, NULL,
         ximage->width, ximage->height, ximagesink->xcontext->bpp, 0);
-    if (!ximage->ximage) {
+    if (!ximage->ximage || error_caught) {
       g_mutex_unlock (ximagesink->x_lock);
+      /* Reset error handler */
+      error_caught = FALSE;
+      XSetErrorHandler (handler);
+      /* Push an error */
       GST_ELEMENT_ERROR (ximagesink, RESOURCE, WRITE,
           ("Failed to create output image buffer of %dx%d pixels",
               ximage->width, ximage->height),
@@ -510,6 +523,11 @@
 
     XSync (ximagesink->xcontext->disp, FALSE);
   }
+  
+  /* Reset error handler */
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+  
   succeeded = TRUE;
 
   GST_BUFFER_DATA (ximage) = (guchar *) ximage->ximage->data;
Index: sys/xvimage/xvimagesink.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/sys/xvimage/xvimagesink.c,v
retrieving revision 1.173
diff -u -r1.173 xvimagesink.c
--- sys/xvimage/xvimagesink.c	4 Jan 2007 11:30:53 -0000	1.173
+++ sys/xvimage/xvimagesink.c	7 Jan 2007 12:05:31 -0000
@@ -389,7 +389,7 @@
   char error_msg[1024];
 
   XGetErrorText (display, xevent->error_code, error_msg, 1024);
-  GST_DEBUG ("xvimagesink failed to use XShm calls. error: %s", error_msg);
+  GST_DEBUG ("xvimagesink triggered an XError. error: %s", error_msg);
   error_caught = TRUE;
   return 0;
 }
@@ -499,6 +499,7 @@
   GstXvImageBuffer *xvimage = NULL;
   GstStructure *structure = NULL;
   gboolean succeeded = FALSE;
+  int (*handler) (Display *, XErrorEvent *);
 
   g_return_val_if_fail (GST_IS_XVIMAGESINK (xvimagesink), NULL);
 
@@ -528,14 +529,22 @@
 
   g_mutex_lock (xvimagesink->x_lock);
 
+  /* Setting an error handler to catch failure */
+  error_caught = FALSE;
+  handler = XSetErrorHandler (gst_xvimagesink_handle_xerror);
+  
 #ifdef HAVE_XSHM
   if (xvimagesink->xcontext->use_xshm) {
     xvimage->xvimage = XvShmCreateImage (xvimagesink->xcontext->disp,
         xvimagesink->xcontext->xv_port_id,
         xvimage->im_format, NULL,
         xvimage->width, xvimage->height, &xvimage->SHMInfo);
-    if (!xvimage->xvimage) {
+    if (!xvimage->xvimage || error_caught) {
       g_mutex_unlock (xvimagesink->x_lock);
+      /* Reset error handler */
+      error_caught = FALSE;
+      XSetErrorHandler (handler);
+      /* Push an error */
       GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
           ("Failed to create output image buffer of %dx%d pixels",
               xvimage->width, xvimage->height),
@@ -598,8 +607,12 @@
     xvimage->xvimage = XvCreateImage (xvimagesink->xcontext->disp,
         xvimagesink->xcontext->xv_port_id,
         xvimage->im_format, NULL, xvimage->width, xvimage->height);
-    if (!xvimage->xvimage) {
+    if (!xvimage->xvimage || error_caught) {
       g_mutex_unlock (xvimagesink->x_lock);
+      /* Reset error handler */
+      error_caught = FALSE;
+      XSetErrorHandler (handler);
+      /* Push an error */
       GST_ELEMENT_ERROR (xvimagesink, RESOURCE, WRITE,
           ("Failed to create outputimage buffer of %dx%d pixels",
               xvimage->width, xvimage->height),
@@ -614,6 +627,11 @@
 
     XSync (xvimagesink->xcontext->disp, FALSE);
   }
+  
+  /* Reset error handler */
+  error_caught = FALSE;
+  XSetErrorHandler (handler);
+  
   succeeded = TRUE;
 
   GST_BUFFER_DATA (xvimage) = (guchar *) xvimage->xvimage->data;
