diff options
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/gl_common.c | 4 | ||||
-rw-r--r-- | video/out/vo_vdpau.c | 4 | ||||
-rw-r--r-- | video/out/vo_x11.c | 134 | ||||
-rw-r--r-- | video/out/vo_xv.c | 408 | ||||
-rw-r--r-- | video/out/x11_common.c | 1108 | ||||
-rw-r--r-- | video/out/x11_common.h | 84 |
6 files changed, 774 insertions, 968 deletions
diff --git a/video/out/gl_common.c b/video/out/gl_common.c index dc249f4a73..887195bf18 100644 --- a/video/out/gl_common.c +++ b/video/out/gl_common.c @@ -1392,12 +1392,12 @@ MPGLContext *mpgl_init(enum MPGLType type, struct vo *vo) ctx->create_window_gl3 = create_window_x11_gl3; ctx->releaseGlContext = releaseGlContext_x11; ctx->swapGlBuffers = swapGlBuffers_x11; - ctx->update_xinerama_info = update_xinerama_info; + ctx->update_xinerama_info = vo_x11_update_screeninfo; ctx->border = vo_x11_border; ctx->check_events = vo_x11_check_events; ctx->fullscreen = vo_x11_fullscreen; ctx->ontop = vo_x11_ontop; - ctx->vo_init = vo_init; + ctx->vo_init = vo_x11_init; ctx->vo_uninit = vo_x11_uninit; break; #endif diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index bc2db52f6a..0777ec084a 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -1511,7 +1511,7 @@ static int preinit(struct vo *vo, const char *arg) if (vc->deint < 0) vc->deint = 0; - if (!vo_init(vo)) + if (!vo_x11_init(vo)) return -1; // After this calling uninit() should work to free resources @@ -1632,7 +1632,7 @@ static int control(struct vo *vo, uint32_t request, void *data) 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_NEWFRAME: vc->deint_queue_pos = next_deint_queue_pos(vo, true); 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); diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index 90cc112ad2..8d52db96fa 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -64,7 +64,21 @@ static const vo_info_t info = { "" }; +#define CK_METHOD_NONE 0 // no colorkey drawing +#define CK_METHOD_BACKGROUND 1 // set colorkey as window background +#define CK_METHOD_AUTOPAINT 2 // let xv draw the colorkey +#define CK_METHOD_MANUALFILL 3 // manually draw the colorkey +#define CK_SRC_USE 0 // use specified / default colorkey +#define CK_SRC_SET 1 // use and set specified / default colorkey +#define CK_SRC_CUR 2 // use current colorkey (get it from xv) + struct xvctx { + struct xv_ck_info_s { + int method; // CK_METHOD_* constants + int source; // CK_SRC_* constants + } xv_ck_info; + unsigned long xv_colorkey; + unsigned int xv_port; XvAdaptorInfo *ai; XvImageFormatValues *fo; unsigned int formats, adaptors, xv_format; @@ -116,14 +130,342 @@ static int find_xv_format(int imgfmt) return 0; } -static void read_xv_csp(struct vo *vo) +static int xv_find_atom(struct vo *vo, uint32_t xv_port, const char *name, + bool get, int *min, int *max) +{ + Atom atom = None; + int howmany = 0; + XvAttribute *attributes = XvQueryPortAttributes(vo->x11->display, xv_port, + &howmany); + for (int i = 0; i < howmany && attributes; i++) { + int flag = get ? XvGettable : XvSettable; + if (attributes[i].flags & flag) { + atom = XInternAtom(vo->x11->display, attributes[i].name, True); + *min = attributes[i].min_value; + *max = attributes[i].max_value; +/* since we have SET_DEFAULTS first in our list, we can check if it's available + then trigger it if it's ok so that the other values are at default upon query */ + if (atom != None) { + if (!strcmp(attributes[i].name, "XV_BRIGHTNESS") && + (!strcasecmp(name, "brightness"))) + break; + else if (!strcmp(attributes[i].name, "XV_CONTRAST") && + (!strcasecmp(name, "contrast"))) + break; + else if (!strcmp(attributes[i].name, "XV_SATURATION") && + (!strcasecmp(name, "saturation"))) + break; + else if (!strcmp(attributes[i].name, "XV_HUE") && + (!strcasecmp(name, "hue"))) + break; + if (!strcmp(attributes[i].name, "XV_RED_INTENSITY") && + (!strcasecmp(name, "red_intensity"))) + break; + else if (!strcmp(attributes[i].name, "XV_GREEN_INTENSITY") + && (!strcasecmp(name, "green_intensity"))) + break; + else if (!strcmp(attributes[i].name, "XV_BLUE_INTENSITY") + && (!strcasecmp(name, "blue_intensity"))) + break; + else if ((!strcmp(attributes[i].name, "XV_ITURBT_709") //NVIDIA + || !strcmp(attributes[i].name, "XV_COLORSPACE")) //ATI + && (!strcasecmp(name, "bt_709"))) + break; + atom = None; + continue; + } + } + } + XFree(attributes); + return atom; +} + +static int xv_set_eq(struct vo *vo, uint32_t xv_port, const char *name, + int value) +{ + mp_dbg(MSGT_VO, MSGL_V, "xv_set_eq called! (%s, %d)\n", name, value); + + int min, max; + int atom = xv_find_atom(vo, xv_port, name, false, &min, &max); + if (atom != None) { + // -100 -> min + // 0 -> (max+min)/2 + // +100 -> max + int port_value = (value + 100) * (max - min) / 200 + min; + XvSetPortAttribute(vo->x11->display, xv_port, atom, port_value); + return VO_TRUE; + } + return VO_FALSE; +} + +static int xv_get_eq(struct vo *vo, uint32_t xv_port, const char *name, + int *value) +{ + int min, max; + int atom = xv_find_atom(vo, xv_port, name, true, &min, &max); + if (atom != None) { + int port_value = 0; + XvGetPortAttribute(vo->x11->display, xv_port, atom, &port_value); + + *value = (port_value - min) * 200 / (max - min) - 100; + mp_dbg(MSGT_VO, MSGL_V, "xv_get_eq called! (%s, %d)\n", + name, *value); + return VO_TRUE; + } + return VO_FALSE; +} + +static Atom xv_intern_atom_if_exists(struct vo *vo, char const *atom_name) +{ + struct xvctx *ctx = vo->priv; + XvAttribute *attributes; + int attrib_count, i; + Atom xv_atom = None; + + attributes = XvQueryPortAttributes(vo->x11->display, ctx->xv_port, + &attrib_count); + if (attributes != NULL) { + for (i = 0; i < attrib_count; ++i) { + if (strcmp(attributes[i].name, atom_name) == 0) { + xv_atom = XInternAtom(vo->x11->display, atom_name, False); + break; + } + } + XFree(attributes); + } + + return xv_atom; +} + +// Try to enable vsync for xv. +// Returns -1 if not available, 0 on failure and 1 on success. +static int xv_enable_vsync(struct vo *vo) +{ + struct xvctx *ctx = vo->priv; + Atom xv_atom = xv_intern_atom_if_exists(vo, "XV_SYNC_TO_VBLANK"); + if (xv_atom == None) + return -1; + return XvSetPortAttribute(vo->x11->display, ctx->xv_port, xv_atom, 1) + == Success; +} + +// Get maximum supported source image dimensions. +// If querying the dimensions fails, don't change *width and *height. +static void xv_get_max_img_dim(struct vo *vo, uint32_t *width, uint32_t *height) +{ + struct xvctx *ctx = vo->priv; + XvEncodingInfo *encodings; + unsigned int num_encodings, idx; + + XvQueryEncodings(vo->x11->display, ctx->xv_port, &num_encodings, &encodings); + + if (encodings) { + for (idx = 0; idx < num_encodings; ++idx) { + if (strcmp(encodings[idx].name, "XV_IMAGE") == 0) { + *width = encodings[idx].width; + *height = encodings[idx].height; + break; + } + } + } + + mp_msg(MSGT_VO, MSGL_V, + "[xv] Maximum source image dimensions: %ux%u\n", + *width, *height); + + XvFreeEncodingInfo(encodings); +} + +static void xv_print_ck_info(struct xvctx *xv) +{ + mp_msg(MSGT_VO, MSGL_V, "[xv] "); + + switch (xv->xv_ck_info.method) { + case CK_METHOD_NONE: + mp_msg(MSGT_VO, MSGL_V, "Drawing no colorkey.\n"); + return; + case CK_METHOD_AUTOPAINT: + mp_msg(MSGT_VO, MSGL_V, "Colorkey is drawn by Xv."); + break; + case CK_METHOD_MANUALFILL: + mp_msg(MSGT_VO, MSGL_V, "Drawing colorkey manually."); + break; + case CK_METHOD_BACKGROUND: + mp_msg(MSGT_VO, MSGL_V, "Colorkey is drawn as window background."); + break; + } + + mp_msg(MSGT_VO, MSGL_V, "\n[xv] "); + + switch (xv->xv_ck_info.source) { + case CK_SRC_CUR: + mp_msg(MSGT_VO, MSGL_V, "Using colorkey from Xv (0x%06lx).\n", + xv->xv_colorkey); + break; + case CK_SRC_USE: + if (xv->xv_ck_info.method == CK_METHOD_AUTOPAINT) { + mp_msg(MSGT_VO, MSGL_V, "Ignoring colorkey from mpv (0x%06lx).\n", + xv->xv_colorkey); + } else { + mp_msg(MSGT_VO, MSGL_V, + "Using colorkey from mpv (0x%06lx). Use -colorkey to change.\n", + xv->xv_colorkey); + } + break; + case CK_SRC_SET: + mp_msg(MSGT_VO, MSGL_V, "Setting and using colorkey from mpv (0x%06lx)." + " Use -colorkey to change.\n", xv->xv_colorkey); + break; + } +} + +/* NOTE: If vo_colorkey has bits set after the first 3 low order bytes + * we don't draw anything as this means it was forced to off. */ +static int xv_init_colorkey(struct vo *vo) +{ + struct xvctx *ctx = vo->priv; + Display *display = vo->x11->display; + Atom xv_atom; + int rez; + + /* check if colorkeying is needed */ + xv_atom = xv_intern_atom_if_exists(vo, "XV_COLORKEY"); + if (xv_atom != None && !(vo_colorkey & 0xFF000000)) { + if (ctx->xv_ck_info.source == CK_SRC_CUR) { + int colorkey_ret; + + rez = XvGetPortAttribute(display, ctx->xv_port, xv_atom, + &colorkey_ret); + if (rez == Success) + ctx->xv_colorkey = colorkey_ret; + else { + mp_msg(MSGT_VO, MSGL_FATAL, "[xv] Couldn't get colorkey!" + "Maybe the selected Xv port has no overlay.\n"); + return 0; // error getting colorkey + } + } else { + ctx->xv_colorkey = vo_colorkey; + + /* check if we have to set the colorkey too */ + if (ctx->xv_ck_info.source == CK_SRC_SET) { + xv_atom = XInternAtom(display, "XV_COLORKEY", False); + + rez = XvSetPortAttribute(display, ctx->xv_port, xv_atom, + vo_colorkey); + if (rez != Success) { + mp_msg(MSGT_VO, MSGL_FATAL, "[xv] Couldn't set colorkey!\n"); + return 0; // error setting colorkey + } + } + } + + xv_atom = xv_intern_atom_if_exists(vo, "XV_AUTOPAINT_COLORKEY"); + + /* should we draw the colorkey ourselves or activate autopainting? */ + if (ctx->xv_ck_info.method == CK_METHOD_AUTOPAINT) { + rez = !Success; + + if (xv_atom != None) // autopaint is supported + rez = XvSetPortAttribute(display, ctx->xv_port, xv_atom, 1); + + if (rez != Success) + ctx->xv_ck_info.method = CK_METHOD_MANUALFILL; + } else { + // disable colorkey autopainting if supported + if (xv_atom != None) + XvSetPortAttribute(display, ctx->xv_port, xv_atom, 0); + } + } else // do no colorkey drawing at all + ctx->xv_ck_info.method = CK_METHOD_NONE; + + xv_print_ck_info(ctx); + + return 1; +} + +/* Draw the colorkey on the video window. + * + * Draws the colorkey depending on the set method ( colorkey_handling ). + * + * Also draws the black bars ( when the video doesn't fit the display in + * fullscreen ) separately, so they don't overlap with the video area. */ +static void xv_draw_colorkey(struct vo *vo, int32_t x, int32_t y, + int32_t w, int32_t h) { struct xvctx *ctx = vo->priv; struct vo_x11_state *x11 = vo->x11; + if (ctx->xv_ck_info.method == CK_METHOD_MANUALFILL || + ctx->xv_ck_info.method == CK_METHOD_BACKGROUND) + { + //less tearing than XClearWindow() + XSetForeground(x11->display, x11->vo_gc, ctx->xv_colorkey); + XFillRectangle(x11->display, x11->window, x11->vo_gc, x, y, w, h); + } +} + +// Tests if a valid argument for the ck suboption was given. +static int xv_test_ck(void *arg) +{ + strarg_t *strarg = (strarg_t *)arg; + + if (strargcmp(strarg, "use") == 0 || + strargcmp(strarg, "set") == 0 || + strargcmp(strarg, "cur") == 0) + return 1; + + return 0; +} + +// Tests if a valid arguments for the ck-method suboption was given. +static int xv_test_ckm(void *arg) +{ + strarg_t *strarg = (strarg_t *)arg; + + if (strargcmp(strarg, "bg") == 0 || + strargcmp(strarg, "man") == 0 || + strargcmp(strarg, "auto") == 0) + return 1; + + return 0; +} + +/* Modify the colorkey_handling var according to str + * + * Checks if a valid pointer ( not NULL ) to the string + * was given. And in that case modifies the colorkey_handling + * var to reflect the requested behaviour. + * If nothing happens the content of colorkey_handling stays + * the same. + */ +static void xv_setup_colorkeyhandling(struct xvctx *ctx, + const char *ck_method_str, + const char *ck_str) +{ + /* check if a valid pointer to the string was passed */ + if (ck_str) { + if (strncmp(ck_str, "use", 3) == 0) + ctx->xv_ck_info.source = CK_SRC_USE; + else if (strncmp(ck_str, "set", 3) == 0) + ctx->xv_ck_info.source = CK_SRC_SET; + } + /* check if a valid pointer to the string was passed */ + if (ck_method_str) { + if (strncmp(ck_method_str, "bg", 2) == 0) + ctx->xv_ck_info.method = CK_METHOD_BACKGROUND; + else if (strncmp(ck_method_str, "man", 3) == 0) + ctx->xv_ck_info.method = CK_METHOD_MANUALFILL; + else if (strncmp(ck_method_str, "auto", 4) == 0) + ctx->xv_ck_info.method = CK_METHOD_AUTOPAINT; + } +} + +static void read_xv_csp(struct vo *vo) +{ + struct xvctx *ctx = vo->priv; struct mp_csp_details *cspc = &ctx->cached_csp; *cspc = (struct mp_csp_details) MP_CSP_DETAILS_DEFAULTS; int bt709_enabled; - if (vo_xv_get_eq(vo, x11->xv_port, "bt_709", &bt709_enabled)) + if (xv_get_eq(vo, ctx->xv_port, "bt_709", &bt709_enabled)) cspc->format = bt709_enabled == 100 ? MP_CSP_BT_709 : MP_CSP_BT_601; } @@ -140,7 +482,7 @@ static void resize(struct vo *vo) struct mp_rect *dst = &ctx->dst_rect; int dw = dst->x1 - dst->x0, dh = dst->y1 - dst->y0; vo_x11_clearwindow_part(vo, vo->x11->window, dw, dh); - vo_xv_draw_colorkey(vo, dst->x0, dst->y0, dw, dh); + xv_draw_colorkey(vo, dst->x0, dst->y0, dw, dh); read_xv_csp(vo); } @@ -204,8 +546,8 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, xswa.border_pixel = 0; xswamask = CWBorderPixel; - if (x11->xv_ck_info.method == CK_METHOD_BACKGROUND) { - xswa.background_pixel = x11->xv_colorkey; + if (ctx->xv_ck_info.method == CK_METHOD_BACKGROUND) { + xswa.background_pixel = ctx->xv_colorkey; xswamask |= CWBackPixel; } @@ -226,7 +568,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height, } mp_msg(MSGT_VO, MSGL_V, "using Xvideo port %d for hw scaling\n", - x11->xv_port); + ctx->xv_port); // In case config has been called before for (i = 0; i < ctx->total_buffers; i++) @@ -264,7 +606,7 @@ static void allocate_xvimage(struct vo *vo, int foo) } if (ctx->Shmem_Flag) { ctx->xvimage[foo] = - (XvImage *) XvShmCreateImage(x11->display, x11->xv_port, + (XvImage *) XvShmCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height, &ctx->Shminfo[foo]); @@ -284,7 +626,7 @@ static void allocate_xvimage(struct vo *vo, int foo) #endif { ctx->xvimage[foo] = - (XvImage *) XvCreateImage(x11->display, x11->xv_port, + (XvImage *) XvCreateImage(x11->display, ctx->xv_port, ctx->xv_format, NULL, aligned_w, ctx->image_height); ctx->xvimage[foo]->data = av_malloc(ctx->xvimage[foo]->data_size); @@ -323,7 +665,7 @@ static inline void put_xvimage(struct vo *vo, XvImage *xvi) int sw = src->x1 - src->x0, sh = src->y1 - src->y0; #ifdef HAVE_SHM if (ctx->Shmem_Flag) { - XvShmPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi, + XvShmPutImage(x11->display, ctx->xv_port, x11->window, x11->vo_gc, xvi, src->x0, src->y0, sw, sh, dst->x0, dst->y0, dw, dh, True); @@ -331,7 +673,7 @@ static inline void put_xvimage(struct vo *vo, XvImage *xvi) } else #endif { - XvPutImage(x11->display, x11->xv_port, x11->window, x11->vo_gc, xvi, + XvPutImage(x11->display, ctx->xv_port, x11->window, x11->vo_gc, xvi, src->x0, src->y0, sw, sh, dst->x0, dst->y0, dw, dh); } @@ -504,11 +846,14 @@ static int preinit(struct vo *vo, const char *arg) unsigned int i; strarg_t ck_src_arg = { 0, NULL }; strarg_t ck_method_arg = { 0, NULL }; - struct xvctx *ctx = talloc_zero(vo, struct xvctx); + struct xvctx *ctx = talloc_ptrtype(vo, ctx); + *ctx = (struct xvctx) { + .xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR }, + }; vo->priv = ctx; int xv_adaptor = -1; - if (!vo_init(vo)) + if (!vo_x11_init(vo)) return -1; struct vo_x11_state *x11 = vo->x11; @@ -516,22 +861,20 @@ static int preinit(struct vo *vo, const char *arg) const opt_t subopts[] = { /* name arg type arg var test */ - { "port", OPT_ARG_INT, &x11->xv_port, int_pos }, + { "port", OPT_ARG_INT, &ctx->xv_port, int_pos }, { "adaptor", OPT_ARG_INT, &xv_adaptor, int_non_neg }, { "ck", OPT_ARG_STR, &ck_src_arg, xv_test_ck }, { "ck-method", OPT_ARG_STR, &ck_method_arg, xv_test_ckm }, { NULL } }; - x11->xv_port = 0; - /* parse suboptions */ if (subopt_parse(arg, subopts) != 0) { return -1; } /* modify colorkey settings according to the given options */ - xv_setup_colorkeyhandling(vo, ck_method_arg.str, ck_src_arg.str); + xv_setup_colorkeyhandling(ctx, ck_method_arg.str, ck_src_arg.str); /* check for Xvideo extension */ unsigned int ver, rel, req, ev, err; @@ -549,7 +892,7 @@ static int preinit(struct vo *vo, const char *arg) } /* check adaptors */ - if (x11->xv_port) { + if (ctx->xv_port) { int port_found; for (port_found = 0, i = 0; !port_found && i < ctx->adaptors; i++) { @@ -558,7 +901,7 @@ static int preinit(struct vo *vo, const char *arg) for (xv_p = ctx->ai[i].base_id; xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) { - if (xv_p == x11->xv_port) { + if (xv_p == ctx->xv_port) { port_found = 1; break; } @@ -566,15 +909,15 @@ static int preinit(struct vo *vo, const char *arg) } } if (port_found) { - if (XvGrabPort(x11->display, x11->xv_port, CurrentTime)) - x11->xv_port = 0; + if (XvGrabPort(x11->display, ctx->xv_port, CurrentTime)) + ctx->xv_port = 0; } else { mp_tmsg(MSGT_VO, MSGL_WARN, "[VO_XV] Invalid port parameter, overriding with port 0.\n"); - x11->xv_port = 0; + ctx->xv_port = 0; } } - for (i = 0; i < ctx->adaptors && x11->xv_port == 0; i++) { + for (i = 0; i < ctx->adaptors && ctx->xv_port == 0; i++) { /* check if adaptor number has been specified */ if (xv_adaptor != -1 && xv_adaptor != i) continue; @@ -583,7 +926,7 @@ static int preinit(struct vo *vo, const char *arg) for (xv_p = ctx->ai[i].base_id; xv_p < ctx->ai[i].base_id + ctx->ai[i].num_ports; ++xv_p) if (!XvGrabPort(x11->display, xv_p, CurrentTime)) { - x11->xv_port = xv_p; + ctx->xv_port = xv_p; mp_msg(MSGT_VO, MSGL_V, "[VO_XV] Using Xv Adapter #%d (%s)\n", i, ctx->ai[i].name); @@ -595,7 +938,7 @@ static int preinit(struct vo *vo, const char *arg) } } } - if (!x11->xv_port) { + if (!ctx->xv_port) { if (busy_ports) mp_tmsg(MSGT_VO, MSGL_ERR, "[VO_XV] Could not find free Xvideo port - maybe another process is already\n"\ @@ -611,13 +954,13 @@ static int preinit(struct vo *vo, const char *arg) goto error; } - if (!vo_xv_init_colorkey(vo)) { + if (!xv_init_colorkey(vo)) { goto error; // bail out, colorkey setup failed } - vo_xv_enable_vsync(vo); - vo_xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height); + xv_enable_vsync(vo); + xv_get_max_img_dim(vo, &ctx->max_width, &ctx->max_height); - ctx->fo = XvListImageFormats(x11->display, x11->xv_port, + ctx->fo = XvListImageFormats(x11->display, ctx->xv_port, (int *) &ctx->formats); return 0; @@ -630,7 +973,6 @@ static int preinit(struct vo *vo, const char *arg) static int control(struct vo *vo, uint32_t request, void *data) { struct xvctx *ctx = vo->priv; - struct vo_x11_state *x11 = vo->x11; switch (request) { case VOCTRL_PAUSE: return (ctx->is_paused = 1); @@ -647,16 +989,16 @@ static int control(struct vo *vo, uint32_t request, void *data) case VOCTRL_SET_EQUALIZER: { vo->want_redraw = true; struct voctrl_set_equalizer_args *args = data; - return vo_xv_set_eq(vo, x11->xv_port, args->name, args->value); + return xv_set_eq(vo, ctx->xv_port, args->name, args->value); } case VOCTRL_GET_EQUALIZER: { struct voctrl_get_equalizer_args *args = data; - return vo_xv_get_eq(vo, x11->xv_port, args->name, args->valueptr); + return xv_get_eq(vo, ctx->xv_port, args->name, args->valueptr); } case VOCTRL_SET_YUV_COLORSPACE:; struct mp_csp_details* given_cspc = data; int is_709 = given_cspc->format == MP_CSP_BT_709; - vo_xv_set_eq(vo, x11->xv_port, "bt_709", is_709 * 200 - 100); + xv_set_eq(vo, ctx->xv_port, "bt_709", is_709 * 200 - 100); read_xv_csp(vo); vo->want_redraw = true; return true; @@ -669,7 +1011,7 @@ static int control(struct vo *vo, uint32_t request, void *data) 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); 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; |