diff options
Diffstat (limited to 'video/out/x11_common.c')
-rw-r--r-- | video/out/x11_common.c | 86 |
1 files changed, 49 insertions, 37 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 13da2706fb..2e5f14f8d1 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -44,6 +44,7 @@ #include <X11/Xutil.h> #include <X11/Xatom.h> #include <X11/keysym.h> +#include <X11/XKBlib.h> #ifdef CONFIG_XSS #include <X11/extensions/scrnsaver.h> @@ -450,6 +451,12 @@ int vo_x11_init(struct vo *vo) x11->screen = DefaultScreen(x11->display); // screen ID x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID + if (!opts->native_keyrepeat) { + Bool ok = False; + XkbSetDetectableAutoRepeat(x11->display, True, &ok); + x11->no_autorepeat = ok; + } + x11->xim = XOpenIM(x11->display, NULL, NULL, NULL); init_atoms(vo->x11); @@ -629,6 +636,8 @@ 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); + saver_on(x11); if (x11->window != None) vo_showcursor(vo, x11->display, x11->window); @@ -721,6 +730,8 @@ int vo_x11_check_events(struct vo *vo) char buf[100]; KeySym keySym = 0; int modifiers = 0; + if (x11->no_autorepeat) + modifiers |= MP_KEY_STATE_DOWN; if (Event.xkey.state & ShiftMask) modifiers |= MP_KEY_MODIFIER_SHIFT; if (Event.xkey.state & ControlMask) @@ -747,8 +758,17 @@ int vo_x11_check_events(struct vo *vo) if (mpkey) mplayer_put_key(vo->key_fifo, mpkey | modifiers); } + break; + } + // Releasing all keys in these situations is simpler and ensures no + // keys can be get "stuck". + case FocusOut: + case KeyRelease: + { + if (x11->no_autorepeat) + mplayer_put_key(vo->key_fifo, MP_INPUT_RELEASE_ALL); + break; } - break; case MotionNotify: vo_mouse_movement(vo, Event.xmotion.x, Event.xmotion.y); vo_x11_unhide_cursor(vo); @@ -924,16 +944,6 @@ static void vo_x11_update_window_title(struct vo *vo) vo_x11_set_property_utf8(vo, x11->XA_NET_WM_ICON_NAME, title); } -static void setup_window_params(struct vo_x11_state *x11, XVisualInfo *vis, - unsigned long *mask, XSetWindowAttributes *att) -{ - vo_x11_create_colormap(x11, vis); - - *mask = CWBorderPixel | CWColormap; - att->border_pixel = 0; - att->colormap = x11->colormap; -} - static void find_default_visual(struct vo_x11_state *x11, XVisualInfo *vis) { Display *display = x11->display; @@ -956,9 +966,12 @@ static void vo_x11_create_window(struct vo *vo, XVisualInfo *vis, int x, int y, find_default_visual(x11, vis); } - unsigned long xswamask; - XSetWindowAttributes xswa; - setup_window_params(x11, vis, &xswamask, &xswa); + vo_x11_create_colormap(x11, vis); + unsigned long xswamask = CWBorderPixel | CWColormap; + XSetWindowAttributes xswa = { + .border_pixel = 0, + .colormap = x11->colormap, + }; Window parent = vo->opts->WinID >= 0 ? vo->opts->WinID : x11->rootwin; @@ -988,7 +1001,8 @@ 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 | KeyPressMask | + StructureNotifyMask | + KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | ExposureMask); XMapWindow(x11->display, x11->window); @@ -1074,36 +1088,34 @@ void vo_x11_config_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y, x11->pending_vo_events &= ~VO_EVENT_RESIZE; // implicitly done by the VO } -void vo_x11_clearwindow_part(struct vo *vo, Window vo_window, - int img_width, int img_height) +static void fill_rect(struct vo *vo, GC gc, int x0, int y0, int x1, int y1) { struct vo_x11_state *x11 = vo->x11; - Display *mDisplay = vo->x11->display; - int u_dheight, u_dwidth, left_ov, left_ov2; - if (x11->f_gc == None) - return; + x0 = FFMAX(x0, 0); + y0 = FFMAX(y0, 0); + x1 = FFMIN(x1, x11->win_width); + y1 = FFMIN(y1, x11->win_height); - u_dheight = x11->win_height; - u_dwidth = x11->win_width; - if ((u_dheight <= img_height) && (u_dwidth <= img_width)) - return; + if (x11->window && x1 > x0 && y1 > y0) + XFillRectangle(x11->display, x11->window, gc, x0, y0, x1 - x0, y1 - y0); +} - left_ov = (u_dheight - img_height) / 2; - left_ov2 = (u_dwidth - img_width) / 2; +// Clear everything outside of rc with the background color +void vo_x11_clear_background(struct vo *vo, const struct mp_rect *rc) +{ + struct vo_x11_state *x11 = vo->x11; + GC gc = x11->f_gc; - XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, 0, u_dwidth, left_ov); - XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, u_dheight - left_ov - 1, - u_dwidth, left_ov + 1); + int w = x11->win_width; + int h = x11->win_height; - if (u_dwidth > img_width) { - XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, left_ov, left_ov2, - img_height); - XFillRectangle(mDisplay, vo_window, x11->f_gc, u_dwidth - left_ov2 - 1, - left_ov, left_ov2 + 1, img_height); - } + fill_rect(vo, gc, 0, 0, w, rc->y0); // top + fill_rect(vo, gc, 0, rc->y1, w, h); // bottom + fill_rect(vo, gc, 0, rc->y0, rc->x0, rc->y1); // left + fill_rect(vo, gc, rc->x1, rc->y0, w, rc->y1); // right - XFlush(mDisplay); + XFlush(x11->display); } void vo_x11_clearwindow(struct vo *vo, Window vo_window) |