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.c1108
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, &nothing, &nothing))
- {
- if (!DPMSEnable(mDisplay))
- { // restoring power saving settings
+ if (DPMSQueryExtension(mDisplay, &nothing, &nothing)) {
+ 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
return VO_NOTIMPL;
- brightness = 0.01 * vo_brightness;
- contrast = tan(0.0095 * (vo_contrast + 100) * M_PI / 4);
- gamma = pow(2, -0.02 * vo_gamma);
+ brightness = 0.01 * x11->vo_brightness;
+ contrast = tan(0.0095 * (x11->vo_contrast + 100) * M_PI / 4);
+ gamma = pow(2, -0.02 * x11->vo_gamma);
rf = (float) ((red_mask & (red_mask - 1)) ^ red_mask) / red_mask;
gf = (float) ((green_mask & (green_mask - 1)) ^ green_mask) /
@@ -1920,28 +1760,29 @@ uint32_t vo_x11_set_equalizer(struct vo *vo, const char *name, int value)
bf = (float) ((blue_mask & (blue_mask - 1)) ^