[Xcb] xcb shm plugin for xine

Christoph Pfister christophpfister at gmail.com
Sun Dec 10 11:57:21 PST 2006


Hi all,

Please find it attached (morely experimental but should work +/- now).

First patch is the stable part of the xine patch which modifies
include/xine.h.in.
Second patch is a destructive one which modifies the existing output
plugin + provides an osd stub.
Third patch is a sample patch for kaffeine that you can actually try it out ;-)

Limitations:
- no unscaled osd
- from time to time player window gets black because of an x error
where we don't recover from. likely this is related to kaffeine only
because there it's present without xcb, too (although we recover from
it there). will investigate on this issue

Have fun ...

Christoph
-------------- next part --------------
diff -dNpru xine-lib/include/xine.h.in xine-lib-xcb/include/xine.h.in
--- xine-lib/include/xine.h.in	2006-10-28 20:51:08.000000000 +0200
+++ xine-lib-xcb/include/xine.h.in	2006-12-10 15:30:19.000000000 +0100
@@ -176,6 +176,7 @@ void xine_close_video_driver (xine_t *se
 #define XINE_VISUAL_TYPE_DIRECTX           7 /* used by the win32/msvc port */
 #define XINE_VISUAL_TYPE_CACA              8
 #define XINE_VISUAL_TYPE_MACOSX            9
+#define XINE_VISUAL_TYPE_XCB              11
 
 /*
  * free all resources, close all plugins, close engine.
@@ -1192,6 +1193,81 @@ typedef struct {
 } x11_visual_t;
 
 /*
+ * this is the visual data struct any xcb gui
+ * must supply to the xine_open_video_driver call
+ * ("data" parameter)
+ */
+
+typedef struct {
+  /* some information about the display */
+  void        *connection; /* xcb_connection_t */
+  void        *screen;     /* xcb_screen_t     */
+
+  /* window to display the video in / on */
+  unsigned int window; /* xcb_window_t */
+
+  void        *user_data;
+
+  /*
+   * dest size callback
+   *
+   * this will be called by the video driver to find out
+   * how big the video output area size will be for a
+   * given video size. The ui should _not_ adjust it's
+   * video out area, just do some calculations and return
+   * the size. This will be called for every frame, ui
+   * implementation should be fast.
+   * dest_pixel_aspect should be set to the used display pixel aspect.
+   * NOTE: Semantics has changed: video_width and video_height
+   * are no longer pixel aspect corrected. Get the old semantics
+   * in the UI with
+   *   *dest_pixel_aspect = display_pixel_aspect;
+   *   if (video_pixel_aspect >= display_pixel_aspect)
+   *     video_width  = video_width * video_pixel_aspect / display_pixel_aspect + .5;
+   *   else
+   *     video_height = video_height * display_pixel_aspect / video_pixel_aspect + .5;
+   */
+  void (*dest_size_cb) (void *user_data,
+			int video_width, int video_height,
+			double video_pixel_aspect,
+			int *dest_width, int *dest_height,
+			double *dest_pixel_aspect);
+
+  /*
+   * frame output callback
+   *
+   * this will be called by the video driver for every frame
+   * it's about to draw. ui can adapt it's size if necessary
+   * here.
+   * note: the ui doesn't have to adjust itself to this
+   * size, this is just to be taken as a hint.
+   * ui must return the actual size of the video output
+   * area and the video output driver will do it's best
+   * to adjust the video frames to that size (while
+   * preserving aspect ratio and stuff).
+   *    dest_x, dest_y: offset inside window
+   *    dest_width, dest_height: available drawing space
+   *    dest_pixel_aspect: display pixel aspect
+   *    win_x, win_y: window absolute screen position
+   * NOTE: Semantics has changed: video_width and video_height
+   * are no longer pixel aspect corrected. Get the old semantics
+   * in the UI with
+   *   *dest_pixel_aspect = display_pixel_aspect;
+   *   if (video_pixel_aspect >= display_pixel_aspect)
+   *     video_width  = video_width * video_pixel_aspect / display_pixel_aspect + .5;
+   *   else
+   *     video_height = video_height * display_pixel_aspect / video_pixel_aspect + .5;
+   */
+  void (*frame_output_cb) (void *user_data,
+			   int video_width, int video_height,
+			   double video_pixel_aspect,
+			   int *dest_x, int *dest_y,
+			   int *dest_width, int *dest_height,
+			   double *dest_pixel_aspect,
+			   int *win_x, int *win_y);
+} xcb_visual_t;
+
+/*
  * this is the visual data struct any fb gui
  * may supply to the xine_open_video_driver call
  * ("data" parameter) to get frame_output_cd calls
-------------- next part --------------
diff -dNpru xine-lib/src/video_out/Makefile.am xine-lib-xcb/src/video_out/Makefile.am
--- xine-lib/src/video_out/Makefile.am	2006-11-05 16:17:00.000000000 +0100
+++ xine-lib-xcb/src/video_out/Makefile.am	2006-12-10 16:55:33.000000000 +0100
@@ -88,11 +88,10 @@ lib_LTLIBRARIES = $(xshm_module) $(xv_mo
 		  $(xxmc_module) \
                   xineplug_vo_out_none.la
 
-xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c \
-	video_out_xshm.c $(X11OSD)
-xineplug_vo_out_xshm_la_LIBADD = $(MLIB_LIBS) $(X_LIBS) -lXext $(X_PRE_LIBS) -lX11 $(XINE_LIB) $(THREAD_LIBS)
-xineplug_vo_out_xshm_la_CFLAGS = $(VISIBILITY_FLAG) $(X_CFLAGS) $(MLIB_CFLAGS) -fno-strict-aliasing
-xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -module
+xineplug_vo_out_xshm_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c video_out_xshm.c
+xineplug_vo_out_xshm_la_LIBADD = $(MLIB_LIBS) $(XINE_LIB) $(THREAD_LIBS) -lxcb-shm
+xineplug_vo_out_xshm_la_CFLAGS = $(VISIBILITY_FLAG) $(MLIB_CFLAGS)
+xineplug_vo_out_xshm_la_LDFLAGS = -avoid-version -no-undefined -module
 
 xineplug_vo_out_xv_la_SOURCES = $(X11OSD) deinterlace.c video_out_xv.c
 xineplug_vo_out_xv_la_LIBADD = $(XV_LIBS) $(X_LIBS) -lXext $(X_PRE_LIBS) -lX11 $(XINE_LIB) $(THREAD_LIBS)
diff -dNpru xine-lib/src/video_out/video_out_xshm.c xine-lib-xcb/src/video_out/video_out_xshm.c
--- xine-lib/src/video_out/video_out_xshm.c	2006-10-28 20:51:08.000000000 +0200
+++ xine-lib-xcb/src/video_out/video_out_xshm.c	2006-12-10 20:36:50.000000000 +0100
@@ -40,13 +40,10 @@
 #include "xine.h"
 #include "video_out.h"
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/cursorfont.h>
 #include <errno.h>
 
-#include <X11/extensions/XShm.h>
+#include <xcb/shm.h>
+
 #include <sys/ipc.h>
 #include <sys/shm.h>
 #include <sys/time.h>
@@ -64,12 +61,8 @@
 #include "yuv2rgb.h"
 #include "xineutils.h"
 #include "vo_scale.h"
-#include "x11osd.h"
+#include "xcbosd.h"
 
-#define LOCK_DISPLAY(this) {if(this->lock_display) this->lock_display(this->user_data); \
-                            else XLockDisplay(this->display);}
-#define UNLOCK_DISPLAY(this) {if(this->unlock_display) this->unlock_display(this->user_data); \
-                            else XUnlockDisplay(this->display);}
 typedef struct {
   vo_frame_t         vo_frame;
 
@@ -80,14 +73,14 @@ typedef struct {
 
   vo_scale_t         sc;
     
-  XImage            *image;
-  XShmSegmentInfo    shminfo;
+  uint8_t           *image;
+  int                bytes_per_line;
+  xcb_shm_seg_t      shmseg;
 
   uint8_t           *chunk[3]; /* mem alloc by xmalloc_aligned           */
 
   yuv2rgb_t         *yuv2rgb; /* yuv2rgb converter set up for this frame */
   uint8_t           *rgb_dst;
-  int                yuv_stride;
 
 } xshm_frame_t;
 
