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,
515 static const char *const colours[] = {
516 "Default Foreground", "Default Bold Foreground",
517 "Default Background", "Default Bold Background",
518 "Cursor Text", "Cursor Colour",
519 "ANSI Black", "ANSI Black Bold",
520 "ANSI Red", "ANSI Red Bold",
521 "ANSI Green", "ANSI Green Bold",
522 "ANSI Yellow", "ANSI Yellow Bold",
523 "ANSI Blue", "ANSI Blue Bold",
524 "ANSI Magenta", "ANSI Magenta Bold",
525 "ANSI Cyan", "ANSI Cyan Bold",
526 "ANSI White", "ANSI White Bold"
528 static const int permcolour[] = {
529 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
530 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
531 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
534 static void fmtfont(char *buf)
536 sprintf(buf, "Font: %s, ", cfg.font);
538 strcat(buf, "bold, ");
539 if (cfg.fontheight == 0)
540 strcat(buf, "default height");
542 sprintf(buf + strlen(buf), "%d-point",
543 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
546 /* 2nd arg: NZ => don't redraw session list (use when loading
548 static void init_dlg_ctrls(HWND hwnd, int keepsess)
551 char fontstatic[256];
553 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
554 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
557 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
558 for (i = n; i-- > 0;)
559 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
560 for (i = 0; i < nsessions; i++)
561 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
562 0, (LPARAM) (sessions[i]));
564 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
565 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
566 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
567 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
569 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
570 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
572 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
573 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
574 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
575 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
576 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
577 cfg.funky_type == 0 ? IDC_FUNCTILDE :
578 cfg.funky_type == 1 ? IDC_FUNCLINUX :
579 cfg.funky_type == 2 ? IDC_FUNCXTERM :
580 cfg.funky_type == 3 ? IDC_FUNCVT400 :
581 cfg.funky_type == 4 ? IDC_FUNCVT100P :
582 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
583 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
584 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
585 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
586 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
587 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
588 cfg.nethack_keypad ? IDC_KPNH :
589 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
590 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
591 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
592 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
593 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
594 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
595 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
596 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
597 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
598 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
599 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
600 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
601 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
602 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
603 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
604 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
605 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
607 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
608 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
609 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
610 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
611 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
612 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
614 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
615 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
616 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
617 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
618 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
620 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
621 CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
623 B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
624 B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
625 B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
626 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
627 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
628 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
629 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
630 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
632 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
633 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
635 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
636 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
637 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
638 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
639 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
640 cfg.cursor_type == 0 ? IDC_CURBLOCK :
641 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
642 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
643 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
644 CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize);
645 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
646 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
648 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
649 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
651 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
652 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
653 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
654 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
655 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
656 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
657 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
658 cfg.logtype == 0 ? IDC_LSTATOFF :
659 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
660 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
661 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
662 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
665 char *p = cfg.environmt;
666 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
668 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
673 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
674 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
675 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
676 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
678 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
679 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
680 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
681 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
682 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
683 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
684 CheckRadioButton(hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
685 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
686 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
687 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
689 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
690 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
691 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
692 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
693 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
695 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
696 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
697 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
699 static int tabs[4] = { 25, 61, 96, 128 };
700 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
703 for (i = 0; i < 128; i++) {
705 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
706 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
707 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
711 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
712 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
715 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
716 for (i = n; i-- > 0;)
717 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
718 LB_DELETESTRING, i, 0);
719 for (i = 0; i < 22; i++)
720 if (cfg.bold_colour || permcolour[i])
721 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
722 (LPARAM) colours[i]);
724 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
725 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
726 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
727 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
729 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
730 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
731 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
732 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
733 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
734 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
737 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
738 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
741 struct treeview_faff {
746 static HTREEITEM treeview_insert(struct treeview_faff *faff,
747 int level, char *text)
752 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
753 ins.hInsertAfter = faff->lastat[level];
754 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
755 #define INSITEM DUMMYUNIONNAME.item
759 ins.INSITEM.mask = TVIF_TEXT;
760 ins.INSITEM.pszText = text;
761 newitem = TreeView_InsertItem(faff->treeview, &ins);
763 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
765 faff->lastat[level] = newitem;
766 for (i = level + 1; i < 4; i++)
767 faff->lastat[i] = NULL;
772 * Create the panelfuls of controls in the configuration box.
774 static void create_controls(HWND hwnd, int dlgtype, int panel)
776 if (panel == sessionpanelstart) {
777 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
779 ctlposinit(&cp, hwnd, 80, 3, 13);
780 bartitle(&cp, "Basic options for your PuTTY session",
783 beginbox(&cp, "Specify your connection by host name",
786 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
787 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
788 if (backends[3].backend == NULL) {
789 /* this is PuTTYtel, so only three protocols available */
790 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
792 "&Telnet", IDC_PROTTELNET,
793 "Rlog&in", IDC_PROTRLOGIN, NULL);
795 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
797 "&Telnet", IDC_PROTTELNET,
798 "Rlog&in", IDC_PROTRLOGIN,
807 beginbox(&cp, "Load, save or delete a stored session",
809 sesssaver(&cp, "Sav&ed Sessions",
810 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
811 "&Load", IDC_SESSLOAD,
812 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
815 beginbox(&cp, NULL, IDC_BOX_SESSION3);
816 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
817 "Always", IDC_COEALWAYS,
818 "Never", IDC_COENEVER,
819 "Only on clean exit", IDC_COENORMAL, NULL);
823 if (panel == loggingpanelstart) {
824 /* The Logging panel. Accelerators used: [acgo] tplfwe */
826 ctlposinit(&cp, hwnd, 80, 3, 13);
827 bartitle(&cp, "Options controlling session logging",
829 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
831 "Session logging:", IDC_LSTATSTATIC,
832 "Logging &turned off completely", IDC_LSTATOFF,
833 "Log &printable output only", IDC_LSTATASCII,
834 "&Log all session output", IDC_LSTATRAW, NULL);
835 editbutton(&cp, "Log &file name:",
836 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
839 "What to do if the log file already &exists:",
840 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
841 "Always append to the end of it", IDC_LSTATXAPN,
842 "Ask the user every time", IDC_LSTATXASK, NULL);
846 if (panel == terminalpanelstart) {
847 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
849 ctlposinit(&cp, hwnd, 80, 3, 13);
850 bartitle(&cp, "Options controlling the terminal emulation",
852 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
853 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
854 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
855 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
856 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
857 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
859 "An&swerback to ^E:", IDC_ANSWERBACK,
860 IDC_ANSWEREDIT, 100, NULL);
863 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
864 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
865 "Auto", IDC_ECHOBACKEND,
866 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
867 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
868 "Auto", IDC_EDITBACKEND,
869 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
873 if (panel == bellpanelstart) {
874 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
876 ctlposinit(&cp, hwnd, 80, 3, 13);
877 bartitle(&cp, "Options controlling the terminal bell",
879 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
881 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
882 "None (bell disabled)", IDC_BELL_DISABLED,
883 "Play Windows Default Sound", IDC_BELL_DEFAULT,
884 "Play a custom sound file", IDC_BELL_WAVEFILE,
885 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
886 editbutton(&cp, "Custom sound file to play as a bell:",
887 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
888 "Bro&wse...", IDC_BELL_WAVEBROWSE);
889 radioline(&cp, "Taskbar/caption &indication on bell:",
890 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
891 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
894 beginbox(&cp, "Control the bell overload behaviour",
896 checkbox(&cp, "Bell is temporarily &disabled when over-used",
898 staticedit(&cp, "Over-use means this &many bells...",
899 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
900 staticedit(&cp, "... in &this many seconds",
901 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
903 "The bell is re-enabled after a few seconds of silence.",
905 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
910 if (panel == keyboardpanelstart) {
911 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
913 ctlposinit(&cp, hwnd, 80, 3, 13);
915 bartitle(&cp, "Options controlling the effects of keys",
918 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
919 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
920 "Control-H", IDC_DEL008,
921 "Control-? (127)", IDC_DEL127, NULL);
922 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
923 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
924 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
925 "ESC[n~", IDC_FUNCTILDE,
926 "Linux", IDC_FUNCLINUX,
927 "Xterm R6", IDC_FUNCXTERM,
928 "VT400", IDC_FUNCVT400,
929 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
931 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
933 "Application c&ursor keys totally disabled",
935 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
936 "Normal", IDC_CURNORMAL,
937 "Application", IDC_CURAPPLIC, NULL);
939 "Application ke&ypad keys totally disabled",
941 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
942 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
943 "NetHack", IDC_KPNH, NULL);
945 beginbox(&cp, "Enable extra keyboard features:",
947 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
948 checkbox(&cp, "Control-Alt is &different from AltGr",
953 if (panel == windowpanelstart) {
954 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
956 ctlposinit(&cp, hwnd, 80, 3, 13);
957 bartitle(&cp, "Options controlling PuTTY's window",
959 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
961 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
962 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
963 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
965 beginbox(&cp, "Control the scrollback in the window",
967 staticedit(&cp, "Lines of &scrollback",
968 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
969 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
970 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
971 checkbox(&cp, "Reset scrollback on dis&play activity",
974 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
975 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
976 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
977 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
978 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
979 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
983 if (panel == appearancepanelstart) {
984 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
986 ctlposinit(&cp, hwnd, 80, 3, 13);
987 bartitle(&cp, "Options controlling PuTTY's appearance",
988 IDC_TITLE_APPEARANCE);
989 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
990 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
991 "B&lock", IDC_CURBLOCK,
992 "&Underline", IDC_CURUNDER,
993 "&Vertical line", IDC_CURVERT, NULL);
994 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
996 beginbox(&cp, "Set the font used in the terminal window",
997 IDC_BOX_APPEARANCE2);
998 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
1000 beginbox(&cp, "Adjust the use of the window title",
1001 IDC_BOX_APPEARANCE3);
1003 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1004 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1006 beginbox(&cp, "Adjust the use of the mouse pointer",
1007 IDC_BOX_APPEARANCE4);
1008 checkbox(&cp, "Hide mouse &pointer when typing in window",
1011 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1012 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1017 if (panel == translationpanelstart) {
1018 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1020 ctlposinit(&cp, hwnd, 80, 3, 13);
1021 bartitle(&cp, "Options controlling character set translation",
1022 IDC_TITLE_TRANSLATION);
1023 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1024 IDC_BOX_TRANSLATION1);
1026 "Handling of line drawing characters:", IDC_VTSTATIC,
1027 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1028 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1029 "Use font in O&EM mode only", IDC_VTOEMONLY,
1030 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1031 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1033 beginbox(&cp, "Enable character set translation on received data",
1034 IDC_BOX_TRANSLATION2);
1035 multiedit(&cp, "Line codepage:", IDC_CODEPAGESTATIC,
1036 IDC_CODEPAGE, 100, NULL);
1040 if (panel == selectionpanelstart) {
1041 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1043 ctlposinit(&cp, hwnd, 80, 3, 13);
1044 bartitle(&cp, "Options controlling copy and paste",
1045 IDC_TITLE_SELECTION);
1046 beginbox(&cp, "Translation of pasted characters",
1047 IDC_BOX_SELECTION1);
1049 "&Don't translate line drawing chars into +, - and |",
1052 beginbox(&cp, "Control which mouse button does which thing",
1053 IDC_BOX_SELECTION2);
1054 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1055 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1056 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1059 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1060 IDC_BOX_SELECTION3);
1061 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1062 "&Set", IDC_CCSET, IDC_CCEDIT,
1063 "&to class", IDC_CCSTATIC2);
1067 if (panel == colourspanelstart) {
1068 /* The Colours panel. Accelerators used: [acgo] blum */
1070 ctlposinit(&cp, hwnd, 80, 3, 13);
1071 bartitle(&cp, "Options controlling use of colours",
1073 beginbox(&cp, "General options for colour usage",
1075 checkbox(&cp, "&Bolded text is a different colour",
1077 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1079 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1081 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1082 IDC_COLOURSTATIC, IDC_COLOURLIST,
1083 "&Modify...", IDC_CHANGE,
1084 "Red:", IDC_RSTATIC, IDC_RVALUE,
1085 "Green:", IDC_GSTATIC, IDC_GVALUE,
1086 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1090 if (panel == connectionpanelstart) {
1091 /* The Connection panel. Accelerators used: [acgo] tuk */
1093 ctlposinit(&cp, hwnd, 80, 3, 13);
1094 bartitle(&cp, "Options controlling the connection",
1095 IDC_TITLE_CONNECTION);
1097 beginbox(&cp, "Data to send to the server",
1098 IDC_BOX_CONNECTION1);
1099 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1101 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1105 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1106 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1110 beginbox(&cp, "Sending of null packets to keep session active",
1111 IDC_BOX_CONNECTION2);
1112 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1113 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1117 if (panel == telnetpanelstart) {
1118 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1120 ctlposinit(&cp, hwnd, 80, 3, 13);
1122 bartitle(&cp, "Options controlling Telnet connections",
1124 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1125 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1127 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1128 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1129 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1130 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1132 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1133 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1134 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1135 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1136 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1137 "Passive", IDC_TPASSIVE, "Active",
1139 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1145 if (panel == rloginpanelstart) {
1146 /* The Rlogin panel. Accelerators used: [acgo] sl */
1148 ctlposinit(&cp, hwnd, 80, 3, 13);
1150 bartitle(&cp, "Options controlling Rlogin connections",
1152 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1153 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1155 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1156 IDC_RLLUSEREDIT, 50);
1161 if (panel == sshpanelstart) {
1162 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1164 ctlposinit(&cp, hwnd, 80, 3, 13);
1166 bartitle(&cp, "Options controlling SSH connections",
1168 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1170 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1173 beginbox(&cp, "Authentication options", IDC_BOX_SSH2);
1174 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1176 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1177 editbutton(&cp, "Private &key file for authentication:",
1178 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1181 beginbox(&cp, "Protocol options", IDC_BOX_SSH3);
1182 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1183 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1184 radioline(&cp, "Preferred SSH protocol version:",
1185 IDC_SSHPROTSTATIC, 2,
1186 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1187 radioline(&cp, "Preferred encryption algorithm:",
1188 IDC_CIPHERSTATIC, 4, "&3DES", IDC_CIPHER3DES,
1189 "&Blowfish", IDC_CIPHERBLOWF, "&DES", IDC_CIPHERDES,
1190 "AE&S", IDC_CIPHERAES, NULL);
1191 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1197 if (panel == tunnelspanelstart) {
1198 /* The Tunnels panel. Accelerators used: [acgo] ex */
1200 ctlposinit(&cp, hwnd, 80, 3, 13);
1202 bartitle(&cp, "Options controlling SSH tunnelling",
1204 beginbox(&cp, "X11 forwarding options", IDC_BOX_TUNNELS);
1205 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1206 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1207 IDC_X11_DISPLAY, 50, NULL);
1214 * Helper function to load the session selected in SESSLIST
1215 * if any, as this is done in more than one place in
1216 * GenericMainDlgProc(). 0 => failure.
1218 static int load_selected_session(HWND hwnd)
1220 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1221 LB_GETCURSEL, 0, 0);
1227 isdef = !strcmp(sessions[n], "Default Settings");
1228 load_settings(sessions[n], !isdef, &cfg);
1229 init_dlg_ctrls(hwnd, TRUE);
1231 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1233 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1234 /* Restore the selection, which will have been clobbered by
1235 * SESSEDIT handling. */
1236 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1241 * This function is the configuration box.
1243 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1244 WPARAM wParam, LPARAM lParam, int dlgtype)
1247 struct treeview_faff tvfaff;
1250 char filename[sizeof(cfg.keyfile)];
1253 char fontstatic[256];
1255 struct servent *service;
1261 SetWindowLong(hwnd, GWL_USERDATA, 0);
1262 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1263 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1265 * Centre the window.
1267 { /* centre the window */
1270 hw = GetDesktopWindow();
1271 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1273 (rs.right + rs.left + rd.left - rd.right) / 2,
1274 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1275 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1279 * Create the tree view.
1287 r.right = r.left + 75;
1289 r.bottom = r.top + 10;
1290 MapDialogRect(hwnd, &r);
1291 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1292 WS_CHILD | WS_VISIBLE,
1294 r.right - r.left, r.bottom - r.top,
1295 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1297 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1298 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1301 r.right = r.left + 75;
1303 r.bottom = r.top + 206;
1304 MapDialogRect(hwnd, &r);
1305 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1306 WS_CHILD | WS_VISIBLE |
1307 WS_TABSTOP | TVS_HASLINES |
1308 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1310 TVS_SHOWSELALWAYS, r.left, r.top,
1311 r.right - r.left, r.bottom - r.top,
1312 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1314 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1315 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1316 tvfaff.treeview = treeview;
1317 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1321 * Set up the tree view contents.
1323 hsession = treeview_insert(&tvfaff, 0, "Session");
1324 treeview_insert(&tvfaff, 1, "Logging");
1325 treeview_insert(&tvfaff, 0, "Terminal");
1326 treeview_insert(&tvfaff, 1, "Keyboard");
1327 treeview_insert(&tvfaff, 1, "Bell");
1328 treeview_insert(&tvfaff, 0, "Window");
1329 treeview_insert(&tvfaff, 1, "Appearance");
1330 treeview_insert(&tvfaff, 1, "Translation");
1331 treeview_insert(&tvfaff, 1, "Selection");
1332 treeview_insert(&tvfaff, 1, "Colours");
1333 treeview_insert(&tvfaff, 0, "Connection");
1335 treeview_insert(&tvfaff, 1, "Telnet");
1336 treeview_insert(&tvfaff, 1, "Rlogin");
1337 if (backends[3].backend != NULL) {
1338 treeview_insert(&tvfaff, 1, "SSH");
1339 treeview_insert(&tvfaff, 2, "Tunnels");
1344 * Put the treeview selection on to the Session panel. This
1345 * should also cause creation of the relevant controls.
1347 TreeView_SelectItem(treeview, hsession);
1350 * Set focus into the first available control.
1354 ctl = GetDlgItem(hwnd, IDC_HOST);
1356 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1360 SetWindowLong(hwnd, GWL_USERDATA, 1);
1361 sesslist_has_focus = 0;
1365 * Button release should trigger WM_OK if there was a
1366 * previous double click on the session list.
1370 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1373 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1374 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1376 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1381 item.pszText = buffer;
1382 item.cchTextMax = sizeof(buffer);
1383 item.mask = TVIF_TEXT;
1384 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1385 for (j = controlstartvalue; j < controlendvalue; j++) {
1386 HWND item = GetDlgItem(hwnd, j);
1388 DestroyWindow(item);
1390 if (!strcmp(buffer, "Session"))
1391 create_controls(hwnd, dlgtype, sessionpanelstart);
1392 if (!strcmp(buffer, "Logging"))
1393 create_controls(hwnd, dlgtype, loggingpanelstart);
1394 if (!strcmp(buffer, "Keyboard"))
1395 create_controls(hwnd, dlgtype, keyboardpanelstart);
1396 if (!strcmp(buffer, "Terminal"))
1397 create_controls(hwnd, dlgtype, terminalpanelstart);
1398 if (!strcmp(buffer, "Bell"))
1399 create_controls(hwnd, dlgtype, bellpanelstart);
1400 if (!strcmp(buffer, "Window"))
1401 create_controls(hwnd, dlgtype, windowpanelstart);
1402 if (!strcmp(buffer, "Appearance"))
1403 create_controls(hwnd, dlgtype, appearancepanelstart);
1404 if (!strcmp(buffer, "Tunnels"))
1405 create_controls(hwnd, dlgtype, tunnelspanelstart);
1406 if (!strcmp(buffer, "Connection"))
1407 create_controls(hwnd, dlgtype, connectionpanelstart);
1408 if (!strcmp(buffer, "Telnet"))
1409 create_controls(hwnd, dlgtype, telnetpanelstart);
1410 if (!strcmp(buffer, "Rlogin"))
1411 create_controls(hwnd, dlgtype, rloginpanelstart);
1412 if (!strcmp(buffer, "SSH"))
1413 create_controls(hwnd, dlgtype, sshpanelstart);
1414 if (!strcmp(buffer, "Selection"))
1415 create_controls(hwnd, dlgtype, selectionpanelstart);
1416 if (!strcmp(buffer, "Colours"))
1417 create_controls(hwnd, dlgtype, colourspanelstart);
1418 if (!strcmp(buffer, "Translation"))
1419 create_controls(hwnd, dlgtype, translationpanelstart);
1421 init_dlg_ctrls(hwnd, FALSE);
1423 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1429 * Only process WM_COMMAND once the dialog is fully formed.
1431 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1432 switch (LOWORD(wParam)) {
1434 /* Behaviour of the "Open" button is different if the
1435 * session list has focus, *unless* the user just
1436 * double-clicked... */
1437 if (sesslist_has_focus && !readytogo) {
1438 if (!load_selected_session(hwnd)) {
1443 /* If at this point we have a valid session, go! */
1452 case IDC_PROTTELNET:
1453 case IDC_PROTRLOGIN:
1456 if (HIWORD(wParam) == BN_CLICKED ||
1457 HIWORD(wParam) == BN_DOUBLECLICKED) {
1458 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1459 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1460 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1462 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1464 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1465 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1466 || (cfg.protocol == PROT_RLOGIN
1467 && cfg.port != 513)) {
1468 cfg.port = i ? 22 : j ? 23 : 513;
1469 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1474 if (HIWORD(wParam) == EN_CHANGE)
1475 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1476 sizeof(cfg.host) - 1);
1479 if (HIWORD(wParam) == EN_CHANGE) {
1480 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1481 if (isdigit(portname[0]))
1482 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1484 service = getservbyname(portname, NULL);
1486 cfg.port = ntohs(service->s_port);
1493 if (HIWORD(wParam) == EN_CHANGE) {
1494 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1496 GetDlgItemText(hwnd, IDC_SESSEDIT,
1497 savedsession, sizeof(savedsession) - 1);
1498 savedsession[sizeof(savedsession) - 1] = '\0';
1502 if (HIWORD(wParam) == BN_CLICKED ||
1503 HIWORD(wParam) == BN_DOUBLECLICKED) {
1508 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1511 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1512 LB_GETCURSEL, 0, 0);
1517 strcpy(str, sessions[n]);
1519 save_settings(str, !!strcmp(str, "Default Settings"),
1521 get_sesslist(FALSE);
1523 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1525 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1527 for (i = 0; i < nsessions; i++)
1528 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1530 (LPARAM) (sessions[i]));
1531 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1533 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1535 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1541 if (LOWORD(wParam) == IDC_SESSLIST) {
1542 if (HIWORD(wParam) == LBN_SETFOCUS)
1543 sesslist_has_focus = 1;
1544 else if (HIWORD(wParam) == LBN_KILLFOCUS)
1545 sesslist_has_focus = 0;
1547 if (LOWORD(wParam) == IDC_SESSLOAD &&
1548 HIWORD(wParam) != BN_CLICKED &&
1549 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1550 if (LOWORD(wParam) == IDC_SESSLIST &&
1551 HIWORD(wParam) != LBN_DBLCLK) break;
1552 /* Load the session selected in SESSLIST. */
1553 if (load_selected_session(hwnd) &&
1554 LOWORD(wParam) == IDC_SESSLIST) {
1556 * A double-click on a saved session should
1557 * actually start the session, not just load it.
1558 * Unless it's Default Settings or some other
1559 * host-less set of saved settings.
1568 if (HIWORD(wParam) == BN_CLICKED ||
1569 HIWORD(wParam) == BN_DOUBLECLICKED) {
1570 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1571 LB_GETCURSEL, 0, 0);
1572 if (n == LB_ERR || n == 0) {
1576 del_settings(sessions[n]);
1577 get_sesslist(FALSE);
1579 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1581 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1583 for (i = 0; i < nsessions; i++)
1584 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1586 (LPARAM) (sessions[i]));
1587 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1589 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1591 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1595 if (HIWORD(wParam) == EN_CHANGE)
1596 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1597 &cfg.ping_interval);
1601 if (HIWORD(wParam) == BN_CLICKED ||
1602 HIWORD(wParam) == BN_DOUBLECLICKED)
1603 cfg.bksp_is_delete =
1604 IsDlgButtonChecked(hwnd, IDC_DEL127);
1608 if (HIWORD(wParam) == BN_CLICKED ||
1609 HIWORD(wParam) == BN_DOUBLECLICKED)
1611 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1617 case IDC_FUNCVT100P:
1619 if (HIWORD(wParam) == BN_CLICKED ||
1620 HIWORD(wParam) == BN_DOUBLECLICKED)
1621 switch (LOWORD(wParam)) {
1634 case IDC_FUNCVT100P:
1644 if (HIWORD(wParam) == BN_CLICKED ||
1645 HIWORD(wParam) == BN_DOUBLECLICKED) {
1647 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1648 cfg.nethack_keypad = FALSE;
1652 if (HIWORD(wParam) == BN_CLICKED ||
1653 HIWORD(wParam) == BN_DOUBLECLICKED) {
1654 cfg.app_keypad = FALSE;
1655 cfg.nethack_keypad = TRUE;
1660 if (HIWORD(wParam) == BN_CLICKED ||
1661 HIWORD(wParam) == BN_DOUBLECLICKED)
1663 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1666 if (HIWORD(wParam) == BN_CLICKED ||
1667 HIWORD(wParam) == BN_DOUBLECLICKED)
1669 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1672 if (HIWORD(wParam) == BN_CLICKED ||
1673 HIWORD(wParam) == BN_DOUBLECLICKED)
1675 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1678 if (HIWORD(wParam) == BN_CLICKED ||
1679 HIWORD(wParam) == BN_DOUBLECLICKED)
1680 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1683 if (HIWORD(wParam) == BN_CLICKED ||
1684 HIWORD(wParam) == BN_DOUBLECLICKED)
1686 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1689 if (HIWORD(wParam) == BN_CLICKED ||
1690 HIWORD(wParam) == BN_DOUBLECLICKED)
1692 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1694 case IDC_ECHOBACKEND:
1697 if (HIWORD(wParam) == BN_CLICKED ||
1698 HIWORD(wParam) == BN_DOUBLECLICKED) {
1699 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1700 cfg.localecho = LD_BACKEND;
1701 if (LOWORD(wParam) == IDC_ECHOYES)
1702 cfg.localecho = LD_YES;
1703 if (LOWORD(wParam) == IDC_ECHONO)
1704 cfg.localecho = LD_NO;
1707 case IDC_EDITBACKEND:
1710 if (HIWORD(wParam) == BN_CLICKED ||
1711 HIWORD(wParam) == BN_DOUBLECLICKED) {
1712 if (LOWORD(wParam) == IDC_EDITBACKEND)
1713 cfg.localedit = LD_BACKEND;
1714 if (LOWORD(wParam) == IDC_EDITYES)
1715 cfg.localedit = LD_YES;
1716 if (LOWORD(wParam) == IDC_EDITNO)
1717 cfg.localedit = LD_NO;
1720 case IDC_ANSWEREDIT:
1721 if (HIWORD(wParam) == EN_CHANGE)
1722 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1723 sizeof(cfg.answerback) - 1);
1725 case IDC_ALWAYSONTOP:
1726 if (HIWORD(wParam) == BN_CLICKED ||
1727 HIWORD(wParam) == BN_DOUBLECLICKED)
1729 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1732 if (HIWORD(wParam) == BN_CLICKED ||
1733 HIWORD(wParam) == BN_DOUBLECLICKED)
1735 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1737 case IDC_SCROLLDISP:
1738 if (HIWORD(wParam) == BN_CLICKED ||
1739 HIWORD(wParam) == BN_DOUBLECLICKED)
1740 cfg.scroll_on_disp =
1741 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1743 case IDC_COMPOSEKEY:
1744 if (HIWORD(wParam) == BN_CLICKED ||
1745 HIWORD(wParam) == BN_DOUBLECLICKED)
1747 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1749 case IDC_CTRLALTKEYS:
1750 if (HIWORD(wParam) == BN_CLICKED ||
1751 HIWORD(wParam) == BN_DOUBLECLICKED)
1753 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1756 if (HIWORD(wParam) == BN_CLICKED ||
1757 HIWORD(wParam) == BN_DOUBLECLICKED)
1758 cfg.telnet_keyboard =
1759 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1762 if (HIWORD(wParam) == BN_CLICKED ||
1763 HIWORD(wParam) == BN_DOUBLECLICKED)
1765 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1768 if (HIWORD(wParam) == BN_CLICKED ||
1769 HIWORD(wParam) == BN_DOUBLECLICKED)
1770 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1773 if (HIWORD(wParam) == BN_CLICKED ||
1774 HIWORD(wParam) == BN_DOUBLECLICKED)
1776 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1779 if (HIWORD(wParam) == EN_CHANGE)
1780 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1783 if (HIWORD(wParam) == EN_CHANGE)
1784 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1787 if (HIWORD(wParam) == EN_CHANGE)
1788 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1790 case IDC_CHOOSEFONT:
1793 lf.lfHeight = -MulDiv(cfg.fontheight,
1794 GetDeviceCaps(hdc, LOGPIXELSY),
1798 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1799 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1800 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1801 lf.lfCharSet = cfg.fontcharset;
1802 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1803 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1804 lf.lfQuality = DEFAULT_QUALITY;
1805 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1806 strncpy(lf.lfFaceName, cfg.font,
1807 sizeof(lf.lfFaceName) - 1);
1808 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1810 cf.lStructSize = sizeof(cf);
1811 cf.hwndOwner = hwnd;
1813 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1814 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1816 if (ChooseFont(&cf)) {
1817 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1818 cfg.font[sizeof(cfg.font) - 1] = '\0';
1819 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1820 cfg.fontcharset = lf.lfCharSet;
1821 cfg.fontheight = cf.iPointSize / 10;
1822 fmtfont(fontstatic);
1823 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1826 case IDC_BELL_DISABLED:
1827 case IDC_BELL_DEFAULT:
1828 case IDC_BELL_WAVEFILE:
1829 case IDC_BELL_VISUAL:
1830 if (HIWORD(wParam) == BN_CLICKED ||
1831 HIWORD(wParam) == BN_DOUBLECLICKED) {
1832 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1833 cfg.beep = BELL_DISABLED;
1834 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1835 cfg.beep = BELL_DEFAULT;
1836 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1837 cfg.beep = BELL_WAVEFILE;
1838 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1839 cfg.beep = BELL_VISUAL;
1842 case IDC_B_IND_DISABLED:
1843 case IDC_B_IND_FLASH:
1844 case IDC_B_IND_STEADY:
1845 if (HIWORD(wParam) == BN_CLICKED ||
1846 HIWORD(wParam) == BN_DOUBLECLICKED) {
1847 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
1848 cfg.beep_ind = B_IND_DISABLED;
1849 if (LOWORD(wParam) == IDC_B_IND_FLASH)
1850 cfg.beep_ind = B_IND_FLASH;
1851 if (LOWORD(wParam) == IDC_B_IND_STEADY)
1852 cfg.beep_ind = B_IND_STEADY;
1855 case IDC_BELL_WAVEBROWSE:
1856 memset(&of, 0, sizeof(of));
1857 #ifdef OPENFILENAME_SIZE_VERSION_400
1858 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1860 of.lStructSize = sizeof(of);
1862 of.hwndOwner = hwnd;
1863 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1864 of.lpstrCustomFilter = NULL;
1865 of.nFilterIndex = 1;
1866 of.lpstrFile = filename;
1867 strcpy(filename, cfg.bell_wavefile);
1868 of.nMaxFile = sizeof(filename);
1869 of.lpstrFileTitle = NULL;
1870 of.lpstrInitialDir = NULL;
1871 of.lpstrTitle = "Select Bell Sound File";
1873 if (GetOpenFileName(&of)) {
1874 strcpy(cfg.bell_wavefile, filename);
1875 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1879 case IDC_BELL_WAVEEDIT:
1880 if (HIWORD(wParam) == EN_CHANGE)
1881 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1883 sizeof(cfg.bell_wavefile) - 1);
1886 if (HIWORD(wParam) == BN_CLICKED ||
1887 HIWORD(wParam) == BN_DOUBLECLICKED)
1889 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1892 if (HIWORD(wParam) == EN_CHANGE)
1893 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
1896 if (HIWORD(wParam) == EN_CHANGE)
1897 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
1901 if (HIWORD(wParam) == EN_CHANGE)
1902 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
1906 if (HIWORD(wParam) == BN_CLICKED ||
1907 HIWORD(wParam) == BN_DOUBLECLICKED)
1909 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
1912 if (HIWORD(wParam) == BN_CLICKED ||
1913 HIWORD(wParam) == BN_DOUBLECLICKED)
1914 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
1917 if (HIWORD(wParam) == BN_CLICKED ||
1918 HIWORD(wParam) == BN_DOUBLECLICKED)
1919 cfg.win_name_always =
1920 IsDlgButtonChecked(hwnd, IDC_WINNAME);
1923 if (HIWORD(wParam) == BN_CLICKED ||
1924 HIWORD(wParam) == BN_DOUBLECLICKED)
1926 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
1928 case IDC_SUNKENEDGE:
1929 if (HIWORD(wParam) == BN_CLICKED ||
1930 HIWORD(wParam) == BN_DOUBLECLICKED)
1932 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
1935 if (HIWORD(wParam) == BN_CLICKED ||
1936 HIWORD(wParam) == BN_DOUBLECLICKED)
1937 cfg.cursor_type = 0;
1940 if (HIWORD(wParam) == BN_CLICKED ||
1941 HIWORD(wParam) == BN_DOUBLECLICKED)
1942 cfg.cursor_type = 1;
1945 if (HIWORD(wParam) == BN_CLICKED ||
1946 HIWORD(wParam) == BN_DOUBLECLICKED)
1947 cfg.cursor_type = 2;
1950 if (HIWORD(wParam) == BN_CLICKED ||
1951 HIWORD(wParam) == BN_DOUBLECLICKED)
1953 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
1956 if (HIWORD(wParam) == BN_CLICKED ||
1957 HIWORD(wParam) == BN_DOUBLECLICKED)
1959 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
1962 if (HIWORD(wParam) == BN_CLICKED ||
1963 HIWORD(wParam) == BN_DOUBLECLICKED)
1965 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
1968 if (HIWORD(wParam) == EN_CHANGE)
1969 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
1970 sizeof(cfg.wintitle) - 1);
1975 if (HIWORD(wParam) == BN_CLICKED ||
1976 HIWORD(wParam) == BN_DOUBLECLICKED) {
1978 IsDlgButtonChecked(hwnd,
1979 IDC_COEALWAYS) ? COE_ALWAYS :
1980 IsDlgButtonChecked(hwnd,
1981 IDC_COENEVER) ? COE_NEVER :
1986 if (HIWORD(wParam) == BN_CLICKED ||
1987 HIWORD(wParam) == BN_DOUBLECLICKED)
1989 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
1992 if (HIWORD(wParam) == EN_CHANGE)
1993 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
1994 sizeof(cfg.termtype) - 1);
1997 if (HIWORD(wParam) == EN_CHANGE)
1998 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
1999 sizeof(cfg.logfilename) - 1);
2002 memset(&of, 0, sizeof(of));
2003 #ifdef OPENFILENAME_SIZE_VERSION_400
2004 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2006 of.lStructSize = sizeof(of);
2008 of.hwndOwner = hwnd;
2009 of.lpstrFilter = "All Files\0*\0\0\0";
2010 of.lpstrCustomFilter = NULL;
2011 of.nFilterIndex = 1;
2012 of.lpstrFile = filename;
2013 strcpy(filename, cfg.logfilename);
2014 of.nMaxFile = sizeof(filename);
2015 of.lpstrFileTitle = NULL;
2016 of.lpstrInitialDir = NULL;
2017 of.lpstrTitle = "Select session log file";
2019 if (GetSaveFileName(&of)) {
2020 strcpy(cfg.logfilename, filename);
2021 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2025 case IDC_LSTATASCII:
2027 if (HIWORD(wParam) == BN_CLICKED ||
2028 HIWORD(wParam) == BN_DOUBLECLICKED) {
2029 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2031 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2033 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2040 if (HIWORD(wParam) == BN_CLICKED ||
2041 HIWORD(wParam) == BN_DOUBLECLICKED) {
2042 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2043 cfg.logxfovr = LGXF_ASK;
2044 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2045 cfg.logxfovr = LGXF_APN;
2046 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2047 cfg.logxfovr = LGXF_OVR;
2052 if (HIWORD(wParam) == EN_CHANGE)
2053 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2054 sizeof(cfg.termspeed) - 1);
2057 if (HIWORD(wParam) == EN_CHANGE)
2058 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2059 sizeof(cfg.username) - 1);
2061 case IDC_RLLUSEREDIT:
2062 if (HIWORD(wParam) == EN_CHANGE)
2063 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2065 sizeof(cfg.localusername) - 1);
2069 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2073 cfg.passive_telnet =
2074 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2077 if (HIWORD(wParam) == BN_CLICKED ||
2078 HIWORD(wParam) == BN_DOUBLECLICKED) {
2079 char str[sizeof(cfg.environmt)];
2081 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2087 p = str + strlen(str);
2089 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2090 sizeof(str) - 1 - (p - str));
2101 if ((p - cfg.environmt) + strlen(str) + 2 <
2102 sizeof(cfg.environmt)) {
2104 p[strlen(str) + 1] = '\0';
2105 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2107 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2108 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2110 MessageBox(hwnd, "Environment too big",
2111 "PuTTY Error", MB_OK | MB_ICONERROR);
2116 if (HIWORD(wParam) != BN_CLICKED &&
2117 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2119 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2126 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2153 if (HIWORD(wParam) == BN_CLICKED ||
2154 HIWORD(wParam) == BN_DOUBLECLICKED)
2155 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2158 if (HIWORD(wParam) == BN_CLICKED ||
2159 HIWORD(wParam) == BN_DOUBLECLICKED)
2161 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2164 if (HIWORD(wParam) == BN_CLICKED ||
2165 HIWORD(wParam) == BN_DOUBLECLICKED)
2167 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2170 if (HIWORD(wParam) == BN_CLICKED ||
2171 HIWORD(wParam) == BN_DOUBLECLICKED)
2173 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2175 case IDC_CIPHER3DES:
2176 case IDC_CIPHERBLOWF:
2179 if (HIWORD(wParam) == BN_CLICKED ||
2180 HIWORD(wParam) == BN_DOUBLECLICKED) {
2181 if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES))
2182 cfg.cipher = CIPHER_3DES;
2183 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF))
2184 cfg.cipher = CIPHER_BLOWFISH;
2185 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES))
2186 cfg.cipher = CIPHER_DES;
2187 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES))
2188 cfg.cipher = CIPHER_AES;
2193 if (HIWORD(wParam) == BN_CLICKED ||
2194 HIWORD(wParam) == BN_DOUBLECLICKED) {
2195 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2197 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2202 if (HIWORD(wParam) == BN_CLICKED ||
2203 HIWORD(wParam) == BN_DOUBLECLICKED)
2205 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2208 if (HIWORD(wParam) == EN_CHANGE)
2209 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2210 sizeof(cfg.keyfile) - 1);
2213 if (HIWORD(wParam) == EN_CHANGE)
2214 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2215 sizeof(cfg.remote_cmd) - 1);
2218 memset(&of, 0, sizeof(of));
2219 #ifdef OPENFILENAME_SIZE_VERSION_400
2220 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2222 of.lStructSize = sizeof(of);
2224 of.hwndOwner = hwnd;
2225 of.lpstrFilter = "All Files\0*\0\0\0";
2226 of.lpstrCustomFilter = NULL;
2227 of.nFilterIndex = 1;
2228 of.lpstrFile = filename;
2229 strcpy(filename, cfg.keyfile);
2230 of.nMaxFile = sizeof(filename);
2231 of.lpstrFileTitle = NULL;
2232 of.lpstrInitialDir = NULL;
2233 of.lpstrTitle = "Select Public Key File";
2235 if (GetOpenFileName(&of)) {
2236 strcpy(cfg.keyfile, filename);
2237 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2241 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2244 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2250 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2255 for (i = 0; i < 128; i++)
2256 if (SendDlgItemMessage
2257 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2259 cfg.wordness[i] = n;
2260 SendDlgItemMessage(hwnd, IDC_CCLIST,
2261 LB_DELETESTRING, i, 0);
2262 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2263 (i >= 0x21 && i != 0x7F) ? i : ' ',
2265 SendDlgItemMessage(hwnd, IDC_CCLIST,
2272 case IDC_BOLDCOLOUR:
2273 if (HIWORD(wParam) == BN_CLICKED ||
2274 HIWORD(wParam) == BN_DOUBLECLICKED) {
2277 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2278 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2281 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2283 if (n != 12 + 10 * cfg.bold_colour) {
2284 for (i = n; i-- > 0;)
2285 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2286 LB_DELETESTRING, i, 0);
2287 for (i = 0; i < 22; i++)
2288 if (cfg.bold_colour || permcolour[i])
2289 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2291 (LPARAM) colours[i]);
2293 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2295 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2300 if (HIWORD(wParam) == BN_CLICKED ||
2301 HIWORD(wParam) == BN_DOUBLECLICKED)
2303 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2305 case IDC_COLOURLIST:
2306 if (HIWORD(wParam) == LBN_DBLCLK ||
2307 HIWORD(wParam) == LBN_SELCHANGE) {
2309 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2312 if (!cfg.bold_colour)
2313 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2314 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2316 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2318 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2323 if (HIWORD(wParam) == BN_CLICKED ||
2324 HIWORD(wParam) == BN_DOUBLECLICKED) {
2325 static CHOOSECOLOR cc;
2326 static DWORD custom[16] = { 0 }; /* zero initialisers */
2328 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2331 if (!cfg.bold_colour)
2332 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2333 cc.lStructSize = sizeof(cc);
2334 cc.hwndOwner = hwnd;
2335 cc.hInstance = (HWND) hinst;
2336 cc.lpCustColors = custom;
2338 RGB(cfg.colours[i][0], cfg.colours[i][1],
2340 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2341 if (ChooseColor(&cc)) {
2343 (unsigned char) (cc.rgbResult & 0xFF);
2345 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2347 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2348 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2350 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2352 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2358 if (HIWORD(wParam) == EN_CHANGE)
2359 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2360 sizeof(cfg.line_codepage) - 1);
2361 if (HIWORD(wParam) == EN_KILLFOCUS) {
2362 int cp = decode_codepage(cfg.line_codepage);
2367 "Unable to identify character set '%s', "
2368 "translation disabled.",
2372 "Character set '%s' is a DBCS, "
2373 "translation is not available.",
2375 MessageBox(hwnd, buf, "PuTTY Error",
2376 MB_ICONERROR | MB_OK);
2378 strcpy(cfg.line_codepage, cp_name(cp));
2379 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2382 case IDC_VTXWINDOWS:
2388 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2389 : IsDlgButtonChecked(hwnd,
2390 IDC_VTOEMANSI) ? VT_OEMANSI :
2391 IsDlgButtonChecked(hwnd,
2392 IDC_VTOEMONLY) ? VT_OEMONLY :
2393 IsDlgButtonChecked(hwnd,
2394 IDC_VTUNICODE) ? VT_UNICODE :
2397 case IDC_X11_FORWARD:
2398 if (HIWORD(wParam) == BN_CLICKED ||
2399 HIWORD(wParam) == BN_DOUBLECLICKED)
2401 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2403 case IDC_X11_DISPLAY:
2404 if (HIWORD(wParam) == EN_CHANGE)
2405 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2406 sizeof(cfg.x11_display) - 1);
2414 /* Grrr Explorer will maximize Dialogs! */
2416 if (wParam == SIZE_MAXIMIZED)
2423 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2424 WPARAM wParam, LPARAM lParam)
2426 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2428 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2429 EnableWindow(hwnd, 0);
2430 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2431 EnableWindow(hwnd, 1);
2432 SetActiveWindow(hwnd);
2434 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2437 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2438 WPARAM wParam, LPARAM lParam)
2440 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2443 void defuse_showwindow(void)
2446 * Work around the fact that the app's first call to ShowWindow
2447 * will ignore the default in favour of the shell-provided
2452 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2454 ShowWindow(hwnd, SW_HIDE);
2455 SetActiveWindow(hwnd);
2456 DestroyWindow(hwnd);
2465 savedsession[0] = '\0';
2467 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2468 get_sesslist(FALSE);
2473 int do_reconfig(HWND hwnd)
2478 backup_cfg = cfg; /* structure copy */
2480 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2482 cfg = backup_cfg; /* structure copy */
2487 void logevent(char *string)
2492 if (nevents >= negsize) {
2494 events = srealloc(events, negsize * sizeof(*events));
2498 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2501 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2502 strcpy(events[nevents], timebuf);
2503 strcat(events[nevents], string);
2506 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2507 0, (LPARAM) events[nevents]);
2508 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2509 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2514 void showeventlog(HWND hwnd)
2517 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2519 ShowWindow(logbox, SW_SHOWNORMAL);
2521 SetActiveWindow(logbox);
2524 void showabout(HWND hwnd)
2526 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2529 void verify_ssh_host_key(char *host, int port, char *keytype,
2530 char *keystr, char *fingerprint)
2534 static const char absentmsg[] =
2535 "The server's host key is not cached in the registry. You\n"
2536 "have no guarantee that the server is the computer you\n"
2538 "The server's key fingerprint is:\n"
2540 "If you trust this host, hit Yes to add the key to\n"
2541 "PuTTY's cache and carry on connecting.\n"
2542 "If you want to carry on connecting just once, without\n"
2543 "adding the key to the cache, hit No.\n"
2544 "If you do not trust this host, hit Cancel to abandon the\n"
2547 static const char wrongmsg[] =
2548 "WARNING - POTENTIAL SECURITY BREACH!\n"
2550 "The server's host key does not match the one PuTTY has\n"
2551 "cached in the registry. This means that either the\n"
2552 "server administrator has changed the host key, or you\n"
2553 "have actually connected to another computer pretending\n"
2554 "to be the server.\n"
2555 "The new key fingerprint is:\n"
2557 "If you were expecting this change and trust the new key,\n"
2558 "hit Yes to update PuTTY's cache and continue connecting.\n"
2559 "If you want to carry on connecting but without updating\n"
2560 "the cache, hit No.\n"
2561 "If you want to abandon the connection completely, hit\n"
2562 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2564 static const char mbtitle[] = "PuTTY Security Alert";
2567 /* sensible fingerprint max size */
2568 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2569 sizeof(absentmsg) : sizeof(wrongmsg))];
2572 * Verify the key against the registry.
2574 ret = verify_host_key(host, port, keytype, keystr);
2576 if (ret == 0) /* success - key matched OK */
2578 if (ret == 2) { /* key was different */
2580 sprintf(message, wrongmsg, fingerprint);
2581 mbret = MessageBox(NULL, message, mbtitle,
2582 MB_ICONWARNING | MB_YESNOCANCEL);
2584 store_host_key(host, port, keytype, keystr);
2585 if (mbret == IDCANCEL)
2588 if (ret == 1) { /* key was absent */
2590 sprintf(message, absentmsg, fingerprint);
2591 mbret = MessageBox(NULL, message, mbtitle,
2592 MB_ICONWARNING | MB_YESNOCANCEL);
2594 store_host_key(host, port, keytype, keystr);
2595 if (mbret == IDCANCEL)
2601 * Ask whether to wipe a session log file before writing to it.
2602 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2604 int askappend(char *filename)
2606 static const char mbtitle[] = "PuTTY Log to File";
2607 static const char msgtemplate[] =
2608 "The session log file \"%.*s\" already exists.\n"
2609 "You can overwrite it with a new session log,\n"
2610 "append your session log to the end of it,\n"
2611 "or disable session logging for this session.\n"
2612 "Hit Yes to wipe the file, No to append to it,\n"
2613 "or Cancel to disable logging.";
2614 char message[sizeof(msgtemplate) + FILENAME_MAX];
2616 if (cfg.logxfovr != LGXF_ASK) {
2617 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2619 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2621 mbret = MessageBox(NULL, message, mbtitle,
2622 MB_ICONQUESTION | MB_YESNOCANCEL);
2625 else if (mbret == IDNO)