X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/74086be00836c578aa8e79f29006c3963043616b..5fd70d0768f86274b22e73f3cd8f59fec0325e36:/windows/window.c diff --git a/windows/window.c b/windows/window.c index a0a52685..8d13ff91 100644 --- a/windows/window.c +++ b/windows/window.c @@ -168,14 +168,15 @@ struct agent_callback { #define FONT_OEMUND 0x22 #define FONT_OEMBOLDUND 0x23 -#define FONT_MAXNO 0x2F +#define FONT_MAXNO 0x40 #define FONT_SHIFT 5 static HFONT fonts[FONT_MAXNO]; static LOGFONT lfont; static int fontflag[FONT_MAXNO]; static enum { - BOLD_COLOURS, BOLD_SHADOW, BOLD_FONT -} bold_mode; + BOLD_NONE, BOLD_SHADOW, BOLD_FONT +} bold_font_mode; +static int bold_colours; static enum { UND_LINE, UND_FONT } und_mode; @@ -616,10 +617,21 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } } - /* - * Trim off a colon suffix if it's there. - */ - host[strcspn(host, ":")] = '\0'; + /* + * Trim a colon suffix off the hostname if it's there. In + * order to protect IPv6 address literals against this + * treatment, we do not do this if there's _more_ than one + * colon. + */ + { + char *c = strchr(host, ':'); + + if (c) { + char *d = strchr(c+1, ':'); + if (!d) + *c = '\0'; + } + } /* * Remove any remaining whitespace. @@ -1409,8 +1421,9 @@ static void init_fonts(int pick_width, int pick_height) for (i = 0; i < FONT_MAXNO; i++) fonts[i] = NULL; - bold_mode = conf_get_int(conf, CONF_bold_colour) ? - BOLD_COLOURS : BOLD_FONT; + bold_font_mode = conf_get_int(conf, CONF_bold_style) & 1 ? + BOLD_FONT : BOLD_NONE; + bold_colours = conf_get_int(conf, CONF_bold_style) & 2 ? TRUE : FALSE; und_mode = UND_FONT; font = conf_get_fontspec(conf, CONF_font); @@ -1535,7 +1548,7 @@ static void init_fonts(int pick_width, int pick_height) } } - if (bold_mode == BOLD_FONT) { + if (bold_font_mode == BOLD_FONT) { f(FONT_BOLD, font->charset, fw_bold, FALSE); } #undef f @@ -1562,9 +1575,9 @@ static void init_fonts(int pick_width, int pick_height) fonts[FONT_UNDERLINE] = 0; } - if (bold_mode == BOLD_FONT && + if (bold_font_mode == BOLD_FONT && fontsize[FONT_BOLD] != fontsize[FONT_NORMAL]) { - bold_mode = BOLD_SHADOW; + bold_font_mode = BOLD_SHADOW; DeleteObject(fonts[FONT_BOLD]); fonts[FONT_BOLD] = 0; } @@ -2010,10 +2023,14 @@ void notify_remote_exit(void *fe) } } -void timer_change_notify(long next) +void timer_change_notify(unsigned long next) { - long ticks = next - GETTICKCOUNT(); - if (ticks <= 0) ticks = 1; /* just in case */ + unsigned long now = GETTICKCOUNT(); + long ticks; + if (now - next < INT_MAX) + ticks = 0; + else + ticks = next - now; KillTimer(hwnd, TIMING_TIMER_ID); SetTimer(hwnd, TIMING_TIMER_ID, ticks, NULL); timing_next_time = next; @@ -2040,7 +2057,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, switch (message) { case WM_TIMER: if ((UINT_PTR)wParam == TIMING_TIMER_ID) { - long next; + unsigned long next; KillTimer(hwnd, TIMING_TIMER_ID); if (run_timers(timing_next_time, &next)) { @@ -2150,6 +2167,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, si.lpReserved2 = NULL; CreateProcess(b, cl, NULL, NULL, inherit_handles, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); if (filemap) CloseHandle(filemap); @@ -2189,8 +2208,10 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, reconfig_result = do_reconfig(hwnd, back ? back->cfg_info(backhandle) : 0); reconfiguring = FALSE; - if (!reconfig_result) + if (!reconfig_result) { + conf_free(prev_conf); break; + } conf_cache_data(); @@ -2333,8 +2354,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, conf_get_int(prev_conf, CONF_font_quality) || conf_get_int(conf, CONF_vtmode) != conf_get_int(prev_conf, CONF_vtmode) || - conf_get_int(conf, CONF_bold_colour) != - conf_get_int(prev_conf, CONF_bold_colour) || + conf_get_int(conf, CONF_bold_style) != + conf_get_int(prev_conf, CONF_bold_style) || resize_action == RESIZE_DISABLED || resize_action == RESIZE_EITHER || resize_action != conf_get_int(prev_conf, @@ -2986,7 +3007,19 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, break; case SB_THUMBPOSITION: case SB_THUMBTRACK: - term_scroll(term, 1, HIWORD(wParam)); + /* + * Use GetScrollInfo instead of HIWORD(wParam) to get + * 32-bit scroll position. + */ + { + SCROLLINFO si; + + si.cbSize = sizeof(si); + si.fMask = SIF_TRACKPOS; + if (GetScrollInfo(hwnd, SB_VERT, &si) == 0) + si.nTrackPos = HIWORD(wParam); + term_scroll(term, 1, si.nTrackPos); + } break; } break; @@ -3215,8 +3248,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, } else break; - if (send_raw_mouse && shift_pressed && - !(conf_get_int(conf, CONF_mouse_override))) { + if (send_raw_mouse && + !(conf_get_int(conf, CONF_mouse_override) && + shift_pressed)) { /* Mouse wheel position is in screen coordinates for * some reason */ POINT p; @@ -3323,6 +3357,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, int text_adjust = 0; int xoffset = 0; int maxlen, remaining, opaque; + int is_cursor = FALSE; static int *lpDx = NULL; static int lpDx_len = 0; int *lpDx_maybe; @@ -3346,11 +3381,9 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, if ((attr & TATTR_ACTCURS) && (cursor_type == 0 || term->big_cursor)) { attr &= ~(ATTR_REVERSE|ATTR_BLINK|ATTR_COLOURS); - if (bold_mode == BOLD_COLOURS) - attr &= ~ATTR_BOLD; - /* cursor fg and bg */ attr |= (260 << ATTR_FGSHIFT) | (261 << ATTR_BGSHIFT); + is_cursor = TRUE; } nfont = 0; @@ -3412,7 +3445,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, nfg = ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT); nbg = ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT); - if (bold_mode == BOLD_FONT && (attr & ATTR_BOLD)) + if (bold_font_mode == BOLD_FONT && (attr & ATTR_BOLD)) nfont |= FONT_BOLD; if (und_mode == UND_FONT && (attr & ATTR_UNDER)) nfont |= FONT_UNDERLINE; @@ -3432,11 +3465,11 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, nfg = nbg; nbg = t; } - if (bold_mode == BOLD_COLOURS && (attr & ATTR_BOLD)) { + if (bold_colours && (attr & ATTR_BOLD) && !is_cursor) { if (nfg < 16) nfg |= 8; else if (nfg >= 256) nfg |= 1; } - if (bold_mode == BOLD_COLOURS && (attr & ATTR_BLINK)) { + if (bold_colours && (attr & ATTR_BLINK)) { if (nbg < 16) nbg |= 8; else if (nbg >= 256) nbg |= 1; } @@ -3586,7 +3619,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0), &line_box, uni_buf, nlen, lpDx_maybe); - if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { + if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { SetBkMode(hdc, TRANSPARENT); ExtTextOutW(hdc, x + xoffset - 1, y - font_height * (lattr == @@ -3611,7 +3644,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, y - font_height * (lattr == LATTR_BOT) + text_adjust, ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0), &line_box, directbuf, len, lpDx_maybe); - if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { + if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { SetBkMode(hdc, TRANSPARENT); /* GRR: This draws the character outside its box and @@ -3650,7 +3683,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, opaque && !(attr & TATTR_COMBINING)); /* And the shadow bold hack. */ - if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { + if (bold_font_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) { SetBkMode(hdc, TRANSPARENT); ExtTextOutW(hdc, x + xoffset - 1, y - font_height * (lattr == @@ -3885,8 +3918,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, HKL kbd_layout = GetKeyboardLayout(0); - /* keys is for ToAsciiEx. There's some ick here, see below. */ - static WORD keys[3]; + static wchar_t keys_unicode[3]; static int compose_char = 0; static WPARAM compose_keycode = 0; @@ -3938,12 +3970,12 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, else if (ch) debug((", $%02x", ch)); - if (keys[0]) - debug((", KB0=%02x", keys[0])); - if (keys[1]) - debug((", KB1=%02x", keys[1])); - if (keys[2]) - debug((", KB2=%02x", keys[2])); + if (keys_unicode[0]) + debug((", KB0=%04x", keys_unicode[0])); + if (keys_unicode[1]) + debug((", KB1=%04x", keys_unicode[1])); + if (keys_unicode[2]) + debug((", KB2=%04x", keys_unicode[2])); if ((keystate[VK_SHIFT] & 0x80) != 0) debug((", S")); @@ -4559,6 +4591,9 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, * be is? There's indication on MS' website of an Inquire/InquireEx * functioning returning a KBINFO structure which tells us. */ if (osVersion.dwPlatformId == VER_PLATFORM_WIN32_NT) { + r = ToUnicodeEx(wParam, scan, keystate, keys_unicode, + lenof(keys_unicode), 0, kbd_layout); + } else { /* XXX 'keys' parameter is declared in MSDN documentation as * 'LPWORD lpChar'. * The experience of a French user indicates that on @@ -4569,12 +4604,17 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, * Win9x/NT split, but I suspect it's worse than that. * See wishlist item `win-dead-keys' for more horrible detail * and speculations. */ - BYTE keybs[3]; int i; - r = ToAsciiEx(wParam, scan, keystate, (LPWORD)keybs, 0, kbd_layout); - for (i=0; i<3; i++) keys[i] = keybs[i]; - } else { + static WORD keys[3]; + static BYTE keysb[3]; r = ToAsciiEx(wParam, scan, keystate, keys, 0, kbd_layout); + if (r > 0) { + for (i = 0; i < r; i++) { + keysb[i] = (BYTE)keys[i]; + } + MultiByteToWideChar(CP_ACP, 0, (LPCSTR)keysb, r, + keys_unicode, lenof(keys_unicode)); + } } #ifdef SHOW_TOASCII_RESULT if (r == 1 && !key_down) { @@ -4584,13 +4624,13 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, else debug((", LCH(%d)", alt_sum)); } else { - debug((", ACH(%d)", keys[0])); + debug((", ACH(%d)", keys_unicode[0])); } } else if (r > 0) { int r1; debug((", ASC(")); for (r1 = 0; r1 < r; r1++) { - debug(("%s%d", r1 ? "," : "", keys[r1])); + debug(("%s%d", r1 ? "," : "", keys_unicode[r1])); } debug((")")); } @@ -4607,18 +4647,18 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, p = output; for (i = 0; i < r; i++) { - unsigned char ch = (unsigned char) keys[i]; + wchar_t wch = keys_unicode[i]; - if (compose_state == 2 && (ch & 0x80) == 0 && ch > ' ') { - compose_char = ch; + if (compose_state == 2 && wch >= ' ' && wch < 0x80) { + compose_char = wch; compose_state++; continue; } - if (compose_state == 3 && (ch & 0x80) == 0 && ch > ' ') { + if (compose_state == 3 && wch >= ' ' && wch < 0x80) { int nc; compose_state = 0; - if ((nc = check_compose(compose_char, ch)) == -1) { + if ((nc = check_compose(compose_char, wch)) == -1) { MessageBeep(MB_ICONHAND); return 0; } @@ -4639,7 +4679,7 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, if (ldisc) luni_send(ldisc, &keybuf, 1, 1); } else { - ch = (char) alt_sum; + char ch = (char) alt_sum; /* * We need not bother about stdin * backlogs here, because in GUI PuTTY @@ -4657,40 +4697,39 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam, } else { term_seen_key_event(term); if (ldisc) - lpage_send(ldisc, kbd_codepage, &ch, 1, 1); + luni_send(ldisc, &wch, 1, 1); } } else { - if(capsOn && ch < 0x80) { + if(capsOn && wch < 0x80) { WCHAR cbuf[2]; cbuf[0] = 27; - cbuf[1] = xlat_uskbd2cyrllic(ch); + cbuf[1] = xlat_uskbd2cyrllic(wch); term_seen_key_event(term); if (ldisc) luni_send(ldisc, cbuf+!left_alt, 1+!!left_alt, 1); } else { - char cbuf[2]; + WCHAR cbuf[2]; cbuf[0] = '\033'; - cbuf[1] = ch; + cbuf[1] = wch; term_seen_key_event(term); if (ldisc) - lpage_send(ldisc, kbd_codepage, - cbuf+!left_alt, 1+!!left_alt, 1); + luni_send(ldisc, cbuf +!left_alt, 1+!!left_alt, 1); } } show_mouseptr(0); } /* This is so the ALT-Numpad and dead keys work correctly. */ - keys[0] = 0; + keys_unicode[0] = 0; return p - output; } /* If we're definitly not building up an ALT-54321 then clear it */ if (!left_alt) - keys[0] = 0; + keys_unicode[0] = 0; /* If we will be using alt_sum fix the 256s */ - else if (keys[0] && (in_utf(term) || ucsdata.dbcs_screenfont)) - keys[0] = 10; + else if (keys_unicode[0] && (in_utf(term) || ucsdata.dbcs_screenfont)) + keys_unicode[0] = 10; } /* @@ -4777,7 +4816,7 @@ void palette_set(void *frontend, int n, int r, int g, int b) { if (n >= 16) n += 256 - 16; - if (n > NALLCOLOURS) + if (n >= NALLCOLOURS) return; real_palette_set(n, r, g, b); if (pal) { @@ -4877,10 +4916,17 @@ void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_des GlobalFree(clipdata2); return; } - if (!(lock = GlobalLock(clipdata))) + if (!(lock = GlobalLock(clipdata))) { + GlobalFree(clipdata); + GlobalFree(clipdata2); return; - if (!(lock2 = GlobalLock(clipdata2))) + } + if (!(lock2 = GlobalLock(clipdata2))) { + GlobalUnlock(clipdata); + GlobalFree(clipdata); + GlobalFree(clipdata2); return; + } memcpy(lock, data, len * sizeof(wchar_t)); WideCharToMultiByte(CP_ACP, 0, data, len, lock2, len2, NULL, NULL); @@ -4930,7 +4976,7 @@ void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_des bgcolour = tmpcolour; } - if (bold_mode == BOLD_COLOURS && (attr[i] & ATTR_BOLD)) { + if (bold_colours && (attr[i] & ATTR_BOLD)) { if (fgcolour < 8) /* ANSI colours */ fgcolour += 8; else if (fgcolour >= 256) /* Default colours */ @@ -5021,7 +5067,7 @@ void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_des bgcolour = tmpcolour; } - if (bold_mode == BOLD_COLOURS && (attr[tindex] & ATTR_BOLD)) { + if (bold_colours && (attr[tindex] & ATTR_BOLD)) { if (fgcolour < 8) /* ANSI colours */ fgcolour += 8; else if (fgcolour >= 256) /* Default colours */ @@ -5038,7 +5084,7 @@ void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_des /* * Collect other attributes */ - if (bold_mode != BOLD_COLOURS) + if (bold_font_mode != BOLD_NONE) attrBold = attr[tindex] & ATTR_BOLD; else attrBold = 0; @@ -5057,7 +5103,7 @@ void write_clip(void *frontend, wchar_t * data, int *attr, int len, int must_des bgcolour = -1; /* No coloring */ if (fgcolour >= 256) { /* Default colour */ - if (bold_mode == BOLD_COLOURS && (fgcolour & 1) && bgcolour == -1) + if (bold_colours && (fgcolour & 1) && bgcolour == -1) attrBold = ATTR_BOLD; /* Emphasize text with bold attribute */ fgcolour = -1; /* No coloring */ @@ -5322,6 +5368,22 @@ void modalfatalbox(char *fmt, ...) cleanup_exit(1); } +/* + * Print a message box and don't close the connection. + */ +void nonfatal(char *fmt, ...) +{ + va_list ap; + char *stuff, morestuff[100]; + + va_start(ap, fmt); + stuff = dupvprintf(fmt, ap); + va_end(ap); + sprintf(morestuff, "%.70s Error", appname); + MessageBox(hwnd, stuff, morestuff, MB_ICONERROR | MB_OK); + sfree(stuff); +} + DECL_WINDOWS_FUNCTION(static, BOOL, FlashWindowEx, (PFLASHWINFO)); static void init_flashwindow(void) @@ -5353,9 +5415,9 @@ static int flashing = 0; * Timer for platforms where we must maintain window flashing manually * (e.g., Win95). */ -static void flash_window_timer(void *ctx, long now) +static void flash_window_timer(void *ctx, unsigned long now) { - if (flashing && now - next_flash >= 0) { + if (flashing && now == next_flash) { flash_window(1); } }