#define VK_PROCESSKEY 0xE5
#endif
+/* Needed for mouse wheel support and not defined in earlier SDKs. */
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x020A
+#endif
+
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
unsigned char *output);
static void cfgtopalette(void);
static void init_palette(void);
static void init_fonts(int);
+static void another_font(int);
+static void deinit_fonts(void);
static int extra_width, extra_height;
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;
#define FONT_BOLD 1
#define FONT_UNDERLINE 2
#define FONT_BOLDUND 3
-#define FONT_OEM 4
-#define FONT_OEMBOLD 5
-#define FONT_OEMBOLDUND 6
-#define FONT_OEMUND 7
-static HFONT fonts[8];
-static int font_needs_hand_underlining;
+#define FONT_WIDE 0x04
+#define FONT_HIGH 0x08
+#define FONT_NARROW 0x10
+#define FONT_OEM 0x20
+#define FONT_OEMBOLD 0x21
+#define FONT_OEMUND 0x22
+#define FONT_OEMBOLDUND 0x23
+#define FONT_MSGOTHIC 0x40
+#define FONT_MINGLIU 0x60
+#define FONT_GULIMCHE 0x80
+#define FONT_MAXNO 0x8F
+#define FONT_SHIFT 5
+static HFONT fonts[FONT_MAXNO];
+static int fontflag[FONT_MAXNO];
static enum {
BOLD_COLOURS, BOLD_SHADOW, BOLD_FONT
} bold_mode;
static int compose_state = 0;
+static OSVERSIONINFO osVersion;
+
/* Dummy routine, only required in plink. */
void ldisc_update(int echo, int edit)
{
* 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.
*/
}
}
+ /*
+ * 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, '@');
* Finally show the window!
*/
ShowWindow(hwnd, show);
+ SetForegroundWindow(hwnd);
/*
* Open the initial log file if there is one.
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;
/*
* Clean up.
*/
- {
- int i;
- for (i = 0; i < 8; i++)
- if (fonts[i])
- DeleteObject(fonts[i]);
- }
+ deinit_fonts();
sfree(logpal);
if (pal)
DeleteObject(pal);
int msg, events;
if (startup) {
msg = WM_NETEVENT;
- events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE;
+ events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE | FD_ACCEPT;
} else {
msg = events = 0;
}
}
/*
- * Initialise all the fonts we will need. There may be as many as
- * eight or as few as one. We also:
+ * Initialise all the fonts we will need initially. There may be as many as
+ * three or as few as one. The other (poentially) twentyone fonts are done
+ * if/when they are needed.
+ *
+ * We also:
*
* - check the font width and height, correcting our guesses if
* necessary.
static void init_fonts(int pick_width)
{
TEXTMETRIC tm;
+ CPINFO cpinfo;
+ int fontsize[3];
int i;
- int fsize[8];
HDC hdc;
int fw_dontcare, fw_bold;
- int firstchar = ' ';
-#ifdef CHECKOEMFONT
- font_messup:
-#endif
- for (i = 0; i < 8; i++)
+ for (i = 0; i < FONT_MAXNO; i++)
fonts[i] = NULL;
if (cfg.fontisbold) {
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \
FIXED_PITCH | FF_DONTCARE, cfg.font)
- if (cfg.vtmode != VT_OEMONLY) {
- f(FONT_NORMAL, cfg.fontcharset, fw_dontcare, FALSE);
+ f(FONT_NORMAL, cfg.fontcharset, fw_dontcare, FALSE);
- SelectObject(hdc, fonts[FONT_NORMAL]);
- GetTextMetrics(hdc, &tm);
- font_height = tm.tmHeight;
- font_width = tm.tmAveCharWidth;
+ SelectObject(hdc, fonts[FONT_NORMAL]);
+ GetTextMetrics(hdc, &tm);
+ font_height = tm.tmHeight;
+ font_width = tm.tmAveCharWidth;
- f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE);
+ {
+ CHARSETINFO info;
+ DWORD cset = tm.tmCharSet;
+ memset(&info, 0xFF, sizeof(info));
- /*
- * 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;
- }
+ /* !!! Yes the next line is right */
+ if (cset == OEM_CHARSET)
+ font_codepage = GetOEMCP();
+ else
+ if (TranslateCharsetInfo
+ ((DWORD *) cset, &info, TCI_SRCCHARSET)) font_codepage =
+ info.ciACP;
+ else
+ font_codepage = -1;
- if (bold_mode == BOLD_FONT) {
- f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE);
- f(FONT_BOLDUND, cfg.fontcharset, fw_bold, TRUE);
- }
+ GetCPInfo(font_codepage, &cpinfo);
+ dbcs_screenfont = (cpinfo.MaxCharSize > 1);
+ }
- if (cfg.vtmode == VT_OEMANSI) {
- f(FONT_OEM, OEM_CHARSET, fw_dontcare, FALSE);
- f(FONT_OEMUND, OEM_CHARSET, fw_dontcare, TRUE);
+ f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE);
- if (bold_mode == BOLD_FONT) {
- f(FONT_OEMBOLD, OEM_CHARSET, fw_bold, FALSE);
- f(FONT_OEMBOLDUND, OEM_CHARSET, fw_bold, 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);
+ if (!gotit) {
+ und_mode = UND_LINE;
+ DeleteObject(fonts[FONT_UNDERLINE]);
+ fonts[FONT_UNDERLINE] = 0;
}
- } else {
- f(FONT_OEM, cfg.fontcharset, fw_dontcare, FALSE);
-
- SelectObject(hdc, fonts[FONT_OEM]);
- GetTextMetrics(hdc, &tm);
- font_height = tm.tmHeight;
- font_width = tm.tmAveCharWidth;
-
- f(FONT_OEMUND, cfg.fontcharset, fw_dontcare, TRUE);
+ }
- if (bold_mode == BOLD_FONT) {
- f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE);
- f(FONT_BOLDUND, cfg.fontcharset, fw_bold, TRUE);
- }
+ if (bold_mode == BOLD_FONT) {
+ f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE);
}
#undef f
descent = tm.tmAscent + 1;
if (descent >= font_height)
descent = font_height - 1;
- firstchar = tm.tmFirstChar;
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < 3; i++) {
if (fonts[i]) {
if (SelectObject(hdc, fonts[i]) && GetTextMetrics(hdc, &tm))
- fsize[i] = tm.tmAveCharWidth + 256 * tm.tmHeight;
+ fontsize[i] = tm.tmAveCharWidth + 256 * tm.tmHeight;
else
- fsize[i] = -i;
+ fontsize[i] = -i;
} else
- fsize[i] = -i;
+ fontsize[i] = -i;
}
ReleaseDC(hwnd, hdc);
- /* ... This is wrong in OEM only mode */
- if (fsize[FONT_UNDERLINE] != fsize[FONT_NORMAL] ||
- (bold_mode == BOLD_FONT &&
- fsize[FONT_BOLDUND] != fsize[FONT_BOLD])) {
+ if (fontsize[FONT_UNDERLINE] != fontsize[FONT_NORMAL]) {
und_mode = UND_LINE;
DeleteObject(fonts[FONT_UNDERLINE]);
- if (bold_mode == BOLD_FONT)
- DeleteObject(fonts[FONT_BOLDUND]);
+ fonts[FONT_UNDERLINE] = 0;
}
- if (bold_mode == BOLD_FONT && fsize[FONT_BOLD] != fsize[FONT_NORMAL]) {
+ if (bold_mode == BOLD_FONT &&
+ fontsize[FONT_BOLD] != fontsize[FONT_NORMAL]) {
bold_mode = BOLD_SHADOW;
DeleteObject(fonts[FONT_BOLD]);
- if (und_mode == UND_FONT)
- DeleteObject(fonts[FONT_BOLDUND]);
+ fonts[FONT_BOLD] = 0;
}
-#ifdef CHECKOEMFONT
- /* With the fascist font painting it doesn't matter if the linedraw font
- * isn't exactly the right size anymore so we don't have to check this.
- */
- if (cfg.vtmode == VT_OEMANSI && fsize[FONT_OEM] != fsize[FONT_NORMAL]) {
- if (cfg.fontcharset == OEM_CHARSET) {
- MessageBox(NULL, "The OEM and ANSI versions of this font are\n"
- "different sizes. Using OEM-only mode instead",
- "Font Size Mismatch", MB_ICONINFORMATION | MB_OK);
- cfg.vtmode = VT_OEMONLY;
- } else if (firstchar < ' ') {
- MessageBox(NULL, "The OEM and ANSI versions of this font are\n"
- "different sizes. Using XTerm mode instead",
- "Font Size Mismatch", MB_ICONINFORMATION | MB_OK);
- cfg.vtmode = VT_XWINDOWS;
- } else {
- MessageBox(NULL, "The OEM and ANSI versions of this font are\n"
- "different sizes. Using ISO8859-1 mode instead",
- "Font Size Mismatch", MB_ICONINFORMATION | MB_OK);
- cfg.vtmode = VT_POORMAN;
- }
+ fontflag[0] = fontflag[1] = fontflag[2] = 1;
+
+ init_ucs_tables();
+}
+
+static void another_font(int fontno)
+{
+ int basefont;
+ int fw_dontcare, fw_bold;
+ int c, u, w, x;
+ char *s;
+
+ if (fontno < 0 || fontno >= FONT_MAXNO || fontflag[fontno])
+ return;
+
+ basefont = (fontno & ~(FONT_BOLDUND));
+ if (basefont != fontno && !fontflag[basefont])
+ another_font(basefont);
- for (i = 0; i < 8; i++)
- if (fonts[i])
- DeleteObject(fonts[i]);
- goto font_messup;
+ if (cfg.fontisbold) {
+ fw_dontcare = FW_BOLD;
+ fw_bold = FW_HEAVY;
+ } else {
+ fw_dontcare = FW_DONTCARE;
+ fw_bold = FW_BOLD;
+ }
+
+ c = cfg.fontcharset;
+ w = fw_dontcare;
+ u = FALSE;
+ s = cfg.font;
+ x = font_width;
+
+ if (fontno & FONT_WIDE)
+ x *= 2;
+ if (fontno & FONT_NARROW)
+ x /= 2;
+ if (fontno & FONT_OEM)
+ c = OEM_CHARSET;
+ if (fontno & FONT_BOLD)
+ w = fw_bold;
+ if (fontno & FONT_UNDERLINE)
+ u = TRUE;
+
+ fonts[fontno] =
+ CreateFont(font_height * (1 + !!(fontno & FONT_HIGH)), x, 0, 0, w,
+ FALSE, u, FALSE, c, OUT_DEFAULT_PRECIS,
+ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
+ FIXED_PITCH | FF_DONTCARE, s);
+
+ fontflag[fontno] = 1;
+}
+
+static void deinit_fonts(void)
+{
+ int i;
+ for (i = 0; i < FONT_MAXNO; i++) {
+ if (fonts[i])
+ DeleteObject(fonts[i]);
+ fonts[i] = 0;
+ fontflag[i] = 0;
}
-#endif
}
void request_resize(int w, int h, int refont)
if (IsZoomed(hwnd))
return;
-#ifdef CHECKOEMFONT
- /* Don't do this in OEMANSI, you may get disable messages */
- if (refont && w != cols && (cols == 80 || cols == 132)
- && cfg.vtmode != VT_OEMANSI)
-#else
- if (refont && w != cols && (cols == 80 || cols == 132))
-#endif
- {
+ if (refont && w != cols && (cols == 80 || cols == 132)) {
/* If font width too big for screen should we shrink the font more ? */
if (w == 132)
font_width = ((font_width * cols + w / 2) / w);
else
font_width = 0;
- {
- int i;
- for (i = 0; i < 8; i++)
- if (fonts[i])
- DeleteObject(fonts[i]);
- }
+ deinit_fonts();
bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT;
und_mode = UND_FONT;
init_fonts(font_width);
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)
}
just_reconfigged = TRUE;
- {
- int i;
- for (i = 0; i < 8; i++)
- if (fonts[i])
- DeleteObject(fonts[i]);
- }
+ deinit_fonts();
bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT;
und_mode = UND_FONT;
init_fonts(0);
button = MBT_RIGHT;
press = 0;
break;
+ default:
+ button = press = 0; /* shouldn't happen */
}
show_mouseptr(1);
if (press) {
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);
has_focus = TRUE;
CreateCaret(hwnd, caretbm, font_width, font_height);
ShowCaret(hwnd);
+ flash_window(0); /* stop */
compose_state = 0;
term_out();
term_update();
}
}
return 0;
- case WM_IME_CHAR:
+ case WM_INPUTLANGCHANGE:
{
+ /* wParam == Font number */
+ /* lParam == Locale */
+ char lbuf[20];
+ HKL NewInputLocale = (HKL) lParam;
+
+ // lParam == GetKeyboardLayout(0);
+
+ GetLocaleInfo(LOWORD(NewInputLocale),
+ LOCALE_IDEFAULTANSICODEPAGE, lbuf, sizeof(lbuf));
+
+ 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];
buf[1] = wParam;
buf[0] = wParam >> 8;
- ldisc_send(buf, 2);
+ lpage_send(kbd_codepage, buf, 2);
+ } else {
+ char c = (unsigned char) wParam;
+ lpage_send(kbd_codepage, &c, 1);
}
+ return (0);
case WM_CHAR:
case WM_SYSCHAR:
/*
* we're ready to cope.
*/
{
- char c = xlat_kbd2tty((unsigned char) wParam);
- ldisc_send(&c, 1);
+ char c = (unsigned char)wParam;
+ lpage_send(CP_ACP, &c, 1);
}
return 0;
case WM_SETCURSOR:
*/
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);
}
/*
RECT line_box;
int force_manual_underline = 0;
int fnt_width = font_width * (1 + (lattr != LATTR_NORM));
- static int *IpDx = 0, IpDxLEN = 0;;
+ int char_width = fnt_width;
+ int text_adjust = 0;
+ static int *IpDx = 0, IpDxLEN = 0;
+
+ if (attr & ATTR_WIDE)
+ char_width *= 2;
- if (len > IpDxLEN || IpDx[0] != fnt_width) {
+ if (len > IpDxLEN || IpDx[0] != char_width) {
int i;
if (len > IpDxLEN) {
sfree(IpDx);
IpDxLEN = (len + 16);
}
for (i = 0; i < IpDxLEN; i++)
- IpDx[i] = fnt_width;
+ IpDx[i] = char_width;
}
x *= fnt_width;
y *= font_height;
- if ((attr & ATTR_ACTCURS) && cfg.cursor_type == 0) {
- attr &= (bold_mode == BOLD_COLOURS ? 0x300200 : 0x300300);
+ if ((attr & TATTR_ACTCURS) && (cfg.cursor_type == 0 || big_cursor)) {
+ attr &= ATTR_CUR_AND | (bold_mode != BOLD_COLOURS ? ATTR_BOLD : 0);
attr ^= ATTR_CUR_XOR;
}
nfont = 0;
- if (cfg.vtmode == VT_OEMONLY)
- nfont |= FONT_OEM;
-
- /*
- * Map high-half characters in order to approximate ISO using
- * OEM character set. No characters are missing if the OEM codepage
- * is CP850.
- */
- if (nfont & FONT_OEM) {
- int i;
- for (i = 0; i < len; i++)
- if (text[i] >= '\xA0' && text[i] <= '\xFF') {
-#if 0
- /* This is CP850 ... perfect translation */
- static const char oemhighhalf[] = "\x20\xAD\xBD\x9C\xCF\xBE\xDD\xF5" /* A0-A7 */
- "\xF9\xB8\xA6\xAE\xAA\xF0\xA9\xEE" /* A8-AF */
- "\xF8\xF1\xFD\xFC\xEF\xE6\xF4\xFA" /* B0-B7 */
- "\xF7\xFB\xA7\xAF\xAC\xAB\xF3\xA8" /* B8-BF */
- "\xB7\xB5\xB6\xC7\x8E\x8F\x92\x80" /* C0-C7 */
- "\xD4\x90\xD2\xD3\xDE\xD6\xD7\xD8" /* C8-CF */
- "\xD1\xA5\xE3\xE0\xE2\xE5\x99\x9E" /* D0-D7 */
- "\x9D\xEB\xE9\xEA\x9A\xED\xE8\xE1" /* D8-DF */
- "\x85\xA0\x83\xC6\x84\x86\x91\x87" /* E0-E7 */
- "\x8A\x82\x88\x89\x8D\xA1\x8C\x8B" /* E8-EF */
- "\xD0\xA4\x95\xA2\x93\xE4\x94\xF6" /* F0-F7 */
- "\x9B\x97\xA3\x96\x81\xEC\xE7\x98" /* F8-FF */
- ;
-#endif
- /* This is CP437 ... junk translation */
- static const unsigned char oemhighhalf[] = {
- 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,
- 0x41, 0x41, 0x41, 0x41, 0x8e, 0x8f, 0x92, 0x80,
- 0x45, 0x90, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49,
- 0x44, 0xa5, 0x4f, 0x4f, 0x4f, 0x4f, 0x99, 0x78,
- 0xed, 0x55, 0x55, 0x55, 0x9a, 0x59, 0x50, 0xe1,
- 0x85, 0xa0, 0x83, 0x61, 0x84, 0x86, 0x91, 0x87,
- 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b,
- 0x0b, 0xa4, 0x95, 0xa2, 0x93, 0x6f, 0x94, 0xf6,
- 0xed, 0x97, 0xa3, 0x96, 0x81, 0x79, 0x70, 0x98
- };
-
- text[i] = oemhighhalf[(unsigned char) text[i] - 0xA0];
- }
- }
-
- if (attr & ATTR_LINEDRW) {
- int i;
- /* ISO 8859-1 */
- static const char poorman[] =
- "*#****\xB0\xB1**+++++-----++++|****\xA3\xB7";
-
- /* CP437 */
- static const char oemmap_437[] =
- "\x04\xB1****\xF8\xF1**\xD9\xBF\xDA\xC0\xC5"
- "\xC4\xC4\xC4\xC4\xC4\xC3\xB4\xC1\xC2\xB3\xF3\xF2\xE3*\x9C\xFA";
-
- /* CP850 */
- static const char oemmap_850[] =
- "\x04\xB1****\xF8\xF1**\xD9\xBF\xDA\xC0\xC5"
- "\xC4\xC4\xC4\xC4\xC4\xC3\xB4\xC1\xC2\xB3****\x9C\xFA";
-
- /* Poor windows font ... eg: windows courier */
- static const char oemmap[] =
- "*\xB1****\xF8\xF1**\xD9\xBF\xDA\xC0\xC5"
- "\xC4\xC4\xC4\xC4\xC4\xC3\xB4\xC1\xC2\xB3****\x9C\xFA";
-
- /*
- * Line drawing mapping: map ` thru ~ (0x60 thru 0x7E) to
- * VT100 line drawing chars; everything else stays normal.
- *
- * Actually '_' maps to space too, but that's done before.
- */
- switch (cfg.vtmode) {
- case VT_XWINDOWS:
- for (i = 0; i < len; i++)
- if (text[i] >= '\x60' && text[i] <= '\x7E')
- text[i] += '\x01' - '\x60';
+ if (cfg.vtmode == VT_POORMAN && lattr != LATTR_NORM) {
+ /* Assume a poorman font is borken in other ways too. */
+ lattr = LATTR_WIDE;
+ } else
+ switch (lattr) {
+ case LATTR_NORM:
+ break;
+ case LATTR_WIDE:
+ nfont |= FONT_WIDE;
+ break;
+ default:
+ nfont |= FONT_WIDE + FONT_HIGH;
break;
- case VT_OEMANSI:
- /* Make sure we actually have an OEM font */
- if (fonts[nfont | FONT_OEM]) {
- case VT_OEMONLY:
- nfont |= FONT_OEM;
- for (i = 0; i < len; i++)
- if (text[i] >= '\x60' && text[i] <= '\x7E')
- text[i] = oemmap[(unsigned char) text[i] - 0x60];
+ }
+
+ /* Special hack for the VT100 linedraw glyphs. */
+ if ((attr & CSET_MASK) == 0x2300) {
+ if (!dbcs_screenfont &&
+ text[0] >= (char) 0xBA && text[0] <= (char) 0xBD) {
+ switch ((unsigned char) (text[0])) {
+ case 0xBA:
+ text_adjust = -2 * font_height / 5;
+ break;
+ case 0xBB:
+ text_adjust = -1 * font_height / 5;
+ break;
+ case 0xBC:
+ text_adjust = font_height / 5;
+ break;
+ case 0xBD:
+ text_adjust = 2 * font_height / 5;
break;
}
- case VT_POORMAN:
- for (i = 0; i < len; i++)
- if (text[i] >= '\x60' && text[i] <= '\x7E')
- text[i] = poorman[(unsigned char) text[i] - 0x60];
- break;
+ if (lattr == LATTR_TOP || lattr == LATTR_BOT)
+ text_adjust *= 2;
+ attr &= ~CSET_MASK;
+ text[0] = (char) (unitab_xterm['q'] & CHAR_MASK);
+ attr |= (unitab_xterm['q'] & CSET_MASK);
+ if (attr & ATTR_UNDER) {
+ attr &= ~ATTR_UNDER;
+ force_manual_underline = 1;
+ }
}
}
+ /* Anything left as an original character set is unprintable. */
+ if (DIRECT_CHAR(attr)) {
+ attr &= ~CSET_MASK;
+ attr |= 0xFF00;
+ memset(text, 0xFF, len);
+ }
+
+ /* OEM CP */
+ if ((attr & CSET_MASK) == ATTR_OEMCP)
+ nfont |= FONT_OEM;
+
nfg = 2 * ((attr & ATTR_FGMASK) >> ATTR_FGSHIFT);
nbg = 2 * ((attr & ATTR_BGMASK) >> ATTR_BGSHIFT);
if (bold_mode == BOLD_FONT && (attr & ATTR_BOLD))
nfont |= FONT_BOLD;
if (und_mode == UND_FONT && (attr & ATTR_UNDER))
nfont |= FONT_UNDERLINE;
+ another_font(nfont);
if (!fonts[nfont]) {
if (nfont & FONT_UNDERLINE)
force_manual_underline = 1;
nfont &= ~(FONT_BOLD | FONT_UNDERLINE);
}
- if (font_needs_hand_underlining && (attr & ATTR_UNDER))
- force_manual_underline = 1;
+ another_font(nfont);
+ if (!fonts[nfont])
+ nfont = FONT_NORMAL;
if (attr & ATTR_REVERSE) {
t = nfg;
nfg = nbg;
SetBkMode(hdc, OPAQUE);
line_box.left = x;
line_box.top = y;
- line_box.right = x + fnt_width * len;
+ line_box.right = x + char_width * len;
line_box.bottom = y + font_height;
- ExtTextOut(hdc, x, y, ETO_CLIPPED | ETO_OPAQUE, &line_box, text, len,
- IpDx);
- if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
- SetBkMode(hdc, TRANSPARENT);
-
- /* GRR: This draws the character outside it's box and can leave
- * 'droppings' even with the clip box! I suppose I could loop it
- * one character at a time ... yuk.
- *
- * Or ... I could do a test print with "W", and use +1 or -1 for this
- * shift depending on if the leftmost column is blank...
- */
- ExtTextOut(hdc, x - 1, y, ETO_CLIPPED, &line_box, text, len, IpDx);
+
+ /* We're using a private area for direct to font. (512 chars.) */
+ if (dbcs_screenfont && (attr & CSET_MASK) == ATTR_ACP) {
+ /* Ho Hum, dbcs fonts are a PITA! */
+ /* To display on W9x I have to convert to UCS */
+ static wchar_t *uni_buf = 0;
+ static int uni_len = 0;
+ int nlen;
+ if (len > uni_len) {
+ sfree(uni_buf);
+ uni_buf = smalloc((uni_len = len) * sizeof(wchar_t));
+ }
+ nlen = MultiByteToWideChar(font_codepage, MB_USEGLYPHCHARS,
+ text, len, uni_buf, uni_len);
+
+ if (nlen <= 0)
+ return; /* Eeek! */
+
+ ExtTextOutW(hdc, x,
+ y - font_height * (lattr == LATTR_BOT) + text_adjust,
+ ETO_CLIPPED | ETO_OPAQUE, &line_box, uni_buf, nlen, 0);
+ if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
+ SetBkMode(hdc, TRANSPARENT);
+ ExtTextOutW(hdc, x - 1,
+ y - font_height * (lattr ==
+ LATTR_BOT) + text_adjust,
+ ETO_CLIPPED, &line_box, uni_buf, nlen, 0);
+ }
+ } else if (DIRECT_FONT(attr)) {
+ ExtTextOut(hdc, x,
+ y - font_height * (lattr == LATTR_BOT) + text_adjust,
+ ETO_CLIPPED | ETO_OPAQUE, &line_box, text, len, IpDx);
+ if (bold_mode == BOLD_SHADOW && (attr & ATTR_BOLD)) {
+ SetBkMode(hdc, TRANSPARENT);
+
+ /* GRR: This draws the character outside it's box and can leave
+ * 'droppings' even with the clip box! I suppose I could loop it
+ * one character at a time ... yuk.
+ *
+ * Or ... I could do a test print with "W", and use +1 or -1 for this
+ * shift depending on if the leftmost column is blank...
+ */
+ ExtTextOut(hdc, x - 1,
+ y - font_height * (lattr ==
+ LATTR_BOT) + text_adjust,
+ ETO_CLIPPED, &line_box, text, len, IpDx);
+ }
+ } else {
+ /* And 'normal' unicode characters */
+ static WCHAR *wbuf = NULL;
+ static int wlen = 0;
+ int i;
+ if (wlen < len) {
+ sfree(wbuf);
+ wlen = len;
+ wbuf = smalloc(wlen * sizeof(WCHAR));
+ }
+ for (i = 0; i < len; i++)
+ wbuf[i] = (WCHAR) ((attr & CSET_MASK) + (text[i] & CHAR_MASK));
+
+ ExtTextOutW(hdc, x,
+ y - font_height * (lattr == LATTR_BOT) + text_adjust,
+ ETO_CLIPPED | ETO_OPAQUE, &line_box, wbuf, len, IpDx);
+
+ /* And the shadow bold hack. */
+ if (bold_mode == BOLD_SHADOW) {
+ SetBkMode(hdc, TRANSPARENT);
+ ExtTextOutW(hdc, x - 1,
+ y - font_height * (lattr ==
+ LATTR_BOT) + text_adjust,
+ ETO_CLIPPED, &line_box, wbuf, len, IpDx);
+ }
}
- if (force_manual_underline ||
- (und_mode == UND_LINE && (attr & ATTR_UNDER))) {
+ if (lattr != LATTR_TOP && (force_manual_underline ||
+ (und_mode == UND_LINE
+ && (attr & ATTR_UNDER)))) {
HPEN oldpen;
+ int dec = descent;
+ if (lattr == LATTR_BOT)
+ dec = dec * 2 - font_height;
+
oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, fg));
- MoveToEx(hdc, x, y + descent, NULL);
- LineTo(hdc, x + len * fnt_width, y + descent);
+ MoveToEx(hdc, x, y + dec, NULL);
+ LineTo(hdc, x + len * char_width, y + dec);
oldpen = SelectObject(hdc, oldpen);
DeleteObject(oldpen);
}
- if ((attr & ATTR_PASCURS) && cfg.cursor_type == 0) {
+}
+
+void do_cursor(Context ctx, int x, int y, char *text, int len,
+ unsigned long attr, int lattr)
+{
+
+ int fnt_width;
+ int char_width;
+ HDC hdc = ctx;
+ int ctype = cfg.cursor_type;
+
+ if ((attr & TATTR_ACTCURS) && (ctype == 0 || big_cursor)) {
+ if (((attr & CSET_MASK) | (unsigned char) *text) != UCSWIDE) {
+ do_text(ctx, x, y, text, len, attr, lattr);
+ return;
+ }
+ ctype = 2;
+ attr |= TATTR_RIGHTCURS;
+ }
+
+ fnt_width = char_width = font_width * (1 + (lattr != LATTR_NORM));
+ if (attr & ATTR_WIDE)
+ char_width *= 2;
+ x *= fnt_width;
+ y *= font_height;
+
+ if ((attr & TATTR_PASCURS) && (ctype == 0 || big_cursor)) {
POINT pts[5];
HPEN oldpen;
pts[0].x = pts[1].x = pts[4].x = x;
- pts[2].x = pts[3].x = x + fnt_width - 1;
+ pts[2].x = pts[3].x = x + char_width - 1;
pts[0].y = pts[3].y = pts[4].y = y;
pts[1].y = pts[2].y = y + font_height - 1;
oldpen = SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[23]));
Polyline(hdc, pts, 5);
oldpen = SelectObject(hdc, oldpen);
DeleteObject(oldpen);
- }
- if ((attr & (ATTR_ACTCURS | ATTR_PASCURS)) && cfg.cursor_type != 0) {
+ } else if ((attr & (TATTR_ACTCURS | TATTR_PASCURS)) && ctype != 0) {
int startx, starty, dx, dy, length, i;
- if (cfg.cursor_type == 1) {
+ if (ctype == 1) {
startx = x;
starty = y + descent;
dx = 1;
dy = 0;
- length = fnt_width;
+ length = char_width;
} else {
int xadjust = 0;
- if (attr & ATTR_RIGHTCURS)
- xadjust = fnt_width - 1;
+ if (attr & TATTR_RIGHTCURS)
+ xadjust = char_width - 1;
startx = x + xadjust;
starty = y;
dx = 0;
dy = 1;
length = font_height;
}
- if (attr & ATTR_ACTCURS) {
+ if (attr & TATTR_ACTCURS) {
HPEN oldpen;
oldpen =
SelectObject(hdc, CreatePen(PS_SOLID, 0, colours[23]));
}
}
-static int check_compose(int first, int second)
-{
-
- static char *composetbl[] = {
- "++#", "AA@", "(([", "//\\", "))]", "(-{", "-)}", "/^|", "!!¡",
- "C/¢",
- "C|¢", "L-£", "L=£", "XO¤", "X0¤", "Y-¥", "Y=¥", "||¦", "SO§",
- "S!§",
- "S0§", "\"\"¨", "CO©", "C0©", "A_ª", "<<«", ",-¬", "--", "RO®",
- "-^¯", "0^°", "+-±", "2^²", "3^³", "''´", "/Uµ", "P!¶", ".^·",
- ",,¸",
- "1^¹", "O_º", ">>»", "14¼", "12½", "34¾", "??¿", "`AÀ", "'AÁ",
- "^AÂ",
- "~AÃ", "\"AÄ", "*AÅ", "AEÆ", ",CÇ", "`EÈ", "'EÉ", "^EÊ", "\"EË",
- "`IÌ", "'IÍ", "^IÎ", "\"IÏ", "-DÐ", "~NÑ", "`OÒ", "'OÓ", "^OÔ",
- "~OÕ", "\"OÖ", "XX×", "/OØ", "`UÙ", "'UÚ", "^UÛ", "\"UÜ", "'YÝ",
- "HTÞ", "ssß", "`aà", "'aá", "^aâ", "~aã", "\"aä", "*aå", "aeæ",
- ",cç",
- "`eè", "'eé", "^eê", "\"eë", "`iì", "'ií", "^iî", "\"iï", "-dð",
- "~nñ",
- "`oò", "'oó", "^oô", "~oõ", "\"oö", ":-÷", "o/ø", "`uù", "'uú",
- "^uû",
- "\"uü", "'yý", "htþ", "\"yÿ",
- 0
- };
-
- char **c;
- static int recurse = 0;
- int nc = -1;
-
- for (c = composetbl; *c; c++) {
- if ((*c)[0] == first && (*c)[1] == second) {
- return (*c)[2] & 0xFF;
- }
- }
-
- if (recurse == 0) {
- recurse = 1;
- nc = check_compose(second, first);
- if (nc == -1)
- nc = check_compose(toupper(first), toupper(second));
- if (nc == -1)
- nc = check_compose(toupper(second), toupper(first));
- recurse = 0;
- }
- return nc;
-}
-
-
/*
* Translate a WM_(SYS)?KEY(UP|DOWN) message into a string of ASCII
* codes. Returns number of bytes used or zero to drop the message
int r, i, code;
unsigned char *p = output;
static int alt_state = 0;
+ static int alt_sum = 0;
HKL kbd_layout = GetKeyboardLayout(0);
memset(keystate, 0, sizeof(keystate));
else {
#if 0
+#define SHOW_TOASCII_RESULT
{ /* Tell us all about key events */
static BYTE oldstate[256];
static int first = 1;
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 p - output;
}
- if (cfg.funky_type == 5 && code >= 11 && code <= 24) {
- p += sprintf((char *) p, "\x1B[%c", code + 'M' - 11);
+ if (cfg.funky_type == 5 && /* SCO function keys */
+ code >= 11 && code <= 34) {
+ char codes[] = "MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@[\\]^_`{";
+ int index = 0;
+ switch (wParam) {
+ case VK_F1: index = 0; break;
+ case VK_F2: index = 1; break;
+ case VK_F3: index = 2; break;
+ case VK_F4: index = 3; break;
+ case VK_F5: index = 4; break;
+ case VK_F6: index = 5; break;
+ case VK_F7: index = 6; break;
+ case VK_F8: index = 7; break;
+ case VK_F9: index = 8; break;
+ case VK_F10: index = 9; break;
+ case VK_F11: index = 10; break;
+ case VK_F12: index = 11; break;
+ }
+ if (keystate[VK_SHIFT] & 0x80) index += 12;
+ if (keystate[VK_CONTROL] & 0x80) index += 24;
+ 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) {
*p++ = 0;
return -2;
}
+
+ if (left_alt && wParam >= VK_NUMPAD0 && wParam <= VK_NUMPAD9)
+ alt_sum = alt_sum * 10 + wParam - VK_NUMPAD0;
+ else
+ alt_sum = 0;
}
/* Okay we've done everything interesting; let windows deal with
* the boring stuff */
{
- BOOL capsOn = keystate[VK_CAPITAL] != 0;
-
- /* helg: clear CAPS LOCK state if caps lock switches to cyrillic */
- if (cfg.xlat_capslockcyr)
- keystate[VK_CAPITAL] = 0;
-
r = ToAsciiEx(wParam, scan, keystate, keys, 0, kbd_layout);
+#ifdef SHOW_TOASCII_RESULT
+ if (r == 1 && !key_down) {
+ if (alt_sum) {
+ if (in_utf || dbcs_screenfont)
+ debug((", (U+%04x)", alt_sum));
+ else
+ debug((", LCH(%d)", alt_sum));
+ } else {
+ debug((", ACH(%d)", keys[0]));
+ }
+ } else if (r > 0) {
+ int r1;
+ debug((", ASC("));
+ for (r1 = 0; r1 < r; r1++) {
+ debug(("%s%d", r1 ? "," : "", keys[r1]));
+ }
+ debug((")"));
+ }
+#endif
if (r > 0) {
+ WCHAR keybuf;
p = output;
for (i = 0; i < r; i++) {
unsigned char ch = (unsigned char) keys[i];
MessageBeep(MB_ICONHAND);
return 0;
}
- *p++ = xlat_kbd2tty((unsigned char) nc);
- return p - output;
+ keybuf = nc;
+ luni_send(&keybuf, 1);
+ continue;
}
compose_state = 0;
- if (left_alt && key_down)
- *p++ = '\033';
- if (!key_down)
- *p++ = ch;
- else {
- if (capsOn)
- ch = xlat_latkbd2win(ch);
- *p++ = xlat_kbd2tty(ch);
+ if (!key_down) {
+ if (alt_sum) {
+ if (in_utf || dbcs_screenfont) {
+ keybuf = alt_sum;
+ luni_send(&keybuf, 1);
+ } else {
+ ch = (char) alt_sum;
+ ldisc_send(&ch, 1);
+ }
+ alt_sum = 0;
+ } else
+ lpage_send(kbd_codepage, &ch, 1);
+ } else {
+ static char cbuf[] = "\033 ";
+ cbuf[1] = ch;
+ lpage_send(kbd_codepage, cbuf + !left_alt,
+ 1 + !!left_alt);
}
}
/* If we're definitly not building up an ALT-54321 then clear it */
if (!left_alt)
keys[0] = 0;
+ /* If we will be using alt_sum fix the 256s */
+ else if (keys[0] && (in_utf || dbcs_screenfont))
+ keys[0] = 10;
}
/* ALT alone may or may not want to bring up the System menu */
}
}
-void write_clip(void *data, int len, int must_deselect)
+void write_aclip(char *data, int len, int must_deselect)
{
HGLOBAL clipdata;
void *lock;
SendMessage(hwnd, WM_IGNORE_CLIP, FALSE, 0);
}
-void get_clip(void **p, int *len)
+/*
+ * Note: unlike write_aclip() this will not append a nul.
+ */
+void write_clip(wchar_t * data, int len, int must_deselect)
+{
+ HGLOBAL clipdata;
+ HGLOBAL clipdata2;
+ int len2;
+ void *lock, *lock2;
+
+ len2 = WideCharToMultiByte(CP_ACP, 0, data, len, 0, 0, NULL, NULL);
+
+ clipdata = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,
+ len * sizeof(wchar_t));
+ clipdata2 = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, len2);
+
+ if (!clipdata || !clipdata2) {
+ if (clipdata)
+ GlobalFree(clipdata);
+ if (clipdata2)
+ GlobalFree(clipdata2);
+ return;
+ }
+ if (!(lock = GlobalLock(clipdata)))
+ return;
+ if (!(lock2 = GlobalLock(clipdata2)))
+ return;
+
+ memcpy(lock, data, len * sizeof(wchar_t));
+ WideCharToMultiByte(CP_ACP, 0, data, len, lock2, len2, NULL, NULL);
+
+ GlobalUnlock(clipdata);
+ GlobalUnlock(clipdata2);
+
+ if (!must_deselect)
+ SendMessage(hwnd, WM_IGNORE_CLIP, TRUE, 0);
+
+ if (OpenClipboard(hwnd)) {
+ EmptyClipboard();
+ SetClipboardData(CF_UNICODETEXT, clipdata);
+ SetClipboardData(CF_TEXT, clipdata2);
+ CloseClipboard();
+ } else {
+ GlobalFree(clipdata);
+ GlobalFree(clipdata2);
+ }
+
+ if (!must_deselect)
+ SendMessage(hwnd, WM_IGNORE_CLIP, FALSE, 0);
+}
+
+void get_clip(wchar_t ** p, int *len)
{
static HGLOBAL clipdata = NULL;
+ static wchar_t *converted = 0;
+ wchar_t *p2;
+ if (converted) {
+ sfree(converted);
+ converted = 0;
+ }
if (!p) {
if (clipdata)
GlobalUnlock(clipdata);
clipdata = NULL;
return;
- } else {
- if (OpenClipboard(NULL)) {
- clipdata = GetClipboardData(CF_TEXT);
+ } else if (OpenClipboard(NULL)) {
+ if ((clipdata = GetClipboardData(CF_UNICODETEXT))) {
CloseClipboard();
- if (clipdata) {
- *p = GlobalLock(clipdata);
- if (*p) {
- *len = strlen(*p);
- return;
- }
+ *p = GlobalLock(clipdata);
+ if (*p) {
+ for (p2 = *p; *p2; p2++);
+ *len = p2 - *p;
+ return;
}
- }
+ } else if ( (clipdata = GetClipboardData(CF_TEXT)) ) {
+ char *s;
+ int i;
+ CloseClipboard();
+ s = GlobalLock(clipdata);
+ i = MultiByteToWideChar(CP_ACP, 0, s, strlen(s) + 1, 0, 0);
+ *p = converted = smalloc(i * sizeof(wchar_t));
+ MultiByteToWideChar(CP_ACP, 0, s, strlen(s) + 1, converted, i);
+ *len = i - 1;
+ return;
+ } else
+ CloseClipboard();
}
*p = NULL;
*len = 0;
}
+#if 0
/*
* Move `lines' lines from position `from' to position `to' in the
* window.
r.bottom = (max + lines) * font_height;
ScrollWindow(hwnd, 0, (to - from) * font_height, &r, &r);
}
+#endif
/*
* Print a message box and perform a fatal exit.
exit(1);
}
+/*
+ * 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.
*/
cfg.beep = BELL_DEFAULT;
}
}
+ /* Otherwise, either visual bell or disabled; do nothing here */
+ if (!has_focus) {
+ flash_window(2); /* start */
+ }
}