@@ -96,17 +89,15 @@ typedef struct {
   vo_driver_t        vo_driver;
 
   /* X11 / XShm related stuff */
-  Display           *display;
-  int                screen;
-  Drawable           drawable;
-  Visual	    *visual;
-  GC                 gc;
-  int                depth, bpp, bytes_per_pixel, image_byte_order;
+  xcb_connection_t  *connection;
+  xcb_screen_t      *screen;
+  xcb_window_t       window;
+  xcb_gcontext_t     gc;
+  int                depth;
+  int                bpp;
+  int                scanline_pad;
   int                use_shm;
-  XColor             black;
   
-  int                yuv2rgb_mode;
-  int                yuv2rgb_swap;
   int                yuv2rgb_brightness;
   int                yuv2rgb_contrast;
   int                yuv2rgb_saturation;
@@ -116,21 +107,13 @@ typedef struct {
   vo_scale_t         sc;
   
   xshm_frame_t      *cur_frame;
-  x11osd            *xoverlay;
+  xcbosd            *xoverlay;
   int                ovl_changed;
 
-  int (*x11_old_error_handler)  (Display *, XErrorEvent *);
-
   xine_t            *xine;
 
   alphablend_t       alphablend_extra_data;
 
-  void             (*lock_display) (void *);
-
-  void             (*unlock_display) (void *);
-
-  void              *user_data;
-
 } xshm_driver_t;
 
 typedef struct {
@@ -141,112 +124,52 @@ typedef struct {
 } xshm_class_t;
 
 
-static int gX11Fail;
-
-/*
- * first, some utility functions
- */
-/* called xlocked */
-static int HandleXError (Display *display, XErrorEvent *xevent) {
-  char str [1024];
-
-  XGetErrorText (display, xevent->error_code, str, 1024);
-  printf ("video_out_xshm: received X error event: %s\n", str);
-  gX11Fail = 1;
-
-  return 0;
-}
-
-/* called xlocked */
-static void x11_InstallXErrorHandler (xshm_driver_t *this) {
-  this->x11_old_error_handler = XSetErrorHandler (HandleXError);
-  XSync(this->display, False);
-}
-
-static void x11_DeInstallXErrorHandler (xshm_driver_t *this) {
-  XSetErrorHandler (this->x11_old_error_handler);
-  XSync(this->display, False);
-  this->x11_old_error_handler = NULL;
-}
-
 /*
- * allocate an XImage, try XShm first but fall back to 
- * plain X11 if XShm should fail
+ * allocate an image, try shm first but
+ * fall back to plain xcb if shm should fail
  */
-/* called xlocked */
-static XImage *create_ximage (xshm_driver_t *this, XShmSegmentInfo *shminfo, 
-			      int width, int height) {
-  XImage *myimage = NULL;
-
-  if (this->use_shm) {
-
-    /*
-     * try shm
-     */
     
-    gX11Fail = 0;
-    x11_InstallXErrorHandler (this);
+static void create_ximage(xshm_driver_t *this, xshm_frame_t *frame, int width, int height)
+{
+  int shmid;
+  xcb_void_cookie_t shm_attach_cookie;
 
-    myimage = XShmCreateImage(this->display, 
-			      this->visual,
-			      this->depth,
-			      ZPixmap, NULL,
-			      shminfo,
-			      width, 
-			      height);
+  frame->bytes_per_line = ((this->bpp * width + this->scanline_pad - 1) &
+                           (-this->scanline_pad)) >> 3;
 
-    if (myimage == NULL )  {
-      xprintf(this->xine, XINE_VERBOSITY_LOG,
-	      _("video_out_xshm: shared memory error when allocating image\n"
-		"video_out_xshm: => not using MIT Shared Memory extension.\n"));
-      this->use_shm = 0;
-      goto finishShmTesting;
-    }
+  if (!this->use_shm)
+    goto no_shm;
   
-    this->bpp = myimage->bits_per_pixel;
-    this->bytes_per_pixel = this->bpp / 8;
-    this->image_byte_order = myimage->byte_order;
+   /*
+    * try shm
+    */
     
-    shminfo->shmid=shmget(IPC_PRIVATE,
-			  myimage->bytes_per_line * myimage->height, 
-			  IPC_CREAT | 0777);
+  shmid = shmget(IPC_PRIVATE, frame->bytes_per_line * height, IPC_CREAT | 0777);
     
-    if (shminfo->shmid < 0 ) {
+  if (shmid < 0) {
       xprintf(this->xine, XINE_VERBOSITY_LOG,
 	      _("video_out_xshm: %s: allocating image\n"
 		"video_out_xshm: => not using MIT Shared Memory extension.\n"), strerror(errno));
-      this->use_shm = 0;
-      goto finishShmTesting;
+    goto shm_fail1;
     }
   
-    shminfo->shmaddr  = (char *) shmat(shminfo->shmid, 0, 0);
+  frame->image = shmat(shmid, 0, 0);
   
-    if (shminfo->shmaddr == ((char *) -1)) {
+  if (frame->image == ((void *) -1)) {
       xprintf(this->xine, XINE_VERBOSITY_LOG,
 	      _("video_out_xshm: shared memory error (address error) when allocating image \n"
 		"video_out_xshm: => not using MIT Shared Memory extension.\n"));
-      shmctl (shminfo->shmid, IPC_RMID, 0);
-      shminfo->shmid = -1;
-      this->use_shm = 0;
-      goto finishShmTesting;
+    goto shm_fail2;
     }
   
-    shminfo->readOnly = False;
-    myimage->data = shminfo->shmaddr;
-  
-    XShmAttach(this->display, shminfo);
-  
-    XSync(this->display, False);
+  frame->shmseg = xcb_generate_id(this->connection);
 
-    if (gX11Fail) {
+  shm_attach_cookie = xcb_shm_attach_checked(this->connection, frame->shmseg, shmid, 0);
+  if (xcb_request_check(this->connection, shm_attach_cookie) != NULL) {
       xprintf(this->xine, XINE_VERBOSITY_LOG,
 	      _("video_out_xshm: x11 error during shared memory XImage creation\n"
 		"video_out_xshm: => not using MIT Shared Memory extension.\n"));
-      shmdt (shminfo->shmaddr);
-      shmctl (shminfo->shmid, IPC_RMID, 0);
-      shminfo->shmid = -1;
-      this->use_shm = 0;
-      goto finishShmTesting;
+    goto shm_fail3;
     }
 
     /* 
@@ -255,58 +178,40 @@ static XImage *create_ximage (xshm_drive
      * the kernel when all users of that segment have detached from 
      * it.  Gives an automatic shared memory cleanup in case we crash.
      */
-    shmctl (shminfo->shmid, IPC_RMID, 0);
-    shminfo->shmid = -1;
+  shmctl(shmid, IPC_RMID, 0);
 
-  finishShmTesting:
-    x11_DeInstallXErrorHandler(this);
+  return;
 
-  }
+shm_fail3:
+  frame->shmseg = 0;
+  shmdt(frame->image);
+  frame->image = NULL;
+shm_fail2:
+  shmctl(shmid, IPC_RMID, 0);
+shm_fail1:
+  this->use_shm = 0;
+no_shm:
 
   /*
    * fall back to plain X11 if necessary
    */
 
-  if (!this->use_shm) {
-
-    myimage = XCreateImage (this->display,
-			    this->visual,
-			    this->depth,
-			    ZPixmap, 0,
-			    NULL,
-			    width, 
-			    height,
-			    8, 0);
-
-    this->bpp = myimage->bits_per_pixel;
-    this->bytes_per_pixel = this->bpp / 8;
-    this->image_byte_order = myimage->byte_order;
-
-    myimage->data = xine_xmalloc (width * this->bytes_per_pixel * height);
-  }
-
-  return myimage;
+  frame->image = malloc(frame->bytes_per_line * height);
 
+  return;
 }
 
-/* called xlocked */
-static void dispose_ximage (xshm_driver_t *this, 
-			    XShmSegmentInfo *shminfo, 
-			    XImage *myimage) {
-
-  if (this->use_shm) {
-
-    XShmDetach (this->display, shminfo);
-    XDestroyImage (myimage);
-    shmdt (shminfo->shmaddr);
-    if (shminfo->shmid >= 0) {
-      shmctl (shminfo->shmid, IPC_RMID, 0);
-      shminfo->shmid = -1;
-    }
-
+static void dispose_ximage(xshm_driver_t *this, xshm_frame_t *frame)
+{
+  if (frame->shmseg) {
+    xcb_shm_detach(this->connection, frame->shmseg);
+    frame->shmseg = 0;
+    shmdt(frame->image);
+    frame->image = NULL;
+  } else {
+    free(frame->image);
+    frame->image = NULL;
   } 
-  else
-    XDestroyImage (myimage);
 }
 
 
@@ -357,13 +262,13 @@ static void xshm_frame_field (vo_frame_t
 
   switch (which_field) {
   case VO_TOP_FIELD:
-    frame->rgb_dst    = (uint8_t *)frame->image->data;
+    frame->rgb_dst    = frame->image;
     break;
   case VO_BOTTOM_FIELD:
-    frame->rgb_dst    = (uint8_t *)frame->image->data + frame->image->bytes_per_line ;
+    frame->rgb_dst    = frame->image + frame->bytes_per_line;
     break;
   case VO_BOTH_FIELDS:
-    frame->rgb_dst    = (uint8_t *)frame->image->data;
+    frame->rgb_dst    = frame->image;
     break;
   }
 
@@ -374,11 +279,8 @@ static void xshm_frame_dispose (vo_frame
   xshm_frame_t  *frame = (xshm_frame_t *) vo_img ;
   xshm_driver_t *this  = (xshm_driver_t *) vo_img->driver;
 
-  if (frame->image) {
-    LOCK_DISPLAY(this);
-    dispose_ximage (this, &frame->shminfo, frame->image);
-    UNLOCK_DISPLAY(this);
-  }
+  if (frame->image)
+    dispose_ximage (this, frame);
 
   frame->yuv2rgb->dispose (frame->yuv2rgb);
 
@@ -522,15 +424,13 @@ static void xshm_update_frame_format (vo
     lprintf ("updating frame to %d x %d\n",
 	     frame->sc.output_width, frame->sc.output_height);
 
-    LOCK_DISPLAY(this);
-
     /*
      * (re-) allocate XImage
      */
 
     if (frame->image) {
 
-      dispose_ximage (this, &frame->shminfo, frame->image);
+      dispose_ximage (this, frame);
 
       if (frame->chunk[0]){
 	free (frame->chunk[0]);
@@ -544,14 +444,9 @@ static void xshm_update_frame_format (vo
 	free (frame->chunk[2]);
 	frame->chunk[2] = NULL;
       }
-
-      frame->image = NULL;
     }
 
-    frame->image = create_ximage (this, &frame->shminfo,
-				  frame->sc.output_width, frame->sc.output_height);
-
-    UNLOCK_DISPLAY(this);
+    create_ximage (this, frame, frame->sc.output_width, frame->sc.output_height);
 
     if (format == XINE_IMGFMT_YV12) {
       frame->vo_frame.pitches[0] = 8*((width + 7) / 8);
@@ -584,8 +479,7 @@ static void xshm_update_frame_format (vo
 				 2*frame->vo_frame.pitches[1],
 				 frame->sc.output_width,
 				 frame->sc.output_height,
-				 frame->image->bytes_per_line*2);
-      frame->yuv_stride = frame->image->bytes_per_line*2;
+				 frame->bytes_per_line*2);
       break;
     case VO_BOTH_FIELDS:
       frame->yuv2rgb->configure (frame->yuv2rgb,
@@ -595,8 +489,7 @@ static void xshm_update_frame_format (vo
 				 frame->vo_frame.pitches[1],
 				 frame->sc.output_width,
 				 frame->sc.output_height,
-				 frame->image->bytes_per_line);
-      frame->yuv_stride = frame->image->bytes_per_line;
+				 frame->bytes_per_line);
       break;
     }
   }
@@ -634,11 +527,8 @@ static void xshm_overlay_begin (vo_drive
 
   this->ovl_changed += changed;
 
-  if( this->ovl_changed && this->xoverlay ) {
-    LOCK_DISPLAY(this);
-    x11osd_clear(this->xoverlay); 
-    UNLOCK_DISPLAY(this);
-  }
+  if( this->ovl_changed && this->xoverlay )
+    xcbosd_clear(this->xoverlay);
   
   this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x;
   this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y;
@@ -647,11 +537,8 @@ static void xshm_overlay_begin (vo_drive
 static void xshm_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) {
   xshm_driver_t  *this  = (xshm_driver_t *) this_gen;
 
-  if( this->ovl_changed && this->xoverlay ) {
-    LOCK_DISPLAY(this);
-    x11osd_expose(this->xoverlay);
-    UNLOCK_DISPLAY(this);
-  }
+  if( this->ovl_changed && this->xoverlay )
+    xcbosd_expose(this->xoverlay);
 
   this->ovl_changed = 0;
 }
@@ -664,30 +551,27 @@ static void xshm_overlay_blend (vo_drive
   /* Alpha Blend here */
   if (overlay->rle) {
     if( overlay->unscaled ) {
-      if( this->ovl_changed && this->xoverlay ) {
-        LOCK_DISPLAY(this);
-        x11osd_blend(this->xoverlay, overlay); 
-        UNLOCK_DISPLAY(this);
-      }
+      if( this->ovl_changed && this->xoverlay )
+        xcbosd_blend(this->xoverlay, overlay);
     } else {
       if (!overlay->rgb_clut || !overlay->hili_rgb_clut)
         xshm_overlay_clut_yuv2rgb (this, overlay, frame);
  
       switch (this->bpp) {
         case 16:
-         _x_blend_rgb16 ((uint8_t *)frame->image->data, overlay,
+         _x_blend_rgb16 (frame->image, overlay,
 		      frame->sc.output_width, frame->sc.output_height,
 		      frame->sc.delivered_width, frame->sc.delivered_height,
                       &this->alphablend_extra_data);
          break;
         case 24:
-         _x_blend_rgb24 ((uint8_t *)frame->image->data, overlay,
+         _x_blend_rgb24 (frame->image, overlay,
 		      frame->sc.output_width, frame->sc.output_height,
 		      frame->sc.delivered_width, frame->sc.delivered_height,
                       &this->alphablend_extra_data);
          break;
         case 32:
-         _x_blend_rgb32 ((uint8_t *)frame->image->data, overlay,
+         _x_blend_rgb32 (frame->image, overlay,
 		      frame->sc.output_width, frame->sc.output_height,
 		      frame->sc.delivered_width, frame->sc.delivered_height,
                       &this->alphablend_extra_data);
@@ -704,24 +588,27 @@ static void xshm_overlay_blend (vo_drive
 
 static void clean_output_area (xshm_driver_t *this, xshm_frame_t *frame) {
   int i;
+  xcb_rectangle_t rects[4];
+  int rects_count = 0;
   
   memcpy( this->sc.border, frame->sc.border, sizeof(this->sc.border) );
   
-  LOCK_DISPLAY(this);
-  XSetForeground (this->display, this->gc, this->black.pixel);
-  
   for( i = 0; i < 4; i++ ) {
     if( this->sc.border[i].w && this->sc.border[i].h )
-      XFillRectangle(this->display, this->drawable, this->gc,
-                     this->sc.border[i].x, this->sc.border[i].y,
-                     this->sc.border[i].w, this->sc.border[i].h);
+      rects[rects_count].x = frame->sc.border[i].x;
+      rects[rects_count].y = frame->sc.border[i].y;
+      rects[rects_count].width = frame->sc.border[i].w;
+      rects[rects_count].height = frame->sc.border[i].h;
+      rects_count++;
   }
+
+  if (rects_count > 0)
+    xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects);
+
   if (this->xoverlay) {
-    x11osd_resize (this->xoverlay, this->sc.gui_width, this->sc.gui_height);
+    xcbosd_resize (this->xoverlay, this->sc.gui_width, this->sc.gui_height);
     this->ovl_changed = 1;
   }
-  
-  UNLOCK_DISPLAY(this);
 }
 
 static int xshm_redraw_needed (vo_driver_t *this_gen) {
@@ -778,29 +665,26 @@ static void xshm_display_frame (vo_drive
   }
 
   this->cur_frame = frame;
-    
-  LOCK_DISPLAY(this);
-  lprintf ("display locked...\n");
   
-  if (this->use_shm) {
+  if (frame->shmseg) {
 
     lprintf ("put image (shm)\n");
-    XShmPutImage(this->display,
-                 this->drawable, this->gc, frame->image,
-                 0, 0, frame->sc.output_xoffset, frame->sc.output_yoffset,
-                 frame->sc.output_width, frame->sc.output_height, True);
+    xcb_shm_put_image(this->connection, this->window, this->gc, this->cur_frame->sc.output_width,
+                      this->cur_frame->sc.output_height, 0, 0, this->cur_frame->sc.output_width,
+                      this->cur_frame->sc.output_height, this->cur_frame->sc.output_xoffset,
+                      this->cur_frame->sc.output_yoffset, this->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
+                      0, this->cur_frame->shmseg, 0);
 
   } else {
 
     lprintf ("put image (plain/remote)\n");
-    XPutImage(this->display,
-              this->drawable, this->gc, frame->image,
-              0, 0, frame->sc.output_xoffset, frame->sc.output_yoffset,
-              frame->sc.output_width, frame->sc.output_height);
+    xcb_put_image(this->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, this->window, this->gc,
+                  frame->sc.output_width, frame->sc.output_height, frame->sc.output_xoffset, frame->sc.output_yoffset,
+                  0, this->depth, frame->bytes_per_line * frame->sc.output_height, frame->image);
 
   }
-  XSync(this->display, False);
-  UNLOCK_DISPLAY(this);
+
+  xcb_flush(this->connection);
 
   lprintf ("display frame done\n");
 }
@@ -915,54 +799,55 @@ static int xshm_gui_data_exchange (vo_dr
     lprintf ("expose event\n");
 
     if (this->cur_frame) {
-      XExposeEvent * xev = (XExposeEvent *) data;
+      xcb_expose_event_t *xev = (xcb_expose_event_t *) data;
       
       if (xev && xev->count == 0) {
 	int i;
+	xcb_rectangle_t rects[4];
+	int rects_count = 0;
 	
-	LOCK_DISPLAY(this);
-	if (this->use_shm) {
-	  XShmPutImage(this->display,
-		       this->drawable, this->gc, this->cur_frame->image,
-		       0, 0, this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset,
-		       this->cur_frame->sc.output_width, this->cur_frame->sc.output_height,
-		       False);
-	}
-	else {
-	  XPutImage(this->display, 
-		    this->drawable, this->gc, this->cur_frame->image,
-		    0, 0, this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset,
-		    this->cur_frame->sc.output_width, this->cur_frame->sc.output_height);
-	}
-
-	XSetForeground (this->display, this->gc, this->black.pixel);
+	if (this->cur_frame->shmseg)
+	  xcb_shm_put_image(this->connection, this->window, this->gc, this->cur_frame->sc.output_width,
+			    this->cur_frame->sc.output_height, 0, 0, this->cur_frame->sc.output_width,
+			    this->cur_frame->sc.output_height, this->cur_frame->sc.output_xoffset,
+			    this->cur_frame->sc.output_yoffset, this->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
+			    0, this->cur_frame->shmseg, 0);
+	else
+	  xcb_put_image(this->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, this->window, this->gc,
+			this->cur_frame->sc.output_width, this->cur_frame->sc.output_height,
+			this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset,
+			0, this->depth, this->cur_frame->bytes_per_line * this->cur_frame->sc.output_height,
+			this->cur_frame->image);
 
 	for( i = 0; i < 4; i++ ) {
 	  if( this->sc.border[i].w && this->sc.border[i].h )
-	    XFillRectangle(this->display, this->drawable, this->gc,
-			   this->sc.border[i].x, this->sc.border[i].y,
-			   this->sc.border[i].w, this->sc.border[i].h);
+	    rects[rects_count].x = this->sc.border[i].x;
+	    rects[rects_count].y = this->sc.border[i].y;
+	    rects[rects_count].width = this->sc.border[i].w;
+	    rects[rects_count].height = this->sc.border[i].h;
+	    rects_count++;
 	}
 
+	if (rects_count > 0)
+	  xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects);
+
         if(this->xoverlay)
-          x11osd_expose(this->xoverlay);
+          xcbosd_expose(this->xoverlay);
 
-	XSync(this->display, False);
-	UNLOCK_DISPLAY(this);
+	xcb_flush(this->connection);
       }
     }
   break;
   
   case XINE_GUI_SEND_DRAWABLE_CHANGED:
-    this->drawable = (Drawable) data;
+    this->window = (xcb_window_t) data;
 
-    LOCK_DISPLAY(this);
-    XFreeGC(this->display, this->gc);
-    this->gc = XCreateGC (this->display, this->drawable, 0, NULL);
+    xcb_free_gc(this->connection, this->gc);
+    this->gc = xcb_generate_id(this->connection);
+    xcb_create_gc(this->connection, this->gc, this->window, XCB_GC_FOREGROUND, &this->screen->black_pixel);
     if(this->xoverlay)
-      x11osd_drawable_changed(this->xoverlay, this->drawable);
+      xcbosd_drawable_changed(this->xoverlay, this->window);
     this->ovl_changed = 1;
-    UNLOCK_DISPLAY(this);
   break;
 
   case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO:
@@ -999,90 +884,104 @@ static void xshm_dispose (vo_driver_t *t
 
   this->yuv2rgb_factory->dispose (this->yuv2rgb_factory);
   
-  LOCK_DISPLAY(this);
-  XFreeGC(this->display, this->gc);
-  UNLOCK_DISPLAY(this);
+  xcb_free_gc(this->connection, this->gc);
   
-  if( this->xoverlay ) {
-    LOCK_DISPLAY(this);
-    x11osd_destroy (this->xoverlay);
-    UNLOCK_DISPLAY(this);
-  }
+  if( this->xoverlay )
+    xcbosd_destroy (this->xoverlay);
 
   _x_alphablend_free(&this->alphablend_extra_data);
   
   free (this);
 }
 
-/* called xlocked */
 static int ImlibPaletteLUTGet(xshm_driver_t *this) {
-  unsigned char      *retval;
-  Atom                type_ret;
-  unsigned long       bytes_after, num_ret;
-  int                 format_ret;
-  long                length;
-  Atom                to_get;
-  
-  retval = NULL;
-  length = 0x7fffffff;
-  to_get = XInternAtom(this->display, "_IMLIB_COLORMAP", False);
-  XGetWindowProperty(this->display, RootWindow(this->display, this->screen),
-		     to_get, 0, length, False,
-		     XA_CARDINAL, &type_ret, &format_ret, &num_ret,
-		     &bytes_after, &retval);
-  if (retval != 0 && num_ret > 0 && format_ret > 0) {
-    if (format_ret == 8) {
-      unsigned int i;
-      unsigned long j;
-	  
-      j = 1 + retval[0]*4;
-      this->yuv2rgb_cmap = malloc(sizeof(uint8_t) * 32 * 32 * 32);
-      for (i = 0; i < 32 * 32 * 32 && j < num_ret; i++)
-	this->yuv2rgb_cmap[i] = retval[1+4*retval[j++]+3];
+  static const xcb_atom_t CARDINAL = 6;
 
-      XFree(retval);
-      return 1;
-    } else
-      XFree(retval);
+  xcb_generic_error_t *generic_error = NULL;
+
+  xcb_intern_atom_cookie_t atom_cookie;
+  xcb_intern_atom_reply_t *atom_reply;
+
+  xcb_get_property_cookie_t prop_cookie;
+  xcb_get_property_reply_t *prop_reply;
+
+  atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("_IMLIB_COLORMAP"), "_IMLIB_COLORMAP");
+  atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, &generic_error);
+
+  if ((generic_error != NULL) || (atom_reply == NULL)) {
+    free(generic_error);
+    return 0;
+  }
+
+  prop_cookie = xcb_get_property(this->connection, 0, this->window, atom_reply->atom, CARDINAL, 0, 0x7fffffff);
+  prop_reply = xcb_get_property_reply(this->connection, prop_cookie, &generic_error);
+
+  free(atom_reply);
+
+  if ((generic_error != NULL) || (prop_reply == NULL)) {
+    free(generic_error);
+    return 0;
   }
+
+  if (prop_reply->format == 8) {
+    unsigned int i;
+    unsigned long j;
+    int num_ret = xcb_get_property_value_length(prop_reply);
+    char *retval = xcb_get_property_value(prop_reply);
+
+    j = 1 + retval[0]*4;
+
+    this->yuv2rgb_cmap = malloc(sizeof(uint8_t) * 32 * 32 * 32);
+    for (i = 0; i < 32 * 32 * 32 && j < num_ret; i++)
+			this->yuv2rgb_cmap[i] = retval[1 + 4 * retval[j++] + 3];
+      free(prop_reply);
+    return 1;
+  }
+
+  free(prop_reply);
   return 0;
 }
 
 
-static char *visual_class_name(Visual *visual) {
+static char *visual_class_name(xcb_visualtype_t *visual) {
 
-  switch (visual->class) {
-  case StaticGray:
+  switch (visual->_class) {
+  case XCB_VISUAL_CLASS_STATIC_GRAY:
     return "StaticGray";
-  case GrayScale:
+  case XCB_VISUAL_CLASS_GRAY_SCALE:
     return "GrayScale";
-  case StaticColor:
+  case XCB_VISUAL_CLASS_STATIC_COLOR:
     return "StaticColor";
-  case PseudoColor:
+  case XCB_VISUAL_CLASS_PSEUDO_COLOR:
     return "PseudoColor";
-  case TrueColor:
+  case XCB_VISUAL_CLASS_TRUE_COLOR:
     return "TrueColor";
-  case DirectColor:
+  case XCB_VISUAL_CLASS_DIRECT_COLOR:
     return "DirectColor";
   default:
     return "unknown visual class";
   }
 }
 
-/* expects XINE_VISUAL_TYPE_X11_2 with configurable locking */
-static vo_driver_t *xshm_open_plugin_2 (video_driver_class_t *class_gen, const void *visual_gen) {
+static vo_driver_t *xshm_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) {
   xshm_class_t         *class   = (xshm_class_t *) class_gen;
   config_values_t      *config  = class->config;
-  x11_visual_t         *visual  = (x11_visual_t *) visual_gen;
+  xcb_visual_t         *visual  = (xcb_visual_t *) visual_gen;
   xshm_driver_t        *this;
-  XWindowAttributes     attribs;
-  XImage               *myimage;
-  XShmSegmentInfo       myshminfo;
+  xcb_visualtype_t     *visualtype;
   int                   mode;
   int			swapped;
   int			cpu_byte_order;
-  XColor                dummy;
+  int			image_byte_order;
   
+  xcb_get_window_attributes_cookie_t window_attrs_cookie;
+  xcb_get_window_attributes_reply_t *window_attrs_reply;
+
+  xcb_get_geometry_cookie_t geometry_cookie;
+  xcb_get_geometry_reply_t *geometry_reply;
+
+  const xcb_query_extension_reply_t *query_extension_reply;
+
   this = (xshm_driver_t *) xine_xmalloc (sizeof (xshm_driver_t));
 
   if (!this)
@@ -1090,13 +989,9 @@ static vo_driver_t *xshm_open_plugin_2 (
 
   _x_alphablend_init(&this->alphablend_extra_data, class->xine);
   
-  this->display		    = visual->display;
-  this->screen		    = visual->screen;
-
-  /* configurable X11 locking */
-  this->lock_display        = visual->lock_display;
-  this->unlock_display      = visual->unlock_display;
-  this->user_data           = visual->user_data;
+  this->connection          = visual->connection;
+  this->screen              = visual->screen;
+  this->window              = visual->window;
 
   _x_vo_scale_init( &this->sc, 0, 0, config );
   this->sc.frame_output_cb  = visual->frame_output_cb;
@@ -1104,17 +999,13 @@ static vo_driver_t *xshm_open_plugin_2 (
   this->sc.user_data        = visual->user_data;
   
   this->sc.user_ratio       = XINE_VO_ASPECT_AUTO;
-  
-  this->drawable	    = visual->d;
   this->cur_frame           = NULL;
-  LOCK_DISPLAY(this);
-  this->gc		    = XCreateGC (this->display, this->drawable, 0, NULL);
-  UNLOCK_DISPLAY(this);
-  this->xoverlay                = NULL;
-  this->ovl_changed             = 0;
+  this->gc                  = xcb_generate_id(this->connection);
+  xcb_create_gc(this->connection, this->gc, this->window, XCB_GC_FOREGROUND, &this->screen->black_pixel);
+  this->xoverlay            = NULL;
+  this->ovl_changed         = 0;
  
-  this->x11_old_error_handler = NULL;
-  this->xine                  = class->xine;
+  this->xine                = class->xine;
 
   this->vo_driver.get_capabilities     = xshm_get_capabilities;
   this->vo_driver.alloc_frame          = xshm_alloc_frame;
@@ -1130,11 +1021,6 @@ static vo_driver_t *xshm_open_plugin_2 (
   this->vo_driver.dispose              = xshm_dispose;
   this->vo_driver.redraw_needed        = xshm_redraw_needed;
   
-  LOCK_DISPLAY(this);
-  XAllocNamedColor (this->display,
-		    DefaultColormap (this->display, this->screen),
-		    "black", &this->black, &dummy);
-
   /*
    *
    * depth in X11 terminology land is the number of bits used to
@@ -1147,11 +1033,33 @@ static vo_driver_t *xshm_open_plugin_2 (
    *     color is 24 bit depth, but can be 24 bpp or 32 bpp.
    */
 
-  XGetWindowAttributes(this->display, this->drawable, &attribs);
-  UNLOCK_DISPLAY(this);
-  this->visual = attribs.visual;
-  this->depth  = attribs.depth;
-  
+  window_attrs_cookie = xcb_get_window_attributes(this->connection, this->window);
+  geometry_cookie = xcb_get_geometry(this->connection, this->window);
+  xcb_prefetch_extension_data(this->connection, &xcb_shm_id);
+
+  window_attrs_reply = xcb_get_window_attributes_reply(this->connection, window_attrs_cookie, NULL);
+
+  visualtype = NULL;
+  {
+    xcb_depth_t *depth = xcb_screen_allowed_depths_iterator(this->screen).data;
+    xcb_visualtype_iterator_t iter = xcb_depth_visuals_iterator(depth);
+    int cur;
+
+    for (cur = 0; cur < iter.rem; xcb_visualtype_next(&iter), ++cur)
+      if (window_attrs_reply->visual == iter.data->visual_id) {
+        visualtype = iter.data;
+        break;
+      }
+  }
+
+  free(window_attrs_reply);
+
+  geometry_reply = xcb_get_geometry_reply(this->connection, geometry_cookie, NULL);
+
+  this->depth = geometry_reply->depth;
+
+  free(geometry_reply);
+
   if (this->depth>16)
     xprintf(this->xine, XINE_VERBOSITY_LOG,
 	    _("\n\nWARNING: current display depth is %d. For better performance\n"
@@ -1161,8 +1069,8 @@ static vo_driver_t *xshm_open_plugin_2 (
    * check for X shared memory support
    */
 
-  LOCK_DISPLAY(this);
-  if (XShmQueryExtension(this->display)) {
+  query_extension_reply = xcb_get_extension_data(this->connection, &xcb_shm_id);
+  if (query_extension_reply && query_extension_reply->present) {
     this->use_shm = 1;
   } 
   else {
@@ -1171,63 +1079,80 @@ static vo_driver_t *xshm_open_plugin_2 (
     this->use_shm = 0;
   }
 
-  /*
-   * try to create a shared image
-   * to find out if MIT shm really works
-   * and what bpp it uses
-   */
+  {
+    const xcb_setup_t *setup = xcb_get_setup(this->connection);
+    xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+    xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
 
-  myimage = create_ximage (this, &myshminfo, 100, 100);
-  dispose_ximage (this, &myshminfo, myimage);
-  UNLOCK_DISPLAY(this);
+    for(; fmt != fmtend; ++fmt)
+      if(fmt->depth == this->depth) {
+        this->bpp = fmt->bits_per_pixel;
+        this->scanline_pad = fmt->scanline_pad;
+        break;
+    }
+
+    if (fmt == fmtend) {
+      if (this->depth <= 4)
+        this->bpp = 4;
+      else if (this->depth <= 8)
+        this->bpp = 8;
+      else if (this->depth <= 16)
+        this->bpp = 16;
+      else
+        this->bpp = 32;
+      this->scanline_pad = setup->bitmap_format_scanline_pad;
+    }
+
+    image_byte_order = setup->image_byte_order;
+  }
 
   /*
    * Is the same byte order in use on the X11 client and server?
    */
-  cpu_byte_order = htonl(1) == 1 ? MSBFirst : LSBFirst;
-  swapped = cpu_byte_order != this->image_byte_order;
+  cpu_byte_order = htonl(1) == 1 ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST;
+  swapped = cpu_byte_order != image_byte_order;
   
   xprintf(this->xine, XINE_VERBOSITY_DEBUG,
 	  "video_out_xshm: video mode depth is %d (%d bpp), %s, %sswapped,\n"
-	  "\tred: %08lx, green: %08lx, blue: %08lx\n",
+	  "\tred: %08x, green: %08x, blue: %08x\n",
 	  this->depth, this->bpp,
-	  visual_class_name(this->visual),
+	  visual_class_name(visualtype),
 	  swapped ? "" : "not ",
-	  this->visual->red_mask, this->visual->green_mask, this->visual->blue_mask);
+	  visualtype->red_mask, visualtype->green_mask, visualtype->blue_mask);
 
   mode = 0;
 
-  switch (this->visual->class) {
-  case TrueColor:
+  switch (visualtype->_class) {
+  case XCB_VISUAL_CLASS_TRUE_COLOR:
     switch (this->depth) {
     case 24:
     case 32:
       if (this->bpp == 32) {
-	if (this->visual->red_mask == 0x00ff0000)
+	if (visualtype->red_mask == 0x00ff0000)
 	  mode = MODE_32_RGB;
 	else
 	  mode = MODE_32_BGR;
       } else {
-	if (this->visual->red_mask == 0x00ff0000)
+	if (visualtype->red_mask == 0x00ff0000)
 	  mode = MODE_24_RGB;
 	else
 	  mode = MODE_24_BGR;
       }
       break;
     case 16:
-      if (this->visual->red_mask == 0xf800)
+	if (visualtype->red_mask == 0xf800)
 	mode = MODE_16_RGB;
       else
 	mode = MODE_16_BGR;
       break;
     case 15:
-      if (this->visual->red_mask == 0x7C00)
+	if (visualtype->red_mask == 0x7C00)
 	mode = MODE_15_RGB;
       else
 	mode = MODE_15_BGR;
       break;
     case 8:
-      if (this->visual->red_mask == 0xE0)
+	if (visualtype->red_mask == 0xE0)
 	mode = MODE_8_RGB; /* Solaris x86: RGB332 */
       else
 	mode = MODE_8_BGR; /* XFree86: BGR233 */
@@ -1235,17 +1160,15 @@ static vo_driver_t *xshm_open_plugin_2 (
     }
     break;
 
-  case StaticGray:
+  case XCB_VISUAL_CLASS_STATIC_GRAY:
     if (this->depth == 8)
       mode = MODE_8_GRAY;
     break;
 
-  case PseudoColor:
-  case GrayScale:
-    LOCK_DISPLAY(this);
+  case XCB_VISUAL_CLASS_PSEUDO_COLOR:
+  case XCB_VISUAL_CLASS_GRAY_SCALE:
     if (this->depth <= 8 && ImlibPaletteLUTGet(this))
       mode = MODE_PALETTE;
-    UNLOCK_DISPLAY(this);
     break;
   }
 
@@ -1255,8 +1178,6 @@ static vo_driver_t *xshm_open_plugin_2 (
     return NULL;
   }
   
-  this->yuv2rgb_mode  = mode;
-  this->yuv2rgb_swap  = swapped;
   this->yuv2rgb_brightness = 0;
   this->yuv2rgb_contrast   = 128;
   this->yuv2rgb_saturation = 128;
@@ -1268,31 +1189,12 @@ static vo_driver_t *xshm_open_plugin_2 (
 					 this->yuv2rgb_contrast,
 					 this->yuv2rgb_saturation);
 
-  LOCK_DISPLAY(this);
-  this->xoverlay = x11osd_create (this->xine, this->display, this->screen,
-                                  this->drawable, X11OSD_SHAPED);
-  UNLOCK_DISPLAY(this);
+  this->xoverlay = xcbosd_create (this->xine, this->connection, this->screen,
+                                  this->window, XCBOSD_SHAPED);
 
   return &this->vo_driver;
 }
 
-static vo_driver_t *xshm_open_plugin_old (video_driver_class_t *class_gen, const void *visual_gen) {
-  x11_visual_t         *old_visual  = (x11_visual_t *) visual_gen;
-  x11_visual_t         visual;
-
-  /* provides compatibility for XINE_VISUAL_TYPE_X11 */
-  visual.display         = old_visual->display;
-  visual.screen          = old_visual->screen;
-  visual.d               = old_visual->d;
-  visual.user_data       = old_visual->user_data;
-  visual.dest_size_cb    = old_visual->dest_size_cb;
-  visual.frame_output_cb = old_visual->frame_output_cb;
-  visual.lock_display    = NULL;
-  visual.unlock_display  = NULL;
-  
-  return xshm_open_plugin_2(class_gen, (void *)&visual);
-}
-
 /*
  * class functions
  */
@@ -1314,7 +1216,7 @@ static void xshm_dispose_class (video_dr
 static void *xshm_init_class (xine_t *xine, void *visual_gen) {
   xshm_class_t	       *this = (xshm_class_t *) xine_xmalloc (sizeof (xshm_class_t));
 
-  this->driver_class.open_plugin     = xshm_open_plugin_old;
+  this->driver_class.open_plugin     = xshm_open_plugin;
   this->driver_class.get_identifier  = xshm_get_identifier;
   this->driver_class.get_description = xshm_get_description;
   this->driver_class.dispose         = xshm_dispose_class;
@@ -1324,23 +1226,10 @@ static void *xshm_init_class (xine_t *xi
   return this;
 }
 
-static void *xshm_init_class_2 (xine_t *xine, void *visual_gen) {
-  xshm_class_t	       *this;
-  this = xshm_init_class (xine, visual_gen);
-  this->driver_class.open_plugin     = xshm_open_plugin_2;
-  return this;
-}
-
 
 static const vo_info_t vo_info_xshm = {
   6,                      /* priority    */
-  XINE_VISUAL_TYPE_X11    /* visual type */
-};
-
-/* visual type with configurable X11 locking */
-static const vo_info_t vo_info_xshm_2 = {
-  6,                      /* priority    */
-  XINE_VISUAL_TYPE_X11_2  /* visual type */
+  XINE_VISUAL_TYPE_XCB    /* visual type */
 };
 
 
@@ -1351,6 +1240,5 @@ static const vo_info_t vo_info_xshm_2 = 
 const plugin_info_t xine_plugin_info[] EXPORTED = {
   /* type, API, "name", version, special_info, init_function */  
   { PLUGIN_VIDEO_OUT, 21, "xshm", XINE_VERSION_CODE, &vo_info_xshm, xshm_init_class },
-  { PLUGIN_VIDEO_OUT, 21, "xshm", XINE_VERSION_CODE, &vo_info_xshm_2, xshm_init_class_2 },
   { PLUGIN_NONE, 0, "", 0, NULL, NULL }
 };
diff -dNpru xine-lib/src/video_out/xcbosd.h xine-lib-xcb/src/video_out/xcbosd.h
--- xine-lib/src/video_out/xcbosd.h	1970-01-01 01:00:00.000000000 +0100
+++ xine-lib-xcb/src/video_out/xcbosd.h	2006-12-10 19:12:02.000000000 +0100
@@ -0,0 +1,54 @@
+/* 
+ * Copyright (C) 2003 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+ *
+ * $Id: xcbosd.h,v 1.4 2004/04/10 15:31:10 miguelfreitas Exp $
+ *
+ * xcbosd.h, use XCB Nonrectangular Window Shape Extension to draw xine OSD
+ *
+ * Nov 2003 - Miguel Freitas
+ *
+ * based on ideas and code of
+ * xosd Copyright (c) 2000 Andre Renaud (andre at ignavus.net)
+ */
+
+#ifndef XCBOSD_H
+#define XCBOSD_H
+
+#include "vo_scale.h"
+
+typedef struct xcbosd xcbosd;
+enum xcbosd_mode {XCBOSD_SHAPED, XCBOSD_COLORKEY};
+
+xcbosd *xcbosd_create (xine_t *xine, xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window, enum xcbosd_mode mode) { return NULL; }
+
+void xcbosd_colorkey(xcbosd * osd, uint32_t colorkey, vo_scale_t *scaling) { }
+
+void xcbosd_destroy (xcbosd * osd) { }
+
+void xcbosd_expose (xcbosd * osd) { }
+
+void xcbosd_resize (xcbosd * osd, int width, int height) { }
+
+void xcbosd_drawable_changed (xcbosd * osd, xcb_window_t window) { }
+
+void xcbosd_clear(xcbosd *osd) { }
+
+void xcbosd_blend(xcbosd *osd, vo_overlay_t *overlay) { }
+
+#endif
-------------- next part --------------
diff -dNpru multimedia-xcb-original/kaffeine/src/main.cpp multimedia-xcb/kaffeine/src/main.cpp
--- multimedia-xcb-original/kaffeine/src/main.cpp	2006-12-10 20:49:21.000000000 +0100
+++ multimedia-xcb/kaffeine/src/main.cpp	2006-12-10 20:49:38.000000000 +0100
@@ -30,9 +30,6 @@
 #include "kaffeine.h"
 #include "version.h"
 
-/* including the Xlib header pollutes namespace too much --pfister */
-extern "C" int XInitThreads();
-
 class KaffeineApp : public KUniqueApplication
 {
 public:
@@ -92,23 +89,6 @@ int main(int argc, char *argv[])
 	if (!KaffeineApp::start())
 		return 0;
 
-	/*
-	 * XInitThreads() should the first call to xlib in multithreaded X programs -
-	 * but because of a bug in some xfree versions that can freeze at startup,
-	 * we also call XInitThreads() in kxinewidget.cpp
-	 *
-	 * kaffeinepart & konqueror: We call XInitThreads() in kxinewidget.cpp, so the part is
-	 * not stable with buggy X implementations.
-	 *
-	 * FIXME: deadline for this workaround is 2007-03-16 --pfister
-	 */
-
-#ifndef XINIT_WKRND /* configure flag --with-xinit-workaround not set */
-	flush(kdDebug() << "if kaffeine hangs here run 'configure --with-xinit-workaround' and recompile / reinstall ...");
-	XInitThreads();
-	kdDebug() << " ok\n";
-#endif
-
 	KaffeineApp a;
 	return a.exec();
 }
diff -dNpru multimedia-xcb-original/kaffeine/src/player-parts/xine-part/kxinewidget.cpp multimedia-xcb/kaffeine/src/player-parts/xine-part/kxinewidget.cpp
--- multimedia-xcb-original/kaffeine/src/player-parts/xine-part/kxinewidget.cpp	2006-12-10 20:49:21.000000000 +0100
+++ multimedia-xcb/kaffeine/src/player-parts/xine-part/kxinewidget.cpp	2006-12-10 20:49:38.000000000 +0100
@@ -38,10 +38,6 @@
 
 #include "kxinewidget.h"
 
-#ifdef HAVE_XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
-
 #ifndef USE_QT_ONLY
 #include "kxinewidget.moc"
 #include <klocale.h>
@@ -68,7 +64,7 @@ KXineWidget::KXineWidget(QWidget* parent
                          bool startManual, bool verbose)
 		: QWidget(parent,name), m_startXineManual(startManual), m_xineReady(false),
 		m_logoFile(pathToLogoFile), m_preferedAudio(audioDriver), m_preferedVideo(videoDriver), m_xineVerbose(verbose),
-		m_xineEngine(NULL), m_audioDriver(NULL), m_videoDriver(NULL), m_xineStream(NULL), m_xineDisplay(NULL),
+		m_xineEngine(NULL), m_audioDriver(NULL), m_videoDriver(NULL), m_xineStream(NULL), connection(NULL),
 		m_eventQueue(NULL), m_osd(NULL), m_osdUnscaled(false), m_osdShow(false), m_osdSize(0), m_osdFont(NULL),
 		m_audioChoices(NULL), m_audioInfo(NULL), m_videoChoices(NULL), m_videoInfo(NULL), m_mixerInfo(NULL),
 		m_osdShowInfo(NULL),
@@ -239,12 +235,12 @@ KXineWidget::~KXineWidget()
 		delete [] m_audioChoices;
 	}
 
-	if (m_xineDisplay)
+	if (connection)
 	{
 		debugOut("Close xine display");
-		XCloseDisplay(m_xineDisplay);  /* close xine display */
+		xcb_disconnect(connection);  /* close xine display */
 	}
-	m_xineDisplay = NULL;
+	connection = NULL;
 
 	debugOut("xine closed");
 }
@@ -831,7 +827,7 @@ void KXineWidget::videoDriverChangedCall
 	xine_close_video_driver(vw->m_xineEngine, oldVideoDriver);
 
 	vw->m_videoDriver = xine_open_video_driver(vw->m_xineEngine,
-	                    entry->enum_values[entry->num_value], XINE_VISUAL_TYPE_X11,
+	                    entry->enum_values[entry->num_value], XINE_VISUAL_TYPE_XCB,
 	                    (void *) &(vw->m_x11Visual));
 
 	if (!vw->m_videoDriver)
@@ -840,7 +836,7 @@ void KXineWidget::videoDriverChangedCall
 		QApplication::postEvent(vw, new QTimerEvent( TIMER_EVENT_NEW_XINE_ERROR));
 		playing = false;
 		vw->m_videoDriver = xine_open_video_driver(vw->m_xineEngine,
-		                    vw->m_videoDriverName.ascii(), XINE_VISUAL_TYPE_X11,
+		                    vw->m_videoDriverName.ascii(), XINE_VISUAL_TYPE_XCB,
 		                    (void *) &(vw->m_x11Visual));
 	}
 	else
@@ -1012,11 +1008,13 @@ void KXineWidget::fontForOSDMessagesChan
  *      EVENT LOOP
  *********************************************/
 
-bool KXineWidget::x11Event(XEvent *event)
+bool KXineWidget::x11Event(XEvent *_event)
 {
+	xcb_expose_event_t *event = (xcb_expose_event_t *) _event;
+
 	if (isXineReady())
-		if (event->type == Expose)
-			if (event->xexpose.count == 0)
+		if (event->response_type == XCB_EXPOSE)
+			if (event->count == 0)
 				xine_port_send_gui_data(m_videoDriver, XINE_GUI_SEND_EXPOSE_EVENT, event);
 
 	return false;
@@ -1044,39 +1042,18 @@ bool KXineWidget::initXine()
 
 	/**** INIT XINE DISPLAY  ****/
 
-	XInitThreads();
-
-	m_xineDisplay = XOpenDisplay( getenv("DISPLAY") );
+	int screen;
+	connection = xcb_connect(NULL, &screen);
 
-	if (!m_xineDisplay)
+	if (!connection)
 	{
 		emit signalXineFatal(i18n("Failed to connect to X-Server!"));
 		return false;
 	}
 
-	int m_xineScreen = DefaultScreen(m_xineDisplay);
-	Window m_xineWindow = winId();
-
-	/* determine display aspect ratio  */
-	double resHor = ((double) DisplayWidth(m_xineDisplay, m_xineScreen)) / DisplayWidthMM(m_xineDisplay, m_xineScreen);
-	double resVer = ((double) DisplayHeight(m_xineDisplay, m_xineScreen)) / DisplayHeightMM(m_xineDisplay, m_xineScreen);
-
-	m_displayRatio = resVer / resHor;
-
-#ifdef HAVE_XINERAMA
-	int dummy_event, dummy_error;
+	int m_xineWindow = winId();
 
-	if (XineramaQueryExtension(m_xineDisplay, &dummy_event, &dummy_error))
-	{
-		int count = 1;
-		debugOut("Xinerama extension present");
-		XineramaQueryScreens(m_xineDisplay, &count);
-		debugOut(QString("%1 screens detected").arg(count));
-		if (count > 1)
-			/* multihead -> assuming square pixels */
-			m_displayRatio = 1.0;
-	}
-#endif
+	m_displayRatio = 1.0;
 
 	debugOut(QString("Display aspect ratio (v/h): %1").arg(m_displayRatio));
 
@@ -1188,15 +1165,15 @@ bool KXineWidget::initXine()
 	/* init video driver */
 	debugOut("Init video driver");
 
-	m_x11Visual.display          = m_xineDisplay;
-	m_x11Visual.screen           = m_xineScreen;
-	m_x11Visual.d                = m_xineWindow;
+	m_x11Visual.connection       = connection;
+	m_x11Visual.screen           = xcb_setup_roots_iterator(xcb_get_setup(connection)).data;
+	m_x11Visual.window           = m_xineWindow;
 	m_x11Visual.dest_size_cb     = &KXineWidget::destSizeCallback;
 	m_x11Visual.frame_output_cb  = &KXineWidget::frameOutputCallback;
 	m_x11Visual.user_data        = (void*)this;
 
 	m_videoDriver = xine_open_video_driver(m_xineEngine,
-	                                       m_videoDriverName.ascii(),  XINE_VISUAL_TYPE_X11,
+	                                       m_videoDriverName.ascii(),  XINE_VISUAL_TYPE_XCB,
 	                                       (void *) &(m_x11Visual));
 
 	if (!m_videoDriver && m_videoDriverName != "auto")
@@ -1204,7 +1181,7 @@ bool KXineWidget::initXine()
 		emit signalXineError(i18n("Can't init Video Driver '%1' - trying 'auto'...").arg(m_videoDriverName));
 		m_videoDriverName = "auto";
 		m_videoDriver = xine_open_video_driver(m_xineEngine,
-		                                       m_videoDriverName.ascii(),  XINE_VISUAL_TYPE_X11,
+		                                       m_videoDriverName.ascii(), XINE_VISUAL_TYPE_XCB,
 		                                       (void *) &(m_x11Visual));
 	}
 
diff -dNpru multimedia-xcb-original/kaffeine/src/player-parts/xine-part/kxinewidget.h multimedia-xcb/kaffeine/src/player-parts/xine-part/kxinewidget.h
--- multimedia-xcb-original/kaffeine/src/player-parts/xine-part/kxinewidget.h	2006-12-10 20:49:21.000000000 +0100
+++ multimedia-xcb/kaffeine/src/player-parts/xine-part/kxinewidget.h	2006-12-10 20:49:38.000000000 +0100
@@ -48,7 +48,6 @@ class QTime;
 
 #include <qtimer.h>
 #include <qptrlist.h>
-#include <X11/Xlib.h>
 #include <xine.h>
 
 #ifndef USE_QT_ONLY
@@ -57,6 +56,8 @@ class QTime;
 typedef int PostFilter; /* dummy type */
 #endif
 
+#include <xcb/xcb.h>
+
 #define SUPPORTED_PROTOCOLS "file,http,mms,mmst,rtsp,rtp,tcp,pnm,cdda,vcd,vcdo,dvd,dvb,pvr,v4l,net,vdr,smb"
 
 #define DEFAULT_TVTIME_CONFIG "tvtime:method=LinearBlend,enabled=1,pulldown=none,framerate_mode=half_top,judder_correction=0,use_progressive_frame_flag=1,chroma_filter=0,cheap_mode=1"
@@ -363,10 +364,10 @@ protected:
 	QStringList m_videoDriverList;
 
 	/*x11*/
-	Display* m_xineDisplay;
+	xcb_connection_t* connection;
 
 	/*xine*/
-	x11_visual_t m_x11Visual;
+	xcb_visual_t m_x11Visual;
 	xine_t* m_xineEngine;
 	xine_audio_port_t* m_audioDriver;
 	xine_video_port_t* m_videoDriver;
diff -dNpru multimedia-xcb-original/kaffeine/src/player-parts/xine-part/Makefile.am multimedia-xcb/kaffeine/src/player-parts/xine-part/Makefile.am
--- multimedia-xcb-original/kaffeine/src/player-parts/xine-part/Makefile.am	2006-12-10 20:49:21.000000000 +0100
+++ multimedia-xcb/kaffeine/src/player-parts/xine-part/Makefile.am	2006-12-10 20:49:38.000000000 +0100
@@ -13,7 +13,7 @@ noinst_HEADERS =  xine_part_iface.h kxin
 libxinepart_la_SOURCES = xine_part.cpp kxinewidget.cpp postfilter.cpp deinterlacequality.cpp \
                              videosettings.cpp filterdialog.cpp screenshotpreview.cpp xineconfig.cpp positionslider.cpp \
                              equalizer.cpp xine_part_iface.skel
-libxinepart_la_LIBADD  = $(LIB_XINERAMA) $(LIB_XINE) ../kaffeine-part/libkaffeinepart.la
+libxinepart_la_LIBADD  = $(LIB_XINERAMA) $(LIB_XINE) ../kaffeine-part/libkaffeinepart.la -lxcb
 libxinepart_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) -avoid-version -no-undefined
 
 


More information about the Xcb mailing list