X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/70887be9ad821c22faf52c87597a707a8320a8cf..4d331a77f20f321f867f5907e2ffc06249378881:/window.c diff --git a/window.c b/window.c index 6c67b592..9c973faf 100644 --- a/window.c +++ b/window.c @@ -1,6 +1,12 @@ #include #include +#ifndef AUTO_WINSOCK +#ifdef WINSOCK_TWO +#include +#else #include +#endif +#endif #include #include #include @@ -36,6 +42,7 @@ #define WM_IGNORE_SIZE (WM_XUSER + 1) #define WM_IGNORE_CLIP (WM_XUSER + 2) +#define WM_IGNORE_KEYMENU (WM_XUSER + 3) static LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, unsigned char *output); @@ -59,6 +66,7 @@ static void enact_pending_netevent(void); #define FONT_OEMBOLDUND 6 #define FONT_OEMUND 7 static HFONT fonts[8]; +static int font_needs_hand_underlining; static enum { BOLD_COLOURS, BOLD_SHADOW, BOLD_FONT } bold_mode; @@ -80,6 +88,12 @@ static Mouse_Button lastbtn; static char *window_name, *icon_name; +static Ldisc *real_ldisc; + +void begin_session(void) { + ldisc = real_ldisc; +} + int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { static char appname[] = "PuTTY"; WORD winsock_ver; @@ -89,6 +103,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { int guess_width, guess_height; putty_inst = inst; + flags = FLAG_VERBOSE | FLAG_INTERACTIVE; winsock_ver = MAKEWORD(1, 1); if (WSAStartup(winsock_ver, &wsadata)) { @@ -236,7 +251,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { } } - ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple); + 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... */ + ldisc = &ldisc_simple; if (!prev) { wndclass.style = 0; @@ -518,12 +536,39 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { } /* + * Print a message box and close the connection. + */ +void connection_fatal(char *fmt, ...) { + va_list ap; + char stuff[200]; + + va_start(ap, fmt); + vsprintf(stuff, fmt, ap); + va_end(ap); + MessageBox(hwnd, stuff, "PuTTY Fatal Error", MB_ICONERROR | MB_OK); + if (cfg.close_on_exit) + PostQuitMessage(1); + else { + session_closed = TRUE; + SetWindowText (hwnd, "PuTTY (inactive)"); + } +} + +/* * Actually do the job requested by a WM_NETEVENT */ static void enact_pending_netevent(void) { int i; + static int reentering = 0; + + if (reentering) + return; /* don't unpend the pending */ + pending_netevent = FALSE; + + reentering = 1; i = back->msg (pend_netevent_wParam, pend_netevent_lParam); + reentering = 0; if (i < 0) { char buf[1024]; @@ -535,10 +580,9 @@ static void enact_pending_netevent(void) { sprintf(buf, "Unexpected network error %d", -i); break; } - MessageBox(hwnd, buf, "PuTTY Fatal Error", - MB_ICONERROR | MB_OK); - PostQuitMessage(1); - } else if (i == 0) { + connection_fatal(buf); + } + if (i <= 0) { if (cfg.close_on_exit) PostQuitMessage(0); else { @@ -669,6 +713,50 @@ font_messup: f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE); + /* + * Some fonts, e.g. 9-pt Courier, draw their underlines + * outside their character cell. We successfully prevent + * screen corruption by clipping the text output, but then + * we lose the underline completely. Here we try to work + * out whether this is such a font, and if it is, we set a + * flag that causes underlines to be drawn by hand. + * + * Having tried other more sophisticated approaches (such + * as examining the TEXTMETRIC structure or requesting the + * height of a string), I think we'll do this the brute + * force way: we create a small bitmap, draw an underlined + * space on it, and test to see whether any pixels are + * foreground-coloured. (Since we expect the underline to + * go all the way across the character cell, we only search + * down a single column of the bitmap, half way across.) + */ + { + HDC und_dc; + HBITMAP und_bm, und_oldbm; + int i, gotit; + COLORREF c; + + und_dc = CreateCompatibleDC(hdc); + und_bm = CreateCompatibleBitmap(hdc, font_width, font_height); + und_oldbm = SelectObject(und_dc, und_bm); + SelectObject(und_dc, fonts[FONT_UNDERLINE]); + SetTextAlign(und_dc, TA_TOP | TA_LEFT | TA_NOUPDATECP); + SetTextColor (und_dc, RGB(255,255,255)); + SetBkColor (und_dc, RGB(0,0,0)); + SetBkMode (und_dc, OPAQUE); + ExtTextOut (und_dc, 0, 0, ETO_OPAQUE, NULL, " ", 1, NULL); + gotit = FALSE; + for (i = 0; i < font_height; i++) { + c = GetPixel(und_dc, font_width/2, i); + if (c != RGB(0,0,0)) + gotit = TRUE; + } + SelectObject(und_dc, und_oldbm); + DeleteObject(und_bm); + DeleteDC(und_dc); + font_needs_hand_underlining = !gotit; + } + if (bold_mode == BOLD_FONT) { f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE); f(FONT_BOLDUND, cfg.fontcharset, fw_bold, TRUE); @@ -854,6 +942,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, HDC hdc; static int ignore_size = FALSE; static int ignore_clip = FALSE; + static int ignore_keymenu = TRUE; static int just_reconfigged = FALSE; switch (message) { @@ -878,6 +967,10 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, return 0; case WM_SYSCOMMAND: switch (wParam & ~0xF) { /* low 4 bits reserved to Windows */ + case SC_KEYMENU: + if (ignore_keymenu) + return 0; /* don't put up system menu on Alt */ + break; case IDM_SHOWLOG: showeventlog(hwnd); break; @@ -1107,6 +1200,9 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, case WM_IGNORE_CLIP: ignore_clip = wParam; /* don't panic on DESTROYCLIPBOARD */ break; + case WM_IGNORE_KEYMENU: + ignore_keymenu = wParam; /* do or don't ignore SC_KEYMENU */ + break; case WM_DESTROYCLIPBOARD: if (!ignore_clip) term_deselect(); @@ -1324,7 +1420,7 @@ void do_text (Context ctx, int x, int y, char *text, int len, RECT line_box; int force_manual_underline = 0; int fnt_width = font_width*(1+(lattr!=LATTR_NORM)); -static int *IpDx = 0, IpDxLEN = 0;; + static int *IpDx = 0, IpDxLEN = 0;; if (len>IpDxLEN || IpDx[0] != fnt_width) { int i; @@ -1467,6 +1563,8 @@ static int *IpDx = 0, IpDxLEN = 0;; nfont &= ~(FONT_BOLD|FONT_UNDERLINE); } + if (font_needs_hand_underlining && (attr & ATTR_UNDER)) + force_manual_underline = 1; if (attr & ATTR_REVERSE) { t = nfg; nfg = nbg; nbg = t; } @@ -1694,19 +1792,22 @@ static WPARAM compose_key = 0; /* Lets see if it's a pattern we know all about ... */ if (wParam == VK_PRIOR && shift_state == 1) { - SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0); - return 0; + SendMessage (hwnd, WM_VSCROLL, SB_PAGEUP, 0); + return 0; } if (wParam == VK_NEXT && shift_state == 1) { - SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0); - return 0; + SendMessage (hwnd, WM_VSCROLL, SB_PAGEDOWN, 0); + return 0; } if (left_alt && wParam == VK_F4 && cfg.alt_f4) { - return -1; + return -1; } if (left_alt && wParam == VK_SPACE && cfg.alt_space) { - SendMessage (hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0); - return -1; + + SendMessage (hwnd, WM_IGNORE_KEYMENU, FALSE, 0); + SendMessage (hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0); + SendMessage (hwnd, WM_IGNORE_KEYMENU, TRUE, 0); + return -1; } /* Nethack keypad */ @@ -1730,7 +1831,7 @@ static WPARAM compose_key = 0; if ( cfg.funky_type == 0 || ( cfg.funky_type == 1 && app_keypad_keys)) switch(wParam) { - case VK_EXECUTE: xkey = 'P'; break; + case VK_EXECUTE: if (app_keypad_keys) xkey = 'P'; break; case VK_DIVIDE: xkey = 'Q'; break; case VK_MULTIPLY:xkey = 'R'; break; case VK_SUBTRACT:xkey = 'S'; break;