15 static char **events = NULL;
16 static int nevents = 0, negsize = 0;
19 static int sesslist_has_focus;
21 static struct prefslist cipherlist;
23 void force_normal(HWND hwnd)
25 static int recurse = 0;
33 wp.length = sizeof(wp);
34 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
35 wp.showCmd = SW_SHOWNORMAL;
36 SetWindowPlacement(hwnd, &wp);
41 static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
45 n = GetDlgItemInt(hwnd, id, &ok, FALSE);
50 static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
54 ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
56 *result = (int) (scale * atof(text));
59 static void MySetDlgItemFlt(HWND hwnd, int id, double value)
62 sprintf(text, "%g", value);
63 SetDlgItemText(hwnd, id, text);
66 static int CALLBACK LogProc(HWND hwnd, UINT msg,
67 WPARAM wParam, LPARAM lParam)
74 static int tabs[4] = { 78, 108 };
75 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
78 for (i = 0; i < nevents; i++)
79 SendDlgItemMessage(hwnd, IDN_LIST, LB_ADDSTRING,
80 0, (LPARAM) events[i]);
83 switch (LOWORD(wParam)) {
87 SetActiveWindow(GetParent(hwnd));
91 if (HIWORD(wParam) == BN_CLICKED ||
92 HIWORD(wParam) == BN_DOUBLECLICKED) {
95 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
96 LB_GETSELCOUNT, 0, 0);
97 if (selcount == 0) { /* don't even try to copy zero items */
102 selitems = smalloc(selcount * sizeof(int));
104 int count = SendDlgItemMessage(hwnd, IDN_LIST,
111 static unsigned char sel_nl[] = SEL_NL;
113 if (count == 0) { /* can't copy zero stuff */
119 for (i = 0; i < count; i++)
121 strlen(events[selitems[i]]) + sizeof(sel_nl);
123 clipdata = smalloc(size);
126 for (i = 0; i < count; i++) {
127 char *q = events[selitems[i]];
128 int qlen = strlen(q);
131 memcpy(p, sel_nl, sizeof(sel_nl));
134 write_aclip(clipdata, size, TRUE);
139 for (i = 0; i < nevents; i++)
140 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
149 SetActiveWindow(GetParent(hwnd));
156 static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
157 WPARAM wParam, LPARAM lParam)
163 switch (LOWORD(wParam)) {
176 static int CALLBACK AboutProc(HWND hwnd, UINT msg,
177 WPARAM wParam, LPARAM lParam)
181 SetDlgItemText(hwnd, IDA_VERSION, ver);
184 switch (LOWORD(wParam)) {
187 EndDialog(hwnd, TRUE);
190 EnableWindow(hwnd, 0);
191 DialogBox(hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
193 EnableWindow(hwnd, 1);
194 SetActiveWindow(hwnd);
198 /* Load web browser */
199 ShellExecute(hwnd, "open",
200 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
201 0, 0, SW_SHOWDEFAULT);
206 EndDialog(hwnd, TRUE);
213 * Null dialog procedure.
215 static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
216 WPARAM wParam, LPARAM lParam)
221 static char savedsession[2048];
224 IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
369 IDC_FULLSCREENONALTENTER,
372 appearancepanelstart,
373 IDC_TITLE_APPEARANCE,
395 connectionpanelstart,
396 IDC_TITLE_CONNECTION,
504 translationpanelstart,
505 IDC_TITLE_TRANSLATION,
506 IDC_BOX_TRANSLATION1,
507 IDC_BOX_TRANSLATION2,
543 static const char *const colours[] = {
544 "Default Foreground", "Default Bold Foreground",
545 "Default Background", "Default Bold Background",
546 "Cursor Text", "Cursor Colour",
547 "ANSI Black", "ANSI Black Bold",
548 "ANSI Red", "ANSI Red Bold",
549 "ANSI Green", "ANSI Green Bold",
550 "ANSI Yellow", "ANSI Yellow Bold",
551 "ANSI Blue", "ANSI Blue Bold",
552 "ANSI Magenta", "ANSI Magenta Bold",
553 "ANSI Cyan", "ANSI Cyan Bold",
554 "ANSI White", "ANSI White Bold"
556 static const int permcolour[] = {
557 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
558 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
559 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
562 static void fmtfont(char *buf)
564 sprintf(buf, "Font: %s, ", cfg.font);
566 strcat(buf, "bold, ");
567 if (cfg.fontheight == 0)
568 strcat(buf, "default height");
570 sprintf(buf + strlen(buf), "%d-point",
571 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
574 /* 2nd arg: NZ => don't redraw session list (use when loading
576 static void init_dlg_ctrls(HWND hwnd, int keepsess)
579 char fontstatic[256];
581 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
582 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
585 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
586 for (i = n; i-- > 0;)
587 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
588 for (i = 0; i < nsessions; i++)
589 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
590 0, (LPARAM) (sessions[i]));
592 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
593 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
594 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
595 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
597 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
598 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
600 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
601 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
602 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
603 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
604 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
605 cfg.funky_type == 0 ? IDC_FUNCTILDE :
606 cfg.funky_type == 1 ? IDC_FUNCLINUX :
607 cfg.funky_type == 2 ? IDC_FUNCXTERM :
608 cfg.funky_type == 3 ? IDC_FUNCVT400 :
609 cfg.funky_type == 4 ? IDC_FUNCVT100P :
610 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
611 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
612 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
613 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
614 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
615 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
616 cfg.nethack_keypad ? IDC_KPNH :
617 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
618 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
619 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
620 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
621 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
622 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
623 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
624 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
625 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
626 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
627 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
628 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
629 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
630 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
631 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
632 CheckDlgButton(hwnd, IDC_FULLSCREENONALTENTER, cfg.fullscreenonaltenter);
633 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
634 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
636 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
637 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
638 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
639 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
640 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
641 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
643 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
644 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
645 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
646 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
647 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
649 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
650 CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
652 B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
653 B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
654 B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
655 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
656 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
657 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
658 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
659 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
661 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
662 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
664 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
665 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
666 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
667 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
668 SetDlgItemInt(hwnd, IDC_WINBEDIT, cfg.window_border, FALSE);
669 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
670 cfg.cursor_type == 0 ? IDC_CURBLOCK :
671 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
672 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
673 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
674 CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize);
675 CheckDlgButton(hwnd, IDC_LOCKFONT, cfg.lockfont);
676 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
677 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
679 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
680 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
682 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
683 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
684 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
685 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
686 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
687 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
688 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
689 cfg.logtype == 0 ? IDC_LSTATOFF :
690 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
691 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
692 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
693 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
696 char *p = cfg.environmt;
697 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
699 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
705 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
710 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
711 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
712 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
713 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
715 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
716 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
717 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
718 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
719 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
720 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
721 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
722 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
723 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
724 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
725 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
729 static const struct { char *s; int c; } ciphers[] = {
730 { "3DES", CIPHER_3DES },
731 { "Blowfish", CIPHER_BLOWFISH },
732 { "DES (SSH 1 only)", CIPHER_DES },
733 { "AES (SSH 2 only)", CIPHER_AES },
734 { "-- warn below here --", CIPHER_WARN }
737 /* Set up the "selected ciphers" box. */
738 /* (cipherlist assumed to contain all ciphers) */
739 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0);
740 for (i = 0; i < CIPHER_MAX; i++) {
741 int c = cfg.ssh_cipherlist[i];
744 for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
745 if (ciphers[j].c == c) {
750 pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING,
752 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA,
759 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
760 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
761 CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
762 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
764 static int tabs[4] = { 25, 61, 96, 128 };
765 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
768 for (i = 0; i < 128; i++) {
770 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
771 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
772 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
776 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
777 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
780 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
781 for (i = n; i-- > 0;)
782 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
783 LB_DELETESTRING, i, 0);
784 for (i = 0; i < 22; i++)
785 if (cfg.bold_colour || permcolour[i])
786 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
787 (LPARAM) colours[i]);
789 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
790 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
791 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
792 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
797 strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
798 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
799 for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
800 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
803 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
806 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
807 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
808 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
809 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
810 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
813 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
814 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
816 CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
817 CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
820 struct treeview_faff {
825 static HTREEITEM treeview_insert(struct treeview_faff *faff,
826 int level, char *text)
831 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
832 ins.hInsertAfter = faff->lastat[level];
833 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
834 #define INSITEM DUMMYUNIONNAME.item
838 ins.INSITEM.mask = TVIF_TEXT;
839 ins.INSITEM.pszText = text;
840 newitem = TreeView_InsertItem(faff->treeview, &ins);
842 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
844 faff->lastat[level] = newitem;
845 for (i = level + 1; i < 4; i++)
846 faff->lastat[i] = NULL;
851 * Create the panelfuls of controls in the configuration box.
853 static void create_controls(HWND hwnd, int dlgtype, int panel)
855 if (panel == sessionpanelstart) {
856 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
858 ctlposinit(&cp, hwnd, 80, 3, 13);
859 bartitle(&cp, "Basic options for your PuTTY session",
862 beginbox(&cp, "Specify your connection by host name or IP address",
865 "Host &Name (or IP address)",
866 IDC_HOSTSTATIC, IDC_HOST, 75,
867 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
868 if (backends[3].backend == NULL) {
869 /* this is PuTTYtel, so only three protocols available */
870 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
872 "&Telnet", IDC_PROTTELNET,
873 "Rlog&in", IDC_PROTRLOGIN, NULL);
875 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
877 "&Telnet", IDC_PROTTELNET,
878 "Rlog&in", IDC_PROTRLOGIN,
887 beginbox(&cp, "Load, save or delete a stored session",
889 sesssaver(&cp, "Sav&ed Sessions",
890 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
891 "&Load", IDC_SESSLOAD,
892 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
895 beginbox(&cp, NULL, IDC_BOX_SESSION3);
896 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
897 "Always", IDC_COEALWAYS,
898 "Never", IDC_COENEVER,
899 "Only on clean exit", IDC_COENORMAL, NULL);
903 if (panel == loggingpanelstart) {
904 /* The Logging panel. Accelerators used: [acgo] tplfwe */
906 ctlposinit(&cp, hwnd, 80, 3, 13);
907 bartitle(&cp, "Options controlling session logging",
909 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
911 "Session logging:", IDC_LSTATSTATIC,
912 "Logging &turned off completely", IDC_LSTATOFF,
913 "Log &printable output only", IDC_LSTATASCII,
914 "&Log all session output", IDC_LSTATRAW, NULL);
915 editbutton(&cp, "Log &file name:",
916 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
918 statictext(&cp, "(Log file name can contain &&Y, &&M, &&D for date,"
919 " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN);
921 "What to do if the log file already &exists:",
922 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
923 "Always append to the end of it", IDC_LSTATXAPN,
924 "Ask the user every time", IDC_LSTATXASK, NULL);
928 if (panel == terminalpanelstart) {
929 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
931 ctlposinit(&cp, hwnd, 80, 3, 13);
932 bartitle(&cp, "Options controlling the terminal emulation",
934 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
935 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
936 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
937 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
938 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
939 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
941 "An&swerback to ^E:", IDC_ANSWERBACK,
942 IDC_ANSWEREDIT, 100, NULL);
945 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
946 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
947 "Auto", IDC_ECHOBACKEND,
948 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
949 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
950 "Auto", IDC_EDITBACKEND,
951 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
955 if (panel == bellpanelstart) {
956 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
958 ctlposinit(&cp, hwnd, 80, 3, 13);
959 bartitle(&cp, "Options controlling the terminal bell",
961 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
963 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
964 "None (bell disabled)", IDC_BELL_DISABLED,
965 "Play Windows Default Sound", IDC_BELL_DEFAULT,
966 "Play a custom sound file", IDC_BELL_WAVEFILE,
967 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
968 editbutton(&cp, "Custom sound file to play as a bell:",
969 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
970 "Bro&wse...", IDC_BELL_WAVEBROWSE);
971 radioline(&cp, "Taskbar/caption &indication on bell:",
972 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
973 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
976 beginbox(&cp, "Control the bell overload behaviour",
978 checkbox(&cp, "Bell is temporarily &disabled when over-used",
980 staticedit(&cp, "Over-use means this &many bells...",
981 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
982 staticedit(&cp, "... in &this many seconds",
983 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
985 "The bell is re-enabled after a few seconds of silence.",
986 1, IDC_BELLOVLEXPLAIN);
987 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
992 if (panel == keyboardpanelstart) {
993 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
995 ctlposinit(&cp, hwnd, 80, 3, 13);
997 bartitle(&cp, "Options controlling the effects of keys",
1000 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
1001 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
1002 "Control-H", IDC_DEL008,
1003 "Control-? (127)", IDC_DEL127, NULL);
1004 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
1005 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
1006 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
1007 "ESC[n~", IDC_FUNCTILDE,
1008 "Linux", IDC_FUNCLINUX,
1009 "Xterm R6", IDC_FUNCXTERM,
1010 "VT400", IDC_FUNCVT400,
1011 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
1013 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
1015 "Application c&ursor keys totally disabled",
1017 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
1018 "Normal", IDC_CURNORMAL,
1019 "Application", IDC_CURAPPLIC, NULL);
1021 "Application ke&ypad keys totally disabled",
1023 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
1024 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
1025 "NetHack", IDC_KPNH, NULL);
1027 beginbox(&cp, "Enable extra keyboard features:",
1029 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
1030 checkbox(&cp, "Control-Alt is &different from AltGr",
1035 if (panel == windowpanelstart) {
1036 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt f */
1038 ctlposinit(&cp, hwnd, 80, 3, 13);
1039 bartitle(&cp, "Options controlling PuTTY's window",
1041 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
1043 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
1044 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
1045 checkbox(&cp, "Lock terminal size against resi&zing", IDC_LOCKSIZE);
1046 checkbox(&cp, "Lock font size against resi&zing", IDC_LOCKFONT);
1048 beginbox(&cp, "Control the scrollback in the window",
1050 staticedit(&cp, "Lines of &scrollback",
1051 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
1052 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
1053 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
1054 checkbox(&cp, "Reset scrollback on dis&play activity",
1057 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
1058 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
1059 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
1060 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
1061 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
1062 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
1063 checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
1067 if (panel == appearancepanelstart) {
1068 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
1070 ctlposinit(&cp, hwnd, 80, 3, 13);
1071 /* bartitle(&cp, "Options controlling PuTTY's appearance",
1072 IDC_TITLE_APPEARANCE); */
1073 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
1074 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
1075 "B&lock", IDC_CURBLOCK,
1076 "&Underline", IDC_CURUNDER,
1077 "&Vertical line", IDC_CURVERT, NULL);
1078 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
1080 beginbox(&cp, "Set the font used in the terminal window",
1081 IDC_BOX_APPEARANCE2);
1082 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
1084 beginbox(&cp, "Adjust the use of the window title",
1085 IDC_BOX_APPEARANCE3);
1087 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1088 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1090 beginbox(&cp, "Adjust the use of the mouse pointer",
1091 IDC_BOX_APPEARANCE4);
1092 checkbox(&cp, "Hide mouse &pointer when typing in window",
1095 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1096 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1098 staticedit(&cp, "Gap between text and window edge",
1099 IDC_WINBSTATIC, IDC_WINBEDIT, 20);
1103 if (panel == translationpanelstart) {
1104 /* The Translation panel. Accelerators used: [acgo] rxbepu */
1106 ctlposinit(&cp, hwnd, 80, 3, 13);
1107 bartitle(&cp, "Options controlling character set translation",
1108 IDC_TITLE_TRANSLATION);
1109 beginbox(&cp, "Character set translation on received data",
1110 IDC_BOX_TRANSLATION2);
1111 combobox(&cp, "&Received data assumed to be in which character set:",
1112 IDC_CODEPAGESTATIC, IDC_CODEPAGE);
1114 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1115 IDC_BOX_TRANSLATION1);
1117 "Handling of line drawing characters:", IDC_VTSTATIC,
1118 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1119 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1120 "Use font in O&EM mode only", IDC_VTOEMONLY,
1121 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1122 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1126 if (panel == selectionpanelstart) {
1127 /* The Selection panel. Accelerators used: [acgo] d wxp hst */
1129 ctlposinit(&cp, hwnd, 80, 3, 13);
1130 bartitle(&cp, "Options controlling copy and paste",
1131 IDC_TITLE_SELECTION);
1132 beginbox(&cp, "Translation of pasted characters",
1133 IDC_BOX_SELECTION1);
1135 "&Don't translate line drawing chars into +, - and |",
1138 beginbox(&cp, "Control which mouse button does which thing",
1139 IDC_BOX_SELECTION2);
1140 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1141 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1142 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1145 "Shift overrides a&pplication's use of mouse",
1148 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1149 IDC_BOX_SELECTION3);
1150 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1151 "&Set", IDC_CCSET, IDC_CCEDIT,
1152 "&to class", IDC_CCSTATIC2);
1156 if (panel == colourspanelstart) {
1157 /* The Colours panel. Accelerators used: [acgo] blum */
1159 ctlposinit(&cp, hwnd, 80, 3, 13);
1160 bartitle(&cp, "Options controlling use of colours",
1162 beginbox(&cp, "General options for colour usage",
1164 checkbox(&cp, "&Bolded text is a different colour",
1166 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1168 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1170 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1171 IDC_COLOURSTATIC, IDC_COLOURLIST,
1172 "&Modify...", IDC_CHANGE,
1173 "Red:", IDC_RSTATIC, IDC_RVALUE,
1174 "Green:", IDC_GSTATIC, IDC_GVALUE,
1175 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1179 if (panel == connectionpanelstart) {
1180 /* The Connection panel. Accelerators used: [acgo] tuk */
1182 ctlposinit(&cp, hwnd, 80, 3, 13);
1183 bartitle(&cp, "Options controlling the connection",
1184 IDC_TITLE_CONNECTION);
1186 beginbox(&cp, "Data to send to the server",
1187 IDC_BOX_CONNECTION1);
1188 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1190 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1194 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1195 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1199 beginbox(&cp, "Sending of null packets to keep session active",
1200 IDC_BOX_CONNECTION2);
1201 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1202 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1206 if (panel == telnetpanelstart) {
1207 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1209 ctlposinit(&cp, hwnd, 80, 3, 13);
1211 bartitle(&cp, "Options controlling Telnet connections",
1213 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1214 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1216 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1217 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1218 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1219 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1221 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1222 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1223 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1224 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1225 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1226 "Passive", IDC_TPASSIVE, "Active",
1228 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1234 if (panel == rloginpanelstart) {
1235 /* The Rlogin panel. Accelerators used: [acgo] sl */
1237 ctlposinit(&cp, hwnd, 80, 3, 13);
1239 bartitle(&cp, "Options controlling Rlogin connections",
1241 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1242 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1244 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1245 IDC_RLLUSEREDIT, 50);
1250 if (panel == sshpanelstart) {
1251 /* The SSH panel. Accelerators used: [acgo] r pe12i s */
1253 ctlposinit(&cp, hwnd, 80, 3, 13);
1255 bartitle(&cp, "Options controlling SSH connections",
1257 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1259 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1262 beginbox(&cp, "Protocol options", IDC_BOX_SSH2);
1263 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1264 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1265 radioline(&cp, "Preferred SSH protocol version:",
1266 IDC_SSHPROTSTATIC, 2,
1267 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1268 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1271 beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
1272 prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
1273 IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
1279 if (panel == sshauthpanelstart) {
1280 /* The SSH authentication panel. Accelerators used: [acgo] m fkw */
1282 ctlposinit(&cp, hwnd, 80, 3, 13);
1284 bartitle(&cp, "Options controlling SSH authentication",
1286 beginbox(&cp, "Authentication methods",
1288 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1291 beginbox(&cp, "Authentication parameters",
1293 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1294 editbutton(&cp, "Private &key file for authentication:",
1295 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1301 if (panel == tunnelspanelstart) {
1302 /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
1304 ctlposinit(&cp, hwnd, 80, 3, 13);
1306 bartitle(&cp, "Options controlling SSH tunnelling",
1308 beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
1309 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1310 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1311 IDC_X11_DISPLAY, 50, NULL);
1313 beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
1314 checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL);
1315 staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
1316 "&Remove", IDC_PFWDREMOVE);
1317 fwdsetter(&cp, IDC_PFWDLIST,
1318 "Add new forwarded port:", IDC_PFWDSTATIC2,
1319 "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
1320 "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
1321 "A&dd", IDC_PFWDADD);
1322 bareradioline(&cp, 2,
1323 "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL);
1331 * Helper function to load the session selected in SESSLIST
1332 * if any, as this is done in more than one place in
1333 * GenericMainDlgProc(). 0 => failure.
1335 static int load_selected_session(HWND hwnd)
1337 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1338 LB_GETCURSEL, 0, 0);
1344 isdef = !strcmp(sessions[n], "Default Settings");
1345 load_settings(sessions[n], !isdef, &cfg);
1346 init_dlg_ctrls(hwnd, TRUE);
1348 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1350 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1351 /* Restore the selection, which will have been clobbered by
1352 * SESSEDIT handling. */
1353 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1358 * This function is the configuration box.
1360 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1361 WPARAM wParam, LPARAM lParam, int dlgtype)
1364 struct treeview_faff tvfaff;
1367 char filename[sizeof(cfg.keyfile)];
1370 char fontstatic[256];
1372 struct servent *service;
1374 static UINT draglistmsg = WM_NULL;
1379 SetWindowLong(hwnd, GWL_USERDATA, 0);
1380 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1381 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1383 * Centre the window.
1385 { /* centre the window */
1388 hw = GetDesktopWindow();
1389 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1391 (rs.right + rs.left + rd.left - rd.right) / 2,
1392 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1393 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1397 * Create the tree view.
1405 r.right = r.left + 75;
1407 r.bottom = r.top + 10;
1408 MapDialogRect(hwnd, &r);
1409 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1410 WS_CHILD | WS_VISIBLE,
1412 r.right - r.left, r.bottom - r.top,
1413 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1415 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1416 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1419 r.right = r.left + 75;
1421 r.bottom = r.top + 206;
1422 MapDialogRect(hwnd, &r);
1423 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1424 WS_CHILD | WS_VISIBLE |
1425 WS_TABSTOP | TVS_HASLINES |
1426 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1428 TVS_SHOWSELALWAYS, r.left, r.top,
1429 r.right - r.left, r.bottom - r.top,
1430 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1432 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1433 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1434 tvfaff.treeview = treeview;
1435 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1439 * Set up the tree view contents.
1441 hsession = treeview_insert(&tvfaff, 0, "Session");
1442 treeview_insert(&tvfaff, 1, "Logging");
1443 treeview_insert(&tvfaff, 0, "Terminal");
1444 treeview_insert(&tvfaff, 1, "Keyboard");
1445 treeview_insert(&tvfaff, 1, "Bell");
1446 treeview_insert(&tvfaff, 0, "Window");
1447 treeview_insert(&tvfaff, 1, "Appearance");
1448 treeview_insert(&tvfaff, 1, "Translation");
1449 treeview_insert(&tvfaff, 1, "Selection");
1450 treeview_insert(&tvfaff, 1, "Colours");
1451 treeview_insert(&tvfaff, 0, "Connection");
1453 treeview_insert(&tvfaff, 1, "Telnet");
1454 treeview_insert(&tvfaff, 1, "Rlogin");
1455 if (backends[3].backend != NULL) {
1456 treeview_insert(&tvfaff, 1, "SSH");
1457 /* XXX long name is ugly */
1458 /* XXX make it closed by default? */
1459 treeview_insert(&tvfaff, 2, "Auth");
1460 treeview_insert(&tvfaff, 2, "Tunnels");
1465 * Put the treeview selection on to the Session panel. This
1466 * should also cause creation of the relevant controls.
1468 TreeView_SelectItem(treeview, hsession);
1471 * Set focus into the first available control.
1475 ctl = GetDlgItem(hwnd, IDC_HOST);
1477 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1481 SetWindowLong(hwnd, GWL_USERDATA, 1);
1482 sesslist_has_focus = 0;
1486 * Button release should trigger WM_OK if there was a
1487 * previous double click on the session list.
1491 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1494 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1495 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1497 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1502 SendMessage (hwnd, WM_SETREDRAW, FALSE, 0);
1505 item.pszText = buffer;
1506 item.cchTextMax = sizeof(buffer);
1507 item.mask = TVIF_TEXT;
1508 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1509 for (j = controlstartvalue; j < controlendvalue; j++) {
1510 HWND item = GetDlgItem(hwnd, j);
1512 DestroyWindow(item);
1514 if (!strcmp(buffer, "Session"))
1515 create_controls(hwnd, dlgtype, sessionpanelstart);
1516 if (!strcmp(buffer, "Logging"))
1517 create_controls(hwnd, dlgtype, loggingpanelstart);
1518 if (!strcmp(buffer, "Keyboard"))
1519 create_controls(hwnd, dlgtype, keyboardpanelstart);
1520 if (!strcmp(buffer, "Terminal"))
1521 create_controls(hwnd, dlgtype, terminalpanelstart);
1522 if (!strcmp(buffer, "Bell"))
1523 create_controls(hwnd, dlgtype, bellpanelstart);
1524 if (!strcmp(buffer, "Window"))
1525 create_controls(hwnd, dlgtype, windowpanelstart);
1526 if (!strcmp(buffer, "Appearance"))
1527 create_controls(hwnd, dlgtype, appearancepanelstart);
1528 if (!strcmp(buffer, "Tunnels"))
1529 create_controls(hwnd, dlgtype, tunnelspanelstart);
1530 if (!strcmp(buffer, "Connection"))
1531 create_controls(hwnd, dlgtype, connectionpanelstart);
1532 if (!strcmp(buffer, "Telnet"))
1533 create_controls(hwnd, dlgtype, telnetpanelstart);
1534 if (!strcmp(buffer, "Rlogin"))
1535 create_controls(hwnd, dlgtype, rloginpanelstart);
1536 if (!strcmp(buffer, "SSH"))
1537 create_controls(hwnd, dlgtype, sshpanelstart);
1538 if (!strcmp(buffer, "Auth"))
1539 create_controls(hwnd, dlgtype, sshauthpanelstart);
1540 if (!strcmp(buffer, "Selection"))
1541 create_controls(hwnd, dlgtype, selectionpanelstart);
1542 if (!strcmp(buffer, "Colours"))
1543 create_controls(hwnd, dlgtype, colourspanelstart);
1544 if (!strcmp(buffer, "Translation"))
1545 create_controls(hwnd, dlgtype, translationpanelstart);
1547 init_dlg_ctrls(hwnd, FALSE);
1549 SendMessage (hwnd, WM_SETREDRAW, TRUE, 0);
1550 InvalidateRect (hwnd, NULL, TRUE);
1552 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1558 * Only process WM_COMMAND once the dialog is fully formed.
1560 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1561 switch (LOWORD(wParam)) {
1563 /* Behaviour of the "Open" button is different if the
1564 * session list has focus, *unless* the user just
1565 * double-clicked... */
1566 if (sesslist_has_focus && !readytogo) {
1567 if (!load_selected_session(hwnd)) {
1572 /* If at this point we have a valid session, go! */
1581 case IDC_PROTTELNET:
1582 case IDC_PROTRLOGIN:
1585 if (HIWORD(wParam) == BN_CLICKED ||
1586 HIWORD(wParam) == BN_DOUBLECLICKED) {
1587 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1588 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1589 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1591 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1593 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1594 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1595 || (cfg.protocol == PROT_RLOGIN
1596 && cfg.port != 513)) {
1597 cfg.port = i ? 22 : j ? 23 : 513;
1598 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1603 if (HIWORD(wParam) == EN_CHANGE)
1604 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1605 sizeof(cfg.host) - 1);
1608 if (HIWORD(wParam) == EN_CHANGE) {
1609 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1610 if (isdigit(portname[0]))
1611 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1613 service = getservbyname(portname, NULL);
1615 cfg.port = ntohs(service->s_port);
1622 if (HIWORD(wParam) == EN_CHANGE) {
1623 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1625 GetDlgItemText(hwnd, IDC_SESSEDIT,
1626 savedsession, sizeof(savedsession) - 1);
1627 savedsession[sizeof(savedsession) - 1] = '\0';
1631 if (HIWORD(wParam) == BN_CLICKED ||
1632 HIWORD(wParam) == BN_DOUBLECLICKED) {
1637 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1640 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1641 LB_GETCURSEL, 0, 0);
1646 strcpy(str, sessions[n]);
1648 save_settings(str, !!strcmp(str, "Default Settings"),
1650 get_sesslist(FALSE);
1652 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1654 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1656 for (i = 0; i < nsessions; i++)
1657 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1659 (LPARAM) (sessions[i]));
1660 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1662 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1664 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1670 if (LOWORD(wParam) == IDC_SESSLIST) {
1671 if (HIWORD(wParam) == LBN_SETFOCUS)
1672 sesslist_has_focus = 1;
1673 else if (HIWORD(wParam) == LBN_KILLFOCUS)
1674 sesslist_has_focus = 0;
1676 if (LOWORD(wParam) == IDC_SESSLOAD &&
1677 HIWORD(wParam) != BN_CLICKED &&
1678 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1679 if (LOWORD(wParam) == IDC_SESSLIST &&
1680 HIWORD(wParam) != LBN_DBLCLK) break;
1681 /* Load the session selected in SESSLIST. */
1682 if (load_selected_session(hwnd) &&
1683 LOWORD(wParam) == IDC_SESSLIST) {
1685 * A double-click on a saved session should
1686 * actually start the session, not just load it.
1687 * Unless it's Default Settings or some other
1688 * host-less set of saved settings.
1697 if (HIWORD(wParam) == BN_CLICKED ||
1698 HIWORD(wParam) == BN_DOUBLECLICKED) {
1699 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1700 LB_GETCURSEL, 0, 0);
1701 if (n == LB_ERR || n == 0) {
1705 del_settings(sessions[n]);
1706 get_sesslist(FALSE);
1708 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1710 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1712 for (i = 0; i < nsessions; i++)
1713 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1715 (LPARAM) (sessions[i]));
1716 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1718 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1720 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1724 if (HIWORD(wParam) == EN_CHANGE)
1725 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1726 &cfg.ping_interval);
1730 if (HIWORD(wParam) == BN_CLICKED ||
1731 HIWORD(wParam) == BN_DOUBLECLICKED)
1732 cfg.bksp_is_delete =
1733 IsDlgButtonChecked(hwnd, IDC_DEL127);
1737 if (HIWORD(wParam) == BN_CLICKED ||
1738 HIWORD(wParam) == BN_DOUBLECLICKED)
1740 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1746 case IDC_FUNCVT100P:
1748 if (HIWORD(wParam) == BN_CLICKED ||
1749 HIWORD(wParam) == BN_DOUBLECLICKED)
1750 switch (LOWORD(wParam)) {
1763 case IDC_FUNCVT100P:
1773 if (HIWORD(wParam) == BN_CLICKED ||
1774 HIWORD(wParam) == BN_DOUBLECLICKED) {
1776 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1777 cfg.nethack_keypad = FALSE;
1781 if (HIWORD(wParam) == BN_CLICKED ||
1782 HIWORD(wParam) == BN_DOUBLECLICKED) {
1783 cfg.app_keypad = FALSE;
1784 cfg.nethack_keypad = TRUE;
1789 if (HIWORD(wParam) == BN_CLICKED ||
1790 HIWORD(wParam) == BN_DOUBLECLICKED)
1792 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1795 if (HIWORD(wParam) == BN_CLICKED ||
1796 HIWORD(wParam) == BN_DOUBLECLICKED)
1798 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1801 if (HIWORD(wParam) == BN_CLICKED ||
1802 HIWORD(wParam) == BN_DOUBLECLICKED)
1804 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1807 if (HIWORD(wParam) == BN_CLICKED ||
1808 HIWORD(wParam) == BN_DOUBLECLICKED)
1809 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1812 if (HIWORD(wParam) == BN_CLICKED ||
1813 HIWORD(wParam) == BN_DOUBLECLICKED)
1815 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1818 if (HIWORD(wParam) == BN_CLICKED ||
1819 HIWORD(wParam) == BN_DOUBLECLICKED)
1821 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1823 case IDC_ECHOBACKEND:
1826 if (HIWORD(wParam) == BN_CLICKED ||
1827 HIWORD(wParam) == BN_DOUBLECLICKED) {
1828 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1829 cfg.localecho = LD_BACKEND;
1830 if (LOWORD(wParam) == IDC_ECHOYES)
1831 cfg.localecho = LD_YES;
1832 if (LOWORD(wParam) == IDC_ECHONO)
1833 cfg.localecho = LD_NO;
1836 case IDC_EDITBACKEND:
1839 if (HIWORD(wParam) == BN_CLICKED ||
1840 HIWORD(wParam) == BN_DOUBLECLICKED) {
1841 if (LOWORD(wParam) == IDC_EDITBACKEND)
1842 cfg.localedit = LD_BACKEND;
1843 if (LOWORD(wParam) == IDC_EDITYES)
1844 cfg.localedit = LD_YES;
1845 if (LOWORD(wParam) == IDC_EDITNO)
1846 cfg.localedit = LD_NO;
1849 case IDC_ANSWEREDIT:
1850 if (HIWORD(wParam) == EN_CHANGE)
1851 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1852 sizeof(cfg.answerback) - 1);
1854 case IDC_ALWAYSONTOP:
1855 if (HIWORD(wParam) == BN_CLICKED ||
1856 HIWORD(wParam) == BN_DOUBLECLICKED)
1858 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1860 case IDC_FULLSCREENONALTENTER:
1861 if (HIWORD(wParam) == BN_CLICKED ||
1862 HIWORD(wParam) == BN_DOUBLECLICKED)
1863 cfg.fullscreenonaltenter =
1864 IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER);
1867 if (HIWORD(wParam) == BN_CLICKED ||
1868 HIWORD(wParam) == BN_DOUBLECLICKED)
1870 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1872 case IDC_SCROLLDISP:
1873 if (HIWORD(wParam) == BN_CLICKED ||
1874 HIWORD(wParam) == BN_DOUBLECLICKED)
1875 cfg.scroll_on_disp =
1876 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1878 case IDC_COMPOSEKEY:
1879 if (HIWORD(wParam) == BN_CLICKED ||
1880 HIWORD(wParam) == BN_DOUBLECLICKED)
1882 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1884 case IDC_CTRLALTKEYS:
1885 if (HIWORD(wParam) == BN_CLICKED ||
1886 HIWORD(wParam) == BN_DOUBLECLICKED)
1888 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1891 if (HIWORD(wParam) == BN_CLICKED ||
1892 HIWORD(wParam) == BN_DOUBLECLICKED)
1893 cfg.telnet_keyboard =
1894 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1897 if (HIWORD(wParam) == BN_CLICKED ||
1898 HIWORD(wParam) == BN_DOUBLECLICKED)
1900 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1903 if (HIWORD(wParam) == BN_CLICKED ||
1904 HIWORD(wParam) == BN_DOUBLECLICKED)
1905 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1908 if (HIWORD(wParam) == BN_CLICKED ||
1909 HIWORD(wParam) == BN_DOUBLECLICKED)
1911 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1914 if (HIWORD(wParam) == EN_CHANGE)
1915 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1918 if (HIWORD(wParam) == EN_CHANGE)
1919 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1922 if (HIWORD(wParam) == EN_CHANGE)
1923 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1925 case IDC_CHOOSEFONT:
1928 lf.lfHeight = -MulDiv(cfg.fontheight,
1929 GetDeviceCaps(hdc, LOGPIXELSY),
1933 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1934 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1935 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1936 lf.lfCharSet = cfg.fontcharset;
1937 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1938 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1939 lf.lfQuality = DEFAULT_QUALITY;
1940 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1941 strncpy(lf.lfFaceName, cfg.font,
1942 sizeof(lf.lfFaceName) - 1);
1943 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1945 cf.lStructSize = sizeof(cf);
1946 cf.hwndOwner = hwnd;
1948 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1949 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1951 if (ChooseFont(&cf)) {
1952 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1953 cfg.font[sizeof(cfg.font) - 1] = '\0';
1954 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1955 cfg.fontcharset = lf.lfCharSet;
1956 cfg.fontheight = cf.iPointSize / 10;
1957 fmtfont(fontstatic);
1958 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1961 case IDC_BELL_DISABLED:
1962 case IDC_BELL_DEFAULT:
1963 case IDC_BELL_WAVEFILE:
1964 case IDC_BELL_VISUAL:
1965 if (HIWORD(wParam) == BN_CLICKED ||
1966 HIWORD(wParam) == BN_DOUBLECLICKED) {
1967 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1968 cfg.beep = BELL_DISABLED;
1969 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1970 cfg.beep = BELL_DEFAULT;
1971 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1972 cfg.beep = BELL_WAVEFILE;
1973 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1974 cfg.beep = BELL_VISUAL;
1977 case IDC_B_IND_DISABLED:
1978 case IDC_B_IND_FLASH:
1979 case IDC_B_IND_STEADY:
1980 if (HIWORD(wParam) == BN_CLICKED ||
1981 HIWORD(wParam) == BN_DOUBLECLICKED) {
1982 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
1983 cfg.beep_ind = B_IND_DISABLED;
1984 if (LOWORD(wParam) == IDC_B_IND_FLASH)
1985 cfg.beep_ind = B_IND_FLASH;
1986 if (LOWORD(wParam) == IDC_B_IND_STEADY)
1987 cfg.beep_ind = B_IND_STEADY;
1990 case IDC_BELL_WAVEBROWSE:
1991 memset(&of, 0, sizeof(of));
1992 #ifdef OPENFILENAME_SIZE_VERSION_400
1993 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1995 of.lStructSize = sizeof(of);
1997 of.hwndOwner = hwnd;
1998 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1999 of.lpstrCustomFilter = NULL;
2000 of.nFilterIndex = 1;
2001 of.lpstrFile = filename;
2002 strcpy(filename, cfg.bell_wavefile);
2003 of.nMaxFile = sizeof(filename);
2004 of.lpstrFileTitle = NULL;
2005 of.lpstrInitialDir = NULL;
2006 of.lpstrTitle = "Select Bell Sound File";
2008 if (GetOpenFileName(&of)) {
2009 strcpy(cfg.bell_wavefile, filename);
2010 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2014 case IDC_BELL_WAVEEDIT:
2015 if (HIWORD(wParam) == EN_CHANGE)
2016 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2018 sizeof(cfg.bell_wavefile) - 1);
2021 if (HIWORD(wParam) == BN_CLICKED ||
2022 HIWORD(wParam) == BN_DOUBLECLICKED)
2024 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
2027 if (HIWORD(wParam) == EN_CHANGE)
2028 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2031 if (HIWORD(wParam) == EN_CHANGE)
2032 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2036 if (HIWORD(wParam) == EN_CHANGE)
2037 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2041 if (HIWORD(wParam) == BN_CLICKED ||
2042 HIWORD(wParam) == BN_DOUBLECLICKED)
2044 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2047 if (HIWORD(wParam) == BN_CLICKED ||
2048 HIWORD(wParam) == BN_DOUBLECLICKED)
2049 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2052 if (HIWORD(wParam) == BN_CLICKED ||
2053 HIWORD(wParam) == BN_DOUBLECLICKED)
2054 cfg.win_name_always =
2055 IsDlgButtonChecked(hwnd, IDC_WINNAME);
2058 if (HIWORD(wParam) == BN_CLICKED ||
2059 HIWORD(wParam) == BN_DOUBLECLICKED)
2061 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2063 case IDC_SUNKENEDGE:
2064 if (HIWORD(wParam) == BN_CLICKED ||
2065 HIWORD(wParam) == BN_DOUBLECLICKED)
2067 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2070 if (HIWORD(wParam) == EN_CHANGE)
2071 MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
2072 &cfg.window_border);
2073 if (cfg.window_border > 32)
2074 cfg.window_border = 32;
2077 if (HIWORD(wParam) == BN_CLICKED ||
2078 HIWORD(wParam) == BN_DOUBLECLICKED)
2079 cfg.cursor_type = 0;
2082 if (HIWORD(wParam) == BN_CLICKED ||
2083 HIWORD(wParam) == BN_DOUBLECLICKED)
2084 cfg.cursor_type = 1;
2087 if (HIWORD(wParam) == BN_CLICKED ||
2088 HIWORD(wParam) == BN_DOUBLECLICKED)
2089 cfg.cursor_type = 2;
2092 if (HIWORD(wParam) == BN_CLICKED ||
2093 HIWORD(wParam) == BN_DOUBLECLICKED)
2095 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2098 if (HIWORD(wParam) == BN_CLICKED ||
2099 HIWORD(wParam) == BN_DOUBLECLICKED)
2101 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2104 if (HIWORD(wParam) == BN_CLICKED ||
2105 HIWORD(wParam) == BN_DOUBLECLICKED)
2107 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
2110 if (HIWORD(wParam) == BN_CLICKED ||
2111 HIWORD(wParam) == BN_DOUBLECLICKED)
2113 IsDlgButtonChecked(hwnd, IDC_LOCKFONT);
2116 if (HIWORD(wParam) == EN_CHANGE)
2117 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2118 sizeof(cfg.wintitle) - 1);
2123 if (HIWORD(wParam) == BN_CLICKED ||
2124 HIWORD(wParam) == BN_DOUBLECLICKED) {
2126 IsDlgButtonChecked(hwnd,
2127 IDC_COEALWAYS) ? COE_ALWAYS :
2128 IsDlgButtonChecked(hwnd,
2129 IDC_COENEVER) ? COE_NEVER :
2134 if (HIWORD(wParam) == BN_CLICKED ||
2135 HIWORD(wParam) == BN_DOUBLECLICKED)
2137 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
2140 if (HIWORD(wParam) == EN_CHANGE)
2141 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
2142 sizeof(cfg.termtype) - 1);
2145 if (HIWORD(wParam) == EN_CHANGE)
2146 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
2147 sizeof(cfg.logfilename) - 1);
2150 memset(&of, 0, sizeof(of));
2151 #ifdef OPENFILENAME_SIZE_VERSION_400
2152 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2154 of.lStructSize = sizeof(of);
2156 of.hwndOwner = hwnd;
2157 of.lpstrFilter = "All Files\0*\0\0\0";
2158 of.lpstrCustomFilter = NULL;
2159 of.nFilterIndex = 1;
2160 of.lpstrFile = filename;
2161 strcpy(filename, cfg.logfilename);
2162 of.nMaxFile = sizeof(filename);
2163 of.lpstrFileTitle = NULL;
2164 of.lpstrInitialDir = NULL;
2165 of.lpstrTitle = "Select session log file";
2167 if (GetSaveFileName(&of)) {
2168 strcpy(cfg.logfilename, filename);
2169 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2173 case IDC_LSTATASCII:
2175 if (HIWORD(wParam) == BN_CLICKED ||
2176 HIWORD(wParam) == BN_DOUBLECLICKED) {
2177 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2179 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2181 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2188 if (HIWORD(wParam) == BN_CLICKED ||
2189 HIWORD(wParam) == BN_DOUBLECLICKED) {
2190 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2191 cfg.logxfovr = LGXF_ASK;
2192 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2193 cfg.logxfovr = LGXF_APN;
2194 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2195 cfg.logxfovr = LGXF_OVR;
2200 if (HIWORD(wParam) == EN_CHANGE)
2201 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2202 sizeof(cfg.termspeed) - 1);
2205 if (HIWORD(wParam) == EN_CHANGE)
2206 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2207 sizeof(cfg.username) - 1);
2209 case IDC_RLLUSEREDIT:
2210 if (HIWORD(wParam) == EN_CHANGE)
2211 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2213 sizeof(cfg.localusername) - 1);
2217 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2221 cfg.passive_telnet =
2222 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2225 if (HIWORD(wParam) == BN_CLICKED ||
2226 HIWORD(wParam) == BN_DOUBLECLICKED) {
2227 char str[sizeof(cfg.environmt)];
2229 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2235 p = str + strlen(str);
2237 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2238 sizeof(str) - 1 - (p - str));
2249 if ((p - cfg.environmt) + strlen(str) + 2 <
2250 sizeof(cfg.environmt)) {
2252 p[strlen(str) + 1] = '\0';
2253 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2255 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2256 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2258 MessageBox(hwnd, "Environment too big",
2259 "PuTTY Error", MB_OK | MB_ICONERROR);
2264 if (HIWORD(wParam) != BN_CLICKED &&
2265 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2267 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2274 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2301 if (HIWORD(wParam) == BN_CLICKED ||
2302 HIWORD(wParam) == BN_DOUBLECLICKED)
2303 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2306 if (HIWORD(wParam) == BN_CLICKED ||
2307 HIWORD(wParam) == BN_DOUBLECLICKED)
2309 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2312 if (HIWORD(wParam) == BN_CLICKED ||
2313 HIWORD(wParam) == BN_DOUBLECLICKED)
2315 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2318 if (HIWORD(wParam) == BN_CLICKED ||
2319 HIWORD(wParam) == BN_DOUBLECLICKED)
2321 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2323 case IDC_CIPHERLIST:
2326 handle_prefslist(&cipherlist,
2327 cfg.ssh_cipherlist, CIPHER_MAX,
2328 0, hwnd, wParam, lParam);
2332 if (HIWORD(wParam) == BN_CLICKED ||
2333 HIWORD(wParam) == BN_DOUBLECLICKED) {
2334 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2336 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2341 if (HIWORD(wParam) == BN_CLICKED ||
2342 HIWORD(wParam) == BN_DOUBLECLICKED)
2344 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2347 if (HIWORD(wParam) == EN_CHANGE)
2348 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2349 sizeof(cfg.keyfile) - 1);
2352 if (HIWORD(wParam) == EN_CHANGE)
2353 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2354 sizeof(cfg.remote_cmd) - 1);
2357 memset(&of, 0, sizeof(of));
2358 #ifdef OPENFILENAME_SIZE_VERSION_400
2359 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2361 of.lStructSize = sizeof(of);
2363 of.hwndOwner = hwnd;
2364 of.lpstrFilter = "All Files\0*\0\0\0";
2365 of.lpstrCustomFilter = NULL;
2366 of.nFilterIndex = 1;
2367 of.lpstrFile = filename;
2368 strcpy(filename, cfg.keyfile);
2369 of.nMaxFile = sizeof(filename);
2370 of.lpstrFileTitle = NULL;
2371 of.lpstrInitialDir = NULL;
2372 of.lpstrTitle = "Select Public Key File";
2374 if (GetOpenFileName(&of)) {
2375 strcpy(cfg.keyfile, filename);
2376 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2380 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2384 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2386 case IDC_MOUSEOVERRIDE:
2387 cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
2393 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2398 for (i = 0; i < 128; i++)
2399 if (SendDlgItemMessage
2400 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2402 cfg.wordness[i] = n;
2403 SendDlgItemMessage(hwnd, IDC_CCLIST,
2404 LB_DELETESTRING, i, 0);
2405 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2406 (i >= 0x21 && i != 0x7F) ? i : ' ',
2408 SendDlgItemMessage(hwnd, IDC_CCLIST,
2415 case IDC_BOLDCOLOUR:
2416 if (HIWORD(wParam) == BN_CLICKED ||
2417 HIWORD(wParam) == BN_DOUBLECLICKED) {
2420 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2421 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2424 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2426 if (n != 12 + 10 * cfg.bold_colour) {
2427 for (i = n; i-- > 0;)
2428 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2429 LB_DELETESTRING, i, 0);
2430 for (i = 0; i < 22; i++)
2431 if (cfg.bold_colour || permcolour[i])
2432 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2434 (LPARAM) colours[i]);
2436 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2438 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2443 if (HIWORD(wParam) == BN_CLICKED ||
2444 HIWORD(wParam) == BN_DOUBLECLICKED)
2446 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2448 case IDC_COLOURLIST:
2449 if (HIWORD(wParam) == LBN_DBLCLK ||
2450 HIWORD(wParam) == LBN_SELCHANGE) {
2452 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2455 if (!cfg.bold_colour)
2456 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2457 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2459 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2461 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2466 if (HIWORD(wParam) == BN_CLICKED ||
2467 HIWORD(wParam) == BN_DOUBLECLICKED) {
2468 static CHOOSECOLOR cc;
2469 static DWORD custom[16] = { 0 }; /* zero initialisers */
2471 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2474 if (!cfg.bold_colour)
2475 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2476 cc.lStructSize = sizeof(cc);
2477 cc.hwndOwner = hwnd;
2478 cc.hInstance = (HWND) hinst;
2479 cc.lpCustColors = custom;
2481 RGB(cfg.colours[i][0], cfg.colours[i][1],
2483 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2484 if (ChooseColor(&cc)) {
2486 (unsigned char) (cc.rgbResult & 0xFF);
2488 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2490 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2491 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2493 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2495 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2501 if (HIWORD(wParam) == CBN_SELCHANGE) {
2502 int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
2503 CB_GETCURSEL, 0, 0);
2504 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
2505 index, (LPARAM)cfg.line_codepage);
2506 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
2507 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2508 sizeof(cfg.line_codepage) - 1);
2509 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
2510 strcpy(cfg.line_codepage,
2511 cp_name(decode_codepage(cfg.line_codepage)));
2512 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2515 case IDC_VTXWINDOWS:
2521 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2522 : IsDlgButtonChecked(hwnd,
2523 IDC_VTOEMANSI) ? VT_OEMANSI :
2524 IsDlgButtonChecked(hwnd,
2525 IDC_VTOEMONLY) ? VT_OEMONLY :
2526 IsDlgButtonChecked(hwnd,
2527 IDC_VTUNICODE) ? VT_UNICODE :
2530 case IDC_X11_FORWARD:
2531 if (HIWORD(wParam) == BN_CLICKED ||
2532 HIWORD(wParam) == BN_DOUBLECLICKED)
2534 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2537 if (HIWORD(wParam) == BN_CLICKED ||
2538 HIWORD(wParam) == BN_DOUBLECLICKED)
2539 cfg.lport_acceptall =
2540 IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
2542 case IDC_X11_DISPLAY:
2543 if (HIWORD(wParam) == EN_CHANGE)
2544 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2545 sizeof(cfg.x11_display) - 1);
2548 if (HIWORD(wParam) == BN_CLICKED ||
2549 HIWORD(wParam) == BN_DOUBLECLICKED) {
2550 char str[sizeof(cfg.portfwd)];
2552 if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
2556 GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
2560 "You need to specify a source port number",
2561 "PuTTY Error", MB_OK | MB_ICONERROR);
2564 p = str + strlen(str);
2566 GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
2567 sizeof(str) - 1 - (p - str));
2568 if (!*p || !strchr(p, ':')) {
2570 "You need to specify a destination address\n"
2571 "in the form \"host.name:port\"",
2572 "PuTTY Error", MB_OK | MB_ICONERROR);
2581 if ((p - cfg.portfwd) + strlen(str) + 2 <
2582 sizeof(cfg.portfwd)) {
2584 p[strlen(str) + 1] = '\0';
2585 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
2587 SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
2588 SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
2590 MessageBox(hwnd, "Too many forwardings",
2591 "PuTTY Error", MB_OK | MB_ICONERROR);
2595 case IDC_PFWDREMOVE:
2596 if (HIWORD(wParam) != BN_CLICKED &&
2597 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2598 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
2599 LB_GETCURSEL, 0, 0);
2605 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
2637 /* Grrr Explorer will maximize Dialogs! */
2639 if (wParam == SIZE_MAXIMIZED)
2645 * Handle application-defined messages eg. DragListBox
2647 /* First find out what the number is (once). */
2648 if (draglistmsg == WM_NULL)
2649 draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
2651 if (msg == draglistmsg) {
2652 /* Only process once dialog is fully formed. */
2653 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
2654 case IDC_CIPHERLIST:
2655 return handle_prefslist(&cipherlist,
2656 cfg.ssh_cipherlist, CIPHER_MAX,
2657 1, hwnd, wParam, lParam);
2666 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2667 WPARAM wParam, LPARAM lParam)
2669 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2671 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2672 EnableWindow(hwnd, 0);
2673 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2674 EnableWindow(hwnd, 1);
2675 SetActiveWindow(hwnd);
2677 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2680 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2681 WPARAM wParam, LPARAM lParam)
2683 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2686 void defuse_showwindow(void)
2689 * Work around the fact that the app's first call to ShowWindow
2690 * will ignore the default in favour of the shell-provided
2695 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2697 ShowWindow(hwnd, SW_HIDE);
2698 SetActiveWindow(hwnd);
2699 DestroyWindow(hwnd);
2708 savedsession[0] = '\0';
2710 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2711 get_sesslist(FALSE);
2716 int do_reconfig(HWND hwnd)
2721 backup_cfg = cfg; /* structure copy */
2723 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2725 cfg = backup_cfg; /* structure copy */
2730 void logevent(char *string)
2735 if (nevents >= negsize) {
2737 events = srealloc(events, negsize * sizeof(*events));
2741 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2744 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2745 strcpy(events[nevents], timebuf);
2746 strcat(events[nevents], string);
2749 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2750 0, (LPARAM) events[nevents]);
2751 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2752 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2757 void showeventlog(HWND hwnd)
2760 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2762 ShowWindow(logbox, SW_SHOWNORMAL);
2764 SetActiveWindow(logbox);
2767 void showabout(HWND hwnd)
2769 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2772 void verify_ssh_host_key(char *host, int port, char *keytype,
2773 char *keystr, char *fingerprint)
2777 static const char absentmsg[] =
2778 "The server's host key is not cached in the registry. You\n"
2779 "have no guarantee that the server is the computer you\n"
2781 "The server's key fingerprint is:\n"
2783 "If you trust this host, hit Yes to add the key to\n"
2784 "PuTTY's cache and carry on connecting.\n"
2785 "If you want to carry on connecting just once, without\n"
2786 "adding the key to the cache, hit No.\n"
2787 "If you do not trust this host, hit Cancel to abandon the\n"
2790 static const char wrongmsg[] =
2791 "WARNING - POTENTIAL SECURITY BREACH!\n"
2793 "The server's host key does not match the one PuTTY has\n"
2794 "cached in the registry. This means that either the\n"
2795 "server administrator has changed the host key, or you\n"
2796 "have actually connected to another computer pretending\n"
2797 "to be the server.\n"
2798 "The new key fingerprint is:\n"
2800 "If you were expecting this change and trust the new key,\n"
2801 "hit Yes to update PuTTY's cache and continue connecting.\n"
2802 "If you want to carry on connecting but without updating\n"
2803 "the cache, hit No.\n"
2804 "If you want to abandon the connection completely, hit\n"
2805 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2807 static const char mbtitle[] = "PuTTY Security Alert";
2810 /* sensible fingerprint max size */
2811 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2812 sizeof(absentmsg) : sizeof(wrongmsg))];
2815 * Verify the key against the registry.
2817 ret = verify_host_key(host, port, keytype, keystr);
2819 if (ret == 0) /* success - key matched OK */
2821 if (ret == 2) { /* key was different */
2823 sprintf(message, wrongmsg, fingerprint);
2824 mbret = MessageBox(NULL, message, mbtitle,
2825 MB_ICONWARNING | MB_YESNOCANCEL);
2827 store_host_key(host, port, keytype, keystr);
2828 if (mbret == IDCANCEL)
2831 if (ret == 1) { /* key was absent */
2833 sprintf(message, absentmsg, fingerprint);
2834 mbret = MessageBox(NULL, message, mbtitle,
2835 MB_ICONWARNING | MB_YESNOCANCEL);
2837 store_host_key(host, port, keytype, keystr);
2838 if (mbret == IDCANCEL)
2844 * Ask whether the selected cipher is acceptable (since it was
2845 * below the configured 'warn' threshold).
2846 * cs: 0 = both ways, 1 = client->server, 2 = server->client
2848 void askcipher(char *ciphername, int cs)
2850 static const char mbtitle[] = "PuTTY Security Alert";
2851 static const char msg[] =
2852 "The first %.35scipher supported by the server\n"
2853 "is %.64s, which is below the configured\n"
2854 "warning threshold.\n"
2855 "Do you want to continue with this connection?\n";
2856 /* guessed cipher name + type max length */
2857 char message[100 + sizeof(msg)];
2860 sprintf(message, msg,
2862 (cs == 1) ? "client-to-server " :
2863 "server-to-client ",
2865 mbret = MessageBox(NULL, message, mbtitle,
2866 MB_ICONWARNING | MB_YESNO);
2874 * Ask whether to wipe a session log file before writing to it.
2875 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2877 int askappend(char *filename)
2879 static const char mbtitle[] = "PuTTY Log to File";
2880 static const char msgtemplate[] =
2881 "The session log file \"%.*s\" already exists.\n"
2882 "You can overwrite it with a new session log,\n"
2883 "append your session log to the end of it,\n"
2884 "or disable session logging for this session.\n"
2885 "Hit Yes to wipe the file, No to append to it,\n"
2886 "or Cancel to disable logging.";
2887 char message[sizeof(msgtemplate) + FILENAME_MAX];
2889 if (cfg.logxfovr != LGXF_ASK) {
2890 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2892 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2894 mbret = MessageBox(NULL, message, mbtitle,
2895 MB_ICONQUESTION | MB_YESNOCANCEL);
2898 else if (mbret == IDNO)