From 1242eddfb2959397d126041e19d29366532d6241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net> Date: Tue, 6 Jun 2023 18:56:22 -0400 Subject: [PATCH] Add fullscreen GDI startup mode. --- src/conio/ciolib.c | 1 + src/conio/ciolib.h | 1 + src/conio/win32gdi.c | 111 ++++++++++++++++++++++++++++++---------- src/syncterm/bbslist.c | 15 +++--- src/syncterm/syncterm.c | 42 +++++++++------ 5 files changed, 122 insertions(+), 48 deletions(-) diff --git a/src/conio/ciolib.c b/src/conio/ciolib.c index 220144ffb9..0deeb80471 100644 --- a/src/conio/ciolib.c +++ b/src/conio/ciolib.c @@ -521,6 +521,7 @@ CIOLIBEXPORT int initciolib(int mode) #if defined(WITH_GDI) case CIOLIB_MODE_GDI: + case CIOLIB_MODE_GDI_FULLSCREEN: try_gdi_init(mode); break; #endif diff --git a/src/conio/ciolib.h b/src/conio/ciolib.h index 9e4e2d2fa5..3a80614ae8 100644 --- a/src/conio/ciolib.h +++ b/src/conio/ciolib.h @@ -80,6 +80,7 @@ enum { ,CIOLIB_MODE_SDL ,CIOLIB_MODE_SDL_FULLSCREEN ,CIOLIB_MODE_GDI + ,CIOLIB_MODE_GDI_FULLSCREEN }; enum ciolib_mouse_ptr { diff --git a/src/conio/win32gdi.c b/src/conio/win32gdi.c index fb27ce6e53..7b5b5d216a 100644 --- a/src/conio/win32gdi.c +++ b/src/conio/win32gdi.c @@ -19,6 +19,7 @@ static bool maximized = false; static uint16_t winxpos, winypos; static const DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_VISIBLE; static const DWORD fs_style = WS_POPUP | WS_VISIBLE; +#define STYLE (fullscreen ? fs_style : style) static HCURSOR cursor; static HANDLE init_sem; static int xoff, yoff; @@ -66,6 +67,8 @@ static pthread_mutex_t stypelock; // Internal implementation +static bool get_monitor_size_pos(int *w, int *h, int *xpos, int *ypos); + static LPWSTR utf8_to_utf16(const uint8_t *str8, int buflen) { @@ -181,7 +184,9 @@ UnadjustWindowSize(int *w, int *h) RECT r = {0}; bool ret; - ret = AdjustWindowRect(&r, style, FALSE); + if (fullscreen) + return true; + ret = AdjustWindowRect(&r, STYLE, FALSE); if (ret) { *w += r.left - r.right; *h += r.top - r.bottom; @@ -482,17 +487,42 @@ gdi_handle_activate(HWND hwnd, WPARAM wParam) } static bool -gdi_get_monitor_size(int *w, int *h) +get_monitor_size_pos(int *w, int *h, int *xpos, int *ypos) { + bool primary = false; + bool ret = false; HMONITOR mon; MONITORINFO mi; - bool ret; - mon = MonitorFromWindow(win, MONITOR_DEFAULTTOPRIMARY); - mi.cbSize = sizeof(mi); - ret = GetMonitorInfoW(mon, &mi); - *w = mi.rcWork.right - mi.rcWork.left; - *h = mi.rcWork.bottom - mi.rcWork.top; + if (!primary && win == NULL) + primary = true; + mon = MonitorFromWindow(win, primary ? MONITOR_DEFAULTTOPRIMARY : MONITOR_DEFAULTTONEAREST); + if (mon) { + mi.cbSize = sizeof(mi); + ret = GetMonitorInfoW(mon, &mi); + if (ret) { + if (fullscreen) { + if (w) + *w = mi.rcMonitor.right - mi.rcMonitor.left; + if (h) + *h = mi.rcMonitor.bottom - mi.rcMonitor.top; + if (xpos) + *xpos = mi.rcMonitor.left; + if (ypos) + *ypos = mi.rcMonitor.top; + } + else { + if (w) + *w = mi.rcWork.right - mi.rcWork.left; + if (h) + *h = mi.rcWork.bottom - mi.rcWork.top; + if (xpos) + *xpos = mi.rcWork.left; + if (ypos) + *ypos = mi.rcWork.top; + } + } + } return ret; } @@ -505,7 +535,7 @@ handle_wm_getminmaxinfo(MINMAXINFO *inf) double mult; RECT r; - gdi_get_monitor_size(&monw, &monh); + get_monitor_size_pos(&monw, &monh, NULL, NULL); maxw = monw; maxh = monh; UnadjustWindowSize(&maxw, &maxh); @@ -519,7 +549,7 @@ handle_wm_getminmaxinfo(MINMAXINFO *inf) r.left = 0; r.right = maxw; r.bottom = maxh; - AdjustWindowRect(&r, style, FALSE); + AdjustWindowRect(&r, STYLE, FALSE); inf->ptMaxTrackSize.x = r.right - r.left; inf->ptMaxTrackSize.y = r.bottom - r.top; inf->ptMaxSize.x = inf->ptMaxTrackSize.x; @@ -531,7 +561,7 @@ handle_wm_getminmaxinfo(MINMAXINFO *inf) r.left = 0; r.right = minw; r.bottom = minh; - AdjustWindowRect(&r, style, FALSE); + AdjustWindowRect(&r, STYLE, FALSE); inf->ptMinTrackSize.x = r.right - r.left; inf->ptMinTrackSize.y = r.bottom - r.top; @@ -609,8 +639,7 @@ gdi_WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { r.right = wParam; r.bottom = lParam; pthread_mutex_unlock(&vstatlock); - if (!fullscreen) - AdjustWindowRect(&r, style, FALSE); + AdjustWindowRect(&r, STYLE, FALSE); SetWindowPos(win, NULL, 0, 0, r.right - r.left, r.bottom - r.top, SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); return true; case WM_USER_SETPOS: @@ -628,7 +657,7 @@ gdi_snap(bool grow) if (maximized || fullscreen) return; - gdi_get_monitor_size(&mw, &mh); + get_monitor_size_pos(&mw, &mh, NULL, NULL); UnadjustWindowSize(&mw, &mh); pthread_mutex_lock(&vstatlock); bitmap_snap(grow, mw, mh); @@ -642,7 +671,7 @@ gdi_snap(bool grow) #define WMOD_SHIFT 8 #define WMOD_LSHIFT 16 #define WMOD_RSHIFT 32 -bool +static bool magic_message(MSG msg) { static uint8_t mods = 0; @@ -716,7 +745,7 @@ magic_message(MSG msg) pthread_mutex_lock(&vstatlock); window_scaling = vstat.scaling; pthread_mutex_unlock(&vstatlock); - SetWindowLongPtr(win, GWL_STYLE, fs_style); + SetWindowLongPtr(win, GWL_STYLE, STYLE); PostMessageW(win, WM_USER_SETPOS, mi.rcMonitor.left, mi.rcMonitor.top); PostMessageW(win, WM_USER_SETSIZE, mi.rcMonitor.right - mi.rcMonitor.left, mi.rcMonitor.bottom - mi.rcMonitor.top); } @@ -730,7 +759,7 @@ magic_message(MSG msg) int w, h; bitmap_get_scaled_win_size(window_scaling, &w, &h, 0, 0); - SetWindowLongPtr(win, GWL_STYLE, style); + SetWindowLongPtr(win, GWL_STYLE, STYLE); PostMessageW(win, WM_USER_SETSIZE, w, h); PostMessageW(win, WM_USER_SETPOS, window_left, window_top); } @@ -773,9 +802,14 @@ gdi_thread(void *arg) MSG msg; RECT r; ATOM cl; + int wx = CW_USEDEFAULT; + int wy = CW_USEDEFAULT; + int mode = (int)arg; SetThreadName("GDI Events"); + if (mode == CIOLIB_MODE_GDI_FULLSCREEN) + fullscreen = true; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = gdi_WndProc; // This is actually required or the link will fail (it can be overwritten though) @@ -797,6 +831,13 @@ gdi_thread(void *arg) pthread_mutex_lock(&vstatlock); if (ciolib_initial_scaling != 0) { bitmap_get_scaled_win_size(ciolib_initial_scaling, &vstat.winwidth, &vstat.winheight, 0, 0); + vstat.scaling = ciolib_initial_scaling; + } + if (fullscreen) { + if (get_monitor_size_pos(&vstat.winwidth, &vstat.winheight, &wx, &wy)) + vstat.scaling = bitmap_double_mult_inside(vstat.winwidth, vstat.winheight); + else + fullscreen = false; } stype = ciolib_initial_scaling_type; // Now make the inside of the window the size we want (sigh) @@ -804,12 +845,16 @@ gdi_thread(void *arg) r.right = vstat.winwidth; r.bottom = vstat.winheight; pthread_mutex_unlock(&vstatlock); - AdjustWindowRect(&r, style, FALSE); - win = CreateWindowW(wc.lpszClassName, L"SyncConsole", style, CW_USEDEFAULT, SW_SHOWNORMAL, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); + AdjustWindowRect(&r, STYLE, FALSE); + win = CreateWindowW(wc.lpszClassName, L"SyncConsole", STYLE, wx, wy, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); if (win == NULL) goto fail; // No failing after this... init_success = true; + if (fullscreen) + cio_api.mode = CIOLIB_MODE_GDI_FULLSCREEN; + else + cio_api.mode = CIOLIB_MODE_GDI; ReleaseSemaphore(init_sem, 1, NULL); while (GetMessage(&msg, NULL, 0, 0)) { @@ -875,9 +920,13 @@ gdi_textmode(int mode) } pthread_mutex_lock(&vstatlock); - gdi_get_monitor_size(&mw, &mh); + get_monitor_size_pos(&mw, &mh, NULL, NULL); UnadjustWindowSize(&mw, &mh); bitmap_drv_init_mode(mode, NULL, NULL, mw, mh); + if (fullscreen) { + vstat.winwidth = mw; + vstat.winheight = mh; + } gdi_setwinsize(vstat.winwidth, vstat.winheight); pthread_mutex_unlock(&vstatlock); bitmap_drv_request_pixels(); @@ -1067,11 +1116,11 @@ gdi_init(int mode) else if (SetProcessDPIAware) { SetProcessDPIAware(); } - _beginthread(gdi_mouse_thread, 0, NULL); - _beginthread(gdi_thread, 0, NULL); + _beginthread(gdi_thread, 0, (void *)(intptr_t)mode); WaitForSingleObject(init_sem, INFINITE); CloseHandle(init_sem); if (init_success) { + _beginthread(gdi_mouse_thread, 0, NULL); gdi_textmode(ciolib_initial_mode); cio_api.mode=CIOLIB_MODE_GDI; @@ -1158,7 +1207,10 @@ gdi_setwinposition(int x, int y) void gdi_setwinsize(int w, int h) { - PostMessageW(win, WM_USER_SETSIZE, w, h); + if (fullscreen) + window_scaling = bitmap_double_mult_inside(w, h); + else + PostMessageW(win, WM_USER_SETSIZE, w, h); } double @@ -1177,10 +1229,15 @@ gdi_setscaling(double newval) { int w, h; - pthread_mutex_lock(&vstatlock); - bitmap_get_scaled_win_size(newval, &w, &h, 0, 0); - pthread_mutex_unlock(&vstatlock); - gdi_setwinsize(w, h); + if (fullscreen) { + window_scaling = newval; + } + else { + pthread_mutex_lock(&vstatlock); + bitmap_get_scaled_win_size(newval, &w, &h, 0, 0); + pthread_mutex_unlock(&vstatlock); + gdi_setwinsize(w, h); + } } enum ciolib_scaling diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c index 830c8db17c..8f3877644e 100644 --- a/src/syncterm/bbslist.c +++ b/src/syncterm/bbslist.c @@ -1911,7 +1911,7 @@ change_settings(int connected) #ifdef __unix__ "~ Curses ~\n" " Use text output using the Curses library. This mode should work\n" - " from any terminal, however, high and low ASCII will not work\n" + " from any terminal, however, high and low ASCII may not work\n" " correctly.\n\n" "~ Curses on cp437 Device ~\n" " As above, but assumes that the current terminal is configured to\n" @@ -1925,8 +1925,7 @@ change_settings(int connected) #if defined(__unix__) && !defined(NO_X) "~ X11 ~\n" " Uses the Xlib library directly for graphical output. This is\n" - " the graphical mode most likely to work when using X11. This\n" - " mode supports font changes.\n\n" + " the graphical mode most likely to work when using X11.\n\n" "~ X11 Fullscreen ~\n" " As above, but starts in full-screen mode rather than a window\n\n" #endif @@ -1936,15 +1935,19 @@ change_settings(int connected) " affect the look of the output and some low ASCII characters are\n" " not displayable. When in a window, blinking text is displayed\n" " with a high-intensity background rather than blinking. In\n" - " full-screen mode, blinking works correctly.\n\n" + " full-screen mode (where available), blinking works correctly.\n\n" #endif #if defined(WITH_SDL) || defined(WITH_SDL_AUDIO) "~ SDL ~\n" " Makes use of the SDL graphics library for graphical output.\n" - " This output mode allows switching to full-screen mode but is\n" - " otherwise identical to X11 mode.\n\n" "~ SDL Fullscreen ~\n" " As above, but starts in full-screen mode rather than a window\n\n" +#endif +#if defined(WITH_GDI) + "~ GDI ~\n" + " Native Windows graphics library for graphical output.\n" + "~ GDI Fullscreen ~\n" + " As above, but starts in full-screen mode rather than a window\n\n" #endif ; switch (i = uifc.list(WIN_SAV, 0, 0, 0, &j, NULL, "Video Output Mode", output_types)) { diff --git a/src/syncterm/syncterm.c b/src/syncterm/syncterm.c index fc4cf96992..f8b548fe01 100644 --- a/src/syncterm/syncterm.c +++ b/src/syncterm/syncterm.c @@ -101,17 +101,18 @@ char *usage = "-e# = set escape delay to #msec\n" "-h = use SSH mode if URL does not include the scheme\n" "-iX = set interface mode to X (default=auto) where X is one of:\n" - " S[W|F] = SDL surface mode W for windowed and F for fullscreen\n" + " A = ANSI mode\n" #ifdef __unix__ - " X[W|F] = X11 mode W for windowed and F for fullscreen\n" " C = Curses mode\n" - " I = Curses mode with forced ASCII charset\n" " F = Curses mode with forced IBM charset\n" + " I = Curses mode with forced ASCII charset\n" + " S[W|F] = SDL surface mode W for windowed and F for fullscreen\n" + " X[W|F] = X11 mode W for windowed and F for fullscreen\n" #else + " G[W|F] = Win32 GDI (graphics) mode W for windowed and F for fullscreen\n" + " S[W|F] = SDL surface mode W for windowed and F for fullscreen\n" " W = Win32 console (text) mode\n" - " G = Win32 GDI (graphics) mode\n" #endif - " A = ANSI mode\n" "-l# = set screen lines to # (default=auto-detect)\n" "-n/path/to/ini = specify a config ini path\n" "-q = Quiet mode (Hide various popups such as this during a connect)\n" @@ -771,15 +772,16 @@ char *output_types[] = { #endif #if defined(WITH_GDI) , "GDI" + , "GDI Fullscreen" #endif , NULL }; int output_map[] = { CIOLIB_MODE_AUTO #ifdef __unix__ - , CIOLIB_MODE_CURSES, - CIOLIB_MODE_CURSES_IBM, - CIOLIB_MODE_CURSES_ASCII + , CIOLIB_MODE_CURSES + , CIOLIB_MODE_CURSES_IBM + , CIOLIB_MODE_CURSES_ASCII #endif , CIOLIB_MODE_ANSI #if defined(__unix__) && !defined(NO_X) @@ -787,16 +789,16 @@ int output_map[] = { , CIOLIB_MODE_X_FULLSCREEN #endif #ifdef _WIN32 - , CIOLIB_MODE_CONIO, - CIOLIB_MODE_CONIO_FULLSCREEN + , CIOLIB_MODE_CONIO + , CIOLIB_MODE_CONIO_FULLSCREEN #endif #if defined(WITH_SDL) || defined(WITH_SDL_AUDIO) - , CIOLIB_MODE_SDL, - CIOLIB_MODE_SDL_FULLSCREEN + , CIOLIB_MODE_SDL + , CIOLIB_MODE_SDL_FULLSCREEN #endif #ifdef WITH_GDI - , CIOLIB_MODE_GDI, - CIOLIB_MODE_GDI + , CIOLIB_MODE_GDI + , CIOLIB_MODE_GDI_FULLSCREEN #endif , 0 }; @@ -813,6 +815,7 @@ char *output_descrs[] = { "SDL", "SDL Fullscreen", "GDI", + "GDI Fullscreen", NULL }; @@ -829,6 +832,7 @@ char *output_enum[] = { "SDL", "SDLFullscreen", "GDI", + "GDIFullscreen", NULL }; @@ -1626,7 +1630,15 @@ main(int argc, char **argv) ciolib_mode = CIOLIB_MODE_CURSES_IBM; break; case 'G': - ciolib_mode = CIOLIB_MODE_GDI; + switch (toupper(argv[i][3])) { + case 0: + case 'W': + ciolib_mode = CIOLIB_MODE_GDI; + break; + case 'F': + ciolib_mode = CIOLIB_MODE_GDI_FULLSCREEN; + break; + } break; case 'I': ciolib_mode = CIOLIB_MODE_CURSES_ASCII; -- GitLab