]> git.sesse.net Git - vlc/blobdiff - modules/access/screen/xcb.c
Dead code
[vlc] / modules / access / screen / xcb.c
index 8f0b67c56424f8c34f43499af8d01497b5aa9ea7..1e2314f963c4dfa0463fd350f3c5cd379385fe28 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdarg.h>
 #include <assert.h>
 #include <xcb/xcb.h>
+#include <xcb/composite.h>
 #include <vlc_common.h>
 #include <vlc_demux.h>
 #include <vlc_plugin.h>
@@ -79,13 +80,13 @@ vlc_module_begin ()
     add_integer ("screen-left", 0, LEFT_TEXT, LEFT_LONGTEXT, true)
         change_integer_range (-32768, 32767)
         change_safe ()
-    add_integer ("screen-top", 0, LEFT_TEXT, LEFT_LONGTEXT, true)
+    add_integer ("screen-top", 0, TOP_TEXT, TOP_LONGTEXT, true)
         change_integer_range (-32768, 32767)
         change_safe ()
-    add_integer ("screen-width", 0, LEFT_TEXT, LEFT_LONGTEXT, true)
+    add_integer ("screen-width", 0, WIDTH_TEXT, WIDTH_LONGTEXT, true)
         change_integer_range (0, 65535)
         change_safe ()
-    add_integer ("screen-height", 0, LEFT_TEXT, LEFT_LONGTEXT, true)
+    add_integer ("screen-height", 0, HEIGHT_TEXT, HEIGHT_LONGTEXT, true)
         change_integer_range (0, 65535)
         change_safe ()
     add_bool ("screen-follow-mouse", false, FOLLOW_MOUSE_TEXT,
@@ -104,17 +105,17 @@ static es_out_id_t *InitES (demux_t *, uint_fast16_t, uint_fast16_t,
 
 struct demux_sys_t
 {
+    /* All owned by timer thread while timer is armed: */
     xcb_connection_t *conn;
     es_out_id_t      *es;
     mtime_t           pts, interval;
     float             rate;
     xcb_window_t      window;
+    xcb_pixmap_t      pixmap;
     int16_t           x, y;
     uint16_t          w, h;
     uint16_t          cur_w, cur_h;
     bool              follow_mouse;
-    /* fmt, es and pts are protected by the lock. The rest is read-only. */
-    vlc_mutex_t       lock;
     /* Timer does not use this, only input thread: */
     vlc_timer_t       timer;
 };
@@ -177,11 +178,28 @@ static int Open (vlc_object_t *obj)
             goto error;
         }
         p_sys->window = ul;
+
+        xcb_composite_query_version_reply_t *r =
+            xcb_composite_query_version_reply (conn,
+                xcb_composite_query_version (conn, 0, 4), NULL);
+        if (r == NULL || r->minor_version < 2)
+        {
+            msg_Err (obj, "X Composite extension not available");
+            free (r);
+            goto error;
+        }
+        msg_Dbg (obj, "using Composite extension v%"PRIu32".%"PRIu32,
+                 r->major_version, r->minor_version);
+        free (r);
+
+        xcb_composite_redirect_window (conn, p_sys->window,
+                                       XCB_COMPOSITE_REDIRECT_AUTOMATIC);
     }
     else
         goto error;
 
     /* Window properties */
+    p_sys->pixmap = xcb_generate_id (conn);
     p_sys->x = var_InheritInteger (obj, "screen-left");
     p_sys->y = var_InheritInteger (obj, "screen-top");
     p_sys->w = var_InheritInteger (obj, "screen-width");
@@ -201,7 +219,6 @@ static int Open (vlc_object_t *obj)
     p_sys->cur_h = 0;
     p_sys->es = NULL;
     p_sys->pts = VLC_TS_INVALID;
-    vlc_mutex_init (&p_sys->lock);
     if (vlc_timer_create (&p_sys->timer, Demux, demux))
         goto error;
     vlc_timer_schedule (p_sys->timer, false, 1, p_sys->interval);
@@ -227,7 +244,6 @@ static void Close (vlc_object_t *obj)
     demux_sys_t *p_sys = demux->p_sys;
 
     vlc_timer_destroy (p_sys->timer);
-    vlc_mutex_destroy (&p_sys->lock);
     xcb_disconnect (p_sys->conn);
     free (p_sys);
 }
@@ -238,8 +254,6 @@ static void Close (vlc_object_t *obj)
  */
 static int Control (demux_t *demux, int query, va_list args)
 {
-    demux_sys_t *p_sys = demux->p_sys;
-
     switch (query)
     {
         case DEMUX_GET_POSITION:
@@ -267,28 +281,6 @@ static int Control (demux_t *demux, int query, va_list args)
         }
 
         case DEMUX_CAN_PAUSE:
-        {
-            bool *v = (bool*)va_arg( args, bool * );
-            *v = true;
-            return VLC_SUCCESS;
-        }
-
-        case DEMUX_SET_PAUSE_STATE:
-        {
-            bool pausing = va_arg (args, int);
-
-            if (!pausing)
-            {
-                vlc_mutex_lock (&p_sys->lock);
-                p_sys->pts = VLC_TS_INVALID;
-                es_out_Control (demux->out, ES_OUT_RESET_PCR);
-                vlc_mutex_unlock (&p_sys->lock);
-            }
-            vlc_timer_schedule (p_sys->timer, false,
-                                pausing ? 0 : 1, p_sys->interval);
-            return VLC_SUCCESS;
-        }
-
         case DEMUX_CAN_CONTROL_PACE:
         case DEMUX_CAN_CONTROL_RATE:
         case DEMUX_CAN_SEEK:
@@ -297,6 +289,9 @@ static int Control (demux_t *demux, int query, va_list args)
             *v = false;
             return VLC_SUCCESS;
         }
