[vlc-devel] commit: XCB screen: capture root window through translation ( Rémi Denis-Courmont )

git version control git at videolan.org
Mon Jun 8 22:27:24 CEST 2009


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Jun  8 23:25:43 2009 +0300| [3bce3729728e2e40972f80fbf67fdab10851d2f4] | committer: Rémi Denis-Courmont 

XCB screen: capture root window through translation

This allows capturing child (esp. menus) or overlapping windows instead
of void when the captured window is not at the top.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3bce3729728e2e40972f80fbf67fdab10851d2f4
---

 modules/access/screen/xcb.c |   47 ++++++++++++++++++++++++++++--------------
 1 files changed, 31 insertions(+), 16 deletions(-)

diff --git a/modules/access/screen/xcb.c b/modules/access/screen/xcb.c
index bef07b7..f07da39 100644
--- a/modules/access/screen/xcb.c
+++ b/modules/access/screen/xcb.c
@@ -100,7 +100,7 @@ struct demux_sys_t
     es_out_id_t      *es;
     es_format_t       fmt;
     mtime_t           pts, interval;
-    xcb_window_t      window;
+    xcb_window_t      root, window;
     int16_t           x, y;
     uint16_t          w, h;
 };
@@ -149,8 +149,9 @@ static int Open (vlc_object_t *obj)
     }
 
     /* Determine capture window */
+    p_sys->root = scr->root;
     if (!strcmp (demux->psz_access, "screen"))
-        p_sys->window = scr->root;
+        p_sys->window = p_sys->root;
     else
     if (!strcmp (demux->psz_access, "window"))
     {
@@ -178,7 +179,7 @@ static int Open (vlc_object_t *obj)
              *end = fmt + xcb_setup_pixmap_formats_length (setup);
          fmt < end; fmt++)
     {
-        if (fmt->depth != geo->depth)
+        if (fmt->depth != scr->root_depth)
             continue;
         bpp = fmt->depth;
         switch (fmt->depth)
@@ -340,19 +341,24 @@ static int Demux (demux_t *demux)
     else
         p_sys->pts = now;
 
-    /* Update capture size (if needed) */
-    xcb_get_geometry_reply_t *geo;
-    geo = xcb_get_geometry_reply (conn,
-                                  xcb_get_geometry (conn, p_sys->window),
-                                  NULL);
+    /* Update capture region (if needed) */
+    xcb_get_geometry_cookie_t gc = xcb_get_geometry (conn, p_sys->window);
+    int16_t x = p_sys->x, y = p_sys->y;
+    xcb_translate_coordinates_cookie_t tc;
+
+    if (p_sys->window != p_sys->root)
+        tc = xcb_translate_coordinates (conn, p_sys->window, p_sys->root,
+                                        x, y);
+
+    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);
         return 0;
     }
 
-    uint16_t w = geo->width - p_sys->x;
-    uint16_t h = geo->height - p_sys->y;
+    uint16_t w = geo->width - x;
+    uint16_t h = geo->height - y;
     if (p_sys->w > 0 && p_sys->w < w)
         w = p_sys->w;
     if (p_sys->h > 0 && p_sys->h < h)
@@ -368,19 +374,28 @@ static int Demux (demux_t *demux)
         p_sys->es = es_out_Add (demux->out, &p_sys->fmt);
     }
     free (geo);
+
+    if (p_sys->window != p_sys->root)
+    {
+        xcb_translate_coordinates_reply_t *coords =
+             xcb_translate_coordinates_reply (conn, tc, NULL);
+        if (coords == NULL)
+            return 1;
+        x = coords->dst_x;
+        y = coords->dst_y;
+        free (coords);
+    }
+
+    /* Capture screen */
     if (p_sys->es == NULL)
         return 1;
 
-    /* Capture screen */
     xcb_get_image_reply_t *img;
     img = xcb_get_image_reply (conn,
-        xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, p_sys->window,
-                       p_sys->x, p_sys->y, w, h, ~0), NULL);
+        xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, p_sys->root,
+                       x, y, w, h, ~0), NULL);
     if (img == NULL)
-    {
-        msg_Warn (demux, "no image");
         return 1;
-    }
 
     /* Send block - zero copy */
     block_t *block = block_heap_Alloc (img, xcb_get_image_data (img),




More information about the vlc-devel mailing list