summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xold-configure5
-rw-r--r--video/out/vo_vdpau.c8
-rw-r--r--video/out/x11_common.c84
-rw-r--r--video/out/x11_common.h11
-rw-r--r--waftools/fragments/xf86vm.c8
-rw-r--r--wscript7
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;
-}
diff --git a/wscript b/wscript
index 464be54b09..478a6cefe7 100644
--- a/wscript
+++ b/wscript
@@ -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',