diff options
Diffstat (limited to 'video/out/x11_common.c')
-rw-r--r-- | video/out/x11_common.c | 1108 |
1 files changed, 251 insertions, 857 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 9176165b8b..6e6a6861e5 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -65,41 +65,76 @@ #include <X11/XF86keysym.h> #endif -#ifdef CONFIG_XV -#include <X11/extensions/Xv.h> -#include <X11/extensions/Xvlib.h> - -#include "core/subopt-helper.h" -#endif - #include "core/input/input.h" #include "core/input/keycodes.h" +#define vo_wm_LAYER 1 +#define vo_wm_FULLSCREEN 2 +#define vo_wm_STAYS_ON_TOP 4 +#define vo_wm_ABOVE 8 +#define vo_wm_BELOW 16 +#define vo_wm_NETWM (vo_wm_FULLSCREEN | vo_wm_STAYS_ON_TOP | vo_wm_ABOVE | vo_wm_BELOW) + +/* EWMH state actions, see + http://freedesktop.org/Standards/wm-spec/index.html#id2768769 */ +#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ +#define _NET_WM_STATE_ADD 1 /* add/set property */ +#define _NET_WM_STATE_TOGGLE 2 /* toggle property */ + #define WIN_LAYER_ONBOTTOM 2 #define WIN_LAYER_NORMAL 4 #define WIN_LAYER_ONTOP 6 #define WIN_LAYER_ABOVE_DOCK 10 -int fs_layer = WIN_LAYER_ABOVE_DOCK; +// ----- Motif header: ------- + +#define MWM_HINTS_FUNCTIONS (1L << 0) +#define MWM_HINTS_DECORATIONS (1L << 1) +#define MWM_HINTS_INPUT_MODE (1L << 2) +#define MWM_HINTS_STATUS (1L << 3) + +#define MWM_FUNC_ALL (1L << 0) +#define MWM_FUNC_RESIZE (1L << 1) +#define MWM_FUNC_MOVE (1L << 2) +#define MWM_FUNC_MINIMIZE (1L << 3) +#define MWM_FUNC_MAXIMIZE (1L << 4) +#define MWM_FUNC_CLOSE (1L << 5) -int stop_xscreensaver = 1; +#define MWM_DECOR_ALL (1L << 0) +#define MWM_DECOR_BORDER (1L << 1) +#define MWM_DECOR_RESIZEH (1L << 2) +#define MWM_DECOR_TITLE (1L << 3) +#define MWM_DECOR_MENU (1L << 4) +#define MWM_DECOR_MINIMIZE (1L << 5) +#define MWM_DECOR_MAXIMIZE (1L << 6) -static int dpms_disabled = 0; +#define MWM_INPUT_MODELESS 0 +#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 +#define MWM_INPUT_SYSTEM_MODAL 2 +#define MWM_INPUT_FULL_APPLICATION_MODAL 3 +#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL -char **vo_fstype_list; +#define MWM_TEAROFF_WINDOW (1L<<0) -/* 1 means that the WM is metacity (broken as hell) */ -int metacity_hack = 0; +typedef struct +{ + long flags; + long functions; + long decorations; + long input_mode; + long state; +} MotifWmHints; -#ifdef CONFIG_XF86VM -static int modecount; -static XF86VidModeModeInfo **vidmodes; -static XF86VidModeModeLine modeline; -#endif +static XErrorHandler old_handler = NULL; +static int selectinput_err = 0; -static int vo_x11_get_fs_type(int supported); -static void saver_off(Display *); -static void saver_on(Display *); +static void vo_x11_update_geometry(struct vo *vo, bool update_pos); +static int vo_x11_get_fs_type(struct vo *vo); +static void saver_on(struct vo_x11_state *x11); +static void saver_off(struct vo_x11_state *x11); +static void vo_x11_selectinput_witherr(Display *display, Window w, + long event_mask); +static void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer); /* * Sends the EWMH fullscreen state event. @@ -108,7 +143,7 @@ static void saver_on(Display *); * _NET_WM_STATE_ADD -- add state * _NET_WM_STATE_TOGGLE -- toggle */ -void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action) +static void vo_x11_ewmh_fullscreen(struct vo_x11_state *x11, int action) { assert(action == _NET_WM_STATE_REMOVE || action == _NET_WM_STATE_ADD || action == _NET_WM_STATE_TOGGLE); @@ -279,17 +314,18 @@ static int vo_wm_detect(struct vo *vo) if (x11_get_property(x11, x11->XA_WIN_PROTOCOLS, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports layers.\n"); + int metacity_hack = 0; for (i = 0; i < nitems; i++) { - if (args[i] == x11->XA_WIN_LAYER) - { + if (args[i] == x11->XA_WIN_LAYER) { wm |= vo_wm_LAYER; metacity_hack |= 1; - } else + } else { /* metacity is the only window manager I know which reports * supporting only the _WIN_LAYER hint in _WIN_PROTOCOLS. * (what's more support for it is broken) */ metacity_hack |= 2; + } } XFree(args); if (wm && (metacity_hack == 1)) @@ -337,7 +373,7 @@ static void init_atoms(struct vo_x11_state *x11) x11->XA_NET_WM_CM = XInternAtom(x11->display, buf, False); } -void update_xinerama_info(struct vo *vo) { +void vo_x11_update_screeninfo(struct vo *vo) { struct MPOpts *opts = vo->opts; xinerama_x = xinerama_y = 0; #ifdef CONFIG_XINERAMA @@ -375,36 +411,26 @@ void update_xinerama_info(struct vo *vo) { aspect_save_screenres(vo, opts->vo_screenwidth, opts->vo_screenheight); } -int vo_init(struct vo *vo) +int vo_x11_init(struct vo *vo) { struct MPOpts *opts = vo->opts; -// int mScreen; - int depth, bpp; - unsigned int mask; - -// char * DisplayName = ":0.0"; -// Display * mDisplay; - XImage *mXImage = NULL; - -// Window mRootWin; - XWindowAttributes attribs; char *dispName; - if (vo->x11) - return 1; + assert(!vo->x11); - vo->x11 = vo_x11_init_state(); - struct vo_x11_state *x11 = vo->x11; + struct vo_x11_state *x11 = talloc_ptrtype(NULL, x11); + *x11 = (struct vo_x11_state){ + .olddecor = MWM_DECOR_ALL, + .oldfuncs = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | + MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE, + .old_gravity = NorthWestGravity, + .fs_layer = WIN_LAYER_ABOVE_DOCK, + }; + vo->x11 = x11; if (vo_rootwin) WinID = 0; // use root window - if (x11->depthonscreen) - { - saver_off(x11->display); - return 1; // already called - } - XSetErrorHandler(x11_errorhandler); dispName = XDisplayName(NULL); @@ -430,6 +456,7 @@ int vo_init(struct vo *vo) #ifdef CONFIG_XF86VM { int clock; + XF86VidModeModeLine modeline; XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline); if (!opts->vo_screenwidth) @@ -444,55 +471,7 @@ int vo_init(struct vo *vo) if (!opts->vo_screenheight) opts->vo_screenheight = DisplayHeight(x11->display, x11->screen); } - // get color depth (from root window, or the best visual): - XGetWindowAttributes(x11->display, x11->rootwin, &attribs); - depth = attribs.depth; - if (depth != 15 && depth != 16 && depth != 24 && depth != 32) - { - Visual *visual; - - depth = vo_find_depth_from_visuals(x11->display, x11->screen, &visual); - if (depth != -1) - mXImage = XCreateImage(x11->display, visual, depth, ZPixmap, - 0, NULL, 1, 1, 8, 1); - } else - mXImage = - XGetImage(x11->display, x11->rootwin, 0, 0, 1, 1, AllPlanes, ZPixmap); - - x11->depthonscreen = depth; // display depth on screen - - // get bits/pixel from XImage structure: - if (mXImage == NULL) - { - mask = 0; - } else - { - /* - * for the depth==24 case, the XImage structures might use - * 24 or 32 bits of data per pixel. The x11->depthonscreen - * field stores the amount of data per pixel in the - * XImage structure! - * - * Maybe we should rename vo_depthonscreen to (or add) vo_bpp? - */ - bpp = mXImage->bits_per_pixel; - if ((x11->depthonscreen + 7) / 8 != (bpp + 7) / 8) - x11->depthonscreen = bpp; // by A'rpi - mask = - mXImage->red_mask | mXImage->green_mask | mXImage->blue_mask; - mp_msg(MSGT_VO, MSGL_V, - "vo: X11 color mask: %X (R:%lX G:%lX B:%lX)\n", mask, - mXImage->red_mask, mXImage->green_mask, mXImage->blue_mask); - XDestroyImage(mXImage); - } - if (((x11->depthonscreen + 7) / 8) == 2) - { - if (mask == 0x7FFF) - x11->depthonscreen = 15; - else if (mask == 0xFFFF) - x11->depthonscreen = 16; - } // XCloseDisplay( mDisplay ); /* slightly improved local display detection AST */ if (strncmp(dispName, "unix:", 5) == 0) @@ -503,39 +482,20 @@ int vo_init(struct vo *vo) x11->display_is_local = 1; else x11->display_is_local = 0; - mp_msg(MSGT_VO, MSGL_V, - "vo: X11 running at %dx%d with depth %d and %d bpp (\"%s\" => %s display)\n", - opts->vo_screenwidth, opts->vo_screenheight, depth, x11->depthonscreen, - dispName, x11->display_is_local ? "local" : "remote"); + mp_msg(MSGT_VO, MSGL_V, "vo: X11 running at %dx%d (\"%s\" => %s display)\n", + opts->vo_screenwidth, opts->vo_screenheight, dispName, + x11->display_is_local ? "local" : "remote"); x11->wm_type = vo_wm_detect(vo); - x11->fs_type = vo_x11_get_fs_type(x11->wm_type); + x11->fs_type = vo_x11_get_fs_type(vo); fstype_dump(x11->fs_type); - saver_off(x11->display); - return 1; -} + if (opts->vo_stop_screensaver) + saver_off(x11); -void vo_uninit(struct vo_x11_state *x11) -{ - if (!x11) - return; - if (!x11->display) - { - mp_msg(MSGT_VO, MSGL_V, - "vo: x11 uninit called but X11 not initialized..\n"); - } else { - mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n"); - if (x11->xim) - XCloseIM(x11->xim); - XSetErrorHandler(NULL); - XCloseDisplay(x11->display); - x11->depthonscreen = 0; - x11->display = NULL; - } - talloc_free(x11); + return 1; } static const struct mp_keymap keymap[] = { @@ -599,55 +559,14 @@ static int vo_x11_lookupkey(int key) return mpkey; } - -// ----- Motif header: ------- - -#define MWM_HINTS_FUNCTIONS (1L << 0) -#define MWM_HINTS_DECORATIONS (1L << 1) -#define MWM_HINTS_INPUT_MODE (1L << 2) -#define MWM_HINTS_STATUS (1L << 3) - -#define MWM_FUNC_ALL (1L << 0) -#define MWM_FUNC_RESIZE (1L << 1) -#define MWM_FUNC_MOVE (1L << 2) -#define MWM_FUNC_MINIMIZE (1L << 3) -#define MWM_FUNC_MAXIMIZE (1L << 4) -#define MWM_FUNC_CLOSE (1L << 5) - -#define MWM_DECOR_ALL (1L << 0) -#define MWM_DECOR_BORDER (1L << 1) -#define MWM_DECOR_RESIZEH (1L << 2) -#define MWM_DECOR_TITLE (1L << 3) -#define MWM_DECOR_MENU (1L << 4) -#define MWM_DECOR_MINIMIZE (1L << 5) -#define MWM_DECOR_MAXIMIZE (1L << 6) - -#define MWM_INPUT_MODELESS 0 -#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1 -#define MWM_INPUT_SYSTEM_MODAL 2 -#define MWM_INPUT_FULL_APPLICATION_MODAL 3 -#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL - -#define MWM_TEAROFF_WINDOW (1L<<0) - -typedef struct -{ - long flags; - long functions; - long decorations; - long input_mode; - long state; -} MotifWmHints; - -static MotifWmHints vo_MotifWmHints; -static Atom vo_MotifHints = None; - -void vo_x11_decoration(struct vo *vo, int d) +static void vo_x11_decoration(struct vo *vo, int d) { struct vo_x11_state *x11 = vo->x11; Atom mtype; int mformat; unsigned long mn, mb; + Atom vo_MotifHints; + MotifWmHints vo_MotifWmHints; if (!WinID) return; @@ -702,7 +621,7 @@ void vo_x11_decoration(struct vo *vo, int d) } } -void vo_x11_classhint(struct vo *vo, Window window, const char *name) +static void vo_x11_classhint(struct vo *vo, Window window, const char *name) { struct MPOpts *opts = vo->opts; struct vo_x11_state *x11 = vo->x11; @@ -719,51 +638,41 @@ void vo_x11_classhint(struct vo *vo, Window window, const char *name) void vo_x11_uninit(struct vo *vo) { struct vo_x11_state *x11 = vo->x11; - saver_on(x11->display); + assert(x11); + + saver_on(x11); if (x11->window != None) vo_showcursor(x11->display, x11->window); if (x11->f_gc != None) - { XFreeGC(vo->x11->display, x11->f_gc); - x11->f_gc = None; - } - { - if (x11->vo_gc != None) - { - XFreeGC(vo->x11->display, x11->vo_gc); - x11->vo_gc = None; + if (x11->vo_gc != None) + XFreeGC(vo->x11->display, x11->vo_gc); + if (x11->window != None) { + XClearWindow(x11->display, x11->window); + if (WinID < 0) { + XEvent xev; + + XUnmapWindow(x11->display, x11->window); + XSelectInput(x11->display, x11->window, StructureNotifyMask); + XDestroyWindow(x11->display, x11->window); + do { + XNextEvent(x11->display, &xev); + } while (xev.type != DestroyNotify || + xev.xdestroywindow.event != x11->window); } - if (x11->window != None) - { - XClearWindow(x11->display, x11->window); - if (WinID < 0) - { - XEvent xev; + } + if (x11->xic) + XDestroyIC(x11->xic); + vo_fs = 0; - if (x11->xic) - XDestroyIC(x11->xic); - x11->xic = NULL; + mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n"); + if (x11->xim) + XCloseIM(x11->xim); + XSetErrorHandler(NULL); + XCloseDisplay(x11->display); - XUnmapWindow(x11->display, x11->window); - XSelectInput(x11->display, x11->window, StructureNotifyMask); - XDestroyWindow(x11->display, x11->window); - do - { - XNextEvent(x11->display, &xev); - } - while (xev.type != DestroyNotify - || xev.xdestroywindow.event != x11->window); - } - x11->window = None; - } - vo_fs = 0; - x11->vo_old_width = x11->vo_old_height = 0; - x11->last_video_width = 0; - x11->last_video_height = 0; - x11->size_changed_during_fs = false; - } - vo_uninit(x11); + talloc_free(x11); vo->x11 = NULL; } @@ -912,40 +821,8 @@ int vo_x11_check_events(struct vo *vo) return ret; } -/** - * \brief sets the size and position of the non-fullscreen window. - */ -static void vo_x11_nofs_sizepos(struct vo *vo, int x, int y, - int width, int height) -{ - struct vo_x11_state *x11 = vo->x11; - if (width == x11->last_video_width && height == x11->last_video_height) { - if (!vo->opts->force_window_position && !x11->size_changed_during_fs) - return; - } else if (vo_fs) - x11->size_changed_during_fs = true; - x11->last_video_height = height; - x11->last_video_width = width; - vo_x11_sizehint(vo, x, y, width, height, 0); - if (vo_fs) { - x11->vo_old_x = x; - x11->vo_old_y = y; - x11->vo_old_width = width; - x11->vo_old_height = height; - } - else - { - vo->dwidth = width; - vo->dheight = height; - if (vo->opts->force_window_position) - XMoveResizeWindow(vo->x11->display, vo->x11->window, x, y, width, - height); - else - XResizeWindow(vo->x11->display, vo->x11->window, width, height); - } -} - -void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max) +static void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, + int max) { struct vo_x11_state *x11 = vo->x11; x11->vo_hint.flags = 0; @@ -990,6 +867,39 @@ void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max XSetWMNormalHints(x11->display, x11->window, &x11->vo_hint); } +/** + * \brief sets the size and position of the non-fullscreen window. + */ +static void vo_x11_nofs_sizepos(struct vo *vo, int x, int y, + int width, int height) +{ + struct vo_x11_state *x11 = vo->x11; + if (width == x11->last_video_width && height == x11->last_video_height) { + if (!vo->opts->force_window_position && !x11->size_changed_during_fs) + return; + } else if (vo_fs) + x11->size_changed_during_fs = true; + x11->last_video_height = height; + x11->last_video_width = width; + vo_x11_sizehint(vo, x, y, width, height, 0); + if (vo_fs) { + x11->vo_old_x = x; + x11->vo_old_y = y; + x11->vo_old_width = width; + x11->vo_old_height = height; + } + else + { + vo->dwidth = width; + vo->dheight = height; + if (vo->opts->force_window_position) + XMoveResizeWindow(vo->x11->display, vo->x11->window, x, y, width, + height); + else + XResizeWindow(vo->x11->display, vo->x11->window, width, height); + } +} + static int vo_x11_get_gnome_layer(struct vo_x11_state *x11, Window win) { Atom type; @@ -1232,7 +1142,7 @@ void vo_x11_clearwindow(struct vo *vo, Window vo_window) } -void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer) +static void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer) { struct vo_x11_state *x11 = vo->x11; if (WinID >= 0) @@ -1251,7 +1161,8 @@ void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer) xev.window = vo_window; xev.message_type = x11->XA_WIN_LAYER; xev.format = 32; - xev.data.l[0] = layer ? fs_layer : x11->orig_layer; // if not fullscreen, stay on default layer + // if not fullscreen, stay on default layer + xev.data.l[0] = layer ? x11->fs_layer : x11->orig_layer; xev.data.l[1] = CurrentTime; mp_msg(MSGT_VO, MSGL_V, "[x11] Layered style stay on top (layer %ld).\n", @@ -1292,22 +1203,24 @@ void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer) } } -static int vo_x11_get_fs_type(int supported) +static int vo_x11_get_fs_type(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + int type = x11->wm_type; + char **fstype_list = vo->opts->vo_fstype_list; int i; - int type = supported; - if (vo_fstype_list) + if (fstype_list) { - for (i = 0; vo_fstype_list[i]; i++) + for (i = 0; fstype_list[i]; i++) { int neg = 0; - char *arg = vo_fstype_list[i]; + char *arg = fstype_list[i]; - if (vo_fstype_list[i][0] == '-') + if (fstype_list[i][0] == '-') { neg = 1; - arg = vo_fstype_list[i] + 1; + arg = fstype_list[i] + 1; } if (!strncmp(arg, "layer", 5)) @@ -1315,11 +1228,11 @@ static int vo_x11_get_fs_type(int supported) if (!neg && (arg[5] == '=')) { char *endptr = NULL; - int layer = strtol(vo_fstype_list[i] + 6, &endptr, 10); + int layer = strtol(fstype_list[i] + 6, &endptr, 10); if (endptr && *endptr == '\0' && layer >= 0 && layer <= 15) - fs_layer = layer; + x11->fs_layer = layer; } if (neg) type &= ~vo_wm_LAYER; @@ -1363,18 +1276,15 @@ static int vo_x11_get_fs_type(int supported) return type; } -/** - * \brief update vo->dx, vo->dy, vo->dwidth and vo->dheight with current values of vo->x11->window - * \return returns current color depth of vo->x11->window - */ -int vo_x11_update_geometry(struct vo *vo, bool update_pos) +// update vo->dx, vo->dy, vo->dwidth and vo->dheight with current values of vo->x11->window +static void vo_x11_update_geometry(struct vo *vo, bool update_pos) { struct vo_x11_state *x11 = vo->x11; - unsigned depth, w, h; + unsigned w, h, dummy_uint; int dummy_int; Window dummy_win; XGetGeometry(x11->display, x11->window, &dummy_win, &dummy_int, &dummy_int, - &w, &h, &dummy_int, &depth); + &w, &h, &dummy_int, &dummy_uint); if (w <= INT_MAX && h <= INT_MAX) { vo->dwidth = w; vo->dheight = h; @@ -1382,8 +1292,6 @@ int vo_x11_update_geometry(struct vo *vo, bool update_pos) if (update_pos) XTranslateCoordinates(x11->display, x11->window, x11->rootwin, 0, 0, &vo->dx, &vo->dy, &dummy_win); - - return depth <= INT_MAX ? depth : 0; } void vo_x11_fullscreen(struct vo *vo) @@ -1424,7 +1332,7 @@ void vo_x11_fullscreen(struct vo *vo) x11->vo_old_width = vo->dwidth; x11->vo_old_height = vo->dheight; } - update_xinerama_info(vo); + vo_x11_update_screeninfo(vo); x = xinerama_x; y = xinerama_y; w = opts->vo_screenwidth; @@ -1484,16 +1392,14 @@ void vo_x11_border(struct vo *vo) * XScreensaver stuff */ -static int screensaver_off; -static unsigned int time_last; - void xscreensaver_heartbeat(struct vo_x11_state *x11) { unsigned int time = GetTimerMS(); - if (x11->display && screensaver_off && (time - time_last) > 30000) + if (x11->display && x11->screensaver_off && + (time - x11->screensaver_time_last) > 30000) { - time_last = time; + x11->screensaver_time_last = time; XResetScreenSaver(x11->display); } @@ -1519,25 +1425,21 @@ static int xss_suspend(Display *mDisplay, Bool suspend) * End of XScreensaver stuff */ -static void saver_on(Display * mDisplay) +static void saver_on(struct vo_x11_state *x11) { - - if (!screensaver_off) + Display *mDisplay = x11->display; + if (!x11->screensaver_off) return; - screensaver_off = 0; + x11->screensaver_off = 0; if (xss_suspend(mDisplay, False)) return; #ifdef CONFIG_XDPMS - if (dpms_disabled) - { + if (x11->dpms_disabled) { int nothing; - if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) - { - if (!DPMSEnable(mDisplay)) - { // restoring power saving settings + if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) { + if (!DPMSEnable(mDisplay)) { // restoring power saving settings mp_msg(MSGT_VO, MSGL_WARN, "DPMS not available?\n"); - } else - { + } else { // DPMS does not seem to be enabled unless we call DPMSInfo BOOL onoff; CARD16 state; @@ -1554,18 +1456,19 @@ static void saver_on(Display * mDisplay) } } } - dpms_disabled = 0; + x11->dpms_disabled = 0; } #endif } -static void saver_off(Display * mDisplay) +static void saver_off(struct vo_x11_state *x11) { + Display *mDisplay = x11->display; int nothing; - if (!stop_xscreensaver || screensaver_off) + if (x11->screensaver_off) return; - screensaver_off = 1; + x11->screensaver_off = 1; if (xss_suspend(mDisplay, True)) return; #ifdef CONFIG_XDPMS @@ -1580,7 +1483,7 @@ static void saver_off(Display * mDisplay) Status stat; mp_msg(MSGT_VO, MSGL_V, "Disabling DPMS\n"); - dpms_disabled = 1; + x11->dpms_disabled = 1; stat = DPMSDisable(mDisplay); // monitor powersave off mp_msg(MSGT_VO, MSGL_V, "DPMSDisable stat: %d\n", stat); } @@ -1588,8 +1491,6 @@ static void saver_off(Display * mDisplay) #endif } -static XErrorHandler old_handler = NULL; -static int selectinput_err = 0; static int x11_selectinput_errorhandler(Display * display, XErrorEvent * event) { @@ -1611,8 +1512,8 @@ static int x11_selectinput_errorhandler(Display * display, return 0; } -void vo_x11_selectinput_witherr(Display * display, Window w, - long event_mask) +static void vo_x11_selectinput_witherr(Display * display, Window w, + long event_mask) { XSync(display, False); old_handler = XSetErrorHandler(x11_selectinput_errorhandler); @@ -1663,18 +1564,18 @@ void vo_vm_switch(struct vo *vo) "XF86VidMode extension not available.\n"); } - if (have_vm) - { - if (vidmodes == NULL) - XF86VidModeGetAllModeLines(mDisplay, x11->screen, &modecount, - &vidmodes); + if (have_vm) { + int modecount = 0; + XF86VidModeModeInfo **vidmodes = NULL; + XF86VidModeGetAllModeLines(mDisplay, x11->screen, &modecount, &vidmodes); j = 0; modeline_width = vidmodes[0]->hdisplay; modeline_height = vidmodes[0]->vdisplay; - for (i = 1; i < modecount; i++) + for (i = 1; i < modecount; i++) { if ((vidmodes[i]->hdisplay >= X) && (vidmodes[i]->vdisplay >= Y)) + { if ((vidmodes[i]->hdisplay <= modeline_width) && (vidmodes[i]->vdisplay <= modeline_height)) { @@ -1682,6 +1583,8 @@ void vo_vm_switch(struct vo *vo) modeline_height = vidmodes[i]->vdisplay; j = i; } + } + } mp_tmsg(MSGT_VO, MSGL_INFO, "XF86VM: Selected video mode %dx%d for image size %dx%d.\n", modeline_width, modeline_height, X, Y); @@ -1698,21 +1601,23 @@ void vo_vm_switch(struct vo *vo) vo->dwidth = modeline_width; vo->dheight = modeline_height; aspect_save_screenres(vo, modeline_width, modeline_height); + + x11->vm_set = 1; + free(vidmodes); } } void vo_vm_close(struct vo *vo) { - Display *dpy = vo->x11->display; + struct vo_x11_state *x11 = vo->x11; + Display *dpy = x11->display; struct MPOpts *opts = vo->opts; - if (vidmodes != NULL) - { + if (x11->vm_set) { + int modecount = 0; + XF86VidModeModeInfo **vidmodes = NULL; int i; - free(vidmodes); - vidmodes = NULL; - XF86VidModeGetAllModeLines(dpy, vo->x11->screen, &modecount, - &vidmodes); + XF86VidModeGetAllModeLines(dpy, x11->screen, &modecount, &vidmodes); for (i = 0; i < modecount; i++) if ((vidmodes[i]->hdisplay == opts->vo_screenwidth) && (vidmodes[i]->vdisplay == opts->vo_screenheight)) @@ -1723,10 +1628,9 @@ void vo_vm_close(struct vo *vo) break; } - XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); - XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, x11->screen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, x11->screen, vidmodes[i]); free(vidmodes); - vidmodes = NULL; modecount = 0; } } @@ -1745,64 +1649,6 @@ double vo_vm_get_fps(struct vo *vo) #endif -/* - * Scan the available visuals on this Display/Screen. Try to find - * the 'best' available TrueColor visual that has a decent color - * depth (at least 15bit). If there are multiple visuals with depth - * >= 15bit, we prefer visuals with a smaller color depth. - */ -int vo_find_depth_from_visuals(Display * dpy, int screen, - Visual ** visual_return) -{ - XVisualInfo visual_tmpl; - XVisualInfo *visuals; - int nvisuals, i; - int bestvisual = -1; - int bestvisual_depth = -1; - - visual_tmpl.screen = screen; - visual_tmpl.class = TrueColor; - visuals = XGetVisualInfo(dpy, - VisualScreenMask | VisualClassMask, - &visual_tmpl, &nvisuals); - if (visuals != NULL) - { - for (i = 0; i < nvisuals; i++) - { - mp_msg(MSGT_VO, MSGL_V, - "vo: X11 truecolor visual %#lx, depth %d, R:%lX G:%lX B:%lX\n", - visuals[i].visualid, visuals[i].depth, - visuals[i].red_mask, visuals[i].green_mask, - visuals[i].blue_mask); - /* - * Save the visual index and its depth, if this is the first - * truecolor visul, or a visual that is 'preferred' over the - * previous 'best' visual. - */ - if (bestvisual_depth == -1 - || (visuals[i].depth >= 15 - && (visuals[i].depth < bestvisual_depth - || bestvisual_depth < 15))) - { - bestvisual = i; - bestvisual_depth = visuals[i].depth; - } - } - - if (bestvisual != -1 && visual_return != NULL) - *visual_return = visuals[bestvisual].visual; - - XFree(visuals); - } - return bestvisual_depth; -} - - -static Colormap cmap = None; -static XColor cols[256]; -static int cm_size, red_mask, green_mask, blue_mask; - - Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo) { struct vo_x11_state *x11 = vo->x11; @@ -1813,39 +1659,39 @@ Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo) AllocNone); /* can this function get called twice or more? */ - if (cmap) - return cmap; - cm_size = vinfo->colormap_size; - red_mask = vinfo->red_mask; - green_mask = vinfo->green_mask; - blue_mask = vinfo->blue_mask; - ru = (red_mask & (red_mask - 1)) ^ red_mask; - gu = (green_mask & (green_mask - 1)) ^ green_mask; - bu = (blue_mask & (blue_mask - 1)) ^ blue_mask; - rvu = 65536ull * ru / (red_mask + ru); - gvu = 65536ull * gu / (green_mask + gu); - bvu = 65536ull * bu / (blue_mask + bu); + if (x11->cmap) + return x11->cmap; + x11->cm_size = vinfo->colormap_size; + x11->red_mask = vinfo->red_mask; + x11->green_mask = vinfo->green_mask; + x11->blue_mask = vinfo->blue_mask; + ru = (x11->red_mask & (x11->red_mask - 1)) ^ x11->red_mask; + gu = (x11->green_mask & (x11->green_mask - 1)) ^ x11->green_mask; + bu = (x11->blue_mask & (x11->blue_mask - 1)) ^ x11->blue_mask; + rvu = 65536ull * ru / (x11->red_mask + ru); + gvu = 65536ull * gu / (x11->green_mask + gu); + bvu = 65536ull * bu / (x11->blue_mask + bu); r = g = b = 0; rv = gv = bv = 0; m = DoRed | DoGreen | DoBlue; - for (k = 0; k < cm_size; k++) + for (k = 0; k < x11->cm_size; k++) { int t; - cols[k].pixel = r | g | b; - cols[k].red = rv; - cols[k].green = gv; - cols[k].blue = bv; - cols[k].flags = m; - t = (r + ru) & red_mask; + x11->cols[k].pixel = r | g | b; + x11->cols[k].red = rv; + x11->cols[k].green = gv; + x11->cols[k].blue = bv; + x11->cols[k].flags = m; + t = (r + ru) & x11->red_mask; if (t < r) m &= ~DoRed; r = t; - t = (g + gu) & green_mask; + t = (g + gu) & x11->green_mask; if (t < g) m &= ~DoGreen; g = t; - t = (b + bu) & blue_mask; + t = (b + bu) & x11->blue_mask; if (t < b) m &= ~DoBlue; b = t; @@ -1853,22 +1699,12 @@ Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo) gv += gvu; bv += bvu; } - cmap = XCreateColormap(x11->display, x11->rootwin, vinfo->visual, AllocAll); - XStoreColors(x11->display, cmap, cols, cm_size); - return cmap; + x11->cmap = XCreateColormap(x11->display, x11->rootwin, vinfo->visual, + AllocAll); + XStoreColors(x11->display, x11->cmap, x11->cols, x11->cm_size); + return x11->cmap; } -/* - * Via colormaps/gamma ramps we can do gamma, brightness, contrast, - * hue and red/green/blue intensity, but we cannot do saturation. - * Currently only gamma, brightness and contrast are implemented. - * Is there sufficient interest for hue and/or red/green/blue intensity? - */ -/* these values have range [-100,100] and are initially 0 */ -static int vo_gamma = 0; -static int vo_brightness = 0; -static int vo_contrast = 0; - static int transform_color(float val, float brightness, float contrast, float gamma) { float s = pow(val, gamma); @@ -1883,9 +1719,13 @@ static int transform_color(float val, uint32_t vo_x11_set_equalizer(struct vo *vo, const char *name, int value) { + struct vo_x11_state *x11 = vo->x11; float gamma, brightness, contrast; float rf, gf, bf; int k; + int red_mask = x11->red_mask; + int green_mask = x11->green_mask; + int blue_mask = x11->blue_mask; /* * IMPLEMENTME: consider using XF86VidModeSetGammaRamp in the case @@ -1898,21 +1738,21 @@ uint32_t vo_x11_set_equalizer(struct vo *vo, const char *name, int value) * for some reason) it is impossible to restore the setting, * and such behaviour could be rather annoying for the users. */ - if (cmap == None) + if (x11->cmap == None) return VO_NOTAVAIL; if (!strcasecmp(name, "brightness")) - vo_brightness = value; + x11->vo_brightness = value; else if (!strcasecmp(name, "contrast")) - vo_contrast = value; + x11->vo_contrast = value; else if (!strcasecmp(name, "gamma")) - vo_gamma = value; + x11->vo_gamma = value; else |