[FFmpeg-devel] [PATCH] lavd/xv: handle delete window message

Lukasz Marek lukasz.m.luki2 at gmail.com
Mon Jun 16 23:56:27 CEST 2014


On 01.06.2014 15:43, Nicolas George wrote:
> Le primidi 11 prairial, an CCXXII, Lukasz Marek a écrit :
>>  From c6745beaddad2ddd4ed7c18e7705bd79e95efcf5 Mon Sep 17 00:00:00 2001
>> From: Lukasz Marek <lukasz.m.luki2 at gmail.com>
>> Date: Tue, 27 May 2014 22:57:26 +0200
>> Subject: [PATCH] lavd/xv: handle delete window message
>>
>> User may close X11 window by close button on tray.
>> FFmpeg leaves in graceless way.
>> This commit detects it and return EPIPE error.
>>
>> Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com>
>> ---
>>   libavdevice/xv.c |   19 +++++++++++++++++++
>>   1 file changed, 19 insertions(+)
>>
>> diff --git a/libavdevice/xv.c b/libavdevice/xv.c
>> index d1f8907..a702a50 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,22 @@ 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;
>
>> +        int cnt = XPending(xv->display);
>> +        while (cnt--) {
>> +            XNextEvent(xv->display, &event);
>
> Most of the time, this kind of loop just looks like that:
>
> 	while (XPending(display)) {
>
> That is slightly simpler and possibly more robust in case some event handler
> causes events to be received.
>
>> +            if (event.type == ClientMessage) {
>> +                if (event.xclient.data.l[0] == xv->wm_delete_message) {
>
> You could combine the two tests into a single one.
>
>> +                    av_log(xv, AV_LOG_DEBUG, "Window close event.\n");
>> +                    return AVERROR(EPIPE);
>
> I am afraid the proper behaviour is more complex than that, but this version
> is probably a good start until we make devices' behaviour uniform.
>
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>>       av_image_copy(data, img->pitches, (const uint8_t **)pict->data, pict->linesize,
>>                     xv->image_format, img->width, img->height);
>>       return xv_repaint(s);
>
> Globally LGTM, thanks.

Updated patch attached.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-lavd-xv-handle-delete-window-message.patch
Type: text/x-patch
Size: 2001 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140616/4406c31c/attachment.bin>


More information about the ffmpeg-devel mailing list