X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/49bad83179144047e7d9e070d63d869dba691736..3ad8c6db2a0d488f0d8fa23d8e71306572df8ff2:/window.c diff --git a/window.c b/window.c index 3cab8197..f810eba9 100644 --- a/window.c +++ b/window.c @@ -40,6 +40,7 @@ #define IDM_TEL_EOF 0x0130 #define IDM_ABOUT 0x0140 #define IDM_SAVEDSESS 0x0150 +#define IDM_COPYALL 0x0160 #define IDM_SAVED_MIN 0x1000 #define IDM_SAVED_MAX 0x2000 @@ -102,6 +103,8 @@ static char *window_name, *icon_name; static Ldisc *real_ldisc; +static int compose_state = 0; + void begin_session(void) { ldisc = real_ldisc; } @@ -311,6 +314,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { } } + /* Check for invalid Port number (i.e. zero) */ + if (cfg.port == 0) { + MessageBox(NULL, "Invalid Port Number", + "PuTTY Internal Error", MB_OK |MB_ICONEXCLAMATION); + WSACleanup(); + return 1; + } + real_ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple); /* To start with, we use the simple line discipline, so we can * type passwords etc without fear of them being echoed... */ @@ -365,14 +376,15 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { { int winmode = WS_OVERLAPPEDWINDOW|WS_VSCROLL; - if (!cfg.scrollbar) winmode &= ~(WS_VSCROLL); - if (cfg.locksize) winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX); - hwnd = CreateWindow (appname, appname, - winmode, - CW_USEDEFAULT, CW_USEDEFAULT, - guess_width, guess_height, - NULL, NULL, inst, NULL); - } + int exwinmode = 0; + if (!cfg.scrollbar) winmode &= ~(WS_VSCROLL); + if (cfg.locksize) winmode &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX); + if (cfg.alwaysontop) exwinmode = WS_EX_TOPMOST; + hwnd = CreateWindowEx (exwinmode, appname, appname, + winmode, CW_USEDEFAULT, CW_USEDEFAULT, + guess_width, guess_height, + NULL, NULL, inst, NULL); + } /* * Initialise the fonts, simultaneously correcting the guesses @@ -409,10 +421,12 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { { char *bits; int size = (font_width+15)/16 * 2 * font_height; - bits = calloc(size, 1); + bits = smalloc(size); + memset(bits, 0, size); caretbm = CreateBitmap(font_width, font_height, 1, 1, bits); - free(bits); + sfree(bits); } + CreateCaret(hwnd, caretbm, font_width, font_height); /* * Initialise the scroll bar. @@ -501,15 +515,16 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { } AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "&Event Log"); AppendMenu (m, MF_SEPARATOR, 0, 0); - AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "Ne&w Session"); + AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "Ne&w Session..."); AppendMenu (m, MF_ENABLED, IDM_DUPSESS, "&Duplicate Session"); s = CreateMenu(); get_sesslist(TRUE); for (i = 1 ; i < ((nsessions < 256) ? nsessions : 256) ; i++) AppendMenu (s, MF_ENABLED, IDM_SAVED_MIN + (16 * i) , sessions[i]); AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) s, "Sa&ved Sessions"); - AppendMenu (m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings"); + AppendMenu (m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings..."); AppendMenu (m, MF_SEPARATOR, 0, 0); + AppendMenu (m, MF_ENABLED, IDM_COPYALL, "C&opy All to Clipboard"); AppendMenu (m, MF_ENABLED, IDM_CLRSB, "C&lear Scrollback"); AppendMenu (m, MF_ENABLED, IDM_RESET, "Rese&t Terminal"); AppendMenu (m, MF_SEPARATOR, 0, 0); @@ -589,7 +604,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { if (!has_focus) timer_id = SetTimer(hwnd, 1, 59500, NULL); else - timer_id = SetTimer(hwnd, 1, 250, NULL); + timer_id = SetTimer(hwnd, 1, 100, NULL); long_timer = 1; /* There's no point rescanning everything in the message queue @@ -1045,6 +1060,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, static int ignore_clip = FALSE; static int just_reconfigged = FALSE; static int resizing = FALSE; + static int need_backend_resize = FALSE; switch (message) { case WM_TIMER: @@ -1125,7 +1141,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, cl = c; } else if (wParam == IDM_SAVEDSESS) { char *session = sessions[(lParam - IDM_SAVED_MIN) / 16]; - cl = malloc(16 + strlen(session)); /* 8, but play safe */ + cl = smalloc(16 + strlen(session)); /* 8, but play safe */ if (!cl) cl = NULL; /* not a very important failure mode */ else { @@ -1149,82 +1165,125 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, if (filemap) CloseHandle(filemap); if (freecl) - free(cl); + sfree(cl); } break; - case IDM_RECONF: - if (!do_reconfig(hwnd)) - break; - just_reconfigged = TRUE; - { - int i; - for (i=0; i<8; i++) - if (fonts[i]) - DeleteObject(fonts[i]); - } - bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT; - und_mode = UND_FONT; - init_fonts(0); - sfree(logpal); - /* Telnet will change local echo -> remote if the remote asks */ - if (cfg.protocol != PROT_TELNET) - ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple); - if (pal) - DeleteObject(pal); - logpal = NULL; - pal = NULL; - cfgtopalette(); - init_palette(); - - /* Enable or disable the scroll bar, etc */ - { - LONG nflg, flag = GetWindowLong(hwnd, GWL_STYLE); - - nflg = flag; - if (cfg.scrollbar) nflg |= WS_VSCROLL; - else nflg &= ~WS_VSCROLL; - if (cfg.locksize) - nflg &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX); - else - nflg |= (WS_THICKFRAME|WS_MAXIMIZEBOX); + case IDM_RECONF: + { + int prev_alwaysontop = cfg.alwaysontop; + int need_setwpos = FALSE; + int old_fwidth, old_fheight; + cfg.width = cols; + cfg.height = rows; + old_fwidth = font_width; + old_fheight = font_height; + if (!do_reconfig(hwnd)) + break; + just_reconfigged = TRUE; + { + int i; + for (i=0; i<8; i++) + if (fonts[i]) + DeleteObject(fonts[i]); + } + bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT; + und_mode = UND_FONT; + init_fonts(0); + sfree(logpal); + /* + * Telnet will change local echo -> remote if the + * remote asks. + */ + if (cfg.protocol != PROT_TELNET) + ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple); + if (pal) + DeleteObject(pal); + logpal = NULL; + pal = NULL; + cfgtopalette(); + init_palette(); + + /* Enable or disable the scroll bar, etc */ + { + LONG nflg, flag = GetWindowLong(hwnd, GWL_STYLE); + LONG nexflag, exflag = GetWindowLong(hwnd, GWL_EXSTYLE); + + nexflag = exflag; + if (cfg.alwaysontop != prev_alwaysontop) { + if (cfg.alwaysontop) { + nexflag = WS_EX_TOPMOST; + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE); + } else { + nexflag = 0; + SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE); + } + } + + nflg = flag; + if (cfg.scrollbar) nflg |= WS_VSCROLL; + else nflg &= ~WS_VSCROLL; + if (cfg.locksize) + nflg &= ~(WS_THICKFRAME|WS_MAXIMIZEBOX); + else + nflg |= (WS_THICKFRAME|WS_MAXIMIZEBOX); + + if (nflg != flag || nexflag != exflag) + { + RECT cr, wr; + + if (nflg != flag) + SetWindowLong(hwnd, GWL_STYLE, nflg); + if (nexflag != exflag) + SetWindowLong(hwnd, GWL_EXSTYLE, nexflag); + + SendMessage (hwnd, WM_IGNORE_SIZE, 0, 0); + + SetWindowPos(hwnd, NULL, 0,0,0,0, + SWP_NOACTIVATE|SWP_NOCOPYBITS| + SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER| + SWP_FRAMECHANGED); + + GetWindowRect (hwnd, &wr); + GetClientRect (hwnd, &cr); + extra_width = wr.right - wr.left - cr.right + cr.left; + extra_height = wr.bottom - wr.top - cr.bottom + cr.top; + } + } - if (nflg != flag) - { - RECT cr, wr; - - SetWindowLong(hwnd, GWL_STYLE, nflg); - SendMessage (hwnd, WM_IGNORE_SIZE, 0, 0); - SetWindowPos(hwnd, NULL, 0,0,0,0, - SWP_NOACTIVATE|SWP_NOCOPYBITS| - SWP_NOMOVE|SWP_NOSIZE| SWP_NOZORDER| - SWP_FRAMECHANGED); - - GetWindowRect (hwnd, &wr); - GetClientRect (hwnd, &cr); - extra_width = wr.right - wr.left - cr.right + cr.left; - extra_height = wr.bottom - wr.top - cr.bottom + cr.top; + if (cfg.height != rows || + cfg.width != cols || + old_fwidth != font_width || + old_fheight != font_height || + cfg.savelines != savelines) + need_setwpos = TRUE; + term_size(cfg.height, cfg.width, cfg.savelines); + InvalidateRect(hwnd, NULL, TRUE); + if (need_setwpos) { + force_normal(hwnd); + SetWindowPos (hwnd, NULL, 0, 0, + extra_width + font_width * cfg.width, + extra_height + font_height * cfg.height, + SWP_NOACTIVATE | SWP_NOCOPYBITS | + SWP_NOMOVE | SWP_NOZORDER); } - } - - term_size(cfg.height, cfg.width, cfg.savelines); - InvalidateRect(hwnd, NULL, TRUE); - SetWindowPos (hwnd, NULL, 0, 0, - extra_width + font_width * cfg.width, - extra_height + font_height * cfg.height, - SWP_NOACTIVATE | SWP_NOCOPYBITS | - SWP_NOMOVE | SWP_NOZORDER); - if (IsIconic(hwnd)) { - SetWindowText (hwnd, - cfg.win_name_always ? window_name : icon_name); - } - break; - case IDM_CLRSB: - term_clrsb(); - break; - case IDM_RESET: - term_pwron(); + if (IsIconic(hwnd)) { + SetWindowText (hwnd, + cfg.win_name_always ? window_name : icon_name); + } + } + break; + case IDM_COPYALL: + term_copyall(); break; - case IDM_TEL_AYT: back->special (TS_AYT); break; + case IDM_CLRSB: + term_clrsb(); + break; + case IDM_RESET: + term_pwron(); + break; + case IDM_TEL_AYT: back->special (TS_AYT); break; case IDM_TEL_BRK: back->special (TS_BRK); break; case IDM_TEL_SYNCH: back->special (TS_SYNCH); break; case IDM_TEL_EC: back->special (TS_EC); break; @@ -1346,8 +1405,9 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, return 0; case WM_SETFOCUS: has_focus = TRUE; - CreateCaret(hwnd, caretbm, 0, 0); + CreateCaret(hwnd, caretbm, font_width, font_height); ShowCaret(hwnd); + compose_state = 0; term_out(); term_update(); break; @@ -1363,11 +1423,13 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, case WM_ENTERSIZEMOVE: EnableSizeTip(1); resizing = TRUE; + need_backend_resize = FALSE; break; case WM_EXITSIZEMOVE: EnableSizeTip(0); resizing = FALSE; - back->size(); + if (need_backend_resize) + back->size(); break; case WM_SIZING: { @@ -1443,6 +1505,8 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, */ if (!resizing) back->size(); + else + need_backend_resize = TRUE; just_reconfigged = FALSE; } } @@ -1813,7 +1877,6 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char * p = output; static WORD keys[3]; - static int compose_state = 0; static int compose_char = 0; static WPARAM compose_key = 0; @@ -1878,11 +1941,14 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, } #endif + if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED)) { + keystate[VK_RMENU] = keystate[VK_MENU]; + } + /* Note if AltGr was pressed and if it was used as a compose key */ if (cfg.compose_key) { if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED)) { - keystate[VK_RMENU] = keystate[VK_MENU]; if (!compose_state) compose_key = wParam; } if (wParam == VK_APPS && !compose_state) @@ -1899,11 +1965,13 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, } else if (compose_state==1 && wParam != VK_CONTROL) compose_state = 0; - } else + } else { compose_state = 0; + } /* Nastyness with NUMLock - Shift-NUMLock is left alone though */ - if ( (cfg.funky_type == 3 || (cfg.funky_type <= 1 && app_keypad_keys)) + if ( (cfg.funky_type == 3 || + (cfg.funky_type <= 1 && app_keypad_keys && !cfg.no_applic_k)) && wParam==VK_NUMLOCK && !(keystate[VK_SHIFT]&0x80)) { wParam = VK_EXECUTE; @@ -1948,7 +2016,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, if (compose_state>1 && left_alt) compose_state = 0; /* Sanitize the number pad if not using a PC NumPad */ - if( left_alt || (app_keypad_keys && cfg.funky_type != 2) + if( left_alt || (app_keypad_keys && !cfg.no_applic_k + && cfg.funky_type != 2) || cfg.funky_type == 3 || cfg.nethack_keypad || compose_state ) { if ((HIWORD(lParam)&KF_EXTENDED) == 0) @@ -2000,7 +2069,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, return -1; } if (left_alt && wParam == VK_SPACE && cfg.alt_space) { - + PostMessage(hwnd, WM_CHAR, ' ', 0); SendMessage (hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0); return -1; } @@ -2030,13 +2099,14 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, int xkey = 0; if ( cfg.funky_type == 3 || - ( cfg.funky_type <= 1 && app_keypad_keys)) switch(wParam) { + ( cfg.funky_type <= 1 && + app_keypad_keys && !cfg.no_applic_k)) switch(wParam) { case VK_EXECUTE: xkey = 'P'; break; case VK_DIVIDE: xkey = 'Q'; break; case VK_MULTIPLY:xkey = 'R'; break; case VK_SUBTRACT:xkey = 'S'; break; } - if(app_keypad_keys) switch(wParam) { + if(app_keypad_keys && !cfg.no_applic_k) switch(wParam) { case VK_NUMPAD0: xkey = 'p'; break; case VK_NUMPAD1: xkey = 'q'; break; case VK_NUMPAD2: xkey = 'r'; break; @@ -2198,7 +2268,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, { if (vt52_mode) p += sprintf((char *)p, "\x1B%c", xkey); - else if (app_cursor_keys) + else if (app_cursor_keys && !cfg.no_applic_c) p += sprintf((char *)p, "\x1BO%c", xkey); else p += sprintf((char *)p, "\x1B[%c", xkey); @@ -2272,9 +2342,17 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, } } - /* This stops ALT press-release doing a 'COMMAND MENU' function */ - if (!cfg.alt_only) { - if (message == WM_SYSKEYUP && wParam == VK_MENU) + /* ALT alone may or may not want to bring up the System menu */ + if (wParam == VK_MENU) { + if (cfg.alt_only) { + static int alt_state = 0; + if (message == WM_SYSKEYDOWN) + alt_state = 1; + else if (message == WM_SYSKEYUP && alt_state) + PostMessage(hwnd, WM_CHAR, ' ', 0); + if (message == WM_SYSKEYUP) + alt_state = 0; + } else return 0; }