summaryrefslogtreecommitdiffstats
path: root/video/out/w32_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/w32_common.c')
-rw-r--r--video/out/w32_common.c171
1 files changed, 71 insertions, 100 deletions
diff --git a/video/out/w32_common.c b/video/out/w32_common.c
index 1db54fc70e..f0a568dbcb 100644
--- a/video/out/w32_common.c
+++ b/video/out/w32_common.c
@@ -62,6 +62,9 @@ typedef enum MONITOR_DPI_TYPE {
} MONITOR_DPI_TYPE;
#endif
+#define rect_w(r) ((r).right - (r).left)
+#define rect_h(r) ((r).bottom - (r).top)
+
struct w32_api {
HRESULT (WINAPI *pGetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
BOOL (WINAPI *pImmDisableIME)(DWORD);
@@ -85,15 +88,8 @@ struct vo_w32_state {
HWINEVENTHOOK parent_evt_hook;
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;
- int prev_height;
- int prev_x;
- int prev_y;
-
// Has the window seen a WM_DESTROY? If so, don't call DestroyWindow again.
bool destroyed;
@@ -103,11 +99,10 @@ struct vo_w32_state {
bool current_fs;
bool toggle_fs; // whether the current fullscreen state needs to be switched
- // currently known window state
- int window_x;
- int window_y;
- int dw;
- int dh;
+ RECT windowrc; // currently known window rect
+ RECT screenrc; // current screen rect
+ // last non-fullscreen rect, updated only on fullscreen or on initialization
+ RECT prev_windowrc;
// video size
uint32_t o_dwidth;
@@ -184,16 +179,16 @@ static LRESULT borderless_nchittest(struct vo_w32_state *w32, int x, int y)
if (mouse.y < frame_size) {
if (mouse.x < diagonal_width)
return HTTOPLEFT;
- if (mouse.x >= w32->dw - diagonal_width)
+ if (mouse.x >= rect_w(w32->windowrc) - diagonal_width)
return HTTOPRIGHT;
return HTTOP;
}
// Hit-test bottom border
- if (mouse.y >= w32->dh - frame_size) {
+ if (mouse.y >= rect_h(w32->windowrc) - frame_size) {
if (mouse.x < diagonal_width)
return HTBOTTOMLEFT;
- if (mouse.x >= w32->dw - diagonal_width)
+ if (mouse.x >= rect_w(w32->windowrc) - diagonal_width)
return HTBOTTOMRIGHT;
return HTBOTTOM;
}
@@ -201,7 +196,7 @@ static LRESULT borderless_nchittest(struct vo_w32_state *w32, int x, int y)
// Hit-test side borders
if (mouse.x < frame_size)
return HTLEFT;
- if (mouse.x >= w32->dw - frame_size)
+ if (mouse.x >= rect_w(w32->windowrc) - frame_size)
return HTRIGHT;
return HTCLIENT;
}
@@ -619,8 +614,7 @@ static bool snap_to_screen_edges(struct vo_w32_state *w32, RECT *rc)
if (!GetWindowRect(w32->window, &rect) || !GetCursorPos(&cursor))
return false;
// Check if window is going to be aero-snapped
- if ((rc->right - rc->left != rect.right - rect.left) ||
- (rc->bottom - rc->top != rect.bottom - rect.top))
+ if (rect_w(*rc) != rect_w(rect) || rect_h(*rc) != rect_h(rect))
return false;
// Check if window has already been aero-snapped
@@ -629,8 +623,7 @@ static bool snap_to_screen_edges(struct vo_w32_state *w32, RECT *rc)
if (!GetWindowPlacement(w32->window, &wp))
return false;
RECT wr = wp.rcNormalPosition;
- if ((rc->right - rc->left != wr.right - wr.left) ||
- (rc->bottom - rc->top != wr.bottom - wr.top))
+ if (rect_w(*rc) != rect_w(wr) || rect_h(*rc) != rect_h(wr))
return false;
MONITORINFO mi = { .cbSize = sizeof(mi) };
@@ -718,15 +711,10 @@ static void update_screen_rect(struct vo_w32_state *w32)
// Handle --fs-screen=all
if (w32->current_fs && screen == -2) {
- struct mp_rect rc = {
- GetSystemMetrics(SM_XVIRTUALSCREEN),
- GetSystemMetrics(SM_YVIRTUALSCREEN),
- GetSystemMetrics(SM_CXVIRTUALSCREEN),
- GetSystemMetrics(SM_CYVIRTUALSCREEN),
- };
- rc.x1 += rc.x0;
- rc.y1 += rc.y0;
- w32->screenrc = rc;
+ const int x = GetSystemMetrics(SM_XVIRTUALSCREEN);
+ const int y = GetSystemMetrics(SM_YVIRTUALSCREEN);
+ SetRect(&w32->screenrc, x, y, x + GetSystemMetrics(SM_CXVIRTUALSCREEN),
+ y + GetSystemMetrics(SM_CYVIRTUALSCREEN));
return;
}
@@ -746,10 +734,7 @@ static void update_screen_rect(struct vo_w32_state *w32)
MONITORINFO mi = { .cbSize = sizeof(mi) };
GetMonitorInfoW(mon, &mi);
- w32->screenrc = (struct mp_rect){
- mi.rcMonitor.left, mi.rcMonitor.top,
- mi.rcMonitor.right, mi.rcMonitor.bottom,
- };
+ w32->screenrc = mi.rcMonitor;
}
static DWORD update_style(struct vo_w32_state *w32, DWORD style)
@@ -793,41 +778,26 @@ static void reinit_window_state(struct vo_w32_state *w32)
// xxx not sure if this can trigger any unwanted messages (WM_MOVE/WM_SIZE)
update_screen_rect(w32);
- int screen_w = w32->screenrc.x1 - w32->screenrc.x0;
- int screen_h = w32->screenrc.y1 - w32->screenrc.y0;
-
if (w32->current_fs) {
// Save window position and size when switching to fullscreen.
if (toggle_fs) {
- w32->prev_width = w32->dw;
- w32->prev_height = w32->dh;
- w32->prev_x = w32->window_x;
- w32->prev_y = w32->window_y;
+ w32->prev_windowrc = w32->windowrc;
MP_VERBOSE(w32, "save window bounds: %d:%d:%d:%d\n",
- w32->prev_x, w32->prev_y, w32->prev_width, w32->prev_height);
+ (int)w32->windowrc.left, (int)w32->windowrc.top,
+ (int)rect_w(w32->windowrc), (int)rect_h(w32->windowrc));
}
-
- w32->window_x = w32->screenrc.x0;
- w32->window_y = w32->screenrc.y0;
- w32->dw = screen_w;
- w32->dh = screen_h;
+ w32->windowrc = w32->screenrc;
} else {
+ // Restore window position and size when switching from fullscreen.
if (toggle_fs) {
- // Restore window position and size when switching from fullscreen.
+ w32->windowrc = w32->prev_windowrc;
MP_VERBOSE(w32, "restore window bounds: %d:%d:%d:%d\n",
- w32->prev_x, w32->prev_y, w32->prev_width, w32->prev_height);
- w32->dw = w32->prev_width;
- w32->dh = w32->prev_height;
- w32->window_x = w32->prev_x;
- w32->window_y = w32->prev_y;
+ (int)w32->windowrc.left, (int)w32->windowrc.top,
+ (int)rect_w(w32->windowrc), (int)rect_h(w32->windowrc));
}
}
- r.left = w32->window_x;
- r.right = r.left + w32->dw;
- r.top = w32->window_y;
- r.bottom = r.top + w32->dh;
-
+ r = w32->windowrc;
SetWindowLongPtrW(w32->window, GWL_STYLE, style);
RECT cr = r;
@@ -843,6 +813,9 @@ static void reinit_window_state(struct vo_w32_state *w32)
o_h = cr.bottom - cr.top;
}
+ const int screen_w = rect_w(w32->screenrc);
+ const int screen_h = rect_h(w32->screenrc);
+
if ( !w32->current_fs && ( o_w > screen_w || o_h > screen_h ) )
{
MP_VERBOSE(w32, "requested window size larger than the screen\n");
@@ -866,8 +839,8 @@ static void reinit_window_state(struct vo_w32_state *w32)
n_w = n_h * asp;
}
// Save new size
- w32->dw = n_w;
- w32->dh = n_h;
+ w32->windowrc.right = w32->windowrc.left + n_w;
+ w32->windowrc.bottom = w32->windowrc.top + n_h;
// Get old window center
long o_cx = r.left + (r.right - r.left) / 2;
long o_cy = r.top + (r.bottom - r.top) / 2;
@@ -885,8 +858,8 @@ static void reinit_window_state(struct vo_w32_state *w32)
r.right = r.left + n_w;
r.bottom = r.top + n_h;
// Save new client area position
- w32->window_x = r.left + b_left;
- w32->window_y = r.top + b_top;
+ OffsetRect(&w32->windowrc, r.left + b_left - w32->windowrc.left,
+ r.top + b_top - w32->windowrc.top);
}
MP_VERBOSE(w32, "reset window bounds: %d:%d:%d:%d\n",
@@ -929,16 +902,15 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
signal_events(w32, VO_EVENT_EXPOSE);
break;
case WM_MOVE: {
- POINT p = {0};
- ClientToScreen(w32->window, &p);
- w32->window_x = p.x;
- w32->window_y = p.y;
+ const int x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
+ OffsetRect(&w32->windowrc, x - w32->windowrc.left,
+ y - w32->windowrc.top);
// Window may intersect with new monitors (see VOCTRL_GET_DISPLAY_NAMES)
signal_events(w32, VO_EVENT_WIN_STATE);
update_display_info(w32); // if we moved between monitors
- MP_DBG(w32, "move window: %d:%d\n", w32->window_x, w32->window_y);
+ MP_DBG(w32, "move window: %d:%d\n", x, y);
break;
}
case WM_MOVING: {
@@ -968,12 +940,12 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
if (w32->moving)
w32->snapped = false;
- RECT r;
- if (GetClientRect(w32->window, &r) && r.right > 0 && r.bottom > 0) {
- w32->dw = r.right;
- w32->dh = r.bottom;
+ const int w = LOWORD(lParam), h = HIWORD(lParam);
+ if (w > 0 && h > 0) {
+ w32->windowrc.right = w32->windowrc.left + w;
+ w32->windowrc.bottom = w32->windowrc.top + h;
signal_events(w32, VO_EVENT_RESIZE);
- MP_VERBOSE(w32, "resize window: %d:%d\n", w32->dw, w32->dh);
+ MP_VERBOSE(w32, "resize window: %d:%d\n", w, h);
}
// Window may have been minimized or restored
@@ -991,7 +963,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
// (subtracting the window borders)
RECT r = *rc;
subtract_window_borders(w32->window, &r);
- int c_w = r.right - r.left, c_h = r.bottom - r.top;
+ int c_w = rect_w(r), c_h = rect_h(r);
float aspect = w32->o_dwidth / (float) MPMAX(w32->o_dheight, 1);
int d_w = c_h * aspect - c_w;
int d_h = c_w / aspect - c_h;
@@ -1279,14 +1251,16 @@ static void run_message_loop(struct vo_w32_state *w32)
static void gui_thread_reconfig(void *ptr)
{
struct vo_w32_state *w32 = ptr;
-
struct vo *vo = w32->vo;
struct vo_win_geometry geo;
- vo_calc_window_geometry(vo, &w32->screenrc, &geo);
+ struct mp_rect screen = { w32->screenrc.left, w32->screenrc.top,
+ w32->screenrc.right, w32->screenrc.bottom };
+ vo_calc_window_geometry(vo, &screen, &geo);
vo_apply_window_geometry(vo, &geo);
- bool reset_size = w32->o_dwidth != vo->dwidth || w32->o_dheight != vo->dheight;
+ bool reset_size = w32->o_dwidth != vo->dwidth ||
+ w32->o_dheight != vo->dheight;
bool pos_init = false;
w32->o_dwidth = vo->dwidth;
@@ -1305,13 +1279,15 @@ static void gui_thread_reconfig(void *ptr)
w32->window_bounds_initialized = true;
reset_size = true;
pos_init = true;
- w32->window_x = w32->prev_x = geo.win.x0;
- w32->window_y = w32->prev_y = geo.win.y0;
+ w32->windowrc.left = w32->prev_windowrc.left = geo.win.x0;
+ w32->windowrc.top = w32->prev_windowrc.top = geo.win.y0;
}
if (reset_size) {
- w32->prev_width = vo->dwidth = w32->o_dwidth;
- w32->prev_height = vo->dheight = w32->o_dheight;
+ vo->dwidth = w32->o_dwidth;
+ vo->dheight = w32->o_dheight;
+ w32->prev_windowrc.right = w32->prev_windowrc.left + vo->dwidth;
+ w32->prev_windowrc.bottom = w32->prev_windowrc.top + vo->dheight;
}
} else {
RECT r;
@@ -1323,11 +1299,11 @@ static void gui_thread_reconfig(void *ptr)
// Recenter window around old position on new video size
// excluding the case when initial position handled by win_state.
if (!pos_init) {
- w32->window_x += w32->dw / 2 - vo->dwidth / 2;
- w32->window_y += w32->dh / 2 - vo->dheight / 2;
+ w32->windowrc.left += rect_w(w32->windowrc) / 2 - vo->dwidth / 2;
+ w32->windowrc.top += rect_h(w32->windowrc) / 2 - vo->dheight / 2;
}
- w32->dw = vo->dwidth;
- w32->dh = vo->dheight;
+ w32->windowrc.right = w32->windowrc.left + vo->dwidth;
+ w32->windowrc.bottom = w32->windowrc.top + vo->dheight;
reinit_window_state(w32);
}
@@ -1576,8 +1552,9 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg)
if (!w32->window_bounds_initialized)
return VO_FALSE;
- s[0] = w32->current_fs ? w32->prev_width : w32->dw;
- s[1] = w32->current_fs ? w32->prev_height : w32->dh;
+ RECT *rc = w32->current_fs ? &w32->prev_windowrc : &w32->windowrc;
+ s[0] = rect_w(*rc);
+ s[1] = rect_h(*rc);
return VO_TRUE;
}
case VOCTRL_SET_UNFS_WINDOW_SIZE: {
@@ -1585,17 +1562,11 @@ static int gui_thread_control(struct vo_w32_state *w32, int request, void *arg)
if (!w32->window_bounds_initialized)
return VO_FALSE;
- if (w32->current_fs) {
- w32->prev_x += w32->prev_width / 2 - s[0] / 2;
- w32->prev_y += w32->prev_height / 2 - s[1] / 2;
- w32->prev_width = s[0];
- w32->prev_height = s[1];
- } else {
- w32->window_x += w32->dw / 2 - s[0] / 2;
- w32->window_y += w32->dh / 2 - s[1] / 2;
- w32->dw = s[0];
- w32->dh = s[1];
- }
+
+ RECT *rc = w32->current_fs ? &w32->prev_windowrc : &w32->windowrc;
+ const int x = rc->left + rect_w(*rc) / 2 - s[0] / 2;
+ const int y = rc->top + rect_h(*rc) / 2 - s[1] / 2;
+ SetRect(rc, x, y, x + s[0], y + s[1]);
reinit_window_state(w32);
return VO_TRUE;
@@ -1666,8 +1637,8 @@ static void do_control(void *ptr)
*events |= atomic_fetch_and(&w32->event_flags, 0);
// Safe access, since caller (owner of vo) is blocked.
if (*events & VO_EVENT_RESIZE) {
- w32->vo->dwidth = w32->dw;
- w32->vo->dheight = w32->dh;
+ w32->vo->dwidth = rect_w(w32->windowrc);
+ w32->vo->dheight = rect_h(w32->windowrc);
}
}
@@ -1678,8 +1649,8 @@ int vo_w32_control(struct vo *vo, int *events, int request, void *arg)
*events |= atomic_fetch_and(&w32->event_flags, 0);
if (*events & VO_EVENT_RESIZE) {
mp_dispatch_lock(w32->dispatch);
- vo->dwidth = w32->dw;
- vo->dheight = w32->dh;
+ vo->dwidth = rect_w(w32->windowrc);
+ vo->dheight = rect_h(w32->windowrc);
mp_dispatch_unlock(w32->dispatch);
}
return VO_TRUE;