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;
667 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
672 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
673 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
674 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
675 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
677 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
678 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
679 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
680 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
681 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
682 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
683 CheckRadioButton(hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
684 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
685 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
686 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
688 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
689 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
690 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
691 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
692 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
694 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
695 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
696 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
698 static int tabs[4] = { 25, 61, 96, 128 };
699 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
702 for (i = 0; i < 128; i++) {
704 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
705 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
706 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
710 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
711 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
714 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
715 for (i = n; i-- > 0;)
716 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
717 LB_DELETESTRING, i, 0);
718 for (i = 0; i < 22; i++)
719 if (cfg.bold_colour || permcolour[i])
720 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
721 (LPARAM) colours[i]);
723 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
724 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
725 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
726 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
728 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
729 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
730 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
731 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
732 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
733 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
736 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
737 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
740 struct treeview_faff {
745 static HTREEITEM treeview_insert(struct treeview_faff *faff,
746 int level, char *text)
751 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
752 ins.hInsertAfter = faff->lastat[level];
753 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
754 #define INSITEM DUMMYUNIONNAME.item
758 ins.INSITEM.mask = TVIF_TEXT;
759 ins.INSITEM.pszText = text;
760 newitem = TreeView_InsertItem(faff->treeview, &ins);
762 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
764 faff->lastat[level] = newitem;
765 for (i = level + 1; i < 4; i++)
766 faff->lastat[i] = NULL;
771 * Create the panelfuls of controls in the configuration box.
773 static void create_controls(HWND hwnd, int dlgtype, int panel)
775 if (panel == sessionpanelstart) {
776 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
778 ctlposinit(&cp, hwnd, 80, 3, 13);
779 bartitle(&cp, "Basic options for your PuTTY session",
782 beginbox(&cp, "Specify your connection by host name",
785 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
786 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
787 if (backends[3].backend == NULL) {
788 /* this is PuTTYtel, so only three protocols available */
789 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
791 "&Telnet", IDC_PROTTELNET,
792 "Rlog&in", IDC_PROTRLOGIN, NULL);
794 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
796 "&Telnet", IDC_PROTTELNET,
797 "Rlog&in", IDC_PROTRLOGIN,
806 beginbox(&cp, "Load, save or delete a stored session",
808 sesssaver(&cp, "Sav&ed Sessions",
809 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
810 "&Load", IDC_SESSLOAD,
811 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
814 beginbox(&cp, NULL, IDC_BOX_SESSION3);
815 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
816 "Always", IDC_COEALWAYS,
817 "Never", IDC_COENEVER,
818 "Only on clean exit", IDC_COENORMAL, NULL);
822 if (panel == loggingpanelstart) {
823 /* The Logging panel. Accelerators used: [acgo] tplfwe */
825 ctlposinit(&cp, hwnd, 80, 3, 13);
826 bartitle(&cp, "Options controlling session logging",
828 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
830 "Session logging:", IDC_LSTATSTATIC,
831 "Logging &turned off completely", IDC_LSTATOFF,
832 "Log &printable output only", IDC_LSTATASCII,
833 "&Log all session output", IDC_LSTATRAW, NULL);
834 editbutton(&cp, "Log &file name:",
835 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
838 "What to do if the log file already &exists:",
839 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
840 "Always append to the end of it", IDC_LSTATXAPN,
841 "Ask the user every time", IDC_LSTATXASK, NULL);
845 if (panel == terminalpanelstart) {
846 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
848 ctlposinit(&cp, hwnd, 80, 3, 13);
849 bartitle(&cp, "Options controlling the terminal emulation",
851 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
852 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
853 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
854 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
855 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
856 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
858 "An&swerback to ^E:", IDC_ANSWERBACK,
859 IDC_ANSWEREDIT, 100, NULL);
862 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
863 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
864 "Auto", IDC_ECHOBACKEND,
865 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
866 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
867 "Auto", IDC_EDITBACKEND,
868 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
872 if (panel == bellpanelstart) {
873 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
875 ctlposinit(&cp, hwnd, 80, 3, 13);
876 bartitle(&cp, "Options controlling the terminal bell",
878 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
880 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
881 "None (bell disabled)", IDC_BELL_DISABLED,
882 "Play Windows Default Sound", IDC_BELL_DEFAULT,
883 "Play a custom sound file", IDC_BELL_WAVEFILE,
884 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
885 editbutton(&cp, "Custom sound file to play as a bell:",
886 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
887 "Bro&wse...", IDC_BELL_WAVEBROWSE);
888 radioline(&cp, "Taskbar/caption &indication on bell:",
889 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
890 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
893 beginbox(&cp, "Control the bell overload behaviour",
895 checkbox(&cp, "Bell is temporarily &disabled when over-used",
897 staticedit(&cp, "Over-use means this &many bells...",
898 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
899 staticedit(&cp, "... in &this many seconds",
900 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
902 "The bell is re-enabled after a few seconds of silence.",
904 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
909 if (panel == keyboardpanelstart) {
910 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
912 ctlposinit(&cp, hwnd, 80, 3, 13);
914 bartitle(&cp, "Options controlling the effects of keys",
917 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
918 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
919 "Control-H", IDC_DEL008,
920 "Control-? (127)", IDC_DEL127, NULL);
921 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
922 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
923 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
924 "ESC[n~", IDC_FUNCTILDE,
925 "Linux", IDC_FUNCLINUX,
926 "Xterm R6", IDC_FUNCXTERM,
927 "VT400", IDC_FUNCVT400,
928 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
930 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
932 "Application c&ursor keys totally disabled",
934 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
935 "Normal", IDC_CURNORMAL,
936 "Application", IDC_CURAPPLIC, NULL);
938 "Application ke&ypad keys totally disabled",
940 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
941 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
942 "NetHack", IDC_KPNH, NULL);
944 beginbox(&cp, "Enable extra keyboard features:",
946 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
947 checkbox(&cp, "Control-Alt is &different from AltGr",
952 if (panel == windowpanelstart) {
953 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
955 ctlposinit(&cp, hwnd, 80, 3, 13);
956 bartitle(&cp, "Options controlling PuTTY's window",
958 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
960 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
961 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
962 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
964 beginbox(&cp, "Control the scrollback in the window",
966 staticedit(&cp, "Lines of &scrollback",
967 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
968 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
969 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
970 checkbox(&cp, "Reset scrollback on dis&play activity",
973 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
974 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
975 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
976 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
977 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
978 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
982 if (panel == appearancepanelstart) {
983 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
985 ctlposinit(&cp, hwnd, 80, 3, 13);
986 bartitle(&cp, "Options controlling PuTTY's appearance",
987 IDC_TITLE_APPEARANCE);
988 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
989 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
990 "B&lock", IDC_CURBLOCK,
991 "&Underline", IDC_CURUNDER,
992 "&Vertical line", IDC_CURVERT, NULL);
993 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
995 beginbox(&cp, "Set the font used in the terminal window",
996 IDC_BOX_APPEARANCE2);
997 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
999 beginbox(&cp, "Adjust the use of the window title",
1000 IDC_BOX_APPEARANCE3);
1002 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1003 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1005 beginbox(&cp, "Adjust the use of the mouse pointer",
1006 IDC_BOX_APPEARANCE4);
1007 checkbox(&cp, "Hide mouse &pointer when typing in window",
1010 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1011 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1016 if (panel == translationpanelstart) {
1017 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1019 ctlposinit(&cp, hwnd, 80, 3, 13);
1020 bartitle(&cp, "Options controlling character set translation",
1021 IDC_TITLE_TRANSLATION);
1022 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1023 IDC_BOX_TRANSLATION1);
1025 "Handling of line drawing characters:", IDC_VTSTATIC,
1026 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1027 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1028 "Use font in O&EM mode only", IDC_VTOEMONLY,
1029 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1030 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1032 beginbox(&cp, "Enable character set translation on received data",
1033 IDC_BOX_TRANSLATION2);
1034 multiedit(&cp, "Line codepage:", IDC_CODEPAGESTATIC,
1035 IDC_CODEPAGE, 100, NULL);
1039 if (panel == selectionpanelstart) {
1040 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1042 ctlposinit(&cp, hwnd, 80, 3, 13);
1043 bartitle(&cp, "Options controlling copy and paste",
1044 IDC_TITLE_SELECTION);
1045 beginbox(&cp, "Translation of pasted characters",
1046 IDC_BOX_SELECTION1);
1048 "&Don't translate line drawing chars into +, - and |",
1051 beginbox(&cp, "Control which mouse button does which thing",
1052 IDC_BOX_SELECTION2);
1053 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1054 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1055 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1058 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1059 IDC_BOX_SELECTION3);
1060 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1061 "&Set", IDC_CCSET, IDC_CCEDIT,
1062 "&to class", IDC_CCSTATIC2);
1066 if (panel == colourspanelstart) {
1067 /* The Colours panel. Accelerators used: [acgo] blum */
1069 ctlposinit(&cp, hwnd, 80, 3, 13);
1070 bartitle(&cp, "Options controlling use of colours",
1072 beginbox(&cp, "General options for colour usage",
1074 checkbox(&cp, "&Bolded text is a different colour",
1076 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1078 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1080 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1081 IDC_COLOURSTATIC, IDC_COLOURLIST,
1082 "&Modify...", IDC_CHANGE,
1083 "Red:", IDC_RSTATIC, IDC_RVALUE,
1084 "Green:", IDC_GSTATIC, IDC_GVALUE,
1085 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1089 if (panel == connectionpanelstart) {
1090 /* The Connection panel. Accelerators used: [acgo] tuk */
1092 ctlposinit(&cp, hwnd, 80, 3, 13);
1093 bartitle(&cp, "Options controlling the connection",
1094 IDC_TITLE_CONNECTION);
1096 beginbox(&cp, "Data to send to the server",
1097 IDC_BOX_CONNECTION1);
1098 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1100 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1104 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1105 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1109 beginbox(&cp, "Sending of null packets to keep session active",
1110 IDC_BOX_CONNECTION2);
1111 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1112 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1116 if (panel == telnetpanelstart) {
1117 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1119 ctlposinit(&cp, hwnd, 80, 3, 13);
1121 bartitle(&cp, "Options controlling Telnet connections",
1123 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1124 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1126 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1127 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1128 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1129 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1131 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1132 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1133 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1134 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1135 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1136 "Passive", IDC_TPASSIVE, "Active",
1138 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1144 if (panel == rloginpanelstart) {
1145 /* The Rlogin panel. Accelerators used: [acgo] sl */
1147 ctlposinit(&cp, hwnd, 80, 3, 13);
1149 bartitle(&cp, "Options controlling Rlogin connections",
1151 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1152 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1154 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1155 IDC_RLLUSEREDIT, 50);
1160 if (panel == sshpanelstart) {
1161 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1163 ctlposinit(&cp, hwnd, 80, 3, 13);
1165 bartitle(&cp, "Options controlling SSH connections",
1167 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1169 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1172 beginbox(&cp, "Authentication options", IDC_BOX_SSH2);
1173 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1175 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1176 editbutton(&cp, "Private &key file for authentication:",
1177 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1180 beginbox(&cp, "Protocol options", IDC_BOX_SSH3);
1181 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1182 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1183 radioline(&cp, "Preferred SSH protocol version:",
1184 IDC_SSHPROTSTATIC, 2,
1185 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1186 radioline(&cp, "Preferred encryption algorithm:",
1187 IDC_CIPHERSTATIC, 4, "&3DES", IDC_CIPHER3DES,
1188 "&Blowfish", IDC_CIPHERBLOWF, "&DES", IDC_CIPHERDES,
1189 "AE&S", IDC_CIPHERAES, NULL);
1190 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1196 if (panel == tunnelspanelstart) {
1197 /* The Tunnels panel. Accelerators used: [acgo] ex */
1199 ctlposinit(&cp, hwnd, 80, 3, 13);
1201 bartitle(&cp, "Options controlling SSH tunnelling",
1203 beginbox(&cp, "X11 forwarding options", IDC_BOX_TUNNELS);
1204 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1205 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1206 IDC_X11_DISPLAY, 50, NULL);
1213 * Helper function to load the session selected in SESSLIST
1214 * if any, as this is done in more than one place in
1215 * GenericMainDlgProc(). 0 => failure.
1217 static int load_selected_session(HWND hwnd)
1219 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1220 LB_GETCURSEL, 0, 0);
1226 isdef = !strcmp(sessions[n], "Default Settings");
1227 load_settings(sessions[n], !isdef, &cfg);
1228 init_dlg_ctrls(hwnd, TRUE);
1230 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1232 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1233 /* Restore the selection, which will have been clobbered by
1234 * SESSEDIT handling. */
1235 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1240 * This function is the configuration box.
1242 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1243 WPARAM wParam, LPARAM lParam, int dlgtype)
1246 struct treeview_faff tvfaff;
1249 char filename[sizeof(cfg.keyfile)];
1252 char fontstatic[256];
1254 struct servent *service;
1260 SetWindowLong(hwnd, GWL_USERDATA, 0);
1261 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1262 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1264 * Centre the window.
1266 { /* centre the window */
1269 hw = GetDesktopWindow();
1270 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1272 (rs.right + rs.left + rd.left - rd.right) / 2,
1273 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1274 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1278 * Create the tree view.
1286 r.right = r.left + 75;
1288 r.bottom = r.top + 10;
1289 MapDialogRect(hwnd, &r);
1290 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1291 WS_CHILD | WS_VISIBLE,
1293 r.right - r.left, r.bottom - r.top,
1294 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1296 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1297 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1300 r.right = r.left + 75;
1302 r.bottom = r.top + 206;
1303 MapDialogRect(hwnd, &r);
1304 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1305 WS_CHILD | WS_VISIBLE |
1306 WS_TABSTOP | TVS_HASLINES |
1307 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1309 TVS_SHOWSELALWAYS, r.left, r.top,
1310 r.right - r.left, r.bottom - r.top,
1311 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1313 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1314 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1315 tvfaff.treeview = treeview;
1316 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1320 * Set up the tree view contents.
1322 hsession = treeview_insert(&tvfaff, 0, "Session");
1323 treeview_insert(&tvfaff, 1, "Logging");
1324 treeview_insert(&tvfaff, 0, "Terminal");
1325 treeview_insert(&tvfaff, 1, "Keyboard");
1326 treeview_insert(&tvfaff, 1, "Bell");
1327 treeview_insert(&tvfaff, 0, "Window");
1328 treeview_insert(&tvfaff, 1, "Appearance");
1329 treeview_insert(&tvfaff, 1, "Translation");
1330 treeview_insert(&tvfaff, 1, "Selection");
1331 treeview_insert(&tvfaff, 1, "Colours");
1332 treeview_insert(&tvfaff, 0, "Connection");
1334 treeview_insert(&tvfaff, 1, "Telnet");
1335 treeview_insert(&tvfaff, 1, "Rlogin");
1336 if (backends[3].backend != NULL) {
1337 treeview_insert(&tvfaff, 1, "SSH");
1338 treeview_insert(&tvfaff, 2, "Tunnels");
1343 * Put the treeview selection on to the Session panel. This
1344 * should also cause creation of the relevant controls.
1346 TreeView_SelectItem(treeview, hsession);
1349 * Set focus into the first available control.
1353 ctl = GetDlgItem(hwnd, IDC_HOST);
1355 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1359 SetWindowLong(hwnd, GWL_USERDATA, 1);
1360 sesslist_has_focus = 0;
1364 * Button release should trigger WM_OK if there was a
1365 * previous double click on the session list.
1369 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1372 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1373 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1375 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1380 item.pszText = buffer;
1381 item.cchTextMax = sizeof(buffer);
1382 item.mask = TVIF_TEXT;
1383 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1384 for (j = controlstartvalue; j < controlendvalue; j++) {
1385 HWND item = GetDlgItem(hwnd, j);
1387 DestroyWindow(item);
1389 if (!strcmp(buffer, "Session"))
1390 create_controls(hwnd, dlgtype, sessionpanelstart);
1391 if (!strcmp(buffer, "Logging"))
1392 create_controls(hwnd, dlgtype, loggingpanelstart);
1393 if (!strcmp(buffer, "Keyboard"))
1394 create_controls(hwnd, dlgtype, keyboardpanelstart);
1395 if (!strcmp(buffer, "Terminal"))
1396 create_controls(hwnd, dlgtype, terminalpanelstart);
1397 if (!strcmp(buffer, "Bell"))
1398 create_controls(hwnd, dlgtype, bellpanelstart);
1399 if (!strcmp(buffer, "Window"))
1400 create_controls(hwnd, dlgtype, windowpanelstart);
1401 if (!strcmp(buffer, "Appearance"))
1402 create_controls(hwnd, dlgtype, appearancepanelstart);
1403 if (!strcmp(buffer, "Tunnels"))
1404 create_controls(hwnd, dlgtype, tunnelspanelstart);
1405 if (!strcmp(buffer, "Connection"))
1406 create_controls(hwnd, dlgtype, connectionpanelstart);
1407 if (!strcmp(buffer, "Telnet"))
1408 create_controls(hwnd, dlgtype, telnetpanelstart);
1409 if (!strcmp(buffer, "Rlogin"))
1410 create_controls(hwnd, dlgtype, rloginpanelstart);
1411 if (!strcmp(buffer, "SSH"))
1412 create_controls(hwnd, dlgtype, sshpanelstart);
1413 if (!strcmp(buffer, "Selection"))
1414 create_controls(hwnd, dlgtype, selectionpanelstart);
1415 if (!strcmp(buffer, "Colours"))
1416 create_controls(hwnd, dlgtype, colourspanelstart);
1417 if (!strcmp(buffer, "Translation"))
1418 create_controls(hwnd, dlgtype, translationpanelstart);
1420 init_dlg_ctrls(hwnd, FALSE);
1422 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1428 * Only process WM_COMMAND once the dialog is fully formed.
1430 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1431 switch (LOWORD(wParam)) {
1433 /* Behaviour of the "Open" button is different if the
1434 * session list has focus, *unless* the user just
1435 * double-clicked... */
1436 if (sesslist_has_focus && !readytogo) {
1437 if (!load_selected_session(hwnd)) {
1442 /* If at this point we have a valid session, go! */
1451 case IDC_PROTTELNET:
1452 case IDC_PROTRLOGIN:
1455 if (HIWORD(wParam) == BN_CLICKED ||
1456 HIWORD(wParam) == BN_DOUBLECLICKED) {
1457 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1458 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1459 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1461 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1463 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1464 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1465 || (cfg.protocol == PROT_RLOGIN
1466 && cfg.port != 513)) {
1467 cfg.port = i ? 22 : j ? 23 : 513;
1468 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1473 if (HIWORD(wParam) == EN_CHANGE)
1474 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1475 sizeof(cfg.host) - 1);
1478 if (HIWORD(wParam) == EN_CHANGE) {
1479 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1480 if (isdigit(portname[0]))
1481 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1483 service = getservbyname(portname, NULL);
1485 cfg.port = ntohs(service->s_port);
1492 if (HIWORD(wParam) == EN_CHANGE) {
1493 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1495 GetDlgItemText(hwnd, IDC_SESSEDIT,
1496 savedsession, sizeof(savedsession) - 1);
1497 savedsession[sizeof(savedsession) - 1] = '\0';
1501 if (HIWORD(wParam) == BN_CLICKED ||
1502 HIWORD(wParam) == BN_DOUBLECLICKED) {
1507 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1510 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1511 LB_GETCURSEL, 0, 0);
1516 strcpy(str, sessions[n]);
1518 save_settings(str, !!strcmp(str, "Default Settings"),
1520 get_sesslist(FALSE);
1522 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1524 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1526 for (i = 0; i < nsessions; i++)
1527 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1529 (LPARAM) (sessions[i]));
1530 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1532 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1534 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1540 if (LOWORD(wParam) == IDC_SESSLIST) {
1541 if (HIWORD(wParam) == LBN_SETFOCUS)
1542 sesslist_has_focus = 1;
1543 else if (HIWORD(wParam) == LBN_KILLFOCUS)
1544 sesslist_has_focus = 0;
1546 if (LOWORD(wParam) == IDC_SESSLOAD &&
1547 HIWORD(wParam) != BN_CLICKED &&
1548 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1549 if (LOWORD(wParam) == IDC_SESSLIST &&
1550 HIWORD(wParam) != LBN_DBLCLK) break;
1551 /* Load the session selected in SESSLIST. */
1552 if (load_selected_session(hwnd) &&
1553 LOWORD(wParam) == IDC_SESSLIST) {
1555 * A double-click on a saved session should
1556 * actually start the session, not just load it.
1557 * Unless it's Default Settings or some other
1558 * host-less set of saved settings.
1567 if (HIWORD(wParam) == BN_CLICKED ||
1568 HIWORD(wParam) == BN_DOUBLECLICKED) {
1569 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1570 LB_GETCURSEL, 0, 0);
1571 if (n == LB_ERR || n == 0) {
1575 del_settings(sessions[n]);
1576 get_sesslist(FALSE);
1578 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1580 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1582 for (i = 0; i < nsessions; i++)
1583 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1585 (LPARAM) (sessions[i]));
1586 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1588 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1590 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1594 if (HIWORD(wParam) == EN_CHANGE)
1595 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1596 &cfg.ping_interval);
1600 if (HIWORD(wParam) == BN_CLICKED ||
1601 HIWORD(wParam) == BN_DOUBLECLICKED)
1602 cfg.bksp_is_delete =
1603 IsDlgButtonChecked(hwnd, IDC_DEL127);
1607 if (HIWORD(wParam) == BN_CLICKED ||
1608 HIWORD(wParam) == BN_DOUBLECLICKED)
1610 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1616 case IDC_FUNCVT100P:
1618 if (HIWORD(wParam) == BN_CLICKED ||
1619 HIWORD(wParam) == BN_DOUBLECLICKED)
1620 switch (LOWORD(wParam)) {
1633 case IDC_FUNCVT100P:
1643 if (HIWORD(wParam) == BN_CLICKED ||
1644 HIWORD(wParam) == BN_DOUBLECLICKED) {
1646 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1647 cfg.nethack_keypad = FALSE;
1651 if (HIWORD(wParam) == BN_CLICKED ||
1652 HIWORD(wParam) == BN_DOUBLECLICKED) {
1653 cfg.app_keypad = FALSE;
1654 cfg.nethack_keypad = TRUE;
1659 if (HIWORD(wParam) == BN_CLICKED ||
1660 HIWORD(wParam) == BN_DOUBLECLICKED)
1662 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1665 if (HIWORD(wParam) == BN_CLICKED ||
1666 HIWORD(wParam) == BN_DOUBLECLICKED)
1668 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1671 if (HIWORD(wParam) == BN_CLICKED ||
1672 HIWORD(wParam) == BN_DOUBLECLICKED)
1674 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1677 if (HIWORD(wParam) == BN_CLICKED ||
1678 HIWORD(wParam) == BN_DOUBLECLICKED)
1679 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1682 if (HIWORD(wParam) == BN_CLICKED ||
1683 HIWORD(wParam) == BN_DOUBLECLICKED)
1685 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1688 if (HIWORD(wParam) == BN_CLICKED ||
1689 HIWORD(wParam) == BN_DOUBLECLICKED)
1691 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1693 case IDC_ECHOBACKEND:
1696 if (HIWORD(wParam) == BN_CLICKED ||
1697 HIWORD(wParam) == BN_DOUBLECLICKED) {
1698 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1699 cfg.localecho = LD_BACKEND;
1700 if (LOWORD(wParam) == IDC_ECHOYES)
1701 cfg.localecho = LD_YES;
1702 if (LOWORD(wParam) == IDC_ECHONO)
1703 cfg.localecho = LD_NO;
1706 case IDC_EDITBACKEND:
1709 if (HIWORD(wParam) == BN_CLICKED ||
1710 HIWORD(wParam) == BN_DOUBLECLICKED) {
1711 if (LOWORD(wParam) == IDC_EDITBACKEND)
1712 cfg.localedit = LD_BACKEND;
1713 if (LOWORD(wParam) == IDC_EDITYES)
1714 cfg.localedit = LD_YES;
1715 if (LOWORD(wParam) == IDC_EDITNO)
1716 cfg.localedit = LD_NO;
1719 case IDC_ANSWEREDIT:
1720 if (HIWORD(wParam) == EN_CHANGE)
1721 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1722 sizeof(cfg.answerback) - 1);
1724 case IDC_ALWAYSONTOP:
1725 if (HIWORD(wParam) == BN_CLICKED ||
1726 HIWORD(wParam) == BN_DOUBLECLICKED)
1728 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1731 if (HIWORD(wParam) == BN_CLICKED ||
1732 HIWORD(wParam) == BN_DOUBLECLICKED)
1734 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1736 case IDC_SCROLLDISP:
1737 if (HIWORD(wParam) == BN_CLICKED ||
1738 HIWORD(wParam) == BN_DOUBLECLICKED)
1739 cfg.scroll_on_disp =
1740 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1742 case IDC_COMPOSEKEY:
1743 if (HIWORD(wParam) == BN_CLICKED ||
1744 HIWORD(wParam) == BN_DOUBLECLICKED)
1746 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1748 case IDC_CTRLALTKEYS:
1749 if (HIWORD(wParam) == BN_CLICKED ||
1750 HIWORD(wParam) == BN_DOUBLECLICKED)
1752 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1755 if (HIWORD(wParam) == BN_CLICKED ||
1756 HIWORD(wParam) == BN_DOUBLECLICKED)
1757 cfg.telnet_keyboard =
1758 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1761 if (HIWORD(wParam) == BN_CLICKED ||
1762 HIWORD(wParam) == BN_DOUBLECLICKED)
1764 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1767 if (HIWORD(wParam) == BN_CLICKED ||
1768 HIWORD(wParam) == BN_DOUBLECLICKED)
1769 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1772 if (HIWORD(wParam) == BN_CLICKED ||
1773 HIWORD(wParam) == BN_DOUBLECLICKED)
1775 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1778 if (HIWORD(wParam) == EN_CHANGE)
1779 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1782 if (HIWORD(wParam) == EN_CHANGE)
1783 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1786 if (HIWORD(wParam) == EN_CHANGE)
1787 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1789 case IDC_CHOOSEFONT:
1792 lf.lfHeight = -MulDiv(cfg.fontheight,
1793 GetDeviceCaps(hdc, LOGPIXELSY),
1797 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1798 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1799 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1800 lf.lfCharSet = cfg.fontcharset;
1801 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1802 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1803 lf.lfQuality = DEFAULT_QUALITY;
1804 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1805 strncpy(lf.lfFaceName, cfg.font,
1806 sizeof(lf.lfFaceName) - 1);
1807 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1809 cf.lStructSize = sizeof(cf);
1810 cf.hwndOwner = hwnd;
1812 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1813 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1815 if (ChooseFont(&cf)) {
1816 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1817 cfg.font[sizeof(cfg.font) - 1] = '\0';
1818 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1819 cfg.fontcharset = lf.lfCharSet;
1820 cfg.fontheight = cf.iPointSize / 10;
1821 fmtfont(fontstatic);
1822 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1825 case IDC_BELL_DISABLED:
1826 case IDC_BELL_DEFAULT:
1827 case IDC_BELL_WAVEFILE:
1828 case IDC_BELL_VISUAL:
1829 if (HIWORD(wParam) == BN_CLICKED ||
1830 HIWORD(wParam) == BN_DOUBLECLICKED) {
1831 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1832 cfg.beep = BELL_DISABLED;
1833 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1834 cfg.beep = BELL_DEFAULT;
1835 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1836 cfg.beep = BELL_WAVEFILE;
1837 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1838 cfg.beep = BELL_VISUAL;
1841 case IDC_B_IND_DISABLED:
1842 case IDC_B_IND_FLASH:
1843 case IDC_B_IND_STEADY:
1844 if (HIWORD(wParam) == BN_CLICKED ||
1845 HIWORD(wParam) == BN_DOUBLECLICKED) {
1846 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
1847 cfg.beep_ind = B_IND_DISABLED;
1848 if (LOWORD(wParam) == IDC_B_IND_FLASH)
1849 cfg.beep_ind = B_IND_FLASH;
1850 if (LOWORD(wParam) == IDC_B_IND_STEADY)
1851 cfg.beep_ind = B_IND_STEADY;
1854 case IDC_BELL_WAVEBROWSE:
1855 memset(&of, 0, sizeof(of));
1856 #ifdef OPENFILENAME_SIZE_VERSION_400
1857 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1859 of.lStructSize = sizeof(of);
1861 of.hwndOwner = hwnd;
1862 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1863 of.lpstrCustomFilter = NULL;
1864 of.nFilterIndex = 1;
1865 of.lpstrFile = filename;
1866 strcpy(filename, cfg.bell_wavefile);
1867 of.nMaxFile = sizeof(filename);
1868 of.lpstrFileTitle = NULL;
1869 of.lpstrInitialDir = NULL;
1870 of.lpstrTitle = "Select Bell Sound File";
1872 if (GetOpenFileName(&of)) {
1873 strcpy(cfg.bell_wavefile, filename);
1874 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1878 case IDC_BELL_WAVEEDIT:
1879 if (HIWORD(wParam) == EN_CHANGE)
1880 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1882 sizeof(cfg.bell_wavefile) - 1);
1885 if (HIWORD(wParam) == BN_CLICKED ||
1886 HIWORD(wParam) == BN_DOUBLECLICKED)
1888 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1891 if (HIWORD(wParam) == EN_CHANGE)
1892 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
1895 if (HIWORD(wParam) == EN_CHANGE)
1896 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
1900 if (HIWORD(wParam) == EN_CHANGE)
1901 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
1905 if (HIWORD(wParam) == BN_CLICKED ||
1906 HIWORD(wParam) == BN_DOUBLECLICKED)
1908 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
1911 if (HIWORD(wParam) == BN_CLICKED ||
1912 HIWORD(wParam) == BN_DOUBLECLICKED)
1913 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
1916 if (HIWORD(wParam) == BN_CLICKED ||
1917 HIWORD(wParam) == BN_DOUBLECLICKED)
1918 cfg.win_name_always =
1919 IsDlgButtonChecked(hwnd, IDC_WINNAME);
1922 if (HIWORD(wParam) == BN_CLICKED ||
1923 HIWORD(wParam) == BN_DOUBLECLICKED)
1925 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
1927 case IDC_SUNKENEDGE:
1928 if (HIWORD(wParam) == BN_CLICKED ||
1929 HIWORD(wParam) == BN_DOUBLECLICKED)
1931 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
1934 if (HIWORD(wParam) == BN_CLICKED ||
1935 HIWORD(wParam) == BN_DOUBLECLICKED)
1936 cfg.cursor_type = 0;
1939 if (HIWORD(wParam) == BN_CLICKED ||
1940 HIWORD(wParam) == BN_DOUBLECLICKED)
1941 cfg.cursor_type = 1;
1944 if (HIWORD(wParam) == BN_CLICKED ||
1945 HIWORD(wParam) == BN_DOUBLECLICKED)
1946 cfg.cursor_type = 2;
1949 if (HIWORD(wParam) == BN_CLICKED ||
1950 HIWORD(wParam) == BN_DOUBLECLICKED)
1952 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
1955 if (HIWORD(wParam) == BN_CLICKED ||
1956 HIWORD(wParam) == BN_DOUBLECLICKED)
1958 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
1961 if (HIWORD(wParam) == BN_CLICKED ||
1962 HIWORD(wParam) == BN_DOUBLECLICKED)
1964 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
1967 if (HIWORD(wParam) == EN_CHANGE)
1968 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
1969 sizeof(cfg.wintitle) - 1);
1974 if (HIWORD(wParam) == BN_CLICKED ||
1975 HIWORD(wParam) == BN_DOUBLECLICKED) {
1977 IsDlgButtonChecked(hwnd,
1978 IDC_COEALWAYS) ? COE_ALWAYS :
1979 IsDlgButtonChecked(hwnd,
1980 IDC_COENEVER) ? COE_NEVER :
1985 if (HIWORD(wParam) == BN_CLICKED ||
1986 HIWORD(wParam) == BN_DOUBLECLICKED)
1988 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
1991 if (HIWORD(wParam) == EN_CHANGE)
1992 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
1993 sizeof(cfg.termtype) - 1);
1996 if (HIWORD(wParam) == EN_CHANGE)
1997 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
1998 sizeof(cfg.logfilename) - 1);
2001 memset(&of, 0, sizeof(of));
2002 #ifdef OPENFILENAME_SIZE_VERSION_400
2003 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2005 of.lStructSize = sizeof(of);
2007 of.hwndOwner = hwnd;
2008 of.lpstrFilter = "All Files\0*\0\0\0";
2009 of.lpstrCustomFilter = NULL;
2010 of.nFilterIndex = 1;
2011 of.lpstrFile = filename;
2012 strcpy(filename, cfg.logfilename);
2013 of.nMaxFile = sizeof(filename);
2014 of.lpstrFileTitle = NULL;
2015 of.lpstrInitialDir = NULL;
2016 of.lpstrTitle = "Select session log file";
2018 if (GetSaveFileName(&of)) {
2019 strcpy(cfg.logfilename, filename);
2020 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2024 case IDC_LSTATASCII:
2026 if (HIWORD(wParam) == BN_CLICKED ||
2027 HIWORD(wParam) == BN_DOUBLECLICKED) {
2028 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2030 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2032 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2039 if (HIWORD(wParam) == BN_CLICKED ||
2040 HIWORD(wParam) == BN_DOUBLECLICKED) {
2041 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2042 cfg.logxfovr = LGXF_ASK;
2043 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2044 cfg.logxfovr = LGXF_APN;
2045 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2046 cfg.logxfovr = LGXF_OVR;
2051 if (HIWORD(wParam) == EN_CHANGE)
2052 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2053 sizeof(cfg.termspeed) - 1);
2056 if (HIWORD(wParam) == EN_CHANGE)
2057 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2058 sizeof(cfg.username) - 1);
2060 case IDC_RLLUSEREDIT:
2061 if (HIWORD(wParam) == EN_CHANGE)
2062 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2064 sizeof(cfg.localusername) - 1);
2068 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2072 cfg.passive_telnet =
2073 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2076 if (HIWORD(wParam) == BN_CLICKED ||
2077 HIWORD(wParam) == BN_DOUBLECLICKED) {
2078 char str[sizeof(cfg.environmt)];
2080 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2086 p = str + strlen(str);
2088 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2089 sizeof(str) - 1 - (p - str));
2100 if ((p - cfg.environmt) + strlen(str) + 2 <
2101 sizeof(cfg.environmt)) {
2103 p[strlen(str) + 1] = '\0';
2104 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2106 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2107 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2109 MessageBox(hwnd, "Environment too big",
2110 "PuTTY Error", MB_OK | MB_ICONERROR);
2115 if (HIWORD(wParam) != BN_CLICKED &&
2116 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2118 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2125 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2152 if (HIWORD(wParam) == BN_CLICKED ||
2153 HIWORD(wParam) == BN_DOUBLECLICKED)
2154 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2157 if (HIWORD(wParam) == BN_CLICKED ||
2158 HIWORD(wParam) == BN_DOUBLECLICKED)
2160 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2163 if (HIWORD(wParam) == BN_CLICKED ||
2164 HIWORD(wParam) == BN_DOUBLECLICKED)
2166 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2169 if (HIWORD(wParam) == BN_CLICKED ||
2170 HIWORD(wParam) == BN_DOUBLECLICKED)
2172 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2174 case IDC_CIPHER3DES:
2175 case IDC_CIPHERBLOWF:
2178 if (HIWORD(wParam) == BN_CLICKED ||
2179 HIWORD(wParam) == BN_DOUBLECLICKED) {
2180 if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES))
2181 cfg.cipher = CIPHER_3DES;
2182 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF))
2183 cfg.cipher = CIPHER_BLOWFISH;
2184 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES))
2185 cfg.cipher = CIPHER_DES;
2186 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES))
2187 cfg.cipher = CIPHER_AES;
2192 if (HIWORD(wParam) == BN_CLICKED ||
2193 HIWORD(wParam) == BN_DOUBLECLICKED) {
2194 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2196 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2201 if (HIWORD(wParam) == BN_CLICKED ||
2202 HIWORD(wParam) == BN_DOUBLECLICKED)
2204 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2207 if (HIWORD(wParam) == EN_CHANGE)
2208 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2209 sizeof(cfg.keyfile) - 1);
2212 if (HIWORD(wParam) == EN_CHANGE)
2213 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2214 sizeof(cfg.remote_cmd) - 1);
2217 memset(&of, 0, sizeof(of));
2218 #ifdef OPENFILENAME_SIZE_VERSION_400
2219 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2221 of.lStructSize = sizeof(of);
2223 of.hwndOwner = hwnd;
2224 of.lpstrFilter = "All Files\0*\0\0\0";
2225 of.lpstrCustomFilter = NULL;
2226 of.nFilterIndex = 1;
2227 of.lpstrFile = filename;
2228 strcpy(filename, cfg.keyfile);
2229 of.nMaxFile = sizeof(filename);
2230 of.lpstrFileTitle = NULL;
2231 of.lpstrInitialDir = NULL;
2232 of.lpstrTitle = "Select Public Key File";
2234 if (GetOpenFileName(&of)) {
2235 strcpy(cfg.keyfile, filename);
2236 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2240 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2243 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2249 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2254 for (i = 0; i < 128; i++)
2255 if (SendDlgItemMessage
2256 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2258 cfg.wordness[i] = n;
2259 SendDlgItemMessage(hwnd, IDC_CCLIST,
2260 LB_DELETESTRING, i, 0);
2261 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2262 (i >= 0x21 && i != 0x7F) ? i : ' ',
2264 SendDlgItemMessage(hwnd, IDC_CCLIST,
2271 case IDC_BOLDCOLOUR:
2272 if (HIWORD(wParam) == BN_CLICKED ||
2273 HIWORD(wParam) == BN_DOUBLECLICKED) {
2276 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2277 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2280 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2282 if (n != 12 + 10 * cfg.bold_colour) {
2283 for (i = n; i-- > 0;)
2284 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2285 LB_DELETESTRING, i, 0);
2286 for (i = 0; i < 22; i++)
2287 if (cfg.bold_colour || permcolour[i])
2288 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2290 (LPARAM) colours[i]);
2292 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2294 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2299 if (HIWORD(wParam) == BN_CLICKED ||
2300 HIWORD(wParam) == BN_DOUBLECLICKED)
2302 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2304 case IDC_COLOURLIST:
2305 if (HIWORD(wParam) == LBN_DBLCLK ||
2306 HIWORD(wParam) == LBN_SELCHANGE) {
2308 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2311 if (!cfg.bold_colour)
2312 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2313 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2315 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2317 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2322 if (HIWORD(wParam) == BN_CLICKED ||
2323 HIWORD(wParam) == BN_DOUBLECLICKED) {
2324 static CHOOSECOLOR cc;
2325 static DWORD custom[16] = { 0 }; /* zero initialisers */
2327 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2330 if (!cfg.bold_colour)
2331 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2332 cc.lStructSize = sizeof(cc);
2333 cc.hwndOwner = hwnd;
2334 cc.hInstance = (HWND) hinst;
2335 cc.lpCustColors = custom;
2337 RGB(cfg.colours[i][0], cfg.colours[i][1],
2339 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2340 if (ChooseColor(&cc)) {
2342 (unsigned char) (cc.rgbResult & 0xFF);
2344 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2346 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2347 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2349 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2351 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2357 if (HIWORD(wParam) == EN_CHANGE)
2358 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2359 sizeof(cfg.line_codepage) - 1);
2360 if (HIWORD(wParam) == EN_KILLFOCUS) {
2361 int cp = decode_codepage(cfg.line_codepage);
2366 "Unable to identify character set '%s', "
2367 "translation disabled.",
2371 "Character set '%s' is a DBCS, "
2372 "translation is not available.",
2374 MessageBox(hwnd, buf, "PuTTY Error",
2375 MB_ICONERROR | MB_OK);
2377 strcpy(cfg.line_codepage, cp_name(cp));
2378 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2381 case IDC_VTXWINDOWS:
2387 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2388 : IsDlgButtonChecked(hwnd,
2389 IDC_VTOEMANSI) ? VT_OEMANSI :
2390 IsDlgButtonChecked(hwnd,
2391 IDC_VTOEMONLY) ? VT_OEMONLY :
2392 IsDlgButtonChecked(hwnd,
2393 IDC_VTUNICODE) ? VT_UNICODE :
2396 case IDC_X11_FORWARD:
2397 if (HIWORD(wParam) == BN_CLICKED ||
2398 HIWORD(wParam) == BN_DOUBLECLICKED)
2400 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2402 case IDC_X11_DISPLAY:
2403 if (HIWORD(wParam) == EN_CHANGE)
2404 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2405 sizeof(cfg.x11_display) - 1);
2413 /* Grrr Explorer will maximize Dialogs! */
2415 if (wParam == SIZE_MAXIMIZED)
2422 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2423 WPARAM wParam, LPARAM lParam)
2425 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2427 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2428 EnableWindow(hwnd, 0);
2429 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2430 EnableWindow(hwnd, 1);
2431 SetActiveWindow(hwnd);
2433 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2436 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2437 WPARAM wParam, LPARAM lParam)
2439 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2442 void defuse_showwindow(void)
2445 * Work around the fact that the app's first call to ShowWindow
2446 * will ignore the default in favour of the shell-provided
2451 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2453 ShowWindow(hwnd, SW_HIDE);
2454 SetActiveWindow(hwnd);
2455 DestroyWindow(hwnd);
2464 savedsession[0] = '\0';
2466 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2467 get_sesslist(FALSE);
2472 int do_reconfig(HWND hwnd)
2477 backup_cfg = cfg; /* structure copy */
2479 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2481 cfg = backup_cfg; /* structure copy */
2486 void logevent(char *string)
2491 if (nevents >= negsize) {
2493 events = srealloc(events, negsize * sizeof(*events));
2497 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2500 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2501 strcpy(events[nevents], timebuf);
2502 strcat(events[nevents], string);
2505 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2506 0, (LPARAM) events[nevents]);
2507 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2508 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2513 void showeventlog(HWND hwnd)
2516 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2518 ShowWindow(logbox, SW_SHOWNORMAL);
2520 SetActiveWindow(logbox);
2523 void showabout(HWND hwnd)
2525 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2528 void verify_ssh_host_key(char *host, int port, char *keytype,
2529 char *keystr, char *fingerprint)
2533 static const char absentmsg[] =
2534 "The server's host key is not cached in the registry. You\n"
2535 "have no guarantee that the server is the computer you\n"
2537 "The server's key fingerprint is:\n"
2539 "If you trust this host, hit Yes to add the key to\n"
2540 "PuTTY's cache and carry on connecting.\n"
2541 "If you want to carry on connecting just once, without\n"
2542 "adding the key to the cache, hit No.\n"
2543 "If you do not trust this host, hit Cancel to abandon the\n"
2546 static const char wrongmsg[] =
2547 "WARNING - POTENTIAL SECURITY BREACH!\n"
2549 "The server's host key does not match the one PuTTY has\n"
2550 "cached in the registry. This means that either the\n"
2551 "server administrator has changed the host key, or you\n"
2552 "have actually connected to another computer pretending\n"
2553 "to be the server.\n"
2554 "The new key fingerprint is:\n"
2556 "If you were expecting this change and trust the new key,\n"
2557 "hit Yes to update PuTTY's cache and continue connecting.\n"
2558 "If you want to carry on connecting but without updating\n"
2559 "the cache, hit No.\n"
2560 "If you want to abandon the connection completely, hit\n"
2561 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2563 static const char mbtitle[] = "PuTTY Security Alert";
2566 /* sensible fingerprint max size */
2567 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2568 sizeof(absentmsg) : sizeof(wrongmsg))];
2571 * Verify the key against the registry.
2573 ret = verify_host_key(host, port, keytype, keystr);
2575 if (ret == 0) /* success - key matched OK */
2577 if (ret == 2) { /* key was different */
2579 sprintf(message, wrongmsg, fingerprint);
2580 mbret = MessageBox(NULL, message, mbtitle,
2581 MB_ICONWARNING | MB_YESNOCANCEL);
2583 store_host_key(host, port, keytype, keystr);
2584 if (mbret == IDCANCEL)
2587 if (ret == 1) { /* key was absent */
2589 sprintf(message, absentmsg, fingerprint);
2590 mbret = MessageBox(NULL, message, mbtitle,
2591 MB_ICONWARNING | MB_YESNOCANCEL);
2593 store_host_key(host, port, keytype, keystr);
2594 if (mbret == IDCANCEL)
2600 * Ask whether to wipe a session log file before writing to it.
2601 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2603 int askappend(char *filename)
2605 static const char mbtitle[] = "PuTTY Log to File";
2606 static const char msgtemplate[] =
2607 "The session log file \"%.*s\" already exists.\n"
2608 "You can overwrite it with a new session log,\n"
2609 "append your session log to the end of it,\n"
2610 "or disable session logging for this session.\n"
2611 "Hit Yes to wipe the file, No to append to it,\n"
2612 "or Cancel to disable logging.";
2613 char message[sizeof(msgtemplate) + FILENAME_MAX];
2615 if (cfg.logxfovr != LGXF_ASK) {
2616 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2618 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2620 mbret = MessageBox(NULL, message, mbtitle,
2621 MB_ICONQUESTION | MB_YESNOCANCEL);
2624 else if (mbret == IDNO)