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 appearancepanelstart,
370 IDC_TITLE_APPEARANCE,
390 connectionpanelstart,
391 IDC_TITLE_CONNECTION,
498 translationpanelstart,
499 IDC_TITLE_TRANSLATION,
500 IDC_BOX_TRANSLATION1,
501 IDC_BOX_TRANSLATION2,
537 static const char *const colours[] = {
538 "Default Foreground", "Default Bold Foreground",
539 "Default Background", "Default Bold Background",
540 "Cursor Text", "Cursor Colour",
541 "ANSI Black", "ANSI Black Bold",
542 "ANSI Red", "ANSI Red Bold",
543 "ANSI Green", "ANSI Green Bold",
544 "ANSI Yellow", "ANSI Yellow Bold",
545 "ANSI Blue", "ANSI Blue Bold",
546 "ANSI Magenta", "ANSI Magenta Bold",
547 "ANSI Cyan", "ANSI Cyan Bold",
548 "ANSI White", "ANSI White Bold"
550 static const int permcolour[] = {
551 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
552 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
553 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
556 static void fmtfont(char *buf)
558 sprintf(buf, "Font: %s, ", cfg.font);
560 strcat(buf, "bold, ");
561 if (cfg.fontheight == 0)
562 strcat(buf, "default height");
564 sprintf(buf + strlen(buf), "%d-point",
565 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
568 /* 2nd arg: NZ => don't redraw session list (use when loading
570 static void init_dlg_ctrls(HWND hwnd, int keepsess)
573 char fontstatic[256];
575 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
576 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
579 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
580 for (i = n; i-- > 0;)
581 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
582 for (i = 0; i < nsessions; i++)
583 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
584 0, (LPARAM) (sessions[i]));
586 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
587 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
588 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
589 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
591 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
592 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
594 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
595 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
596 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
597 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
598 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
599 cfg.funky_type == 0 ? IDC_FUNCTILDE :
600 cfg.funky_type == 1 ? IDC_FUNCLINUX :
601 cfg.funky_type == 2 ? IDC_FUNCXTERM :
602 cfg.funky_type == 3 ? IDC_FUNCVT400 :
603 cfg.funky_type == 4 ? IDC_FUNCVT100P :
604 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
605 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
606 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
607 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
608 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
609 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
610 cfg.nethack_keypad ? IDC_KPNH :
611 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
612 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
613 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
614 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
615 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
616 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
617 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
618 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
619 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
620 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
621 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
622 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
623 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
624 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
625 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
626 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
627 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
629 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
630 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
631 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
632 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
633 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
634 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
636 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
637 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
638 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
639 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
640 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
642 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
643 CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
645 B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
646 B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
647 B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
648 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
649 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
650 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
651 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
652 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
654 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
655 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
657 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
658 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
659 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
660 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
661 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
662 cfg.cursor_type == 0 ? IDC_CURBLOCK :
663 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
664 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
665 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
666 CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize);
667 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
668 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
670 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
671 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
673 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
674 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
675 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
676 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
677 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
678 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
679 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
680 cfg.logtype == 0 ? IDC_LSTATOFF :
681 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
682 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
683 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
684 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
687 char *p = cfg.environmt;
688 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
690 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
696 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
701 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
702 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
703 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
704 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
706 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
707 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
708 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
709 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
710 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
711 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
712 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
713 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
714 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
715 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
716 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
720 static const struct { char *s; int c; } ciphers[] = {
721 { "3DES", CIPHER_3DES },
722 { "Blowfish", CIPHER_BLOWFISH },
723 { "DES (SSH 1 only)", CIPHER_DES },
724 { "AES (SSH 2 only)", CIPHER_AES },
725 { "-- warn below here --", CIPHER_WARN }
728 /* Set up the "selected ciphers" box. */
729 /* (cipherlist assumed to contain all ciphers) */
730 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0);
731 for (i = 0; i < CIPHER_MAX; i++) {
732 int c = cfg.ssh_cipherlist[i];
735 for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
736 if (ciphers[j].c == c) {
741 pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING,
743 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA,
750 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
751 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
752 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
754 static int tabs[4] = { 25, 61, 96, 128 };
755 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
758 for (i = 0; i < 128; i++) {
760 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
761 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
762 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
766 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
767 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
770 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
771 for (i = n; i-- > 0;)
772 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
773 LB_DELETESTRING, i, 0);
774 for (i = 0; i < 22; i++)
775 if (cfg.bold_colour || permcolour[i])
776 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
777 (LPARAM) colours[i]);
779 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
780 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
781 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
782 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
787 strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
788 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
789 for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
790 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
793 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
796 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
797 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
798 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
799 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
800 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
803 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
804 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
806 CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
807 CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
810 struct treeview_faff {
815 static HTREEITEM treeview_insert(struct treeview_faff *faff,
816 int level, char *text)
821 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
822 ins.hInsertAfter = faff->lastat[level];
823 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
824 #define INSITEM DUMMYUNIONNAME.item
828 ins.INSITEM.mask = TVIF_TEXT;
829 ins.INSITEM.pszText = text;
830 newitem = TreeView_InsertItem(faff->treeview, &ins);
832 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
834 faff->lastat[level] = newitem;
835 for (i = level + 1; i < 4; i++)
836 faff->lastat[i] = NULL;
841 * Create the panelfuls of controls in the configuration box.
843 static void create_controls(HWND hwnd, int dlgtype, int panel)
845 if (panel == sessionpanelstart) {
846 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
848 ctlposinit(&cp, hwnd, 80, 3, 13);
849 bartitle(&cp, "Basic options for your PuTTY session",
852 beginbox(&cp, "Specify your connection by host name or IP address",
855 "Host &Name (or IP address)",
856 IDC_HOSTSTATIC, IDC_HOST, 75,
857 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
858 if (backends[3].backend == NULL) {
859 /* this is PuTTYtel, so only three protocols available */
860 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
862 "&Telnet", IDC_PROTTELNET,
863 "Rlog&in", IDC_PROTRLOGIN, NULL);
865 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
867 "&Telnet", IDC_PROTTELNET,
868 "Rlog&in", IDC_PROTRLOGIN,
877 beginbox(&cp, "Load, save or delete a stored session",
879 sesssaver(&cp, "Sav&ed Sessions",
880 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
881 "&Load", IDC_SESSLOAD,
882 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
885 beginbox(&cp, NULL, IDC_BOX_SESSION3);
886 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
887 "Always", IDC_COEALWAYS,
888 "Never", IDC_COENEVER,
889 "Only on clean exit", IDC_COENORMAL, NULL);
893 if (panel == loggingpanelstart) {
894 /* The Logging panel. Accelerators used: [acgo] tplfwe */
896 ctlposinit(&cp, hwnd, 80, 3, 13);
897 bartitle(&cp, "Options controlling session logging",
899 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
901 "Session logging:", IDC_LSTATSTATIC,
902 "Logging &turned off completely", IDC_LSTATOFF,
903 "Log &printable output only", IDC_LSTATASCII,
904 "&Log all session output", IDC_LSTATRAW, NULL);
905 editbutton(&cp, "Log &file name:",
906 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
909 "What to do if the log file already &exists:",
910 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
911 "Always append to the end of it", IDC_LSTATXAPN,
912 "Ask the user every time", IDC_LSTATXASK, NULL);
916 if (panel == terminalpanelstart) {
917 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
919 ctlposinit(&cp, hwnd, 80, 3, 13);
920 bartitle(&cp, "Options controlling the terminal emulation",
922 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
923 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
924 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
925 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
926 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
927 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
929 "An&swerback to ^E:", IDC_ANSWERBACK,
930 IDC_ANSWEREDIT, 100, NULL);
933 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
934 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
935 "Auto", IDC_ECHOBACKEND,
936 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
937 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
938 "Auto", IDC_EDITBACKEND,
939 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
943 if (panel == bellpanelstart) {
944 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
946 ctlposinit(&cp, hwnd, 80, 3, 13);
947 bartitle(&cp, "Options controlling the terminal bell",
949 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
951 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
952 "None (bell disabled)", IDC_BELL_DISABLED,
953 "Play Windows Default Sound", IDC_BELL_DEFAULT,
954 "Play a custom sound file", IDC_BELL_WAVEFILE,
955 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
956 editbutton(&cp, "Custom sound file to play as a bell:",
957 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
958 "Bro&wse...", IDC_BELL_WAVEBROWSE);
959 radioline(&cp, "Taskbar/caption &indication on bell:",
960 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
961 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
964 beginbox(&cp, "Control the bell overload behaviour",
966 checkbox(&cp, "Bell is temporarily &disabled when over-used",
968 staticedit(&cp, "Over-use means this &many bells...",
969 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
970 staticedit(&cp, "... in &this many seconds",
971 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
973 "The bell is re-enabled after a few seconds of silence.",
975 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
980 if (panel == keyboardpanelstart) {
981 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
983 ctlposinit(&cp, hwnd, 80, 3, 13);
985 bartitle(&cp, "Options controlling the effects of keys",
988 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
989 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
990 "Control-H", IDC_DEL008,
991 "Control-? (127)", IDC_DEL127, NULL);
992 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
993 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
994 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
995 "ESC[n~", IDC_FUNCTILDE,
996 "Linux", IDC_FUNCLINUX,
997 "Xterm R6", IDC_FUNCXTERM,
998 "VT400", IDC_FUNCVT400,
999 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
1001 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
1003 "Application c&ursor keys totally disabled",
1005 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
1006 "Normal", IDC_CURNORMAL,
1007 "Application", IDC_CURAPPLIC, NULL);
1009 "Application ke&ypad keys totally disabled",
1011 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
1012 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
1013 "NetHack", IDC_KPNH, NULL);
1015 beginbox(&cp, "Enable extra keyboard features:",
1017 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
1018 checkbox(&cp, "Control-Alt is &different from AltGr",
1023 if (panel == windowpanelstart) {
1024 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
1026 ctlposinit(&cp, hwnd, 80, 3, 13);
1027 bartitle(&cp, "Options controlling PuTTY's window",
1029 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
1031 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
1032 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
1033 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
1035 beginbox(&cp, "Control the scrollback in the window",
1037 staticedit(&cp, "Lines of &scrollback",
1038 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
1039 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
1040 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
1041 checkbox(&cp, "Reset scrollback on dis&play activity",
1044 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
1045 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
1046 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
1047 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
1048 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
1049 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
1053 if (panel == appearancepanelstart) {
1054 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
1056 ctlposinit(&cp, hwnd, 80, 3, 13);
1057 bartitle(&cp, "Options controlling PuTTY's appearance",
1058 IDC_TITLE_APPEARANCE);
1059 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
1060 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
1061 "B&lock", IDC_CURBLOCK,
1062 "&Underline", IDC_CURUNDER,
1063 "&Vertical line", IDC_CURVERT, NULL);
1064 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
1066 beginbox(&cp, "Set the font used in the terminal window",
1067 IDC_BOX_APPEARANCE2);
1068 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
1070 beginbox(&cp, "Adjust the use of the window title",
1071 IDC_BOX_APPEARANCE3);
1073 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1074 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1076 beginbox(&cp, "Adjust the use of the mouse pointer",
1077 IDC_BOX_APPEARANCE4);
1078 checkbox(&cp, "Hide mouse &pointer when typing in window",
1081 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1082 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1087 if (panel == translationpanelstart) {
1088 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1090 ctlposinit(&cp, hwnd, 80, 3, 13);
1091 bartitle(&cp, "Options controlling character set translation",
1092 IDC_TITLE_TRANSLATION);
1093 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1094 IDC_BOX_TRANSLATION1);
1096 "Handling of line drawing characters:", IDC_VTSTATIC,
1097 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1098 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1099 "Use font in O&EM mode only", IDC_VTOEMONLY,
1100 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1101 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1103 beginbox(&cp, "Character set translation on received data",
1104 IDC_BOX_TRANSLATION2);
1105 combobox(&cp, "Received data assumed to be in which character set:",
1106 IDC_CODEPAGESTATIC, IDC_CODEPAGE);
1110 if (panel == selectionpanelstart) {
1111 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1113 ctlposinit(&cp, hwnd, 80, 3, 13);
1114 bartitle(&cp, "Options controlling copy and paste",
1115 IDC_TITLE_SELECTION);
1116 beginbox(&cp, "Translation of pasted characters",
1117 IDC_BOX_SELECTION1);
1119 "&Don't translate line drawing chars into +, - and |",
1122 beginbox(&cp, "Control which mouse button does which thing",
1123 IDC_BOX_SELECTION2);
1124 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1125 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1126 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1129 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1130 IDC_BOX_SELECTION3);
1131 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1132 "&Set", IDC_CCSET, IDC_CCEDIT,
1133 "&to class", IDC_CCSTATIC2);
1137 if (panel == colourspanelstart) {
1138 /* The Colours panel. Accelerators used: [acgo] blum */
1140 ctlposinit(&cp, hwnd, 80, 3, 13);
1141 bartitle(&cp, "Options controlling use of colours",
1143 beginbox(&cp, "General options for colour usage",
1145 checkbox(&cp, "&Bolded text is a different colour",
1147 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1149 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1151 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1152 IDC_COLOURSTATIC, IDC_COLOURLIST,
1153 "&Modify...", IDC_CHANGE,
1154 "Red:", IDC_RSTATIC, IDC_RVALUE,
1155 "Green:", IDC_GSTATIC, IDC_GVALUE,
1156 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1160 if (panel == connectionpanelstart) {
1161 /* The Connection panel. Accelerators used: [acgo] tuk */
1163 ctlposinit(&cp, hwnd, 80, 3, 13);
1164 bartitle(&cp, "Options controlling the connection",
1165 IDC_TITLE_CONNECTION);
1167 beginbox(&cp, "Data to send to the server",
1168 IDC_BOX_CONNECTION1);
1169 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1171 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1175 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1176 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1180 beginbox(&cp, "Sending of null packets to keep session active",
1181 IDC_BOX_CONNECTION2);
1182 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1183 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1187 if (panel == telnetpanelstart) {
1188 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1190 ctlposinit(&cp, hwnd, 80, 3, 13);
1192 bartitle(&cp, "Options controlling Telnet connections",
1194 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1195 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1197 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1198 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1199 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1200 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1202 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1203 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1204 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1205 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1206 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1207 "Passive", IDC_TPASSIVE, "Active",
1209 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1215 if (panel == rloginpanelstart) {
1216 /* The Rlogin panel. Accelerators used: [acgo] sl */
1218 ctlposinit(&cp, hwnd, 80, 3, 13);
1220 bartitle(&cp, "Options controlling Rlogin connections",
1222 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1223 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1225 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1226 IDC_RLLUSEREDIT, 50);
1231 if (panel == sshpanelstart) {
1232 /* The SSH panel. Accelerators used: [acgo] r pe12i sud */
1234 ctlposinit(&cp, hwnd, 80, 3, 13);
1236 bartitle(&cp, "Options controlling SSH connections",
1238 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1240 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1243 beginbox(&cp, "Protocol options", IDC_BOX_SSH2);
1244 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1245 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1246 radioline(&cp, "Preferred SSH protocol version:",
1247 IDC_SSHPROTSTATIC, 2,
1248 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1249 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1252 beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
1253 prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
1254 IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
1260 if (panel == sshauthpanelstart) {
1261 /* The SSH authentication panel. Accelerators used: [acgo] m fkw */
1263 ctlposinit(&cp, hwnd, 80, 3, 13);
1265 bartitle(&cp, "Options controlling SSH authentication",
1267 beginbox(&cp, "Authentication methods",
1269 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1272 beginbox(&cp, "Authentication parameters",
1274 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1275 editbutton(&cp, "Private &key file for authentication:",
1276 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1282 if (panel == tunnelspanelstart) {
1283 /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
1285 ctlposinit(&cp, hwnd, 80, 3, 13);
1287 bartitle(&cp, "Options controlling SSH tunnelling",
1289 beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
1290 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1291 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1292 IDC_X11_DISPLAY, 50, NULL);
1294 beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
1295 checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL);
1296 staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
1297 "&Remove", IDC_PFWDREMOVE);
1298 fwdsetter(&cp, IDC_PFWDLIST,
1299 "Add new forwarded port:", IDC_PFWDSTATIC2,
1300 "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
1301 "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
1302 "A&dd", IDC_PFWDADD);
1303 bareradioline(&cp, 2,
1304 "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL);
1312 * Helper function to load the session selected in SESSLIST
1313 * if any, as this is done in more than one place in
1314 * GenericMainDlgProc(). 0 => failure.
1316 static int load_selected_session(HWND hwnd)
1318 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1319 LB_GETCURSEL, 0, 0);
1325 isdef = !strcmp(sessions[n], "Default Settings");
1326 load_settings(sessions[n], !isdef, &cfg);
1327 init_dlg_ctrls(hwnd, TRUE);
1329 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1331 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1332 /* Restore the selection, which will have been clobbered by
1333 * SESSEDIT handling. */
1334 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1339 * This function is the configuration box.
1341 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1342 WPARAM wParam, LPARAM lParam, int dlgtype)
1345 struct treeview_faff tvfaff;
1348 char filename[sizeof(cfg.keyfile)];
1351 char fontstatic[256];
1353 struct servent *service;
1355 static UINT draglistmsg = WM_NULL;
1360 SetWindowLong(hwnd, GWL_USERDATA, 0);
1361 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1362 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1364 * Centre the window.
1366 { /* centre the window */
1369 hw = GetDesktopWindow();
1370 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1372 (rs.right + rs.left + rd.left - rd.right) / 2,
1373 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1374 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1378 * Create the tree view.
1386 r.right = r.left + 75;
1388 r.bottom = r.top + 10;
1389 MapDialogRect(hwnd, &r);
1390 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1391 WS_CHILD | WS_VISIBLE,
1393 r.right - r.left, r.bottom - r.top,
1394 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1396 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1397 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1400 r.right = r.left + 75;
1402 r.bottom = r.top + 206;
1403 MapDialogRect(hwnd, &r);
1404 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1405 WS_CHILD | WS_VISIBLE |
1406 WS_TABSTOP | TVS_HASLINES |
1407 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1409 TVS_SHOWSELALWAYS, r.left, r.top,
1410 r.right - r.left, r.bottom - r.top,
1411 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1413 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1414 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1415 tvfaff.treeview = treeview;
1416 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1420 * Set up the tree view contents.
1422 hsession = treeview_insert(&tvfaff, 0, "Session");
1423 treeview_insert(&tvfaff, 1, "Logging");
1424 treeview_insert(&tvfaff, 0, "Terminal");
1425 treeview_insert(&tvfaff, 1, "Keyboard");
1426 treeview_insert(&tvfaff, 1, "Bell");
1427 treeview_insert(&tvfaff, 0, "Window");
1428 treeview_insert(&tvfaff, 1, "Appearance");
1429 treeview_insert(&tvfaff, 1, "Translation");
1430 treeview_insert(&tvfaff, 1, "Selection");
1431 treeview_insert(&tvfaff, 1, "Colours");
1432 treeview_insert(&tvfaff, 0, "Connection");
1434 treeview_insert(&tvfaff, 1, "Telnet");
1435 treeview_insert(&tvfaff, 1, "Rlogin");
1436 if (backends[3].backend != NULL) {
1437 treeview_insert(&tvfaff, 1, "SSH");
1438 /* XXX long name is ugly */
1439 /* XXX make it closed by default? */
1440 treeview_insert(&tvfaff, 2, "Auth");
1441 treeview_insert(&tvfaff, 2, "Tunnels");
1446 * Put the treeview selection on to the Session panel. This
1447 * should also cause creation of the relevant controls.
1449 TreeView_SelectItem(treeview, hsession);
1452 * Set focus into the first available control.
1456 ctl = GetDlgItem(hwnd, IDC_HOST);
1458 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1462 SetWindowLong(hwnd, GWL_USERDATA, 1);
1463 sesslist_has_focus = 0;
1467 * Button release should trigger WM_OK if there was a
1468 * previous double click on the session list.
1472 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1475 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1476 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1478 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1483 item.pszText = buffer;
1484 item.cchTextMax = sizeof(buffer);
1485 item.mask = TVIF_TEXT;
1486 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1487 for (j = controlstartvalue; j < controlendvalue; j++) {
1488 HWND item = GetDlgItem(hwnd, j);
1490 DestroyWindow(item);
1492 if (!strcmp(buffer, "Session"))
1493 create_controls(hwnd, dlgtype, sessionpanelstart);
1494 if (!strcmp(buffer, "Logging"))
1495 create_controls(hwnd, dlgtype, loggingpanelstart);
1496 if (!strcmp(buffer, "Keyboard"))
1497 create_controls(hwnd, dlgtype, keyboardpanelstart);
1498 if (!strcmp(buffer, "Terminal"))
1499 create_controls(hwnd, dlgtype, terminalpanelstart);
1500 if (!strcmp(buffer, "Bell"))
1501 create_controls(hwnd, dlgtype, bellpanelstart);
1502 if (!strcmp(buffer, "Window"))
1503 create_controls(hwnd, dlgtype, windowpanelstart);
1504 if (!strcmp(buffer, "Appearance"))
1505 create_controls(hwnd, dlgtype, appearancepanelstart);
1506 if (!strcmp(buffer, "Tunnels"))
1507 create_controls(hwnd, dlgtype, tunnelspanelstart);
1508 if (!strcmp(buffer, "Connection"))
1509 create_controls(hwnd, dlgtype, connectionpanelstart);
1510 if (!strcmp(buffer, "Telnet"))
1511 create_controls(hwnd, dlgtype, telnetpanelstart);
1512 if (!strcmp(buffer, "Rlogin"))
1513 create_controls(hwnd, dlgtype, rloginpanelstart);
1514 if (!strcmp(buffer, "SSH"))
1515 create_controls(hwnd, dlgtype, sshpanelstart);
1516 if (!strcmp(buffer, "Auth"))
1517 create_controls(hwnd, dlgtype, sshauthpanelstart);
1518 if (!strcmp(buffer, "Selection"))
1519 create_controls(hwnd, dlgtype, selectionpanelstart);
1520 if (!strcmp(buffer, "Colours"))
1521 create_controls(hwnd, dlgtype, colourspanelstart);
1522 if (!strcmp(buffer, "Translation"))
1523 create_controls(hwnd, dlgtype, translationpanelstart);
1525 init_dlg_ctrls(hwnd, FALSE);
1527 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1533 * Only process WM_COMMAND once the dialog is fully formed.
1535 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1536 switch (LOWORD(wParam)) {
1538 /* Behaviour of the "Open" button is different if the
1539 * session list has focus, *unless* the user just
1540 * double-clicked... */
1541 if (sesslist_has_focus && !readytogo) {
1542 if (!load_selected_session(hwnd)) {
1547 /* If at this point we have a valid session, go! */
1556 case IDC_PROTTELNET:
1557 case IDC_PROTRLOGIN:
1560 if (HIWORD(wParam) == BN_CLICKED ||
1561 HIWORD(wParam) == BN_DOUBLECLICKED) {
1562 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1563 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1564 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1566 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1568 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1569 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1570 || (cfg.protocol == PROT_RLOGIN
1571 && cfg.port != 513)) {
1572 cfg.port = i ? 22 : j ? 23 : 513;
1573 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1578 if (HIWORD(wParam) == EN_CHANGE)
1579 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1580 sizeof(cfg.host) - 1);
1583 if (HIWORD(wParam) == EN_CHANGE) {
1584 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1585 if (isdigit(portname[0]))
1586 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1588 service = getservbyname(portname, NULL);
1590 cfg.port = ntohs(service->s_port);
1597 if (HIWORD(wParam) == EN_CHANGE) {
1598 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1600 GetDlgItemText(hwnd, IDC_SESSEDIT,
1601 savedsession, sizeof(savedsession) - 1);
1602 savedsession[sizeof(savedsession) - 1] = '\0';
1606 if (HIWORD(wParam) == BN_CLICKED ||
1607 HIWORD(wParam) == BN_DOUBLECLICKED) {
1612 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1615 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1616 LB_GETCURSEL, 0, 0);
1621 strcpy(str, sessions[n]);
1623 save_settings(str, !!strcmp(str, "Default Settings"),
1625 get_sesslist(FALSE);
1627 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1629 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1631 for (i = 0; i < nsessions; i++)
1632 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1634 (LPARAM) (sessions[i]));
1635 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1637 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1639 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1645 if (LOWORD(wParam) == IDC_SESSLIST) {
1646 if (HIWORD(wParam) == LBN_SETFOCUS)
1647 sesslist_has_focus = 1;
1648 else if (HIWORD(wParam) == LBN_KILLFOCUS)
1649 sesslist_has_focus = 0;
1651 if (LOWORD(wParam) == IDC_SESSLOAD &&
1652 HIWORD(wParam) != BN_CLICKED &&
1653 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1654 if (LOWORD(wParam) == IDC_SESSLIST &&
1655 HIWORD(wParam) != LBN_DBLCLK) break;
1656 /* Load the session selected in SESSLIST. */
1657 if (load_selected_session(hwnd) &&
1658 LOWORD(wParam) == IDC_SESSLIST) {
1660 * A double-click on a saved session should
1661 * actually start the session, not just load it.
1662 * Unless it's Default Settings or some other
1663 * host-less set of saved settings.
1672 if (HIWORD(wParam) == BN_CLICKED ||
1673 HIWORD(wParam) == BN_DOUBLECLICKED) {
1674 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1675 LB_GETCURSEL, 0, 0);
1676 if (n == LB_ERR || n == 0) {
1680 del_settings(sessions[n]);
1681 get_sesslist(FALSE);
1683 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1685 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1687 for (i = 0; i < nsessions; i++)
1688 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1690 (LPARAM) (sessions[i]));
1691 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1693 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1695 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1699 if (HIWORD(wParam) == EN_CHANGE)
1700 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1701 &cfg.ping_interval);
1705 if (HIWORD(wParam) == BN_CLICKED ||
1706 HIWORD(wParam) == BN_DOUBLECLICKED)
1707 cfg.bksp_is_delete =
1708 IsDlgButtonChecked(hwnd, IDC_DEL127);
1712 if (HIWORD(wParam) == BN_CLICKED ||
1713 HIWORD(wParam) == BN_DOUBLECLICKED)
1715 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1721 case IDC_FUNCVT100P:
1723 if (HIWORD(wParam) == BN_CLICKED ||
1724 HIWORD(wParam) == BN_DOUBLECLICKED)
1725 switch (LOWORD(wParam)) {
1738 case IDC_FUNCVT100P:
1748 if (HIWORD(wParam) == BN_CLICKED ||
1749 HIWORD(wParam) == BN_DOUBLECLICKED) {
1751 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1752 cfg.nethack_keypad = FALSE;
1756 if (HIWORD(wParam) == BN_CLICKED ||
1757 HIWORD(wParam) == BN_DOUBLECLICKED) {
1758 cfg.app_keypad = FALSE;
1759 cfg.nethack_keypad = TRUE;
1764 if (HIWORD(wParam) == BN_CLICKED ||
1765 HIWORD(wParam) == BN_DOUBLECLICKED)
1767 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1770 if (HIWORD(wParam) == BN_CLICKED ||
1771 HIWORD(wParam) == BN_DOUBLECLICKED)
1773 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1776 if (HIWORD(wParam) == BN_CLICKED ||
1777 HIWORD(wParam) == BN_DOUBLECLICKED)
1779 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1782 if (HIWORD(wParam) == BN_CLICKED ||
1783 HIWORD(wParam) == BN_DOUBLECLICKED)
1784 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1787 if (HIWORD(wParam) == BN_CLICKED ||
1788 HIWORD(wParam) == BN_DOUBLECLICKED)
1790 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1793 if (HIWORD(wParam) == BN_CLICKED ||
1794 HIWORD(wParam) == BN_DOUBLECLICKED)
1796 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1798 case IDC_ECHOBACKEND:
1801 if (HIWORD(wParam) == BN_CLICKED ||
1802 HIWORD(wParam) == BN_DOUBLECLICKED) {
1803 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1804 cfg.localecho = LD_BACKEND;
1805 if (LOWORD(wParam) == IDC_ECHOYES)
1806 cfg.localecho = LD_YES;
1807 if (LOWORD(wParam) == IDC_ECHONO)
1808 cfg.localecho = LD_NO;
1811 case IDC_EDITBACKEND:
1814 if (HIWORD(wParam) == BN_CLICKED ||
1815 HIWORD(wParam) == BN_DOUBLECLICKED) {
1816 if (LOWORD(wParam) == IDC_EDITBACKEND)
1817 cfg.localedit = LD_BACKEND;
1818 if (LOWORD(wParam) == IDC_EDITYES)
1819 cfg.localedit = LD_YES;
1820 if (LOWORD(wParam) == IDC_EDITNO)
1821 cfg.localedit = LD_NO;
1824 case IDC_ANSWEREDIT:
1825 if (HIWORD(wParam) == EN_CHANGE)
1826 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1827 sizeof(cfg.answerback) - 1);
1829 case IDC_ALWAYSONTOP:
1830 if (HIWORD(wParam) == BN_CLICKED ||
1831 HIWORD(wParam) == BN_DOUBLECLICKED)
1833 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1836 if (HIWORD(wParam) == BN_CLICKED ||
1837 HIWORD(wParam) == BN_DOUBLECLICKED)
1839 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1841 case IDC_SCROLLDISP:
1842 if (HIWORD(wParam) == BN_CLICKED ||
1843 HIWORD(wParam) == BN_DOUBLECLICKED)
1844 cfg.scroll_on_disp =
1845 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1847 case IDC_COMPOSEKEY:
1848 if (HIWORD(wParam) == BN_CLICKED ||
1849 HIWORD(wParam) == BN_DOUBLECLICKED)
1851 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1853 case IDC_CTRLALTKEYS:
1854 if (HIWORD(wParam) == BN_CLICKED ||
1855 HIWORD(wParam) == BN_DOUBLECLICKED)
1857 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1860 if (HIWORD(wParam) == BN_CLICKED ||
1861 HIWORD(wParam) == BN_DOUBLECLICKED)
1862 cfg.telnet_keyboard =
1863 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1866 if (HIWORD(wParam) == BN_CLICKED ||
1867 HIWORD(wParam) == BN_DOUBLECLICKED)
1869 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1872 if (HIWORD(wParam) == BN_CLICKED ||
1873 HIWORD(wParam) == BN_DOUBLECLICKED)
1874 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1877 if (HIWORD(wParam) == BN_CLICKED ||
1878 HIWORD(wParam) == BN_DOUBLECLICKED)
1880 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1883 if (HIWORD(wParam) == EN_CHANGE)
1884 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1887 if (HIWORD(wParam) == EN_CHANGE)
1888 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1891 if (HIWORD(wParam) == EN_CHANGE)
1892 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1894 case IDC_CHOOSEFONT:
1897 lf.lfHeight = -MulDiv(cfg.fontheight,
1898 GetDeviceCaps(hdc, LOGPIXELSY),
1902 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1903 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1904 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1905 lf.lfCharSet = cfg.fontcharset;
1906 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1907 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1908 lf.lfQuality = DEFAULT_QUALITY;
1909 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1910 strncpy(lf.lfFaceName, cfg.font,
1911 sizeof(lf.lfFaceName) - 1);
1912 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1914 cf.lStructSize = sizeof(cf);
1915 cf.hwndOwner = hwnd;
1917 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1918 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1920 if (ChooseFont(&cf)) {
1921 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1922 cfg.font[sizeof(cfg.font) - 1] = '\0';
1923 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1924 cfg.fontcharset = lf.lfCharSet;
1925 cfg.fontheight = cf.iPointSize / 10;
1926 fmtfont(fontstatic);
1927 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1930 case IDC_BELL_DISABLED:
1931 case IDC_BELL_DEFAULT:
1932 case IDC_BELL_WAVEFILE:
1933 case IDC_BELL_VISUAL:
1934 if (HIWORD(wParam) == BN_CLICKED ||
1935 HIWORD(wParam) == BN_DOUBLECLICKED) {
1936 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1937 cfg.beep = BELL_DISABLED;
1938 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1939 cfg.beep = BELL_DEFAULT;
1940 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1941 cfg.beep = BELL_WAVEFILE;
1942 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1943 cfg.beep = BELL_VISUAL;
1946 case IDC_B_IND_DISABLED:
1947 case IDC_B_IND_FLASH:
1948 case IDC_B_IND_STEADY:
1949 if (HIWORD(wParam) == BN_CLICKED ||
1950 HIWORD(wParam) == BN_DOUBLECLICKED) {
1951 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
1952 cfg.beep_ind = B_IND_DISABLED;
1953 if (LOWORD(wParam) == IDC_B_IND_FLASH)
1954 cfg.beep_ind = B_IND_FLASH;
1955 if (LOWORD(wParam) == IDC_B_IND_STEADY)
1956 cfg.beep_ind = B_IND_STEADY;
1959 case IDC_BELL_WAVEBROWSE:
1960 memset(&of, 0, sizeof(of));
1961 #ifdef OPENFILENAME_SIZE_VERSION_400
1962 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1964 of.lStructSize = sizeof(of);
1966 of.hwndOwner = hwnd;
1967 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1968 of.lpstrCustomFilter = NULL;
1969 of.nFilterIndex = 1;
1970 of.lpstrFile = filename;
1971 strcpy(filename, cfg.bell_wavefile);
1972 of.nMaxFile = sizeof(filename);
1973 of.lpstrFileTitle = NULL;
1974 of.lpstrInitialDir = NULL;
1975 of.lpstrTitle = "Select Bell Sound File";
1977 if (GetOpenFileName(&of)) {
1978 strcpy(cfg.bell_wavefile, filename);
1979 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1983 case IDC_BELL_WAVEEDIT:
1984 if (HIWORD(wParam) == EN_CHANGE)
1985 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1987 sizeof(cfg.bell_wavefile) - 1);
1990 if (HIWORD(wParam) == BN_CLICKED ||
1991 HIWORD(wParam) == BN_DOUBLECLICKED)
1993 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1996 if (HIWORD(wParam) == EN_CHANGE)
1997 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2000 if (HIWORD(wParam) == EN_CHANGE)
2001 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2005 if (HIWORD(wParam) == EN_CHANGE)
2006 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2010 if (HIWORD(wParam) == BN_CLICKED ||
2011 HIWORD(wParam) == BN_DOUBLECLICKED)
2013 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2016 if (HIWORD(wParam) == BN_CLICKED ||
2017 HIWORD(wParam) == BN_DOUBLECLICKED)
2018 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2021 if (HIWORD(wParam) == BN_CLICKED ||
2022 HIWORD(wParam) == BN_DOUBLECLICKED)
2023 cfg.win_name_always =
2024 IsDlgButtonChecked(hwnd, IDC_WINNAME);
2027 if (HIWORD(wParam) == BN_CLICKED ||
2028 HIWORD(wParam) == BN_DOUBLECLICKED)
2030 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2032 case IDC_SUNKENEDGE:
2033 if (HIWORD(wParam) == BN_CLICKED ||
2034 HIWORD(wParam) == BN_DOUBLECLICKED)
2036 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2039 if (HIWORD(wParam) == BN_CLICKED ||
2040 HIWORD(wParam) == BN_DOUBLECLICKED)
2041 cfg.cursor_type = 0;
2044 if (HIWORD(wParam) == BN_CLICKED ||
2045 HIWORD(wParam) == BN_DOUBLECLICKED)
2046 cfg.cursor_type = 1;
2049 if (HIWORD(wParam) == BN_CLICKED ||
2050 HIWORD(wParam) == BN_DOUBLECLICKED)
2051 cfg.cursor_type = 2;
2054 if (HIWORD(wParam) == BN_CLICKED ||
2055 HIWORD(wParam) == BN_DOUBLECLICKED)
2057 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2060 if (HIWORD(wParam) == BN_CLICKED ||
2061 HIWORD(wParam) == BN_DOUBLECLICKED)
2063 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2066 if (HIWORD(wParam) == BN_CLICKED ||
2067 HIWORD(wParam) == BN_DOUBLECLICKED)
2069 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
2072 if (HIWORD(wParam) == EN_CHANGE)
2073 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2074 sizeof(cfg.wintitle) - 1);
2079 if (HIWORD(wParam) == BN_CLICKED ||
2080 HIWORD(wParam) == BN_DOUBLECLICKED) {
2082 IsDlgButtonChecked(hwnd,
2083 IDC_COEALWAYS) ? COE_ALWAYS :
2084 IsDlgButtonChecked(hwnd,
2085 IDC_COENEVER) ? COE_NEVER :
2090 if (HIWORD(wParam) == BN_CLICKED ||
2091 HIWORD(wParam) == BN_DOUBLECLICKED)
2093 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
2096 if (HIWORD(wParam) == EN_CHANGE)
2097 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
2098 sizeof(cfg.termtype) - 1);
2101 if (HIWORD(wParam) == EN_CHANGE)
2102 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
2103 sizeof(cfg.logfilename) - 1);
2106 memset(&of, 0, sizeof(of));
2107 #ifdef OPENFILENAME_SIZE_VERSION_400
2108 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2110 of.lStructSize = sizeof(of);
2112 of.hwndOwner = hwnd;
2113 of.lpstrFilter = "All Files\0*\0\0\0";
2114 of.lpstrCustomFilter = NULL;
2115 of.nFilterIndex = 1;
2116 of.lpstrFile = filename;
2117 strcpy(filename, cfg.logfilename);
2118 of.nMaxFile = sizeof(filename);
2119 of.lpstrFileTitle = NULL;
2120 of.lpstrInitialDir = NULL;
2121 of.lpstrTitle = "Select session log file";
2123 if (GetSaveFileName(&of)) {
2124 strcpy(cfg.logfilename, filename);
2125 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2129 case IDC_LSTATASCII:
2131 if (HIWORD(wParam) == BN_CLICKED ||
2132 HIWORD(wParam) == BN_DOUBLECLICKED) {
2133 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2135 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2137 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2144 if (HIWORD(wParam) == BN_CLICKED ||
2145 HIWORD(wParam) == BN_DOUBLECLICKED) {
2146 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2147 cfg.logxfovr = LGXF_ASK;
2148 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2149 cfg.logxfovr = LGXF_APN;
2150 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2151 cfg.logxfovr = LGXF_OVR;
2156 if (HIWORD(wParam) == EN_CHANGE)
2157 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2158 sizeof(cfg.termspeed) - 1);
2161 if (HIWORD(wParam) == EN_CHANGE)
2162 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2163 sizeof(cfg.username) - 1);
2165 case IDC_RLLUSEREDIT:
2166 if (HIWORD(wParam) == EN_CHANGE)
2167 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2169 sizeof(cfg.localusername) - 1);
2173 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2177 cfg.passive_telnet =
2178 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2181 if (HIWORD(wParam) == BN_CLICKED ||
2182 HIWORD(wParam) == BN_DOUBLECLICKED) {
2183 char str[sizeof(cfg.environmt)];
2185 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2191 p = str + strlen(str);
2193 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2194 sizeof(str) - 1 - (p - str));
2205 if ((p - cfg.environmt) + strlen(str) + 2 <
2206 sizeof(cfg.environmt)) {
2208 p[strlen(str) + 1] = '\0';
2209 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2211 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2212 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2214 MessageBox(hwnd, "Environment too big",
2215 "PuTTY Error", MB_OK | MB_ICONERROR);
2220 if (HIWORD(wParam) != BN_CLICKED &&
2221 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2223 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2230 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2257 if (HIWORD(wParam) == BN_CLICKED ||
2258 HIWORD(wParam) == BN_DOUBLECLICKED)
2259 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2262 if (HIWORD(wParam) == BN_CLICKED ||
2263 HIWORD(wParam) == BN_DOUBLECLICKED)
2265 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2268 if (HIWORD(wParam) == BN_CLICKED ||
2269 HIWORD(wParam) == BN_DOUBLECLICKED)
2271 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2274 if (HIWORD(wParam) == BN_CLICKED ||
2275 HIWORD(wParam) == BN_DOUBLECLICKED)
2277 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2279 case IDC_CIPHERLIST:
2282 handle_prefslist(&cipherlist,
2283 cfg.ssh_cipherlist, CIPHER_MAX,
2284 0, hwnd, wParam, lParam);
2288 if (HIWORD(wParam) == BN_CLICKED ||
2289 HIWORD(wParam) == BN_DOUBLECLICKED) {
2290 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2292 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2297 if (HIWORD(wParam) == BN_CLICKED ||
2298 HIWORD(wParam) == BN_DOUBLECLICKED)
2300 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2303 if (HIWORD(wParam) == EN_CHANGE)
2304 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2305 sizeof(cfg.keyfile) - 1);
2308 if (HIWORD(wParam) == EN_CHANGE)
2309 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2310 sizeof(cfg.remote_cmd) - 1);
2313 memset(&of, 0, sizeof(of));
2314 #ifdef OPENFILENAME_SIZE_VERSION_400
2315 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2317 of.lStructSize = sizeof(of);
2319 of.hwndOwner = hwnd;
2320 of.lpstrFilter = "All Files\0*\0\0\0";
2321 of.lpstrCustomFilter = NULL;
2322 of.nFilterIndex = 1;
2323 of.lpstrFile = filename;
2324 strcpy(filename, cfg.keyfile);
2325 of.nMaxFile = sizeof(filename);
2326 of.lpstrFileTitle = NULL;
2327 of.lpstrInitialDir = NULL;
2328 of.lpstrTitle = "Select Public Key File";
2330 if (GetOpenFileName(&of)) {
2331 strcpy(cfg.keyfile, filename);
2332 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2336 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2339 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2345 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2350 for (i = 0; i < 128; i++)
2351 if (SendDlgItemMessage
2352 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2354 cfg.wordness[i] = n;
2355 SendDlgItemMessage(hwnd, IDC_CCLIST,
2356 LB_DELETESTRING, i, 0);
2357 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2358 (i >= 0x21 && i != 0x7F) ? i : ' ',
2360 SendDlgItemMessage(hwnd, IDC_CCLIST,
2367 case IDC_BOLDCOLOUR:
2368 if (HIWORD(wParam) == BN_CLICKED ||
2369 HIWORD(wParam) == BN_DOUBLECLICKED) {
2372 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2373 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2376 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2378 if (n != 12 + 10 * cfg.bold_colour) {
2379 for (i = n; i-- > 0;)
2380 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2381 LB_DELETESTRING, i, 0);
2382 for (i = 0; i < 22; i++)
2383 if (cfg.bold_colour || permcolour[i])
2384 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2386 (LPARAM) colours[i]);
2388 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2390 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2395 if (HIWORD(wParam) == BN_CLICKED ||
2396 HIWORD(wParam) == BN_DOUBLECLICKED)
2398 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2400 case IDC_COLOURLIST:
2401 if (HIWORD(wParam) == LBN_DBLCLK ||
2402 HIWORD(wParam) == LBN_SELCHANGE) {
2404 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2407 if (!cfg.bold_colour)
2408 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2409 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2411 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2413 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2418 if (HIWORD(wParam) == BN_CLICKED ||
2419 HIWORD(wParam) == BN_DOUBLECLICKED) {
2420 static CHOOSECOLOR cc;
2421 static DWORD custom[16] = { 0 }; /* zero initialisers */
2423 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2426 if (!cfg.bold_colour)
2427 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2428 cc.lStructSize = sizeof(cc);
2429 cc.hwndOwner = hwnd;
2430 cc.hInstance = (HWND) hinst;
2431 cc.lpCustColors = custom;
2433 RGB(cfg.colours[i][0], cfg.colours[i][1],
2435 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2436 if (ChooseColor(&cc)) {
2438 (unsigned char) (cc.rgbResult & 0xFF);
2440 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2442 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2443 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2445 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2447 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2453 if (HIWORD(wParam) == CBN_SELCHANGE) {
2454 int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
2455 CB_GETCURSEL, 0, 0);
2456 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
2457 index, (LPARAM)cfg.line_codepage);
2458 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
2459 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2460 sizeof(cfg.line_codepage) - 1);
2461 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
2462 strcpy(cfg.line_codepage,
2463 cp_name(decode_codepage(cfg.line_codepage)));
2464 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2467 case IDC_VTXWINDOWS:
2473 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2474 : IsDlgButtonChecked(hwnd,
2475 IDC_VTOEMANSI) ? VT_OEMANSI :
2476 IsDlgButtonChecked(hwnd,
2477 IDC_VTOEMONLY) ? VT_OEMONLY :
2478 IsDlgButtonChecked(hwnd,
2479 IDC_VTUNICODE) ? VT_UNICODE :
2482 case IDC_X11_FORWARD:
2483 if (HIWORD(wParam) == BN_CLICKED ||
2484 HIWORD(wParam) == BN_DOUBLECLICKED)
2486 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2489 if (HIWORD(wParam) == BN_CLICKED ||
2490 HIWORD(wParam) == BN_DOUBLECLICKED)
2491 cfg.lport_acceptall =
2492 IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
2494 case IDC_X11_DISPLAY:
2495 if (HIWORD(wParam) == EN_CHANGE)
2496 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2497 sizeof(cfg.x11_display) - 1);
2500 if (HIWORD(wParam) == BN_CLICKED ||
2501 HIWORD(wParam) == BN_DOUBLECLICKED) {
2502 char str[sizeof(cfg.portfwd)];
2504 if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
2508 GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
2512 "You need to specify a source port number",
2513 "PuTTY Error", MB_OK | MB_ICONERROR);
2516 p = str + strlen(str);
2518 GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
2519 sizeof(str) - 1 - (p - str));
2520 if (!*p || !strchr(p, ':')) {
2522 "You need to specify a destination address\n"
2523 "in the form \"host.name:port\"",
2524 "PuTTY Error", MB_OK | MB_ICONERROR);
2533 if ((p - cfg.portfwd) + strlen(str) + 2 <
2534 sizeof(cfg.portfwd)) {
2536 p[strlen(str) + 1] = '\0';
2537 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
2539 SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
2540 SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
2542 MessageBox(hwnd, "Too many forwardings",
2543 "PuTTY Error", MB_OK | MB_ICONERROR);
2547 case IDC_PFWDREMOVE:
2548 if (HIWORD(wParam) != BN_CLICKED &&
2549 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2550 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
2551 LB_GETCURSEL, 0, 0);
2557 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
2589 /* Grrr Explorer will maximize Dialogs! */
2591 if (wParam == SIZE_MAXIMIZED)
2597 * Handle application-defined messages eg. DragListBox
2599 /* First find out what the number is (once). */
2600 if (draglistmsg == WM_NULL)
2601 draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
2603 if (msg == draglistmsg) {
2604 /* Only process once dialog is fully formed. */
2605 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
2606 case IDC_CIPHERLIST:
2607 return handle_prefslist(&cipherlist,
2608 cfg.ssh_cipherlist, CIPHER_MAX,
2609 1, hwnd, wParam, lParam);
2618 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2619 WPARAM wParam, LPARAM lParam)
2621 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2623 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2624 EnableWindow(hwnd, 0);
2625 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2626 EnableWindow(hwnd, 1);
2627 SetActiveWindow(hwnd);
2629 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2632 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2633 WPARAM wParam, LPARAM lParam)
2635 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2638 void defuse_showwindow(void)
2641 * Work around the fact that the app's first call to ShowWindow
2642 * will ignore the default in favour of the shell-provided
2647 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2649 ShowWindow(hwnd, SW_HIDE);
2650 SetActiveWindow(hwnd);
2651 DestroyWindow(hwnd);
2660 savedsession[0] = '\0';
2662 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2663 get_sesslist(FALSE);
2668 int do_reconfig(HWND hwnd)
2673 backup_cfg = cfg; /* structure copy */
2675 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2677 cfg = backup_cfg; /* structure copy */
2682 void logevent(char *string)
2687 if (nevents >= negsize) {
2689 events = srealloc(events, negsize * sizeof(*events));
2693 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2696 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2697 strcpy(events[nevents], timebuf);
2698 strcat(events[nevents], string);
2701 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2702 0, (LPARAM) events[nevents]);
2703 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2704 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2709 void showeventlog(HWND hwnd)
2712 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2714 ShowWindow(logbox, SW_SHOWNORMAL);
2716 SetActiveWindow(logbox);
2719 void showabout(HWND hwnd)
2721 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2724 void verify_ssh_host_key(char *host, int port, char *keytype,
2725 char *keystr, char *fingerprint)
2729 static const char absentmsg[] =
2730 "The server's host key is not cached in the registry. You\n"
2731 "have no guarantee that the server is the computer you\n"
2733 "The server's key fingerprint is:\n"
2735 "If you trust this host, hit Yes to add the key to\n"
2736 "PuTTY's cache and carry on connecting.\n"
2737 "If you want to carry on connecting just once, without\n"
2738 "adding the key to the cache, hit No.\n"
2739 "If you do not trust this host, hit Cancel to abandon the\n"
2742 static const char wrongmsg[] =
2743 "WARNING - POTENTIAL SECURITY BREACH!\n"
2745 "The server's host key does not match the one PuTTY has\n"
2746 "cached in the registry. This means that either the\n"
2747 "server administrator has changed the host key, or you\n"
2748 "have actually connected to another computer pretending\n"
2749 "to be the server.\n"
2750 "The new key fingerprint is:\n"
2752 "If you were expecting this change and trust the new key,\n"
2753 "hit Yes to update PuTTY's cache and continue connecting.\n"
2754 "If you want to carry on connecting but without updating\n"
2755 "the cache, hit No.\n"
2756 "If you want to abandon the connection completely, hit\n"
2757 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2759 static const char mbtitle[] = "PuTTY Security Alert";
2762 /* sensible fingerprint max size */
2763 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2764 sizeof(absentmsg) : sizeof(wrongmsg))];
2767 * Verify the key against the registry.
2769 ret = verify_host_key(host, port, keytype, keystr);
2771 if (ret == 0) /* success - key matched OK */
2773 if (ret == 2) { /* key was different */
2775 sprintf(message, wrongmsg, fingerprint);
2776 mbret = MessageBox(NULL, message, mbtitle,
2777 MB_ICONWARNING | MB_YESNOCANCEL);
2779 store_host_key(host, port, keytype, keystr);
2780 if (mbret == IDCANCEL)
2783 if (ret == 1) { /* key was absent */
2785 sprintf(message, absentmsg, fingerprint);
2786 mbret = MessageBox(NULL, message, mbtitle,
2787 MB_ICONWARNING | MB_YESNOCANCEL);
2789 store_host_key(host, port, keytype, keystr);
2790 if (mbret == IDCANCEL)
2796 * Ask whether the selected cipher is acceptable (since it was
2797 * below the configured 'warn' threshold).
2798 * cs: 0 = both ways, 1 = client->server, 2 = server->client
2800 void askcipher(char *ciphername, int cs)
2802 static const char mbtitle[] = "PuTTY Security Alert";
2803 static const char msg[] =
2804 "The first %.35scipher supported by the server\n"
2805 "is %.64s, which is below the configured\n"
2806 "warning threshold.\n"
2807 "Do you want to continue with this connection?\n";
2808 /* guessed cipher name + type max length */
2809 char message[100 + sizeof(msg)];
2812 sprintf(message, msg,
2814 (cs == 1) ? "client-to-server " :
2815 "server-to-client ",
2817 mbret = MessageBox(NULL, message, mbtitle,
2818 MB_ICONWARNING | MB_YESNO);
2826 * Ask whether to wipe a session log file before writing to it.
2827 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2829 int askappend(char *filename)
2831 static const char mbtitle[] = "PuTTY Log to File";
2832 static const char msgtemplate[] =
2833 "The session log file \"%.*s\" already exists.\n"
2834 "You can overwrite it with a new session log,\n"
2835 "append your session log to the end of it,\n"
2836 "or disable session logging for this session.\n"
2837 "Hit Yes to wipe the file, No to append to it,\n"
2838 "or Cancel to disable logging.";
2839 char message[sizeof(msgtemplate) + FILENAME_MAX];
2841 if (cfg.logxfovr != LGXF_ASK) {
2842 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2844 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2846 mbret = MessageBox(NULL, message, mbtitle,
2847 MB_ICONQUESTION | MB_YESNOCANCEL);
2850 else if (mbret == IDNO)