#define IDM_RECONF 0x0040
#define IDM_CLRSB 0x0050
#define IDM_RESET 0x0060
-#define IDM_TEL_AYT 0x0070
-#define IDM_TEL_BRK 0x0080
-#define IDM_TEL_SYNCH 0x0090
-#define IDM_TEL_EC 0x00a0
-#define IDM_TEL_EL 0x00b0
-#define IDM_TEL_GA 0x00c0
-#define IDM_TEL_NOP 0x00d0
-#define IDM_TEL_ABORT 0x00e0
-#define IDM_TEL_AO 0x00f0
-#define IDM_TEL_IP 0x0100
-#define IDM_TEL_SUSP 0x0110
-#define IDM_TEL_EOR 0x0120
-#define IDM_TEL_EOF 0x0130
#define IDM_HELP 0x0140
#define IDM_ABOUT 0x0150
#define IDM_SAVEDSESS 0x0160
#define IDM_SESSLGP 0x0250 /* log type printable */
#define IDM_SESSLGA 0x0260 /* log type all chars */
#define IDM_SESSLGE 0x0270 /* log end */
+
+#define IDM_SPECIAL_MIN 0x0400
+#define IDM_SPECIAL_MAX 0x0800
+
#define IDM_SAVED_MIN 0x1000
#define IDM_SAVED_MAX 0x2000
static struct unicode_data ucsdata;
static int session_closed;
+static const struct telnet_special *specials;
+static int specials_menu_position;
+
Config cfg; /* exported to windlg.c */
extern struct sesslist sesslist; /* imported from windlg.c */
{
char *bits;
int size = (font_width + 15) / 16 * 2 * font_height;
- bits = smalloc(size);
+ bits = snewn(size, char);
memset(bits, 0, size);
caretbm = CreateBitmap(font_width, font_height, 1, 1, bits);
sfree(bits);
*/
{
HMENU m = GetSystemMenu(hwnd, FALSE);
- HMENU p, s;
+ HMENU s;
int i;
AppendMenu(m, MF_SEPARATOR, 0, 0);
- if (cfg.protocol == PROT_TELNET) {
- p = CreateMenu();
- AppendMenu(p, MF_ENABLED, IDM_TEL_AYT, "Are You There");
- AppendMenu(p, MF_ENABLED, IDM_TEL_BRK, "Break");
- AppendMenu(p, MF_ENABLED, IDM_TEL_SYNCH, "Synch");
- AppendMenu(p, MF_SEPARATOR, 0, 0);
- AppendMenu(p, MF_ENABLED, IDM_TEL_EC, "Erase Character");
- AppendMenu(p, MF_ENABLED, IDM_TEL_EL, "Erase Line");
- AppendMenu(p, MF_ENABLED, IDM_TEL_GA, "Go Ahead");
- AppendMenu(p, MF_ENABLED, IDM_TEL_NOP, "No Operation");
- AppendMenu(p, MF_SEPARATOR, 0, 0);
- AppendMenu(p, MF_ENABLED, IDM_TEL_ABORT, "Abort Process");
- AppendMenu(p, MF_ENABLED, IDM_TEL_AO, "Abort Output");
- AppendMenu(p, MF_ENABLED, IDM_TEL_IP, "Interrupt Process");
- AppendMenu(p, MF_ENABLED, IDM_TEL_SUSP, "Suspend Process");
- AppendMenu(p, MF_SEPARATOR, 0, 0);
- AppendMenu(p, MF_ENABLED, IDM_TEL_EOR, "End Of Record");
- AppendMenu(p, MF_ENABLED, IDM_TEL_EOF, "End Of File");
- AppendMenu(m, MF_POPUP | MF_ENABLED, (UINT) p,
- "Telnet Command");
- AppendMenu(m, MF_SEPARATOR, 0, 0);
- }
+ specials_menu_position = GetMenuItemCount(m);
+ debug(("specials_menu_position = %d\n", specials_menu_position));
AppendMenu(m, MF_ENABLED, IDM_SHOWLOG, "&Event Log");
AppendMenu(m, MF_SEPARATOR, 0, 0);
AppendMenu(m, MF_ENABLED, IDM_NEWSESS, "Ne&w Session...");
AppendMenu(m, MF_ENABLED, IDM_ABOUT, "&About PuTTY");
}
+ update_specials_menu(NULL);
+
/*
* Set up the initial input locale.
*/
if (pending_netevent) {
enact_pending_netevent();
- /* Force the cursor blink on */
- term_blink(term, 1);
-
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
continue;
}
}
/*
+ * Update the Special Commands submenu.
+ */
+void update_specials_menu(void *frontend)
+{
+ HMENU m = GetSystemMenu(hwnd, FALSE);
+ int menu_already_exists = (specials != NULL);
+ int i;
+
+ specials = back->get_specials(backhandle);
+ if (specials) {
+ HMENU p = CreateMenu();
+ for (i = 0; specials[i].name; i++) {
+ assert(IDM_SPECIAL_MIN + 0x10 * i < IDM_SPECIAL_MAX);
+ if (*specials[i].name)
+ AppendMenu(p, MF_ENABLED, IDM_SPECIAL_MIN + 0x10 * i,
+ specials[i].name);
+ else
+ AppendMenu(p, MF_SEPARATOR, 0, 0);
+ }
+ if (menu_already_exists)
+ DeleteMenu(m, specials_menu_position, MF_BYPOSITION);
+ else
+ InsertMenu(m, specials_menu_position,
+ MF_BYPOSITION | MF_SEPARATOR, 0, 0);
+ InsertMenu(m, specials_menu_position,
+ MF_BYPOSITION | MF_POPUP | MF_ENABLED,
+ (UINT) p, "Special Command");
+ }
+}
+
+/*
* set or clear the "raw mouse message" mode
*/
void set_raw_mouse_mode(void *frontend, int activate)
HDC hdc = GetDC(hwnd);
if (hdc) {
if (cfg.try_palette && GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) {
+ /*
+ * This is a genuine case where we must use smalloc
+ * because the snew macros can't cope.
+ */
logpal = smalloc(sizeof(*logpal)
- sizeof(logpal->palPalEntry)
+ NCOLOURS * sizeof(PALETTEENTRY));
if ((lParam - IDM_SAVED_MIN) / 16 < sesslist.nsessions) {
char *session =
sesslist.sessions[(lParam - IDM_SAVED_MIN) / 16];
- cl = smalloc(16 + strlen(session));
+ cl = snewn(16 + strlen(session), char);
/* 8, but play safe */
if (!cl)
cl = NULL;
term_pwron(term);
ldisc_send(ldisc, NULL, 0, 0);
break;
- case IDM_TEL_AYT:
- back->special(backhandle, TS_AYT);
- net_pending_errors();
- break;
- case IDM_TEL_BRK:
- back->special(backhandle, TS_BRK);
- net_pending_errors();
- break;
- case IDM_TEL_SYNCH:
- back->special(backhandle, TS_SYNCH);
- net_pending_errors();
- break;
- case IDM_TEL_EC:
- back->special(backhandle, TS_EC);
- net_pending_errors();
- break;
- case IDM_TEL_EL:
- back->special(backhandle, TS_EL);
- net_pending_errors();
- break;
- case IDM_TEL_GA:
- back->special(backhandle, TS_GA);
- net_pending_errors();
- break;
- case IDM_TEL_NOP:
- back->special(backhandle, TS_NOP);
- net_pending_errors();
- break;
- case IDM_TEL_ABORT:
- back->special(backhandle, TS_ABORT);
- net_pending_errors();
- break;
- case IDM_TEL_AO:
- back->special(backhandle, TS_AO);
- net_pending_errors();
- break;
- case IDM_TEL_IP:
- back->special(backhandle, TS_IP);
- net_pending_errors();
- break;
- case IDM_TEL_SUSP:
- back->special(backhandle, TS_SUSP);
- net_pending_errors();
- break;
- case IDM_TEL_EOR:
- back->special(backhandle, TS_EOR);
- net_pending_errors();
- break;
- case IDM_TEL_EOF:
- back->special(backhandle, TS_EOF);
- net_pending_errors();
- break;
case IDM_ABOUT:
showabout(hwnd);
break;
if (wParam >= IDM_SAVED_MIN && wParam <= IDM_SAVED_MAX) {
SendMessage(hwnd, WM_SYSCOMMAND, IDM_SAVEDSESS, wParam);
}
+ 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) {
+ back->special(backhandle, specials[i].code);
+ net_pending_errors();
+ }
+ }
}
break;
if (n > 0) {
int i;
- buff = (char*) smalloc(n);
+ buff = snewn(n, char);
ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, buff, n);
/*
* Jaeyoun Chung reports that Korean character
int i;
if (len > IpDxLEN) {
sfree(IpDx);
- IpDx = smalloc((len + 16) * sizeof(int));
+ IpDx = snewn(len + 16, int);
IpDxLEN = (len + 16);
}
for (i = 0; i < IpDxLEN; i++)
int nlen, mptr;
if (len > uni_len) {
sfree(uni_buf);
- uni_buf = smalloc((uni_len = len) * sizeof(wchar_t));
+ uni_len = len;
+ uni_buf = snewn(uni_len, wchar_t);
}
for(nlen = mptr = 0; mptr<len; mptr++) {
if (wlen < len) {
sfree(wbuf);
wlen = len;
- wbuf = smalloc(wlen * sizeof(WCHAR));
+ wbuf = snewn(wlen, WCHAR);
}
for (i = 0; i < len; i++)
wbuf[i] = (WCHAR) ((attr & CSET_MASK) + (text[i] & CHAR_MASK));
void set_title(void *frontend, char *title)
{
sfree(window_name);
- window_name = smalloc(1 + strlen(title));
+ window_name = snewn(1 + strlen(title), char);
strcpy(window_name, title);
if (cfg.win_name_always || !IsIconic(hwnd))
SetWindowText(hwnd, title);
void set_icon(void *frontend, char *title)
{
sfree(icon_name);
- icon_name = smalloc(1 + strlen(title));
+ icon_name = snewn(1 + strlen(title), char);
strcpy(icon_name, title);
if (!cfg.win_name_always && IsIconic(hwnd))
SetWindowText(hwnd, title);
get_unitab(CP_ACP, unitab, 0);
rtfsize = 100 + strlen(cfg.font.name);
- rtf = smalloc(rtfsize);
+ rtf = snewn(rtfsize, char);
sprintf(rtf, "{\\rtf1\\ansi%d{\\fonttbl\\f0\\fmodern %s;}\\f0",
GetACP(), cfg.font.name);
rtflen = strlen(rtf);
if (rtfsize < rtflen + totallen + 3) {
rtfsize = rtflen + totallen + 512;
- rtf = srealloc(rtf, rtfsize);
+ rtf = sresize(rtf, rtfsize, char);
}
strcpy(rtf + rtflen, before); rtflen += blen;
CloseClipboard();
s = GlobalLock(clipdata);
i = MultiByteToWideChar(CP_ACP, 0, s, strlen(s) + 1, 0, 0);
- *p = converted = smalloc(i * sizeof(wchar_t));
+ *p = converted = snewn(i, wchar_t);
MultiByteToWideChar(CP_ACP, 0, s, strlen(s) + 1, converted, i);
*len = i - 1;
return;