summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorJames Ross-Gowan <rossymiles@gmail.com>2015-11-26 22:11:45 +1100
committerJames Ross-Gowan <rossymiles@gmail.com>2015-11-26 23:04:50 +1100
commit69ba4f776ffffc0fa59a88ddcb2cd22d0326d007 (patch)
treec7d6fd9b90552310b67604d87f98e56526612835 /video
parent4c111fbcde6abe9ce4fab0f1e7fcef384efcc4e5 (diff)
downloadmpv-69ba4f776ffffc0fa59a88ddcb2cd22d0326d007.tar.bz2
mpv-69ba4f776ffffc0fa59a88ddcb2cd22d0326d007.tar.xz
w32_common: implement icc-profile-auto
This adds basic support for ICC profiles. Per-monitor profiles are supported. WCS profiles are not supported, but there is an API for converting WCS profiles to ICC, so they might be supported in future. I'm just not sure if anyone actually uses them. Reloading the ICC profile when it's changed in the control panel is also not supported. This might be possible by using the WCS APIs and watching the registry for changes, but there is no official API for it, and as far as I can tell, no other Windows programs can do it.
Diffstat (limited to 'video')
-rw-r--r--video/out/w32_common.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/video/out/w32_common.c b/video/out/w32_common.c
index 6d02c62c57..217359a7b1 100644
--- a/video/out/w32_common.c
+++ b/video/out/w32_common.c
@@ -30,6 +30,7 @@
#include "input/keycodes.h"
#include "input/input.h"
#include "input/event.h"
+#include "stream/stream.h"
#include "common/msg.h"
#include "common/common.h"
#include "vo.h"
@@ -63,6 +64,7 @@ struct vo_w32_state {
HMONITOR monitor; // Handle of the current screen
struct mp_rect screenrc; // Size and virtual position of the current screen
+ char *color_profile; // Path of the current screen's color profile
// last non-fullscreen extends (updated only on fullscreen or on initialization)
int prev_width;
@@ -606,7 +608,25 @@ static double get_refresh_rate_from_gdi(const wchar_t *device)
return rv;
}
-static void update_display_fps(struct vo_w32_state *w32)
+static char *get_color_profile(void *ctx, const wchar_t *device)
+{
+ char *name = NULL;
+
+ HDC ic = CreateICW(device, NULL, NULL, NULL);
+ if (!ic)
+ goto done;
+ wchar_t wname[MAX_PATH + 1];
+ if (!GetICMProfileW(ic, &(DWORD){ MAX_PATH }, wname))
+ goto done;
+
+ name = mp_to_utf8(ctx, wname);
+done:
+ if (ic)
+ DeleteDC(ic);
+ return name;
+}
+
+static void update_display_info(struct vo_w32_state *w32)
{
HMONITOR monitor = MonitorFromWindow(w32->window, MONITOR_DEFAULTTOPRIMARY);
if (w32->monitor == monitor)
@@ -631,12 +651,26 @@ static void update_display_fps(struct vo_w32_state *w32)
w32->display_fps = freq;
signal_events(w32, VO_EVENT_WIN_STATE);
}
+
+ char *color_profile = get_color_profile(w32, mi.szDevice);
+ if ((color_profile == NULL) != (w32->color_profile == NULL) ||
+ (color_profile && strcmp(color_profile, w32->color_profile)))
+ {
+ if (color_profile)
+ MP_VERBOSE(w32, "color-profile: %s\n", color_profile);
+ talloc_free(w32->color_profile);
+ w32->color_profile = color_profile;
+ color_profile = NULL;
+ signal_events(w32, VO_EVENT_ICC_PROFILE_CHANGED);
+ }
+
+ talloc_free(color_profile);
}
-static void force_update_display_fps(struct vo_w32_state *w32)
+static void force_update_display_info(struct vo_w32_state *w32)
{
w32->monitor = 0;
- update_display_fps(w32);
+ update_display_info(w32);
}
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
@@ -664,7 +698,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
ClientToScreen(w32->window, &p);
w32->window_x = p.x;
w32->window_y = p.y;
- update_display_fps(w32); // if we moved between monitors
+ update_display_info(w32); // if we moved between monitors
MP_VERBOSE(w32, "move window: %d:%d\n", w32->window_x, w32->window_y);
break;
}
@@ -680,7 +714,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
// Window may have been minimized or restored
signal_events(w32, VO_EVENT_WIN_STATE);
- update_display_fps(w32);
+ update_display_info(w32);
break;
}
case WM_SIZING:
@@ -825,7 +859,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
mouse_button |= MP_KEY_STATE_UP;
break;
case WM_DISPLAYCHANGE:
- force_update_display_fps(w32);
+ force_update_display_info(w32);
break;
}
@@ -1393,9 +1427,18 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg)
return VO_TRUE;
}
case VOCTRL_GET_DISPLAY_FPS:
- update_display_fps(w32);
+ update_display_info(w32);
*(double*) arg = w32->display_fps;
return VO_TRUE;
+ case VOCTRL_GET_ICC_PROFILE:
+ update_display_info(w32);
+ if (w32->color_profile) {
+ bstr *p = arg;
+ *p = stream_read_file(w32->color_profile, NULL,
+ w32->vo->global, 100000000); // 100 MB
+ return p->len ? VO_TRUE : VO_FALSE;
+ }
+ return VO_FALSE;
}
return VO_NOTIMPL;
}