13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
16 static HWND logbox = NULL, abtbox = NULL;
20 static void force_normal(HWND hwnd)
22 static int recurse = 0;
29 wp.length = sizeof(wp);
30 if (GetWindowPlacement(hwnd, &wp))
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
38 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
46 static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
52 for (i=0; i<nevents; i++)
53 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
54 0, (LPARAM)events[i]);
57 switch (LOWORD(wParam)) {
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
69 selitems = malloc(selcount * sizeof(int));
71 int count = SendDlgItemMessage(hwnd, IDN_LIST,
73 selcount, (LPARAM)selitems);
77 static unsigned char sel_nl[] = SEL_NL;
79 if (count == 0) { /* can't copy zero stuff */
85 for (i = 0; i < count; i++)
86 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
88 clipdata = malloc(size);
91 for (i = 0; i < count; i++) {
92 char *q = events[selitems[i]];
96 memcpy(p, sel_nl, sizeof(sel_nl));
99 write_clip(clipdata, size, TRUE);
104 for (i = 0; i < nevents; i++)
105 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
114 DestroyWindow (hwnd);
120 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
121 WPARAM wParam, LPARAM lParam) {
126 switch (LOWORD(wParam)) {
139 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
140 WPARAM wParam, LPARAM lParam) {
143 SetDlgItemText (hwnd, IDA_VERSION, ver);
146 switch (LOWORD(wParam)) {
149 DestroyWindow (hwnd);
152 EnableWindow(hwnd, 0);
153 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
155 EnableWindow(hwnd, 1);
156 SetActiveWindow(hwnd);
162 DestroyWindow (hwnd);
169 * Null dialog procedure.
171 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
172 WPARAM wParam, LPARAM lParam) {
176 static char savedsession[2048];
178 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
182 IDC_BOX_SESSION1, IDC_BOXT_SESSION1,
183 IDC_BOX_SESSION2, IDC_BOXT_SESSION2,
204 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1,
205 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2,
206 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3,
232 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
244 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
245 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
263 appearancepanelstart,
264 IDC_TITLE_APPEARANCE,
265 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1,
266 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2,
267 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3,
276 connectionpanelstart,
277 IDC_TITLE_CONNECTION,
278 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
279 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
290 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
291 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
309 IDC_BOX_SSH1, IDC_BOXT_SSH1,
310 IDC_BOX_SSH2, IDC_BOXT_SSH2,
311 IDC_BOX_SSH3, IDC_BOXT_SSH3,
332 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
333 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
346 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
347 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
361 translationpanelstart,
362 IDC_TITLE_TRANSLATION,
363 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
364 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
365 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
382 static const char *const colours[] = {
383 "Default Foreground", "Default Bold Foreground",
384 "Default Background", "Default Bold Background",
385 "Cursor Text", "Cursor Colour",
386 "ANSI Black", "ANSI Black Bold",
387 "ANSI Red", "ANSI Red Bold",
388 "ANSI Green", "ANSI Green Bold",
389 "ANSI Yellow", "ANSI Yellow Bold",
390 "ANSI Blue", "ANSI Blue Bold",
391 "ANSI Magenta", "ANSI Magenta Bold",
392 "ANSI Cyan", "ANSI Cyan Bold",
393 "ANSI White", "ANSI White Bold"
395 static const int permcolour[] = {
396 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
397 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
398 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
401 static void fmtfont (char *buf) {
402 sprintf (buf, "Font: %s, ", cfg.font);
404 strcat(buf, "bold, ");
405 if (cfg.fontheight == 0)
406 strcat (buf, "default height");
408 sprintf (buf+strlen(buf), "%d-%s",
409 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
410 (cfg.fontheight < 0 ? "pixel" : "point"));
413 static void init_dlg_ctrls(HWND hwnd) {
415 char fontstatic[256];
417 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
418 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
419 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
420 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
421 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
422 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : IDC_PROTRAW );
423 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
425 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
426 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
427 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
428 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
429 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
430 cfg.funky_type == 0 ? IDC_FUNCTILDE :
431 cfg.funky_type == 1 ? IDC_FUNCLINUX :
432 cfg.funky_type == 2 ? IDC_FUNCXTERM :
433 cfg.funky_type == 3 ? IDC_FUNCVT400 :
435 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
436 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
437 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
438 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
439 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
440 cfg.nethack_keypad ? IDC_KPNH :
441 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
442 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
443 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
444 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
445 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
446 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
447 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
448 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
450 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
451 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
452 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
453 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
454 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
455 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
456 fmtfont (fontstatic);
457 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
458 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
459 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
460 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
462 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
463 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
464 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
465 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
466 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
467 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
468 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
470 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
471 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
472 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
474 char *p = cfg.environmt;
476 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
481 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
482 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
484 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
485 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
486 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
487 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
488 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
489 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
490 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
491 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
493 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
494 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
495 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
496 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
497 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
499 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
500 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
502 static int tabs[4] = {25, 61, 96, 128};
503 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
506 for (i=0; i<256; i++) {
508 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
509 (i>=0x21 && i != 0x7F) ? i : ' ',
511 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
515 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
516 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
520 if (cfg.bold_colour || permcolour[i])
521 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
522 (LPARAM) colours[i]);
524 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
525 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
526 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
527 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
529 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
530 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
531 cfg.xlat_88592cp852 ? IDC_88592CP852 :
532 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
534 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
535 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
536 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
537 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
538 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
542 static void hide(HWND hwnd, int hide, int minid, int maxid) {
544 for (i = minid; i < maxid; i++) {
545 HWND ctl = GetDlgItem(hwnd, i);
547 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
552 struct treeview_faff {
557 static HTREEITEM treeview_insert(struct treeview_faff *faff,
558 int level, char *text) {
562 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
563 ins.hInsertAfter = faff->lastat[level];
564 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
565 #define INSITEM DUMMYUNIONNAME.item
569 ins.INSITEM.mask = TVIF_TEXT;
570 ins.INSITEM.pszText = text;
571 newitem = TreeView_InsertItem(faff->treeview, &ins);
573 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
574 faff->lastat[level] = newitem;
575 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
580 * This _huge_ function is the configuration box.
582 static int GenericMainDlgProc (HWND hwnd, UINT msg,
583 WPARAM wParam, LPARAM lParam,
586 struct treeview_faff tvfaff;
589 char filename[sizeof(cfg.keyfile)];
592 char fontstatic[256];
598 SetWindowLong(hwnd, GWL_USERDATA, 0);
602 { /* centre the window */
605 hw = GetDesktopWindow();
606 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
607 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
608 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
609 rd.right-rd.left, rd.bottom-rd.top, TRUE);
613 * Create the tree view.
620 r.left = 3; r.right = r.left + 75;
621 r.top = 3; r.bottom = r.top + 10;
622 MapDialogRect(hwnd, &r);
623 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
624 WS_CHILD | WS_VISIBLE,
626 r.right-r.left, r.bottom-r.top,
627 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
628 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
629 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
631 r.left = 3; r.right = r.left + 75;
632 r.top = 13; r.bottom = r.top + 196;
633 MapDialogRect(hwnd, &r);
634 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
635 WS_CHILD | WS_VISIBLE |
636 WS_TABSTOP | TVS_HASLINES |
637 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
638 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
640 r.right-r.left, r.bottom-r.top,
641 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
642 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
643 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
644 tvfaff.treeview = treeview;
645 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
649 * Create the various panelfuls of controls.
652 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
655 ctlposinit(&cp, hwnd, 80, 3, 13);
656 bartitle(&cp, "Basic options for your PuTTY session",
659 beginbox(&cp, "Specify your connection by host name",
660 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
662 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
663 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
664 if (backends[2].backend == NULL) {
665 /* this is PuTTYtel, so only two protocols available */
666 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
668 "&Telnet", IDC_PROTTELNET, NULL);
670 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
672 "&Telnet", IDC_PROTTELNET,
681 beginbox(&cp, "Load, save or delete a stored session",
682 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
683 sesssaver(&cp, "Sav&ed Sessions",
684 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
685 "&Load", IDC_SESSLOAD,
686 "&Save", IDC_SESSSAVE,
687 "&Delete", IDC_SESSDEL, NULL);
690 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
691 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
694 hsession = treeview_insert(&tvfaff, 0, "Session");
697 /* The Terminal panel. Accelerators used: [acgo] &dlbenu */
700 ctlposinit(&cp, hwnd, 80, 3, 13);
701 bartitle(&cp, "Options controlling the terminal emulation",
703 beginbox(&cp, "Set various terminal options",
704 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
705 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
706 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
707 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
708 checkbox(&cp, "&Beep enabled", IDC_BEEP);
709 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
710 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
711 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
714 treeview_insert(&tvfaff, 0, "Terminal");
717 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
720 ctlposinit(&cp, hwnd, 80, 3, 13);
721 bartitle(&cp, "Options controlling the effects of keys",
723 beginbox(&cp, "Change the sequences sent by:",
724 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
725 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
726 "Control-&H", IDC_DEL008,
727 "Control-&? (127)", IDC_DEL127, NULL);
728 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
729 "&Standard", IDC_HOMETILDE,
730 "&rxvt", IDC_HOMERXVT, NULL);
731 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
732 "ESC[n&~", IDC_FUNCTILDE,
733 "&Linux", IDC_FUNCLINUX,
734 "&Xterm R6", IDC_FUNCXTERM,
735 "&VT400", IDC_FUNCVT400, NULL);
737 beginbox(&cp, "Application keypad settings:",
738 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
740 "Application c&ursor keys totally disabled",
742 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
743 "&Normal", IDC_CURNORMAL,
744 "A&pplication", IDC_CURAPPLIC, NULL);
746 "Application ke&ypad keys totally disabled",
748 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
749 "Nor&mal", IDC_KPNORMAL,
750 "Appl&ication", IDC_KPAPPLIC,
751 "N&etHack", IDC_KPNH, NULL);
753 beginbox(&cp, "Enable extra keyboard features:",
754 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
755 checkbox(&cp, "Application and AltGr ac&t as Compose key",
759 treeview_insert(&tvfaff, 1, "Keyboard");
762 /* The Window panel. Accelerators used: [acgo] bsdkw4ylp */
765 ctlposinit(&cp, hwnd, 80, 3, 13);
766 bartitle(&cp, "Options controlling PuTTY's window",
768 beginbox(&cp, "Set the size of the window",
769 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
771 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
772 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
774 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
776 beginbox(&cp, "Control the scrollback in the window",
777 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
778 staticedit(&cp, "Lines of &scrollback",
779 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
780 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
781 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
782 checkbox(&cp, "Reset scrollback on dis&play activity",
785 beginbox(&cp, NULL, IDC_BOX_WINDOW3, 0);
786 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
787 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
788 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
789 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
792 treeview_insert(&tvfaff, 0, "Window");
795 /* The Appearance panel. Accelerators used: [acgo] rmkhti */
798 ctlposinit(&cp, hwnd, 80, 3, 13);
799 bartitle(&cp, "Options controlling PuTTY's appearance",
800 IDC_TITLE_APPEARANCE);
801 beginbox(&cp, "Adjust the use of the cursor",
802 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1);
803 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
805 beginbox(&cp, "Set the font used in the terminal window",
806 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2);
807 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
809 beginbox(&cp, "Adjust the use of the window title",
810 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3);
813 "Initial window &title:", IDC_WINTITLE,
814 IDC_WINEDIT, 100, NULL);
815 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
818 treeview_insert(&tvfaff, 1, "Appearance");
821 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
824 ctlposinit(&cp, hwnd, 80, 3, 13);
825 bartitle(&cp, "Options controlling character set translation",
826 IDC_TITLE_TRANSLATION);
827 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
828 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
830 "Handling of line drawing characters:", IDC_VTSTATIC,
831 "Font has &XWindows encoding", IDC_VTXWINDOWS,
832 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
833 "Use font in O&EM mode only", IDC_VTOEMONLY,
834 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
835 IDC_VTPOORMAN, NULL);
837 beginbox(&cp, "Enable character set translation on received data",
838 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
840 "Character set translation:", IDC_XLATSTATIC,
842 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
843 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
844 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
846 beginbox(&cp, "Enable character set translation on input data",
847 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
848 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
852 treeview_insert(&tvfaff, 1, "Translation");
855 /* The Selection panel. Accelerators used: [acgo] wxst */
858 ctlposinit(&cp, hwnd, 80, 3, 13);
859 bartitle(&cp, "Options controlling copy and paste",
860 IDC_TITLE_SELECTION);
861 beginbox(&cp, "Control which mouse button does which thing",
862 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
863 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
864 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
865 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
868 beginbox(&cp, "Control the select-one-word-at-a-time mode",
869 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
870 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
871 "&Set", IDC_CCSET, IDC_CCEDIT,
872 "&to class", IDC_CCSTATIC2);
875 treeview_insert(&tvfaff, 1, "Selection");
878 /* The Colours panel. Accelerators used: [acgo] blum */
881 ctlposinit(&cp, hwnd, 80, 3, 13);
882 bartitle(&cp, "Options controlling use of colours",
884 beginbox(&cp, "General options for colour usage",
885 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
886 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
887 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
889 beginbox(&cp, "Adjust the precise colours PuTTY displays",
890 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
891 colouredit(&cp, "Select a colo&ur and then click to modify it:",
892 IDC_COLOURSTATIC, IDC_COLOURLIST,
893 "&Modify...", IDC_CHANGE,
894 "Red:", IDC_RSTATIC, IDC_RVALUE,
895 "Green:", IDC_GSTATIC, IDC_GVALUE,
896 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
899 treeview_insert(&tvfaff, 1, "Colours");
902 /* The Connection panel. Accelerators used: [acgo] tuk */
905 ctlposinit(&cp, hwnd, 80, 3, 13);
906 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
908 beginbox(&cp, "Data to send to the server",
909 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
910 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
911 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
914 beginbox(&cp, "Sending of null packets to keep session active",
915 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
916 staticedit(&cp, "Minutes between &keepalives (0 to turn off)",
917 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
920 treeview_insert(&tvfaff, 0, "Connection");
923 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
926 ctlposinit(&cp, hwnd, 80, 3, 13);
928 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
929 beginbox(&cp, "Data to send to the server",
930 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
931 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
932 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
933 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
934 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
936 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
938 beginbox(&cp, "Telnet protocol adjustments",
939 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
940 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
941 "&BSD (commonplace)", IDC_EMBSD,
942 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
945 treeview_insert(&tvfaff, 1, "Telnet");
949 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
950 if (backends[2].backend != NULL) {
952 ctlposinit(&cp, hwnd, 80, 3, 13);
954 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
955 beginbox(&cp, "Data to send to the server",
956 IDC_BOX_SSH1, IDC_BOXT_SSH1);
958 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
961 beginbox(&cp, "Authentication options",
962 IDC_BOX_SSH2, IDC_BOXT_SSH2);
963 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
965 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
966 editbutton(&cp, "Private &key file for authentication:",
967 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
969 beginbox(&cp, "Protocol options",
970 IDC_BOX_SSH3, IDC_BOXT_SSH3);
971 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
972 radioline(&cp, "Preferred SSH protocol version:",
973 IDC_SSHPROTSTATIC, 2,
974 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
975 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
976 "&3DES", IDC_CIPHER3DES,
977 "&Blowfish", IDC_CIPHERBLOWF,
978 "&DES", IDC_CIPHERDES, NULL);
979 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
983 treeview_insert(&tvfaff, 1, "SSH");
987 init_dlg_ctrls(hwnd);
988 for (i = 0; i < nsessions; i++)
989 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
990 0, (LPARAM) (sessions[i]));
993 * Hide all the controls to start with.
995 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
998 * Put the treeview selection on to the Session panel. This
999 * should also cause unhiding of the relevant controls.
1001 TreeView_SelectItem(treeview, hsession);
1004 * Set focus into the first available control.
1008 ctl = GetDlgItem(hwnd, IDC_HOST);
1009 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1013 SetWindowLong(hwnd, GWL_USERDATA, 1);
1017 * Button release should trigger WM_OK if there was a
1018 * previous double click on the session list.
1022 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1025 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1026 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1027 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1031 item.pszText = buffer;
1032 item.cchTextMax = sizeof(buffer);
1033 item.mask = TVIF_TEXT;
1034 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1035 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1036 if (!strcmp(buffer, "Session"))
1037 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1038 if (!strcmp(buffer, "Keyboard"))
1039 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1040 if (!strcmp(buffer, "Terminal"))
1041 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1042 if (!strcmp(buffer, "Window"))
1043 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1044 if (!strcmp(buffer, "Appearance"))
1045 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
1046 if (!strcmp(buffer, "Connection"))
1047 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1048 if (!strcmp(buffer, "Telnet"))
1049 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1050 if (!strcmp(buffer, "SSH"))
1051 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1052 if (!strcmp(buffer, "Selection"))
1053 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1054 if (!strcmp(buffer, "Colours"))
1055 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1056 if (!strcmp(buffer, "Translation"))
1057 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1059 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1065 * Only process WM_COMMAND once the dialog is fully formed.
1067 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1070 EndDialog (hwnd, 1);
1075 EndDialog (hwnd, 0);
1077 case IDC_PROTTELNET:
1080 if (HIWORD(wParam) == BN_CLICKED ||
1081 HIWORD(wParam) == BN_DOUBLECLICKED) {
1082 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1083 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1084 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1085 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1086 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1087 cfg.port = i ? 22 : 23;
1088 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1093 if (HIWORD(wParam) == EN_CHANGE)
1094 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1095 sizeof(cfg.host)-1);
1098 if (HIWORD(wParam) == EN_CHANGE)
1099 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1102 if (HIWORD(wParam) == EN_CHANGE) {
1103 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1105 GetDlgItemText (hwnd, IDC_SESSEDIT,
1106 savedsession, sizeof(savedsession)-1);
1107 savedsession[sizeof(savedsession)-1] = '\0';
1111 if (HIWORD(wParam) == BN_CLICKED ||
1112 HIWORD(wParam) == BN_DOUBLECLICKED) {
1117 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1119 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1120 LB_GETCURSEL, 0, 0);
1125 strcpy (str, sessions[n]);
1127 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1128 get_sesslist (FALSE);
1129 get_sesslist (TRUE);
1130 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1132 for (i = 0; i < nsessions; i++)
1133 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1134 0, (LPARAM) (sessions[i]));
1135 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1141 if (LOWORD(wParam) == IDC_SESSLOAD &&
1142 HIWORD(wParam) != BN_CLICKED &&
1143 HIWORD(wParam) != BN_DOUBLECLICKED)
1145 if (LOWORD(wParam) == IDC_SESSLIST &&
1146 HIWORD(wParam) != LBN_DBLCLK)
1149 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1150 LB_GETCURSEL, 0, 0);
1156 isdef = !strcmp(sessions[n], "Default Settings");
1157 load_settings (sessions[n], !isdef, &cfg);
1158 init_dlg_ctrls(hwnd);
1160 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1162 if (LOWORD(wParam) == IDC_SESSLIST) {
1164 * A double-click on a saved session should
1165 * actually start the session, not just load it.
1166 * Unless it's Default Settings or some other
1167 * host-less set of saved settings.
1176 if (HIWORD(wParam) == BN_CLICKED ||
1177 HIWORD(wParam) == BN_DOUBLECLICKED) {
1178 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1179 LB_GETCURSEL, 0, 0);
1180 if (n == LB_ERR || n == 0) {
1184 del_settings(sessions[n]);
1185 get_sesslist (FALSE);
1186 get_sesslist (TRUE);
1187 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1189 for (i = 0; i < nsessions; i++)
1190 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1191 0, (LPARAM) (sessions[i]));
1192 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1196 if (HIWORD(wParam) == EN_CHANGE)
1197 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1201 if (HIWORD(wParam) == BN_CLICKED ||
1202 HIWORD(wParam) == BN_DOUBLECLICKED)
1203 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1207 if (HIWORD(wParam) == BN_CLICKED ||
1208 HIWORD(wParam) == BN_DOUBLECLICKED)
1209 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1212 if (HIWORD(wParam) == BN_CLICKED ||
1213 HIWORD(wParam) == BN_DOUBLECLICKED)
1217 if (HIWORD(wParam) == BN_CLICKED ||
1218 HIWORD(wParam) == BN_DOUBLECLICKED)
1223 if (HIWORD(wParam) == BN_CLICKED ||
1224 HIWORD(wParam) == BN_DOUBLECLICKED)
1225 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1229 if (HIWORD(wParam) == BN_CLICKED ||
1230 HIWORD(wParam) == BN_DOUBLECLICKED) {
1231 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1232 cfg.nethack_keypad = FALSE;
1236 if (HIWORD(wParam) == BN_CLICKED ||
1237 HIWORD(wParam) == BN_DOUBLECLICKED) {
1238 cfg.app_keypad = FALSE;
1239 cfg.nethack_keypad = TRUE;
1244 if (HIWORD(wParam) == BN_CLICKED ||
1245 HIWORD(wParam) == BN_DOUBLECLICKED)
1246 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1249 if (HIWORD(wParam) == BN_CLICKED ||
1250 HIWORD(wParam) == BN_DOUBLECLICKED)
1251 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1254 if (HIWORD(wParam) == BN_CLICKED ||
1255 HIWORD(wParam) == BN_DOUBLECLICKED)
1256 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1259 if (HIWORD(wParam) == BN_CLICKED ||
1260 HIWORD(wParam) == BN_DOUBLECLICKED)
1261 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1264 if (HIWORD(wParam) == BN_CLICKED ||
1265 HIWORD(wParam) == BN_DOUBLECLICKED)
1266 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1269 if (HIWORD(wParam) == BN_CLICKED ||
1270 HIWORD(wParam) == BN_DOUBLECLICKED)
1271 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1274 if (HIWORD(wParam) == BN_CLICKED ||
1275 HIWORD(wParam) == BN_DOUBLECLICKED)
1276 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1279 if (HIWORD(wParam) == BN_CLICKED ||
1280 HIWORD(wParam) == BN_DOUBLECLICKED)
1281 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1283 case IDC_SCROLLDISP:
1284 if (HIWORD(wParam) == BN_CLICKED ||
1285 HIWORD(wParam) == BN_DOUBLECLICKED)
1286 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1288 case IDC_COMPOSEKEY:
1289 if (HIWORD(wParam) == BN_CLICKED ||
1290 HIWORD(wParam) == BN_DOUBLECLICKED)
1291 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1294 if (HIWORD(wParam) == BN_CLICKED ||
1295 HIWORD(wParam) == BN_DOUBLECLICKED)
1296 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1299 if (HIWORD(wParam) == BN_CLICKED ||
1300 HIWORD(wParam) == BN_DOUBLECLICKED)
1301 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1304 if (HIWORD(wParam) == BN_CLICKED ||
1305 HIWORD(wParam) == BN_DOUBLECLICKED)
1306 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1309 if (HIWORD(wParam) == EN_CHANGE)
1310 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1313 if (HIWORD(wParam) == EN_CHANGE)
1314 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1317 if (HIWORD(wParam) == EN_CHANGE)
1318 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1320 case IDC_CHOOSEFONT:
1321 lf.lfHeight = cfg.fontheight;
1322 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1323 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1324 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1325 lf.lfCharSet = cfg.fontcharset;
1326 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1327 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1328 lf.lfQuality = DEFAULT_QUALITY;
1329 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1330 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1331 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1333 cf.lStructSize = sizeof(cf);
1334 cf.hwndOwner = hwnd;
1336 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1337 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1339 if (ChooseFont (&cf)) {
1340 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1341 cfg.font[sizeof(cfg.font)-1] = '\0';
1342 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1343 cfg.fontcharset = lf.lfCharSet;
1344 cfg.fontheight = lf.lfHeight;
1345 fmtfont (fontstatic);
1346 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1350 if (HIWORD(wParam) == BN_CLICKED ||
1351 HIWORD(wParam) == BN_DOUBLECLICKED)
1352 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1355 if (HIWORD(wParam) == BN_CLICKED ||
1356 HIWORD(wParam) == BN_DOUBLECLICKED)
1357 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1360 if (HIWORD(wParam) == BN_CLICKED ||
1361 HIWORD(wParam) == BN_DOUBLECLICKED)
1362 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1365 if (HIWORD(wParam) == BN_CLICKED ||
1366 HIWORD(wParam) == BN_DOUBLECLICKED)
1367 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1370 if (HIWORD(wParam) == BN_CLICKED ||
1371 HIWORD(wParam) == BN_DOUBLECLICKED)
1372 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1375 if (HIWORD(wParam) == BN_CLICKED ||
1376 HIWORD(wParam) == BN_DOUBLECLICKED)
1377 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1380 if (HIWORD(wParam) == BN_CLICKED ||
1381 HIWORD(wParam) == BN_DOUBLECLICKED)
1382 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1385 if (HIWORD(wParam) == EN_CHANGE)
1386 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1387 sizeof(cfg.wintitle)-1);
1390 if (HIWORD(wParam) == BN_CLICKED ||
1391 HIWORD(wParam) == BN_DOUBLECLICKED)
1392 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1395 if (HIWORD(wParam) == BN_CLICKED ||
1396 HIWORD(wParam) == BN_DOUBLECLICKED)
1397 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1400 if (HIWORD(wParam) == EN_CHANGE)
1401 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1402 sizeof(cfg.termtype)-1);
1405 if (HIWORD(wParam) == EN_CHANGE)
1406 GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
1407 sizeof(cfg.termspeed)-1);
1410 if (HIWORD(wParam) == EN_CHANGE)
1411 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1412 sizeof(cfg.username)-1);
1416 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1419 if (HIWORD(wParam) == BN_CLICKED ||
1420 HIWORD(wParam) == BN_DOUBLECLICKED) {
1421 char str[sizeof(cfg.environmt)];
1423 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1428 p = str + strlen(str);
1430 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1440 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1442 p[strlen(str)+1] = '\0';
1443 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1445 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1446 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1448 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1449 MB_OK | MB_ICONERROR);
1454 if (HIWORD(wParam) != BN_CLICKED &&
1455 HIWORD(wParam) != BN_DOUBLECLICKED)
1457 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1463 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1488 if (HIWORD(wParam) == BN_CLICKED ||
1489 HIWORD(wParam) == BN_DOUBLECLICKED)
1490 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1493 if (HIWORD(wParam) == BN_CLICKED ||
1494 HIWORD(wParam) == BN_DOUBLECLICKED)
1495 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1498 if (HIWORD(wParam) == BN_CLICKED ||
1499 HIWORD(wParam) == BN_DOUBLECLICKED)
1500 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1502 case IDC_CIPHER3DES:
1503 case IDC_CIPHERBLOWF:
1505 if (HIWORD(wParam) == BN_CLICKED ||
1506 HIWORD(wParam) == BN_DOUBLECLICKED) {
1507 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1508 cfg.cipher = CIPHER_3DES;
1509 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1510 cfg.cipher = CIPHER_BLOWFISH;
1511 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1512 cfg.cipher = CIPHER_DES;
1517 if (HIWORD(wParam) == BN_CLICKED ||
1518 HIWORD(wParam) == BN_DOUBLECLICKED) {
1519 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1521 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1526 if (HIWORD(wParam) == BN_CLICKED ||
1527 HIWORD(wParam) == BN_DOUBLECLICKED)
1528 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1531 if (HIWORD(wParam) == EN_CHANGE)
1532 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1533 sizeof(cfg.keyfile)-1);
1536 if (HIWORD(wParam) == EN_CHANGE)
1537 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1538 sizeof(cfg.remote_cmd)-1);
1541 memset(&of, 0, sizeof(of));
1542 #ifdef OPENFILENAME_SIZE_VERSION_400
1543 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1545 of.lStructSize = sizeof(of);
1547 of.hwndOwner = hwnd;
1548 of.lpstrFilter = "All Files\0*\0\0\0";
1549 of.lpstrCustomFilter = NULL;
1550 of.nFilterIndex = 1;
1551 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1552 of.nMaxFile = sizeof(filename);
1553 of.lpstrFileTitle = NULL;
1554 of.lpstrInitialDir = NULL;
1555 of.lpstrTitle = "Select Public Key File";
1557 if (GetOpenFileName(&of)) {
1558 strcpy(cfg.keyfile, filename);
1559 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1564 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1570 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1575 for (i=0; i<256; i++)
1576 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1579 cfg.wordness[i] = n;
1580 SendDlgItemMessage (hwnd, IDC_CCLIST,
1581 LB_DELETESTRING, i, 0);
1582 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1583 (i>=0x21 && i != 0x7F) ? i : ' ',
1585 SendDlgItemMessage (hwnd, IDC_CCLIST,
1592 case IDC_BOLDCOLOUR:
1593 if (HIWORD(wParam) == BN_CLICKED ||
1594 HIWORD(wParam) == BN_DOUBLECLICKED) {
1596 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1597 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1598 if (cfg.bold_colour && n!=22) {
1599 for (i=0; i<22; i++)
1601 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1603 (LPARAM) colours[i]);
1604 } else if (!cfg.bold_colour && n!=12) {
1607 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1608 LB_DELETESTRING, i, 0);
1613 if (HIWORD(wParam) == BN_CLICKED ||
1614 HIWORD(wParam) == BN_DOUBLECLICKED)
1615 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1617 case IDC_COLOURLIST:
1618 if (HIWORD(wParam) == LBN_DBLCLK ||
1619 HIWORD(wParam) == LBN_SELCHANGE) {
1620 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1622 if (!cfg.bold_colour)
1623 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1624 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1625 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1626 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1630 if (HIWORD(wParam) == BN_CLICKED ||
1631 HIWORD(wParam) == BN_DOUBLECLICKED) {
1632 static CHOOSECOLOR cc;
1633 static DWORD custom[16] = {0}; /* zero initialisers */
1634 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1636 if (!cfg.bold_colour)
1637 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1638 cc.lStructSize = sizeof(cc);
1639 cc.hwndOwner = hwnd;
1640 cc.hInstance = (HWND)hinst;
1641 cc.lpCustColors = custom;
1642 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1644 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1645 if (ChooseColor(&cc)) {
1647 (unsigned char) (cc.rgbResult & 0xFF);
1649 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1651 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1652 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1654 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1656 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1662 case IDC_KOI8WIN1251:
1663 case IDC_88592WIN1250:
1664 case IDC_88592CP852:
1665 cfg.xlat_enablekoiwin =
1666 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1667 cfg.xlat_88592w1250 =
1668 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1669 cfg.xlat_88592cp852 =
1670 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1672 case IDC_CAPSLOCKCYR:
1673 if (HIWORD(wParam) == BN_CLICKED ||
1674 HIWORD(wParam) == BN_DOUBLECLICKED) {
1675 cfg.xlat_capslockcyr =
1676 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1679 case IDC_VTXWINDOWS:
1684 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1685 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1686 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1692 EndDialog (hwnd, 0);
1695 /* Grrr Explorer will maximize Dialogs! */
1697 if (wParam == SIZE_MAXIMIZED)
1704 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1705 WPARAM wParam, LPARAM lParam) {
1706 static HWND page = NULL;
1708 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1710 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1711 EnableWindow(hwnd, 0);
1712 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1713 GetParent(hwnd), AboutProc);
1714 EnableWindow(hwnd, 1);
1715 SetActiveWindow(hwnd);
1717 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1720 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1721 WPARAM wParam, LPARAM lParam) {
1723 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1726 void defuse_showwindow(void) {
1728 * Work around the fact that the app's first call to ShowWindow
1729 * will ignore the default in favour of the shell-provided
1734 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1736 ShowWindow(hwnd, SW_HIDE);
1737 DestroyWindow(hwnd);
1741 int do_config (void) {
1745 savedsession[0] = '\0';
1746 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1747 get_sesslist(FALSE);
1752 int do_reconfig (HWND hwnd) {
1756 backup_cfg = cfg; /* structure copy */
1757 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1759 cfg = backup_cfg; /* structure copy */
1766 void logevent (char *string) {
1767 if (nevents >= negsize) {
1769 events = srealloc (events, negsize * sizeof(*events));
1771 events[nevents] = smalloc(1+strlen(string));
1772 strcpy (events[nevents], string);
1776 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1778 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1779 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1783 void showeventlog (HWND hwnd) {
1785 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1787 ShowWindow (logbox, SW_SHOWNORMAL);
1791 void showabout (HWND hwnd) {
1793 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1795 ShowWindow (abtbox, SW_SHOWNORMAL);
1799 void verify_ssh_host_key(char *host, int port, char *keytype,
1800 char *keystr, char *fingerprint) {
1803 static const char absentmsg[] =
1804 "The server's host key is not cached in the registry. You\n"
1805 "have no guarantee that the server is the computer you\n"
1807 "The server's key fingerprint is:\n"
1809 "If you trust this host, hit Yes to add the key to\n"
1810 "PuTTY's cache and carry on connecting.\n"
1811 "If you do not trust this host, hit No to abandon the\n"
1814 static const char wrongmsg[] =
1815 "WARNING - POTENTIAL SECURITY BREACH!\n"
1817 "The server's host key does not match the one PuTTY has\n"
1818 "cached in the registry. This means that either the\n"
1819 "server administrator has changed the host key, or you\n"
1820 "have actually connected to another computer pretending\n"
1821 "to be the server.\n"
1822 "The new key fingerprint is:\n"
1824 "If you were expecting this change and trust the new key,\n"
1825 "hit Yes to update PuTTY's cache and continue connecting.\n"
1826 "If you want to carry on connecting but without updating\n"
1827 "the cache, hit No.\n"
1828 "If you want to abandon the connection completely, hit\n"
1829 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1832 static const char mbtitle[] = "PuTTY Security Alert";
1835 char message[160+ /* sensible fingerprint max size */
1836 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1837 sizeof(absentmsg) : sizeof(wrongmsg))];
1840 * Verify the key against the registry.
1842 ret = verify_host_key(host, port, keytype, keystr);
1844 if (ret == 0) /* success - key matched OK */
1846 if (ret == 2) { /* key was different */
1848 sprintf(message, wrongmsg, fingerprint);
1849 mbret = MessageBox(NULL, message, mbtitle,
1850 MB_ICONWARNING | MB_YESNOCANCEL);
1852 store_host_key(host, port, keytype, keystr);
1853 if (mbret == IDCANCEL)
1856 if (ret == 1) { /* key was absent */
1858 sprintf(message, absentmsg, fingerprint);
1859 mbret = MessageBox(NULL, message, mbtitle,
1860 MB_ICONWARNING | MB_YESNO);
1863 store_host_key(host, port, keytype, keystr);