Commit e51b412b authored by Jean-Paul Saman's avatar Jean-Paul Saman

VAAPI-X11: Workaround for X11 window resize updates.

Query the window size inside Manage() to catch changes. The parent
window does not forward resizes to the client.
parent 10821ecd
......@@ -333,6 +333,27 @@ static vout_window_t *MakeWindow (vout_display_t *vd)
return wnd;
}
static int GetWindowSize(vout_display_t *vd, Display *dpy,
Window window, int *px, int *py,
unsigned int *pwidth, unsigned int *pheight)
{
vout_display_sys_t *sys = vd->sys;
Status status = 0;
Window root_window;
unsigned int bw, depth;
sys->conn->lock();
if ((window != None) || (window != BadDrawable))
{
status = XGetGeometry(dpy, window,
&root_window,
px, py, pwidth, pheight,
&bw, &depth);
}
sys->conn->unlock();
return (status == 0) ? VLC_EGENERIC : VLC_SUCCESS;
}
static Screen *FindScreen(vout_display_t *vd, Display *dpy,
int *px, int *py, unsigned int *pnum, unsigned int *pdepth,
unsigned int *pwidth, unsigned int *pheight)
......@@ -401,6 +422,7 @@ static Window CreateWindow(vout_display_t *vd, Display *dpy, Screen *screen)
vout_display_sys_t *sys = vd->sys;
assert(screen);
sys->conn->lock();
int scr = XScreenNumberOfScreen(screen);
XVisualInfo visualInfo;
......@@ -426,35 +448,53 @@ static Window CreateWindow(vout_display_t *vd, Display *dpy, Screen *screen)
0, sys->geo.depth,
InputOutput,
vi->visual, xswa_mask, &xswa);
if (window == None)
{
switch (window)
{
case None:
case BadAlloc:
case BadColor:
case BadCursor:
case BadMatch:
case BadPixmap:
case BadValue:
case BadWindow:
XFree(vi);
return None;
goto error;
default:
break;
}
if (vi != &visualInfo)
XFree(vi);
/* */
long mask = (ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
ResizeRedirectMask | StructureNotifyMask | SubstructureRedirectMask |
long mask = (PointerMotionMask | StructureNotifyMask |
ExposureMask | VisibilityChangeMask);
if (var_InheritBool(vd, "mouse-events"))
mask |= (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask);
int err = XSelectInput(dpy, window, mask);
if (err == BadWindow)
return None;
goto error;
XMapWindow(dpy, window);
WaitEvent(dpy, window, MapNotify);
WaitEvent(dpy, window, Expose); /* XXX: workaround an XvBA init bug */
XFlush(dpy);
sys->conn->unlock();
return window;
error:
sys->conn->unlock();
return None;
}
static void DestroyWindow(Display *dpy, Window window)
{
/* use unlocked */
XUnmapWindow(dpy, window);
WaitEvent(dpy, window, UnmapNotify);
int err = XSelectInput(dpy, window, NoEventMask);
if (err != BadWindow)
XFlush(dpy);
XDestroyWindow(dpy, window);
}
......@@ -469,17 +509,20 @@ static Cursor CreateBlankCursor(vout_display_t *vd, Display *dpy,
XColor dummy;
static char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0};
sys->conn->lock();
int scr = XScreenNumberOfScreen(screen);
cmap = DefaultColormap(dpy, scr);
XAllocNamedColor(dpy, cmap, "black", &sys->black, &dummy);
sys->bitmap = XCreateBitmapFromData(dpy, sys->window, bm_no_data, 8, 8);
no_ptr = XCreatePixmapCursor(dpy, sys->bitmap, sys->bitmap, &sys->black, &sys->black, 0, 0);
sys->conn->unlock();
return no_ptr;
}
static void DestroyBlankCursor(vout_display_t *vd, Display *dpy,
Window window, Screen *screen)
{
/* use unlocked */
vout_display_sys_t *sys = vd->sys;
assert(screen);
......@@ -607,20 +650,22 @@ void CloseVaapiX11 (vlc_object_t *obj)
{
XFlush(sys->conn->p_x11);
XSync(sys->conn->p_x11, False);
}
if (sys->blank_cursor != None)
if ((sys->window != None) && (sys->blank_cursor != None))
DestroyBlankCursor(vd, sys->conn->p_x11,
sys->window, sys->screen);
if (sys->window != None)
DestroyWindow(sys->conn->p_x11, sys->window);
}
sys->blank_cursor = None;
sys->window = None;
sys->conn->unlock();
if (sys->embed)
vout_display_DeleteWindow (vd, sys->embed);
sys->embed = NULL;
/* Cleanup cache */
vlc_mutex_destroy(&sys->cache_lock);
......@@ -695,8 +740,8 @@ static int Control (vout_display_t *vd, int query, va_list ap)
is_forced = (bool)va_arg (ap, int);
}
msg_Info(vd, "display size %dx%d %dx%d",
0, 0, cfg->display.width, cfg->display.height);
// msg_Dbg(vd, "display size %dx%d %dx%d",
// 0, 0, cfg->display.width, cfg->display.height);
/* */
if (query == VOUT_DISPLAY_CHANGE_DISPLAY_SIZE
......@@ -707,24 +752,41 @@ static int Control (vout_display_t *vd, int query, va_list ap)
cfg->display.width, cfg->display.height))
return VLC_EGENERIC;
/* FIXME: updating picture geometry */
#if 0
vout_display_place_t place;
vout_display_PlacePicture(&place, source, cfg, false);
/* */
sys->geo.x = place.x;
sys->geo.y = place.y;
sys->geo.width = place.width;
sys->geo.height = place.height;
#else
VLC_UNUSED(source);
XWindowChanges changes = { .x = place.x, .y = place.y,
.width = place.width, .height = place.height };
sys->geo.x = 0;
sys->geo.y = 0;
sys->geo.width = cfg->display.width;
sys->geo.height = cfg->display.height;
#endif
if (sys->window == None)
return VLC_EGENERIC;
sys->conn->lock();
XWindowChanges changes = { .x = sys->geo.x, .y = sys->geo.y,
.width = sys->geo.width, .height = sys->geo.height };
int err = XConfigureWindow(sys->conn->p_x11, sys->window,
CWX | CWY | CWWidth | CWHeight, &changes);
if (err == BadMatch || err == BadValue || err == BadWindow)
{
sys->conn->unlock();
return VLC_EGENERIC;
}
XFlush(sys->conn->p_x11);
sys->conn->unlock();
msg_Info(vd, "New window size %dx%d %dx%d",
place.x, place.y, place.width, place.height);
msg_Dbg(vd, "New window size %dx%d %dx%d",
sys->geo.x, sys->geo.y, sys->geo.width, sys->geo.height);
return VLC_SUCCESS;
}
case VOUT_DISPLAY_RESET_PICTURES:
......@@ -737,16 +799,17 @@ static int Control (vout_display_t *vd, int query, va_list ap)
* vout_display_t::info.b_hide_mouse is false */
case VOUT_DISPLAY_HIDE_MOUSE:
{
sys->conn->lock();
int err = XDefineCursor(sys->conn->p_x11, sys->window,
sys->blank_cursor);
sys->conn->unlock();
if (err == BadAlloc || err == BadWindow || err == BadCursor)
return VLC_EGENERIC;
return VLC_SUCCESS;
}
default:
msg_Err (vd, "Unknown request in XCB vout display");
msg_Err (vd, "Unknown request in VAAPI-X11 vout display");
return VLC_EGENERIC;
}
}
......@@ -776,7 +839,9 @@ static int HandleEvent(vout_display_t *vd, Display *dpy, XEvent *event,
vout_display_place_t place;
/* show the default cursor */
sys->conn->lock();
XUndefineCursor(dpy, sys->window);
sys->conn->unlock();
/* TODO it could be saved */
vout_display_PlacePicture (&place, &vd->source, vd->cfg, false);
......@@ -823,7 +888,9 @@ static int HandleEvent(vout_display_t *vd, Display *dpy, XEvent *event,
case DestroyNotify:
vout_display_SendEventClose(vd);
break;
case CreateNotify:
case Expose:
case MapNotify:
case MappingNotify:
break;
default:
......@@ -837,12 +904,42 @@ static void Manage(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
while (XPending(sys->conn->p_x11))
/* FIXME: workaround for not receiving updates from X11 when resizing */
int x, y;
unsigned int w, h;
if (GetWindowSize(vd, sys->conn->p_x11, sys->embed->handle.xid,
&x, &y, &w, &h) == VLC_SUCCESS)
{
if (sys->geo.width != w || sys->geo.height != h)
{
sys->geo.y = y;
sys->geo.x = x;
sys->geo.width = w;
sys->geo.height = h;
vout_display_SendEventDisplaySize(vd, w, h, vd->cfg->is_fullscreen);
}
}
/* */
int num = 0;
do
{
if (sys->window == None)
break;
sys->conn->lock();
num = XPending(sys->conn->p_x11);
if (num <= 0)
{
sys->conn->unlock();
break;
}
XEvent event;
XNextEvent(sys->conn->p_x11, &event);
sys->conn->unlock();
HandleEvent(vd, sys->conn->p_x11, &event, &sys->visible);
}
} while(num > 0);
}
static VASubpictureID SubpictureCreate(vout_display_t *vd, const subpicture_t *subpicture,
......@@ -1410,6 +1507,9 @@ static void DisplayPicture(vout_display_t *vd, picture_t *pic, subpicture_t *sub
if (!sys->visible)
goto out;
if (sys->window == None)
goto out;
assert(pic->format.i_chroma == VLC_CODEC_VAAPI_SURFACE);
if ((pic->p_sys == NULL) || (pic->p_sys->i_id == VA_INVALID_SURFACE))
......
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