From 1de1d68cad6cdaeaaccd834a799fdee074dd220e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Sun, 26 Jan 2025 21:23:08 -0500
Subject: [PATCH] Add Alt+Home to centre window on screen

Works in SDL mode and X11 mode with an appropriate Window Manager
(I was going to use center window gravity, but since my WM doesn't
support that, I just assume that all the good ones dont).

Not tested in Win32-GDI mode, but should likely work I suppose.
---
 src/conio/ciolib.adoc   | 54 +++++++++++++++++++++++++++++++++++++----
 src/conio/sdl_con.c     |  5 ++++
 src/conio/win32gdi.c    |  9 +++++++
 src/conio/x_events.c    | 10 ++++++++
 src/syncterm/CHANGES    |  1 +
 src/syncterm/Manual.txt |  6 +++++
 6 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/src/conio/ciolib.adoc b/src/conio/ciolib.adoc
index cb4de0ce98..650287cf7c 100644
--- a/src/conio/ciolib.adoc
+++ b/src/conio/ciolib.adoc
@@ -190,18 +190,20 @@ program to create exactly the desired mode.
 == Fonts
 
 There are a large number of built in fonts that ciolib supports. Most
-are codepage fonts, but there is also Commodore, Atari, and Amiga fonts
-included in the default set.  Not all builtin fonts are available in
-every size.  The following table summarizes the available fonts.
+are codepage fonts, but there is also Commodore, Atari, Amiga, and "Prestel"
+(SAA5050 as used in BBC Micro Model 7 and others) fonts included in the
+default set.  Not all builtin fonts are available in every size.  The
+following table summarizes the available fonts.
 
-[%autowidth,cols="1,^2,^3,^4,5"]
+[%autowidth,cols="1,^2,^3,^4,^5,6"]
 |===
-|Name |8x16 |8x12 |8x8 |Character Set
+|Name |8x16 |8x12 |8x8 |12x20| Character Set
 
 |Codepage 437 English
 |√
 |√
 |√
+|√
 |CP437
 
 |Codepage 1251 Cyrillic, (swiss)
@@ -214,251 +216,293 @@ every size.  The following table summarizes the available fonts.
 |√
 |√
 |√
+|
 |KOI8_R
 
 |ISO-8859-2 Central European
 |√
 |√
 |√
+|
 |ISO_8859_2
 
 |ISO-8859-4 Baltic wide (VGA 9bit mapped)
 |√
 |
 |
+|
 |ISO_8859_4
 
 |Codepage 866 (c) Russian
 |√
 |
 |
+|
 |CP866M
 
 |ISO-8859-9 Turkish
 |√
 |
 |
+|
 |ISO_8859_9
 
 |haik8 codepage (use only with armscii8 screenmap)
 |√
 |√
 |√
+|
 |HAIK8
 
 |ISO-8859-8 Hebrew
 |√
 |√
 |√
+|
 |ISO_8859_8
 
 |Ukrainian font koi8-u
 |√
 |√
 |√
+|
 |KOI8_U
 
 |ISO-8859-15 West European, (thin)
 |√
 |
 |
+|
 |ISO_8859_15
 
 |ISO-8859-4 Baltic (VGA 9bit mapped)
 |√
 |√
 |√
+|
 |ISO_8859_4
 
 |Russian koi8-r (b)
 |√
 |
 |
+|
 |KOI8_R
 
 |ISO-8859-4 Baltic wide
 |√
 |
 |
+|
 |ISO_8859_4
 
 |ISO-8859-5 Cyrillic
 |√
 |√
 |√
+|
 |ISO_8859_5
 
 |ARMSCII-8 Character set
 |√
 |√
 |√
+|
 |ARMSCII8
 
 |ISO-8859-15 West European
 |√
 |√
 |√
+|
 |ISO_8859_15
 
 |Codepage 850 Multilingual Latin I, (thin)
 |√
 |
 |√
+|
 |CP850
 
 |Codepage 850 Multilingual Latin I
 |√
 |√
 |√
+|
 |CP850
 
 |Codepage 865 Norwegian, (thin)
 |√
 |
 |√
+|
 |CP865
 
 |Codepage 1251 Cyrillic
 |√
 |√
 |√
+|
 |CP1251
 
 |ISO-8859-7 Greek
 |√
 |√
 |√
+|
 |ISO_8859_7
 
 |Russian koi8-r (c)
 |√
 |
 |
+|
 |KOI8_R
 
 |ISO-8859-4 Baltic
 |√
 |√
 |√
+|
 |ISO_8859_4
 
 |ISO-8859-1 West European
 |√
 |√
 |√
+|
 |ISO_8859_1
 
 |Codepage 866 Russian
 |√
 |√
 |√
+|
 |CP866M2
 
 |Codepage 437 English, (thin)
 |√
 |
 |√
+|
 |CP437
 
 |Codepage 866 (b) Russian
 |√
 |
 |
+|
 |CP866M2
 
 |Codepage 865 Norwegian
 |√
 |√
 |√
+|
 |CP865
 
 |Ukrainian font cp866u
 |√
 |√
 |√
+|
 |CP866U
 
 |ISO-8859-1 West European, (thin)
 |√
 |
 |
+|
 |ISO_8859_1
 
 |Codepage 1131 Belarusian, (swiss)
 |√
 |
 |
+|
 |CP1131
 
 |Commodore 64 (UPPER)
 |√
 |
 |√
