libvo: register X11 connection fd in input event system

Register the X11 connection fd in the input system so that
mp_input_get_cmd() can immediately wake up and handle keyboard or
other X events. The callback calls vo_check_events() and tells the
input system to handle any input possibly recorded during that. Before
this was done for vo_xv only; this commit generalizes it to all VOs
that call vo_x11_create_vo_window() - those are hopefully ones that
will handle all X events in check_events().

The callback is only kept registered while the vo is properly
configured. At other times calling check_events() would not clear
pending input and so could lead to a busy loop.
This commit is contained in:
Uoti Urpala 2010-12-14 21:58:47 +02:00
parent 2ba074e613
commit 4f610adfc2
4 changed files with 26 additions and 17 deletions

View File

@ -35,6 +35,8 @@
#include "geometry.h" #include "geometry.h"
#include "old_vo_wrapper.h" #include "old_vo_wrapper.h"
#include "input/input.h" #include "input/input.h"
#include "mp_fifo.h"
#include "mp_msg.h" #include "mp_msg.h"
@ -352,8 +354,12 @@ void vo_flip_page(struct vo *vo, unsigned int pts_us, int duration)
void vo_check_events(struct vo *vo) void vo_check_events(struct vo *vo)
{ {
if (!vo->config_ok) if (!vo->config_ok) {
if (vo->registered_fd != -1)
mp_input_rm_key_fd(vo->input_ctx, vo->registered_fd);
vo->registered_fd = -1;
return; return;
}
vo->driver->check_events(vo); vo->driver->check_events(vo);
} }
@ -365,6 +371,8 @@ void vo_seek_reset(struct vo *vo)
void vo_destroy(struct vo *vo) void vo_destroy(struct vo *vo)
{ {
if (vo->registered_fd != -1)
mp_input_rm_key_fd(vo->input_ctx, vo->registered_fd);
vo->driver->uninit(vo); vo->driver->uninit(vo);
talloc_free(vo); talloc_free(vo);
} }
@ -393,6 +401,8 @@ struct vo *init_best_video_out(struct MPOpts *opts, struct vo_x11_state *x11,
.x11 = x11, .x11 = x11,
.key_fifo = key_fifo, .key_fifo = key_fifo,
.input_ctx = input_ctx, .input_ctx = input_ctx,
.event_fd = -1,
.registered_fd = -1,
}; };
// first try the preferred drivers, with their optional subdevice param: // first try the preferred drivers, with their optional subdevice param:
if (vo_list && vo_list[0]) if (vo_list && vo_list[0])
@ -441,6 +451,13 @@ struct vo *init_best_video_out(struct MPOpts *opts, struct vo_x11_state *x11,
return NULL; return NULL;
} }
static int event_fd_callback(void *ctx, int fd)
{
struct vo *vo = ctx;
vo_check_events(vo);
return mplayer_get_key(vo->key_fifo, 0);
}
int vo_config(struct vo *vo, uint32_t width, uint32_t height, int vo_config(struct vo *vo, uint32_t width, uint32_t height,
uint32_t d_width, uint32_t d_height, uint32_t flags, uint32_t d_width, uint32_t d_height, uint32_t flags,
char *title, uint32_t format) char *title, uint32_t format)
@ -467,6 +484,11 @@ int vo_config(struct vo *vo, uint32_t width, uint32_t height,
title, format); title, format);
vo->config_ok = (ret == 0); vo->config_ok = (ret == 0);
vo->config_count += vo->config_ok; vo->config_count += vo->config_ok;
if (vo->registered_fd == -1 && vo->event_fd != -1 && vo->config_ok) {
mp_input_add_key_fd(vo->input_ctx, vo->event_fd, 1, event_fd_callback,
NULL, vo);
vo->registered_fd = vo->event_fd;
}
return ret; return ret;
} }

View File

@ -251,6 +251,8 @@ struct vo {
struct vo_x11_state *x11; struct vo_x11_state *x11;
struct mp_fifo *key_fifo; struct mp_fifo *key_fifo;
struct input_ctx *input_ctx; struct input_ctx *input_ctx;
int event_fd; // check_events() should be called when this has input
int registered_fd; // set to event_fd when registered in input system
// requested position/resolution // requested position/resolution
int dx; int dx;

View File

@ -61,9 +61,6 @@ Buffer allocation:
#include "subopt-helper.h" #include "subopt-helper.h"
#include "input/input.h"
#include "mp_fifo.h"
#include "libavutil/common.h" #include "libavutil/common.h"
static const vo_info_t info = { static const vo_info_t info = {
@ -104,7 +101,6 @@ struct xvctx {
struct vo_rect src_rect; struct vo_rect src_rect;
struct vo_rect dst_rect; struct vo_rect dst_rect;
uint32_t max_width, max_height; // zero means: not set uint32_t max_width, max_height; // zero means: not set
int event_fd_registered; // for uninit called from preinit
int mode_switched; int mode_switched;
int osd_objects_drawn; int osd_objects_drawn;
void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h, void (*draw_alpha_fnc)(void *ctx, int x0, int y0, int w, int h,
@ -645,19 +641,10 @@ static void uninit(struct vo *vo)
if (ctx->mode_switched) if (ctx->mode_switched)
vo_vm_close(vo); vo_vm_close(vo);
#endif #endif
if (ctx->event_fd_registered)
mp_input_rm_key_fd(vo->input_ctx, ConnectionNumber(vo->x11->display));
// uninit() shouldn't get called unless initialization went past vo_init() // uninit() shouldn't get called unless initialization went past vo_init()
vo_x11_uninit(vo); vo_x11_uninit(vo);
} }
static int x11_fd_callback(void *ctx, int fd)
{
struct vo *vo = ctx;
check_events(vo);
return mplayer_get_key(vo->key_fifo, 0);
}
static int preinit(struct vo *vo, const char *arg) static int preinit(struct vo *vo, const char *arg)
{ {
XvPortID xv_p; XvPortID xv_p;
@ -780,9 +767,6 @@ static int preinit(struct vo *vo, const char *arg)
ctx->fo = XvListImageFormats(x11->display, x11->xv_port, ctx->fo = XvListImageFormats(x11->display, x11->xv_port,
(int *) &ctx->formats); (int *) &ctx->formats);
mp_input_add_key_fd(vo->input_ctx, ConnectionNumber(x11->display), 1,
x11_fd_callback, NULL, vo);
ctx->event_fd_registered = 1;
return 0; return 0;
error: error:

View File

@ -1123,6 +1123,7 @@ final:
x11->vo_gc = XCreateGC(mDisplay, x11->window, GCForeground, &xgcv); x11->vo_gc = XCreateGC(mDisplay, x11->window, GCForeground, &xgcv);
XSync(mDisplay, False); XSync(mDisplay, False);
x11->vo_mouse_autohide = 1; x11->vo_mouse_autohide = 1;
vo->event_fd = ConnectionNumber(x11->display);
} }
void vo_x11_clearwindow_part(struct vo *vo, Window vo_window, void vo_x11_clearwindow_part(struct vo *vo, Window vo_window,