[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