summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-01-26 02:18:47 +0100
committerwm4 <wm4@nowhere>2015-01-26 02:18:47 +0100
commitdf3e6b549c568e4b9d7981c9e4eedba9689c2e05 (patch)
treee7aacd9e1bca2430b58c0afaf47484e768bdc109
parent73d5e396fee7de11c525495d066f40d28e3c242b (diff)
downloadmpv-df3e6b549c568e4b9d7981c9e4eedba9689c2e05.tar.bz2
mpv-df3e6b549c568e4b9d7981c9e4eedba9689c2e05.tar.xz
vo_opengl, x11: implement icc-profile-auto
This queries the _ICC_PROFILE property on the root window. It also tries to reload the ICC when it changes, or if the mpv window changes the monitor. (If multiple monitors are covered, mpv will randomly select one of them.) The official spec is a dead link on freedesktop.org, so don't blame me for any bugs. Note that this assumes that Xinerama screen numbers match the way mpv enumerates the xrandr monitors. Although there is some chance that this matches, it most likely doesn't, and we actually have to do complicated things to map the screen numbers. If it turns out that this is required, I will fix it as soon as someone with a suitable setup for testing the fix reports it.
-rw-r--r--DOCS/man/vo.rst2
-rw-r--r--video/out/x11_common.c37
-rw-r--r--video/out/x11_common.h3
3 files changed, 37 insertions, 5 deletions
diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst
index d5be46ac9b..1d1ab950c7 100644
--- a/DOCS/man/vo.rst
+++ b/DOCS/man/vo.rst
@@ -523,7 +523,7 @@ Available video output drivers are:
Automatically select the ICC display profile currently specified by
the display settings of the operating system.
- NOTE: Only implemented on OS X with Cocoa.
+ NOTE: Only implemented on OS X and X11
``icc-cache=<file>``
Store and load the 3D LUT created from the ICC profile in this file.
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 4f602c802d..804c62b805 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -148,7 +148,7 @@ static void *x11_get_property(struct vo_x11_state *x11, Window w, Atom property,
*out_nitems = 0;
if (!w)
return NULL;
- long max_len = 64 * 1024; // static maximum limit
+ long max_len = 128 * 1024 * 1024; // static maximum limit
Atom ret_type = 0;
int ret_format = 0;
unsigned long ret_nitems = 0;
@@ -970,6 +970,8 @@ int vo_x11_check_events(struct vo *vo)
}
} else if (Event.xproperty.atom == XA(x11, _NET_WM_STATE)) {
x11->pending_vo_events |= VO_EVENT_WIN_STATE;
+ } else if (Event.xproperty.atom == x11->icc_profile_property) {
+ x11->pending_vo_events |= VO_EVENT_ICC_PROFILE_PATH_CHANGED;
}
break;
default:
@@ -1541,8 +1543,10 @@ static void vo_x11_update_geometry(struct vo *vo)
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);
+ struct xrandr_display *disp = &x11->displays[n];
+ disp->overlaps = rc_overlaps(disp->rc, x11->winrc);
+ if (disp->overlaps)
+ fps = MPMIN(fps, disp->fps);
}
double fallback = x11->num_displays > 0 ? x11->displays[0].fps : 0;
fps = fps < 1000.0 ? fps : fallback;
@@ -1550,7 +1554,7 @@ static void vo_x11_update_geometry(struct vo *vo)
MP_VERBOSE(x11, "Current display FPS: %f\n", fps);
x11->current_display_fps = fps;
// might have changed displays
- x11->pending_vo_events |= VO_EVENT_WIN_STATE;
+ x11->pending_vo_events |= VO_EVENT_WIN_STATE | VO_EVENT_ICC_PROFILE_PATH_CHANGED;
}
static void vo_x11_fullscreen(struct vo *vo)
@@ -1684,6 +1688,31 @@ int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
*(char ***)arg = names;
return VO_TRUE;
}
+ case VOCTRL_GET_ICC_PROFILE: {
+ int screen = 0; // xinerama screen number
+ for (int n = 0; n < x11->num_displays; n++) {
+ struct xrandr_display *disp = &x11->displays[n];
+ if (disp->overlaps) {
+ screen = n;
+ break;
+ }
+ }
+ char prop[80];
+ snprintf(prop, sizeof(prop), "_ICC_PROFILE");
+ if (screen > 0)
+ mp_snprintf_cat(prop, sizeof(prop), "_%d", screen);
+ x11->icc_profile_property = XAs(x11, prop);
+ int len;
+ void *icc = x11_get_property(x11, x11->rootwin, x11->icc_profile_property,
+ XA_CARDINAL, 8, &len);
+ if (!icc)
+ return VO_FALSE;
+ *(bstr *)arg = bstrdup(NULL, (bstr){icc, len});
+ XFree(icc);
+ // Watch x11->icc_profile_property
+ XSelectInput(x11->display, x11->rootwin, PropertyChangeMask);
+ return VO_TRUE;
+ }
case VOCTRL_SET_CURSOR_VISIBILITY:
vo_set_cursor_hidden(vo, !(*(bool *)arg));
return VO_TRUE;
diff --git a/video/out/x11_common.h b/video/out/x11_common.h
index ba52bb92aa..095872cf78 100644
--- a/video/out/x11_common.h
+++ b/video/out/x11_common.h
@@ -35,6 +35,7 @@ struct xrandr_display {
struct mp_rect rc;
double fps;
char *name;
+ bool overlaps;
};
struct vo_x11_state {
@@ -110,6 +111,8 @@ struct vo_x11_state {
/* dragging the window */
bool win_drag_button1_down;
+
+ Atom icc_profile_property;
};
int vo_x11_init(struct vo *vo);