static int session_closed;
static const struct telnet_special *specials;
+static int n_specials;
static struct {
HMENU menu;
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);
*/
static void exact_textout(HDC hdc, int x, int y, CONST RECT *lprc,
unsigned short *lpString, UINT cbCount,
- CONST INT *lpDx)
+ CONST INT *lpDx, int opaque)
{
GCP_RESULTSW gcpr;
gcpr.nGlyphs = cbCount;
GetCharacterPlacementW(hdc, lpString, cbCount, 0, &gcpr,
- FLI_MASK | GCP_CLASSIN);
+ FLI_MASK | GCP_CLASSIN | GCP_DIACRITIC);
- ExtTextOut(hdc, x, y, ETO_GLYPH_INDEX | ETO_CLIPPED | ETO_OPAQUE, lprc,
- buffer, cbCount, lpDx);
+ ExtTextOut(hdc, x, y,
+ ETO_GLYPH_INDEX | ETO_CLIPPED | (opaque ? ETO_OPAQUE : 0),
+ lprc, buffer, cbCount, lpDx);
}
/*
}
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;
*
* We are allowed to fiddle with the contents of `text'.
*/
-void do_text(Context ctx, int x, int y, wchar_t *text, int len,
- unsigned long attr, int lattr)
+void do_text_internal(Context ctx, int x, int y, wchar_t *text, int len,
+ unsigned long attr, int lattr)
{
COLORREF fg, bg, t;
int nfg, nbg, nfont;
SelectObject(hdc, fonts[nfont]);
SetTextColor(hdc, fg);
SetBkColor(hdc, bg);
- SetBkMode(hdc, OPAQUE);
+ if (attr & TATTR_COMBINING)
+ SetBkMode(hdc, TRANSPARENT);
+ else
+ SetBkMode(hdc, OPAQUE);
line_box.left = x;
line_box.top = y;
line_box.right = x + char_width * len;
static WCHAR *wbuf = NULL;
static int wlen = 0;
int i;
+
if (wlen < len) {
sfree(wbuf);
wlen = len;
wbuf = snewn(wlen, WCHAR);
}
+
for (i = 0; i < len; i++)
wbuf[i] = text[i];
/* 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);
+ &line_box, wbuf, len, IpDx, !(attr & TATTR_COMBINING));
/* ExtTextOutW(hdc, x,
y - font_height * (lattr == LATTR_BOT) + text_adjust,
ETO_CLIPPED | ETO_OPAQUE, &line_box, wbuf, len, IpDx);
}
}
+/*
+ * Wrapper that handles combining characters.
+ */
+void do_text(Context ctx, int x, int y, wchar_t *text, int len,
+ unsigned long attr, int lattr)
+{
+ if (attr & TATTR_COMBINING) {
+ unsigned long a = 0;
+ attr &= ~TATTR_COMBINING;
+ while (len--) {
+ do_text_internal(ctx, x, y, text, 1, attr | a, lattr);
+ text++;
+ a = TATTR_COMBINING;
+ }
+ } else
+ do_text_internal(ctx, x, y, text, len, attr, lattr);
+}
+
void do_cursor(Context ctx, int x, int y, wchar_t *text, int len,
unsigned long attr, int lattr)
{