15 static char **events = NULL;
16 static int nevents = 0, negsize = 0;
19 static int sesslist_has_focus;
21 void force_normal(HWND hwnd)
23 static int recurse = 0;
31 wp.length = sizeof(wp);
32 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
33 wp.showCmd = SW_SHOWNORMAL;
34 SetWindowPlacement(hwnd, &wp);
39 static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
43 n = GetDlgItemInt(hwnd, id, &ok, FALSE);
48 static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
52 ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
54 *result = (int) (scale * atof(text));
57 static void MySetDlgItemFlt(HWND hwnd, int id, double value)
60 sprintf(text, "%g", value);
61 SetDlgItemText(hwnd, id, text);
64 static int CALLBACK LogProc(HWND hwnd, UINT msg,
65 WPARAM wParam, LPARAM lParam)
72 static int tabs[4] = { 78, 108 };
73 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
76 for (i = 0; i < nevents; i++)
77 SendDlgItemMessage(hwnd, IDN_LIST, LB_ADDSTRING,
78 0, (LPARAM) events[i]);
81 switch (LOWORD(wParam)) {
85 SetActiveWindow(GetParent(hwnd));
89 if (HIWORD(wParam) == BN_CLICKED ||
90 HIWORD(wParam) == BN_DOUBLECLICKED) {
93 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
94 LB_GETSELCOUNT, 0, 0);
95 if (selcount == 0) { /* don't even try to copy zero items */
100 selitems = smalloc(selcount * sizeof(int));
102 int count = SendDlgItemMessage(hwnd, IDN_LIST,
109 static unsigned char sel_nl[] = SEL_NL;
111 if (count == 0) { /* can't copy zero stuff */
117 for (i = 0; i < count; i++)
119 strlen(events[selitems[i]]) + sizeof(sel_nl);
121 clipdata = smalloc(size);
124 for (i = 0; i < count; i++) {
125 char *q = events[selitems[i]];
126 int qlen = strlen(q);
129 memcpy(p, sel_nl, sizeof(sel_nl));
132 write_aclip(clipdata, size, TRUE);
137 for (i = 0; i < nevents; i++)
138 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
147 SetActiveWindow(GetParent(hwnd));
154 static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
155 WPARAM wParam, LPARAM lParam)
161 switch (LOWORD(wParam)) {
174 static int CALLBACK AboutProc(HWND hwnd, UINT msg,
175 WPARAM wParam, LPARAM lParam)
179 SetDlgItemText(hwnd, IDA_VERSION, ver);
182 switch (LOWORD(wParam)) {
185 EndDialog(hwnd, TRUE);
188 EnableWindow(hwnd, 0);
189 DialogBox(hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
191 EnableWindow(hwnd, 1);
192 SetActiveWindow(hwnd);
196 /* Load web browser */
197 ShellExecute(hwnd, "open",
198 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
199 0, 0, SW_SHOWDEFAULT);
204 EndDialog(hwnd, TRUE);
211 * Null dialog procedure.
213 static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
214 WPARAM wParam, LPARAM lParam)
219 static char savedsession[2048];
222 IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
367 appearancepanelstart,
368 IDC_TITLE_APPEARANCE,
388 connectionpanelstart,
389 IDC_TITLE_CONNECTION,
490 translationpanelstart,
491 IDC_TITLE_TRANSLATION,
492 IDC_BOX_TRANSLATION1,
493 IDC_BOX_TRANSLATION2,
529 static const char *const colours[] = {
530 "Default Foreground", "Default Bold Foreground",
531 "Default Background", "Default Bold Background",
532 "Cursor Text", "Cursor Colour",
533 "ANSI Black", "ANSI Black Bold",
534 "ANSI Red", "ANSI Red Bold",
535 "ANSI Green", "ANSI Green Bold",
536 "ANSI Yellow", "ANSI Yellow Bold",
537 "ANSI Blue", "ANSI Blue Bold",
538 "ANSI Magenta", "ANSI Magenta Bold",
539 "ANSI Cyan", "ANSI Cyan Bold",
540 "ANSI White", "ANSI White Bold"
542 static const int permcolour[] = {
543 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
544 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
545 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
548 static void fmtfont(char *buf)
550 sprintf(buf, "Font: %s, ", cfg.font);
552 strcat(buf, "bold, ");
553 if (cfg.fontheight == 0)
554 strcat(buf, "default height");
556 sprintf(buf + strlen(buf), "%d-point",
557 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
560 /* 2nd arg: NZ => don't redraw session list (use when loading
562 static void init_dlg_ctrls(HWND hwnd, int keepsess)
565 char fontstatic[256];
567 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
568 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
571 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
572 for (i = n; i-- > 0;)
573 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
574 for (i = 0; i < nsessions; i++)
575 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
576 0, (LPARAM) (sessions[i]));
578 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
579 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
580 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
581 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
583 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
584 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
586 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
587 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
588 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
589 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
590 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
591 cfg.funky_type == 0 ? IDC_FUNCTILDE :
592 cfg.funky_type == 1 ? IDC_FUNCLINUX :
593 cfg.funky_type == 2 ? IDC_FUNCXTERM :
594 cfg.funky_type == 3 ? IDC_FUNCVT400 :
595 cfg.funky_type == 4 ? IDC_FUNCVT100P :
596 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
597 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
598 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
599 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
600 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
601 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
602 cfg.nethack_keypad ? IDC_KPNH :
603 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
604 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
605 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
606 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
607 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
608 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
609 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
610 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
611 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
612 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
613 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
614 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
615 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
616 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
617 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
618 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
619 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
621 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
622 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
623 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
624 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
625 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
626 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
628 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
629 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
630 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
631 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
632 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
634 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
635 CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
637 B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
638 B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
639 B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
640 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
641 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
642 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
643 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
644 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
646 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
647 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
649 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
650 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
651 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
652 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
653 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
654 cfg.cursor_type == 0 ? IDC_CURBLOCK :
655 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
656 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
657 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
658 CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize);
659 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
660 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
662 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
663 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
665 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
666 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
667 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
668 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
669 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
670 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
671 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
672 cfg.logtype == 0 ? IDC_LSTATOFF :
673 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
674 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
675 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
676 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
679 char *p = cfg.environmt;
680 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
682 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
688 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
693 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
694 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
695 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
696 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
698 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
699 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
700 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
701 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
702 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
703 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
704 CheckRadioButton(hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
705 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
706 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
707 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
709 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
710 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
711 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
712 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
713 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
715 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
716 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
717 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
719 static int tabs[4] = { 25, 61, 96, 128 };
720 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
723 for (i = 0; i < 128; i++) {
725 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
726 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
727 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
731 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
732 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
735 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
736 for (i = n; i-- > 0;)
737 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
738 LB_DELETESTRING, i, 0);
739 for (i = 0; i < 22; i++)
740 if (cfg.bold_colour || permcolour[i])
741 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
742 (LPARAM) colours[i]);
744 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
745 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
746 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
747 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
753 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
754 for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
755 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
757 if (!strcmp(cp, cfg.line_codepage))
760 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_SETCURSEL, index, 0);
763 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
764 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
765 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
766 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
767 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
770 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
771 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
773 CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
774 CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
777 struct treeview_faff {
782 static HTREEITEM treeview_insert(struct treeview_faff *faff,
783 int level, char *text)
788 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
789 ins.hInsertAfter = faff->lastat[level];
790 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
791 #define INSITEM DUMMYUNIONNAME.item
795 ins.INSITEM.mask = TVIF_TEXT;
796 ins.INSITEM.pszText = text;
797 newitem = TreeView_InsertItem(faff->treeview, &ins);
799 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
801 faff->lastat[level] = newitem;
802 for (i = level + 1; i < 4; i++)
803 faff->lastat[i] = NULL;
808 * Create the panelfuls of controls in the configuration box.
810 static void create_controls(HWND hwnd, int dlgtype, int panel)
812 if (panel == sessionpanelstart) {
813 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
815 ctlposinit(&cp, hwnd, 80, 3, 13);
816 bartitle(&cp, "Basic options for your PuTTY session",
819 beginbox(&cp, "Specify your connection by host name",
822 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
823 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
824 if (backends[3].backend == NULL) {
825 /* this is PuTTYtel, so only three protocols available */
826 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
828 "&Telnet", IDC_PROTTELNET,
829 "Rlog&in", IDC_PROTRLOGIN, NULL);
831 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
833 "&Telnet", IDC_PROTTELNET,
834 "Rlog&in", IDC_PROTRLOGIN,
843 beginbox(&cp, "Load, save or delete a stored session",
845 sesssaver(&cp, "Sav&ed Sessions",
846 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
847 "&Load", IDC_SESSLOAD,
848 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
851 beginbox(&cp, NULL, IDC_BOX_SESSION3);
852 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
853 "Always", IDC_COEALWAYS,
854 "Never", IDC_COENEVER,
855 "Only on clean exit", IDC_COENORMAL, NULL);
859 if (panel == loggingpanelstart) {
860 /* The Logging panel. Accelerators used: [acgo] tplfwe */
862 ctlposinit(&cp, hwnd, 80, 3, 13);
863 bartitle(&cp, "Options controlling session logging",
865 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
867 "Session logging:", IDC_LSTATSTATIC,
868 "Logging &turned off completely", IDC_LSTATOFF,
869 "Log &printable output only", IDC_LSTATASCII,
870 "&Log all session output", IDC_LSTATRAW, NULL);
871 editbutton(&cp, "Log &file name:",
872 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
875 "What to do if the log file already &exists:",
876 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
877 "Always append to the end of it", IDC_LSTATXAPN,
878 "Ask the user every time", IDC_LSTATXASK, NULL);
882 if (panel == terminalpanelstart) {
883 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
885 ctlposinit(&cp, hwnd, 80, 3, 13);
886 bartitle(&cp, "Options controlling the terminal emulation",
888 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
889 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
890 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
891 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
892 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
893 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
895 "An&swerback to ^E:", IDC_ANSWERBACK,
896 IDC_ANSWEREDIT, 100, NULL);
899 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
900 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
901 "Auto", IDC_ECHOBACKEND,
902 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
903 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
904 "Auto", IDC_EDITBACKEND,
905 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
909 if (panel == bellpanelstart) {
910 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
912 ctlposinit(&cp, hwnd, 80, 3, 13);
913 bartitle(&cp, "Options controlling the terminal bell",
915 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
917 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
918 "None (bell disabled)", IDC_BELL_DISABLED,
919 "Play Windows Default Sound", IDC_BELL_DEFAULT,
920 "Play a custom sound file", IDC_BELL_WAVEFILE,
921 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
922 editbutton(&cp, "Custom sound file to play as a bell:",
923 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
924 "Bro&wse...", IDC_BELL_WAVEBROWSE);
925 radioline(&cp, "Taskbar/caption &indication on bell:",
926 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
927 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
930 beginbox(&cp, "Control the bell overload behaviour",
932 checkbox(&cp, "Bell is temporarily &disabled when over-used",
934 staticedit(&cp, "Over-use means this &many bells...",
935 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
936 staticedit(&cp, "... in &this many seconds",
937 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
939 "The bell is re-enabled after a few seconds of silence.",
941 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
946 if (panel == keyboardpanelstart) {
947 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
949 ctlposinit(&cp, hwnd, 80, 3, 13);
951 bartitle(&cp, "Options controlling the effects of keys",
954 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
955 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
956 "Control-H", IDC_DEL008,
957 "Control-? (127)", IDC_DEL127, NULL);
958 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
959 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
960 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
961 "ESC[n~", IDC_FUNCTILDE,
962 "Linux", IDC_FUNCLINUX,
963 "Xterm R6", IDC_FUNCXTERM,
964 "VT400", IDC_FUNCVT400,
965 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
967 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
969 "Application c&ursor keys totally disabled",
971 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
972 "Normal", IDC_CURNORMAL,
973 "Application", IDC_CURAPPLIC, NULL);
975 "Application ke&ypad keys totally disabled",
977 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
978 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
979 "NetHack", IDC_KPNH, NULL);
981 beginbox(&cp, "Enable extra keyboard features:",
983 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
984 checkbox(&cp, "Control-Alt is &different from AltGr",
989 if (panel == windowpanelstart) {
990 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
992 ctlposinit(&cp, hwnd, 80, 3, 13);
993 bartitle(&cp, "Options controlling PuTTY's window",
995 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
997 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
998 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
999 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
1001 beginbox(&cp, "Control the scrollback in the window",
1003 staticedit(&cp, "Lines of &scrollback",
1004 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
1005 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
1006 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
1007 checkbox(&cp, "Reset scrollback on dis&play activity",
1010 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
1011 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
1012 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
1013 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
1014 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
1015 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
1019 if (panel == appearancepanelstart) {
1020 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
1022 ctlposinit(&cp, hwnd, 80, 3, 13);
1023 bartitle(&cp, "Options controlling PuTTY's appearance",
1024 IDC_TITLE_APPEARANCE);
1025 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
1026 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
1027 "B&lock", IDC_CURBLOCK,
1028 "&Underline", IDC_CURUNDER,
1029 "&Vertical line", IDC_CURVERT, NULL);
1030 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
1032 beginbox(&cp, "Set the font used in the terminal window",
1033 IDC_BOX_APPEARANCE2);
1034 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
1036 beginbox(&cp, "Adjust the use of the window title",
1037 IDC_BOX_APPEARANCE3);
1039 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1040 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1042 beginbox(&cp, "Adjust the use of the mouse pointer",
1043 IDC_BOX_APPEARANCE4);
1044 checkbox(&cp, "Hide mouse &pointer when typing in window",
1047 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1048 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1053 if (panel == translationpanelstart) {
1054 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1056 ctlposinit(&cp, hwnd, 80, 3, 13);
1057 bartitle(&cp, "Options controlling character set translation",
1058 IDC_TITLE_TRANSLATION);
1059 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1060 IDC_BOX_TRANSLATION1);
1062 "Handling of line drawing characters:", IDC_VTSTATIC,
1063 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1064 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1065 "Use font in O&EM mode only", IDC_VTOEMONLY,
1066 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1067 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1069 beginbox(&cp, "Character set translation on received data",
1070 IDC_BOX_TRANSLATION2);
1072 "Received data assumed to be in which character set:",
1073 IDC_CODEPAGESTATIC, IDC_CODEPAGE);
1077 if (panel == selectionpanelstart) {
1078 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1080 ctlposinit(&cp, hwnd, 80, 3, 13);
1081 bartitle(&cp, "Options controlling copy and paste",
1082 IDC_TITLE_SELECTION);
1083 beginbox(&cp, "Translation of pasted characters",
1084 IDC_BOX_SELECTION1);
1086 "&Don't translate line drawing chars into +, - and |",
1089 beginbox(&cp, "Control which mouse button does which thing",
1090 IDC_BOX_SELECTION2);
1091 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1092 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1093 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1096 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1097 IDC_BOX_SELECTION3);
1098 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1099 "&Set", IDC_CCSET, IDC_CCEDIT,
1100 "&to class", IDC_CCSTATIC2);
1104 if (panel == colourspanelstart) {
1105 /* The Colours panel. Accelerators used: [acgo] blum */
1107 ctlposinit(&cp, hwnd, 80, 3, 13);
1108 bartitle(&cp, "Options controlling use of colours",
1110 beginbox(&cp, "General options for colour usage",
1112 checkbox(&cp, "&Bolded text is a different colour",
1114 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1116 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1118 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1119 IDC_COLOURSTATIC, IDC_COLOURLIST,
1120 "&Modify...", IDC_CHANGE,
1121 "Red:", IDC_RSTATIC, IDC_RVALUE,
1122 "Green:", IDC_GSTATIC, IDC_GVALUE,
1123 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1127 if (panel == connectionpanelstart) {
1128 /* The Connection panel. Accelerators used: [acgo] tuk */
1130 ctlposinit(&cp, hwnd, 80, 3, 13);
1131 bartitle(&cp, "Options controlling the connection",
1132 IDC_TITLE_CONNECTION);
1134 beginbox(&cp, "Data to send to the server",
1135 IDC_BOX_CONNECTION1);
1136 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1138 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1142 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1143 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1147 beginbox(&cp, "Sending of null packets to keep session active",
1148 IDC_BOX_CONNECTION2);
1149 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1150 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1154 if (panel == telnetpanelstart) {
1155 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1157 ctlposinit(&cp, hwnd, 80, 3, 13);
1159 bartitle(&cp, "Options controlling Telnet connections",
1161 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1162 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1164 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1165 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1166 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1167 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1169 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1170 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1171 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1172 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1173 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1174 "Passive", IDC_TPASSIVE, "Active",
1176 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1182 if (panel == rloginpanelstart) {
1183 /* The Rlogin panel. Accelerators used: [acgo] sl */
1185 ctlposinit(&cp, hwnd, 80, 3, 13);
1187 bartitle(&cp, "Options controlling Rlogin connections",
1189 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1190 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1192 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1193 IDC_RLLUSEREDIT, 50);
1198 if (panel == sshpanelstart) {
1199 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1201 ctlposinit(&cp, hwnd, 80, 3, 13);
1203 bartitle(&cp, "Options controlling SSH connections",
1205 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1207 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1210 beginbox(&cp, "Authentication options", IDC_BOX_SSH2);
1211 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1213 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1214 editbutton(&cp, "Private &key file for authentication:",
1215 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1218 beginbox(&cp, "Protocol options", IDC_BOX_SSH3);
1219 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1220 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1221 radioline(&cp, "Preferred SSH protocol version:",
1222 IDC_SSHPROTSTATIC, 2,
1223 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1224 radioline(&cp, "Preferred encryption algorithm:",
1225 IDC_CIPHERSTATIC, 4, "&3DES", IDC_CIPHER3DES,
1226 "&Blowfish", IDC_CIPHERBLOWF, "&DES", IDC_CIPHERDES,
1227 "AE&S", IDC_CIPHERAES, NULL);
1228 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1234 if (panel == tunnelspanelstart) {
1235 /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
1237 ctlposinit(&cp, hwnd, 80, 3, 13);
1239 bartitle(&cp, "Options controlling SSH tunnelling",
1241 beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
1242 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1243 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1244 IDC_X11_DISPLAY, 50, NULL);
1246 beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
1247 checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL);
1248 staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
1249 "&Remove", IDC_PFWDREMOVE);
1250 fwdsetter(&cp, IDC_PFWDLIST,
1251 "Add new forwarded port:", IDC_PFWDSTATIC2,
1252 "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
1253 "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
1254 "A&dd", IDC_PFWDADD);
1255 bareradioline(&cp, 2,
1256 "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL);
1264 * Helper function to load the session selected in SESSLIST
1265 * if any, as this is done in more than one place in
1266 * GenericMainDlgProc(). 0 => failure.
1268 static int load_selected_session(HWND hwnd)
1270 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1271 LB_GETCURSEL, 0, 0);
1277 isdef = !strcmp(sessions[n], "Default Settings");
1278 load_settings(sessions[n], !isdef, &cfg);
1279 init_dlg_ctrls(hwnd, TRUE);
1281 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1283 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1284 /* Restore the selection, which will have been clobbered by
1285 * SESSEDIT handling. */
1286 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1291 * This function is the configuration box.
1293 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1294 WPARAM wParam, LPARAM lParam, int dlgtype)
1297 struct treeview_faff tvfaff;
1300 char filename[sizeof(cfg.keyfile)];
1303 char fontstatic[256];
1305 struct servent *service;
1311 SetWindowLong(hwnd, GWL_USERDATA, 0);
1312 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1313 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1315 * Centre the window.
1317 { /* centre the window */
1320 hw = GetDesktopWindow();
1321 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1323 (rs.right + rs.left + rd.left - rd.right) / 2,
1324 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1325 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1329 * Create the tree view.
1337 r.right = r.left + 75;
1339 r.bottom = r.top + 10;
1340 MapDialogRect(hwnd, &r);
1341 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1342 WS_CHILD | WS_VISIBLE,
1344 r.right - r.left, r.bottom - r.top,
1345 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1347 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1348 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1351 r.right = r.left + 75;
1353 r.bottom = r.top + 206;
1354 MapDialogRect(hwnd, &r);
1355 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1356 WS_CHILD | WS_VISIBLE |
1357 WS_TABSTOP | TVS_HASLINES |
1358 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1360 TVS_SHOWSELALWAYS, r.left, r.top,
1361 r.right - r.left, r.bottom - r.top,
1362 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1364 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1365 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1366 tvfaff.treeview = treeview;
1367 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1371 * Set up the tree view contents.
1373 hsession = treeview_insert(&tvfaff, 0, "Session");
1374 treeview_insert(&tvfaff, 1, "Logging");
1375 treeview_insert(&tvfaff, 0, "Terminal");
1376 treeview_insert(&tvfaff, 1, "Keyboard");
1377 treeview_insert(&tvfaff, 1, "Bell");
1378 treeview_insert(&tvfaff, 0, "Window");
1379 treeview_insert(&tvfaff, 1, "Appearance");
1380 treeview_insert(&tvfaff, 1, "Translation");
1381 treeview_insert(&tvfaff, 1, "Selection");
1382 treeview_insert(&tvfaff, 1, "Colours");
1383 treeview_insert(&tvfaff, 0, "Connection");
1385 treeview_insert(&tvfaff, 1, "Telnet");
1386 treeview_insert(&tvfaff, 1, "Rlogin");
1387 if (backends[3].backend != NULL) {
1388 treeview_insert(&tvfaff, 1, "SSH");
1389 treeview_insert(&tvfaff, 2, "Tunnels");
1394 * Put the treeview selection on to the Session panel. This
1395 * should also cause creation of the relevant controls.
1397 TreeView_SelectItem(treeview, hsession);
1400 * Set focus into the first available control.
1404 ctl = GetDlgItem(hwnd, IDC_HOST);
1406 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1410 SetWindowLong(hwnd, GWL_USERDATA, 1);
1411 sesslist_has_focus = 0;
1415 * Button release should trigger WM_OK if there was a
1416 * previous double click on the session list.
1420 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1423 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1424 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1426 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1431 item.pszText = buffer;
1432 item.cchTextMax = sizeof(buffer);
1433 item.mask = TVIF_TEXT;
1434 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1435 for (j = controlstartvalue; j < controlendvalue; j++) {
1436 HWND item = GetDlgItem(hwnd, j);
1438 DestroyWindow(item);
1440 if (!strcmp(buffer, "Session"))
1441 create_controls(hwnd, dlgtype, sessionpanelstart);
1442 if (!strcmp(buffer, "Logging"))
1443 create_controls(hwnd, dlgtype, loggingpanelstart);
1444 if (!strcmp(buffer, "Keyboard"))
1445 create_controls(hwnd, dlgtype, keyboardpanelstart);
1446 if (!strcmp(buffer, "Terminal"))
1447 create_controls(hwnd, dlgtype, terminalpanelstart);
1448 if (!strcmp(buffer, "Bell"))
1449 create_controls(hwnd, dlgtype, bellpanelstart);
1450 if (!strcmp(buffer, "Window"))
1451 create_controls(hwnd, dlgtype, windowpanelstart);
1452 if (!strcmp(buffer, "Appearance"))
1453 create_controls(hwnd, dlgtype, appearancepanelstart);
1454 if (!strcmp(buffer, "Tunnels"))
1455 create_controls(hwnd, dlgtype, tunnelspanelstart);
1456 if (!strcmp(buffer, "Connection"))
1457 create_controls(hwnd, dlgtype, connectionpanelstart);
1458 if (!strcmp(buffer, "Telnet"))
1459 create_controls(hwnd, dlgtype, telnetpanelstart);
1460 if (!strcmp(buffer, "Rlogin"))
1461 create_controls(hwnd, dlgtype, rloginpanelstart);
1462 if (!strcmp(buffer, "SSH"))
1463 create_controls(hwnd, dlgtype, sshpanelstart);
1464 if (!strcmp(buffer, "Selection"))
1465 create_controls(hwnd, dlgtype, selectionpanelstart);
1466 if (!strcmp(buffer, "Colours"))
1467 create_controls(hwnd, dlgtype, colourspanelstart);
1468 if (!strcmp(buffer, "Translation"))
1469 create_controls(hwnd, dlgtype, translationpanelstart);
1471 init_dlg_ctrls(hwnd, FALSE);
1473 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1479 * Only process WM_COMMAND once the dialog is fully formed.
1481 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1482 switch (LOWORD(wParam)) {
1484 /* Behaviour of the "Open" button is different if the
1485 * session list has focus, *unless* the user just
1486 * double-clicked... */
1487 if (sesslist_has_focus && !readytogo) {
1488 if (!load_selected_session(hwnd)) {
1493 /* If at this point we have a valid session, go! */
1502 case IDC_PROTTELNET:
1503 case IDC_PROTRLOGIN:
1506 if (HIWORD(wParam) == BN_CLICKED ||
1507 HIWORD(wParam) == BN_DOUBLECLICKED) {
1508 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1509 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1510 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1512 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1514 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1515 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1516 || (cfg.protocol == PROT_RLOGIN
1517 && cfg.port != 513)) {
1518 cfg.port = i ? 22 : j ? 23 : 513;
1519 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1524 if (HIWORD(wParam) == EN_CHANGE)
1525 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1526 sizeof(cfg.host) - 1);
1529 if (HIWORD(wParam) == EN_CHANGE) {
1530 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1531 if (isdigit(portname[0]))
1532 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1534 service = getservbyname(portname, NULL);
1536 cfg.port = ntohs(service->s_port);
1543 if (HIWORD(wParam) == EN_CHANGE) {
1544 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1546 GetDlgItemText(hwnd, IDC_SESSEDIT,
1547 savedsession, sizeof(savedsession) - 1);
1548 savedsession[sizeof(savedsession) - 1] = '\0';
1552 if (HIWORD(wParam) == BN_CLICKED ||
1553 HIWORD(wParam) == BN_DOUBLECLICKED) {
1558 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1561 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1562 LB_GETCURSEL, 0, 0);
1567 strcpy(str, sessions[n]);
1569 save_settings(str, !!strcmp(str, "Default Settings"),
1571 get_sesslist(FALSE);
1573 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1575 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1577 for (i = 0; i < nsessions; i++)
1578 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1580 (LPARAM) (sessions[i]));
1581 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1583 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1585 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1591 if (LOWORD(wParam) == IDC_SESSLIST) {
1592 if (HIWORD(wParam) == LBN_SETFOCUS)
1593 sesslist_has_focus = 1;
1594 else if (HIWORD(wParam) == LBN_KILLFOCUS)
1595 sesslist_has_focus = 0;
1597 if (LOWORD(wParam) == IDC_SESSLOAD &&
1598 HIWORD(wParam) != BN_CLICKED &&
1599 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1600 if (LOWORD(wParam) == IDC_SESSLIST &&
1601 HIWORD(wParam) != LBN_DBLCLK) break;
1602 /* Load the session selected in SESSLIST. */
1603 if (load_selected_session(hwnd) &&
1604 LOWORD(wParam) == IDC_SESSLIST) {
1606 * A double-click on a saved session should
1607 * actually start the session, not just load it.
1608 * Unless it's Default Settings or some other
1609 * host-less set of saved settings.
1618 if (HIWORD(wParam) == BN_CLICKED ||
1619 HIWORD(wParam) == BN_DOUBLECLICKED) {
1620 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1621 LB_GETCURSEL, 0, 0);
1622 if (n == LB_ERR || n == 0) {
1626 del_settings(sessions[n]);
1627 get_sesslist(FALSE);
1629 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1631 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1633 for (i = 0; i < nsessions; i++)
1634 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1636 (LPARAM) (sessions[i]));
1637 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1639 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1641 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1645 if (HIWORD(wParam) == EN_CHANGE)
1646 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1647 &cfg.ping_interval);
1651 if (HIWORD(wParam) == BN_CLICKED ||
1652 HIWORD(wParam) == BN_DOUBLECLICKED)
1653 cfg.bksp_is_delete =
1654 IsDlgButtonChecked(hwnd, IDC_DEL127);
1658 if (HIWORD(wParam) == BN_CLICKED ||
1659 HIWORD(wParam) == BN_DOUBLECLICKED)
1661 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1667 case IDC_FUNCVT100P:
1669 if (HIWORD(wParam) == BN_CLICKED ||
1670 HIWORD(wParam) == BN_DOUBLECLICKED)
1671 switch (LOWORD(wParam)) {
1684 case IDC_FUNCVT100P:
1694 if (HIWORD(wParam) == BN_CLICKED ||
1695 HIWORD(wParam) == BN_DOUBLECLICKED) {
1697 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1698 cfg.nethack_keypad = FALSE;
1702 if (HIWORD(wParam) == BN_CLICKED ||
1703 HIWORD(wParam) == BN_DOUBLECLICKED) {
1704 cfg.app_keypad = FALSE;
1705 cfg.nethack_keypad = TRUE;
1710 if (HIWORD(wParam) == BN_CLICKED ||
1711 HIWORD(wParam) == BN_DOUBLECLICKED)
1713 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1716 if (HIWORD(wParam) == BN_CLICKED ||
1717 HIWORD(wParam) == BN_DOUBLECLICKED)
1719 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1722 if (HIWORD(wParam) == BN_CLICKED ||
1723 HIWORD(wParam) == BN_DOUBLECLICKED)
1725 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1728 if (HIWORD(wParam) == BN_CLICKED ||
1729 HIWORD(wParam) == BN_DOUBLECLICKED)
1730 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1733 if (HIWORD(wParam) == BN_CLICKED ||
1734 HIWORD(wParam) == BN_DOUBLECLICKED)
1736 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1739 if (HIWORD(wParam) == BN_CLICKED ||
1740 HIWORD(wParam) == BN_DOUBLECLICKED)
1742 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1744 case IDC_ECHOBACKEND:
1747 if (HIWORD(wParam) == BN_CLICKED ||
1748 HIWORD(wParam) == BN_DOUBLECLICKED) {
1749 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1750 cfg.localecho = LD_BACKEND;
1751 if (LOWORD(wParam) == IDC_ECHOYES)
1752 cfg.localecho = LD_YES;
1753 if (LOWORD(wParam) == IDC_ECHONO)
1754 cfg.localecho = LD_NO;
1757 case IDC_EDITBACKEND:
1760 if (HIWORD(wParam) == BN_CLICKED ||
1761 HIWORD(wParam) == BN_DOUBLECLICKED) {
1762 if (LOWORD(wParam) == IDC_EDITBACKEND)
1763 cfg.localedit = LD_BACKEND;
1764 if (LOWORD(wParam) == IDC_EDITYES)
1765 cfg.localedit = LD_YES;
1766 if (LOWORD(wParam) == IDC_EDITNO)
1767 cfg.localedit = LD_NO;
1770 case IDC_ANSWEREDIT:
1771 if (HIWORD(wParam) == EN_CHANGE)
1772 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1773 sizeof(cfg.answerback) - 1);
1775 case IDC_ALWAYSONTOP:
1776 if (HIWORD(wParam) == BN_CLICKED ||
1777 HIWORD(wParam) == BN_DOUBLECLICKED)
1779 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1782 if (HIWORD(wParam) == BN_CLICKED ||
1783 HIWORD(wParam) == BN_DOUBLECLICKED)
1785 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1787 case IDC_SCROLLDISP:
1788 if (HIWORD(wParam) == BN_CLICKED ||
1789 HIWORD(wParam) == BN_DOUBLECLICKED)
1790 cfg.scroll_on_disp =
1791 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1793 case IDC_COMPOSEKEY:
1794 if (HIWORD(wParam) == BN_CLICKED ||
1795 HIWORD(wParam) == BN_DOUBLECLICKED)
1797 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1799 case IDC_CTRLALTKEYS:
1800 if (HIWORD(wParam) == BN_CLICKED ||
1801 HIWORD(wParam) == BN_DOUBLECLICKED)
1803 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1806 if (HIWORD(wParam) == BN_CLICKED ||
1807 HIWORD(wParam) == BN_DOUBLECLICKED)
1808 cfg.telnet_keyboard =
1809 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1812 if (HIWORD(wParam) == BN_CLICKED ||
1813 HIWORD(wParam) == BN_DOUBLECLICKED)
1815 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1818 if (HIWORD(wParam) == BN_CLICKED ||
1819 HIWORD(wParam) == BN_DOUBLECLICKED)
1820 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1823 if (HIWORD(wParam) == BN_CLICKED ||
1824 HIWORD(wParam) == BN_DOUBLECLICKED)
1826 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1829 if (HIWORD(wParam) == EN_CHANGE)
1830 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1833 if (HIWORD(wParam) == EN_CHANGE)
1834 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1837 if (HIWORD(wParam) == EN_CHANGE)
1838 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1840 case IDC_CHOOSEFONT:
1843 lf.lfHeight = -MulDiv(cfg.fontheight,
1844 GetDeviceCaps(hdc, LOGPIXELSY),
1848 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1849 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1850 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1851 lf.lfCharSet = cfg.fontcharset;
1852 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1853 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1854 lf.lfQuality = DEFAULT_QUALITY;
1855 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1856 strncpy(lf.lfFaceName, cfg.font,
1857 sizeof(lf.lfFaceName) - 1);
1858 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1860 cf.lStructSize = sizeof(cf);
1861 cf.hwndOwner = hwnd;
1863 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1864 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1866 if (ChooseFont(&cf)) {
1867 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1868 cfg.font[sizeof(cfg.font) - 1] = '\0';
1869 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1870 cfg.fontcharset = lf.lfCharSet;
1871 cfg.fontheight = cf.iPointSize / 10;
1872 fmtfont(fontstatic);
1873 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1876 case IDC_BELL_DISABLED:
1877 case IDC_BELL_DEFAULT:
1878 case IDC_BELL_WAVEFILE:
1879 case IDC_BELL_VISUAL:
1880 if (HIWORD(wParam) == BN_CLICKED ||
1881 HIWORD(wParam) == BN_DOUBLECLICKED) {
1882 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1883 cfg.beep = BELL_DISABLED;
1884 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1885 cfg.beep = BELL_DEFAULT;
1886 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1887 cfg.beep = BELL_WAVEFILE;
1888 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1889 cfg.beep = BELL_VISUAL;
1892 case IDC_B_IND_DISABLED:
1893 case IDC_B_IND_FLASH:
1894 case IDC_B_IND_STEADY:
1895 if (HIWORD(wParam) == BN_CLICKED ||
1896 HIWORD(wParam) == BN_DOUBLECLICKED) {
1897 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
1898 cfg.beep_ind = B_IND_DISABLED;
1899 if (LOWORD(wParam) == IDC_B_IND_FLASH)
1900 cfg.beep_ind = B_IND_FLASH;
1901 if (LOWORD(wParam) == IDC_B_IND_STEADY)
1902 cfg.beep_ind = B_IND_STEADY;
1905 case IDC_BELL_WAVEBROWSE:
1906 memset(&of, 0, sizeof(of));
1907 #ifdef OPENFILENAME_SIZE_VERSION_400
1908 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1910 of.lStructSize = sizeof(of);
1912 of.hwndOwner = hwnd;
1913 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1914 of.lpstrCustomFilter = NULL;
1915 of.nFilterIndex = 1;
1916 of.lpstrFile = filename;
1917 strcpy(filename, cfg.bell_wavefile);
1918 of.nMaxFile = sizeof(filename);
1919 of.lpstrFileTitle = NULL;
1920 of.lpstrInitialDir = NULL;
1921 of.lpstrTitle = "Select Bell Sound File";
1923 if (GetOpenFileName(&of)) {
1924 strcpy(cfg.bell_wavefile, filename);
1925 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1929 case IDC_BELL_WAVEEDIT:
1930 if (HIWORD(wParam) == EN_CHANGE)
1931 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1933 sizeof(cfg.bell_wavefile) - 1);
1936 if (HIWORD(wParam) == BN_CLICKED ||
1937 HIWORD(wParam) == BN_DOUBLECLICKED)
1939 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1942 if (HIWORD(wParam) == EN_CHANGE)
1943 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
1946 if (HIWORD(wParam) == EN_CHANGE)
1947 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
1951 if (HIWORD(wParam) == EN_CHANGE)
1952 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
1956 if (HIWORD(wParam) == BN_CLICKED ||
1957 HIWORD(wParam) == BN_DOUBLECLICKED)
1959 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
1962 if (HIWORD(wParam) == BN_CLICKED ||
1963 HIWORD(wParam) == BN_DOUBLECLICKED)
1964 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
1967 if (HIWORD(wParam) == BN_CLICKED ||
1968 HIWORD(wParam) == BN_DOUBLECLICKED)
1969 cfg.win_name_always =
1970 IsDlgButtonChecked(hwnd, IDC_WINNAME);
1973 if (HIWORD(wParam) == BN_CLICKED ||
1974 HIWORD(wParam) == BN_DOUBLECLICKED)
1976 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
1978 case IDC_SUNKENEDGE:
1979 if (HIWORD(wParam) == BN_CLICKED ||
1980 HIWORD(wParam) == BN_DOUBLECLICKED)
1982 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
1985 if (HIWORD(wParam) == BN_CLICKED ||
1986 HIWORD(wParam) == BN_DOUBLECLICKED)
1987 cfg.cursor_type = 0;
1990 if (HIWORD(wParam) == BN_CLICKED ||
1991 HIWORD(wParam) == BN_DOUBLECLICKED)
1992 cfg.cursor_type = 1;
1995 if (HIWORD(wParam) == BN_CLICKED ||
1996 HIWORD(wParam) == BN_DOUBLECLICKED)
1997 cfg.cursor_type = 2;
2000 if (HIWORD(wParam) == BN_CLICKED ||
2001 HIWORD(wParam) == BN_DOUBLECLICKED)
2003 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2006 if (HIWORD(wParam) == BN_CLICKED ||
2007 HIWORD(wParam) == BN_DOUBLECLICKED)
2009 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2012 if (HIWORD(wParam) == BN_CLICKED ||
2013 HIWORD(wParam) == BN_DOUBLECLICKED)
2015 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
2018 if (HIWORD(wParam) == EN_CHANGE)
2019 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2020 sizeof(cfg.wintitle) - 1);
2025 if (HIWORD(wParam) == BN_CLICKED ||
2026 HIWORD(wParam) == BN_DOUBLECLICKED) {
2028 IsDlgButtonChecked(hwnd,
2029 IDC_COEALWAYS) ? COE_ALWAYS :
2030 IsDlgButtonChecked(hwnd,
2031 IDC_COENEVER) ? COE_NEVER :
2036 if (HIWORD(wParam) == BN_CLICKED ||
2037 HIWORD(wParam) == BN_DOUBLECLICKED)
2039 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
2042 if (HIWORD(wParam) == EN_CHANGE)
2043 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
2044 sizeof(cfg.termtype) - 1);
2047 if (HIWORD(wParam) == EN_CHANGE)
2048 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
2049 sizeof(cfg.logfilename) - 1);
2052 memset(&of, 0, sizeof(of));
2053 #ifdef OPENFILENAME_SIZE_VERSION_400
2054 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2056 of.lStructSize = sizeof(of);
2058 of.hwndOwner = hwnd;
2059 of.lpstrFilter = "All Files\0*\0\0\0";
2060 of.lpstrCustomFilter = NULL;
2061 of.nFilterIndex = 1;
2062 of.lpstrFile = filename;
2063 strcpy(filename, cfg.logfilename);
2064 of.nMaxFile = sizeof(filename);
2065 of.lpstrFileTitle = NULL;
2066 of.lpstrInitialDir = NULL;
2067 of.lpstrTitle = "Select session log file";
2069 if (GetSaveFileName(&of)) {
2070 strcpy(cfg.logfilename, filename);
2071 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2075 case IDC_LSTATASCII:
2077 if (HIWORD(wParam) == BN_CLICKED ||
2078 HIWORD(wParam) == BN_DOUBLECLICKED) {
2079 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2081 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2083 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2090 if (HIWORD(wParam) == BN_CLICKED ||
2091 HIWORD(wParam) == BN_DOUBLECLICKED) {
2092 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2093 cfg.logxfovr = LGXF_ASK;
2094 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2095 cfg.logxfovr = LGXF_APN;
2096 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2097 cfg.logxfovr = LGXF_OVR;
2102 if (HIWORD(wParam) == EN_CHANGE)
2103 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2104 sizeof(cfg.termspeed) - 1);
2107 if (HIWORD(wParam) == EN_CHANGE)
2108 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2109 sizeof(cfg.username) - 1);
2111 case IDC_RLLUSEREDIT:
2112 if (HIWORD(wParam) == EN_CHANGE)
2113 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2115 sizeof(cfg.localusername) - 1);
2119 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2123 cfg.passive_telnet =
2124 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2127 if (HIWORD(wParam) == BN_CLICKED ||
2128 HIWORD(wParam) == BN_DOUBLECLICKED) {
2129 char str[sizeof(cfg.environmt)];
2131 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2137 p = str + strlen(str);
2139 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2140 sizeof(str) - 1 - (p - str));
2151 if ((p - cfg.environmt) + strlen(str) + 2 <
2152 sizeof(cfg.environmt)) {
2154 p[strlen(str) + 1] = '\0';
2155 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2157 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2158 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2160 MessageBox(hwnd, "Environment too big",
2161 "PuTTY Error", MB_OK | MB_ICONERROR);
2166 if (HIWORD(wParam) != BN_CLICKED &&
2167 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2169 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2176 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2203 if (HIWORD(wParam) == BN_CLICKED ||
2204 HIWORD(wParam) == BN_DOUBLECLICKED)
2205 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2208 if (HIWORD(wParam) == BN_CLICKED ||
2209 HIWORD(wParam) == BN_DOUBLECLICKED)
2211 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2214 if (HIWORD(wParam) == BN_CLICKED ||
2215 HIWORD(wParam) == BN_DOUBLECLICKED)
2217 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2220 if (HIWORD(wParam) == BN_CLICKED ||
2221 HIWORD(wParam) == BN_DOUBLECLICKED)
2223 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2225 case IDC_CIPHER3DES:
2226 case IDC_CIPHERBLOWF:
2229 if (HIWORD(wParam) == BN_CLICKED ||
2230 HIWORD(wParam) == BN_DOUBLECLICKED) {
2231 if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES))
2232 cfg.cipher = CIPHER_3DES;
2233 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF))
2234 cfg.cipher = CIPHER_BLOWFISH;
2235 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES))
2236 cfg.cipher = CIPHER_DES;
2237 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES))
2238 cfg.cipher = CIPHER_AES;
2243 if (HIWORD(wParam) == BN_CLICKED ||
2244 HIWORD(wParam) == BN_DOUBLECLICKED) {
2245 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2247 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2252 if (HIWORD(wParam) == BN_CLICKED ||
2253 HIWORD(wParam) == BN_DOUBLECLICKED)
2255 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2258 if (HIWORD(wParam) == EN_CHANGE)
2259 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2260 sizeof(cfg.keyfile) - 1);
2263 if (HIWORD(wParam) == EN_CHANGE)
2264 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2265 sizeof(cfg.remote_cmd) - 1);
2268 memset(&of, 0, sizeof(of));
2269 #ifdef OPENFILENAME_SIZE_VERSION_400
2270 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2272 of.lStructSize = sizeof(of);
2274 of.hwndOwner = hwnd;
2275 of.lpstrFilter = "All Files\0*\0\0\0";
2276 of.lpstrCustomFilter = NULL;
2277 of.nFilterIndex = 1;
2278 of.lpstrFile = filename;
2279 strcpy(filename, cfg.keyfile);
2280 of.nMaxFile = sizeof(filename);
2281 of.lpstrFileTitle = NULL;
2282 of.lpstrInitialDir = NULL;
2283 of.lpstrTitle = "Select Public Key File";
2285 if (GetOpenFileName(&of)) {
2286 strcpy(cfg.keyfile, filename);
2287 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2291 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2294 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2300 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2305 for (i = 0; i < 128; i++)
2306 if (SendDlgItemMessage
2307 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2309 cfg.wordness[i] = n;
2310 SendDlgItemMessage(hwnd, IDC_CCLIST,
2311 LB_DELETESTRING, i, 0);
2312 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2313 (i >= 0x21 && i != 0x7F) ? i : ' ',
2315 SendDlgItemMessage(hwnd, IDC_CCLIST,
2322 case IDC_BOLDCOLOUR:
2323 if (HIWORD(wParam) == BN_CLICKED ||
2324 HIWORD(wParam) == BN_DOUBLECLICKED) {
2327 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2328 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2331 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2333 if (n != 12 + 10 * cfg.bold_colour) {
2334 for (i = n; i-- > 0;)
2335 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2336 LB_DELETESTRING, i, 0);
2337 for (i = 0; i < 22; i++)
2338 if (cfg.bold_colour || permcolour[i])
2339 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2341 (LPARAM) colours[i]);
2343 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2345 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2350 if (HIWORD(wParam) == BN_CLICKED ||
2351 HIWORD(wParam) == BN_DOUBLECLICKED)
2353 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2355 case IDC_COLOURLIST:
2356 if (HIWORD(wParam) == LBN_DBLCLK ||
2357 HIWORD(wParam) == LBN_SELCHANGE) {
2359 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2362 if (!cfg.bold_colour)
2363 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2364 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2366 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2368 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2373 if (HIWORD(wParam) == BN_CLICKED ||
2374 HIWORD(wParam) == BN_DOUBLECLICKED) {
2375 static CHOOSECOLOR cc;
2376 static DWORD custom[16] = { 0 }; /* zero initialisers */
2378 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2381 if (!cfg.bold_colour)
2382 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2383 cc.lStructSize = sizeof(cc);
2384 cc.hwndOwner = hwnd;
2385 cc.hInstance = (HWND) hinst;
2386 cc.lpCustColors = custom;
2388 RGB(cfg.colours[i][0], cfg.colours[i][1],
2390 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2391 if (ChooseColor(&cc)) {
2393 (unsigned char) (cc.rgbResult & 0xFF);
2395 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2397 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2398 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2400 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2402 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2408 if (HIWORD(wParam) == CBN_SELCHANGE) {
2409 int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
2410 CB_GETCURSEL, 0, 0);
2411 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
2412 index, (LPARAM)cfg.line_codepage);
2415 case IDC_VTXWINDOWS:
2421 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2422 : IsDlgButtonChecked(hwnd,
2423 IDC_VTOEMANSI) ? VT_OEMANSI :
2424 IsDlgButtonChecked(hwnd,
2425 IDC_VTOEMONLY) ? VT_OEMONLY :
2426 IsDlgButtonChecked(hwnd,
2427 IDC_VTUNICODE) ? VT_UNICODE :
2430 case IDC_X11_FORWARD:
2431 if (HIWORD(wParam) == BN_CLICKED ||
2432 HIWORD(wParam) == BN_DOUBLECLICKED)
2434 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2437 if (HIWORD(wParam) == BN_CLICKED ||
2438 HIWORD(wParam) == BN_DOUBLECLICKED)
2439 cfg.lport_acceptall =
2440 IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
2442 case IDC_X11_DISPLAY:
2443 if (HIWORD(wParam) == EN_CHANGE)
2444 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2445 sizeof(cfg.x11_display) - 1);
2448 if (HIWORD(wParam) == BN_CLICKED ||
2449 HIWORD(wParam) == BN_DOUBLECLICKED) {
2450 char str[sizeof(cfg.portfwd)];
2452 if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
2456 GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
2460 "You need to specify a source port number",
2461 "PuTTY Error", MB_OK | MB_ICONERROR);
2464 p = str + strlen(str);
2466 GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
2467 sizeof(str) - 1 - (p - str));
2468 if (!*p || !strchr(p, ':')) {
2470 "You need to specify a destination address\n"
2471 "in the form \"host.name:port\"",
2472 "PuTTY Error", MB_OK | MB_ICONERROR);
2481 if ((p - cfg.portfwd) + strlen(str) + 2 <
2482 sizeof(cfg.portfwd)) {
2484 p[strlen(str) + 1] = '\0';
2485 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
2487 SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
2488 SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
2490 MessageBox(hwnd, "Too many forwardings",
2491 "PuTTY Error", MB_OK | MB_ICONERROR);
2495 case IDC_PFWDREMOVE:
2496 if (HIWORD(wParam) != BN_CLICKED &&
2497 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2498 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
2499 LB_GETCURSEL, 0, 0);
2505 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
2537 /* Grrr Explorer will maximize Dialogs! */
2539 if (wParam == SIZE_MAXIMIZED)
2546 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2547 WPARAM wParam, LPARAM lParam)
2549 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2551 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2552 EnableWindow(hwnd, 0);
2553 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2554 EnableWindow(hwnd, 1);
2555 SetActiveWindow(hwnd);
2557 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2560 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2561 WPARAM wParam, LPARAM lParam)
2563 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2566 void defuse_showwindow(void)
2569 * Work around the fact that the app's first call to ShowWindow
2570 * will ignore the default in favour of the shell-provided
2575 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2577 ShowWindow(hwnd, SW_HIDE);
2578 SetActiveWindow(hwnd);
2579 DestroyWindow(hwnd);
2588 savedsession[0] = '\0';
2590 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2591 get_sesslist(FALSE);
2596 int do_reconfig(HWND hwnd)
2601 backup_cfg = cfg; /* structure copy */
2603 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2605 cfg = backup_cfg; /* structure copy */
2610 void logevent(char *string)
2615 if (nevents >= negsize) {
2617 events = srealloc(events, negsize * sizeof(*events));
2621 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2624 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2625 strcpy(events[nevents], timebuf);
2626 strcat(events[nevents], string);
2629 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2630 0, (LPARAM) events[nevents]);
2631 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2632 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2637 void showeventlog(HWND hwnd)
2640 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2642 ShowWindow(logbox, SW_SHOWNORMAL);
2644 SetActiveWindow(logbox);
2647 void showabout(HWND hwnd)
2649 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2652 void verify_ssh_host_key(char *host, int port, char *keytype,
2653 char *keystr, char *fingerprint)
2657 static const char absentmsg[] =
2658 "The server's host key is not cached in the registry. You\n"
2659 "have no guarantee that the server is the computer you\n"
2661 "The server's key fingerprint is:\n"
2663 "If you trust this host, hit Yes to add the key to\n"
2664 "PuTTY's cache and carry on connecting.\n"
2665 "If you want to carry on connecting just once, without\n"
2666 "adding the key to the cache, hit No.\n"
2667 "If you do not trust this host, hit Cancel to abandon the\n"
2670 static const char wrongmsg[] =
2671 "WARNING - POTENTIAL SECURITY BREACH!\n"
2673 "The server's host key does not match the one PuTTY has\n"
2674 "cached in the registry. This means that either the\n"
2675 "server administrator has changed the host key, or you\n"
2676 "have actually connected to another computer pretending\n"
2677 "to be the server.\n"
2678 "The new key fingerprint is:\n"
2680 "If you were expecting this change and trust the new key,\n"
2681 "hit Yes to update PuTTY's cache and continue connecting.\n"
2682 "If you want to carry on connecting but without updating\n"
2683 "the cache, hit No.\n"
2684 "If you want to abandon the connection completely, hit\n"
2685 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2687 static const char mbtitle[] = "PuTTY Security Alert";
2690 /* sensible fingerprint max size */
2691 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2692 sizeof(absentmsg) : sizeof(wrongmsg))];
2695 * Verify the key against the registry.
2697 ret = verify_host_key(host, port, keytype, keystr);
2699 if (ret == 0) /* success - key matched OK */
2701 if (ret == 2) { /* key was different */
2703 sprintf(message, wrongmsg, fingerprint);
2704 mbret = MessageBox(NULL, message, mbtitle,
2705 MB_ICONWARNING | MB_YESNOCANCEL);
2707 store_host_key(host, port, keytype, keystr);
2708 if (mbret == IDCANCEL)
2711 if (ret == 1) { /* key was absent */
2713 sprintf(message, absentmsg, fingerprint);
2714 mbret = MessageBox(NULL, message, mbtitle,
2715 MB_ICONWARNING | MB_YESNOCANCEL);
2717 store_host_key(host, port, keytype, keystr);
2718 if (mbret == IDCANCEL)
2724 * Ask whether to wipe a session log file before writing to it.
2725 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2727 int askappend(char *filename)
2729 static const char mbtitle[] = "PuTTY Log to File";
2730 static const char msgtemplate[] =
2731 "The session log file \"%.*s\" already exists.\n"
2732 "You can overwrite it with a new session log,\n"
2733 "append your session log to the end of it,\n"
2734 "or disable session logging for this session.\n"
2735 "Hit Yes to wipe the file, No to append to it,\n"
2736 "or Cancel to disable logging.";
2737 char message[sizeof(msgtemplate) + FILENAME_MAX];
2739 if (cfg.logxfovr != LGXF_ASK) {
2740 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2742 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2744 mbret = MessageBox(NULL, message, mbtitle,
2745 MB_ICONQUESTION | MB_YESNOCANCEL);
2748 else if (mbret == IDNO)