Commit 0310df17 authored by Rémi Denis-Courmont's avatar 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.
parent 62701cf2
...@@ -90,10 +90,32 @@ static void HandleMotionNotify (vout_thread_t *vout, ...@@ -90,10 +90,32 @@ static void HandleMotionNotify (vout_thread_t *vout,
var_SetInteger (vout, "mouse-y", v); 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. * 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) switch (ev->response_type & 0x7f)
{ {
...@@ -109,6 +131,16 @@ int ProcessEvent (vout_thread_t *vout, xcb_generic_event_t *ev) ...@@ -109,6 +131,16 @@ int ProcessEvent (vout_thread_t *vout, xcb_generic_event_t *ev)
HandleMotionNotify (vout, (xcb_motion_notify_event_t *)ev); HandleMotionNotify (vout, (xcb_motion_notify_event_t *)ev);
break; 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: default:
msg_Dbg (vout, "unhandled event %"PRIu8, ev->response_type); msg_Dbg (vout, "unhandled event %"PRIu8, ev->response_type);
} }
......
...@@ -233,6 +233,16 @@ static int Open (vlc_object_t *obj) ...@@ -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_init = Init;
vout->pf_end = Deinit; vout->pf_end = Deinit;
vout->pf_render = Render; vout->pf_render = Render;
...@@ -254,7 +264,8 @@ static void Close (vlc_object_t *obj) ...@@ -254,7 +264,8 @@ static void Close (vlc_object_t *obj)
vout_thread_t *vout = (vout_thread_t *)obj; vout_thread_t *vout = (vout_thread_t *)obj;
vout_sys_t *p_sys = vout->p_sys; 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 (?) */ /* colormap is garbage-ollected by X (?) */
if (p_sys->conn) if (p_sys->conn)
xcb_disconnect (p_sys->conn); xcb_disconnect (p_sys->conn);
...@@ -403,27 +414,33 @@ static int Init (vout_thread_t *vout) ...@@ -403,27 +414,33 @@ static int Init (vout_thread_t *vout)
const xcb_screen_t *screen = p_sys->screen; const xcb_screen_t *screen = p_sys->screen;
unsigned x, y, width, height; unsigned x, y, width, height;
/* Determine parent window */ /* Determine parent window and size */
if (vout->b_fullscreen) if (vout->b_fullscreen)
{ {
p_sys->embed = NULL;
p_sys->parent = screen->root; p_sys->parent = screen->root;
width = screen->width_in_pixels; width = screen->width_in_pixels;
height = screen->height_in_pixels; height = screen->height_in_pixels;
} }
else 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; 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); vout_PlacePicture (vout, width, height, &x, &y, &width, &height);
/* FIXME: I don't get the subtlety between output and fmt_out here */ /* FIXME: I don't get the subtlety between output and fmt_out here */
...@@ -505,8 +522,6 @@ static void Deinit (vout_thread_t *vout) ...@@ -505,8 +522,6 @@ static void Deinit (vout_thread_t *vout)
xcb_unmap_window (p_sys->conn, p_sys->window); xcb_unmap_window (p_sys->conn, p_sys->window);
xcb_destroy_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) ...@@ -558,7 +573,7 @@ static int Manage (vout_thread_t *vout)
xcb_generic_event_t *ev; xcb_generic_event_t *ev;
while ((ev = xcb_poll_for_event (p_sys->conn)) != NULL) 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)) if (xcb_connection_has_error (p_sys->conn))
{ {
......
...@@ -21,7 +21,8 @@ ...@@ -21,7 +21,8 @@
****************************************************************************/ ****************************************************************************/
int CheckError (vout_thread_t *, const char *str, xcb_void_cookie_t); 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; typedef struct key_handler_t key_handler_t;
key_handler_t *CreateKeyHandler (vlc_object_t *, xcb_connection_t *); key_handler_t *CreateKeyHandler (vlc_object_t *, xcb_connection_t *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment