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)
{
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);
}
}
}
+ /* 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;
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);
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 */
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;
}
/**
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))
{