+
+        case DEMUX_SET_PAUSE_STATE:
+            return VLC_SUCCESS; /* should not happen */
     }
 
     return VLC_EGENERIC;
@@ -309,55 +304,38 @@ static int Control (demux_t *demux, int query, va_list args)
 static void Demux (void *data)
 {
     demux_t *demux = data;
-    demux_sys_t *p_sys = demux->p_sys;
-    xcb_connection_t *conn = p_sys->conn;
+    demux_sys_t *sys = demux->p_sys;
+    xcb_connection_t *conn = sys->conn;
 
-    /* Update capture region (if needed) */
+    /* Determine capture region */
+    xcb_get_geometry_cookie_t gc;
+    xcb_query_pointer_cookie_t qc;
+
+    gc = xcb_get_geometry (conn, sys->window);
+    if (sys->follow_mouse)
+        qc = xcb_query_pointer (conn, sys->window);
 
-    xcb_get_geometry_reply_t *geo =
-        xcb_get_geometry_reply (conn,
-            xcb_get_geometry (conn, p_sys->window), NULL);
+    xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL);
     if (geo == NULL)
     {
-        msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, p_sys->window);
+        msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, sys->window);
+        if (sys->follow_mouse)
+            xcb_discard_reply (conn, gc.sequence);
         return;
     }
 
-    xcb_window_t root = geo->root;
-    int16_t x = p_sys->x, y = p_sys->y;
-    xcb_translate_coordinates_cookie_t tc;
-    xcb_query_pointer_cookie_t qc;
+    /* FIXME: review for signed overflow */
+    int16_t x = sys->x, y = sys->y;
+    uint16_t w = sys->w, h = sys->h;
 
-    if (p_sys->window != root)
-        tc = xcb_translate_coordinates (conn, p_sys->window, root,
-                                        x, y);
-    if (p_sys->follow_mouse)
-        qc = xcb_query_pointer (conn, p_sys->window);
-
-    uint16_t ow = geo->width - x;
-    uint16_t oh = geo->height - y;
-    uint16_t w = p_sys->w;
-    uint16_t h = p_sys->h;
+    uint16_t ow = geo->width - sys->x;
+    uint16_t oh = geo->height - sys->y;
     if (w == 0 || w > ow)
         w = ow;
     if (h == 0 || h > oh)
         h = oh;
-    uint8_t depth = geo->depth;
-    free (geo);
-
-    if (p_sys->window != root)
-    {
-        xcb_translate_coordinates_reply_t *coords =
-             xcb_translate_coordinates_reply (conn, tc, NULL);
-        if (coords != NULL)
-        {
-            x = coords->dst_x;
-            y = coords->dst_y;
-            free (coords);
-        }
-    }
 
-    if (p_sys->follow_mouse)
+    if (sys->follow_mouse)
     {
         xcb_query_pointer_reply_t *ptr =
             xcb_query_pointer_reply (conn, qc, NULL);
@@ -379,13 +357,41 @@ static void Demux (void *data)
                 y += oh - h;
             else if (ptr->root_y > min_y)
                 y += ptr->root_y - min_y;
+            free (ptr);
+        }
+    }
+
+    /* Update elementary stream format (if needed) */
+    if (w != sys->cur_w || h != sys->cur_h)
+    {
+        if (sys->es != NULL)
+            es_out_Del (demux->out, sys->es);
+
+        /* Update composite pixmap */
+        if (sys->window != geo->root)
+        {
+            xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */
+            xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap);
+            xcb_create_pixmap (conn, geo->depth, sys->pixmap,
+                               geo->root, geo->width, geo->height);
+        }
+
+        sys->es = InitES (demux, w, h, geo->depth);
+        if (sys->es != NULL)
+        {
+            sys->cur_w = w;
+            sys->cur_h = h;
         }
     }
 
     /* Capture screen */
+    xcb_drawable_t drawable =
+        (sys->window != geo->root) ? sys->pixmap : sys->window;
+    free (geo);
+
     xcb_get_image_reply_t *img;
     img = xcb_get_image_reply (conn,
-        xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, root,
+        xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable,
                        x, y, w, h, ~0), NULL);
     if (img == NULL)
         return;
@@ -395,32 +401,17 @@ static void Demux (void *data)
     if (block == NULL)
         return;
 
-    /* Update elementary stream format (if needed) */
-    vlc_mutex_lock (&p_sys->lock);
-    if (w != p_sys->cur_w || h != p_sys->cur_h)
-    {
-        if (p_sys->es != NULL)
-            es_out_Del (demux->out, p_sys->es);
-        p_sys->es = InitES (demux, w, h, depth);
-        if (p_sys->es != NULL)
-        {
-            p_sys->cur_w = w;
-            p_sys->cur_h = h;
-        }
-    }
-
     /* Send block - zero copy */
-    if (p_sys->es != NULL)
+    if (sys->es != NULL)
     {
-        if (p_sys->pts == VLC_TS_INVALID)
-            p_sys->pts = mdate ();
-        block->i_pts = block->i_dts = p_sys->pts;
+        if (sys->pts == VLC_TS_INVALID)
+            sys->pts = mdate ();
+        block->i_pts = block->i_dts = sys->pts;
 
-        es_out_Control (demux->out, ES_OUT_SET_PCR, p_sys->pts);
-        es_out_Send (demux->out, p_sys->es, block);
-        p_sys->pts += p_sys->interval;
+        es_out_Control (demux->out, ES_OUT_SET_PCR, sys->pts);
+        es_out_Send (demux->out, sys->es, block);
+        sys->pts += sys->interval;
     }
-    vlc_mutex_unlock (&p_sys->lock);
 }
 
 static es_out_id_t *InitES (demux_t *demux, uint_fast16_t width,