[vlc-devel] commit: XCB: resize support ( Rémi Denis-Courmont )

git version control git at videolan.org
Thu Apr 9 16:59:55 CEST 2009


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Apr  9 17:54:41 2009 +0300| [0310df1730099612eb0d03e229195b5f1d35ace5] | committer: Rémi Denis-Courmont 

XCB: resize support

Note that the video output core seems to call pf_end while some pictures
are still in use upstream. That will crash. IMHO, this is a libvlc bug,
as the vout plugin cannot know when to release the picture or reallocate
those pictures.

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

 modules/video_output/xcb/events.c  |   34 +++++++++++++++++++++++++++-
 modules/video_output/xcb/xcb.c     |   43 ++++++++++++++++++++++++-----------
 modules/video_output/xcb/xcb_vlc.h |    3 +-
 3 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/modules/video_output/xcb/events.c b/modules/video_output/xcb/events.c
index 908f811..bffe407 100644
--- a/modules/video_output/xcb/events.c
+++ b/modules/video_output/xcb/events.c
@@ -90,10 +90,32 @@ static void HandleMotionNotify (vout_thread_t *vout,
     var_SetInteger (vout, "mouse-y", v);
 }
 
+static void
+HandleParentStructure (vout_thread_t *vout, xcb_connection_t *conn,
+                       xcb_window_t xid, xcb_configure_notify_event_t *ev)
+{
+    unsigned width, height, x, y;
+
+    vout_PlacePicture (vout, ev->width, ev->height, &x, &y, &width, &height);
+    if (width != vout->fmt_out.i_visible_width
+     || height != vout->fmt_out.i_visible_height)
+    {
+        vout->i_changes |= VOUT_SIZE_CHANGE;
+        return; /* vout will be reinitialized */
+    }
+
+    /* Move the picture within the window */
+    const uint32_t values[] = { x, y, };
+    xcb_configure_window (conn, xid,
+                          XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y,
+                          values);
+}
+
 /**
  * Process an X11 event.
  */
-int ProcessEvent (vout_thread_t *vout, xcb_generic_event_t *ev)
+int ProcessEvent (vout_thread_t *vout, xcb_connection_t *conn,
+                  xcb_window_t window, xcb_generic_event_t *ev)
 {
     switch (ev->response_type & 0x7f)
     {
@@ -109,6 +131,16 @@ int ProcessEvent (vout_thread_t *vout, xcb_generic_event_t *ev)
             HandleMotionNotify (vout, (xcb_motion_notify_event_t *)ev);
             break;
 
+        case XCB_CONFIGURE_NOTIFY:
+        {
+            xcb_configure_notify_event_t *cn =
+                (xcb_configure_notify_event_t *)ev;
+
+            assert (cn->window != window)
+            HandleParentStructure (vout, conn, window, cn);
+            break;
+        }
+
         default:
             msg_Dbg (vout, "unhandled event %"PRIu8, ev->response_type);
     }
diff --git a/modules/video_output/xcb/xcb.c b/modules/video_output/xcb/xcb.c
index 0f1eafe..e3dd91a 100644
--- a/modules/video_output/xcb/xcb.c
+++ b/modules/video_output/xcb/xcb.c
@@ -233,6 +233,16 @@ static int Open (vlc_object_t *obj)
         }
     }
 
+    /* Get window */
+    /* FIXME: WTH to put as initial width/height values??? */
+    p_sys->embed = vout_RequestXWindow (vout, &(int){ 0 }, &(int){ 0 },
+                                        &(unsigned){ 0 }, &(unsigned){ 0 });
+    if (p_sys->embed == NULL)
+    {
+        msg_Err (vout, "parent window not available");
+        goto error;
+    }
+
     vout->pf_init = Init;
     vout->pf_end = Deinit;
     vout->pf_render = Render;
@@ -254,7 +264,8 @@ static void Close (vlc_object_t *obj)
     vout_thread_t *vout = (vout_thread_t *)obj;
     vout_sys_t *p_sys = vout->p_sys;
 
-    assert (p_sys->embed == NULL);
+    if (p_sys->embed)
+        vout_ReleaseWindow (p_sys->embed);
     /* colormap is garbage-ollected by X (?) */
     if (p_sys->conn)
         xcb_disconnect (p_sys->conn);
@@ -403,27 +414,33 @@ static int Init (vout_thread_t *vout)
     const xcb_screen_t *screen = p_sys->screen;
     unsigned x, y, width, height;
 
-    /* Determine parent window */
+    /* Determine parent window and size */
     if (vout->b_fullscreen)
     {
-        p_sys->embed = NULL;
         p_sys->parent = screen->root;
         width = screen->width_in_pixels;
         height = screen->height_in_pixels;
     }
     else
     {
-        p_sys->embed = vout_RequestXWindow (vout, &(int){ 0 }, &(int){ 0 },
-                                            &width, &height);
-        if (p_sys->embed == NULL)
-        {
-            msg_Err (vout, "cannot get parent window");
-            return VLC_EGENERIC;
-        }
         p_sys->parent = p_sys->embed->handle.xid;
+
+        /* Subscribe to parent window resize events */
+        const uint32_t value = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+        xcb_change_window_attributes (p_sys->conn, p_sys->parent,
+                                      XCB_CW_EVENT_MASK, &value);
+
+        xcb_get_geometry_cookie_t ck;
+        ck = xcb_get_geometry (p_sys->conn, p_sys->parent);
+
+        xcb_get_geometry_reply_t *geo;
+        xcb_generic_error_t *err;
+        geo = xcb_get_geometry_reply (p_sys->conn, ck, &err);
+        width = geo->width;
+        height = geo->height;
+        free (geo);
     }
 
-    /* FIXME: incorrect placement if resize now */
     vout_PlacePicture (vout, width, height, &x, &y, &width, &height);
 
     /* FIXME: I don't get the subtlety between output and fmt_out here */
@@ -505,8 +522,6 @@ static void Deinit (vout_thread_t *vout)
 
     xcb_unmap_window (p_sys->conn, p_sys->window);
     xcb_destroy_window (p_sys->conn, p_sys->window);
-    vout_ReleaseWindow (p_sys->embed);
-    p_sys->embed = NULL;
 }
 
 /**
@@ -558,7 +573,7 @@ static int Manage (vout_thread_t *vout)
     xcb_generic_event_t *ev;
 
     while ((ev = xcb_poll_for_event (p_sys->conn)) != NULL)
-        ProcessEvent (vout, ev);
+        ProcessEvent (vout, p_sys->conn, p_sys->window, ev);
 
     if (xcb_connection_has_error (p_sys->conn))
     {
diff --git a/modules/video_output/xcb/xcb_vlc.h b/modules/video_output/xcb/xcb_vlc.h
index 51f92c7..efedd02 100644
--- a/modules/video_output/xcb/xcb_vlc.h
+++ b/modules/video_output/xcb/xcb_vlc.h
@@ -21,7 +21,8 @@
  ****************************************************************************/
 
 int CheckError (vout_thread_t *, const char *str, xcb_void_cookie_t);
-int ProcessEvent (vout_thread_t *, xcb_generic_event_t *);
+int ProcessEvent (vout_thread_t *, xcb_connection_t *, xcb_window_t,
+                  xcb_generic_event_t *);
 
 typedef struct key_handler_t key_handler_t;
 key_handler_t *CreateKeyHandler (vlc_object_t *, xcb_connection_t *);




More information about the vlc-devel mailing list