[vlc-commits] [Git][videolan/vlc][master] 2 commits: vout: win32: keep track of monitor changes
Felix Paul Kühne (@fkuehne)
gitlab at videolan.org
Sat Sep 24 08:38:04 UTC 2022
Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
7cdf2b5f by Niklas Haas at 2022-09-24T08:23:36+00:00
vout: win32: keep track of monitor changes
Boilerplate logic leading up to the next commit.
- - - - -
ee462c83 by Niklas Haas at 2022-09-24T08:23:36+00:00
vout: win32: implement ICC profile reading
The Win32 APIs make this somewhat easy for us but also somewhat hard.
It's easy to associate between monitors and profiles, but unfortunately
only in the form of filenames which we then have to read manually.
- - - - -
2 changed files:
- modules/video_output/Makefile.am
- modules/video_output/win32/window.c
Changes:
=====================================
modules/video_output/Makefile.am
=====================================
@@ -252,6 +252,7 @@ endif
libwin32_window_plugin_la_SOURCES = video_output/win32/window.c \
video_output/wasync_resize_compressor.h
+libwin32_window_plugin_la_LIBADD = -lgdi32
if HAVE_WIN32_DESKTOP
vout_LTLIBRARIES += libwin32_window_plugin.la
endif
=====================================
modules/video_output/win32/window.c
=====================================
@@ -33,6 +33,8 @@
#include <vlc_common.h>
#include <vlc_charset.h>
+#include <vlc_es.h>
+#include <vlc_frame.h>
#include <vlc_plugin.h>
#include <vlc_window.h>
#include <vlc_mouse.h>
@@ -56,9 +58,13 @@ typedef struct vout_window_sys_t
HWND hwnd;
+ HMONITOR monitor; /* last monitor associated with window */
WCHAR class_main[256];
HICON vlc_icon;
+ /* icc profile */
+ char *icc_profile;
+
/* mouse */
unsigned button_pressed;
@@ -242,6 +248,78 @@ static void MouseReleased( vlc_window_t *wnd, unsigned button )
vlc_window_ReportMouseReleased(wnd, button);
}
+#define MAX_ICC_FILE_SIZE (100*1024*1024)
+
+static void UpdateICCProfile(vlc_window_t *wnd, const wchar_t *pathw)
+{
+ vout_window_sys_t *sys = wnd->sys;
+ vlc_icc_profile_t *icc = NULL;
+
+ if (!pathw) {
+ /* Profile cleared */
+ if (sys->icc_profile) {
+ free(sys->icc_profile);
+ sys->icc_profile = NULL;
+ vlc_window_ReportICCProfile(wnd, NULL);
+ }
+ return;
+ }
+
+ char *path = FromWide(pathw);
+ if (!path)
+ goto error;
+
+ if (sys->icc_profile && strcmp(path, sys->icc_profile) == 0) {
+ /* No change to profile */
+ free(path);
+ return;
+ }
+
+ free(sys->icc_profile);
+ sys->icc_profile = path;
+
+ /* Open ICC profile */
+ vlc_frame_t *frame = vlc_frame_FilePath(path, false);
+ if (!frame)
+ goto error;
+ vlc_frame_cleanup_push(frame);
+
+ icc = malloc(sizeof(*icc) + frame->i_buffer);
+ if (!icc)
+ goto error;
+
+ icc->size = frame->i_buffer;
+ memcpy(icc->data, frame->p_buffer, icc->size);
+ /* fall through */
+
+error:
+ if (!icc)
+ msg_Err(wnd, "Failed to open ICC profile: %s", path ? path : "(unknown)");
+
+ vlc_cleanup_pop();
+ vlc_window_ReportICCProfile(wnd, icc);
+}
+
+static void MonitorChanged(vlc_window_t *wnd, HMONITOR monitor)
+{
+ MONITORINFOEXW mi = { .cbSize = sizeof(mi) };
+ GetMonitorInfoW(monitor, (LPMONITORINFO) &mi);
+
+ /* Try updating ICC profile */
+ HDC ic = CreateICW(mi.szDevice, NULL, NULL, NULL);
+ if (!ic)
+ return;
+
+ wchar_t iccw[MAX_PATH];
+ if (GetICMProfileW(ic, &(DWORD){ sizeof(iccw) }, iccw)) {
+ UpdateICCProfile(wnd, iccw);
+ } else {
+ UpdateICCProfile(wnd, NULL);
+ }
+
+ DeleteDC(ic);
+}
+
static struct
{
@@ -364,6 +442,23 @@ static long FAR PASCAL WinVoutEventProc( HWND hwnd, UINT message,
case WM_NCMOUSEMOVE:
break;
+ case WM_DISPLAYCHANGE:
+ {
+ vout_window_sys_t *sys = wnd->sys;
+ sys->monitor = NULL;
+ }
+ /* fall through */
+ case WM_MOVE:
+ {
+ vout_window_sys_t *sys = wnd->sys;
+ HMONITOR hmon = MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTONEAREST);
+ if (hmon != sys->monitor) {
+ sys->monitor = hmon;
+ MonitorChanged(wnd, hmon);
+ }
+ break;
+ }
+
case WM_CAPTURECHANGED:
{
vout_window_sys_t *sys = wnd->sys;
@@ -643,6 +738,10 @@ static void *EventThread( void *p_this )
return NULL;
}
+ /* Detect starting monitor */
+ sys->monitor = MonitorFromWindow(sys->hwnd, MONITOR_DEFAULTTOPRIMARY);
+ MonitorChanged(wnd, sys->monitor);
+
/* Append a "Always On Top" entry in the system menu */
HMENU hMenu = GetSystemMenu( sys->hwnd, FALSE );
AppendMenu( hMenu, MF_SEPARATOR, 0, TEXT("") );
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/bc9b62b7babf97942fc48e89925f7716fe050b8a...ee462c838de769f1c44306975b85c4bab4186baa
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/bc9b62b7babf97942fc48e89925f7716fe050b8a...ee462c838de769f1c44306975b85c4bab4186baa
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list