X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/putty/blobdiff_plain/2d3411e92334d83d913cac4298fb218dfaebe291..d9027fbd7d419cd8381d4eedddd162166e20411a:/window.c diff --git a/window.c b/window.c index 26fcb0de..07dc6943 100644 --- a/window.c +++ b/window.c @@ -101,13 +101,10 @@ static Mouse_Button lastbtn; static char *window_name, *icon_name; -static Ldisc *real_ldisc; - static int compose_state = 0; -void begin_session(void) { - ldisc = real_ldisc; -} +/* Dummy routine, only required in plink. */ +void ldisc_update(int echo, int edit) {} int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { static char appname[] = "PuTTY"; @@ -318,11 +315,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { 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... */ - ldisc = &ldisc_simple; - if (!prev) { wndclass.style = 0; wndclass.lpfnWndProc = WndProc; @@ -564,7 +556,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { } if(!timer_id) timer_id = SetTimer(hwnd, 1, 20, NULL); - DispatchMessage (&msg); + if (!(IsWindow(logbox) && IsDialogMessage(logbox, &msg))) + DispatchMessage (&msg); /* Make sure we blink everything that needs it. */ term_blink(0); @@ -602,14 +595,17 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { term_out(); term_update(); ShowCaret(hwnd); - if (!has_focus) + if (in_vbell) + /* Hmm, term_update didn't want to do an update too soon ... */ + timer_id = SetTimer(hwnd, 1, 50, NULL); + else if (!has_focus) timer_id = SetTimer(hwnd, 1, 59500, NULL); else timer_id = SetTimer(hwnd, 1, 100, NULL); long_timer = 1; /* There's no point rescanning everything in the message queue - * so we do an apperently unneccesary wait here + * so we do an apparently unnecessary wait here */ WaitMessage(); if (GetMessage (&msg, NULL, 0, 0) != 1) @@ -674,7 +670,7 @@ void connection_fatal(char *fmt, ...) { vsprintf(stuff, fmt, ap); va_end(ap); MessageBox(hwnd, stuff, "PuTTY Fatal Error", MB_ICONERROR | MB_OK); - if (cfg.close_on_exit) + if (cfg.close_on_exit == COE_ALWAYS) PostQuitMessage(1); else { session_closed = TRUE; @@ -699,14 +695,17 @@ static void enact_pending_netevent(void) { ret = select_result (pend_netevent_wParam, pend_netevent_lParam); reentering = 0; - if (ret == 0) { - if (cfg.close_on_exit) + if (ret == 0 && !session_closed) { + /* Abnormal exits will already have set session_closed and taken + * appropriate action. */ + if (cfg.close_on_exit == COE_ALWAYS || + cfg.close_on_exit == COE_NORMAL) PostQuitMessage(0); else { - session_closed = TRUE; - MessageBox(hwnd, "Connection closed by remote host", - "PuTTY", MB_OK | MB_ICONINFORMATION); - SetWindowText (hwnd, "PuTTY (inactive)"); + session_closed = TRUE; + SetWindowText (hwnd, "PuTTY (inactive)"); + MessageBox(hwnd, "Connection closed by remote host", + "PuTTY", MB_OK | MB_ICONINFORMATION); } } } @@ -812,6 +811,9 @@ font_messup: hdc = GetDC(hwnd); font_height = cfg.fontheight; + if (font_height > 0) { + font_height = -MulDiv(font_height, GetDeviceCaps(hdc, LOGPIXELSY), 72); + } font_width = pick_width; #define f(i,c,w,u) \ @@ -1054,6 +1056,17 @@ static void click (Mouse_Button b, int x, int y) { lasttime = thistime; } +static void show_mouseptr(int show) { + static int cursor_visible = 1; + if (!cfg.hide_mouseptr) /* override if this feature disabled */ + show = 1; + if (cursor_visible && !show) + ShowCursor(FALSE); + else if (!cursor_visible && show) + ShowCursor(TRUE); + cursor_visible = show; +} + static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; @@ -1077,7 +1090,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, { time_t now; time(&now); - if (now-last_movement > cfg.ping_interval * 60 - 10) + if (now-last_movement > cfg.ping_interval) { back->special(TS_PING); last_movement = now; @@ -1087,6 +1100,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, case WM_CREATE: break; case WM_CLOSE: + show_mouseptr(1); if (!cfg.warn_on_close || session_closed || MessageBox(hwnd, "Are you sure you want to close this session?", "PuTTY Exit Confirmation", @@ -1094,6 +1108,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, DestroyWindow(hwnd); return 0; case WM_DESTROY: + show_mouseptr(1); PostQuitMessage (0); return 0; case WM_SYSCOMMAND: @@ -1206,11 +1221,10 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, init_fonts(0); sfree(logpal); /* - * Telnet will change local echo -> remote if the - * remote asks. + * Flush the line discipline's edit buffer in the + * case where local editing has just been disabled. */ - if (cfg.protocol != PROT_TELNET) - ldisc = (cfg.ldisc_term ? &ldisc_term : &ldisc_simple); + ldisc_send(NULL, 0); if (pal) DeleteObject(pal); logpal = NULL; @@ -1329,40 +1343,47 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, #define TO_CHR_Y(y) (((y)<0 ? (y)-font_height+1: (y)) / font_height) case WM_LBUTTONDOWN: + show_mouseptr(1); click (MB_SELECT, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam))); SetCapture(hwnd); return 0; case WM_LBUTTONUP: + show_mouseptr(1); term_mouse (MB_SELECT, MA_RELEASE, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam))); ReleaseCapture(); return 0; case WM_MBUTTONDOWN: + show_mouseptr(1); SetCapture(hwnd); click (cfg.mouse_is_xterm ? MB_PASTE : MB_EXTEND, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam))); return 0; case WM_MBUTTONUP: + show_mouseptr(1); term_mouse (cfg.mouse_is_xterm ? MB_PASTE : MB_EXTEND, MA_RELEASE, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam))); ReleaseCapture(); return 0; case WM_RBUTTONDOWN: + show_mouseptr(1); SetCapture(hwnd); click (cfg.mouse_is_xterm ? MB_EXTEND : MB_PASTE, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam))); return 0; case WM_RBUTTONUP: + show_mouseptr(1); term_mouse (cfg.mouse_is_xterm ? MB_EXTEND : MB_PASTE, MA_RELEASE, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam))); ReleaseCapture(); return 0; case WM_MOUSEMOVE: + show_mouseptr(1); /* * Add the mouse position and message time to the random * number noise. @@ -1381,6 +1402,10 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, TO_CHR_Y(Y_POS(lParam))); } return 0; + case WM_NCMOUSEMOVE: + show_mouseptr(1); + noise_ultralight(lParam); + return 0; case WM_IGNORE_CLIP: ignore_clip = wParam; /* don't panic on DESTROYCLIPBOARD */ break; @@ -1428,6 +1453,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, term_update(); break; case WM_KILLFOCUS: + show_mouseptr(1); has_focus = FALSE; DestroyCaret(); term_out(); @@ -1593,7 +1619,10 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, len = TranslateKey (message, wParam, lParam, buf); if (len == -1) return DefWindowProc (hwnd, message, wParam, lParam); - ldisc->send (buf, len); + ldisc_send (buf, len); + + if (len > 0) + show_mouseptr(0); } } return 0; @@ -1603,7 +1632,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, buf[1] = wParam; buf[0] = wParam >> 8; - ldisc->send (buf, 2); + ldisc_send (buf, 2); } case WM_CHAR: case WM_SYSCHAR: @@ -1615,7 +1644,7 @@ static LRESULT CALLBACK WndProc (HWND hwnd, UINT message, */ { char c = xlat_kbd2tty((unsigned char)wParam); - ldisc->send (&c, 1); + ldisc_send (&c, 1); } return 0; } @@ -1700,7 +1729,7 @@ void do_text (Context ctx, int x, int y, char *text, int len, #endif /* This is CP437 ... junk translation */ static const unsigned char oemhighhalf[] = { - 0xff, 0xad, 0x9b, 0x9c, 0x6f, 0x9d, 0x7c, 0x15, + 0x20, 0xad, 0x9b, 0x9c, 0x6f, 0x9d, 0x7c, 0x15, 0x22, 0x43, 0xa6, 0xae, 0xaa, 0x2d, 0x52, 0xc4, 0xf8, 0xf1, 0xfd, 0x33, 0x27, 0xe6, 0x14, 0xfa, 0x2c, 0x31, 0xa7, 0xaf, 0xac, 0xab, 0x2f, 0xa8, @@ -1992,29 +2021,6 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, 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)) - { - if (!compose_state) compose_key = wParam; - } - if (wParam == VK_APPS && !compose_state) - compose_key = wParam; - - if (wParam == compose_key) - { - if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0) - compose_state = 1; - else if (compose_state == 1 && (HIWORD(lParam)&KF_UP)) - compose_state = 2; - else - compose_state = 0; - } - else if (compose_state==1 && wParam != VK_CONTROL) - compose_state = 0; - } else { - compose_state = 0; - } /* Nastyness with NUMLock - Shift-NUMLock is left alone though */ if ( (cfg.funky_type == 3 || @@ -2041,14 +2047,43 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, key_down = ((HIWORD(lParam)&KF_UP)==0); - /* Make sure Ctrl-ALT is not the same as AltGr for ToAscii */ - if (left_alt && (keystate[VK_CONTROL]&0x80)) - keystate[VK_MENU] = 0; + /* Make sure Ctrl-ALT is not the same as AltGr for ToAscii unless told. */ + if (left_alt && (keystate[VK_CONTROL]&0x80)) { + if (cfg.ctrlaltkeys) + keystate[VK_MENU] = 0; + else { + keystate[VK_RMENU] = 0x80; + left_alt = 0; + } + } scan = (HIWORD(lParam) & (KF_UP | KF_EXTENDED | 0xFF)); shift_state = ((keystate[VK_SHIFT]&0x80)!=0) + ((keystate[VK_CONTROL]&0x80)!=0)*2; + /* Note if AltGr was pressed and if it was used as a compose key */ + if (!compose_state) { + compose_key = 0x100; + if (cfg.compose_key) { + if (wParam == VK_MENU && (HIWORD(lParam)&KF_EXTENDED)) + compose_key = wParam; + } + if (wParam == VK_APPS) + compose_key = wParam; + } + + if (wParam == compose_key) + { + if (compose_state == 0 && (HIWORD(lParam)&(KF_UP|KF_REPEAT))==0) + compose_state = 1; + else if (compose_state == 1 && (HIWORD(lParam)&KF_UP)) + compose_state = 2; + else + compose_state = 0; + } + else if (compose_state==1 && wParam != VK_CONTROL) + compose_state = 0; + /* * Record that we pressed key so the scroll window can be reset, but * be careful to avoid Shift-UP/Down @@ -2219,6 +2254,10 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, { *p++ = 3; return p - output; } + if (wParam == VK_PAUSE) /* Break/Pause */ + { + *p++ = 26; *p++ = 0; return -2; + } /* Control-2 to Control-8 are special */ if (shift_state == 2 && wParam >= '2' && wParam <= '8') { @@ -2388,6 +2427,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, return p-output; } + /* If we're definitly not building up an ALT-54321 then clear it */ + if (!left_alt) keys[0] = 0; } /* ALT alone may or may not want to bring up the System menu */ @@ -2402,6 +2443,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, } else return 0; } + else alt_state = 0; return -1; } @@ -2596,21 +2638,16 @@ void fatalbox(char *fmt, ...) { /* * Beep. */ -void beep(int errorbeep) { - static long last_beep = 0; - long now, beep_diff; - - now = GetTickCount(); - beep_diff = now-last_beep; - - /* Make sure we only respond to one beep per packet or so */ - if (beep_diff>=0 && beep_diff<50) - return; - - if(errorbeep) - MessageBeep(MB_ICONHAND); - else - MessageBeep(MB_OK); - - last_beep = GetTickCount(); +void beep(int mode) { + if (mode == BELL_DEFAULT) { + MessageBeep(MB_OK); + } else if (mode == BELL_WAVEFILE) { + if (!PlaySound(cfg.bell_wavefile, NULL, SND_ASYNC | SND_FILENAME)) { + char buf[sizeof(cfg.bell_wavefile)+80]; + sprintf(buf, "Unable to play sound file\n%s\n" + "Using default sound instead", cfg.bell_wavefile); + MessageBox(hwnd, buf, "PuTTY Sound Error", MB_OK | MB_ICONEXCLAMATION); + cfg.beep = BELL_DEFAULT; + } + } }