summaryrefslogtreecommitdiffstats
path: root/video/out/x11_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/x11_common.c')
-rw-r--r--video/out/x11_common.c86
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)