+|
 |PETSCIIU
 
 |Commodore 64 (Lower)
 |√
 |
 |√
+|
 |PETSCIIL
 
 |Commodore 128 (UPPER)
 |√
 |
 |√
+|
 |PETSCIIU
 
 |Commodore 128 (Lower)
 |√
 |
 |√
+|
 |PETSCIIL
 
 |Atari
 |√
 |
 |√
+|
 |ATASCII
 
 |P0T NOoDLE (Amiga)
 |√
 |√
 |
+|
 |ISO_8859_1
 
 |mO'sOul (Amiga)
 |√
 |
 |√
+|
 |ISO_8859_1
 
 |MicroKnight Plus (Amiga)
 |√
 |
 |
+|
 |ISO_8859_1
 
 |Topaz Plus (Amiga)
 |√
 |
 |
+|
 |ISO_8859_1
 
 |MicroKnight (Amiga)
 |√
 |
 |√
+|
 |ISO_8859_1
 
 |Topaz (Amiga)
 |√
 |√
 |
+|
 |ISO_8859_1
 
 |Prestel
 |√
 |
 |
+|√
 |ISO_8859_1
 |===
diff --git a/src/conio/sdl_con.c b/src/conio/sdl_con.c
index ad5df4525d..9cb4a3b9cc 100644
--- a/src/conio/sdl_con.c
+++ b/src/conio/sdl_con.c
@@ -751,6 +751,11 @@ static void sdl_add_key(unsigned int keyval, struct video_stats *vs)
 
 	if (keyval == 0xe0)
 		keyval = CIO_KEY_LITERAL_E0;
+	if (keyval == 0x9700) { // Alt-Home, centre screen
+		assert_pthread_mutex_lock(&win_mutex);
+		sdl.SetWindowPosition(win, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
+		assert_pthread_mutex_unlock(&win_mutex);
+	}
 	if(keyval==0xa600 && vs != NULL) {
 		assert_pthread_mutex_lock(&win_mutex);
 		fullscreen = !(sdl.GetWindowFlags(win) & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_FULLSCREEN_DESKTOP));
diff --git a/src/conio/win32gdi.c b/src/conio/win32gdi.c
index e22ff29098..8affa76ad0 100644
--- a/src/conio/win32gdi.c
+++ b/src/conio/win32gdi.c
@@ -925,6 +925,15 @@ magic_message(MSG msg)
 								PostMessageW(win, WM_USER_SETPOS, window_left, window_top);
 							}
 						}
+						else if (k->VirtualKeyCode == VK_HOME) {
+							// Centre window
+							// Now make the inside of the window the size we want (sigh)
+							LONG w, h;
+							int mw, mh, xpos, ypos;
+							gdi_get_windowsize_at_dpi(false, &w, &h, 0);
+							if (get_monitor_size_pos(&mw, &mh, &xpos, &ypos))
+								SetWindowPos(win, NULL, xpos + ((mw - w) / 2), ypos + ((mh - h) / 2), 0, 0, SWP_NOOWNERZORDER|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE);
+						}
 						if (k->ALT == 0x6b00) { // ALT-F4
 							gdi_add_key(CIO_KEY_QUIT);
 						}
diff --git a/src/conio/x_events.c b/src/conio/x_events.c
index 8f77e86c90..da385f3a24 100644
--- a/src/conio/x_events.c
+++ b/src/conio/x_events.c
@@ -2144,6 +2144,16 @@ x11_event(XEvent *ev)
 								nlock = 1;
 							case XK_Home:
 							case XK_KP_Home:
+								// ALT-Home, centre window
+								if (ev->xkey.state & Mod1Mask) {
+									int x_org, y_org, w, h;
+									if (fullscreen_geometry(&x_org, &y_org, &w, &h)) {
+										int l, r, t, b;
+										if (get_frame_extents(&l, &r, &t, &b)) {
+											x11.XMoveWindow(dpy, win, x_org + ((w - vstat.winwidth + l + r) / 2), y_org + ((h - vstat.winheight + t + b) / 2));
+										}
+									}
+								}
 								scan = 71;
 								goto docode;
 
diff --git a/src/syncterm/CHANGES b/src/syncterm/CHANGES
index f8f9f3ca92..d7a91b3bb0 100644
--- a/src/syncterm/CHANGES
+++ b/src/syncterm/CHANGES
@@ -5,6 +5,7 @@ Use the SAA5050 font for Prestel mode
 Prestel mode is 25 rows, not 24
 Add setting to invert mouse wheel
 Support web-based dialing directories
+Alt+Home now centres the window on the screen
 
 Version 1.5a
 ------------
diff --git a/src/syncterm/Manual.txt b/src/syncterm/Manual.txt
index 4a5e34d30b..c992b40a62 100644
--- a/src/syncterm/Manual.txt
+++ b/src/syncterm/Manual.txt
@@ -236,6 +236,12 @@ Keyboard Controls::
 	Snap the window size to the next larger smaller integer zoom
 	level
 
+	kbd:[Alt+Return]:::
+	Toggle fullscreen mode
+
+	kbd:[Alt+Home]:::
+	Centre window on the screen
+
 In addition, you can directly enter characters either by their "codepage"
 value or their unicode value.  A "codepage" value is an 8-bit value that
 indicates a character in the current codepage (such as the default CP437).
-- 
GitLab