static int session_closed;
static const struct telnet_special *specials;
+static int n_specials;
static struct {
HMENU menu;
/* See if host is of the form user@host */
if (cfg.host[0] != '\0') {
- char *atsign = strchr(cfg.host, '@');
+ char *atsign = strrchr(cfg.host, '@');
/* Make sure we're not overflowing the user field */
if (atsign) {
if (atsign - cfg.host < sizeof cfg.username) {
SetScrollInfo(hwnd, SB_VERT, &si, FALSE);
}
- start_backend();
-
/*
* Prepare the mouse handler.
*/
}
}
- update_specials_menu(NULL);
+ start_backend();
/*
* Set up the initial input locale.
specials = NULL;
if (specials) {
- p = CreateMenu();
- for (i = 0; specials[i].name; i++) {
+ /* We can't use Windows to provide a stack for submenus, so
+ * here's a lame "stack" that will do for now. */
+ HMENU saved_menu = NULL;
+ int nesting = 1;
+ p = CreatePopupMenu();
+ for (i = 0; nesting > 0; i++) {
assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX);
- if (*specials[i].name)
+ switch (specials[i].code) {
+ case TS_SEP:
+ AppendMenu(p, MF_SEPARATOR, 0, 0);
+ break;
+ case TS_SUBMENU:
+ assert(nesting < 2);
+ nesting++;
+ saved_menu = p; /* XXX lame stacking */
+ p = CreatePopupMenu();
+ AppendMenu(saved_menu, MF_POPUP | MF_ENABLED,
+ (UINT) p, specials[i].name);
+ break;
+ case TS_EXITMENU:
+ nesting--;
+ if (nesting) {
+ p = saved_menu; /* XXX lame stacking */
+ saved_menu = NULL;
+ }
+ break;
+ default:
AppendMenu(p, MF_ENABLED, IDM_SPECIAL_MIN + 0x10 * i,
specials[i].name);
- else
- AppendMenu(p, MF_SEPARATOR, 0, 0);
+ break;
+ }
}
- } else
+ /* Squirrel the highest special. */
+ n_specials = i - 1;
+ } else {
p = NULL;
+ n_specials = 0;
+ }
for (j = 0; j < lenof(popup_menus); j++) {
if (menu_already_exists) {
+ /* XXX does this free up all submenus? */
DeleteMenu(popup_menus[j].menu,
popup_menus[j].specials_submenu_pos,
MF_BYPOSITION);
InsertMenu(popup_menus[j].menu,
popup_menus[j].specials_submenu_pos,
MF_BYPOSITION | MF_POPUP | MF_ENABLED,
- (UINT) p, "Special Command");
+ (UINT) p, "S&pecial Command");
}
}
}
defpal[i].rgbtGreen, defpal[i].rgbtBlue);
}
-/*
- * This is a wrapper to ExtTextOut() to force Windows to display
- * the precise glyphs we give it. Otherwise it would do its own
- * bidi and Arabic shaping, and we would end up uncertain which
- * characters it had put where.
- */
-static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
- unsigned short *lpString, UINT cbCount,
- CONST INT *lpDx)
-{
-
- GCP_RESULTSW gcpr;
- char *buffer = snewn(cbCount*2+2, char);
- char *classbuffer = snewn(cbCount, char);
- memset(&gcpr, 0, sizeof(gcpr));
- memset(buffer, 0, cbCount*2+2);
- memset(classbuffer, GCPCLASS_NEUTRAL, cbCount);
-
- gcpr.lStructSize = sizeof(gcpr);
- gcpr.lpGlyphs = (void *)buffer;
- gcpr.lpClass = classbuffer;
- gcpr.nGlyphs = cbCount;
-
- GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr,
- FLI_MASK | GCP_CLASSIN);
-
- ExtTextOut(hdc, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED | ETO_OPAQUE, lprc,
- buffer, cbCount, lpDx);
-}
-
/*
* 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 (wParam >= IDM_SPECIAL_MIN && wParam <= IDM_SPECIAL_MAX) {
int i = (wParam - IDM_SPECIAL_MIN) / 0x10;
- int j;
/*
* Ensure we haven't been sent a bogus SYSCOMMAND
* which would cause us to reference invalid memory
* and crash. Perhaps I'm just too paranoid here.
*/
- for (j = 0; j < i; j++)
- if (!specials || !specials[j].name)
- break;
- if (j == i) {
- if (back)
- back->special(backhandle, specials[i].code);
- net_pending_errors();
- }
+ if (i >= n_specials)
+ break;
+ if (back)
+ back->special(backhandle, specials[i].code);
+ net_pending_errors();
}
}
break;
mi.rcMonitor.top == pt.y) {
mouse_on_hotspot = 1;
}
- CloseHandle(mon);
}
}
#else
return TRUE;
}
break;
+ case WM_SYSCOLORCHANGE:
+ if (cfg.system_colour) {
+ /* Refresh palette from system colours. */
+ /* XXX actually this zaps the entire palette. */
+ systopalette();
+ init_palette();
+ /* Force a repaint of the terminal window. */
+ term_invalidate(term);
+ }
+ break;
case WM_AGENT_CALLBACK:
{
struct agent_callback *c = (struct agent_callback *)lParam;
for (i = 0; i < len; i++)
wbuf[i] = (WCHAR) ((attr & CSET_MASK) + (text[i] & CHAR_MASK));
- /* print Glyphs as they are, without Windows' Shaping*/
- exact_textout(hdc, x, y - font_height * (lattr == LATTR_BOT) + text_adjust,
- &line_box, wbuf, len, IpDx);
-/* ExtTextOutW(hdc, x,
+ 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 && (attr & ATTR_BOLD)) {
/* Nastyness with NUMLock - Shift-NUMLock is left alone though */
- if ((cfg.funky_type == 3 ||
- (cfg.funky_type <= 1 && term->app_keypad_keys &&
+ if ((cfg.funky_type == FUNKY_VT400 ||
+ (cfg.funky_type <= FUNKY_LINUX && term->app_keypad_keys &&
!cfg.no_applic_k))
&& wParam == VK_NUMLOCK && !(keystate[VK_SHIFT] & 0x80)) {
/* Sanitize the number pad if not using a PC NumPad */
if (left_alt || (term->app_keypad_keys && !cfg.no_applic_k
- && cfg.funky_type != 2)
- || cfg.funky_type == 3 || cfg.nethack_keypad || compose_state) {
+ && cfg.funky_type != FUNKY_XTERM)
+ || cfg.funky_type == FUNKY_VT400 || cfg.nethack_keypad || compose_state) {
if ((HIWORD(lParam) & KF_EXTENDED) == 0) {
int nParam = 0;
switch (wParam) {
if (!left_alt) {
int xkey = 0;
- if (cfg.funky_type == 3 ||
- (cfg.funky_type <= 1 &&
+ if (cfg.funky_type == FUNKY_VT400 ||
+ (cfg.funky_type <= FUNKY_LINUX &&
term->app_keypad_keys && !cfg.no_applic_k)) switch (wParam) {
case VK_EXECUTE:
xkey = 'P';
xkey = 'n';
break;
case VK_ADD:
- if (cfg.funky_type == 2) {
+ if (cfg.funky_type == FUNKY_XTERM) {
if (shift_state)
xkey = 'l';
else
break;
case VK_DIVIDE:
- if (cfg.funky_type == 2)
+ if (cfg.funky_type == FUNKY_XTERM)
xkey = 'o';
break;
case VK_MULTIPLY:
- if (cfg.funky_type == 2)
+ if (cfg.funky_type == FUNKY_XTERM)
xkey = 'j';
break;
case VK_SUBTRACT:
- if (cfg.funky_type == 2)
+ if (cfg.funky_type == FUNKY_XTERM)
xkey = 'm';
break;
break;
}
/* Reorder edit keys to physical order */
- if (cfg.funky_type == 3 && code <= 6)
+ if (cfg.funky_type == FUNKY_VT400 && code <= 6)
code = "\0\2\1\4\5\3\6"[code];
if (term->vt52_mode && code > 0 && code <= 6) {
return p - output;
}
- if (cfg.funky_type == 5 && /* SCO function keys */
+ if (cfg.funky_type == FUNKY_SCO && /* SCO function keys */
code >= 11 && code <= 34) {
char codes[] = "MNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@[\\]^_`{";
int index = 0;
p += sprintf((char *) p, "\x1B[%c", codes[index]);
return p - output;
}
- if (cfg.funky_type == 5 && /* SCO small keypad */
+ if (cfg.funky_type == FUNKY_SCO && /* SCO small keypad */
code >= 1 && code <= 6) {
char codes[] = "HL.FIG";
if (code == 3) {
}
return p - output;
}
- if ((term->vt52_mode || cfg.funky_type == 4) && code >= 11 && code <= 24) {
+ if ((term->vt52_mode || cfg.funky_type == FUNKY_VT100P) && code >= 11 && code <= 24) {
int offt = 0;
if (code > 15)
offt++;
sprintf((char *) p, "\x1BO%c", code + 'P' - 11 - offt);
return p - output;
}
- if (cfg.funky_type == 1 && code >= 11 && code <= 15) {
+ if (cfg.funky_type == FUNKY_LINUX && code >= 11 && code <= 15) {
p += sprintf((char *) p, "\x1B[[%c", code + 'A' - 11);
return p - output;
}
- if (cfg.funky_type == 2 && code >= 11 && code <= 14) {
+ if (cfg.funky_type == FUNKY_XTERM && code >= 11 && code <= 14) {
if (term->vt52_mode)
p += sprintf((char *) p, "\x1B%c", code + 'P' - 11);
else