20 #define MAIN_NPANELS 9
21 #define RECONF_NPANELS 6
23 static char **events = NULL;
24 static int nevents = 0, negsize = 0;
26 static HWND logbox = NULL, abtbox = NULL;
28 static void gpps(void *handle, char *name, char *def, char *val, int len) {
29 if (!read_setting_s(handle, name, val, len)) {
30 strncpy(val, def, len);
35 static void gppi(void *handle, char *name, int def, int *i) {
36 *i = read_setting_i(handle, name, def);
39 static HINSTANCE hinst;
43 static void save_settings (char *section, int do_host) {
48 sesskey = open_settings_w(section);
52 write_setting_i (sesskey, "Present", 1);
54 write_setting_s (sesskey, "HostName", cfg.host);
55 write_setting_i (sesskey, "PortNumber", cfg.port);
57 for (i = 0; backends[i].name != NULL; i++)
58 if (backends[i].protocol == cfg.protocol) {
62 write_setting_s (sesskey, "Protocol", p);
64 write_setting_i (sesskey, "CloseOnExit", !!cfg.close_on_exit);
65 write_setting_i (sesskey, "WarnOnClose", !!cfg.warn_on_close);
66 write_setting_s (sesskey, "TerminalType", cfg.termtype);
67 write_setting_s (sesskey, "TerminalSpeed", cfg.termspeed);
69 char buf[2*sizeof(cfg.environmt)], *p, *q;
75 if (c == '=' || c == ',' || c == '\\')
85 write_setting_s (sesskey, "Environment", buf);
87 write_setting_s (sesskey, "UserName", cfg.username);
88 write_setting_i (sesskey, "NoPTY", cfg.nopty);
89 write_setting_i (sesskey, "AgentFwd", cfg.agentfwd);
90 write_setting_s (sesskey, "RemoteCmd", cfg.remote_cmd);
91 write_setting_s (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" :
92 cfg.cipher == CIPHER_DES ? "des" : "3des");
93 write_setting_i (sesskey, "AuthTIS", cfg.try_tis_auth);
94 write_setting_i (sesskey, "SshProt", cfg.sshprot);
95 write_setting_s (sesskey, "PublicKeyFile", cfg.keyfile);
96 write_setting_i (sesskey, "RFCEnviron", cfg.rfc_environ);
97 write_setting_i (sesskey, "BackspaceIsDelete", cfg.bksp_is_delete);
98 write_setting_i (sesskey, "RXVTHomeEnd", cfg.rxvt_homeend);
99 write_setting_i (sesskey, "LinuxFunctionKeys", cfg.funky_type);
100 write_setting_i (sesskey, "ApplicationCursorKeys", cfg.app_cursor);
101 write_setting_i (sesskey, "ApplicationKeypad", cfg.app_keypad);
102 write_setting_i (sesskey, "NetHackKeypad", cfg.nethack_keypad);
103 write_setting_i (sesskey, "AltF4", cfg.alt_f4);
104 write_setting_i (sesskey, "AltSpace", cfg.alt_space);
105 write_setting_i (sesskey, "LdiscTerm", cfg.ldisc_term);
106 write_setting_i (sesskey, "BlinkCur", cfg.blink_cur);
107 write_setting_i (sesskey, "Beep", cfg.beep);
108 write_setting_i (sesskey, "ScrollbackLines", cfg.savelines);
109 write_setting_i (sesskey, "DECOriginMode", cfg.dec_om);
110 write_setting_i (sesskey, "AutoWrapMode", cfg.wrap_mode);
111 write_setting_i (sesskey, "LFImpliesCR", cfg.lfhascr);
112 write_setting_i (sesskey, "WinNameAlways", cfg.win_name_always);
113 write_setting_s (sesskey, "WinTitle", cfg.wintitle);
114 write_setting_i (sesskey, "TermWidth", cfg.width);
115 write_setting_i (sesskey, "TermHeight", cfg.height);
116 write_setting_s (sesskey, "Font", cfg.font);
117 write_setting_i (sesskey, "FontIsBold", cfg.fontisbold);
118 write_setting_i (sesskey, "FontCharSet", cfg.fontcharset);
119 write_setting_i (sesskey, "FontHeight", cfg.fontheight);
120 write_setting_i (sesskey, "FontVTMode", cfg.vtmode);
121 write_setting_i (sesskey, "TryPalette", cfg.try_palette);
122 write_setting_i (sesskey, "BoldAsColour", cfg.bold_colour);
123 for (i=0; i<22; i++) {
124 char buf[20], buf2[30];
125 sprintf(buf, "Colour%d", i);
126 sprintf(buf2, "%d,%d,%d", cfg.colours[i][0],
127 cfg.colours[i][1], cfg.colours[i][2]);
128 write_setting_s (sesskey, buf, buf2);
130 write_setting_i (sesskey, "MouseIsXterm", cfg.mouse_is_xterm);
131 for (i=0; i<256; i+=32) {
132 char buf[20], buf2[256];
134 sprintf(buf, "Wordness%d", i);
136 for (j=i; j<i+32; j++) {
137 sprintf(buf2+strlen(buf2), "%s%d",
138 (*buf2 ? "," : ""), cfg.wordness[j]);
140 write_setting_s (sesskey, buf, buf2);
142 write_setting_i (sesskey, "KoiWinXlat", cfg.xlat_enablekoiwin);
143 write_setting_i (sesskey, "88592Xlat", cfg.xlat_88592w1250);
144 write_setting_i (sesskey, "CapsLockCyr", cfg.xlat_capslockcyr);
145 write_setting_i (sesskey, "ScrollBar", cfg.scrollbar);
146 write_setting_i (sesskey, "ScrollOnKey", cfg.scroll_on_key);
147 write_setting_i (sesskey, "LockSize", cfg.locksize);
148 write_setting_i (sesskey, "BCE", cfg.bce);
149 write_setting_i (sesskey, "BlinkText", cfg.blinktext);
151 close_settings_w(sesskey);
154 static void load_settings (char *section, int do_host) {
159 sesskey = open_settings_r(section);
161 gpps (sesskey, "HostName", "", cfg.host, sizeof(cfg.host));
162 gppi (sesskey, "PortNumber", default_port, &cfg.port);
164 gpps (sesskey, "Protocol", "default", prot, 10);
165 cfg.protocol = default_protocol;
166 for (i = 0; backends[i].name != NULL; i++)
167 if (!strcmp(prot, backends[i].name)) {
168 cfg.protocol = backends[i].protocol;
172 gppi (sesskey, "CloseOnExit", 1, &cfg.close_on_exit);
173 gppi (sesskey, "WarnOnClose", 1, &cfg.warn_on_close);
174 gpps (sesskey, "TerminalType", "xterm", cfg.termtype,
175 sizeof(cfg.termtype));
176 gpps (sesskey, "TerminalSpeed", "38400,38400", cfg.termspeed,
177 sizeof(cfg.termspeed));
179 char buf[2*sizeof(cfg.environmt)], *p, *q;
180 gpps (sesskey, "Environment", "", buf, sizeof(buf));
184 while (*p && *p != ',') {
197 gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username));
198 gppi (sesskey, "NoPTY", 0, &cfg.nopty);
199 gppi (sesskey, "AgentFwd", 0, &cfg.agentfwd);
200 gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd));
203 gpps (sesskey, "Cipher", "3des", cipher, 10);
204 if (!strcmp(cipher, "blowfish"))
205 cfg.cipher = CIPHER_BLOWFISH;
206 else if (!strcmp(cipher, "des"))
207 cfg.cipher = CIPHER_DES;
209 cfg.cipher = CIPHER_3DES;
211 gppi (sesskey, "SshProt", 1, &cfg.sshprot);
212 gppi (sesskey, "AuthTIS", 0, &cfg.try_tis_auth);
213 gpps (sesskey, "PublicKeyFile", "", cfg.keyfile, sizeof(cfg.keyfile));
214 gppi (sesskey, "RFCEnviron", 0, &cfg.rfc_environ);
215 gppi (sesskey, "BackspaceIsDelete", 1, &cfg.bksp_is_delete);
216 gppi (sesskey, "RXVTHomeEnd", 0, &cfg.rxvt_homeend);
217 gppi (sesskey, "LinuxFunctionKeys", 0, &cfg.funky_type);
218 gppi (sesskey, "ApplicationCursorKeys", 0, &cfg.app_cursor);
219 gppi (sesskey, "ApplicationKeypad", 0, &cfg.app_keypad);
220 gppi (sesskey, "NetHackKeypad", 0, &cfg.nethack_keypad);
221 gppi (sesskey, "AltF4", 1, &cfg.alt_f4);
222 gppi (sesskey, "AltSpace", 0, &cfg.alt_space);
223 gppi (sesskey, "LdiscTerm", 0, &cfg.ldisc_term);
224 gppi (sesskey, "BlinkCur", 0, &cfg.blink_cur);
225 gppi (sesskey, "Beep", 1, &cfg.beep);
226 gppi (sesskey, "ScrollbackLines", 200, &cfg.savelines);
227 gppi (sesskey, "DECOriginMode", 0, &cfg.dec_om);
228 gppi (sesskey, "AutoWrapMode", 1, &cfg.wrap_mode);
229 gppi (sesskey, "LFImpliesCR", 0, &cfg.lfhascr);
230 gppi (sesskey, "WinNameAlways", 0, &cfg.win_name_always);
231 gpps (sesskey, "WinTitle", "", cfg.wintitle, sizeof(cfg.wintitle));
232 gppi (sesskey, "TermWidth", 80, &cfg.width);
233 gppi (sesskey, "TermHeight", 24, &cfg.height);
234 gpps (sesskey, "Font", "Courier", cfg.font, sizeof(cfg.font));
235 gppi (sesskey, "FontIsBold", 0, &cfg.fontisbold);
236 gppi (sesskey, "FontCharSet", ANSI_CHARSET, &cfg.fontcharset);
237 gppi (sesskey, "FontHeight", 10, &cfg.fontheight);
238 gppi (sesskey, "FontVTMode", VT_OEMANSI, (int *)&cfg.vtmode);
239 gppi (sesskey, "TryPalette", 0, &cfg.try_palette);
240 gppi (sesskey, "BoldAsColour", 1, &cfg.bold_colour);
241 for (i=0; i<22; i++) {
242 static char *defaults[] = {
243 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
244 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
245 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
246 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
247 "85,255,255", "187,187,187", "255,255,255"
249 char buf[20], buf2[30];
251 sprintf(buf, "Colour%d", i);
252 gpps (sesskey, buf, defaults[i], buf2, sizeof(buf2));
253 if(sscanf(buf2, "%d,%d,%d", &c0, &c1, &c2) == 3) {
254 cfg.colours[i][0] = c0;
255 cfg.colours[i][1] = c1;
256 cfg.colours[i][2] = c2;
259 gppi (sesskey, "MouseIsXterm", 0, &cfg.mouse_is_xterm);
260 for (i=0; i<256; i+=32) {
261 static char *defaults[] = {
262 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
263 "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
264 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
265 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
266 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
267 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
268 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
269 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
271 char buf[20], buf2[256], *p;
273 sprintf(buf, "Wordness%d", i);
274 gpps (sesskey, buf, defaults[i/32], buf2, sizeof(buf2));
276 for (j=i; j<i+32; j++) {
278 while (*p && *p != ',') p++;
279 if (*p == ',') *p++ = '\0';
280 cfg.wordness[j] = atoi(q);
283 gppi (sesskey, "KoiWinXlat", 0, &cfg.xlat_enablekoiwin);
284 gppi (sesskey, "88592Xlat", 0, &cfg.xlat_88592w1250);
285 gppi (sesskey, "CapsLockCyr", 0, &cfg.xlat_capslockcyr);
286 gppi (sesskey, "ScrollBar", 1, &cfg.scrollbar);
287 gppi (sesskey, "ScrollOnKey", 0, &cfg.scroll_on_key);
288 gppi (sesskey, "LockSize", 0, &cfg.locksize);
289 gppi (sesskey, "BCE", 0, &cfg.bce);
290 gppi (sesskey, "BlinkText", 0, &cfg.blinktext);
292 close_settings_r(sesskey);
295 static void force_normal(HWND hwnd)
297 static int recurse = 0;
304 wp.length = sizeof(wp);
305 if (GetWindowPlacement(hwnd, &wp))
307 wp.showCmd = SW_SHOWNORMAL;
308 SetWindowPlacement(hwnd, &wp);
313 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
316 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
321 static int CALLBACK LogProc (HWND hwnd, UINT msg,
322 WPARAM wParam, LPARAM lParam) {
327 for (i=0; i<nevents; i++)
328 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
329 0, (LPARAM)events[i]);
331 /* case WM_CTLCOLORDLG: */
332 /* return (int) GetStockObject (LTGRAY_BRUSH); */
334 switch (LOWORD(wParam)) {
337 DestroyWindow (hwnd);
340 if (HIWORD(wParam) == BN_CLICKED ||
341 HIWORD(wParam) == BN_DOUBLECLICKED) {
344 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
345 LB_GETSELCOUNT, 0, 0);
346 selitems = malloc(selcount * sizeof(int));
348 int count = SendDlgItemMessage(hwnd, IDN_LIST,
350 selcount, (LPARAM)selitems);
354 static unsigned char sel_nl[] = SEL_NL;
357 for (i = 0; i < count; i++)
358 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
360 clipdata = malloc(size);
363 for (i = 0; i < count; i++) {
364 char *q = events[selitems[i]];
365 int qlen = strlen(q);
368 memcpy(p, sel_nl, sizeof(sel_nl));
371 write_clip(clipdata, size);
383 DestroyWindow (hwnd);
389 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
390 WPARAM wParam, LPARAM lParam) {
395 switch (LOWORD(wParam)) {
408 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
409 WPARAM wParam, LPARAM lParam) {
412 SetDlgItemText (hwnd, IDA_VERSION, ver);
414 /* case WM_CTLCOLORDLG: */
415 /* return (int) GetStockObject (LTGRAY_BRUSH); */
416 /* case WM_CTLCOLORSTATIC: */
417 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
418 /* return (int) GetStockObject (LTGRAY_BRUSH); */
420 switch (LOWORD(wParam)) {
423 DestroyWindow (hwnd);
426 EnableWindow(hwnd, 0);
427 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
429 EnableWindow(hwnd, 1);
430 SetActiveWindow(hwnd);
436 DestroyWindow (hwnd);
442 static int GeneralPanelProc (HWND hwnd, UINT msg,
443 WPARAM wParam, LPARAM lParam) {
446 SetWindowPos (hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
448 /* case WM_CTLCOLORDLG: */
449 /* return (int) GetStockObject (LTGRAY_BRUSH); */
450 /* case WM_CTLCOLORSTATIC: */
451 /* case WM_CTLCOLORBTN: */
452 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
453 /* return (int) GetStockObject (LTGRAY_BRUSH); */
455 DestroyWindow (hwnd);
461 static char savedsession[2048];
463 static int CALLBACK ConnectionProc (HWND hwnd, UINT msg,
464 WPARAM wParam, LPARAM lParam) {
469 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
470 SetDlgItemText (hwnd, IDC0_SESSEDIT, savedsession);
471 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
472 for (i = 0; i < nsessions; i++)
473 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
474 0, (LPARAM) (sessions[i]));
475 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
476 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
477 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
478 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
479 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
483 * Button release should trigger WM_OK if there was a
484 * previous double click on the session list.
488 SendMessage (GetParent(hwnd), WM_COMMAND, IDOK, 0);
491 switch (LOWORD(wParam)) {
492 case IDC0_PROTTELNET:
495 if (HIWORD(wParam) == BN_CLICKED ||
496 HIWORD(wParam) == BN_DOUBLECLICKED) {
497 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
498 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
499 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
500 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
501 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
502 cfg.port = i ? 22 : 23;
503 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
508 if (HIWORD(wParam) == EN_CHANGE)
509 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
513 if (HIWORD(wParam) == EN_CHANGE)
514 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
517 if (HIWORD(wParam) == BN_CLICKED ||
518 HIWORD(wParam) == BN_DOUBLECLICKED)
519 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC0_CLOSEEXIT);
522 if (HIWORD(wParam) == BN_CLICKED ||
523 HIWORD(wParam) == BN_DOUBLECLICKED)
524 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC0_CLOSEWARN);
527 if (HIWORD(wParam) == EN_CHANGE) {
528 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
530 GetDlgItemText (hwnd, IDC0_SESSEDIT,
531 savedsession, sizeof(savedsession)-1);
532 savedsession[sizeof(savedsession)-1] = '\0';
536 if (HIWORD(wParam) == BN_CLICKED ||
537 HIWORD(wParam) == BN_DOUBLECLICKED) {
542 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
544 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
550 strcpy (str, sessions[n]);
552 save_settings (str, !!strcmp(str, "Default Settings"));
553 get_sesslist (FALSE);
555 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
557 for (i = 0; i < nsessions; i++)
558 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
559 0, (LPARAM) (sessions[i]));
560 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
566 if (LOWORD(wParam) == IDC0_SESSLOAD &&
567 HIWORD(wParam) != BN_CLICKED &&
568 HIWORD(wParam) != BN_DOUBLECLICKED)
570 if (LOWORD(wParam) == IDC0_SESSLIST &&
571 HIWORD(wParam) != LBN_DBLCLK)
574 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
580 load_settings (sessions[n],
581 !!strcmp(sessions[n], "Default Settings"));
582 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
583 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
584 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
585 (cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
586 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW));
587 CheckDlgButton (hwnd, IDC0_CLOSEEXIT, cfg.close_on_exit);
588 CheckDlgButton (hwnd, IDC0_CLOSEWARN, cfg.warn_on_close);
589 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
592 if (LOWORD(wParam) == IDC0_SESSLIST) {
594 * A double-click on a saved session should
595 * actually start the session, not just load it.
596 * Unless it's Default Settings or some other
597 * host-less set of saved settings.
606 if (HIWORD(wParam) == BN_CLICKED ||
607 HIWORD(wParam) == BN_DOUBLECLICKED) {
608 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
610 if (n == LB_ERR || n == 0) {
614 del_settings(sessions[n]);
615 get_sesslist (FALSE);
617 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
619 for (i = 0; i < nsessions; i++)
620 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
621 0, (LPARAM) (sessions[i]));
622 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
627 return GeneralPanelProc (hwnd, msg, wParam, lParam);
630 static int CALLBACK KeyboardProc (HWND hwnd, UINT msg,
631 WPARAM wParam, LPARAM lParam) {
634 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
635 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
636 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
637 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
638 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
640 (cfg.funky_type==2 ? IDC1_FUNCXTERM
643 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
644 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
645 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
646 cfg.nethack_keypad ? IDC1_KPNH :
647 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
648 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
649 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
650 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
651 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
654 if (HIWORD(wParam) == BN_CLICKED ||
655 HIWORD(wParam) == BN_DOUBLECLICKED)
656 switch (LOWORD(wParam)) {
659 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
663 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
670 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
674 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
675 cfg.nethack_keypad = FALSE;
678 cfg.app_keypad = FALSE;
679 cfg.nethack_keypad = TRUE;
683 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
686 if (HIWORD(wParam) == BN_CLICKED ||
687 HIWORD(wParam) == BN_DOUBLECLICKED)
688 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
691 if (HIWORD(wParam) == BN_CLICKED ||
692 HIWORD(wParam) == BN_DOUBLECLICKED)
693 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
696 if (HIWORD(wParam) == BN_CLICKED ||
697 HIWORD(wParam) == BN_DOUBLECLICKED)
698 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
701 if (HIWORD(wParam) == BN_CLICKED ||
702 HIWORD(wParam) == BN_DOUBLECLICKED)
703 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
707 return GeneralPanelProc (hwnd, msg, wParam, lParam);
710 static void fmtfont (char *buf) {
711 sprintf (buf, "Font: %s, ", cfg.font);
713 strcat(buf, "bold, ");
714 if (cfg.fontheight == 0)
715 strcat (buf, "default height");
717 sprintf (buf+strlen(buf), "%d-%s",
718 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
719 (cfg.fontheight < 0 ? "pixel" : "point"));
722 static int CALLBACK TerminalProc (HWND hwnd, UINT msg,
723 WPARAM wParam, LPARAM lParam) {
726 char fontstatic[256];
730 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
731 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
732 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
733 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
734 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
735 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
736 fmtfont (fontstatic);
737 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
738 CheckDlgButton (hwnd, IDC1_BEEP, cfg.beep);
739 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
740 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
743 switch (LOWORD(wParam)) {
745 if (HIWORD(wParam) == BN_CLICKED ||
746 HIWORD(wParam) == BN_DOUBLECLICKED)
747 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
750 if (HIWORD(wParam) == BN_CLICKED ||
751 HIWORD(wParam) == BN_DOUBLECLICKED)
752 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
755 if (HIWORD(wParam) == BN_CLICKED ||
756 HIWORD(wParam) == BN_DOUBLECLICKED)
757 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
760 if (HIWORD(wParam) == EN_CHANGE)
761 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
764 if (HIWORD(wParam) == EN_CHANGE)
765 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
768 if (HIWORD(wParam) == EN_CHANGE)
769 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
771 case IDC2_CHOOSEFONT:
772 lf.lfHeight = cfg.fontheight;
773 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
774 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
775 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
776 lf.lfCharSet = cfg.fontcharset;
777 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
778 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
779 lf.lfQuality = DEFAULT_QUALITY;
780 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
781 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
782 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
784 cf.lStructSize = sizeof(cf);
787 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
788 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
790 if (ChooseFont (&cf)) {
791 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
792 cfg.font[sizeof(cfg.font)-1] = '\0';
793 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
794 cfg.fontcharset = lf.lfCharSet;
795 cfg.fontheight = lf.lfHeight;
796 fmtfont (fontstatic);
797 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
801 if (HIWORD(wParam) == BN_CLICKED ||
802 HIWORD(wParam) == BN_DOUBLECLICKED)
803 cfg.beep = IsDlgButtonChecked (hwnd, IDC1_BEEP);
806 if (HIWORD(wParam) == BN_CLICKED ||
807 HIWORD(wParam) == BN_DOUBLECLICKED)
808 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
811 if (HIWORD(wParam) == BN_CLICKED ||
812 HIWORD(wParam) == BN_DOUBLECLICKED)
813 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
818 return GeneralPanelProc (hwnd, msg, wParam, lParam);
821 static int CALLBACK WindowProc (HWND hwnd, UINT msg,
822 WPARAM wParam, LPARAM lParam) {
825 SetDlgItemText (hwnd, IDCW_WINEDIT, cfg.wintitle);
826 CheckDlgButton (hwnd, IDCW_WINNAME, cfg.win_name_always);
827 CheckDlgButton (hwnd, IDCW_BLINKCUR, cfg.blink_cur);
828 CheckDlgButton (hwnd, IDCW_SCROLLBAR, cfg.scrollbar);
829 CheckDlgButton (hwnd, IDCW_LOCKSIZE, cfg.locksize);
832 switch (LOWORD(wParam)) {
834 if (HIWORD(wParam) == BN_CLICKED ||
835 HIWORD(wParam) == BN_DOUBLECLICKED)
836 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDCW_WINNAME);
839 if (HIWORD(wParam) == BN_CLICKED ||
840 HIWORD(wParam) == BN_DOUBLECLICKED)
841 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDCW_BLINKCUR);
844 if (HIWORD(wParam) == BN_CLICKED ||
845 HIWORD(wParam) == BN_DOUBLECLICKED)
846 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDCW_SCROLLBAR);
849 if (HIWORD(wParam) == BN_CLICKED ||
850 HIWORD(wParam) == BN_DOUBLECLICKED)
851 cfg.locksize = IsDlgButtonChecked (hwnd, IDCW_LOCKSIZE);
854 if (HIWORD(wParam) == EN_CHANGE)
855 GetDlgItemText (hwnd, IDCW_WINEDIT, cfg.wintitle,
856 sizeof(cfg.wintitle)-1);
861 return GeneralPanelProc (hwnd, msg, wParam, lParam);
864 static int CALLBACK TelnetProc (HWND hwnd, UINT msg,
865 WPARAM wParam, LPARAM lParam) {
870 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
871 SetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed);
872 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
874 char *p = cfg.environmt;
876 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING, 0,
881 CheckRadioButton (hwnd, IDC3_EMBSD, IDC3_EMRFC,
882 cfg.rfc_environ ? IDC3_EMRFC : IDC3_EMBSD);
885 switch (LOWORD(wParam)) {
887 if (HIWORD(wParam) == EN_CHANGE)
888 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
889 sizeof(cfg.termtype)-1);
892 if (HIWORD(wParam) == EN_CHANGE)
893 GetDlgItemText (hwnd, IDC3_TSEDIT, cfg.termspeed,
894 sizeof(cfg.termspeed)-1);
897 if (HIWORD(wParam) == EN_CHANGE)
898 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
899 sizeof(cfg.username)-1);
903 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC3_EMRFC);
906 if (HIWORD(wParam) == BN_CLICKED ||
907 HIWORD(wParam) == BN_DOUBLECLICKED) {
908 char str[sizeof(cfg.environmt)];
910 GetDlgItemText (hwnd, IDC3_VAREDIT, str, sizeof(str)-1);
915 p = str + strlen(str);
917 GetDlgItemText (hwnd, IDC3_VALEDIT, p, sizeof(str)-1-(p-str));
927 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
929 p[strlen(str)+1] = '\0';
930 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_ADDSTRING,
932 SetDlgItemText (hwnd, IDC3_VAREDIT, "");
933 SetDlgItemText (hwnd, IDC3_VALEDIT, "");
935 MessageBox(hwnd, "Environment too big", "PuTTY Error",
936 MB_OK | MB_ICONERROR);
941 if (HIWORD(wParam) != BN_CLICKED &&
942 HIWORD(wParam) != BN_DOUBLECLICKED)
944 i = SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_GETCURSEL, 0, 0);
950 SendDlgItemMessage (hwnd, IDC3_ENVLIST, LB_DELETESTRING,
977 return GeneralPanelProc (hwnd, msg, wParam, lParam);
980 static int CALLBACK SshProc (HWND hwnd, UINT msg,
981 WPARAM wParam, LPARAM lParam) {
983 char filename[sizeof(cfg.keyfile)];
987 SetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype);
988 SetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username);
989 CheckDlgButton (hwnd, IDC3_NOPTY, cfg.nopty);
990 CheckDlgButton (hwnd, IDC3_AGENTFWD, cfg.agentfwd);
991 CheckRadioButton (hwnd, IDC3_CIPHER3DES, IDC3_CIPHERDES,
992 cfg.cipher == CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF :
993 cfg.cipher == CIPHER_DES ? IDC3_CIPHERDES :
995 CheckRadioButton (hwnd, IDC3_SSHPROT1, IDC3_SSHPROT2,
996 cfg.sshprot == 1 ? IDC3_SSHPROT1 : IDC3_SSHPROT2);
997 CheckDlgButton (hwnd, IDC3_AUTHTIS, cfg.try_tis_auth);
998 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1001 switch (LOWORD(wParam)) {
1003 if (HIWORD(wParam) == EN_CHANGE)
1004 GetDlgItemText (hwnd, IDC3_TTEDIT, cfg.termtype,
1005 sizeof(cfg.termtype)-1);
1008 if (HIWORD(wParam) == EN_CHANGE)
1009 GetDlgItemText (hwnd, IDC3_LOGEDIT, cfg.username,
1010 sizeof(cfg.username)-1);
1013 if (HIWORD(wParam) == BN_CLICKED ||
1014 HIWORD(wParam) == BN_DOUBLECLICKED)
1015 cfg.nopty = IsDlgButtonChecked (hwnd, IDC3_NOPTY);
1018 if (HIWORD(wParam) == BN_CLICKED ||
1019 HIWORD(wParam) == BN_DOUBLECLICKED)
1020 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC3_AGENTFWD);
1022 case IDC3_CIPHER3DES:
1023 case IDC3_CIPHERBLOWF:
1024 case IDC3_CIPHERDES:
1025 if (HIWORD(wParam) == BN_CLICKED ||
1026 HIWORD(wParam) == BN_DOUBLECLICKED) {
1027 if (IsDlgButtonChecked (hwnd, IDC3_CIPHER3DES))
1028 cfg.cipher = CIPHER_3DES;
1029 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERBLOWF))
1030 cfg.cipher = CIPHER_BLOWFISH;
1031 else if (IsDlgButtonChecked (hwnd, IDC3_CIPHERDES))
1032 cfg.cipher = CIPHER_DES;
1037 if (HIWORD(wParam) == BN_CLICKED ||
1038 HIWORD(wParam) == BN_DOUBLECLICKED) {
1039 if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT1))
1041 else if (IsDlgButtonChecked (hwnd, IDC3_SSHPROT2))
1046 if (HIWORD(wParam) == BN_CLICKED ||
1047 HIWORD(wParam) == BN_DOUBLECLICKED)
1048 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC3_AUTHTIS);
1051 if (HIWORD(wParam) == EN_CHANGE)
1052 GetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile,
1053 sizeof(cfg.keyfile)-1);
1057 * FIXME: this crashes. Find out why.
1059 memset(&of, 0, sizeof(of));
1060 #ifdef OPENFILENAME_SIZE_VERSION_400
1061 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1063 of.lStructSize = sizeof(of);
1065 of.hwndOwner = hwnd;
1066 of.lpstrFilter = "All Files\0*\0\0\0";
1067 of.lpstrCustomFilter = NULL;
1068 of.nFilterIndex = 1;
1069 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1070 of.nMaxFile = sizeof(filename);
1071 of.lpstrFileTitle = NULL;
1072 of.lpstrInitialDir = NULL;
1073 of.lpstrTitle = "Select Public Key File";
1075 if (GetOpenFileName(&of)) {
1076 strcpy(cfg.keyfile, filename);
1077 SetDlgItemText (hwnd, IDC3_PKEDIT, cfg.keyfile);
1083 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1086 static int CALLBACK SelectionProc (HWND hwnd, UINT msg,
1087 WPARAM wParam, LPARAM lParam) {
1092 CheckRadioButton (hwnd, IDC4_MBWINDOWS, IDC4_MBXTERM,
1093 cfg.mouse_is_xterm ? IDC4_MBXTERM : IDC4_MBWINDOWS);
1095 static int tabs[4] = {25, 61, 96, 128};
1096 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_SETTABSTOPS, 4,
1099 for (i=0; i<256; i++) {
1101 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1102 (i>=0x21 && i != 0x7F) ? i : ' ',
1104 SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_ADDSTRING, 0,
1109 switch (LOWORD(wParam)) {
1110 case IDC4_MBWINDOWS:
1112 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC4_MBXTERM);
1118 int n = GetDlgItemInt (hwnd, IDC4_CCEDIT, &ok, FALSE);
1123 for (i=0; i<256; i++)
1124 if (SendDlgItemMessage (hwnd, IDC4_CCLIST, LB_GETSEL,
1127 cfg.wordness[i] = n;
1128 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1129 LB_DELETESTRING, i, 0);
1130 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1131 (i>=0x21 && i != 0x7F) ? i : ' ',
1133 SendDlgItemMessage (hwnd, IDC4_CCLIST,
1143 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1146 static int CALLBACK ColourProc (HWND hwnd, UINT msg,
1147 WPARAM wParam, LPARAM lParam) {
1148 static const char *const colours[] = {
1149 "Default Foreground", "Default Bold Foreground",
1150 "Default Background", "Default Bold Background",
1151 "Cursor Text", "Cursor Colour",
1152 "ANSI Black", "ANSI Black Bold",
1153 "ANSI Red", "ANSI Red Bold",
1154 "ANSI Green", "ANSI Green Bold",
1155 "ANSI Yellow", "ANSI Yellow Bold",
1156 "ANSI Blue", "ANSI Blue Bold",
1157 "ANSI Magenta", "ANSI Magenta Bold",
1158 "ANSI Cyan", "ANSI Cyan Bold",
1159 "ANSI White", "ANSI White Bold"
1161 static const int permanent[] = {
1162 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
1163 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
1164 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
1168 CheckDlgButton (hwnd, IDC5_BOLDCOLOUR, cfg.bold_colour);
1169 CheckDlgButton (hwnd, IDC5_PALETTE, cfg.try_palette);
1172 for (i=0; i<22; i++)
1173 if (cfg.bold_colour || permanent[i])
1174 SendDlgItemMessage (hwnd, IDC5_LIST, LB_ADDSTRING, 0,
1175 (LPARAM) colours[i]);
1177 SendDlgItemMessage (hwnd, IDC5_LIST, LB_SETCURSEL, 0, 0);
1178 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[0][0], FALSE);
1179 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[0][1], FALSE);
1180 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[0][2], FALSE);
1183 switch (LOWORD(wParam)) {
1184 case IDC5_BOLDCOLOUR:
1185 if (HIWORD(wParam) == BN_CLICKED ||
1186 HIWORD(wParam) == BN_DOUBLECLICKED) {
1188 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC5_BOLDCOLOUR);
1189 n = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCOUNT, 0, 0);
1190 if (cfg.bold_colour && n!=22) {
1191 for (i=0; i<22; i++)
1193 SendDlgItemMessage (hwnd, IDC5_LIST,
1195 (LPARAM) colours[i]);
1196 } else if (!cfg.bold_colour && n!=12) {
1199 SendDlgItemMessage (hwnd, IDC5_LIST,
1200 LB_DELETESTRING, i, 0);
1205 if (HIWORD(wParam) == BN_CLICKED ||
1206 HIWORD(wParam) == BN_DOUBLECLICKED)
1207 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC5_PALETTE);
1210 if (HIWORD(wParam) == LBN_DBLCLK ||
1211 HIWORD(wParam) == LBN_SELCHANGE) {
1212 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1214 if (!cfg.bold_colour)
1215 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1216 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0], FALSE);
1217 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1], FALSE);
1218 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2], FALSE);
1222 if (HIWORD(wParam) == BN_CLICKED ||
1223 HIWORD(wParam) == BN_DOUBLECLICKED) {
1224 static CHOOSECOLOR cc;
1225 static DWORD custom[16] = {0}; /* zero initialisers */
1226 int i = SendDlgItemMessage (hwnd, IDC5_LIST, LB_GETCURSEL,
1228 if (!cfg.bold_colour)
1229 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1230 cc.lStructSize = sizeof(cc);
1231 cc.hwndOwner = hwnd;
1232 cc.hInstance = (HWND)hinst;
1233 cc.lpCustColors = custom;
1234 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1236 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1237 if (ChooseColor(&cc)) {
1239 (unsigned char) (cc.rgbResult & 0xFF);
1241 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1243 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1244 SetDlgItemInt (hwnd, IDC5_RVALUE, cfg.colours[i][0],
1246 SetDlgItemInt (hwnd, IDC5_GVALUE, cfg.colours[i][1],
1248 SetDlgItemInt (hwnd, IDC5_BVALUE, cfg.colours[i][2],
1256 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1259 static int CALLBACK TranslationProc (HWND hwnd, UINT msg,
1260 WPARAM wParam, LPARAM lParam) {
1263 CheckRadioButton (hwnd, IDC6_NOXLAT, IDC6_88592WIN1250,
1264 cfg.xlat_88592w1250 ? IDC6_88592WIN1250 :
1265 cfg.xlat_enablekoiwin ? IDC6_KOI8WIN1251 :
1267 CheckDlgButton (hwnd, IDC6_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1268 CheckRadioButton (hwnd, IDC2_VTXWINDOWS, IDC2_VTPOORMAN,
1269 cfg.vtmode == VT_XWINDOWS ? IDC2_VTXWINDOWS :
1270 cfg.vtmode == VT_OEMANSI ? IDC2_VTOEMANSI :
1271 cfg.vtmode == VT_OEMONLY ? IDC2_VTOEMONLY :
1274 switch (LOWORD(wParam)) {
1276 case IDC6_KOI8WIN1251:
1277 case IDC6_88592WIN1250:
1278 cfg.xlat_enablekoiwin =
1279 IsDlgButtonChecked (hwnd, IDC6_KOI8WIN1251);
1280 cfg.xlat_88592w1250 =
1281 IsDlgButtonChecked (hwnd, IDC6_88592WIN1250);
1283 case IDC6_CAPSLOCKCYR:
1284 if (HIWORD(wParam) == BN_CLICKED ||
1285 HIWORD(wParam) == BN_DOUBLECLICKED) {
1286 cfg.xlat_capslockcyr =
1287 IsDlgButtonChecked (hwnd, IDC6_CAPSLOCKCYR);
1290 case IDC2_VTXWINDOWS:
1291 case IDC2_VTOEMANSI:
1292 case IDC2_VTOEMONLY:
1293 case IDC2_VTPOORMAN:
1295 (IsDlgButtonChecked (hwnd, IDC2_VTXWINDOWS) ? VT_XWINDOWS :
1296 IsDlgButtonChecked (hwnd, IDC2_VTOEMANSI) ? VT_OEMANSI :
1297 IsDlgButtonChecked (hwnd, IDC2_VTOEMONLY) ? VT_OEMONLY :
1302 return GeneralPanelProc (hwnd, msg, wParam, lParam);
1305 static DLGPROC panelproc[NPANELS] = {
1306 ConnectionProc, KeyboardProc, TerminalProc, WindowProc,
1307 TelnetProc, SshProc, SelectionProc, ColourProc, TranslationProc
1309 static char *panelids[NPANELS] = {
1310 MAKEINTRESOURCE(IDD_PANEL0),
1311 MAKEINTRESOURCE(IDD_PANEL1),
1312 MAKEINTRESOURCE(IDD_PANEL2),
1313 MAKEINTRESOURCE(IDD_PANELW),
1314 MAKEINTRESOURCE(IDD_PANEL3),
1315 MAKEINTRESOURCE(IDD_PANEL35),
1316 MAKEINTRESOURCE(IDD_PANEL4),
1317 MAKEINTRESOURCE(IDD_PANEL5),
1318 MAKEINTRESOURCE(IDD_PANEL6)
1321 static char *names[NPANELS] = {
1322 "Connection", "Keyboard", "Terminal", "Window", "Telnet",
1323 "SSH", "Selection", "Colours", "Translation"
1326 static int mainp[MAIN_NPANELS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8};
1327 static int reconfp[RECONF_NPANELS] = { 1, 2, 3, 6, 7, 8};
1329 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1330 WPARAM wParam, LPARAM lParam,
1331 int npanels, int *panelnums, HWND *page) {
1336 { /* centre the window */
1339 hw = GetDesktopWindow();
1340 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1341 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1342 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1343 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1346 { /* initialise the tab control */
1350 hw = GetDlgItem (hwnd, IDC_TAB);
1351 for (i=0; i<npanels; i++) {
1352 tab.mask = TCIF_TEXT;
1353 tab.pszText = names[panelnums[i]];
1354 TabCtrl_InsertItem (hw, i, &tab);
1356 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1357 hwnd, panelproc[panelnums[0]]);*/
1358 *page = CreateDialog (hinst, panelids[panelnums[0]],
1359 hwnd, panelproc[panelnums[0]]);
1360 SetWindowLong (*page, GWL_EXSTYLE,
1361 GetWindowLong (*page, GWL_EXSTYLE) |
1362 WS_EX_CONTROLPARENT);
1367 if (LOWORD(wParam) == IDC_TAB &&
1368 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1369 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1371 DestroyWindow (*page);
1372 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1373 hwnd, panelproc[panelnums[i]]);*/
1374 *page = CreateDialog (hinst, panelids[panelnums[i]],
1375 hwnd, panelproc[panelnums[i]]);
1376 SetWindowLong (*page, GWL_EXSTYLE,
1377 GetWindowLong (*page, GWL_EXSTYLE) |
1378 WS_EX_CONTROLPARENT);
1379 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1383 /* case WM_CTLCOLORDLG: */
1384 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1386 switch (LOWORD(wParam)) {
1389 EndDialog (hwnd, 1);
1394 EndDialog (hwnd, 0);
1399 EndDialog (hwnd, 0);
1402 /* Grrr Explorer will maximize Dialogs! */
1404 if (wParam == SIZE_MAXIMIZED)
1411 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1412 WPARAM wParam, LPARAM lParam) {
1417 static HWND page = NULL;
1419 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1422 * If the Connection panel is active and the Session List
1423 * box is selected, we treat a press of Open to have an
1424 * implicit press of Load preceding it.
1426 hw = GetDlgItem (hwnd, IDC_TAB);
1427 i = TabCtrl_GetCurSel(hw);
1428 if (panelproc[mainp[i]] == ConnectionProc &&
1429 page && implicit_load_ok) {
1430 SendMessage (page, WM_COMMAND,
1431 MAKELONG(IDC0_SESSLOAD, BN_CLICKED), 0);
1435 if (msg == WM_COMMAND && LOWORD(wParam) == IDC_ABOUT) {
1436 EnableWindow(hwnd, 0);
1437 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1438 GetParent(hwnd), AboutProc);
1439 EnableWindow(hwnd, 1);
1440 SetActiveWindow(hwnd);
1442 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1443 MAIN_NPANELS, mainp, &page);
1446 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1447 WPARAM wParam, LPARAM lParam) {
1449 return GenericMainDlgProc (hwnd, msg, wParam, lParam,
1450 RECONF_NPANELS, reconfp, &page);
1453 void get_sesslist(int allocate) {
1454 static char otherbuf[2048];
1455 static char *buffer;
1456 int buflen, bufsize, i;
1462 if ((handle = enum_settings_start()) == NULL)
1465 buflen = bufsize = 0;
1468 ret = enum_settings_next(handle, otherbuf, sizeof(otherbuf));
1470 int len = strlen(otherbuf)+1;
1471 if (bufsize < buflen+len) {
1472 bufsize = buflen + len + 2048;
1473 buffer = srealloc(buffer, bufsize);
1475 strcpy(buffer+buflen, otherbuf);
1476 buflen += strlen(buffer+buflen)+1;
1479 enum_settings_finish(handle);
1480 buffer = srealloc(buffer, buflen+1);
1481 buffer[buflen] = '\0';
1484 nsessions = 1; /* "Default Settings" counts as one */
1486 if (strcmp(p, "Default Settings"))
1492 sessions = smalloc(nsessions * sizeof(char *));
1493 sessions[0] = "Default Settings";
1497 if (strcmp(p, "Default Settings"))
1508 int do_config (void) {
1512 savedsession[0] = '\0';
1513 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1514 get_sesslist(FALSE);
1519 int do_reconfig (HWND hwnd) {
1523 backup_cfg = cfg; /* structure copy */
1524 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1526 cfg = backup_cfg; /* structure copy */
1533 void do_defaults (char *session) {
1535 load_settings (session, TRUE);
1537 load_settings ("Default Settings", FALSE);
1540 void logevent (char *string) {
1541 if (nevents >= negsize) {
1543 events = srealloc (events, negsize * sizeof(*events));
1545 events[nevents] = smalloc(1+strlen(string));
1546 strcpy (events[nevents], string);
1550 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1552 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1553 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1557 void showeventlog (HWND hwnd) {
1559 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1561 ShowWindow (logbox, SW_SHOWNORMAL);
1565 void showabout (HWND hwnd) {
1567 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1569 ShowWindow (abtbox, SW_SHOWNORMAL);
1573 void verify_ssh_host_key(char *host, int port, char *keytype,
1574 char *keystr, char *fingerprint) {
1577 static const char absentmsg[] =
1578 "The server's host key is not cached in the registry. You\n"
1579 "have no guarantee that the server is the computer you\n"
1581 "The server's key fingerprint is:\n"
1583 "If you trust this host, hit Yes to add the key to\n"
1584 "PuTTY's cache and carry on connecting.\n"
1585 "If you do not trust this host, hit No to abandon the\n"
1588 static const char wrongmsg[] =
1589 "WARNING - POTENTIAL SECURITY BREACH!\n"
1591 "The server's host key does not match the one PuTTY has\n"
1592 "cached in the registry. This means that either the\n"
1593 "server administrator has changed the host key, or you\n"
1594 "have actually connected to another computer pretending\n"
1595 "to be the server.\n"
1596 "The new key fingerprint is:\n"
1598 "If you were expecting this change and trust the new key,\n"
1599 "hit Yes to update PuTTY's cache and continue connecting.\n"
1600 "If you want to carry on connecting but without updating\n"
1601 "the cache, hit No.\n"
1602 "If you want to abandon the connection completely, hit\n"
1603 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1606 static const char mbtitle[] = "PuTTY Security Alert";
1609 char message[160+ /* sensible fingerprint max size */
1610 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1611 sizeof(absentmsg) : sizeof(wrongmsg))];
1614 * Verify the key against the registry.
1616 ret = verify_host_key(host, port, keytype, keystr);
1618 if (ret == 0) /* success - key matched OK */
1620 if (ret == 2) { /* key was different */
1622 sprintf(message, wrongmsg, fingerprint);
1623 mbret = MessageBox(NULL, message, mbtitle,
1624 MB_ICONWARNING | MB_YESNOCANCEL);
1626 store_host_key(host, port, keytype, keystr);
1627 if (mbret == IDCANCEL)
1630 if (ret == 1) { /* key was absent */
1632 sprintf(message, absentmsg, fingerprint);
1633 mbret = MessageBox(NULL, message, mbtitle,
1634 MB_ICONWARNING | MB_YESNO);
1637 store_host_key(host, port, keytype, keystr);