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.c170
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;
}