diff options
-rwxr-xr-x | old-configure | 5 | ||||
-rw-r--r-- | video/out/vo_vdpau.c | 8 | ||||
-rw-r--r-- | video/out/x11_common.c | 84 | ||||
-rw-r--r-- | video/out/x11_common.h | 11 | ||||
-rw-r--r-- | waftools/fragments/xf86vm.c | 8 | ||||
-rw-r--r-- | wscript | 7 |
6 files changed, 83 insertions, 40 deletions
diff --git a/old-configure b/old-configure index cc0945f956..0bfac3633c 100755 --- a/old-configure +++ b/old-configure @@ -169,7 +169,6 @@ options_state_machine() { opt_yes_no _lirc "LIRC (remote control) support" opt_yes_no _joystick "joystick support" no opt_yes_no _vm "X video mode extensions" - opt_yes_no _xf86keysym "support for multimedia keys" opt_yes_no _dvb "DVB input" opt_yes_no _tv "TV interface (TV/DVB grabbers)" yes opt_yes_no _tv_v4l2 "Video4Linux2 TV interface" @@ -201,7 +200,7 @@ options_state_machine() { opt_yes_no _xv "Xv video output" opt_yes_no _vdpau "VDPAU acceleration" opt_yes_no _vaapi "VAAPI acceleration" - opt_yes_no _vm "XF86VidMode support (used for monitor FPS detection)" + opt_yes_no _xrandr "Xrandr support (used for monitor FPS detection)" opt_yes_no _xinerama "Xinerama support" opt_yes_no _x11 "X11 video output" opt_yes_no _wayland "Wayland video output" @@ -635,7 +634,7 @@ fi check_pkg_config "Xinerama" $_xinerama XINERAMA 'xinerama' -check_pkg_config "Xxf86vm" $_vm XF86VM 'xxf86vm' +check_pkg_config "Xrandr" $_xrandr XRANDR 'xrandr' # Check for the presence of special keycodes, like audio control buttons # that XFree86 might have. Used to be bundled with the xf86vm check, but diff --git a/video/out/vo_vdpau.c b/video/out/vo_vdpau.c index e3498be1d1..6699e1b906 100644 --- a/video/out/vo_vdpau.c +++ b/video/out/vo_vdpau.c @@ -338,9 +338,8 @@ static int win_x11_init_vdpau_flip_queue(struct vo *vo) MP_INFO(vo, "Assuming user-specified display refresh rate of %.3f Hz.\n", vc->user_fps); } else if (vc->user_fps == 0) { -#if HAVE_XF86VM double fps = vo_x11_vm_get_fps(vo); - if (!fps) + if (fps < 1) MP_WARN(vo, "Failed to get display FPS\n"); else { vc->vsync_interval = 1e9 / fps; @@ -349,11 +348,6 @@ static int win_x11_init_vdpau_flip_queue(struct vo *vo) MP_INFO(vo, "If that value looks wrong give the " "-vo vdpau:fps=X suboption manually.\n"); } -#else - MP_INFO(vo, "This binary has been compiled without XF86VidMode support.\n"); - MP_INFO(vo, "Can't use vsync-aware timing without manually provided " - "-vo vdpau:fps=X suboption.\n"); -#endif } else MP_VERBOSE(vo, "framedrop/timing logic disabled by user.\n"); diff --git a/video/out/x11_common.c b/video/out/x11_common.c index ef72fb4ca7..7863506cf3 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -59,14 +59,14 @@ #include <X11/extensions/Xinerama.h> #endif -#if HAVE_XF86VM -#include <X11/extensions/xf86vmode.h> -#endif - #if HAVE_XF86XK #include <X11/XF86keysym.h> #endif +#if HAVE_XRANDR +#include <X11/extensions/Xrandr.h> +#endif + #if HAVE_ZLIB #include <zlib.h> #endif @@ -325,6 +325,50 @@ static int vo_wm_detect(struct vo *vo) return wm; } +static void xrandr_read(struct vo_x11_state *x11) +{ +#ifdef HAVE_XRANDR + x11->num_displays = 0; + + XRRScreenResources *r = XRRGetScreenResources(x11->display, x11->rootwin); + if (!r) { + MP_VERBOSE(x11, "Xrandr doesn't work.\n"); + return; + } + + for (int o = 0; o < r->noutput; o++) { + RROutput output = r->outputs[o]; + XRROutputInfo *out = XRRGetOutputInfo(x11->display, r, output); + if (!out || !out->crtc) + continue; + XRRCrtcInfo *crtc = XRRGetCrtcInfo(x11->display, r, out->crtc); + if (!crtc) + continue; + for (int om = 0; om < out->nmode; om++) { + RRMode xm = out->modes[om]; + for (int n = 0; n < r->nmode; n++) { + XRRModeInfo m = r->modes[n]; + if (m.id != xm || crtc->mode != xm) + continue; + if (x11->num_displays >= MAX_DISPLAYS) + continue; + struct xrandr_display d = { + .rc = { crtc->x, crtc->y, + crtc->x + crtc->width, crtc->y + crtc->height }, + .fps = m.dotClock / (m.hTotal * (double)m.vTotal), + }; + int num = x11->num_displays++; + MP_VERBOSE(x11, "Display %d: [%d, %d, %d, %d] @ %f FPS\n", + num, d.rc.x0, d.rc.y0, d.rc.x1, d.rc.y1, d.fps); + x11->displays[num] = d; + } + } + } + + XRRFreeScreenResources(r); +#endif +} + static void vo_x11_update_screeninfo(struct vo *vo) { struct mp_vo_opts *opts = vo->opts; @@ -456,6 +500,8 @@ int vo_x11_init(struct vo *vo) vo->event_fd = ConnectionNumber(x11->display); + xrandr_read(x11); + return 1; } @@ -1359,6 +1405,11 @@ static void vo_x11_setlayer(struct vo *vo, bool ontop) } } +static bool rc_overlaps(struct mp_rect rc1, struct mp_rect rc2) +{ + return mp_rect_intersection(&rc1, &rc2); // changes the first argument +} + // update x11->winrc with current boundaries of vo->x11->window static void vo_x11_update_geometry(struct vo *vo) { @@ -1379,6 +1430,16 @@ static void vo_x11_update_geometry(struct vo *vo) &x, &y, &dummy_win); } x11->winrc = (struct mp_rect){x, y, x + w, y + h}; + double fps = 1000.0; + for (int n = 0; n < x11->num_displays; n++) { + if (rc_overlaps(x11->displays[n].rc, x11->winrc)) + fps = MPMIN(fps, x11->displays[n].fps); + } + double fallback = x11->num_displays > 0 ? x11->displays[0].fps : 0; + fps = fps < 1000.0 ? fps : fallback; + if (fps != x11->current_display_fps) + MP_VERBOSE(x11, "Current display FPS: %f\n", fps); + x11->current_display_fps = fps; } static void vo_x11_fullscreen(struct vo *vo) @@ -1596,24 +1657,11 @@ static void vo_x11_selectinput_witherr(struct vo *vo, } } -#if HAVE_XF86VM double vo_x11_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; + return x11->current_display_fps; } -#else /* HAVE_XF86VM */ -double vo_x11_vm_get_fps(struct vo *vo) -{ - return 0; -} -#endif bool vo_x11_screen_is_composited(struct vo *vo) { diff --git a/video/out/x11_common.h b/video/out/x11_common.h index 72386543de..d1ccdd7223 100644 --- a/video/out/x11_common.h +++ b/video/out/x11_common.h @@ -29,6 +29,13 @@ struct vo; struct mp_log; +#define MAX_DISPLAYS 32 // ought to be enough for everyone + +struct xrandr_display { + struct mp_rect rc; + double fps; +}; + struct vo_x11_state { struct mp_log *log; Display *display; @@ -40,6 +47,9 @@ struct vo_x11_state { int ws_height; struct mp_rect screenrc; + struct xrandr_display displays[MAX_DISPLAYS]; + int num_displays; + bool screensaver_enabled; bool dpms_touched; double screensaver_time_last; @@ -61,6 +71,7 @@ struct vo_x11_state { // Current actual window position (updated on window move/resize events). struct mp_rect winrc; + double current_display_fps; int pending_vo_events; diff --git a/waftools/fragments/xf86vm.c b/waftools/fragments/xf86vm.c deleted file mode 100644 index 195e514d6c..0000000000 --- a/waftools/fragments/xf86vm.c +++ /dev/null @@ -1,8 +0,0 @@ -#include <X11/Xlib.h> -#include <X11/extensions/xf86vmode.h> - -int main(int argc, char **argv) -{ - XF86VidModeQueryExtension(0, 0, 0); - return 0; -} @@ -567,11 +567,10 @@ video_output_features = [ 'deps': [ 'x11' ], 'func': check_pkg_config('xinerama'), }, { - 'name': '--xf86vm', - 'desc': 'Xxf86vm', + 'name': '--xrandr', + 'desc': 'Xrandr', 'deps': [ 'x11' ], - 'func': check_cc(fragment=load_fragment('xf86vm.c'), - lib='Xxf86vm', use='x11') + 'func': check_pkg_config('xrandr'), } , { 'name': '--xf86xk', 'desc': 'XF86keysym', |