From 68f9b3d9a6eccbfb006343ec7edc045e7d673973 Mon Sep 17 00:00:00 2001 From: simon Date: Sun, 25 Nov 2001 15:21:25 +0000 Subject: [PATCH] Add support for most of the ESC[t sequences, which xterm uses to manipulate the window (minimise, maximise, front, back, move, resize) and report things about the window (is it minimised or maximised, how big is it, what's its title). Missing are ESC[4;X;Yt (resize to a specified pixel size; our resize code doesn't like it) and ESC[19;X;Yt (report size of _screen_ in _characters_, which it isn't even obvious how to do when you've got a variable font size). git-svn-id: svn://svn.tartarus.org/sgt/putty@1414 cda61777-01e9-0310-a592-d414129be87e --- putty.h | 10 ++++++ terminal.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- window.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 209 insertions(+), 2 deletions(-) diff --git a/putty.h b/putty.h index de92ab69..53a6c54a 100644 --- a/putty.h +++ b/putty.h @@ -406,6 +406,16 @@ void begin_session(void); void sys_cursor(int x, int y); #define OPTIMISE_IS_SCROLL 1 +void set_iconic(int iconic); +void move_window(int x, int y); +void set_zorder(int top); +void refresh_window(void); +void set_zoomed(int zoomed); +int is_iconic(void); +void get_window_pos(int *x, int *y); +void get_window_pixels(int *x, int *y); +char *get_window_title(int icon); + /* * Exports from noise.c. */ diff --git a/terminal.c b/terminal.c index 7f6f8bba..77bb3905 100644 --- a/terminal.c +++ b/terminal.c @@ -1955,11 +1955,107 @@ void term_out(void) * illegal values (eg first arg 1..9) for window changing * and reports. */ - compatibility(VT340TEXT); if (esc_nargs <= 1 && (esc_args[0] < 1 || esc_args[0] >= 24)) { + compatibility(VT340TEXT); request_resize(cols, def(esc_args[0], 24)); deselect(); + } else if (esc_nargs >= 1 && + esc_args[0] >= 1 && + esc_args[0] < 24) { + compatibility(OTHER); + + switch (esc_args[0]) { + int x, y, len; + char buf[80], *p; + case 1: + set_iconic(FALSE); + break; + case 2: + set_iconic(TRUE); + break; + case 3: + if (esc_nargs >= 3) { + move_window(def(esc_args[1], 0), + def(esc_args[2], 0)); + } + break; + case 4: + /* We should resize the window to a given + * size in pixels here, but currently our + * resizing code isn't healthy enough to + * manage it. */ + break; + case 5: + set_zorder(TRUE); /* move to top */ + break; + case 6: + set_zorder(FALSE); /* move to bottom */ + break; + case 7: + refresh_window(); + break; + case 8: + if (esc_nargs >= 3) { + request_resize(def(esc_args[1], cfg.width), + def(esc_args[2], cfg.height)); + } + break; + case 9: + if (esc_nargs >= 2) + set_zoomed(esc_args[1] ? TRUE : FALSE); + break; + case 11: + ldisc_send(is_iconic() ? "\033[1t" : "\033[2t", + 4, 0); + break; + case 13: + get_window_pos(&x, &y); + len = sprintf(buf, "\033[3;%d;%dt", x, y); + ldisc_send(buf, len, 0); + break; + case 14: + get_window_pixels(&x, &y); + len = sprintf(buf, "\033[4;%d;%dt", x, y); + ldisc_send(buf, len, 0); + break; + case 18: + len = sprintf(buf, "\033[8;%d;%dt", + cols, rows); + ldisc_send(buf, len, 0); + break; + case 19: + /* + * Hmmm. Strictly speaking we + * should return `the size of the + * screen in characters', but + * that's not easy: (a) window + * furniture being what it is it's + * hard to compute, and (b) in + * resize-font mode maximising the + * window wouldn't change the + * number of characters. *shrug*. I + * think we'll ignore it for the + * moment and see if anyone + * complains, and then ask them + * what they would like it to do. + */ + break; + case 20: + p = get_window_title(TRUE); + len = strlen(p); + ldisc_send("\033]L", 3, 0); + ldisc_send(p, len, 0); + ldisc_send("\033\\", 2, 0); + break; + case 21: + p = get_window_title(FALSE); + len = strlen(p); + ldisc_send("\033]l", 3, 0); + ldisc_send(p, len, 0); + ldisc_send("\033\\", 2, 0); + break; + } } break; case 'S': diff --git a/window.c b/window.c index a42d5887..944fdba2 100644 --- a/window.c +++ b/window.c @@ -1407,12 +1407,13 @@ static int is_alt_pressed(void) return FALSE; } +static int resizing; + static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; static int ignore_clip = FALSE; - static int resizing = FALSE; static int need_backend_resize = FALSE; switch (message) { @@ -4074,3 +4075,103 @@ static void flip_full_screen(void) CheckMenuItem(GetSystemMenu(hwnd, FALSE), IDM_FULLSCREEN, MF_BYCOMMAND| full_screen ? MF_CHECKED : MF_UNCHECKED); } + +/* + * Minimise or restore the window in response to a server-side + * request. + */ +void set_iconic(int iconic) +{ + if (IsIconic(hwnd)) { + if (!iconic) + ShowWindow(hwnd, SW_RESTORE); + } else { + if (iconic) + ShowWindow(hwnd, SW_MINIMIZE); + } +} + +/* + * Move the window in response to a server-side request. + */ +void move_window(int x, int y) +{ + SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); +} + +/* + * Move the window to the top or bottom of the z-order in response + * to a server-side request. + */ +void set_zorder(int top) +{ + if (cfg.alwaysontop || full_screen) + return; /* ignore */ + SetWindowPos(hwnd, top ? HWND_TOP : HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE); +} + +/* + * Refresh the window in response to a server-side request. + */ +void refresh_window(void) +{ + InvalidateRect(hwnd, NULL, TRUE); +} + +/* + * Maximise or restore the window in response to a server-side + * request. + */ +void set_zoomed(int zoomed) +{ + if (IsZoomed(hwnd) || full_screen) { + if (!zoomed) { + if (full_screen) + flip_full_screen(); + else + ShowWindow(hwnd, SW_RESTORE); + } + } else { + if (zoomed) + ShowWindow(hwnd, SW_MAXIMIZE); + } +} + +/* + * Report whether the window is iconic, for terminal reports. + */ +int is_iconic(void) +{ + return IsIconic(hwnd); +} + +/* + * Report the window's position, for terminal reports. + */ +void get_window_pos(int *x, int *y) +{ + RECT r; + GetWindowRect(hwnd, &r); + *x = r.left; + *y = r.top; +} + +/* + * Report the window's pixel size, for terminal reports. + */ +void get_window_pixels(int *x, int *y) +{ + RECT r; + GetWindowRect(hwnd, &r); + *x = r.right - r.left; + *y = r.bottom - r.top; +} + +/* + * Return the window or icon title. + */ +char *get_window_title(int icon) +{ + return icon ? icon_name : window_name; +} -- 2.11.0