diff options
Diffstat (limited to 'libvo/x11_common.c')
-rw-r--r-- | libvo/x11_common.c | 1008 |
1 files changed, 500 insertions, 508 deletions
diff --git a/libvo/x11_common.c b/libvo/x11_common.c index bb334f13f5..91431207a3 100644 --- a/libvo/x11_common.c +++ b/libvo/x11_common.c @@ -23,10 +23,12 @@ #include <limits.h> #include "config.h" +#include "options.h" #include "mp_msg.h" #include "mp_fifo.h" #include "libavutil/common.h" #include "x11_common.h" +#include "talloc.h" #ifdef X11_FULLSCREEN @@ -75,11 +77,6 @@ #include "input/input.h" #include "input/mouse.h" -#ifdef CONFIG_GUI -#include "gui/interface.h" -#include "mplayer.h" -#endif - #define WIN_LAYER_ONBOTTOM 2 #define WIN_LAYER_NORMAL 4 #define WIN_LAYER_ONTOP 6 @@ -87,57 +84,26 @@ extern int enable_mouse_movements; int fs_layer = WIN_LAYER_ABOVE_DOCK; -static int orig_layer = 0; -static int old_gravity = NorthWestGravity; int stop_xscreensaver = 0; static int dpms_disabled = 0; char *mDisplayName = NULL; -Display *mDisplay = NULL; -Window mRootWin; -int mScreen; -int mLocalDisplay; - -/* output window id */ -int vo_mouse_autohide = 0; -int vo_wm_type = 0; -int vo_fs_type = 0; // needs to be accessible for GUI X11 code -static int window_state; -static int vo_fs_flip = 0; + char **vo_fstype_list; /* 1 means that the WM is metacity (broken as hell) */ int metacity_hack = 0; -static Atom XA_NET_SUPPORTED; -static Atom XA_NET_WM_STATE; -static Atom XA_NET_WM_STATE_FULLSCREEN; -static Atom XA_NET_WM_STATE_ABOVE; -static Atom XA_NET_WM_STATE_STAYS_ON_TOP; -static Atom XA_NET_WM_STATE_BELOW; -static Atom XA_NET_WM_PID; -static Atom XA_WIN_PROTOCOLS; -static Atom XA_WIN_LAYER; -static Atom XA_WIN_HINTS; -static Atom XAWM_PROTOCOLS; -static Atom XAWM_DELETE_WINDOW; - -#define XA_INIT(x) XA##x = XInternAtom(mDisplay, #x, False) - -static int vo_old_x = 0; -static int vo_old_y = 0; -static int vo_old_width = 0; -static int vo_old_height = 0; - #ifdef CONFIG_XF86VM XF86VidModeModeInfo **vidmodes = NULL; XF86VidModeModeLine modeline; #endif static int vo_x11_get_fs_type(int supported); - +static void saver_off(Display *); +static void saver_on(Display *); /* * Sends the EWMH fullscreen state event. @@ -146,12 +112,12 @@ static int vo_x11_get_fs_type(int supported); * _NET_WM_STATE_ADD -- add state * _NET_WM_STATE_TOGGLE -- toggle */ -void vo_x11_ewmh_fullscreen(int action) +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); - if (vo_fs_type & vo_wm_FULLSCREEN) + if (x11->fs_type & vo_wm_FULLSCREEN) { XEvent xev; @@ -159,32 +125,32 @@ void vo_x11_ewmh_fullscreen(int action) xev.xclient.type = ClientMessage; xev.xclient.serial = 0; xev.xclient.send_event = True; - xev.xclient.message_type = XA_NET_WM_STATE; - xev.xclient.window = vo_window; + xev.xclient.message_type = x11->XA_NET_WM_STATE; + xev.xclient.window = x11->window; xev.xclient.format = 32; xev.xclient.data.l[0] = action; - xev.xclient.data.l[1] = XA_NET_WM_STATE_FULLSCREEN; + xev.xclient.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; xev.xclient.data.l[2] = 0; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; /* finally send that damn thing */ - if (!XSendEvent(mDisplay, DefaultRootWindow(mDisplay), False, + if (!XSendEvent(x11->display, DefaultRootWindow(x11->display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev)) { - mp_msg(MSGT_VO, MSGL_ERR, MSGTR_EwmhFullscreenStateFailed); + mp_tmsg(MSGT_VO, MSGL_ERR, "\nX11: Couldn't send EWMH fullscreen event!\n"); } } } -void vo_hidecursor(Display * disp, Window win) +static void vo_hidecursor(Display * disp, Window win) { Cursor no_ptr; Pixmap bm_no; XColor black, dummy; Colormap colormap; - static char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + const char bm_no_data[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; if (WinID == 0) return; // do not hide if playing on the root window @@ -203,7 +169,7 @@ void vo_hidecursor(Display * disp, Window win) XFreeColors(disp,colormap,&black.pixel,1,0); } -void vo_showcursor(Display * disp, Window win) +static void vo_showcursor(Display * disp, Window win) { if (WinID == 0) return; @@ -234,7 +200,7 @@ static int x11_errorhandler(Display * display, XErrorEvent * event) void fstype_help(void) { - mp_msg(MSGT_VO, MSGL_INFO, MSGTR_AvailableFsType); + mp_tmsg(MSGT_VO, MSGL_INFO, "Available fullscreen layer change modes:\n"); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_FULL_SCREEN_TYPES\n"); mp_msg(MSGT_VO, MSGL_INFO, " %-15s %s\n", "none", @@ -279,9 +245,9 @@ static void fstype_dump(int fstype) "[x11] Current fstype setting doesn't honour any X atoms\n"); } -static int net_wm_support_state_test(Atom atom) +static int net_wm_support_state_test(struct vo_x11_state *x11, Atom atom) { -#define NET_WM_STATE_TEST(x) { if (atom == XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } } +#define NET_WM_STATE_TEST(x) { if (atom == x11->XA_NET_WM_STATE_##x) { mp_msg( MSGT_VO,MSGL_V, "[x11] Detected wm supports " #x " state.\n" ); return vo_wm_##x; } } NET_WM_STATE_TEST(FULLSCREEN); NET_WM_STATE_TEST(ABOVE); @@ -290,20 +256,22 @@ static int net_wm_support_state_test(Atom atom) return 0; } -static int x11_get_property(Atom type, Atom ** args, unsigned long *nitems) +static int x11_get_property(struct vo_x11_state *x11, Atom type, Atom ** args, + unsigned long *nitems) { int format; unsigned long bytesafter; return Success == - XGetWindowProperty(mDisplay, mRootWin, type, 0, 16384, False, + XGetWindowProperty(x11->display, x11->rootwin, type, 0, 16384, False, AnyPropertyType, &type, &format, nitems, &bytesafter, (unsigned char **) args) && *nitems > 0; } -static int vo_wm_detect(void) +static int vo_wm_detect(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; int i; int wm = 0; unsigned long nitems; @@ -313,12 +281,12 @@ static int vo_wm_detect(void) return 0; // -- supports layers - if (x11_get_property(XA_WIN_PROTOCOLS, &args, &nitems)) + if (x11_get_property(x11, x11->XA_WIN_PROTOCOLS, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports layers.\n"); for (i = 0; i < nitems; i++) { - if (args[i] == XA_WIN_LAYER) + if (args[i] == x11->XA_WIN_LAYER) { wm |= vo_wm_LAYER; metacity_hack |= 1; @@ -338,11 +306,11 @@ static int vo_wm_detect(void) } } // --- netwm - if (x11_get_property(XA_NET_SUPPORTED, &args, &nitems)) + if (x11_get_property(x11, x11->XA_NET_SUPPORTED, &args, &nitems)) { mp_msg(MSGT_VO, MSGL_V, "[x11] Detected wm supports NetWM.\n"); for (i = 0; i < nitems; i++) - wm |= net_wm_support_state_test(args[i]); + wm |= net_wm_support_state_test(vo->x11, args[i]); XFree(args); } @@ -351,7 +319,8 @@ static int vo_wm_detect(void) return wm; } -static void init_atoms(void) +#define XA_INIT(x) x11->XA##x = XInternAtom(x11->display, #x, False) +static void init_atoms(struct vo_x11_state *x11) { XA_INIT(_NET_SUPPORTED); XA_INIT(_NET_WM_STATE); @@ -367,21 +336,22 @@ static void init_atoms(void) XA_INIT(WM_DELETE_WINDOW); } -void update_xinerama_info(void) { +void update_xinerama_info(struct vo *vo) { + struct MPOpts *opts = vo->opts; int screen = xinerama_screen; xinerama_x = xinerama_y = 0; #ifdef CONFIG_XINERAMA - if (screen >= -1 && XineramaIsActive(mDisplay)) + if (screen >= -1 && XineramaIsActive(vo->x11->display)) { XineramaScreenInfo *screens; int num_screens; - screens = XineramaQueryScreens(mDisplay, &num_screens); + screens = XineramaQueryScreens(vo->x11->display, &num_screens); if (screen >= num_screens) screen = num_screens - 1; if (screen == -1) { - int x = vo_dx + vo_dwidth / 2; - int y = vo_dy + vo_dheight / 2; + int x = vo->dx + vo->dwidth / 2; + int y = vo->dy + vo->dheight / 2; for (screen = num_screens - 1; screen > 0; screen--) { int left = screens[screen].x_org; int right = left + screens[screen].width; @@ -393,19 +363,21 @@ void update_xinerama_info(void) { } if (screen < 0) screen = 0; - vo_screenwidth = screens[screen].width; - vo_screenheight = screens[screen].height; + opts->vo_screenwidth = screens[screen].width; + opts->vo_screenheight = screens[screen].height; xinerama_x = screens[screen].x_org; xinerama_y = screens[screen].y_org; XFree(screens); } #endif - aspect_save_screenres(vo_screenwidth, vo_screenheight); + aspect_save_screenres(vo, opts->vo_screenwidth, opts->vo_screenheight); } -int vo_init(void) +int vo_init(struct vo *vo) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; // int mScreen; int depth, bpp; unsigned int mask; @@ -421,9 +393,9 @@ int vo_init(void) if (vo_rootwin) WinID = 0; // use root window - if (vo_depthonscreen) + if (x11->depthonscreen) { - saver_off(mDisplay); + saver_off(x11->display); return 1; // already called } @@ -439,52 +411,52 @@ int vo_init(void) mp_msg(MSGT_VO, MSGL_V, "X11 opening display: %s\n", dispName); - mDisplay = XOpenDisplay(dispName); - if (!mDisplay) + x11->display = XOpenDisplay(dispName); + if (!x11->display) { mp_msg(MSGT_VO, MSGL_ERR, "vo: couldn't open the X11 display (%s)!\n", dispName); return 0; } - mScreen = DefaultScreen(mDisplay); // screen ID - mRootWin = RootWindow(mDisplay, mScreen); // root window ID + x11->screen = DefaultScreen(x11->display); // screen ID + x11->rootwin = RootWindow(x11->display, x11->screen); // root window ID - init_atoms(); + init_atoms(vo->x11); #ifdef CONFIG_XF86VM { int clock; - XF86VidModeGetModeLine(mDisplay, mScreen, &clock, &modeline); - if (!vo_screenwidth) - vo_screenwidth = modeline.hdisplay; - if (!vo_screenheight) - vo_screenheight = modeline.vdisplay; + XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline); + if (!opts->vo_screenwidth) + opts->vo_screenwidth = modeline.hdisplay; + if (!opts->vo_screenheight) + opts->vo_screenheight = modeline.vdisplay; } #endif { - if (!vo_screenwidth) - vo_screenwidth = DisplayWidth(mDisplay, mScreen); - if (!vo_screenheight) - vo_screenheight = DisplayHeight(mDisplay, mScreen); + if (!opts->vo_screenwidth) + opts->vo_screenwidth = DisplayWidth(x11->display, x11->screen); + if (!opts->vo_screenheight) + opts->vo_screenheight = DisplayHeight(x11->display, x11->screen); } // get color depth (from root window, or the best visual): - XGetWindowAttributes(mDisplay, mRootWin, &attribs); + 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(mDisplay, mScreen, &visual); + depth = vo_find_depth_from_visuals(x11->display, x11->screen, &visual); if (depth != -1) - mXImage = XCreateImage(mDisplay, visual, depth, ZPixmap, + mXImage = XCreateImage(x11->display, visual, depth, ZPixmap, 0, NULL, 1, 1, 8, 1); } else mXImage = - XGetImage(mDisplay, mRootWin, 0, 0, 1, 1, AllPlanes, ZPixmap); + XGetImage(x11->display, x11->rootwin, 0, 0, 1, 1, AllPlanes, ZPixmap); - vo_depthonscreen = depth; // display depth on screen + x11->depthonscreen = depth; // display depth on screen // get bits/pixel from XImage structure: if (mXImage == NULL) @@ -494,15 +466,15 @@ int vo_init(void) { /* * for the depth==24 case, the XImage structures might use - * 24 or 32 bits of data per pixel. The global variable - * vo_depthonscreen stores the amount of data per pixel in the + * 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 ((vo_depthonscreen + 7) / 8 != (bpp + 7) / 8) - vo_depthonscreen = bpp; // by A'rpi + 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, @@ -510,12 +482,12 @@ int vo_init(void) mXImage->red_mask, mXImage->green_mask, mXImage->blue_mask); XDestroyImage(mXImage); } - if (((vo_depthonscreen + 7) / 8) == 2) + if (((x11->depthonscreen + 7) / 8) == 2) { if (mask == 0x7FFF) - vo_depthonscreen = 15; + x11->depthonscreen = 15; else if (mask == 0xFFFF) - vo_depthonscreen = 16; + x11->depthonscreen = 16; } // XCloseDisplay( mDisplay ); /* slightly improved local display detection AST */ @@ -524,38 +496,38 @@ int vo_init(void) else if (strncmp(dispName, "localhost:", 10) == 0) dispName += 9; if (*dispName == ':' && atoi(dispName + 1) < 10) - mLocalDisplay = 1; + x11->display_is_local = 1; else - mLocalDisplay = 0; + 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", - vo_screenwidth, vo_screenheight, depth, vo_depthonscreen, - dispName, mLocalDisplay ? "local" : "remote"); + opts->vo_screenwidth, opts->vo_screenheight, depth, x11->depthonscreen, + dispName, x11->display_is_local ? "local" : "remote"); - vo_wm_type = vo_wm_detect(); + x11->wm_type = vo_wm_detect(vo); - vo_fs_type = vo_x11_get_fs_type(vo_wm_type); + x11->fs_type = vo_x11_get_fs_type(x11->wm_type); - fstype_dump(vo_fs_type); + fstype_dump(x11->fs_type); - saver_off(mDisplay); + saver_off(x11->display); return 1; } -void vo_uninit(void) +void vo_uninit(struct vo_x11_state *x11) { - if (!mDisplay) + if (!x11->display) { mp_msg(MSGT_VO, MSGL_V, "vo: x11 uninit called but X11 not initialized..\n"); - return; + } else { + mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n"); + XSetErrorHandler(NULL); + XCloseDisplay(x11->display); + x11->depthonscreen = 0; + x11->display = NULL; } -// if( !vo_depthonscreen ) return; - mp_msg(MSGT_VO, MSGL_V, "vo: uninit ...\n"); - XSetErrorHandler(NULL); - XCloseDisplay(mDisplay); - vo_depthonscreen = 0; - mDisplay = NULL; + talloc_free(x11); } #include "osdep/keycodes.h" @@ -570,11 +542,12 @@ static const struct keymap keysym_map[] = { {0, 0} }; -static void vo_x11_putkey_ext(int keysym) +static void vo_x11_putkey_ext(struct vo *vo, int keysym) { + struct mp_fifo *f = vo->key_fifo; int mpkey = lookup_keymap_table(keysym_map, keysym); if (mpkey) - mplayer_put_key(mpkey); + mplayer_put_key(f, mpkey); } #endif @@ -613,7 +586,7 @@ static const struct keymap keymap[] = { {0, 0} }; -void vo_x11_putkey(int key) +void vo_x11_putkey(struct vo *vo, int key) { static const char *passthrough_keys = " -+*/<>`~!@#$%^&()_{}:;\"\',.?\\|=[]"; int mpkey = 0; @@ -627,7 +600,7 @@ void vo_x11_putkey(int key) mpkey = lookup_keymap_table(keymap, key); if (mpkey) - mplayer_put_key(mpkey); + mplayer_put_key(vo->key_fifo, mpkey); } @@ -673,12 +646,9 @@ typedef struct static MotifWmHints vo_MotifWmHints; static Atom vo_MotifHints = None; -void vo_x11_decoration(Display * vo_Display, Window w, int d) +void vo_x11_decoration(struct vo *vo, int d) { - static unsigned int olddecor = MWM_DECOR_ALL; - static unsigned int oldfuncs = - MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | - MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE; + struct vo_x11_state *x11 = vo->x11; Atom mtype; int mformat; unsigned long mn, mb; @@ -688,26 +658,27 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) if (vo_fsmode & 8) { - XSetTransientForHint(vo_Display, w, - RootWindow(vo_Display, mScreen)); + XSetTransientForHint(x11->display, x11->window, + RootWindow(x11->display, x11->screen)); } - vo_MotifHints = XInternAtom(vo_Display, "_MOTIF_WM_HINTS", 0); + vo_MotifHints = XInternAtom(x11->display, "_MOTIF_WM_HINTS", 0); if (vo_MotifHints != None) { if (!d) { MotifWmHints *mhints = NULL; - XGetWindowProperty(vo_Display, w, vo_MotifHints, 0, 20, False, + XGetWindowProperty(x11->display, x11->window, + vo_MotifHints, 0, 20, False, vo_MotifHints, &mtype, &mformat, &mn, &mb, (unsigned char **) &mhints); if (mhints) { if (mhints->flags & MWM_HINTS_DECORATIONS) - olddecor = mhints->decorations; + x11->olddecor = mhints->decorations; if (mhints->flags & MWM_HINTS_FUNCTIONS) - oldfuncs = mhints->functions; + x11->oldfuncs = mhints->functions; XFree(mhints); } } @@ -717,8 +688,8 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; if (d) { - vo_MotifWmHints.functions = oldfuncs; - d = olddecor; + vo_MotifWmHints.functions = x11->oldfuncs; + d = x11->olddecor; } #if 0 vo_MotifWmHints.decorations = @@ -727,113 +698,89 @@ void vo_x11_decoration(Display * vo_Display, Window w, int d) vo_MotifWmHints.decorations = d | ((vo_fsmode & 2) ? MWM_DECOR_MENU : 0); #endif - XChangeProperty(vo_Display, w, vo_MotifHints, vo_MotifHints, 32, + XChangeProperty(x11->display, x11->window, vo_MotifHints, + vo_MotifHints, 32, PropModeReplace, (unsigned char *) &vo_MotifWmHints, (vo_fsmode & 4) ? 4 : 5); } } -void vo_x11_classhint(Display * display, Window window, const char *name) +void vo_x11_classhint(struct vo *vo, Window window, const char *name) { + struct vo_x11_state *x11 = vo->x11; XClassHint wmClass; pid_t pid = getpid(); wmClass.res_name = vo_winname ? vo_winname : name; wmClass.res_class = "MPlayer"; - XSetClassHint(display, window, &wmClass); - XChangeProperty(display, window, XA_NET_WM_PID, XA_CARDINAL, 32, - PropModeReplace, (unsigned char *) &pid, 1); + XSetClassHint(x11->display, window, &wmClass); + XChangeProperty(x11->display, window, x11->XA_NET_WM_PID, XA_CARDINAL, + 32, PropModeReplace, (unsigned char *) &pid, 1); } -Window vo_window = None; -GC vo_gc = NULL; -GC f_gc = NULL; -XSizeHints vo_hint; - -#ifdef CONFIG_GUI -void vo_setwindow(Window w, GC g) +void vo_x11_uninit(struct vo *vo) { - vo_window = w; - vo_gc = g; -} -#endif + struct vo_x11_state *x11 = vo->x11; + saver_on(x11->display); + if (x11->window != None) + vo_showcursor(x11->display, x11->window); -void vo_x11_uninit(void) -{ - saver_on(mDisplay); - if (vo_window != None) - vo_showcursor(mDisplay, vo_window); - - if (f_gc) + if (x11->f_gc) { - XFreeGC(mDisplay, f_gc); - f_gc = NULL; + XFreeGC(vo->x11->display, x11->f_gc); + x11->f_gc = NULL; } -#ifdef CONFIG_GUI - /* destroy window only if it's not controlled by the GUI */ - if (!use_gui) -#endif { - if (vo_gc) + if (x11->vo_gc) { - XSetBackground(mDisplay, vo_gc, 0); - XFreeGC(mDisplay, vo_gc); - vo_gc = NULL; + XSetBackground(vo->x11->display, x11->vo_gc, 0); + XFreeGC(vo->x11->display, x11->vo_gc); + x11->vo_gc = NULL; } - if (vo_window != None) + if (x11->window != None) { - XClearWindow(mDisplay, vo_window); + XClearWindow(x11->display, x11->window); if (WinID < 0) { XEvent xev; - XUnmapWindow(mDisplay, vo_window); - XDestroyWindow(mDisplay, vo_window); + XUnmapWindow(x11->display, x11->window); + XDestroyWindow(x11->display, x11->window); do { - XNextEvent(mDisplay, &xev); + XNextEvent(x11->display, &xev); } while (xev.type != DestroyNotify - || xev.xdestroywindow.event != vo_window); + || xev.xdestroywindow.event != x11->window); } - vo_window = None; + x11->window = None; } vo_fs = 0; - vo_old_width = vo_old_height = 0; + x11->vo_old_width = x11->vo_old_height = 0; } } -static unsigned int mouse_timer; -static int mouse_waiting_hide; - -int vo_x11_check_events(Display * mydisplay) +int vo_x11_check_events(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + Display *display = vo->x11->display; int ret = 0; XEvent Event; char buf[100]; KeySym keySym; - static XComposeStatus stat; // unsigned long vo_KeyTable[512]; - if ((vo_mouse_autohide) && mouse_waiting_hide && - (GetTimerMS() - mouse_timer >= 1000)) { - vo_hidecursor(mydisplay, vo_window); - mouse_waiting_hide = 0; + if ((x11->vo_mouse_autohide) && x11->mouse_waiting_hide && + (GetTimerMS() - x11->mouse_timer >= 1000)) { + vo_hidecursor(display, x11->window); + x11->mouse_waiting_hide = 0; } - while (XPending(mydisplay)) + while (XPending(display)) { - XNextEvent(mydisplay, &Event); -#ifdef CONFIG_GUI - if (use_gui) - { - guiGetEvent(0, (char *) &Event); - if (vo_window != Event.xany.window) - continue; - } -#endif + XNextEvent(display, &Event); // printf("\rEvent.type=%X \n",Event.type); switch (Event.type) { @@ -841,15 +788,12 @@ int vo_x11_check_events(Display * mydisplay) ret |= VO_EVENT_EXPOSE; break; case ConfigureNotify: -// if (!vo_fs && (Event.xconfigure.width == vo_screenwidth || Event.xconfigure.height == vo_screenheight)) break; -// if (vo_fs && Event.xconfigure.width != vo_screenwidth && Event.xconfigure.height != vo_screenheight) break; - if (vo_window == None) + if (x11->window == None) break; { - int old_w = vo_dwidth, old_h = vo_dheight; - int old_x = vo_dx, old_y = vo_dy; - vo_x11_update_geometry(); - if (vo_dwidth != old_w || vo_dheight != old_h || vo_dx != old_x || vo_dy != old_y) + int old_w = vo->dwidth, old_h = vo->dheight; + vo_x11_update_geometry(vo); + if (vo->dwidth != old_w || vo->dheight != old_h) ret |= VO_EVENT_RESIZE; } break; @@ -857,19 +801,15 @@ int vo_x11_check_events(Display * mydisplay) { int key; -#ifdef CONFIG_GUI - if ( use_gui ) { break; } -#endif - XLookupString(&Event.xkey, buf, sizeof(buf), &keySym, - &stat); + &x11->compose_status); #ifdef XF86XK_AudioPause - vo_x11_putkey_ext(keySym); + vo_x11_putkey_ext(vo, keySym); #endif key = ((keySym & 0xff00) != 0 ? ((keySym & 0x00ff) + 256) : (keySym)); - vo_x11_putkey(key); + vo_x11_putkey(vo, key); ret |= VO_EVENT_KEYPRESS; } break; @@ -878,51 +818,42 @@ int vo_x11_check_events(Display * mydisplay) { char cmd_str[40]; sprintf(cmd_str,"set_mouse_pos %i %i",Event.xmotion.x, Event.xmotion.y); - mp_input_queue_cmd(mp_input_parse_cmd(cmd_str)); + mp_input_queue_cmd(vo->input_ctx, + mp_input_parse_cmd(cmd_str)); } - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } break; case ButtonPress: - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } -#ifdef CONFIG_GUI - // Ignore mouse button 1-3 under GUI. - if (use_gui && (Event.xbutton.button >= 1) - && (Event.xbutton.button <= 3)) - break; -#endif - mplayer_put_key((MOUSE_BTN0 + Event.xbutton.button - - 1) | MP_KEY_DOWN); + mplayer_put_key(vo->key_fifo, + (MOUSE_BTN0 + Event.xbutton.button - 1) + | MP_KEY_DOWN); break; case ButtonRelease: - if (vo_mouse_autohide) + if (x11->vo_mouse_autohide) { - vo_showcursor(mydisplay, vo_window); - mouse_waiting_hide = 1; - mouse_timer = GetTimerMS(); + vo_showcursor(display, x11->window); + x11->mouse_waiting_hide = 1; + x11->mouse_timer = GetTimerMS(); } -#ifdef CONFIG_GUI - // Ignore mouse button 1-3 under GUI. - if (use_gui && (Event.xbutton.button >= 1) - && (Event.xbutton.button <= 3)) - break; -#endif - mplayer_put_key(MOUSE_BTN0 + Event.xbutton.button - 1); + mplayer_put_key(vo->key_fifo, + MOUSE_BTN0 + Event.xbutton.button - 1); break; case PropertyNotify: { char *name = - XGetAtomName(mydisplay, Event.xproperty.atom); + XGetAtomName(display, Event.xproperty.atom); if (!name) break; @@ -933,14 +864,14 @@ int vo_x11_check_events(Display * mydisplay) } break; case MapNotify: - vo_hint.win_gravity = old_gravity; - XSetWMNormalHints(mDisplay, vo_window, &vo_hint); - vo_fs_flip = 0; + x11->vo_hint.win_gravity = x11->old_gravity; + XSetWMNormalHints(display, x11->window, &x11->vo_hint); + x11->fs_flip = 0; break; case ClientMessage: - if (Event.xclient.message_type == XAWM_PROTOCOLS && - Event.xclient.data.l[0] == XAWM_DELETE_WINDOW) - mplayer_put_key(KEY_CLOSE_WIN); + if (Event.xclient.message_type == x11->XAWM_PROTOCOLS && + Event.xclient.data.l[0] == x11->XAWM_DELETE_WINDOW) + mplayer_put_key(vo->key_fifo, KEY_CLOSE_WIN); break; } } @@ -950,69 +881,76 @@ int vo_x11_check_events(Display * mydisplay) /** * \brief sets the size and position of the non-fullscreen window. */ -void vo_x11_nofs_sizepos(int x, int y, int width, int height) +static void vo_x11_nofs_sizepos(struct vo *vo, int x, int y, + int width, int height) { - vo_x11_sizehint(x, y, width, height, 0); + struct vo_x11_state *x11 = vo->x11; + vo_x11_sizehint(vo, x, y, width, height, 0); if (vo_fs) { - vo_old_x = x; - vo_old_y = y; - vo_old_width = width; - vo_old_height = height; + 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; - XMoveResizeWindow(mDisplay, vo_window, x, y, width, height); + 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(int x, int y, int width, int height, int max) +void vo_x11_sizehint(struct vo *vo, int x, int y, int width, int height, int max) { - vo_hint.flags = 0; + struct vo_x11_state *x11 = vo->x11; + x11->vo_hint.flags = 0; if (vo_keepaspect) { - vo_hint.flags |= PAspect; - vo_hint.min_aspect.x = width; - vo_hint.min_aspect.y = height; - vo_hint.max_aspect.x = width; - vo_hint.max_aspect.y = height; + x11->vo_hint.flags |= PAspect; + x11->vo_hint.min_aspect.x = width; + x11->vo_hint.min_aspect.y = height; + x11->vo_hint.max_aspect.x = width; + x11->vo_hint.max_aspect.y = height; } - vo_hint.flags |= PPosition | PSize; - vo_hint.x = x; - vo_hint.y = y; - vo_hint.width = width; - vo_hint.height = height; + x11->vo_hint.flags |= PPosition | PSize; + x11->vo_hint.x = x; + x11->vo_hint.y = y; + x11->vo_hint.width = width; + x11->vo_hint.height = height; if (max) { - vo_hint.flags |= PMaxSize; - vo_hint.max_width = width; - vo_hint.max_height = height; + x11->vo_hint.flags |= PMaxSize; + x11->vo_hint.max_width = width; + x11->vo_hint.max_height = height; } else { - vo_hint.max_width = 0; - vo_hint.max_height = 0; + x11->vo_hint.max_width = 0; + x11->vo_hint.max_height = 0; } // Set minimum height/width to 4 to avoid off-by-one errors // and because mga_vid requires a minimal size of 4 pixels. - vo_hint.flags |= PMinSize; - vo_hint.min_width = vo_hint.min_height = 4; + x11->vo_hint.flags |= PMinSize; + x11->vo_hint.min_width = x11->vo_hint.min_height = 4; // Set the base size. A window manager might display the window // size to the user relative to this. // Setting these to width/height might be nice, but e.g. fluxbox can't handle it. - vo_hint.flags |= PBaseSize; - vo_hint.base_width = 0 /*width*/; - vo_hint.base_height = 0 /*height*/; + x11->vo_hint.flags |= PBaseSize; + x11->vo_hint.base_width = 0 /*width*/; + x11->vo_hint.base_height = 0 /*height*/; - vo_hint.flags |= PWinGravity; - vo_hint.win_gravity = StaticGravity; - XSetWMNormalHints(mDisplay, vo_window, &vo_hint); + x11->vo_hint.flags |= PWinGravity; + x11->vo_hint.win_gravity = StaticGravity; + XSetWMNormalHints(x11->display, x11->window, &x11->vo_hint); } -static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) +static int vo_x11_get_gnome_layer(struct vo_x11_state *x11, Window win) { Atom type; int format; @@ -1020,7 +958,7 @@ static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) unsigned long bytesafter; unsigned short *args = NULL; - if (XGetWindowProperty(mDisplay, win, XA_WIN_LAYER, 0, 16384, + if (XGetWindowProperty(x11->display, win, x11->XA_WIN_LAYER, 0, 16384, False, AnyPropertyType, &type, &format, &nitems, &bytesafter, (unsigned char **) &args) == Success @@ -1034,7 +972,7 @@ static int vo_x11_get_gnome_layer(Display * mDisplay, Window win) } // -Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, +static Window vo_x11_create_smooth_window(struct vo_x11_state *x11, Window mRoot, Visual * vis, int x, int y, unsigned int width, unsigned int height, int depth, Colormap col_map) @@ -1054,12 +992,12 @@ Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, xswa.bit_gravity = StaticGravity; ret_win = - XCreateWindow(mDisplay, mRootWin, x, y, width, height, 0, depth, + XCreateWindow(x11->display, x11->rootwin, x, y, width, height, 0, depth, CopyFromParent, vis, xswamask, &xswa); - XSetWMProtocols(mDisplay, ret_win, &XAWM_DELETE_WINDOW, 1); - if (!f_gc) - f_gc = XCreateGC(mDisplay, ret_win, 0, 0); - XSetForeground(mDisplay, f_gc, 0); + XSetWMProtocols(x11->display, ret_win, &x11->XAWM_DELETE_WINDOW, 1); + if (!x11->f_gc) + x11->f_gc = XCreateGC(x11->display, ret_win, 0, 0); + XSetForeground(x11->display, x11->f_gc, 0); return ret_win; } @@ -1080,176 +1018,185 @@ Window vo_x11_create_smooth_window(Display * mDisplay, Window mRoot, * This also does the grunt-work like setting Window Manager hints etc. * If vo_window is already set it just moves and resizes it. */ -void vo_x11_create_vo_window(XVisualInfo *vis, int x, int y, +void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y, unsigned int width, unsigned int height, int flags, Colormap col_map, const char *classname, const char *title) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; + Display *mDisplay = vo->x11->display; XGCValues xgcv; if (WinID >= 0) { vo_fs = flags & VOFLAG_FULLSCREEN; - vo_window = WinID ? (Window)WinID : mRootWin; + x11->window = WinID ? (Window)WinID : x11->rootwin; if (col_map != CopyFromParent) { unsigned long xswamask = CWColormap; XSetWindowAttributes xswa; xswa.colormap = col_map; - XChangeWindowAttributes(mDisplay, vo_window, xswamask, &xswa); + XChangeWindowAttributes(mDisplay, x11->window, xswamask, &xswa); XInstallColormap(mDisplay, col_map); } - if (WinID) vo_x11_update_geometry(); - vo_x11_selectinput_witherr(mDisplay, vo_window, + if (WinID) vo_x11_update_geometry(vo); + vo_x11_selectinput_witherr(mDisplay, x11->window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); goto final; } - if (vo_window == None) { + if (x11->window == None) { vo_fs = 0; - vo_dwidth = width; - vo_dheight = height; - vo_window = vo_x11_create_smooth_window(mDisplay, mRootWin, vis->visual, + vo->dwidth = width; + vo->dheight = height; + x11->window = vo_x11_create_smooth_window(x11, x11->rootwin, vis->visual, x, y, width, height, vis->depth, col_map); - window_state = VOFLAG_HIDDEN; + x11->window_state = VOFLAG_HIDDEN; } if (flags & VOFLAG_HIDDEN) goto final; - if (window_state & VOFLAG_HIDDEN) { + if (x11->window_state & VOFLAG_HIDDEN) { XSizeHints hint; XEvent xev; - window_state &= ~VOFLAG_HIDDEN; - vo_x11_classhint(mDisplay, vo_window, classname); - XStoreName(mDisplay, vo_window, title); - vo_hidecursor(mDisplay, vo_window); - XSelectInput(mDisplay, vo_window, StructureNotifyMask); + x11->window_state &= ~VOFLAG_HIDDEN; + vo_x11_classhint(vo, x11->window, classname); + XStoreName(mDisplay, x11->window, title); + vo_hidecursor(mDisplay, x11->window); + XSelectInput(mDisplay, x11->window, StructureNotifyMask); hint.x = x; hint.y = y; hint.width = width; hint.height = height; hint.flags = PPosition | PSize; - XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint); - if (!vo_border) vo_x11_decoration(mDisplay, vo_window, 0); + XSetStandardProperties(mDisplay, x11->window, title, title, None, NULL, 0, &hint); + if (!vo_border) vo_x11_decoration(vo, 0); // map window - XMapWindow(mDisplay, vo_window); - vo_x11_clearwindow(mDisplay, vo_window); + XMapWindow(mDisplay, x11->window); + vo_x11_clearwindow(vo, x11->window); // wait for map do { XNextEvent(mDisplay, &xev); - } while (xev.type != MapNotify || xev.xmap.event != vo_window); - XSelectInput(mDisplay, vo_window, NoEventMask); + } while (xev.type != MapNotify || xev.xmap.event != x11->window); + XSelectInput(mDisplay, x11->window, NoEventMask); XSync(mDisplay, False); - vo_x11_selectinput_witherr(mDisplay, vo_window, + vo_x11_selectinput_witherr(mDisplay, x11->window, StructureNotifyMask | KeyPressMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask); } - if (vo_ontop) vo_x11_setlayer(mDisplay, vo_window, vo_ontop); - vo_x11_nofs_sizepos(vo_dx, vo_dy, width, height); + if (opts->vo_ontop) vo_x11_setlayer(vo, x11->window, opts->vo_ontop); + vo_x11_nofs_sizepos(vo, vo->dx, vo->dy, width, height); if (!!vo_fs != !!(flags & VOFLAG_FULLSCREEN)) - vo_x11_fullscreen(); + vo_x11_fullscreen(vo); else if (vo_fs) { // if we are already in fullscreen do not switch back and forth, just // set the size values right. - vo_dwidth = vo_screenwidth; - vo_dheight = vo_screenheight; + vo->dwidth = vo->opts->vo_screenwidth; + vo->dheight = vo->opts->vo_screenheight; } final: - if (vo_gc != None) - XFreeGC(mDisplay, vo_gc); - vo_gc = XCreateGC(mDisplay, vo_window, GCForeground, &xgcv); + if (x11->vo_gc != None) + XFreeGC(mDisplay, x11->vo_gc); + x11->vo_gc = XCreateGC(mDisplay, x11->window, GCForeground, &xgcv); XSync(mDisplay, False); - vo_mouse_autohide = 1; + x11->vo_mouse_autohide = 1; } -void vo_x11_clearwindow_part(Display * mDisplay, Window vo_window, +void vo_x11_clearwindow_part(struct vo *vo, Window vo_window, int img_width, int img_height, int use_fs) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *mDisplay = vo->x11->display; int u_dheight, u_dwidth, left_ov, left_ov2; - if (!f_gc) + if (!x11->f_gc) return; - u_dheight = use_fs ? vo_screenheight : vo_dheight; - u_dwidth = use_fs ? vo_screenwidth : vo_dwidth; + u_dheight = use_fs ? opts->vo_screenheight : vo->dheight; + u_dwidth = use_fs ? opts->vo_screenwidth : vo->dwidth; if ((u_dheight <= img_height) && (u_dwidth <= img_width)) return; left_ov = (u_dheight - img_height) / 2; left_ov2 = (u_dwidth - img_width) / 2; - XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, u_dwidth, left_ov); - XFillRectangle(mDisplay, vo_window, f_gc, 0, u_dheight - left_ov - 1, + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, 0, u_dwidth, left_ov); + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, u_dheight - left_ov - 1, u_dwidth, left_ov + 1); if (u_dwidth > img_width) { - XFillRectangle(mDisplay, vo_window, f_gc, 0, left_ov, left_ov2, + XFillRectangle(mDisplay, vo_window, x11->f_gc, 0, left_ov, left_ov2, img_height); - XFillRectangle(mDisplay, vo_window, f_gc, u_dwidth - left_ov2 - 1, + XFillRectangle(mDisplay, vo_window, x11->f_gc, u_dwidth - left_ov2 - 1, left_ov, left_ov2 + 1, img_height); } XFlush(mDisplay); } -void vo_x11_clearwindow(Display * mDisplay, Window vo_window) +void vo_x11_clearwindow(struct vo *vo, Window vo_window) { - if (!f_gc) + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + if (!x11->f_gc) return; - XFillRectangle(mDisplay, vo_window, f_gc, 0, 0, vo_screenwidth, - vo_screenheight); + XFillRectangle(x11->display, vo_window, x11->f_gc, 0, 0, + opts->vo_screenwidth, opts->vo_screenheight); // - XFlush(mDisplay); + XFlush(x11->display); } -void vo_x11_setlayer(Display * mDisplay, Window vo_window, int layer) +void vo_x11_setlayer(struct vo *vo, Window vo_window, int layer) { + struct vo_x11_state *x11 = vo->x11; if (WinID >= 0) return; - if (vo_fs_type & vo_wm_LAYER) + if (x11->fs_type & vo_wm_LAYER) { XClientMessageEvent xev; - if (!orig_layer) - orig_layer = vo_x11_get_gnome_layer(mDisplay, vo_window); + if (!x11->orig_layer) + x11->orig_layer = vo_x11_get_gnome_layer(x11, vo_window); memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; - xev.display = mDisplay; + xev.display = x11->display; xev.window = vo_window; - xev.message_type = XA_WIN_LAYER; + xev.message_type = x11->XA_WIN_LAYER; xev.format = 32; - xev.data.l[0] = layer ? fs_layer : orig_layer; // if not fullscreen, stay on default layer + xev.data.l[0] = layer ? fs_layer : x11->orig_layer; // if not fullscreen, stay on default layer xev.data.l[1] = CurrentTime; mp_msg(MSGT_VO, MSGL_V, "[x11] Layered style stay on top (layer %ld).\n", xev.data.l[0]); - XSendEvent(mDisplay, mRootWin, False, SubstructureNotifyMask, + XSendEvent(x11->display, x11->rootwin, False, SubstructureNotifyMask, (XEvent *) & xev); - } else if (vo_fs_type & vo_wm_NETWM) + } else if (x11->fs_type & vo_wm_NETWM) { XClientMessageEvent xev; char *state; memset(&xev, 0, sizeof(xev)); xev.type = ClientMessage; - xev.message_type = XA_NET_WM_STATE; - xev.display = mDisplay; + xev.message_type = x11->XA_NET_WM_STATE; + xev.display = x11->display; xev.window = vo_window; xev.format = 32; xev.data.l[0] = layer; - if (vo_fs_type & vo_wm_STAYS_ON_TOP) - xev.data.l[1] = XA_NET_WM_STATE_STAYS_ON_TOP; - else if (vo_fs_type & vo_wm_ABOVE) - xev.data.l[1] = XA_NET_WM_STATE_ABOVE; - else if (vo_fs_type & vo_wm_FULLSCREEN) - xev.data.l[1] = XA_NET_WM_STATE_FULLSCREEN; - else if (vo_fs_type & vo_wm_BELOW) + if (x11->fs_type & vo_wm_STAYS_ON_TOP) + xev.data.l[1] = x11->XA_NET_WM_STATE_STAYS_ON_TOP; + else if (x11->fs_type & vo_wm_ABOVE) + xev.data.l[1] = x11->XA_NET_WM_STATE_ABOVE; + else if (x11->fs_type & vo_wm_FULLSCREEN) + xev.data.l[1] = x11->XA_NET_WM_STATE_FULLSCREEN; + else if (x11->fs_type & vo_wm_BELOW) // This is not fallback. We can safely assume that the situation // where only NETWM_STATE_BELOW is supported doesn't exist. - xev.data.l[1] = XA_NET_WM_STATE_BELOW; + xev.data.l[1] = x11->XA_NET_WM_STATE_BELOW; - XSendEvent(mDisplay, mRootWin, False, SubstructureRedirectMask, + XSendEvent(x11->display, x11->rootwin, False, SubstructureRedirectMask, (XEvent *) & xev); - state = XGetAtomName(mDisplay, xev.data.l[1]); + state = XGetAtomName(x11->display, xev.data.l[1]); mp_msg(MSGT_VO, MSGL_V, "[x11] NET style stay on top (layer %d). Using state %s.\n", layer, state); @@ -1329,109 +1276,117 @@ static int vo_x11_get_fs_type(int supported) } /** - * \brief update vo_dx, vo_dy, vo_dwidth and vo_dheight with current values of vo_window - * \return returns current color depth of vo_window + * \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(void) { +int vo_x11_update_geometry(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; unsigned depth, w, h; int dummy_int; Window dummy_win; - XGetGeometry(mDisplay, vo_window, &dummy_win, &dummy_int, &dummy_int, + XGetGeometry(x11->display, x11->window, &dummy_win, &dummy_int, &dummy_int, &w, &h, &dummy_int, &depth); - if (w <= INT_MAX && h <= INT_MAX) { vo_dwidth = w; vo_dheight = h; } - XTranslateCoordinates(mDisplay, vo_window, mRootWin, 0, 0, &vo_dx, &vo_dy, - &dummy_win); + if (w <= INT_MAX && h <= INT_MAX) { + vo->dwidth = w; + vo->dheight = h; + } + XTranslateCoordinates(x11->display, x11->window, x11->rootwin, 0, 0, + &vo->dx, &vo->dy, &dummy_win); if (vo_wintitle) - XStoreName(mDisplay, vo_window, vo_wintitle); + XStoreName(x11->display, x11->window, vo_wintitle); return depth <= INT_MAX ? depth : 0; } -void vo_x11_fullscreen(void) +void vo_x11_fullscreen(struct vo *vo) { + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; int x, y, w, h; - x = vo_old_x; - y = vo_old_y; - w = vo_old_width; - h = vo_old_height; + x = x11->vo_old_x; + y = x11->vo_old_y; + w = x11->vo_old_width; + h = x11->vo_old_height; if (WinID >= 0) { vo_fs = !vo_fs; return; } - if (vo_fs_flip) + if (x11->fs_flip) return; if (vo_fs) { - vo_x11_ewmh_fullscreen(_NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH + vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH vo_fs = VO_FALSE; } else { // win->fs - vo_x11_ewmh_fullscreen(_NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH + vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH vo_fs = VO_TRUE; - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs { - vo_old_x = vo_dx; - vo_old_y = vo_dy; - vo_old_width = vo_dwidth; - vo_old_height = vo_dheight; + x11->vo_old_x = vo->dx; + x11->vo_old_y = vo->dy; + x11->vo_old_width = vo->dwidth; + x11->vo_old_height = vo->dheight; } - update_xinerama_info(); + update_xinerama_info(vo); x = xinerama_x; y = xinerama_y; - w = vo_screenwidth; - h = vo_screenheight; + w = opts->vo_screenwidth; + h = opts->vo_screenheight; } { long dummy; - XGetWMNormalHints(mDisplay, vo_window, &vo_hint, &dummy); - if (!(vo_hint.flags & PWinGravity)) - old_gravity = NorthWestGravity; + XGetWMNormalHints(x11->display, x11->window, &x11->vo_hint, &dummy); + if (!(x11->vo_hint.flags & PWinGravity)) + x11->old_gravity = NorthWestGravity; else - old_gravity = vo_hint.win_gravity; + x11->old_gravity = x11->vo_hint.win_gravity; } - if (vo_wm_type == 0 && !(vo_fsmode & 16)) + if (x11->wm_type == 0 && !(vo_fsmode & 16)) { - XUnmapWindow(mDisplay, vo_window); // required for MWM - XWithdrawWindow(mDisplay, vo_window, mScreen); - vo_fs_flip = 1; + XUnmapWindow(x11->display, x11->window); // required for MWM + XWithdrawWindow(x11->display, x11->window, x11->screen); + x11->fs_flip = 1; } - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // not needed with EWMH fs { - vo_x11_decoration(mDisplay, vo_window, vo_border && !vo_fs); - vo_x11_sizehint(x, y, w, h, 0); - vo_x11_setlayer(mDisplay, vo_window, vo_fs); + vo_x11_decoration(vo, vo_border && !vo_fs); + vo_x11_sizehint(vo, x, y, w, h, 0); + vo_x11_setlayer(vo, x11->window, vo_fs); - XMoveResizeWindow(mDisplay, vo_window, x, y, w, h); + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); } /* some WMs lose ontop after fullscreen */ - if ((!(vo_fs)) & vo_ontop) - vo_x11_setlayer(mDisplay, vo_window, vo_ontop); - - XMapRaised(mDisplay, vo_window); - if ( ! (vo_fs_type & vo_wm_FULLSCREEN) ) // some WMs change window pos on map - XMoveResizeWindow(mDisplay, vo_window, x, y, w, h); - XRaiseWindow(mDisplay, vo_window); - XFlush(mDisplay); + if ((!(vo_fs)) & opts->vo_ontop) + vo_x11_setlayer(vo, x11->window, opts->vo_ontop); + + XMapRaised(x11->display, x11->window); + if ( ! (x11->fs_type & vo_wm_FULLSCREEN) ) // some WMs change window pos on map + XMoveResizeWindow(x11->display, x11->window, x, y, w, h); + XRaiseWindow(x11->display, x11->window); + XFlush(x11->display); } -void vo_x11_ontop(void) +void vo_x11_ontop(struct vo *vo) { - vo_ontop = (!(vo_ontop)); + struct MPOpts *opts = vo->opts; + opts->vo_ontop = !opts->vo_ontop; - vo_x11_setlayer(mDisplay, vo_window, vo_ontop); + vo_x11_setlayer(vo, vo->x11->window, opts->vo_ontop); } -void vo_x11_border(void) +void vo_x11_border(struct vo *vo) { vo_border = !vo_border; - vo_x11_decoration(mDisplay, vo_window, vo_border && !vo_fs); + vo_x11_decoration(vo, vo_border && !vo_fs); } /* @@ -1441,19 +1396,19 @@ void vo_x11_border(void) static int screensaver_off; static unsigned int time_last; -void xscreensaver_heartbeat(void) +void xscreensaver_heartbeat(struct vo_x11_state *x11) { unsigned int time = GetTimerMS(); - if (mDisplay && screensaver_off && (time - time_last) > 30000) + if (x11->display && screensaver_off && (time - time_last) > 30000) { time_last = time; - XResetScreenSaver(mDisplay); + XResetScreenSaver(x11->display); } } -static int xss_suspend(Bool suspend) +static int xss_suspend(Display *mDisplay, Bool suspend) { #ifndef CONFIG_XSS return 0; @@ -1473,13 +1428,13 @@ static int xss_suspend(Bool suspend) * End of XScreensaver stuff */ -void saver_on(Display * mDisplay) +static void saver_on(Display * mDisplay) { if (!screensaver_off) return; screensaver_off = 0; - if (xss_suspend(False)) + if (xss_suspend(mDisplay, False)) return; #ifdef CONFIG_XDPMS if (dpms_disabled) @@ -1513,14 +1468,14 @@ void saver_on(Display * mDisplay) #endif } -void saver_off(Display * mDisplay) +static void saver_off(Display * mDisplay) { int nothing; if (screensaver_off) return; screensaver_off = 1; - if (xss_suspend(True)) + if (xss_suspend(mDisplay, True)) return; #ifdef CONFIG_XDPMS if (DPMSQueryExtension(mDisplay, ¬hing, ¬hing)) @@ -1595,12 +1550,15 @@ void vo_x11_selectinput_witherr(Display * display, Window w, } #ifdef CONFIG_XF86VM -void vo_vm_switch(void) +void vo_vm_switch(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + struct MPOpts *opts = vo->opts; + Display *mDisplay = x11->display; int vm_event, vm_error; int vm_ver, vm_rev; int i, j, have_vm = 0; - int X = vo_dwidth, Y = vo_dheight; + int X = vo->dwidth, Y = vo->dheight; int modeline_width, modeline_height; int modecount; @@ -1619,7 +1577,7 @@ void vo_vm_switch(void) if (have_vm) { if (vidmodes == NULL) - XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, + XF86VidModeGetAllModeLines(mDisplay, x11->screen, &modecount, &vidmodes); j = 0; modeline_width = vidmodes[0]->hdisplay; @@ -1636,54 +1594,64 @@ void vo_vm_switch(void) j = i; } - mp_msg(MSGT_VO, MSGL_INFO, MSGTR_SelectedVideoMode, + mp_tmsg(MSGT_VO, MSGL_INFO, "XF86VM: Selected video mode %dx%d for image size %dx%d.\n", modeline_width, modeline_height, X, Y); - XF86VidModeLockModeSwitch(mDisplay, mScreen, 0); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[j]); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[j]); + XF86VidModeLockModeSwitch(mDisplay, x11->screen, 0); + XF86VidModeSwitchToMode(mDisplay, x11->screen, vidmodes[j]); + XF86VidModeSwitchToMode(mDisplay, x11->screen, vidmodes[j]); // FIXME: all this is more of a hack than proper solution - X = (vo_screenwidth - modeline_width) / 2; - Y = (vo_screenheight - modeline_height) / 2; - XF86VidModeSetViewPort(mDisplay, mScreen, X, Y); - vo_dx = X; - vo_dy = Y; - vo_dwidth = modeline_width; - vo_dheight = modeline_height; - aspect_save_screenres(modeline_width, modeline_height); + X = (opts->vo_screenwidth - modeline_width) / 2; + Y = (opts->vo_screenheight - modeline_height) / 2; + XF86VidModeSetViewPort(mDisplay, x11->screen, X, Y); + vo->dx = X; + vo->dy = Y; + vo->dwidth = modeline_width; + vo->dheight = modeline_height; + aspect_save_screenres(vo, modeline_width, modeline_height); } } -void vo_vm_close(void) +void vo_vm_close(struct vo *vo) { -#ifdef CONFIG_GUI - if (vidmodes != NULL && vo_window != None) -#else + Display *dpy = vo->x11->display; + struct MPOpts *opts = vo->opts; if (vidmodes != NULL) -#endif { int i, modecount; free(vidmodes); vidmodes = NULL; - XF86VidModeGetAllModeLines(mDisplay, mScreen, &modecount, + XF86VidModeGetAllModeLines(dpy, vo->x11->screen, &modecount, &vidmodes); for (i = 0; i < modecount; i++) - if ((vidmodes[i]->hdisplay == vo_screenwidth) - && (vidmodes[i]->vdisplay == vo_screenheight)) + if ((vidmodes[i]->hdisplay == opts->vo_screenwidth) + && (vidmodes[i]->vdisplay == opts->vo_screenheight)) { mp_msg(MSGT_VO, MSGL_INFO, "Returning to original mode %dx%d\n", - vo_screenwidth, vo_screenheight); + opts->vo_screenwidth, opts->vo_screenheight); break; } - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[i]); - XF86VidModeSwitchToMode(mDisplay, mScreen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); + XF86VidModeSwitchToMode(dpy, vo->x11->screen, vidmodes[i]); free(vidmodes); vidmodes = NULL; } } + +double vo_vm_get_fps(struct vo *vo) +{ + struct vo_x11_state *x11 = vo->x11; + int clock; + XF86VidModeModeLine modeline; + if (!XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline)) + return 0; + if (modeline.privsize) + XFree(modeline.private); + return 1e3 * clock / modeline.htotal / modeline.vtotal; +} #endif #endif /* X11_FULLSCREEN */ @@ -1747,12 +1715,13 @@ static XColor cols[256]; static int cm_size, red_mask, green_mask, blue_mask; -Colormap vo_x11_create_colormap(XVisualInfo * vinfo) +Colormap vo_x11_create_colormap(struct vo *vo, XVisualInfo *vinfo) { + struct vo_x11_state *x11 = vo->x11; unsigned k, r, g, b, ru, gu, bu, m, rv, gv, bv, rvu, gvu, bvu; if (vinfo->class != DirectColor) - return XCreateColormap(mDisplay, mRootWin, vinfo->visual, + return XCreateColormap(x11->display, x11->rootwin, vinfo->visual, AllocNone); /* can this function get called twice or more? */ @@ -1796,8 +1765,8 @@ Colormap vo_x11_create_colormap(XVisualInfo * vinfo) gv += gvu; bv += bvu; } - cmap = XCreateColormap(mDisplay, mRootWin, vinfo->visual, AllocAll); - XStoreColors(mDisplay, cmap, cols, cm_size); + cmap = XCreateColormap(x11->display, x11->rootwin, vinfo->visual, AllocAll); + XStoreColors(x11->display, cmap, cols, cm_size); return cmap; } @@ -1824,7 +1793,7 @@ static int transform_color(float val, return (unsigned short) (s * 65535); } -uint32_t vo_x11_set_equalizer(char *name, int value) +uint32_t vo_x11_set_equalizer(struct vo *vo, char *name, int value) { float gamma, brightness, contrast; float rf, gf, bf; @@ -1870,8 +1839,8 @@ uint32_t vo_x11_set_equalizer(char *name, int value) cols[k].blue = transform_color(bf * k, brightness, contrast, gamma); } - XStoreColors(mDisplay, cmap, cols, cm_size); - XFlush(mDisplay); + XStoreColors(vo->x11->display, cmap, cols, cm_size); + XFlush(vo->x11->display); return VO_TRUE; } @@ -1891,7 +1860,7 @@ uint32_t vo_x11_get_equalizer(char *name, int *value) } #ifdef CONFIG_XV -int vo_xv_set_eq(uint32_t xv_port, char *name, int value) +int vo_xv_set_eq(struct vo *vo, uint32_t xv_port, char *name, int value) { XvAttribute *attributes; int i, howmany, xv_atom; @@ -1899,11 +1868,11 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) mp_dbg(MSGT_VO, MSGL_V, "xv_set_eq called! (%s, %d)\n", name, value); /* get available attributes */ - attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany); + attributes = XvQueryPortAttributes(vo->x11->display, xv_port, &howmany); for (i = 0; i < howmany && attributes; i++) if (attributes[i].flags & XvSettable) { - xv_atom = XInternAtom(mDisplay, attributes[i].name, True); + xv_atom = XInternAtom(vo->x11->display, attributes[i].name, True); /* 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 (xv_atom != None) @@ -1935,6 +1904,10 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) else if (!strcmp(attributes[i].name, "XV_BLUE_INTENSITY") && (!strcasecmp(name, "blue_intensity"))) port_value = value; + else if ((!strcmp(attributes[i].name, "XV_ITURBT_709") //NVIDIA + || !strcmp(attributes[i].name, "XV_COLORSPACE"))//ATI + && (!strcasecmp(name, "bt_709"))) + port_value = value; else continue; @@ -1954,32 +1927,32 @@ int vo_xv_set_eq(uint32_t xv_port, char *name, int value) port_value = (port_value + 100) * (port_max - port_min) / 200 + port_min; - XvSetPortAttribute(mDisplay, xv_port, xv_atom, port_value); + XvSetPortAttribute(vo->x11->display, xv_port, xv_atom, port_value); return VO_TRUE; } } return VO_FALSE; } -int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) +int vo_xv_get_eq(struct vo *vo, uint32_t xv_port, char *name, int *value) { XvAttribute *attributes; int i, howmany, xv_atom; /* get available attributes */ - attributes = XvQueryPortAttributes(mDisplay, xv_port, &howmany); + attributes = XvQueryPortAttributes(vo->x11->display, xv_port, &howmany); for (i = 0; i < howmany && attributes; i++) if (attributes[i].flags & XvGettable) { - xv_atom = XInternAtom(mDisplay, attributes[i].name, True); + xv_atom = XInternAtom(vo->x11->display, attributes[i].name, True); /* 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 (xv_atom != None) { int val, port_value = 0, port_min, port_max; - XvGetPortAttribute(mDisplay, xv_port, xv_atom, + XvGetPortAttribute(vo->x11->display, xv_port, xv_atom, &port_value); port_min = attributes[i].min_value; @@ -2016,6 +1989,10 @@ int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) else if (!strcmp(attributes[i].name, "XV_BLUE_INTENSITY") && (!strcasecmp(name, "blue_intensity"))) *value = val; + else if ((!strcmp(attributes[i].name, "XV_ITURBT_709") //NVIDIA + || !strcmp(attributes[i].name, "XV_COLORSPACE"))//ATI + && (!strcasecmp(name, "bt_709"))) + *value = val; else continue; @@ -2027,11 +2004,6 @@ int vo_xv_get_eq(uint32_t xv_port, char *name, int *value) return VO_FALSE; } -/** \brief contains flags changing the execution of the colorkeying code */ -xv_ck_info_t xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR }; -unsigned long xv_colorkey; ///< The color used for manual colorkeying. -unsigned int xv_port; ///< The selected Xv port. - /** * \brief Interns the requested atom if it is available. * @@ -2040,20 +2012,21 @@ unsigned int xv_port; ///< The selected Xv port. * \return Returns the atom if available, else None is returned. * */ -static Atom xv_intern_atom_if_exists( char const * atom_name ) +static Atom xv_intern_atom_if_exists(struct vo_x11_state *x11, + char const *atom_name) { XvAttribute * attributes; int attrib_count,i; Atom xv_atom = None; - attributes = XvQueryPortAttributes( mDisplay, xv_port, &attrib_count ); + attributes = XvQueryPortAttributes(x11->display, x11->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( mDisplay, atom_name, False ); + xv_atom = XInternAtom(x11->display, atom_name, False ); break; // found what we want, break out } } @@ -2067,12 +2040,13 @@ static Atom xv_intern_atom_if_exists( char const * atom_name ) * \brief Try to enable vsync for xv. * \return Returns -1 if not available, 0 on failure and 1 on success. */ -int vo_xv_enable_vsync(void) +int vo_xv_enable_vsync(struct vo *vo) { - Atom xv_atom = xv_intern_atom_if_exists("XV_SYNC_TO_VBLANK"); + struct vo_x11_state *x11 = vo->x11; + Atom xv_atom = xv_intern_atom_if_exists(x11, "XV_SYNC_TO_VBLANK"); if (xv_atom == None) return -1; - return XvSetPortAttribute(mDisplay, xv_port, xv_atom, 1) == Success; + return XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 1) == Success; } /** @@ -2086,13 +2060,14 @@ int vo_xv_enable_vsync(void) * \param height [out] The maximum height gets stored here. * */ -void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ) +void vo_xv_get_max_img_dim(struct vo *vo, uint32_t * width, uint32_t * height) { + struct vo_x11_state *x11 = vo->x11; XvEncodingInfo * encodings; //unsigned long num_encodings, idx; to int or too long?! unsigned int num_encodings, idx; - XvQueryEncodings( mDisplay, xv_port, &num_encodings, &encodings); + XvQueryEncodings(x11->display, x11->xv_port, &num_encodings, &encodings); if ( encodings ) { @@ -2123,11 +2098,11 @@ void vo_xv_get_max_img_dim( uint32_t * width, uint32_t * height ) * Outputs the content of |ck_handling| as a readable message. * */ -void vo_xv_print_ck_info(void) +static void vo_xv_print_ck_info(struct vo_x11_state *x11) { mp_msg( MSGT_VO, MSGL_V, "[xv common] " ); - switch ( xv_ck_info.method ) + switch ( x11->xv_ck_info.method ) { case CK_METHOD_NONE: mp_msg( MSGT_VO, MSGL_V, "Drawing no colorkey.\n" ); return; @@ -2141,32 +2116,32 @@ void vo_xv_print_ck_info(void) mp_msg( MSGT_VO, MSGL_V, "\n[xv common] " ); - switch ( xv_ck_info.source ) + switch ( x11->xv_ck_info.source ) { case CK_SRC_CUR: mp_msg( MSGT_VO, MSGL_V, "Using colorkey from Xv (0x%06lx).\n", - xv_colorkey ); + x11->xv_colorkey ); break; case CK_SRC_USE: - if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + if ( x11->xv_ck_info.method == CK_METHOD_AUTOPAINT ) { mp_msg( MSGT_VO, MSGL_V, "Ignoring colorkey from MPlayer (0x%06lx).\n", - xv_colorkey ); + x11->xv_colorkey ); } else { mp_msg( MSGT_VO, MSGL_V, "Using colorkey from MPlayer (0x%06lx)." " Use -colorkey to change.\n", - xv_colorkey ); + x11->xv_colorkey ); } break; case CK_SRC_SET: mp_msg( MSGT_VO, MSGL_V, "Setting and using colorkey from MPlayer (0x%06lx)." " Use -colorkey to change.\n", - xv_colorkey ); + x11->xv_colorkey ); break; } } @@ -2191,28 +2166,29 @@ void vo_xv_print_ck_info(void) * 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. */ -int vo_xv_init_colorkey(void) +int vo_xv_init_colorkey(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; Atom xv_atom; int rez; /* check if colorkeying is needed */ - xv_atom = xv_intern_atom_if_exists( "XV_COLORKEY" ); + xv_atom = xv_intern_atom_if_exists(vo->x11, "XV_COLORKEY"); /* if we have to deal with colorkeying ... */ if( xv_atom != None && !(vo_colorkey & 0xFF000000) ) { /* check if we should use the colorkey specified in vo_colorkey */ - if ( xv_ck_info.source != CK_SRC_CUR ) + if ( x11->xv_ck_info.source != CK_SRC_CUR ) { - xv_colorkey = vo_colorkey; + x11->xv_colorkey = vo_colorkey; /* check if we have to set the colorkey too */ - if ( xv_ck_info.source == CK_SRC_SET ) + if ( x11->xv_ck_info.source == CK_SRC_SET ) { - xv_atom = XInternAtom(mDisplay, "XV_COLORKEY",False); + xv_atom = XInternAtom(x11->display, "XV_COLORKEY",False); - rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, vo_colorkey ); + rez = XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, vo_colorkey); if ( rez != Success ) { mp_msg( MSGT_VO, MSGL_FATAL, @@ -2225,10 +2201,10 @@ int vo_xv_init_colorkey(void) { int colorkey_ret; - rez=XvGetPortAttribute(mDisplay,xv_port, xv_atom, &colorkey_ret); + rez=XvGetPortAttribute(x11->display,x11->xv_port, xv_atom, &colorkey_ret); if ( rez == Success ) { - xv_colorkey = colorkey_ret; + x11->xv_colorkey = colorkey_ret; } else { @@ -2239,39 +2215,39 @@ int vo_xv_init_colorkey(void) } } - xv_atom = xv_intern_atom_if_exists( "XV_AUTOPAINT_COLORKEY" ); + xv_atom = xv_intern_atom_if_exists(vo->x11, "XV_AUTOPAINT_COLORKEY"); /* should we draw the colorkey ourselves or activate autopainting? */ - if ( xv_ck_info.method == CK_METHOD_AUTOPAINT ) + if ( x11->xv_ck_info.method == CK_METHOD_AUTOPAINT ) { rez = !Success; // reset rez to something different than Success if ( xv_atom != None ) // autopaint is supported { - rez = XvSetPortAttribute( mDisplay, xv_port, xv_atom, 1 ); + rez = XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 1); } if ( rez != Success ) { // fallback to manual colorkey drawing - xv_ck_info.method = CK_METHOD_MANUALFILL; + x11->xv_ck_info.method = CK_METHOD_MANUALFILL; } } else // disable colorkey autopainting if supported { if ( xv_atom != None ) // we have autopaint attribute { - XvSetPortAttribute( mDisplay, xv_port, xv_atom, 0 ); + XvSetPortAttribute(x11->display, x11->xv_port, xv_atom, 0); } } } else // do no colorkey drawing at all { - xv_ck_info.method = CK_METHOD_NONE; + x11->xv_ck_info.method = CK_METHOD_NONE; } /* end: should we draw colorkey */ /* output information about the current colorkey settings */ - vo_xv_print_ck_info(); + vo_xv_print_ck_info(x11); return 1; // success } @@ -2286,14 +2262,16 @@ int vo_xv_init_colorkey(void) * It doesn't call XFlush. * */ -void vo_xv_draw_colorkey( int32_t x, int32_t y, - int32_t w, int32_t h ) +void vo_xv_draw_colorkey(struct vo *vo, int32_t x, int32_t y, + int32_t w, int32_t h) { - if( xv_ck_info.method == CK_METHOD_MANUALFILL || - xv_ck_info.method == CK_METHOD_BACKGROUND )//less tearing than XClearWindow() + struct MPOpts *opts = vo->opts; + struct vo_x11_state *x11 = vo->x11; + if( x11->xv_ck_info.method == CK_METHOD_MANUALFILL || + x11->xv_ck_info.method == CK_METHOD_BACKGROUND )//less tearing than XClearWindow() { - XSetForeground( mDisplay, vo_gc, xv_colorkey ); - XFillRectangle( mDisplay, vo_window, vo_gc, + XSetForeground(x11->display, x11->vo_gc, x11->xv_colorkey ); + XFillRectangle(x11->display, x11->window, x11->vo_gc, x, y, w, h ); } @@ -2302,24 +2280,24 @@ void vo_xv_draw_colorkey( int32_t x, int32_t y, /* TODO! move this to vo_x11_clearwindow_part() */ if ( vo_fs ) { - XSetForeground( mDisplay, vo_gc, 0 ); + XSetForeground(x11->display, x11->vo_gc, 0 ); /* making non-overlap fills, requires 8 checks instead of 4 */ if ( y > 0 ) - XFillRectangle( mDisplay, vo_window, vo_gc, + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, 0, - vo_screenwidth, y); + opts->vo_screenwidth, y); if (x > 0) - XFillRectangle( mDisplay, vo_window, vo_gc, + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, 0, - x, vo_screenheight); - if (x + w < vo_screenwidth) - XFillRectangle( mDisplay, vo_window, vo_gc, + x, opts->vo_screenheight); + if (x + w < opts->vo_screenwidth) + XFillRectangle(x11->display, x11->window, x11->vo_gc, x + w, 0, - vo_screenwidth, vo_screenheight); - if (y + h < vo_screenheight) - XFillRectangle( mDisplay, vo_window, vo_gc, + opts->vo_screenwidth, opts->vo_screenheight); + if (y + h < opts->vo_screenheight) + XFillRectangle(x11->display, x11->window, x11->vo_gc, 0, y + h, - vo_screenwidth, vo_screenheight); + opts->vo_screenwidth, opts->vo_screenheight); } } @@ -2364,19 +2342,20 @@ int xv_test_ckm( void * arg ) * \param str Pointer to the string or NULL * */ -void xv_setup_colorkeyhandling( char const * ck_method_str, - char const * ck_str ) +void xv_setup_colorkeyhandling(struct vo *vo, const char *ck_method_str, + const char *ck_str) { + struct vo_x11_state *x11 = vo->x11; /* check if a valid pointer to the string was passed */ if ( ck_str ) { if ( strncmp( ck_str, "use", 3 ) == 0 ) { - xv_ck_info.source = CK_SRC_USE; + x11->xv_ck_info.source = CK_SRC_USE; } else if ( strncmp( ck_str, "set", 3 ) == 0 ) { - xv_ck_info.source = CK_SRC_SET; + x11->xv_ck_info.source = CK_SRC_SET; } } /* check if a valid pointer to the string was passed */ @@ -2384,17 +2363,30 @@ void xv_setup_colorkeyhandling( char const * ck_method_str, { if ( strncmp( ck_method_str, "bg", 2 ) == 0 ) { - xv_ck_info.method = CK_METHOD_BACKGROUND; + x11->xv_ck_info.method = CK_METHOD_BACKGROUND; } else if ( strncmp( ck_method_str, "man", 3 ) == 0 ) { - xv_ck_info.method = CK_METHOD_MANUALFILL; + x11->xv_ck_info.method = CK_METHOD_MANUALFILL; } else if ( strncmp( ck_method_str, "auto", 4 ) == 0 ) { - xv_ck_info.method = CK_METHOD_AUTOPAINT; + x11->xv_ck_info.method = CK_METHOD_AUTOPAINT; } } } #endif + +struct vo_x11_state *vo_x11_init_state(void) +{ + struct vo_x11_state *s = talloc_ptrtype(NULL, s); + *s = (struct vo_x11_state){ + .xv_ck_info = { CK_METHOD_MANUALFILL, CK_SRC_CUR }, + .olddecor = MWM_DECOR_ALL, + .oldfuncs = MWM_FUNC_MOVE | MWM_FUNC_CLOSE | MWM_FUNC_MINIMIZE | + MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE, + .old_gravity = NorthWestGravity, + }; + return s; +} |