[FFmpeg-devel] [PATCH] lavd/xv: handle delete window message
Nicolas George
george at nsup.org
Wed May 28 09:31:28 CEST 2014
Good idea, thanks.
L'octidi 8 prairial, an CCXXII, Lukasz Marek a écrit :
> User may close X11 window by close button on tray.
> FFmpeg leaves in graceless way.
Bogus window manager, it should not be destroying a window if it can not
delete it, unless the user really request it.
> This commit detects it and return IO error.
Seems reasonable. EPIPE could make sense too.
>
> Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> ---
> libavdevice/xv.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/libavdevice/xv.c b/libavdevice/xv.c
> index d1f8907..cc362a7 100644
> --- a/libavdevice/xv.c
> +++ b/libavdevice/xv.c
> @@ -58,6 +58,7 @@ typedef struct {
> int image_width, image_height;
> XShmSegmentInfo yuv_shminfo;
> int xv_port;
> + Atom wm_delete_message;
> } XVContext;
>
> typedef struct XVTagFormatMap
> @@ -156,6 +157,8 @@ static int xv_write_header(AVFormatContext *s)
> }
> }
> XStoreName(xv->display, xv->window, xv->window_title);
> + xv->wm_delete_message = XInternAtom(xv->display, "WM_DELETE_WINDOW", False);
> + XSetWMProtocols(xv->display, xv->window, &xv->wm_delete_message, 1);
> XMapWindow(xv->display, xv->window);
> } else
> xv->window = xv->window_id;
> @@ -297,6 +300,18 @@ static int write_picture(AVFormatContext *s, AVPicture *pict)
> img->data + img->offsets[1],
> img->data + img->offsets[2]
> };
> +
> + /* Check messages. Window might get closed. */
> + if (!xv->window_id) {
> + XEvent event;
> + if (XCheckTypedEvent(xv->display, ClientMessage, &event)) {
> + if (event.xclient.data.l[0] == xv->wm_delete_message) {
> + av_log(xv, AV_LOG_DEBUG, "Window close event.\n");
> + return AVERROR(EIO);
> + }
> + }
> + }
> +
I must say I do not like XCheckTypedEvent() much: what happens to the other
events? They stay and clobber the queue. I suggest to loop over XPending and
XNextEvent. That would also make life easier to someone who wants to
implement other kind of events.
> av_image_copy(data, img->pitches, (const uint8_t **)pict->data, pict->linesize,
> xv->image_format, img->width, img->height);
> return xv_repaint(s);
Regards,
--
Nicolas George
More information about the ffmpeg-devel
mailing list