From 85b6437fdf96f2dc7277922b6d54acdf3f337a9c Mon Sep 17 00:00:00 2001 From: Themaister <maister@archlinux.us> Date: Tue, 30 Oct 2012 11:47:37 +0100 Subject: [PATCH] Add multi-monitor to D3D9. Untested as I don't have multiple monitors. Refactored slightly in WGL to make the code more uniform. The multi-monitor support should probably be refactored to w32_common or something similar. --- gfx/context/wgl_ctx.c | 40 +++++++++++++++++----------- gfx/d3d9/d3d9.cpp | 61 ++++++++++++++++++++++++++++++++++--------- gfx/d3d9/d3d9.hpp | 1 + 3 files changed, 75 insertions(+), 27 deletions(-) diff --git a/gfx/context/wgl_ctx.c b/gfx/context/wgl_ctx.c index e21b3b4316..c2449ecb45 100644 --- a/gfx/context/wgl_ctx.c +++ b/gfx/context/wgl_ctx.c @@ -200,7 +200,7 @@ static void gfx_ctx_get_video_size(unsigned *width, unsigned *height) } } -BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) +static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) { g_all_hms[g_num_mons++] = hMonitor; return TRUE; @@ -254,6 +254,21 @@ static void show_cursor(bool show) while (ShowCursor(FALSE) >= 0); } +static void monitor_info(MONITORINFOEX *mon, HMONITOR *hm_to_use) +{ + if (!g_last_hm) + g_last_hm = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTONEAREST); + *hm_to_use = g_last_hm; + + unsigned fs_monitor = g_settings.video.monitor_index; + if (fs_monitor && fs_monitor <= g_num_mons && g_all_hms[fs_monitor - 1]) + *hm_to_use = g_all_hms[fs_monitor - 1]; + + memset(mon, 0, sizeof(*mon)); + mon->cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(*hm_to_use, (MONITORINFO*)mon); +} + static bool gfx_ctx_set_video_mode( unsigned width, unsigned height, unsigned bits, bool fullscreen) @@ -261,18 +276,12 @@ static bool gfx_ctx_set_video_mode( (void)bits; DWORD style; + + HMONITOR hm_to_use = nullptr; MONITORINFOEX current_mon; - memset(¤t_mon, 0, sizeof(current_mon)); - current_mon.cbSize = sizeof(MONITORINFOEX); - if (!g_last_hm) - g_last_hm = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTONEAREST); - HMONITOR hm_to_use = g_last_hm; - unsigned fs_monitor = g_settings.video.monitor_index; - if (fs_monitor && fs_monitor <= g_num_mons && g_all_hms[fs_monitor - 1]) - hm_to_use = g_all_hms[fs_monitor - 1]; - - GetMonitorInfo(hm_to_use, (MONITORINFO*)¤t_mon); + monitor_info(¤t_mon, &hm_to_use); + RECT mon_rect = current_mon.rcMonitor; g_resize_width = width; g_resize_height = height; @@ -283,8 +292,8 @@ static bool gfx_ctx_set_video_mode( if (windowed_full) { style = WS_EX_TOPMOST | WS_POPUP; - g_resize_width = width = current_mon.rcMonitor.right - current_mon.rcMonitor.left; - g_resize_height = height = current_mon.rcMonitor.bottom - current_mon.rcMonitor.top; + g_resize_width = width = mon_rect.right - mon_rect.left; + g_resize_height = height = mon_rect.bottom - mon_rect.top; } else { @@ -295,6 +304,7 @@ static bool gfx_ctx_set_video_mode( // display settings might have changed, get new coordinates GetMonitorInfo(hm_to_use, (MONITORINFO*)¤t_mon); + mon_rect = current_mon.rcMonitor; g_restore_desktop = true; } } @@ -310,8 +320,8 @@ static bool gfx_ctx_set_video_mode( } g_hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", style, - fullscreen ? current_mon.rcMonitor.left : CW_USEDEFAULT, - fullscreen ? current_mon.rcMonitor.top : CW_USEDEFAULT, + fullscreen ? mon_rect.left : CW_USEDEFAULT, + fullscreen ? mon_rect.top : CW_USEDEFAULT, width, height, NULL, NULL, NULL, NULL); diff --git a/gfx/d3d9/d3d9.cpp b/gfx/d3d9/d3d9.cpp index 5ba8916592..a749342984 100644 --- a/gfx/d3d9/d3d9.cpp +++ b/gfx/d3d9/d3d9.cpp @@ -17,7 +17,7 @@ // It is written in C++11 (should be compat with MSVC 2010). // Might get rewritten in C99 if I have lots of time to burn. // -// TODO: Multi-monitor. +// TODO: Change shader on the fly. #include "d3d9.hpp" #include "render_chain.hpp" @@ -35,6 +35,14 @@ #include <cmath> #define IDI_ICON 1 +#define MAX_MONITORS 9 + +namespace Monitor +{ + static HMONITOR last_hm; + static HMONITOR all_hms[MAX_MONITORS]; + static unsigned num_mons; +} namespace Callback { @@ -256,6 +264,34 @@ static void show_cursor(bool show) while (ShowCursor(FALSE) >= 0); } +static BOOL CALLBACK monitor_enum_proc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) +{ + Monitor::all_hms[Monitor::num_mons++] = hMonitor; + return TRUE; +} + +// Multi-monitor support. +RECT D3DVideo::monitor_rect() +{ + Monitor::num_mons = 0; + EnumDisplayMonitors(nullptr, nullptr, monitor_enum_proc, 0); + + if (!Monitor::last_hm) + Monitor::last_hm = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTONEAREST); + HMONITOR hm_to_use = Monitor::last_hm; + + unsigned fs_monitor = g_settings.video.monitor_index; + if (fs_monitor && fs_monitor <= Monitor::num_mons && Monitor::all_hms[fs_monitor - 1]) + hm_to_use = Monitor::all_hms[fs_monitor - 1]; + + MONITORINFOEX current_mon; + std::memset(¤t_mon, 0, sizeof(current_mon)); + current_mon.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hm_to_use, (MONITORINFO*)¤t_mon); + + return current_mon.rcMonitor; +} + D3DVideo::D3DVideo(const video_info_t *info) : g_pD3D(nullptr), dev(nullptr), rotation(0), needs_restore(false) { @@ -274,13 +310,11 @@ D3DVideo::D3DVideo(const video_info_t *info) : windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW; RegisterClassEx(&windowClass); + RECT mon_rect = monitor_rect(); - // TODO: Multi-monitor stuff. - RECT rect; - GetClientRect(GetDesktopWindow(), &rect); - unsigned full_x = info->width == 0 ? (rect.right - rect.left) : info->width; - unsigned full_y = info->height == 0 ? (rect.bottom - rect.top) : info->height; - RARCH_LOG("[D3D9]: Desktop size: %dx%d.\n", (int)rect.right, (int)rect.bottom); + unsigned full_x = info->width == 0 ? (mon_rect.right - mon_rect.left) : info->width; + unsigned full_y = info->height == 0 ? (mon_rect.bottom - mon_rect.top) : info->height; + RARCH_LOG("[D3D9]: Monitor size: %dx%d.\n", (int)mon_rect.right, (int)mon_rect.bottom); screen_width = info->fullscreen ? full_x : info->width; screen_height = info->fullscreen ? full_y : info->height; @@ -290,11 +324,11 @@ D3DVideo::D3DVideo(const video_info_t *info) : if (!info->fullscreen) { - RECT rect = {0}; - rect.right = screen_width; + RECT rect = {0}; + rect.right = screen_width; rect.bottom = screen_height; AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX | WS_THICKFRAME), FALSE); - win_width = rect.right - rect.left; + win_width = rect.right - rect.left; win_height = rect.bottom - rect.top; } @@ -307,8 +341,9 @@ D3DVideo::D3DVideo(const video_info_t *info) : hWnd = CreateWindowEx(0, "RetroArch", title.c_str(), info->fullscreen ? (WS_EX_TOPMOST | WS_POPUP) : WS_OVERLAPPEDWINDOW & ~(WS_MAXIMIZEBOX | WS_THICKFRAME), - info->fullscreen ? 0 : CW_USEDEFAULT, - info->fullscreen ? 0 : CW_USEDEFAULT, win_width, win_height, + info->fullscreen ? mon_rect.left : CW_USEDEFAULT, + info->fullscreen ? mon_rect.top : CW_USEDEFAULT, + win_width, win_height, nullptr, nullptr, nullptr, nullptr); driver.display_type = RARCH_DISPLAY_WIN32; @@ -346,7 +381,9 @@ D3DVideo::~D3DVideo() if (g_pD3D) g_pD3D->Release(); + Monitor::last_hm = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST); DestroyWindow(hWnd); + UnregisterClass("RetroArch", GetModuleHandle(nullptr)); } diff --git a/gfx/d3d9/d3d9.hpp b/gfx/d3d9/d3d9.hpp index 5e54638217..ce8475b91b 100644 --- a/gfx/d3d9/d3d9.hpp +++ b/gfx/d3d9/d3d9.hpp @@ -70,6 +70,7 @@ class D3DVideo void init_base(const video_info_t &info); void make_d3dpp(const video_info_t &info, D3DPRESENT_PARAMETERS &d3dpp); void deinit(); + RECT monitor_rect(); video_info_t video_info; bool needs_restore;