From c692f457c2582d37d8fd99c7603f01e0be83d41e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 15 Apr 2018 19:25:00 +0200 Subject: [PATCH] Add switch_resolution to display_server interface --- gfx/display_servers/dispserv_null.c | 1 + gfx/display_servers/dispserv_win32.c | 86 +++++++++++++++++++++++++++- gfx/display_servers/dispserv_x11.c | 1 + gfx/video_crt_switch.c | 86 ++-------------------------- gfx/video_display_server.c | 8 +++ gfx/video_display_server.h | 10 ++++ 6 files changed, 109 insertions(+), 83 deletions(-) diff --git a/gfx/display_servers/dispserv_null.c b/gfx/display_servers/dispserv_null.c index aa02bcc9c4..65d46c5d12 100644 --- a/gfx/display_servers/dispserv_null.c +++ b/gfx/display_servers/dispserv_null.c @@ -49,6 +49,7 @@ const video_display_server_t dispserv_null = { null_set_window_opacity, null_set_window_progress, NULL, + NULL, "null" }; diff --git a/gfx/display_servers/dispserv_win32.c b/gfx/display_servers/dispserv_win32.c index ce72e247f9..901b500a46 100644 --- a/gfx/display_servers/dispserv_win32.c +++ b/gfx/display_servers/dispserv_win32.c @@ -185,9 +185,90 @@ static bool win32_set_window_decorations(void *data, bool on) { dispserv_win32_t *serv = (dispserv_win32_t*)data; - serv->decorations = on; + if (serv) + serv->decorations = on; - /* menu_setting performs a reinit instead to properly apply decoration changes */ + /* menu_setting performs a reinit instead to properly + * apply decoration changes */ + + return true; +} + +static bool win32_display_server_set_resolution(void *data, + unsigned width, unsigned height, int f_restore, int hz) +{ + LONG res; + DEVMODE curDevmode; + DEVMODE devmode; + + int iModeNum; + int freq = 0; + DWORD flags = 0; + int depth = 0; + dispserv_win32_t *serv = (dispserv_win32_t*)data; + + if (!serv) + return false; + + if (f_restore == 0) + freq = hz; + + EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &curDevmode); + + /* used to stop superresolution bug */ + if (width == curDevmode.dmPelsWidth) + width = 0; + if (width == 0) + width = curDevmode.dmPelsWidth; + if (height == 0) + height = curDevmode.dmPelsHeight; + if (depth == 0) + depth = curDevmode.dmBitsPerPel; + if (freq == 0) + freq = curDevmode.dmDisplayFrequency; + + for (iModeNum = 0; ; iModeNum++) + { + if (!EnumDisplaySettings(NULL, iModeNum, &devmode)) + break; + + if (devmode.dmPelsWidth != width) + continue; + + if (devmode.dmPelsHeight != height) + continue; + + if (devmode.dmBitsPerPel != depth) + continue; + + if (devmode.dmDisplayFrequency != freq) + continue; + + devmode.dmFields |= + DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; + res = + win32_change_display_settings(NULL, &devmode, CDS_TEST); + + switch (res) + { + case DISP_CHANGE_SUCCESSFUL: + res = win32_change_display_settings(NULL, &devmode, flags); + switch (res) + { + case DISP_CHANGE_SUCCESSFUL: + return true; + case DISP_CHANGE_NOTUPDATED: + return true; + default: + break; + } + break; + case DISP_CHANGE_RESTART: + break; + default: + break; + } + } return true; } @@ -198,6 +279,7 @@ const video_display_server_t dispserv_win32 = { win32_set_window_opacity, win32_set_window_progress, win32_set_window_decorations, + win32_display_server_set_resolution, "win32" }; diff --git a/gfx/display_servers/dispserv_x11.c b/gfx/display_servers/dispserv_x11.c index 0d20343315..c9ce9293b8 100644 --- a/gfx/display_servers/dispserv_x11.c +++ b/gfx/display_servers/dispserv_x11.c @@ -78,6 +78,7 @@ const video_display_server_t dispserv_x11 = { x11_set_window_opacity, NULL, x11_set_window_decorations, + NULL, /* set_resolution */ "x11" }; diff --git a/gfx/video_crt_switch.c b/gfx/video_crt_switch.c index eb030012ff..558b6a525e 100644 --- a/gfx/video_crt_switch.c +++ b/gfx/video_crt_switch.c @@ -27,6 +27,7 @@ #include "video_driver.h" #include "video_crt_switch.h" +#include "video_display_server.h" static unsigned ra_core_width = 0; static unsigned ra_core_height = 0; @@ -58,85 +59,6 @@ static void crt_check_first_run(void) first_run = false; } -static void crt_switch_res(unsigned width, unsigned height, - int f_restore, int ra_hz) -{ - /* Windows function to switch resolutions */ - -#if defined(_WIN32) - LONG res; - DEVMODE curDevmode; - DEVMODE devmode; - - int iModeNum; - int freq = 0; - DWORD flags = 0; - int depth = 0; - - if (f_restore == 0) - freq = ra_hz; - - EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &curDevmode); - - /* used to stop superresolution bug */ - if (width == curDevmode.dmPelsWidth) - width = 0; - if (width == 0) - width = curDevmode.dmPelsWidth; - if (height == 0) - height = curDevmode.dmPelsHeight; - if (depth == 0) - depth = curDevmode.dmBitsPerPel; - if (freq == 0) - freq = curDevmode.dmDisplayFrequency; - - for (iModeNum = 0; ; iModeNum++) - { - if (!EnumDisplaySettings(NULL, iModeNum, &devmode)) - break; - - if (devmode.dmPelsWidth != width) - continue; - - if (devmode.dmPelsHeight != height) - continue; - - if (devmode.dmBitsPerPel != depth) - continue; - - if (devmode.dmDisplayFrequency != freq) - continue; - - devmode.dmFields |= - DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY; - res = - win32_change_display_settings(NULL, &devmode, CDS_TEST); - - switch (res) - { - case DISP_CHANGE_SUCCESSFUL: - res = win32_change_display_settings(NULL, &devmode, flags); - switch (res) - { - case DISP_CHANGE_SUCCESSFUL: - return; - case DISP_CHANGE_NOTUPDATED: - return; - default: - break; - } - break; - case DISP_CHANGE_RESTART: - break; - default: - break; - } - } -#elif defined(linux) - -#endif -} - static void switch_crt_hz(void) { if (ra_core_hz == ra_tmp_core_hz) @@ -164,7 +86,8 @@ static void switch_res_crt(unsigned width, unsigned height) { if (height > 100) { - crt_switch_res(width, height, 0, ra_set_core_hz); + video_display_server_switch_resolution(width, height, + 0, ra_set_core_hz); video_driver_apply_state_changes(); } } @@ -263,5 +186,6 @@ void crt_switch_res_core(unsigned width, unsigned height, float hz) void crt_video_restore(void) { - crt_switch_res(orig_width, orig_height, 0, 60); + video_display_server_switch_resolution(orig_width, orig_height, + 0, 60); } diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c index 55baa165a2..296a10e264 100644 --- a/gfx/video_display_server.c +++ b/gfx/video_display_server.c @@ -81,3 +81,11 @@ bool video_display_server_set_window_decorations(bool on) return current_display_server->set_window_decorations(current_display_server_data, on); return false; } + +bool video_display_server_switch_resolution(unsigned width, unsigned height, + int f_restore, int hz) +{ + if (current_display_server && current_display_server->switch_resolution) + return current_display_server->switch_resolution(current_display_server_data, width, height, f_restore, hz); + return false; +} diff --git a/gfx/video_display_server.h b/gfx/video_display_server.h index 4f93a55e15..365223b30a 100644 --- a/gfx/video_display_server.h +++ b/gfx/video_display_server.h @@ -30,15 +30,25 @@ typedef struct video_display_server bool (*set_window_opacity)(void *data, unsigned opacity); bool (*set_window_progress)(void *data, int progress, bool finished); bool (*set_window_decorations)(void *data, bool on); + bool (*switch_resolution)(void *data, unsigned width, + unsigned height, int f_restore, int hz); const char *ident; } video_display_server_t; void* video_display_server_init(void); + void video_display_server_destroy(void); + bool video_display_server_set_window_opacity(unsigned opacity); + bool video_display_server_set_window_progress(int progress, bool finished); + bool video_display_server_set_window_decorations(bool on); +bool video_display_server_switch_resolution( + unsigned width, unsigned height, + int f_restore, int hz); + extern const video_display_server_t dispserv_win32; extern const video_display_server_t dispserv_x11; extern const video_display_server_t dispserv_null;