diff options
Diffstat (limited to 'video/out/x11_common.c')
-rw-r--r-- | video/out/x11_common.c | 170 |
1 files changed, 98 insertions, 72 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 2e5f14f8d1..05d6af41cb 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -26,7 +26,7 @@ #include "core/bstr.h" #include "core/options.h" #include "core/mp_msg.h" -#include "core/mp_fifo.h" +#include "core/input/input.h" #include "libavutil/common.h" #include "x11_common.h" #include "talloc.h" @@ -128,6 +128,7 @@ typedef struct } MotifWmHints; static void vo_x11_update_geometry(struct vo *vo); +static void vo_x11_fullscreen(struct vo *vo); static int vo_x11_get_fs_type(struct vo *vo); static void xscreensaver_heartbeat(struct vo_x11_state *x11); static void saver_on(struct vo_x11_state *x11); @@ -176,34 +177,39 @@ static void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action) } } -static void vo_hidecursor(struct vo *vo, Display *disp, Window win) +static void vo_set_cursor_hidden(struct vo *vo, bool cursor_hidden) { Cursor no_ptr; Pixmap bm_no; XColor black, dummy; Colormap colormap; const char bm_no_data[] = {0, 0, 0, 0, 0, 0, 0, 0}; + struct vo_x11_state *x11 = vo->x11; + Display *disp = x11->display; + Window win = x11->window; - if (vo->opts->WinID == 0) - return; // do not hide if playing on the root window + if (cursor_hidden == x11->mouse_cursor_hidden) + return; - colormap = DefaultColormap(disp, DefaultScreen(disp)); - if (!XAllocNamedColor(disp, colormap, "black", &black, &dummy)) - return; // color alloc failed, give up - bm_no = XCreateBitmapFromData(disp, win, bm_no_data, 8, 8); - no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); - XDefineCursor(disp, win, no_ptr); - XFreeCursor(disp, no_ptr); - if (bm_no != None) - XFreePixmap(disp, bm_no); - XFreeColors(disp, colormap, &black.pixel, 1, 0); -} + x11->mouse_cursor_hidden = cursor_hidden; -static void vo_showcursor(struct vo *vo, Display *disp, Window win) -{ - if (vo->opts->WinID == 0) - return; - XDefineCursor(disp, win, 0); + if (vo->opts->WinID == 0 || win == 0) + return; // do not hide if playing on the root window + + if (x11->mouse_cursor_hidden) { + colormap = DefaultColormap(disp, DefaultScreen(disp)); + if (!XAllocNamedColor(disp, colormap, "black", &black, &dummy)) + return; // color alloc failed, give up + bm_no = XCreateBitmapFromData(disp, win, bm_no_data, 8, 8); + no_ptr = XCreatePixmapCursor(disp, bm_no, bm_no, &black, &black, 0, 0); + XDefineCursor(disp, win, no_ptr); + XFreeCursor(disp, no_ptr); + if (bm_no != None) + XFreePixmap(disp, bm_no); + XFreeColors(disp, colormap, &black.pixel, 1, 0); + } else { + XDefineCursor(x11->display, x11->window, 0); + } } static int x11_errorhandler(Display *display, XErrorEvent *event) @@ -371,7 +377,7 @@ static void init_atoms(struct vo_x11_state *x11) x11->XA_NET_WM_CM = XInternAtom(x11->display, buf, False); } -void vo_x11_update_screeninfo(struct vo *vo) +static void vo_x11_update_screeninfo(struct vo *vo) { struct mp_vo_opts *opts = vo->opts; struct vo_x11_state *x11 = vo->x11; @@ -490,9 +496,6 @@ int vo_x11_init(struct vo *vo) fstype_dump(x11->fs_type); - if (opts->stop_screensaver) - saver_off(x11); - vo->event_fd = ConnectionNumber(x11->display); return 1; @@ -636,11 +639,11 @@ void vo_x11_uninit(struct vo *vo) struct vo_x11_state *x11 = vo->x11; assert(x11); - mplayer_put_key(vo->key_fifo, MP_INPUT_RELEASE_ALL); + mp_input_put_key(vo->input_ctx, MP_INPUT_RELEASE_ALL); saver_on(x11); if (x11->window != None) - vo_showcursor(vo, x11->display, x11->window); + vo_set_cursor_hidden(vo, false); if (x11->f_gc != None) XFreeGC(vo->x11->display, x11->f_gc); @@ -674,20 +677,6 @@ void vo_x11_uninit(struct vo *vo) vo->x11 = NULL; } -static void vo_x11_unhide_cursor(struct vo *vo) -{ - struct vo_x11_state *x11 = vo->x11; - struct mp_vo_opts *opts = vo->opts; - - if (opts->cursor_autohide_delay > -2) { - vo_showcursor(vo, x11->display, x11->window); - if (opts->cursor_autohide_delay >= 0) { - x11->mouse_waiting_hide = 1; - x11->mouse_timer = GetTimerMS() + opts->cursor_autohide_delay; - } - } -} - static void update_vo_size(struct vo *vo) { struct vo_x11_state *x11 = vo->x11; @@ -705,11 +694,6 @@ int vo_x11_check_events(struct vo *vo) Display *display = vo->x11->display; XEvent Event; - if (x11->mouse_waiting_hide && GetTimerMS() >= x11->mouse_timer) { - vo_hidecursor(vo, display, x11->window); - x11->mouse_waiting_hide = 0; - } - xscreensaver_heartbeat(vo->x11); if (vo->opts->WinID > 0) @@ -746,17 +730,17 @@ int vo_x11_check_events(struct vo *vo) sizeof(buf), &keySym, &status); int mpkey = vo_x11_lookupkey(keySym); if (mpkey) { - mplayer_put_key(vo->key_fifo, mpkey | modifiers); + mp_input_put_key(vo->input_ctx, mpkey | modifiers); } else if (status == XLookupChars || status == XLookupBoth) { struct bstr t = { buf, len }; - mplayer_put_key_utf8(vo->key_fifo, modifiers, t); + mp_input_put_key_utf8(vo->input_ctx, modifiers, t); } } else { XLookupString(&Event.xkey, buf, sizeof(buf), &keySym, &x11->compose_status); int mpkey = vo_x11_lookupkey(keySym); if (mpkey) - mplayer_put_key(vo->key_fifo, mpkey | modifiers); + mp_input_put_key(vo->input_ctx, mpkey | modifiers); } break; } @@ -766,23 +750,24 @@ int vo_x11_check_events(struct vo *vo) case KeyRelease: { if (x11->no_autorepeat) - mplayer_put_key(vo->key_fifo, MP_INPUT_RELEASE_ALL); + mp_input_put_key(vo->input_ctx, MP_INPUT_RELEASE_ALL); break; } case MotionNotify: vo_mouse_movement(vo, Event.xmotion.x, Event.xmotion.y); - vo_x11_unhide_cursor(vo); + break; + case LeaveNotify: + mp_input_put_key(vo->input_ctx, MP_KEY_MOUSE_LEAVE); break; case ButtonPress: - vo_x11_unhide_cursor(vo); - mplayer_put_key(vo->key_fifo, - (MP_MOUSE_BTN0 + Event.xbutton.button - 1) - | MP_KEY_STATE_DOWN); + mp_input_put_key(vo->input_ctx, + (MP_MOUSE_BTN0 + Event.xbutton.button - 1) + | MP_KEY_STATE_DOWN); break; case ButtonRelease: - vo_x11_unhide_cursor(vo); - mplayer_put_key(vo->key_fifo, - MP_MOUSE_BTN0 + Event.xbutton.button - 1); + mp_input_put_key(vo->input_ctx, + (MP_MOUSE_BTN0 + Event.xbutton.button - 1) + | MP_KEY_STATE_UP); break; case PropertyNotify: { char *name = XGetAtomName(display, Event.xproperty.atom); @@ -798,12 +783,12 @@ int vo_x11_check_events(struct vo *vo) break; case DestroyNotify: mp_msg(MSGT_VO, MSGL_WARN, "Our window was destroyed, exiting\n"); - mplayer_put_key(vo->key_fifo, MP_KEY_CLOSE_WIN); + mp_input_put_key(vo->input_ctx, MP_KEY_CLOSE_WIN); break; case ClientMessage: if (Event.xclient.message_type == x11->XAWM_PROTOCOLS && Event.xclient.data.l[0] == x11->XAWM_DELETE_WINDOW) - mplayer_put_key(vo->key_fifo, MP_KEY_CLOSE_WIN); + mp_input_put_key(vo->input_ctx, MP_KEY_CLOSE_WIN); break; default: if (Event.type == x11->ShmCompletionEvent) { @@ -814,9 +799,6 @@ int vo_x11_check_events(struct vo *vo) } } - if (x11->mouse_waiting_hide) - vo->next_wakeup_time = FFMIN(vo->next_wakeup_time, x11->mouse_timer); - update_vo_size(vo); if (vo->opts->WinID >= 0 && (x11->pending_vo_events & VO_EVENT_RESIZE)) { int x = x11->win_x, y = x11->win_y; @@ -937,6 +919,9 @@ static void vo_x11_update_window_title(struct vo *vo) { struct vo_x11_state *x11 = vo->x11; + if (!x11->window) + return; + const char *title = vo_get_window_title(vo); vo_x11_set_property_string(vo, XA_WM_NAME, title); vo_x11_set_property_string(vo, XA_WM_ICON_NAME, title); @@ -983,12 +968,17 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y, x11->vo_gc = XCreateGC(x11->display, x11->window, 0, NULL); XSetForeground(x11->display, x11->f_gc, 0); - vo_hidecursor(vo, x11->display, x11->window); + if (x11->mouse_cursor_hidden) { + x11->mouse_cursor_hidden = false; + vo_set_cursor_hidden(vo, true); + } x11->xic = XCreateIC(x11->xim, XNInputStyle, XIMPreeditNone | XIMStatusNone, XNClientWindow, x11->window, XNFocusWindow, x11->window, NULL); + + vo_x11_update_window_title(vo); } static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h) @@ -1001,10 +991,10 @@ static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h) vo_x11_decoration(vo, 0); // map window vo_x11_selectinput_witherr(vo, x11->display, x11->window, - StructureNotifyMask | + StructureNotifyMask | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | ExposureMask); + PointerMotionMask | LeaveWindowMask); XMapWindow(x11->display, x11->window); vo_x11_clearwindow(vo, x11->window); } @@ -1041,7 +1031,6 @@ void vo_x11_config_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y, if (flags & VOFLAG_HIDDEN) return; - vo_x11_update_window_title(vo); if (opts->ontop) vo_x11_setlayer(vo, x11->window, opts->ontop); @@ -1275,7 +1264,7 @@ static void vo_x11_update_geometry(struct vo *vo) } } -void vo_x11_fullscreen(struct vo *vo) +static void vo_x11_fullscreen(struct vo *vo) { struct mp_vo_opts *opts = vo->opts; struct vo_x11_state *x11 = vo->x11; @@ -1371,7 +1360,7 @@ void vo_x11_fullscreen(struct vo *vo) x11->pos_changed_during_fs = false; } -void vo_x11_ontop(struct vo *vo) +static void vo_x11_ontop(struct vo *vo) { struct mp_vo_opts *opts = vo->opts; opts->ontop = !opts->ontop; @@ -1379,18 +1368,55 @@ void vo_x11_ontop(struct vo *vo) vo_x11_setlayer(vo, vo->x11->window, opts->ontop); } -void vo_x11_border(struct vo *vo) +static void vo_x11_border(struct vo *vo) { vo->opts->border = !vo->opts->border; vo_x11_decoration(vo, vo->opts->border && !vo->opts->fs); } +int vo_x11_control(struct vo *vo, int *events, int request, void *arg) +{ + struct vo_x11_state *x11 = vo->x11; + switch (request) { + case VOCTRL_CHECK_EVENTS: + *events |= vo_x11_check_events(vo); + return VO_TRUE; + case VOCTRL_FULLSCREEN: + vo_x11_fullscreen(vo); + *events |= VO_EVENT_RESIZE; + return VO_TRUE; + case VOCTRL_ONTOP: + vo_x11_ontop(vo); + return VO_TRUE; + case VOCTRL_BORDER: + vo_x11_border(vo); + *events |= VO_EVENT_RESIZE; + return VO_TRUE; + case VOCTRL_UPDATE_SCREENINFO: + vo_x11_update_screeninfo(vo); + return VO_TRUE; + case VOCTRL_SET_CURSOR_VISIBILITY: + vo_set_cursor_hidden(vo, !(*(bool *)arg)); + return VO_TRUE; + case VOCTRL_KILL_SCREENSAVER: + saver_off(x11); + return VO_TRUE; + case VOCTRL_RESTORE_SCREENSAVER: + saver_on(x11); + return VO_TRUE; + case VOCTRL_UPDATE_WINDOW_TITLE: + vo_x11_update_window_title(vo); + return VO_TRUE; + } + return VO_NOTIMPL; +} + static void xscreensaver_heartbeat(struct vo_x11_state *x11) { - unsigned int time = GetTimerMS(); + double time = mp_time_sec(); if (x11->display && x11->screensaver_off && - (time - x11->screensaver_time_last) > 30000) + (time - x11->screensaver_time_last) > 30) { x11->screensaver_time_last = time; @@ -1519,7 +1545,7 @@ double vo_x11_vm_get_fps(struct vo *vo) return 1e3 * clock / modeline.htotal / modeline.vtotal; } #else /* CONFIG_XF86VM */ -double vo_vm_get_fps(struct vo *vo) +double vo_x11_vm_get_fps(struct vo *vo) { return 0; } |