Date: Tue, 24 Aug 2004 06:16:32 +0200
authorSam Lantinga <slouken@libsdl.org>
Wed, 25 Aug 2004 05:39:03 +0000
changeset 950 b7a5c1b64829
parent 949 e0d96eb0af19
child 951 121f56c1277d
Date: Tue, 24 Aug 2004 06:16:32 +0200 From: Christian Biere Subject: [SDL] YUV Overlay vs. XV_AUTOPAINT_COLORKEY I have a problem with SDL's YUV Overlay support using X11 Xv. Some people reported that they get nothing but a black screen. I've compared the output of xvattr they've sent me with the values I get here. It turned out that XV_AUTOPAINT_COLORKEY was disabled. By enabling this feature everything works fine.
src/video/x11/SDL_x11yuv.c
--- a/src/video/x11/SDL_x11yuv.c	Tue Aug 24 07:40:14 2004 +0000
+++ b/src/video/x11/SDL_x11yuv.c	Wed Aug 25 05:39:03 2004 +0000
@@ -73,10 +73,11 @@
 };
 
 
+static int (*X_handler)(Display *, XErrorEvent *) = NULL;
+
 #ifndef NO_SHARED_MEMORY
 /* Shared memory error handler routine */
 static int shm_error;
-static int (*X_handler)(Display *, XErrorEvent *) = NULL;
 static int shm_errhandler(Display *d, XErrorEvent *e)
 {
         if ( e->error_code == BadAccess ) {
@@ -87,6 +88,15 @@
 }
 #endif /* !NO_SHARED_MEMORY */
 
+static int xv_error;
+static int xv_errhandler(Display *d, XErrorEvent *e)
+{
+        if ( e->error_code == BadMatch ) {
+        	xv_error = True;
+        	return(0);
+        } else
+		return(X_handler(d,e));
+}
 
 SDL_Overlay *X11_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display)
 {
@@ -192,6 +202,30 @@
 		return(NULL);
 	}
 
+	/* Enable auto-painting of the overlay colorkey */
+	{
+		static const char *attr[] = { "XV_AUTOPAINT_COLORKEY", "XV_AUTOPAINT_COLOURKEY" };
+		unsigned int i;
+
+		SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, True);
+		X_handler = XSetErrorHandler(xv_errhandler);
+		for ( i=0; i < sizeof(attr)/(sizeof attr[0]); ++i ) {
+			Atom a;
+
+			xv_error = False;
+			a = XInternAtom(GFX_Display, attr[i], True);
+			if ( a != None ) {
+     				SDL_NAME(XvSetPortAttribute)(GFX_Display, xv_port, a, 1);
+				XSync(GFX_Display, True);
+				if ( ! xv_error ) {
+					break;
+				}
+			}
+		}
+		XSetErrorHandler(X_handler);
+		SDL_NAME(XvSelectPortNotify)(GFX_Display, xv_port, False);
+	}
+
 	/* Create the overlay structure */
 	overlay = (SDL_Overlay *)malloc(sizeof *overlay);
 	if ( overlay == NULL ) {