summaryrefslogtreecommitdiffstats
path: root/video/out/vo_x11.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-01-26 22:37:47 +0100
committerwm4 <wm4@nowhere>2013-01-27 13:30:53 +0100
commita243acb1deccd9526f3867d9a6500743dc190f95 (patch)
treeb33cac6a373bc42f6c685d6f9a0281acffcd5007 /video/out/vo_x11.c
parent9747227e47326851c41fceb386d72f498fba7f87 (diff)
downloadmpv-a243acb1deccd9526f3867d9a6500743dc190f95.tar.bz2
mpv-a243acb1deccd9526f3867d9a6500743dc190f95.tar.xz
x11: cleanup, refactor
Move things that are used by vo_xv only into vo_xv, same for vo_x11. Rename some functions exported by x11_common, like vo_init to vo_x11_common. Make functions not used outsode of x11_common.c private to that file. Eliminate all global variables defined by x11_common (except error handler and colormap stuff). There shouldn't be any functional changes, and only code is moved around. There are some minor simplifications in the X11 init code, as we completely remove the ability to initialize X11 and X11+VO separately (see commit b4d9647 "mplayer: do not create X11 state in player frontend"), and the respective functions are conflated into vo_x11_init() and vo_x11_uninit().
Diffstat (limited to 'video/out/vo_x11.c')
-rw-r--r--video/out/vo_x11.c134
1 files changed, 126 insertions, 8 deletions
diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c
index 72ae992eac..9b13ae2893 100644
--- a/video/out/vo_x11.c
+++ b/video/out/vo_x11.c
@@ -88,6 +88,7 @@ struct priv {
int dst_width;
XVisualInfo vinfo;
+ int ximage_depth;
int firstTime;
@@ -123,6 +124,56 @@ static void check_events(struct vo *vo)
flip_page(vo);
}
+/* 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. */
+static int 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 void getMyXImage(struct priv *p, int foo)
{
struct vo *vo = p->vo;
@@ -298,8 +349,8 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
if (p->depth != 15 && p->depth != 16 && p->depth != 24 && p->depth != 32) {
Visual *visual;
- p->depth = vo_find_depth_from_visuals(vo->x11->display, vo->x11->screen,
- &visual);
+ p->depth = find_depth_from_visuals(vo->x11->display, vo->x11->screen,
+ &visual);
}
if (!XMatchVisualInfo(vo->x11->display, vo->x11->screen, p->depth,
DirectColor, &p->vinfo)
@@ -327,8 +378,6 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
vo_x11_create_vo_window(vo, &p->vinfo, vo->dx, vo->dy, vo->dwidth,
vo->dheight, flags, theCmap, "x11");
- if (WinID > 0)
- p->depth = vo_x11_update_geometry(vo, true);
#ifdef CONFIG_XF86VM
if (vm) {
@@ -343,6 +392,15 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
#endif
}
+ if (WinID > 0) {
+ unsigned depth, dummy_uint;
+ int dummy_int;
+ Window dummy_win;
+ XGetGeometry(vo->x11->display, vo->x11->window, &dummy_win, &dummy_int,
+ &dummy_int, &dummy_uint, &dummy_uint, &dummy_uint, &depth);
+ p->depth = depth;
+ }
+
int i;
for (i = 0; i < p->total_buffers; i++)
freeMyXImage(p, i);
@@ -570,13 +628,14 @@ static int redraw_frame(struct vo *vo)
static int query_format(struct vo *vo, uint32_t format)
{
+ struct priv *p = vo->priv;
mp_msg(MSGT_VO, MSGL_DBG2,
"vo_x11: query_format was called: %x (%s)\n", format,
vo_format_name(format));
if (IMGFMT_IS_RGB(format)) {
for (int n = 0; fmt2Xfmt[n].mpfmt; n++) {
if (fmt2Xfmt[n].mpfmt == format) {
- if (IMGFMT_RGB_DEPTH(format) == vo->x11->depthonscreen) {
+ if (IMGFMT_RGB_DEPTH(format) == p->ximage_depth) {
return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
VFCAP_OSD | VFCAP_FLIP;
} else {
@@ -593,6 +652,64 @@ static int query_format(struct vo *vo, uint32_t format)
return 0;
}
+static void find_x11_depth(struct vo *vo)
+{
+ struct vo_x11_state *x11 = vo->x11;
+ struct priv *p = vo->priv;
+ XImage *mXImage = NULL;
+ int depth, bpp, ximage_depth;
+ unsigned int mask;
+ XWindowAttributes attribs;
+
+ // 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 = 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);
+
+ ximage_depth = 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. */
+ bpp = mXImage->bits_per_pixel;
+ if ((ximage_depth + 7) / 8 != (bpp + 7) / 8)
+ ximage_depth = 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 (((ximage_depth + 7) / 8) == 2)
+ {
+ if (mask == 0x7FFF)
+ ximage_depth = 15;
+ else if (mask == 0xFFFF)
+ ximage_depth = 16;
+ }
+
+ mp_msg(MSGT_VO, MSGL_V, "vo: X11 depth %d and %d bpp.\n", depth,
+ ximage_depth);
+
+ p->ximage_depth = ximage_depth;
+}
static void uninit(struct vo *vo)
{
@@ -624,8 +741,9 @@ static int preinit(struct vo *vo, const char *arg)
return ENOSYS;
}
- if (!vo_init(vo))
+ if (!vo_x11_init(vo))
return -1; // Can't open X11
+ find_x11_depth(vo);
return 0;
}
@@ -649,13 +767,13 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_GET_EQUALIZER:
{
struct voctrl_get_equalizer_args *args = data;
- return vo_x11_get_equalizer(args->name, args->valueptr);
+ return vo_x11_get_equalizer(vo, args->name, args->valueptr);
}
case VOCTRL_ONTOP:
vo_x11_ontop(vo);
return VO_TRUE;
case VOCTRL_UPDATE_SCREENINFO:
- update_xinerama_info(vo);
+ vo_x11_update_screeninfo(vo);
return VO_TRUE;
case VOCTRL_REDRAW_FRAME:
return redraw_frame(vo);