X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/37ca32ed18b3e104c1056713f5112b90c6547e89..125105d16c788398562ac03e91ce7a0dc0292492:/window.c diff --git a/window.c b/window.c index b1fb5fee..96ce4adb 100644 --- a/window.c +++ b/window.c @@ -37,19 +37,6 @@ #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 @@ -59,6 +46,10 @@ #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 @@ -124,6 +115,9 @@ static void *backhandle; 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 */ @@ -600,7 +594,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) { 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); @@ -675,32 +669,12 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) */ { 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..."); @@ -727,6 +701,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) AppendMenu(m, MF_ENABLED, IDM_ABOUT, "&About PuTTY"); } + update_specials_menu(NULL); + /* * Set up the initial input locale. */ @@ -788,9 +764,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) if (pending_netevent) { enact_pending_netevent(); - /* Force the cursor blink on */ - term_blink(term, 1); - if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) continue; } @@ -891,6 +864,37 @@ char *do_select(SOCKET skt, int startup) } /* + * 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) @@ -999,6 +1003,10 @@ static void init_palette(void) 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)); @@ -1062,7 +1070,7 @@ static void init_fonts(int pick_width, int pick_height) bold_mode = cfg.bold_colour ? BOLD_COLOURS : BOLD_FONT; und_mode = UND_FONT; - if (cfg.fontisbold) { + if (cfg.font.isbold) { fw_dontcare = FW_BOLD; fw_bold = FW_HEAVY; } else { @@ -1075,7 +1083,7 @@ static void init_fonts(int pick_width, int pick_height) if (pick_height) font_height = pick_height; else { - font_height = cfg.fontheight; + font_height = cfg.font.height; if (font_height > 0) { font_height = -MulDiv(font_height, GetDeviceCaps(hdc, LOGPIXELSY), 72); @@ -1087,9 +1095,9 @@ static void init_fonts(int pick_width, int pick_height) fonts[i] = CreateFont (font_height, font_width, 0, 0, w, FALSE, u, FALSE, \ c, OUT_DEFAULT_PRECIS, \ CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, \ - FIXED_PITCH | FF_DONTCARE, cfg.font) + FIXED_PITCH | FF_DONTCARE, cfg.font.name) - f(FONT_NORMAL, cfg.fontcharset, fw_dontcare, FALSE); + f(FONT_NORMAL, cfg.font.charset, fw_dontcare, FALSE); lfont.lfHeight = font_height; lfont.lfWidth = font_width; @@ -1099,12 +1107,12 @@ static void init_fonts(int pick_width, int pick_height) lfont.lfItalic = FALSE; lfont.lfUnderline = FALSE; lfont.lfStrikeOut = FALSE; - lfont.lfCharSet = cfg.fontcharset; + lfont.lfCharSet = cfg.font.charset; lfont.lfOutPrecision = OUT_DEFAULT_PRECIS; lfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; lfont.lfQuality = DEFAULT_QUALITY; lfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; - strncpy(lfont.lfFaceName, cfg.font, LF_FACESIZE); + strncpy(lfont.lfFaceName, cfg.font.name, LF_FACESIZE); SelectObject(hdc, fonts[FONT_NORMAL]); GetTextMetrics(hdc, &tm); @@ -1138,7 +1146,7 @@ static void init_fonts(int pick_width, int pick_height) ucsdata.dbcs_screenfont = (cpinfo.MaxCharSize > 1); } - f(FONT_UNDERLINE, cfg.fontcharset, fw_dontcare, TRUE); + f(FONT_UNDERLINE, cfg.font.charset, fw_dontcare, TRUE); /* * Some fonts, e.g. 9-pt Courier, draw their underlines @@ -1189,7 +1197,7 @@ static void init_fonts(int pick_width, int pick_height) } if (bold_mode == BOLD_FONT) { - f(FONT_BOLD, cfg.fontcharset, fw_bold, FALSE); + f(FONT_BOLD, cfg.font.charset, fw_bold, FALSE); } #undef f @@ -1240,7 +1248,7 @@ static void another_font(int fontno) if (basefont != fontno && !fontflag[basefont]) another_font(basefont); - if (cfg.fontisbold) { + if (cfg.font.isbold) { fw_dontcare = FW_BOLD; fw_bold = FW_HEAVY; } else { @@ -1248,10 +1256,10 @@ static void another_font(int fontno) fw_bold = FW_BOLD; } - c = cfg.fontcharset; + c = cfg.font.charset; w = fw_dontcare; u = FALSE; - s = cfg.font; + s = cfg.font.name; x = font_width; if (fontno & FONT_WIDE) @@ -1723,7 +1731,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, 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; @@ -1878,11 +1886,11 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, icon_name); } - if (strcmp(cfg.font, prev_cfg.font) != 0 || + if (strcmp(cfg.font.name, prev_cfg.font.name) != 0 || strcmp(cfg.line_codepage, prev_cfg.line_codepage) != 0 || - cfg.fontisbold != prev_cfg.fontisbold || - cfg.fontheight != prev_cfg.fontheight || - cfg.fontcharset != prev_cfg.fontcharset || + cfg.font.isbold != prev_cfg.font.isbold || + cfg.font.height != prev_cfg.font.height || + cfg.font.charset != prev_cfg.font.charset || cfg.vtmode != prev_cfg.vtmode || cfg.bold_colour != prev_cfg.bold_colour || cfg.resize_action == RESIZE_DISABLED || @@ -1905,58 +1913,6 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, 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; @@ -1991,6 +1947,22 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, 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; @@ -2531,7 +2503,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, 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 @@ -2719,7 +2691,7 @@ void do_text(Context ctx, int x, int y, char *text, int len, 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++) @@ -2850,7 +2822,8 @@ void do_text(Context ctx, int x, int y, char *text, int len, 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