X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/638787a8dca15282e9fe329087865d4a8f8c4047..97fc891ee495682f9939218b223675cdeddc7877:/window.c diff --git a/window.c b/window.c index 0a688573..e85cb024 100644 --- a/window.c +++ b/window.c @@ -3,6 +3,7 @@ #include #include #include +#include #define PUTTY_DO_GLOBALS /* actually _define_ globals */ #include "putty.h" @@ -36,7 +37,7 @@ #define WM_IGNORE_SIZE (WM_USER + 2) #define WM_IGNORE_CLIP (WM_USER + 3) -static int WINAPI WndProc (HWND, UINT, WPARAM, LPARAM); +static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output); static void cfgtopalette(void); static void init_palette(void); @@ -128,6 +129,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { tolower(p[2]) == 'h') { default_protocol = cfg.protocol = PROT_SSH; default_port = cfg.port = 22; + } else if (q == p + 3 && + tolower(p[0]) == 'l' && + tolower(p[1]) == 'o' && + tolower(p[2]) == 'g') { + logfile = "putty.log"; } p = q + strspn(q, " \t"); } @@ -150,7 +156,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { */ HANDLE filemap; Config *cp; - if (sscanf(p+1, "%x", &filemap) == 1 && + if (sscanf(p+1, "%p", &filemap) == 1 && (cp = MapViewOfFile(filemap, FILE_MAP_READ, 0, 0, sizeof(Config))) != NULL) { cfg = *cp; @@ -303,12 +309,19 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { set_icon (msg); } + session_closed = FALSE; + /* * Set up the input and output buffers. */ inbuf_reap = inbuf_head = 0; outbuf_reap = outbuf_head = 0; + /* + * Choose unscroll method + */ + unscroll_event = US_DISP; + /* * Prepare the mouse handler. */ @@ -346,21 +359,21 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) p, "Telnet Command"); AppendMenu (m, MF_SEPARATOR, 0, 0); } - AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "Event Log"); + AppendMenu (m, MF_ENABLED, IDM_SHOWLOG, "&Event Log"); AppendMenu (m, MF_SEPARATOR, 0, 0); - AppendMenu (m, MF_ENABLED, IDM_NEWSESS, "New Session"); - AppendMenu (m, MF_ENABLED, IDM_DUPSESS, "Duplicate 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, "Saved Sessions"); - AppendMenu (m, MF_ENABLED, IDM_RECONF, "Change Settings"); + AppendMenu (m, MF_POPUP | MF_ENABLED, (UINT) s, "Sa&ved Sessions"); + AppendMenu (m, MF_ENABLED, IDM_RECONF, "Chan&ge Settings"); AppendMenu (m, MF_SEPARATOR, 0, 0); - AppendMenu (m, MF_ENABLED, IDM_CLRSB, "Clear Scrollback"); - AppendMenu (m, MF_ENABLED, IDM_RESET, "Reset Terminal"); + AppendMenu (m, MF_ENABLED, IDM_CLRSB, "C&lear Scrollback"); + AppendMenu (m, MF_ENABLED, IDM_RESET, "Rese&t Terminal"); AppendMenu (m, MF_SEPARATOR, 0, 0); - AppendMenu (m, MF_ENABLED, IDM_ABOUT, "About PuTTY"); + AppendMenu (m, MF_ENABLED, IDM_ABOUT, "&About PuTTY"); } /* @@ -488,11 +501,13 @@ static void init_palette(void) { */ static void init_fonts(void) { TEXTMETRIC tm; - int i, j; - int widths[5]; + int i; + int fsize[5]; HDC hdc; int fw_dontcare, fw_bold; + int firstchar = ' '; +font_messup: for (i=0; i<8; i++) fonts[i] = NULL; @@ -504,83 +519,132 @@ static void init_fonts(void) { fw_bold = FW_BOLD; } + hdc = GetDC(hwnd); + + font_height = cfg.fontheight; + font_width = 0; + #define f(i,c,w,u) \ - fonts[i] = CreateFont (cfg.fontheight, 0, 0, 0, w, FALSE, u, FALSE, \ + fonts[i] = CreateFont (font_height, font_width, 0, 0, w, FALSE, u, FALSE, \ c, OUT_DEFAULT_PRECIS, \ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \ FIXED_PITCH | FF_DONTCARE, cfg.font) + if (cfg.vtmode != VT_OEMONLY) { f(FONT_NORMAL, cfg.fontcharset, fw_dontcare, FALSE); + + SelectObject (hdc, fonts[FONT_NORMAL]); + GetTextMetrics(hdc, &tm); + font_height = tm.tmHeight; + font_width = tm.tmAveCharWidth; + f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE); - } - if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_OEMONLY) { - f(FONT_OEM, OEM_CHARSET, fw_dontcare, FALSE); - f(FONT_OEMUND, OEM_CHARSET, fw_dontcare, TRUE); - } - if (bold_mode == BOLD_FONT) { - if (cfg.vtmode != VT_OEMONLY) { + + if (bold_mode == BOLD_FONT) { f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE); f(FONT_BOLDUND, cfg.fontcharset, fw_bold, TRUE); } - if (cfg.vtmode == VT_OEMANSI || cfg.vtmode == VT_OEMONLY) { - f(FONT_OEMBOLD, OEM_CHARSET, fw_bold, FALSE); - f(FONT_OEMBOLDUND, OEM_CHARSET, fw_bold, TRUE); + + if (cfg.vtmode == VT_OEMANSI) { + f(FONT_OEM, OEM_CHARSET, fw_dontcare, FALSE); + f(FONT_OEMUND, OEM_CHARSET, fw_dontcare, TRUE); + + if (bold_mode == BOLD_FONT) { + f(FONT_OEMBOLD, OEM_CHARSET, fw_bold, FALSE); + f(FONT_OEMBOLDUND, OEM_CHARSET, fw_bold, TRUE); + } + } + } + else + { + f(FONT_OEM, cfg.fontcharset, fw_dontcare, FALSE); + + SelectObject (hdc, fonts[FONT_OEM]); + GetTextMetrics(hdc, &tm); + font_height = tm.tmHeight; + font_width = tm.tmAveCharWidth; + + f(FONT_OEMUND, cfg.fontcharset, fw_dontcare, TRUE); + + if (bold_mode == BOLD_FONT) { + f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE); + f(FONT_BOLDUND, cfg.fontcharset, fw_bold, TRUE); } - } else { - fonts[FONT_BOLD] = fonts[FONT_BOLDUND] = NULL; - fonts[FONT_OEMBOLD] = fonts[FONT_OEMBOLDUND] = NULL; } #undef f - hdc = GetDC(hwnd); + descent = tm.tmAscent + 1; + if (descent >= font_height) + descent = font_height - 1; + firstchar = tm.tmFirstChar; - if (cfg.vtmode == VT_OEMONLY) - j = 4; - else - j = 0; + if( cfg.vtmode == VT_XWINDOWS && firstchar >= ' ' ) + cfg.vtmode = VT_POORMAN; - for (i=0; i<(cfg.vtmode == VT_OEMANSI ? 5 : 4); i++) { - if (fonts[i+j]) { - SelectObject (hdc, fonts[i+j]); + for (i=0; i<8; i++) { + if (fonts[i]) { + SelectObject (hdc, fonts[i]); GetTextMetrics(hdc, &tm); - if (i == 0 || i == 4) { - font_height = tm.tmHeight; - font_width = tm.tmAveCharWidth; - descent = tm.tmAscent + 1; - if (descent >= font_height) - descent = font_height - 1; - } - widths[i] = tm.tmAveCharWidth; + fsize[i] = tm.tmAveCharWidth + 256 * tm.tmHeight; } } ReleaseDC (hwnd, hdc); - if (widths[FONT_UNDERLINE] != widths[FONT_NORMAL] || + if (fsize[FONT_UNDERLINE] != fsize[FONT_NORMAL] || (bold_mode == BOLD_FONT && - widths[FONT_BOLDUND] != widths[FONT_BOLD])) { + fsize[FONT_BOLDUND] != fsize[FONT_BOLD])) { und_mode = UND_LINE; DeleteObject (fonts[FONT_UNDERLINE]); if (bold_mode == BOLD_FONT) DeleteObject (fonts[FONT_BOLDUND]); + +#if 0 + MessageBox(NULL, "Disabling underline font", + "Font Size Mismatch", MB_ICONINFORMATION | MB_OK); +#endif } if (bold_mode == BOLD_FONT && - widths[FONT_BOLD] != widths[FONT_NORMAL]) { + fsize[FONT_BOLD] != fsize[FONT_NORMAL]) { bold_mode = BOLD_SHADOW; DeleteObject (fonts[FONT_BOLD]); if (und_mode == UND_FONT) DeleteObject (fonts[FONT_BOLDUND]); + +#if 0 + MessageBox(NULL, "Disabling bold font", + "Font Size Mismatch", MB_ICONINFORMATION | MB_OK); +#endif } - if (cfg.vtmode == VT_OEMANSI && widths[FONT_OEM] != widths[FONT_NORMAL]) { - MessageBox(NULL, "The OEM and ANSI versions of this font are\n" + if (cfg.vtmode == VT_OEMANSI && fsize[FONT_OEM] != fsize[FONT_NORMAL] ) { + if( cfg.fontcharset == OEM_CHARSET ) + { + MessageBox(NULL, "The OEM and ANSI versions of this font are\n" "different sizes. Using OEM-only mode instead", "Font Size Mismatch", MB_ICONINFORMATION | MB_OK); - cfg.vtmode = VT_OEMONLY; - for (i=0; i<4; i++) + cfg.vtmode = VT_OEMONLY; + } + else if( firstchar < ' ' ) + { + MessageBox(NULL, "The OEM and ANSI versions of this font are\n" + "different sizes. Using XTerm mode instead", + "Font Size Mismatch", MB_ICONINFORMATION | MB_OK); + cfg.vtmode = VT_XWINDOWS; + } + else + { + MessageBox(NULL, "The OEM and ANSI versions of this font are\n" + "different sizes. Using ISO8859-1 mode instead", + "Font Size Mismatch", MB_ICONINFORMATION | MB_OK); + cfg.vtmode = VT_POORMAN; + } + + for (i=0; i<8; i++) if (fonts[i]) DeleteObject (fonts[i]); + goto font_messup; } } @@ -609,8 +673,8 @@ static void click (Mouse_Button b, int x, int y) { lasttime = thistime; } -static int WINAPI WndProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam) { +static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) { HDC hdc; static int ignore_size = FALSE; static int ignore_clip = FALSE; @@ -620,7 +684,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message, case WM_CREATE: break; case WM_CLOSE: - if (!cfg.warn_on_close || + if (!cfg.warn_on_close || session_closed || MessageBox(hwnd, "Are you sure you want to close this session?", "PuTTY Exit Confirmation", MB_ICONWARNING | MB_OKCANCEL) == IDOK) @@ -671,15 +735,17 @@ static int WINAPI WndProc (HWND hwnd, UINT message, UnmapViewOfFile(p); } } - sprintf(c, "putty &%08x", filemap); + sprintf(c, "putty &%p", filemap); cl = c; } else if (wParam == IDM_SAVEDSESS) { char *session = sessions[(lParam - IDM_SAVED_MIN) / 16]; cl = malloc(16 + strlen(session)); /* 8, but play safe */ if (!cl) cl = NULL; /* not a very important failure mode */ - sprintf(cl, "putty @%s", session); - freecl = TRUE; + else { + sprintf(cl, "putty @%s", session); + freecl = TRUE; + } } else cl = NULL; @@ -715,6 +781,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message, init_fonts(); sfree(logpal); ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple); + back->special (cfg.ldisc_term ? TS_LECHO : TS_RECHO); if (pal) DeleteObject(pal); logpal = NULL; @@ -865,6 +932,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message, if (cfg.close_on_exit) PostQuitMessage(0); else { + session_closed = TRUE; MessageBox(hwnd, "Connection closed by remote host", "PuTTY", MB_OK | MB_ICONINFORMATION); SetWindowText (hwnd, "PuTTY (inactive)"); @@ -886,11 +954,11 @@ static int WINAPI WndProc (HWND hwnd, UINT message, ignore_size = TRUE; /* don't panic on next WM_SIZE msg */ break; case WM_ENTERSIZEMOVE: - EnableSizeTip(1); - break; + EnableSizeTip(1); + break; case WM_EXITSIZEMOVE: - EnableSizeTip(0); - break; + EnableSizeTip(0); + break; case WM_SIZING: { int width, height, w, h, ew, eh; @@ -900,7 +968,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message, height = r->bottom - r->top - extra_height; w = (width + font_width/2) / font_width; if (w < 1) w = 1; h = (height + font_height/2) / font_height; if (h < 1) h = 1; - UpdateSizeTip(hwnd, w, h); + UpdateSizeTip(hwnd, w, h); ew = width - w * font_width; eh = height - h * font_height; if (ew != 0) { @@ -924,7 +992,7 @@ static int WINAPI WndProc (HWND hwnd, UINT message, else return 0; } - break; + /* break; (never reached) */ case WM_SIZE: if (wParam == SIZE_MINIMIZED) { SetWindowText (hwnd, @@ -1133,8 +1201,8 @@ void do_text (Context ctx, int x, int y, char *text, int len, static const char poorman[] = "*#****\xB0\xB1**+++++-----++++|****\xA3\xB7"; static const char oemmap[] = - "*\xB1****\xF8\xF1**\xD9\xBF\xDA\xC0\xC5" - "\xC4\xC4\xC4\xC4\xC4\xC3\xB4\xC1\xC2\xB3****\x9C\xFA"; + "\x04\xB1****\xF8\xF1**\xD9\xBF\xDA\xC0\xC5" + "\xC4\xC4\xC4\xC4\xC4\xC3\xB4\xC1\xC2\xB3\xF3\xF2\xE3*\x9C\xFA"; /* * Line drawing mapping: map ` thru ~ (0x60 thru 0x7E) to @@ -1222,6 +1290,14 @@ static int TranslateKey(WPARAM wParam, LPARAM lParam, unsigned char *output) { ret = GetKeyboardState(keystate); /* + * Record that we pressed key so the scroll window can be reset, but + * be careful to avoid Shift-UP/Down + */ + if( wParam != VK_SHIFT && wParam != VK_PRIOR && wParam != VK_NEXT ) { + seen_key_event = 1; + } + + /* * Windows does not always want to distinguish left and right * Alt or Control keys. Thus we keep track of them ourselves. * See also the WM_KEYUP handler.