X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/5eaf1e061d83bdfe4f0f16a21bdccfedf070ee3e..3ad9d396e3e57477b4da4b20665ca33edd5d7f67:/window.c diff --git a/window.c b/window.c index 761097e5..378634f9 100644 --- a/window.c +++ b/window.c @@ -77,6 +77,7 @@ static int pending_netevent = 0; static WPARAM pend_netevent_wParam = 0; static LPARAM pend_netevent_lParam = 0; static void enact_pending_netevent(void); +static void flash_window(int mode); static time_t last_movement = 0; @@ -127,6 +128,8 @@ static char *window_name, *icon_name; static int compose_state = 0; +static OSVERSIONINFO osVersion; + /* Dummy routine, only required in plink. */ void ldisc_update(int echo, int edit) { @@ -165,6 +168,16 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * config box. */ defuse_showwindow(); + { + ZeroMemory(&osVersion, sizeof(osVersion)); + osVersion.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (!GetVersionEx ( (OSVERSIONINFO *) &osVersion)) { + MessageBox(NULL, "Windows refuses to report a version", + "PuTTY Fatal Error", MB_OK | MB_ICONEXCLAMATION); + return 1; + } + } + /* * Process the command line. */ @@ -302,6 +315,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } } + /* + * Trim leading whitespace off the hostname if it's there. + */ + { + int space = strspn(cfg.host, " \t"); + memmove(cfg.host, cfg.host+space, 1+strlen(cfg.host)-space); + } + /* See if host is of the form user@host */ if (cfg.host[0] != '\0') { char *atsign = strchr(cfg.host, '@'); @@ -565,6 +586,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * Finally show the window! */ ShowWindow(hwnd, show); + SetForegroundWindow(hwnd); /* * Open the initial log file if there is one. @@ -636,11 +658,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) term_out(); term_update(); ShowCaret(hwnd); + + flash_window(1); /* maintain */ + 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, 2000, NULL); + timer_id = SetTimer(hwnd, 1, 500, NULL); else timer_id = SetTimer(hwnd, 1, 100, NULL); long_timer = 1; @@ -681,7 +706,8 @@ char *do_select(SOCKET skt, int startup) int msg, events; if (startup) { msg = WM_NETEVENT; - events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE; + events = (FD_CONNECT | FD_READ | FD_WRITE | + FD_OOB | FD_CLOSE | FD_ACCEPT); } else { msg = events = 0; } @@ -1104,7 +1130,8 @@ static void click(Mouse_Button b, int x, int y, int shift, int ctrl) { int thistime = GetMessageTime(); - if (send_raw_mouse) { + if (send_raw_mouse && !(cfg.mouse_override && shift)) { + lastbtn = MBT_NOTHING; term_mouse(b, MA_CLICK, x, y, shift, ctrl); return; } @@ -1134,6 +1161,7 @@ Mouse_Button translate_button(Mouse_Button button) return cfg.mouse_is_xterm ? MBT_PASTE : MBT_EXTEND; if (button == MBT_RIGHT) return cfg.mouse_is_xterm ? MBT_EXTEND : MBT_PASTE; + return 0; /* shouldn't happen */ } static void show_mouseptr(int show) @@ -1466,6 +1494,17 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, case IDM_ABOUT: showabout(hwnd); break; + case SC_KEYMENU: + /* + * We get this if the System menu has been activated. + * This might happen from within TranslateKey, in which + * case it really wants to be followed by a `space' + * character to actually _bring the menu up_ rather + * than just sitting there in `ready to appear' state. + */ + if( lParam == 0 ) + PostMessage(hwnd, WM_CHAR, ' ', 0); + break; default: if (wParam >= IDM_SAVED_MIN && wParam <= IDM_SAVED_MAX) { SendMessage(hwnd, WM_SYSCOMMAND, IDM_SAVEDSESS, wParam); @@ -1549,6 +1588,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, button = MBT_RIGHT; press = 0; break; + default: + button = press = 0; /* shouldn't happen */ } show_mouseptr(1); if (press) { @@ -1576,11 +1617,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, if (wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) { Mouse_Button b; if (wParam & MK_LBUTTON) - b = MBT_SELECT; + b = MBT_LEFT; else if (wParam & MK_MBUTTON) - b = cfg.mouse_is_xterm ? MBT_PASTE : MBT_EXTEND; + b = MBT_MIDDLE; else - b = cfg.mouse_is_xterm ? MBT_EXTEND : MBT_PASTE; + b = MBT_RIGHT; term_mouse(b, MA_DRAG, TO_CHR_X(X_POS(lParam)), TO_CHR_Y(Y_POS(lParam)), wParam & MK_SHIFT, wParam & MK_CONTROL); @@ -1626,12 +1667,16 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, pending_netevent = TRUE; pend_netevent_wParam = wParam; pend_netevent_lParam = lParam; + if (WSAGETSELECTEVENT(lParam) != FD_READ) + enact_pending_netevent(); + time(&last_movement); return 0; case WM_SETFOCUS: has_focus = TRUE; CreateCaret(hwnd, caretbm, font_width, font_height); ShowCaret(hwnd); + flash_window(0); /* stop */ compose_state = 0; term_out(); term_update(); @@ -1834,10 +1879,19 @@ 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); - if (len > 0) + if (len != 0) { + /* + * We need not bother about stdin backlogs + * here, because in GUI PuTTY we can't do + * anything about it anyway; there's no means + * of asking Windows to hold off on KEYDOWN + * messages. We _have_ to buffer everything + * we're sent. + */ + ldisc_send(buf, len); show_mouseptr(0); + } } } return 0; @@ -1856,6 +1910,31 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, kbd_codepage = atoi(lbuf); } break; + case WM_IME_COMPOSITION: + { + HIMC hIMC; + int n; + char *buff; + + if(osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS || + osVersion.dwPlatformId == VER_PLATFORM_WIN32s) break; /* no Unicode */ + + if ((lParam & GCS_RESULTSTR) == 0) /* Composition unfinished. */ + break; /* fall back to DefWindowProc */ + + hIMC = ImmGetContext(hwnd); + n = ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, NULL, 0); + + if (n > 0) { + buff = (char*) smalloc(n); + ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, n); + luni_send((unsigned short *)buff, n / 2); + free(buff); + } + ImmReleaseContext(hwnd, hIMC); + return 1; + } + case WM_IME_CHAR: if (wParam & 0xFF00) { unsigned char buf[2]; @@ -1899,8 +1978,27 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, */ void sys_cursor(int x, int y) { - if (has_focus) - SetCaretPos(x * font_width, y * font_height); + COMPOSITIONFORM cf; + HIMC hIMC; + + if (!has_focus) return; + + SetCaretPos(x * font_width, y * font_height); + + /* IMM calls on Win98 and beyond only */ + if(osVersion.dwPlatformId == VER_PLATFORM_WIN32s) return; /* 3.11 */ + + if(osVersion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && + osVersion.dwMinorVersion == 0) return; /* 95 */ + + /* we should have the IMM functions */ + hIMC = ImmGetContext(hwnd); + cf.dwStyle = CFS_POINT; + cf.ptCurrentPos.x = x * font_width; + cf.ptCurrentPos.y = y * font_height; + ImmSetCompositionWindow(hIMC, &cf); + + ImmReleaseContext(hwnd, hIMC); } /* @@ -2211,7 +2309,6 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, int scan, left_alt = 0, key_down, shift_state; int r, i, code; unsigned char *p = output; - static int alt_state = 0; static int alt_sum = 0; HKL kbd_layout = GetKeyboardLayout(0); @@ -2445,16 +2542,13 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, return 0; } if (wParam == VK_INSERT && shift_state == 1) { - term_mouse(MBT_PASTE, MA_CLICK, 0, 0, 0, 0); - term_mouse(MBT_PASTE, MA_RELEASE, 0, 0, 0, 0); + term_do_paste(); return 0; } if (left_alt && wParam == VK_F4 && cfg.alt_f4) { return -1; } if (left_alt && wParam == VK_SPACE && cfg.alt_space) { - alt_state = 0; - PostMessage(hwnd, WM_CHAR, ' ', 0); SendMessage(hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0); return -1; } @@ -2714,6 +2808,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, case VK_F20: code = 34; break; + } + if ((shift_state&2) == 0) switch (wParam) { case VK_HOME: code = 1; break; @@ -2742,7 +2838,8 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, return p - output; } - if (cfg.funky_type == 5 && code >= 11 && code <= 34) { + if (cfg.funky_type == 5 && /* SCO function keys */ + code >= 11 && code <= 34) { char codes[] = "MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@[\\]^_`{"; int index = 0; switch (wParam) { @@ -2764,6 +2861,16 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, p += sprintf((char *) p, "\x1B[%c", codes[index]); return p - output; } + if (cfg.funky_type == 5 && /* SCO small keypad */ + code >= 1 && code <= 6) { + char codes[] = "HL.FIG"; + if (code == 3) { + *p++ = '\x7F'; + } else { + p += sprintf((char *) p, "\x1B[%c", codes[code-1]); + } + return p - output; + } if ((vt52_mode || cfg.funky_type == 4) && code >= 11 && code <= 24) { int offt = 0; if (code > 15) @@ -2866,7 +2973,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, #ifdef SHOW_TOASCII_RESULT if (r == 1 && !key_down) { if (alt_sum) { - if (utf || dbcs_screenfont) + if (in_utf || dbcs_screenfont) debug((", (U+%04x)", alt_sum)); else debug((", LCH(%d)", alt_sum)); @@ -2910,11 +3017,20 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, if (!key_down) { if (alt_sum) { - if (utf || dbcs_screenfont) { + if (in_utf || dbcs_screenfont) { keybuf = alt_sum; luni_send(&keybuf, 1); } else { ch = (char) alt_sum; + /* + * We need not bother about stdin + * backlogs here, because in GUI PuTTY + * we can't do anything about it + * anyway; there's no means of asking + * Windows to hold off on KEYDOWN + * messages. We _have_ to buffer + * everything we're sent. + */ ldisc_send(&ch, 1); } alt_sum = 0; @@ -2926,6 +3042,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, lpage_send(kbd_codepage, cbuf + !left_alt, 1 + !!left_alt); } + show_mouseptr(0); } /* This is so the ALT-Numpad and dead keys work correctly. */ @@ -2937,23 +3054,19 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, if (!left_alt) keys[0] = 0; /* If we will be using alt_sum fix the 256s */ - else if (keys[0] && (utf || dbcs_screenfont)) + else if (keys[0] && (in_utf || dbcs_screenfont)) keys[0] = 10; } - /* ALT alone may or may not want to bring up the System menu */ - if (wParam == VK_MENU) { - if (cfg.alt_only) { - 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; - } else - alt_state = 0; + /* + * ALT alone may or may not want to bring up the System menu. + * If it's not meant to, we return 0 on presses or releases of + * ALT, to show that we've swallowed the keystroke. Otherwise + * we return -1, which means Windows will give the keystroke + * its default handling (i.e. bring up the System menu). + */ + if (wParam == VK_MENU && !cfg.alt_only) + return 0; return -1; } @@ -3165,7 +3278,7 @@ void get_clip(wchar_t ** p, int *len) clipdata = NULL; return; } else if (OpenClipboard(NULL)) { - if (clipdata = GetClipboardData(CF_UNICODETEXT)) { + if ((clipdata = GetClipboardData(CF_UNICODETEXT))) { CloseClipboard(); *p = GlobalLock(clipdata); if (*p) { @@ -3173,7 +3286,7 @@ void get_clip(wchar_t ** p, int *len) *len = p2 - *p; return; } - } else if (clipdata = GetClipboardData(CF_TEXT)) { + } else if ( (clipdata = GetClipboardData(CF_TEXT)) ) { char *s; int i; CloseClipboard(); @@ -3228,6 +3341,42 @@ void fatalbox(char *fmt, ...) } /* + * Manage window caption / taskbar flashing, if enabled. + * 0 = stop, 1 = maintain, 2 = start + */ +static void flash_window(int mode) +{ + static long last_flash = 0; + static int flashing = 0; + if ((mode == 0) || (cfg.beep_ind == B_IND_DISABLED)) { + /* stop */ + if (flashing) { + FlashWindow(hwnd, FALSE); + flashing = 0; + } + + } else if (mode == 2) { + /* start */ + if (!flashing) { + last_flash = GetTickCount(); + flashing = 1; + FlashWindow(hwnd, TRUE); + } + + } else if ((mode == 1) && (cfg.beep_ind == B_IND_FLASH)) { + /* maintain */ + if (flashing) { + long now = GetTickCount(); + long fdiff = now - last_flash; + if (fdiff < 0 || fdiff > 450) { + last_flash = now; + FlashWindow(hwnd, TRUE); /* toggle */ + } + } + } +} + +/* * Beep. */ void beep(int mode) @@ -3261,4 +3410,8 @@ void beep(int mode) cfg.beep = BELL_DEFAULT; } } + /* Otherwise, either visual bell or disabled; do nothing here */ + if (!has_focus) { + flash_window(2); /* start */ + } }