X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/ebe8092cc3f471e782af299699284e9142f11696..5fd70d0768f86274b22e73f3cd8f59fec0325e36:/windows/window.c diff --git a/windows/window.c b/windows/window.c index da0d3d48..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; @@ -206,6 +207,12 @@ static int compose_state = 0; static UINT wm_mousewheel = WM_MOUSEWHEEL; +#define IS_HIGH_VARSEL(wch1, wch2) \ + ((wch1) == 0xDB40 && ((wch2) >= 0xDD00 && (wch2) <= 0xDDEF)) +#define IS_LOW_VARSEL(wch) \ + (((wch) >= 0x180B && (wch) <= 0x180D) || /* MONGOLIAN FREE VARIATION SELECTOR */ \ + ((wch) >= 0xFE00 && (wch) <= 0xFE0F)) /* VARIATION SELECTOR 1-16 */ + /* Dummy routine, only required in plink. */ void ldisc_update(void *frontend, int echo, int edit) { @@ -445,7 +452,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) HANDLE filemap; void *cp; unsigned cpsize; - if (sscanf(p + 1, "%p:%u", &filemap, &cpsize) == 1 && + if (sscanf(p + 1, "%p:%u", &filemap, &cpsize) == 2 && (cp = MapViewOfFile(filemap, FILE_MAP_READ, 0, 0, cpsize)) != NULL) { conf_deserialise(conf, cp, cpsize); @@ -610,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. @@ -693,6 +711,12 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } /* + * Initialise the fonts, simultaneously correcting the guesses + * for font_{width,height}. + */ + init_fonts(0,0); + + /* * Initialise the terminal. (We have to do this _after_ * creating the window, since the terminal is the first thing * which will call schedule_timer(), which will in turn call @@ -706,12 +730,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) conf_get_int(conf, CONF_savelines)); /* - * Initialise the fonts, simultaneously correcting the guesses - * for font_{width,height}. - */ - init_fonts(0,0); - - /* * Correct the guesses for extra_{width,height}. */ { @@ -1403,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); @@ -1433,7 +1452,7 @@ static void init_fonts(int pick_width, int pick_height) #define f(i,c,w,u) \ fonts[i] = CreateFont (font_height, font_width, 0, 0, w, FALSE, u, FALSE, \ c, OUT_DEFAULT_PRECIS, \ - CLIP_DEFAULT_PRECIS, quality, \ + CLIP_DEFAULT_PRECIS, FONT_QUALITY(quality), \ FIXED_PITCH | FF_DONTCARE, font->name) f(FONT_NORMAL, font->charset, fw_dontcare, FALSE); @@ -1529,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 @@ -1556,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; } @@ -2004,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; @@ -2034,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)) { @@ -2144,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); @@ -2183,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(); @@ -2315,7 +2342,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, { FontSpec *font = conf_get_fontspec(conf, CONF_font); FontSpec *prev_font = conf_get_fontspec(prev_conf, - CONF_font); + CONF_font); if (!strcmp(font->name, prev_font->name) || !strcmp(conf_get_str(conf, CONF_line_codepage), @@ -2327,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, @@ -2899,7 +2926,21 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, h = height / font_height; if (h < 1) h = 1; - term_size(term, h, w, conf_get_int(conf, CONF_savelines)); + if (resizing) { + /* + * As below, if we're in the middle of an + * interactive resize we don't call + * back->size. In Windows 7, this case can + * arise in maximisation as well via the Aero + * snap UI. + */ + need_backend_resize = TRUE; + conf_set_int(conf, CONF_height, h); + conf_set_int(conf, CONF_width, w); + } else { + term_size(term, h, w, + conf_get_int(conf, CONF_savelines)); + } } reset_window(0); } else if (wParam == SIZE_RESTORED && was_zoomed) { @@ -2934,7 +2975,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, */ need_backend_resize = TRUE; conf_set_int(conf, CONF_height, h); - conf_set_int(conf, CONF_height, w); + conf_set_int(conf, CONF_width, w); } else { term_size(term, h, w, conf_get_int(conf, CONF_savelines)); } @@ -2966,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; @@ -3091,9 +3144,20 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, * instead we luni_send the characters one by one. */ term_seen_key_event(term); - for (i = 0; i < n; i += 2) { - if (ldisc) + /* don't divide SURROGATE PAIR */ + if (ldisc) { + for (i = 0; i < n; i += 2) { + WCHAR hs = *(unsigned short *)(buff+i); + if (IS_HIGH_SURROGATE(hs) && i+2 < n) { + WCHAR ls = *(unsigned short *)(buff+i+2); + if (IS_LOW_SURROGATE(ls)) { + luni_send(ldisc, (unsigned short *)(buff+i), 2, 1); + i += 2; + continue; + } + } luni_send(ldisc, (unsigned short *)(buff+i), 1, 1); + } } free(buff); } @@ -3184,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; @@ -3292,9 +3357,11 @@ 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; + int len2; /* for SURROGATE PAIR */ lattr &= LATTR_MODE; @@ -3314,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; @@ -3339,6 +3404,7 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, if (attr & ATTR_NARROW) nfont |= FONT_NARROW; +#ifdef USES_VTLINE_HACK /* Special hack for the VT100 linedraw glyphs. */ if (text[0] >= 0x23BA && text[0] <= 0x23BD) { switch ((unsigned char) (text[0])) { @@ -3363,9 +3429,11 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, force_manual_underline = 1; } } +#endif /* Anything left as an original character set is unprintable. */ - if (DIRECT_CHAR(text[0])) { + if (DIRECT_CHAR(text[0]) && + (len < 2 || !IS_SURROGATE_PAIR(text[0], text[1]))) { int i; for (i = 0; i < len; i++) text[i] = 0xFFFD; @@ -3377,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; @@ -3397,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; } @@ -3418,6 +3486,24 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, line_box.top = y; line_box.right = x + char_width * len; line_box.bottom = y + font_height; + /* adjust line_box.right for SURROGATE PAIR & VARIATION SELECTOR */ + { + int i; + int rc_width = 0; + for (i = 0; i < len ; i++) { + if (i+1 < len && IS_HIGH_VARSEL(text[i], text[i+1])) { + i++; + } else if (i+1 < len && IS_SURROGATE_PAIR(text[i], text[i+1])) { + rc_width += char_width; + i++; + } else if (IS_LOW_VARSEL(text[i])) { + /* do nothing */ + } else { + rc_width += char_width; + } + } + line_box.right = line_box.left + rc_width; + } /* Only want the left half of double width lines */ if (line_box.right > font_width*term->cols+offset_width) @@ -3448,19 +3534,47 @@ void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len, opaque = TRUE; /* start by erasing the rectangle */ for (remaining = len; remaining > 0; - text += len, remaining -= len, x += char_width * len) { + text += len, remaining -= len, x += char_width * len2) { len = (maxlen < remaining ? maxlen : remaining); - - if (len > lpDx_len) { - if (len > lpDx_len) { - lpDx_len = len * 9 / 8 + 16; - lpDx = sresize(lpDx, lpDx_len, int); - } + /* don't divide SURROGATE PAIR and VARIATION SELECTOR */ + len2 = len; + if (maxlen == 1) { + if (remaining >= 1 && IS_SURROGATE_PAIR(text[0], text[1])) + len++; + if (remaining-len >= 1 && IS_LOW_VARSEL(text[len])) + len++; + else if (remaining-len >= 2 && + IS_HIGH_VARSEL(text[len], text[len+1])) + len += 2; } + + if (len > lpDx_len) { + lpDx_len = len * 9 / 8 + 16; + lpDx = sresize(lpDx, lpDx_len, int); + + if (lpDx_maybe) lpDx_maybe = lpDx; + } + { int i; - for (i = 0; i < len; i++) + /* only last char has dx width in SURROGATE PAIR and + * VARIATION sequence */ + for (i = 0; i < len; i++) { lpDx[i] = char_width; + if (i+1 < len && IS_HIGH_VARSEL(text[i], text[i+1])) { + if (i > 0) lpDx[i-1] = 0; + lpDx[i] = 0; + i++; + lpDx[i] = char_width; + } else if (i+1 < len && IS_SURROGATE_PAIR(text[i],text[i+1])) { + lpDx[i] = 0; + i++; + lpDx[i] = char_width; + } else if (IS_LOW_VARSEL(text[i])) { + if (i > 0) lpDx[i-1] = 0; + lpDx[i] = char_width; + } + } } /* We're using a private area for direct to font. (512 chars.) */ @@ -3505,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 == @@ -3530,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 @@ -3569,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 == @@ -3609,9 +3723,35 @@ void do_text(Context ctx, int x, int y, wchar_t *text, int len, { if (attr & TATTR_COMBINING) { unsigned long a = 0; - attr &= ~TATTR_COMBINING; + int len0 = 1; + /* don't divide SURROGATE PAIR and VARIATION SELECTOR */ + if (len >= 2 && IS_SURROGATE_PAIR(text[0], text[1])) + len0 = 2; + if (len-len0 >= 1 && IS_LOW_VARSEL(text[len0])) { + attr &= ~TATTR_COMBINING; + do_text_internal(ctx, x, y, text, len0+1, attr, lattr); + text += len0+1; + len -= len0+1; + a = TATTR_COMBINING; + } else if (len-len0 >= 2 && IS_HIGH_VARSEL(text[len0], text[len0+1])) { + attr &= ~TATTR_COMBINING; + do_text_internal(ctx, x, y, text, len0+2, attr, lattr); + text += len0+2; + len -= len0+2; + a = TATTR_COMBINING; + } else { + attr &= ~TATTR_COMBINING; + } + while (len--) { - do_text_internal(ctx, x, y, text, 1, attr | a, lattr); + if (len >= 1 && IS_SURROGATE_PAIR(text[0], text[1])) { + do_text_internal(ctx, x, y, text, 2, attr | a, lattr); + len--; + text++; + } else { + do_text_internal(ctx, x, y, text, 1, attr | a, lattr); + } + text++; a = TATTR_COMBINING; } @@ -3778,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; @@ -3831,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")); @@ -4452,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 @@ -4462,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) { @@ -4477,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((")")); } @@ -4500,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; } @@ -4532,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 @@ -4550,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; } /* @@ -4670,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) { @@ -4770,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); @@ -4823,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 */ @@ -4914,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 */ @@ -4931,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; @@ -4950,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 */ @@ -5215,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) @@ -5246,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); } } @@ -5612,6 +5781,11 @@ int from_backend_untrusted(void *frontend, const char *data, int len) return term_data_untrusted(term, data, len); } +int from_backend_eof(void *frontend) +{ + return TRUE; /* do respond to incoming EOF with outgoing */ +} + int get_userpass_input(prompts_t *p, unsigned char *in, int inlen) { int ret;