15 static char **events = NULL;
16 static int nevents = 0, negsize = 0;
19 static int sesslist_has_focus;
21 static struct prefslist cipherlist;
23 void force_normal(HWND hwnd)
25 static int recurse = 0;
33 wp.length = sizeof(wp);
34 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
35 wp.showCmd = SW_SHOWNORMAL;
36 SetWindowPlacement(hwnd, &wp);
41 static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
45 n = GetDlgItemInt(hwnd, id, &ok, FALSE);
50 static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
54 ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
56 *result = (int) (scale * atof(text));
59 static void MySetDlgItemFlt(HWND hwnd, int id, double value)
62 sprintf(text, "%g", value);
63 SetDlgItemText(hwnd, id, text);
66 static int CALLBACK LogProc(HWND hwnd, UINT msg,
67 WPARAM wParam, LPARAM lParam)
74 static int tabs[4] = { 78, 108 };
75 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
78 for (i = 0; i < nevents; i++)
79 SendDlgItemMessage(hwnd, IDN_LIST, LB_ADDSTRING,
80 0, (LPARAM) events[i]);
83 switch (LOWORD(wParam)) {
87 SetActiveWindow(GetParent(hwnd));
91 if (HIWORD(wParam) == BN_CLICKED ||
92 HIWORD(wParam) == BN_DOUBLECLICKED) {
95 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
96 LB_GETSELCOUNT, 0, 0);
97 if (selcount == 0) { /* don't even try to copy zero items */
102 selitems = smalloc(selcount * sizeof(int));
104 int count = SendDlgItemMessage(hwnd, IDN_LIST,
111 static unsigned char sel_nl[] = SEL_NL;
113 if (count == 0) { /* can't copy zero stuff */
119 for (i = 0; i < count; i++)
121 strlen(events[selitems[i]]) + sizeof(sel_nl);
123 clipdata = smalloc(size);
126 for (i = 0; i < count; i++) {
127 char *q = events[selitems[i]];
128 int qlen = strlen(q);
131 memcpy(p, sel_nl, sizeof(sel_nl));
134 write_aclip(clipdata, size, TRUE);
139 for (i = 0; i < nevents; i++)
140 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
149 SetActiveWindow(GetParent(hwnd));
156 static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
157 WPARAM wParam, LPARAM lParam)
163 switch (LOWORD(wParam)) {
176 static int CALLBACK AboutProc(HWND hwnd, UINT msg,
177 WPARAM wParam, LPARAM lParam)
181 SetDlgItemText(hwnd, IDA_VERSION, ver);
184 switch (LOWORD(wParam)) {
187 EndDialog(hwnd, TRUE);
190 EnableWindow(hwnd, 0);
191 DialogBox(hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
193 EnableWindow(hwnd, 1);
194 SetActiveWindow(hwnd);
198 /* Load web browser */
199 ShellExecute(hwnd, "open",
200 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
201 0, 0, SW_SHOWDEFAULT);
206 EndDialog(hwnd, TRUE);
213 * Null dialog procedure.
215 static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
216 WPARAM wParam, LPARAM lParam)
221 static char savedsession[2048];
224 IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
362 IDC_SCROLLBARFULLSCREEN,
372 IDC_FULLSCREENONALTENTER,
375 appearancepanelstart,
376 IDC_TITLE_APPEARANCE,
398 connectionpanelstart,
399 IDC_TITLE_CONNECTION,
510 translationpanelstart,
511 IDC_TITLE_TRANSLATION,
512 IDC_BOX_TRANSLATION1,
513 IDC_BOX_TRANSLATION2,
514 IDC_BOX_TRANSLATION3,
551 static const char *const colours[] = {
552 "Default Foreground", "Default Bold Foreground",
553 "Default Background", "Default Bold Background",
554 "Cursor Text", "Cursor Colour",
555 "ANSI Black", "ANSI Black Bold",
556 "ANSI Red", "ANSI Red Bold",
557 "ANSI Green", "ANSI Green Bold",
558 "ANSI Yellow", "ANSI Yellow Bold",
559 "ANSI Blue", "ANSI Blue Bold",
560 "ANSI Magenta", "ANSI Magenta Bold",
561 "ANSI Cyan", "ANSI Cyan Bold",
562 "ANSI White", "ANSI White Bold"
564 static const int permcolour[] = {
565 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
566 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
567 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
570 static void fmtfont(char *buf)
572 sprintf(buf, "Font: %s, ", cfg.font);
574 strcat(buf, "bold, ");
575 if (cfg.fontheight == 0)
576 strcat(buf, "default height");
578 sprintf(buf + strlen(buf), "%d-point",
579 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
582 /* 2nd arg: NZ => don't redraw session list (use when loading
584 static void init_dlg_ctrls(HWND hwnd, int keepsess)
587 char fontstatic[256];
589 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
590 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
593 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
594 for (i = n; i-- > 0;)
595 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
596 for (i = 0; i < nsessions; i++)
597 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
598 0, (LPARAM) (sessions[i]));
600 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
601 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
602 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
603 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
605 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
606 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
608 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
609 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
610 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
611 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
612 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
613 cfg.funky_type == 0 ? IDC_FUNCTILDE :
614 cfg.funky_type == 1 ? IDC_FUNCLINUX :
615 cfg.funky_type == 2 ? IDC_FUNCXTERM :
616 cfg.funky_type == 3 ? IDC_FUNCVT400 :
617 cfg.funky_type == 4 ? IDC_FUNCVT100P :
618 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
619 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
620 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
621 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
622 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
623 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
624 cfg.nethack_keypad ? IDC_KPNH :
625 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
626 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
627 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
628 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
629 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
630 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
631 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
632 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
633 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
634 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
635 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
636 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
637 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
638 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
639 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
640 CheckDlgButton(hwnd, IDC_FULLSCREENONALTENTER, cfg.fullscreenonaltenter);
641 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
642 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
644 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
645 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
646 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
647 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
648 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
649 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
651 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
652 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
653 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
654 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
655 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
657 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
658 CheckRadioButton(hwnd, IDC_B_IND_DISABLED, IDC_B_IND_STEADY,
660 B_IND_DISABLED ? IDC_B_IND_DISABLED : cfg.beep_ind ==
661 B_IND_FLASH ? IDC_B_IND_FLASH : cfg.beep_ind ==
662 B_IND_STEADY ? IDC_B_IND_STEADY : IDC_B_IND_DISABLED);
663 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
664 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
665 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
666 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
667 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
669 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
670 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
672 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
673 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
674 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
675 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
676 SetDlgItemInt(hwnd, IDC_WINBEDIT, cfg.window_border, FALSE);
677 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
678 cfg.cursor_type == 0 ? IDC_CURBLOCK :
679 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
680 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
681 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
682 CheckDlgButton(hwnd, IDC_SCROLLBARFULLSCREEN, cfg.scrollbar_in_fullscreen);
683 CheckRadioButton(hwnd, IDC_RESIZETERM, IDC_RESIZENONE,
684 cfg.resize_action == RESIZE_TERM ? IDC_RESIZETERM :
685 cfg.resize_action == RESIZE_FONT ? IDC_RESIZEFONT :
687 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
688 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
690 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
691 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
693 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
694 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
695 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
696 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
697 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
698 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
699 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
700 cfg.logtype == 0 ? IDC_LSTATOFF :
701 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
702 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
703 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
704 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
707 char *p = cfg.environmt;
708 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_RESETCONTENT, 0, 0);
710 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
716 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING, 0,
721 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
722 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
723 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
724 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
726 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
727 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
728 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
729 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
730 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
731 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
732 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
733 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
734 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
735 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
736 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
740 static const struct { char *s; int c; } ciphers[] = {
741 { "3DES", CIPHER_3DES },
742 { "Blowfish", CIPHER_BLOWFISH },
743 { "DES (SSH 1 only)", CIPHER_DES },
744 { "AES (SSH 2 only)", CIPHER_AES },
745 { "-- warn below here --", CIPHER_WARN }
748 /* Set up the "selected ciphers" box. */
749 /* (cipherlist assumed to contain all ciphers) */
750 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_RESETCONTENT, 0, 0);
751 for (i = 0; i < CIPHER_MAX; i++) {
752 int c = cfg.ssh_cipherlist[i];
755 for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) {
756 if (ciphers[j].c == c) {
761 pos = SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_ADDSTRING,
763 SendDlgItemMessage(hwnd, IDC_CIPHERLIST, LB_SETITEMDATA,
769 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
770 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
771 CheckRadioButton(hwnd, IDC_SELTYPELEX, IDC_SELTYPERECT,
772 cfg.rect_select == 0 ? IDC_SELTYPELEX : IDC_SELTYPERECT);
773 CheckDlgButton(hwnd, IDC_MOUSEOVERRIDE, cfg.mouse_override);
774 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
776 static int tabs[4] = { 25, 61, 96, 128 };
777 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
780 for (i = 0; i < 128; i++) {
782 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
783 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
784 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
788 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
789 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
792 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
793 for (i = n; i-- > 0;)
794 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
795 LB_DELETESTRING, i, 0);
796 for (i = 0; i < 22; i++)
797 if (cfg.bold_colour || permcolour[i])
798 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
799 (LPARAM) colours[i]);
801 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
802 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
803 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
804 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
809 strcpy(cfg.line_codepage, cp_name(decode_codepage(cfg.line_codepage)));
810 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_RESETCONTENT, 0, 0);
811 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
812 for (i = 0; (cp = cp_enumerate(i)) != NULL; i++) {
813 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_ADDSTRING,
816 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
819 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
820 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
821 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
822 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
823 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
826 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
827 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
829 CheckDlgButton(hwnd, IDC_LPORT_ALL, cfg.lport_acceptall);
830 CheckRadioButton(hwnd, IDC_PFWDLOCAL, IDC_PFWDREMOTE, IDC_PFWDLOCAL);
833 struct treeview_faff {
838 static HTREEITEM treeview_insert(struct treeview_faff *faff,
839 int level, char *text)
844 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
845 ins.hInsertAfter = faff->lastat[level];
846 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
847 #define INSITEM DUMMYUNIONNAME.item
851 ins.INSITEM.mask = TVIF_TEXT;
852 ins.INSITEM.pszText = text;
853 newitem = TreeView_InsertItem(faff->treeview, &ins);
855 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
857 faff->lastat[level] = newitem;
858 for (i = level + 1; i < 4; i++)
859 faff->lastat[i] = NULL;
864 * Create the panelfuls of controls in the configuration box.
866 static void create_controls(HWND hwnd, int dlgtype, int panel)
868 if (panel == sessionpanelstart) {
869 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
871 ctlposinit(&cp, hwnd, 80, 3, 13);
872 bartitle(&cp, "Basic options for your PuTTY session",
875 beginbox(&cp, "Specify your connection by host name or IP address",
878 "Host &Name (or IP address)",
879 IDC_HOSTSTATIC, IDC_HOST, 75,
880 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
881 if (backends[3].backend == NULL) {
882 /* this is PuTTYtel, so only three protocols available */
883 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
885 "&Telnet", IDC_PROTTELNET,
886 "Rlog&in", IDC_PROTRLOGIN, NULL);
888 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
890 "&Telnet", IDC_PROTTELNET,
891 "Rlog&in", IDC_PROTRLOGIN,
900 beginbox(&cp, "Load, save or delete a stored session",
902 sesssaver(&cp, "Sav&ed Sessions",
903 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
904 "&Load", IDC_SESSLOAD,
905 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
908 beginbox(&cp, NULL, IDC_BOX_SESSION3);
909 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
910 "Always", IDC_COEALWAYS,
911 "Never", IDC_COENEVER,
912 "Only on clean exit", IDC_COENORMAL, NULL);
916 if (panel == loggingpanelstart) {
917 /* The Logging panel. Accelerators used: [acgo] tplfwe */
919 ctlposinit(&cp, hwnd, 80, 3, 13);
920 bartitle(&cp, "Options controlling session logging",
922 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
924 "Session logging:", IDC_LSTATSTATIC,
925 "Logging &turned off completely", IDC_LSTATOFF,
926 "Log &printable output only", IDC_LSTATASCII,
927 "&Log all session output", IDC_LSTATRAW, NULL);
928 editbutton(&cp, "Log &file name:",
929 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
931 statictext(&cp, "(Log file name can contain &&Y, &&M, &&D for date,"
932 " &&T for time, and &&H for host name)", 2, IDC_LGFEXPLAIN);
934 "What to do if the log file already &exists:",
935 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
936 "Always append to the end of it", IDC_LSTATXAPN,
937 "Ask the user every time", IDC_LSTATXASK, NULL);
941 if (panel == terminalpanelstart) {
942 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
944 ctlposinit(&cp, hwnd, 80, 3, 13);
945 bartitle(&cp, "Options controlling the terminal emulation",
947 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
948 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
949 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
950 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
951 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
952 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
954 "An&swerback to ^E:", IDC_ANSWERBACK,
955 IDC_ANSWEREDIT, 100, NULL);
958 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
959 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
960 "Auto", IDC_ECHOBACKEND,
961 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
962 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
963 "Auto", IDC_EDITBACKEND,
964 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
968 if (panel == bellpanelstart) {
969 /* The Bell panel. Accelerators used: [acgo] bdsm wit */
971 ctlposinit(&cp, hwnd, 80, 3, 13);
972 bartitle(&cp, "Options controlling the terminal bell",
974 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
976 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
977 "None (bell disabled)", IDC_BELL_DISABLED,
978 "Play Windows Default Sound", IDC_BELL_DEFAULT,
979 "Play a custom sound file", IDC_BELL_WAVEFILE,
980 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
981 editbutton(&cp, "Custom sound file to play as a bell:",
982 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
983 "Bro&wse...", IDC_BELL_WAVEBROWSE);
984 radioline(&cp, "Taskbar/caption &indication on bell:",
985 IDC_B_IND_STATIC, 3, "Disabled", IDC_B_IND_DISABLED,
986 "Flashing", IDC_B_IND_FLASH, "Steady", IDC_B_IND_STEADY,
989 beginbox(&cp, "Control the bell overload behaviour",
991 checkbox(&cp, "Bell is temporarily &disabled when over-used",
993 staticedit(&cp, "Over-use means this &many bells...",
994 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
995 staticedit(&cp, "... in &this many seconds",
996 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
998 "The bell is re-enabled after a few seconds of silence.",
999 1, IDC_BELLOVLEXPLAIN);
1000 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
1005 if (panel == keyboardpanelstart) {
1006 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
1008 ctlposinit(&cp, hwnd, 80, 3, 13);
1010 bartitle(&cp, "Options controlling the effects of keys",
1011 IDC_TITLE_KEYBOARD);
1013 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
1014 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
1015 "Control-H", IDC_DEL008,
1016 "Control-? (127)", IDC_DEL127, NULL);
1017 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
1018 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
1019 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
1020 "ESC[n~", IDC_FUNCTILDE,
1021 "Linux", IDC_FUNCLINUX,
1022 "Xterm R6", IDC_FUNCXTERM,
1023 "VT400", IDC_FUNCVT400,
1024 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
1026 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
1028 "Application c&ursor keys totally disabled",
1030 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
1031 "Normal", IDC_CURNORMAL,
1032 "Application", IDC_CURAPPLIC, NULL);
1034 "Application ke&ypad keys totally disabled",
1036 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
1037 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
1038 "NetHack", IDC_KPNH, NULL);
1040 beginbox(&cp, "Enable extra keyboard features:",
1042 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
1043 checkbox(&cp, "Control-Alt is &different from AltGr",
1048 if (panel == windowpanelstart) {
1049 /* The Window panel. Accelerators used: [acgo] rmznb sdikp w4ylt f */
1051 ctlposinit(&cp, hwnd, 80, 3, 13);
1052 bartitle(&cp, "Options controlling PuTTY's window",
1054 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
1056 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
1057 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
1058 radioline(&cp, "Action when the window is resized:", IDC_RESIZESTATIC,
1059 3, "Resi&ze terminal", IDC_RESIZETERM,
1060 "Change fo&nt", IDC_RESIZEFONT,
1061 "For&bid resizing", IDC_RESIZENONE, NULL);
1063 beginbox(&cp, "Control the scrollback in the window",
1065 staticedit(&cp, "Lines of &scrollback",
1066 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
1067 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
1068 checkbox(&cp, "D&isplay scrollbar in full screen mode", IDC_SCROLLBARFULLSCREEN);
1069 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
1070 checkbox(&cp, "Reset scrollback on dis&play activity",
1073 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
1074 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
1075 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
1076 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
1077 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
1078 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
1079 checkbox(&cp, "&Full screen on Alt-Enter", IDC_FULLSCREENONALTENTER);
1083 if (panel == appearancepanelstart) {
1084 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
1086 ctlposinit(&cp, hwnd, 80, 3, 13);
1087 /* bartitle(&cp, "Options controlling PuTTY's appearance",
1088 IDC_TITLE_APPEARANCE); */
1089 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
1090 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
1091 "B&lock", IDC_CURBLOCK,
1092 "&Underline", IDC_CURUNDER,
1093 "&Vertical line", IDC_CURVERT, NULL);
1094 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
1096 beginbox(&cp, "Set the font used in the terminal window",
1097 IDC_BOX_APPEARANCE2);
1098 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
1100 beginbox(&cp, "Adjust the use of the window title",
1101 IDC_BOX_APPEARANCE3);
1103 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
1104 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
1106 beginbox(&cp, "Adjust the use of the mouse pointer",
1107 IDC_BOX_APPEARANCE4);
1108 checkbox(&cp, "Hide mouse &pointer when typing in window",
1111 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
1112 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1114 staticedit(&cp, "Gap between text and window edge",
1115 IDC_WINBSTATIC, IDC_WINBEDIT, 20);
1119 if (panel == translationpanelstart) {
1120 /* The Translation panel. Accelerators used: [acgo] rxbepus */
1122 ctlposinit(&cp, hwnd, 80, 3, 13);
1123 bartitle(&cp, "Options controlling character set translation",
1124 IDC_TITLE_TRANSLATION);
1125 beginbox(&cp, "Character set translation on received data",
1126 IDC_BOX_TRANSLATION1);
1127 combobox(&cp, "&Received data assumed to be in which character set:",
1128 IDC_CODEPAGESTATIC, IDC_CODEPAGE);
1130 beginbox(&cp, "Enable character set translation on input data",
1131 IDC_BOX_TRANSLATION2);
1132 checkbox(&cp, "Cap&s Lock acts as Cyrillic switch",
1135 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1136 IDC_BOX_TRANSLATION3);
1138 "Handling of line drawing characters:", IDC_VTSTATIC,
1139 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1140 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1141 "Use font in O&EM mode only", IDC_VTOEMONLY,
1142 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1143 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1147 if (panel == selectionpanelstart) {
1148 /* The Selection panel. Accelerators used: [acgo] d wxp hst nr */
1150 ctlposinit(&cp, hwnd, 80, 3, 13);
1151 bartitle(&cp, "Options controlling copy and paste",
1152 IDC_TITLE_SELECTION);
1153 beginbox(&cp, "Translation of pasted characters",
1154 IDC_BOX_SELECTION1);
1156 "&Don't translate line drawing chars into +, - and |",
1159 beginbox(&cp, "Control which mouse button does which thing",
1160 IDC_BOX_SELECTION2);
1161 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1162 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1163 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1166 "Shift overrides a&pplication's use of mouse",
1169 "Default selection mode (Alt+drag does the other one):",
1170 IDC_SELTYPESTATIC, 2,
1171 "&Normal", IDC_SELTYPELEX,
1172 "&Rectangular block", IDC_SELTYPERECT, NULL);
1174 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1175 IDC_BOX_SELECTION3);
1176 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1177 "&Set", IDC_CCSET, IDC_CCEDIT,
1178 "&to class", IDC_CCSTATIC2);
1182 if (panel == colourspanelstart) {
1183 /* The Colours panel. Accelerators used: [acgo] blum */
1185 ctlposinit(&cp, hwnd, 80, 3, 13);
1186 bartitle(&cp, "Options controlling use of colours",
1188 beginbox(&cp, "General options for colour usage",
1190 checkbox(&cp, "&Bolded text is a different colour",
1192 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1194 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1196 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1197 IDC_COLOURSTATIC, IDC_COLOURLIST,
1198 "&Modify...", IDC_CHANGE,
1199 "Red:", IDC_RSTATIC, IDC_RVALUE,
1200 "Green:", IDC_GSTATIC, IDC_GVALUE,
1201 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1205 if (panel == connectionpanelstart) {
1206 /* The Connection panel. Accelerators used: [acgo] tuk */
1208 ctlposinit(&cp, hwnd, 80, 3, 13);
1209 bartitle(&cp, "Options controlling the connection",
1210 IDC_TITLE_CONNECTION);
1212 beginbox(&cp, "Data to send to the server",
1213 IDC_BOX_CONNECTION1);
1214 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1216 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1220 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1221 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1225 beginbox(&cp, "Sending of null packets to keep session active",
1226 IDC_BOX_CONNECTION2);
1227 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1228 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1232 if (panel == telnetpanelstart) {
1233 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1235 ctlposinit(&cp, hwnd, 80, 3, 13);
1237 bartitle(&cp, "Options controlling Telnet connections",
1239 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1240 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1242 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1243 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1244 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1245 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1247 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1248 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1249 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1250 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1251 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1252 "Passive", IDC_TPASSIVE, "Active",
1254 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1260 if (panel == rloginpanelstart) {
1261 /* The Rlogin panel. Accelerators used: [acgo] sl */
1263 ctlposinit(&cp, hwnd, 80, 3, 13);
1265 bartitle(&cp, "Options controlling Rlogin connections",
1267 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1268 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1270 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1271 IDC_RLLUSEREDIT, 50);
1276 if (panel == sshpanelstart) {
1277 /* The SSH panel. Accelerators used: [acgo] r pe12i s */
1279 ctlposinit(&cp, hwnd, 80, 3, 13);
1281 bartitle(&cp, "Options controlling SSH connections",
1283 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1285 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1288 beginbox(&cp, "Protocol options", IDC_BOX_SSH2);
1289 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1290 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1291 radioline(&cp, "Preferred SSH protocol version:",
1292 IDC_SSHPROTSTATIC, 2,
1293 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1294 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1297 beginbox(&cp, "Encryption options", IDC_BOX_SSH3);
1298 prefslist(&cipherlist, &cp, "Encryption cipher &selection policy:",
1299 IDC_CIPHERSTATIC2, IDC_CIPHERLIST, IDC_CIPHERUP,
1305 if (panel == sshauthpanelstart) {
1306 /* The SSH authentication panel. Accelerators used: [acgo] m fkw */
1308 ctlposinit(&cp, hwnd, 80, 3, 13);
1310 bartitle(&cp, "Options controlling SSH authentication",
1312 beginbox(&cp, "Authentication methods",
1314 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1317 beginbox(&cp, "Authentication parameters",
1319 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1320 editbutton(&cp, "Private &key file for authentication:",
1321 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1327 if (panel == tunnelspanelstart) {
1328 /* The Tunnels panel. Accelerators used: [acgo] deilmrstx */
1330 ctlposinit(&cp, hwnd, 80, 3, 13);
1332 bartitle(&cp, "Options controlling SSH tunnelling",
1334 beginbox(&cp, "X11 forwarding", IDC_BOX_TUNNELS1);
1335 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1336 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1337 IDC_X11_DISPLAY, 50, NULL);
1339 beginbox(&cp, "Port forwarding", IDC_BOX_TUNNELS2);
1340 checkbox(&cp, "Local ports accept connections from o&ther hosts", IDC_LPORT_ALL);
1341 staticbtn(&cp, "Forwarded ports:", IDC_PFWDSTATIC,
1342 "&Remove", IDC_PFWDREMOVE);
1343 fwdsetter(&cp, IDC_PFWDLIST,
1344 "Add new forwarded port:", IDC_PFWDSTATIC2,
1345 "&Source port", IDC_SPORTSTATIC, IDC_SPORTEDIT,
1346 "Dest&ination", IDC_DPORTSTATIC, IDC_DPORTEDIT,
1347 "A&dd", IDC_PFWDADD);
1348 bareradioline(&cp, 2,
1349 "&Local", IDC_PFWDLOCAL, "Re&mote", IDC_PFWDREMOTE, NULL);
1357 * Helper function to load the session selected in SESSLIST
1358 * if any, as this is done in more than one place in
1359 * GenericMainDlgProc(). 0 => failure.
1361 static int load_selected_session(HWND hwnd)
1363 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1364 LB_GETCURSEL, 0, 0);
1370 isdef = !strcmp(sessions[n], "Default Settings");
1371 load_settings(sessions[n], !isdef, &cfg);
1372 init_dlg_ctrls(hwnd, TRUE);
1374 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1376 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1377 /* Restore the selection, which will have been clobbered by
1378 * SESSEDIT handling. */
1379 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL, n, 0);
1384 * This function is the configuration box.
1386 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1387 WPARAM wParam, LPARAM lParam, int dlgtype)
1390 struct treeview_faff tvfaff;
1393 char filename[sizeof(cfg.keyfile)];
1396 char fontstatic[256];
1398 struct servent *service;
1400 static UINT draglistmsg = WM_NULL;
1405 SetWindowLong(hwnd, GWL_USERDATA, 0);
1406 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1407 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1409 * Centre the window.
1411 { /* centre the window */
1414 hw = GetDesktopWindow();
1415 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1417 (rs.right + rs.left + rd.left - rd.right) / 2,
1418 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1419 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1423 * Create the tree view.
1431 r.right = r.left + 75;
1433 r.bottom = r.top + 10;
1434 MapDialogRect(hwnd, &r);
1435 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1436 WS_CHILD | WS_VISIBLE,
1438 r.right - r.left, r.bottom - r.top,
1439 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1441 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1442 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1445 r.right = r.left + 75;
1447 r.bottom = r.top + 219;
1448 MapDialogRect(hwnd, &r);
1449 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1450 WS_CHILD | WS_VISIBLE |
1451 WS_TABSTOP | TVS_HASLINES |
1452 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1454 TVS_SHOWSELALWAYS, r.left, r.top,
1455 r.right - r.left, r.bottom - r.top,
1456 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1458 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1459 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1460 tvfaff.treeview = treeview;
1461 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1465 * Set up the tree view contents.
1467 hsession = treeview_insert(&tvfaff, 0, "Session");
1468 treeview_insert(&tvfaff, 1, "Logging");
1469 treeview_insert(&tvfaff, 0, "Terminal");
1470 treeview_insert(&tvfaff, 1, "Keyboard");
1471 treeview_insert(&tvfaff, 1, "Bell");
1472 treeview_insert(&tvfaff, 0, "Window");
1473 treeview_insert(&tvfaff, 1, "Appearance");
1474 treeview_insert(&tvfaff, 1, "Translation");
1475 treeview_insert(&tvfaff, 1, "Selection");
1476 treeview_insert(&tvfaff, 1, "Colours");
1477 treeview_insert(&tvfaff, 0, "Connection");
1479 treeview_insert(&tvfaff, 1, "Telnet");
1480 treeview_insert(&tvfaff, 1, "Rlogin");
1481 if (backends[3].backend != NULL) {
1482 treeview_insert(&tvfaff, 1, "SSH");
1483 /* XXX long name is ugly */
1484 /* XXX make it closed by default? */
1485 treeview_insert(&tvfaff, 2, "Auth");
1486 treeview_insert(&tvfaff, 2, "Tunnels");
1491 * Put the treeview selection on to the Session panel. This
1492 * should also cause creation of the relevant controls.
1494 TreeView_SelectItem(treeview, hsession);
1497 * Set focus into the first available control.
1501 ctl = GetDlgItem(hwnd, IDC_HOST);
1503 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1507 SetWindowLong(hwnd, GWL_USERDATA, 1);
1508 sesslist_has_focus = 0;
1512 * Button release should trigger WM_OK if there was a
1513 * previous double click on the session list.
1517 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1520 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1521 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1523 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1528 SendMessage (hwnd, WM_SETREDRAW, FALSE, 0);
1531 item.pszText = buffer;
1532 item.cchTextMax = sizeof(buffer);
1533 item.mask = TVIF_TEXT;
1534 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1535 for (j = controlstartvalue; j < controlendvalue; j++) {
1536 HWND item = GetDlgItem(hwnd, j);
1538 DestroyWindow(item);
1540 if (!strcmp(buffer, "Session"))
1541 create_controls(hwnd, dlgtype, sessionpanelstart);
1542 if (!strcmp(buffer, "Logging"))
1543 create_controls(hwnd, dlgtype, loggingpanelstart);
1544 if (!strcmp(buffer, "Keyboard"))
1545 create_controls(hwnd, dlgtype, keyboardpanelstart);
1546 if (!strcmp(buffer, "Terminal"))
1547 create_controls(hwnd, dlgtype, terminalpanelstart);
1548 if (!strcmp(buffer, "Bell"))
1549 create_controls(hwnd, dlgtype, bellpanelstart);
1550 if (!strcmp(buffer, "Window"))
1551 create_controls(hwnd, dlgtype, windowpanelstart);
1552 if (!strcmp(buffer, "Appearance"))
1553 create_controls(hwnd, dlgtype, appearancepanelstart);
1554 if (!strcmp(buffer, "Tunnels"))
1555 create_controls(hwnd, dlgtype, tunnelspanelstart);
1556 if (!strcmp(buffer, "Connection"))
1557 create_controls(hwnd, dlgtype, connectionpanelstart);
1558 if (!strcmp(buffer, "Telnet"))
1559 create_controls(hwnd, dlgtype, telnetpanelstart);
1560 if (!strcmp(buffer, "Rlogin"))
1561 create_controls(hwnd, dlgtype, rloginpanelstart);
1562 if (!strcmp(buffer, "SSH"))
1563 create_controls(hwnd, dlgtype, sshpanelstart);
1564 if (!strcmp(buffer, "Auth"))
1565 create_controls(hwnd, dlgtype, sshauthpanelstart);
1566 if (!strcmp(buffer, "Selection"))
1567 create_controls(hwnd, dlgtype, selectionpanelstart);
1568 if (!strcmp(buffer, "Colours"))
1569 create_controls(hwnd, dlgtype, colourspanelstart);
1570 if (!strcmp(buffer, "Translation"))
1571 create_controls(hwnd, dlgtype, translationpanelstart);
1573 init_dlg_ctrls(hwnd, FALSE);
1575 SendMessage (hwnd, WM_SETREDRAW, TRUE, 0);
1576 InvalidateRect (hwnd, NULL, TRUE);
1578 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1584 * Only process WM_COMMAND once the dialog is fully formed.
1586 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1587 switch (LOWORD(wParam)) {
1589 /* Behaviour of the "Open" button is different if the
1590 * session list has focus, *unless* the user just
1591 * double-clicked... */
1592 if (sesslist_has_focus && !readytogo) {
1593 if (!load_selected_session(hwnd)) {
1598 /* If at this point we have a valid session, go! */
1607 case IDC_PROTTELNET:
1608 case IDC_PROTRLOGIN:
1611 if (HIWORD(wParam) == BN_CLICKED ||
1612 HIWORD(wParam) == BN_DOUBLECLICKED) {
1613 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1614 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1615 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1617 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1619 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1620 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1621 || (cfg.protocol == PROT_RLOGIN
1622 && cfg.port != 513)) {
1623 cfg.port = i ? 22 : j ? 23 : 513;
1624 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1629 if (HIWORD(wParam) == EN_CHANGE)
1630 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1631 sizeof(cfg.host) - 1);
1634 if (HIWORD(wParam) == EN_CHANGE) {
1635 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1636 if (isdigit(portname[0]))
1637 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1639 service = getservbyname(portname, NULL);
1641 cfg.port = ntohs(service->s_port);
1648 if (HIWORD(wParam) == EN_CHANGE) {
1649 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1651 GetDlgItemText(hwnd, IDC_SESSEDIT,
1652 savedsession, sizeof(savedsession) - 1);
1653 savedsession[sizeof(savedsession) - 1] = '\0';
1657 if (HIWORD(wParam) == BN_CLICKED ||
1658 HIWORD(wParam) == BN_DOUBLECLICKED) {
1663 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1666 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1667 LB_GETCURSEL, 0, 0);
1672 strcpy(str, sessions[n]);
1674 save_settings(str, !!strcmp(str, "Default Settings"),
1676 get_sesslist(FALSE);
1678 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1680 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1682 for (i = 0; i < nsessions; i++)
1683 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1685 (LPARAM) (sessions[i]));
1686 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1688 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1690 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1696 if (LOWORD(wParam) == IDC_SESSLIST) {
1697 if (HIWORD(wParam) == LBN_SETFOCUS)
1698 sesslist_has_focus = 1;
1699 else if (HIWORD(wParam) == LBN_KILLFOCUS)
1700 sesslist_has_focus = 0;
1702 if (LOWORD(wParam) == IDC_SESSLOAD &&
1703 HIWORD(wParam) != BN_CLICKED &&
1704 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1705 if (LOWORD(wParam) == IDC_SESSLIST &&
1706 HIWORD(wParam) != LBN_DBLCLK) break;
1707 /* Load the session selected in SESSLIST. */
1708 if (load_selected_session(hwnd) &&
1709 LOWORD(wParam) == IDC_SESSLIST) {
1711 * A double-click on a saved session should
1712 * actually start the session, not just load it.
1713 * Unless it's Default Settings or some other
1714 * host-less set of saved settings.
1723 if (HIWORD(wParam) == BN_CLICKED ||
1724 HIWORD(wParam) == BN_DOUBLECLICKED) {
1725 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1726 LB_GETCURSEL, 0, 0);
1727 if (n == LB_ERR || n == 0) {
1731 del_settings(sessions[n]);
1732 get_sesslist(FALSE);
1734 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1736 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1738 for (i = 0; i < nsessions; i++)
1739 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1741 (LPARAM) (sessions[i]));
1742 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1744 SendDlgItemMessage(hwnd, IDC_SESSLIST, WM_SETREDRAW,
1746 InvalidateRect(GetDlgItem(hwnd, IDC_SESSLIST), NULL,
1750 if (HIWORD(wParam) == EN_CHANGE)
1751 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1752 &cfg.ping_interval);
1756 if (HIWORD(wParam) == BN_CLICKED ||
1757 HIWORD(wParam) == BN_DOUBLECLICKED)
1758 cfg.bksp_is_delete =
1759 IsDlgButtonChecked(hwnd, IDC_DEL127);
1763 if (HIWORD(wParam) == BN_CLICKED ||
1764 HIWORD(wParam) == BN_DOUBLECLICKED)
1766 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1772 case IDC_FUNCVT100P:
1774 if (HIWORD(wParam) == BN_CLICKED ||
1775 HIWORD(wParam) == BN_DOUBLECLICKED)
1776 switch (LOWORD(wParam)) {
1789 case IDC_FUNCVT100P:
1799 if (HIWORD(wParam) == BN_CLICKED ||
1800 HIWORD(wParam) == BN_DOUBLECLICKED) {
1802 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1803 cfg.nethack_keypad = FALSE;
1807 if (HIWORD(wParam) == BN_CLICKED ||
1808 HIWORD(wParam) == BN_DOUBLECLICKED) {
1809 cfg.app_keypad = FALSE;
1810 cfg.nethack_keypad = TRUE;
1815 if (HIWORD(wParam) == BN_CLICKED ||
1816 HIWORD(wParam) == BN_DOUBLECLICKED)
1818 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1821 if (HIWORD(wParam) == BN_CLICKED ||
1822 HIWORD(wParam) == BN_DOUBLECLICKED)
1824 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1827 if (HIWORD(wParam) == BN_CLICKED ||
1828 HIWORD(wParam) == BN_DOUBLECLICKED)
1830 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1833 if (HIWORD(wParam) == BN_CLICKED ||
1834 HIWORD(wParam) == BN_DOUBLECLICKED)
1835 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1838 if (HIWORD(wParam) == BN_CLICKED ||
1839 HIWORD(wParam) == BN_DOUBLECLICKED)
1841 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1844 if (HIWORD(wParam) == BN_CLICKED ||
1845 HIWORD(wParam) == BN_DOUBLECLICKED)
1847 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1849 case IDC_ECHOBACKEND:
1852 if (HIWORD(wParam) == BN_CLICKED ||
1853 HIWORD(wParam) == BN_DOUBLECLICKED) {
1854 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1855 cfg.localecho = LD_BACKEND;
1856 if (LOWORD(wParam) == IDC_ECHOYES)
1857 cfg.localecho = LD_YES;
1858 if (LOWORD(wParam) == IDC_ECHONO)
1859 cfg.localecho = LD_NO;
1862 case IDC_EDITBACKEND:
1865 if (HIWORD(wParam) == BN_CLICKED ||
1866 HIWORD(wParam) == BN_DOUBLECLICKED) {
1867 if (LOWORD(wParam) == IDC_EDITBACKEND)
1868 cfg.localedit = LD_BACKEND;
1869 if (LOWORD(wParam) == IDC_EDITYES)
1870 cfg.localedit = LD_YES;
1871 if (LOWORD(wParam) == IDC_EDITNO)
1872 cfg.localedit = LD_NO;
1875 case IDC_ANSWEREDIT:
1876 if (HIWORD(wParam) == EN_CHANGE)
1877 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1878 sizeof(cfg.answerback) - 1);
1880 case IDC_ALWAYSONTOP:
1881 if (HIWORD(wParam) == BN_CLICKED ||
1882 HIWORD(wParam) == BN_DOUBLECLICKED)
1884 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1886 case IDC_FULLSCREENONALTENTER:
1887 if (HIWORD(wParam) == BN_CLICKED ||
1888 HIWORD(wParam) == BN_DOUBLECLICKED)
1889 cfg.fullscreenonaltenter =
1890 IsDlgButtonChecked(hwnd, IDC_FULLSCREENONALTENTER);
1893 if (HIWORD(wParam) == BN_CLICKED ||
1894 HIWORD(wParam) == BN_DOUBLECLICKED)
1896 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1898 case IDC_SCROLLDISP:
1899 if (HIWORD(wParam) == BN_CLICKED ||
1900 HIWORD(wParam) == BN_DOUBLECLICKED)
1901 cfg.scroll_on_disp =
1902 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1904 case IDC_COMPOSEKEY:
1905 if (HIWORD(wParam) == BN_CLICKED ||
1906 HIWORD(wParam) == BN_DOUBLECLICKED)
1908 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1910 case IDC_CTRLALTKEYS:
1911 if (HIWORD(wParam) == BN_CLICKED ||
1912 HIWORD(wParam) == BN_DOUBLECLICKED)
1914 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1917 if (HIWORD(wParam) == BN_CLICKED ||
1918 HIWORD(wParam) == BN_DOUBLECLICKED)
1919 cfg.telnet_keyboard =
1920 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1923 if (HIWORD(wParam) == BN_CLICKED ||
1924 HIWORD(wParam) == BN_DOUBLECLICKED)
1926 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1929 if (HIWORD(wParam) == BN_CLICKED ||
1930 HIWORD(wParam) == BN_DOUBLECLICKED)
1931 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1934 if (HIWORD(wParam) == BN_CLICKED ||
1935 HIWORD(wParam) == BN_DOUBLECLICKED)
1937 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1940 if (HIWORD(wParam) == EN_CHANGE)
1941 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1944 if (HIWORD(wParam) == EN_CHANGE)
1945 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1948 if (HIWORD(wParam) == EN_CHANGE)
1949 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1951 case IDC_CHOOSEFONT:
1954 lf.lfHeight = -MulDiv(cfg.fontheight,
1955 GetDeviceCaps(hdc, LOGPIXELSY),
1959 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1960 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1961 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1962 lf.lfCharSet = cfg.fontcharset;
1963 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1964 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1965 lf.lfQuality = DEFAULT_QUALITY;
1966 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1967 strncpy(lf.lfFaceName, cfg.font,
1968 sizeof(lf.lfFaceName) - 1);
1969 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1971 cf.lStructSize = sizeof(cf);
1972 cf.hwndOwner = hwnd;
1974 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1975 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1977 if (ChooseFont(&cf)) {
1978 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1979 cfg.font[sizeof(cfg.font) - 1] = '\0';
1980 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1981 cfg.fontcharset = lf.lfCharSet;
1982 cfg.fontheight = cf.iPointSize / 10;
1983 fmtfont(fontstatic);
1984 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1987 case IDC_BELL_DISABLED:
1988 case IDC_BELL_DEFAULT:
1989 case IDC_BELL_WAVEFILE:
1990 case IDC_BELL_VISUAL:
1991 if (HIWORD(wParam) == BN_CLICKED ||
1992 HIWORD(wParam) == BN_DOUBLECLICKED) {
1993 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1994 cfg.beep = BELL_DISABLED;
1995 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1996 cfg.beep = BELL_DEFAULT;
1997 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1998 cfg.beep = BELL_WAVEFILE;
1999 if (LOWORD(wParam) == IDC_BELL_VISUAL)
2000 cfg.beep = BELL_VISUAL;
2003 case IDC_B_IND_DISABLED:
2004 case IDC_B_IND_FLASH:
2005 case IDC_B_IND_STEADY:
2006 if (HIWORD(wParam) == BN_CLICKED ||
2007 HIWORD(wParam) == BN_DOUBLECLICKED) {
2008 if (LOWORD(wParam) == IDC_B_IND_DISABLED)
2009 cfg.beep_ind = B_IND_DISABLED;
2010 if (LOWORD(wParam) == IDC_B_IND_FLASH)
2011 cfg.beep_ind = B_IND_FLASH;
2012 if (LOWORD(wParam) == IDC_B_IND_STEADY)
2013 cfg.beep_ind = B_IND_STEADY;
2016 case IDC_BELL_WAVEBROWSE:
2017 memset(&of, 0, sizeof(of));
2018 #ifdef OPENFILENAME_SIZE_VERSION_400
2019 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2021 of.lStructSize = sizeof(of);
2023 of.hwndOwner = hwnd;
2024 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
2025 of.lpstrCustomFilter = NULL;
2026 of.nFilterIndex = 1;
2027 of.lpstrFile = filename;
2028 strcpy(filename, cfg.bell_wavefile);
2029 of.nMaxFile = sizeof(filename);
2030 of.lpstrFileTitle = NULL;
2031 of.lpstrInitialDir = NULL;
2032 of.lpstrTitle = "Select Bell Sound File";
2034 if (GetOpenFileName(&of)) {
2035 strcpy(cfg.bell_wavefile, filename);
2036 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2040 case IDC_BELL_WAVEEDIT:
2041 if (HIWORD(wParam) == EN_CHANGE)
2042 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
2044 sizeof(cfg.bell_wavefile) - 1);
2047 if (HIWORD(wParam) == BN_CLICKED ||
2048 HIWORD(wParam) == BN_DOUBLECLICKED)
2050 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
2053 if (HIWORD(wParam) == EN_CHANGE)
2054 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
2057 if (HIWORD(wParam) == EN_CHANGE)
2058 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
2062 if (HIWORD(wParam) == EN_CHANGE)
2063 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
2067 if (HIWORD(wParam) == BN_CLICKED ||
2068 HIWORD(wParam) == BN_DOUBLECLICKED)
2070 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
2073 if (HIWORD(wParam) == BN_CLICKED ||
2074 HIWORD(wParam) == BN_DOUBLECLICKED)
2075 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
2078 if (HIWORD(wParam) == BN_CLICKED ||
2079 HIWORD(wParam) == BN_DOUBLECLICKED)
2080 cfg.win_name_always =
2081 IsDlgButtonChecked(hwnd, IDC_WINNAME);
2084 if (HIWORD(wParam) == BN_CLICKED ||
2085 HIWORD(wParam) == BN_DOUBLECLICKED)
2087 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
2089 case IDC_SUNKENEDGE:
2090 if (HIWORD(wParam) == BN_CLICKED ||
2091 HIWORD(wParam) == BN_DOUBLECLICKED)
2093 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
2096 if (HIWORD(wParam) == EN_CHANGE)
2097 MyGetDlgItemInt(hwnd, IDC_WINBEDIT,
2098 &cfg.window_border);
2099 if (cfg.window_border > 32)
2100 cfg.window_border = 32;
2103 if (HIWORD(wParam) == BN_CLICKED ||
2104 HIWORD(wParam) == BN_DOUBLECLICKED)
2105 cfg.cursor_type = 0;
2108 if (HIWORD(wParam) == BN_CLICKED ||
2109 HIWORD(wParam) == BN_DOUBLECLICKED)
2110 cfg.cursor_type = 1;
2113 if (HIWORD(wParam) == BN_CLICKED ||
2114 HIWORD(wParam) == BN_DOUBLECLICKED)
2115 cfg.cursor_type = 2;
2118 if (HIWORD(wParam) == BN_CLICKED ||
2119 HIWORD(wParam) == BN_DOUBLECLICKED)
2121 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
2124 if (HIWORD(wParam) == BN_CLICKED ||
2125 HIWORD(wParam) == BN_DOUBLECLICKED)
2127 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
2129 case IDC_SCROLLBARFULLSCREEN:
2130 if (HIWORD(wParam) == BN_CLICKED ||
2131 HIWORD(wParam) == BN_DOUBLECLICKED)
2132 cfg.scrollbar_in_fullscreen =
2133 IsDlgButtonChecked(hwnd, IDC_SCROLLBARFULLSCREEN);
2135 case IDC_RESIZETERM:
2136 case IDC_RESIZEFONT:
2137 case IDC_RESIZENONE:
2138 if (HIWORD(wParam) == BN_CLICKED ||
2139 HIWORD(wParam) == BN_DOUBLECLICKED) {
2141 IsDlgButtonChecked(hwnd,
2142 IDC_RESIZETERM) ? RESIZE_TERM :
2143 IsDlgButtonChecked(hwnd,
2144 IDC_RESIZEFONT) ? RESIZE_FONT :
2149 if (HIWORD(wParam) == EN_CHANGE)
2150 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
2151 sizeof(cfg.wintitle) - 1);
2156 if (HIWORD(wParam) == BN_CLICKED ||
2157 HIWORD(wParam) == BN_DOUBLECLICKED) {
2159 IsDlgButtonChecked(hwnd,
2160 IDC_COEALWAYS) ? COE_ALWAYS :
2161 IsDlgButtonChecked(hwnd,
2162 IDC_COENEVER) ? COE_NEVER :
2167 if (HIWORD(wParam) == BN_CLICKED ||
2168 HIWORD(wParam) == BN_DOUBLECLICKED)
2170 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
2173 if (HIWORD(wParam) == EN_CHANGE)
2174 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
2175 sizeof(cfg.termtype) - 1);
2178 if (HIWORD(wParam) == EN_CHANGE)
2179 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
2180 sizeof(cfg.logfilename) - 1);
2183 memset(&of, 0, sizeof(of));
2184 #ifdef OPENFILENAME_SIZE_VERSION_400
2185 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2187 of.lStructSize = sizeof(of);
2189 of.hwndOwner = hwnd;
2190 of.lpstrFilter = "All Files\0*\0\0\0";
2191 of.lpstrCustomFilter = NULL;
2192 of.nFilterIndex = 1;
2193 of.lpstrFile = filename;
2194 strcpy(filename, cfg.logfilename);
2195 of.nMaxFile = sizeof(filename);
2196 of.lpstrFileTitle = NULL;
2197 of.lpstrInitialDir = NULL;
2198 of.lpstrTitle = "Select session log file";
2200 if (GetSaveFileName(&of)) {
2201 strcpy(cfg.logfilename, filename);
2202 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
2206 case IDC_LSTATASCII:
2208 if (HIWORD(wParam) == BN_CLICKED ||
2209 HIWORD(wParam) == BN_DOUBLECLICKED) {
2210 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
2212 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
2214 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
2221 if (HIWORD(wParam) == BN_CLICKED ||
2222 HIWORD(wParam) == BN_DOUBLECLICKED) {
2223 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
2224 cfg.logxfovr = LGXF_ASK;
2225 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
2226 cfg.logxfovr = LGXF_APN;
2227 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
2228 cfg.logxfovr = LGXF_OVR;
2233 if (HIWORD(wParam) == EN_CHANGE)
2234 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
2235 sizeof(cfg.termspeed) - 1);
2238 if (HIWORD(wParam) == EN_CHANGE)
2239 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
2240 sizeof(cfg.username) - 1);
2242 case IDC_RLLUSEREDIT:
2243 if (HIWORD(wParam) == EN_CHANGE)
2244 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
2246 sizeof(cfg.localusername) - 1);
2250 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2254 cfg.passive_telnet =
2255 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2258 if (HIWORD(wParam) == BN_CLICKED ||
2259 HIWORD(wParam) == BN_DOUBLECLICKED) {
2260 char str[sizeof(cfg.environmt)];
2262 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2268 p = str + strlen(str);
2270 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2271 sizeof(str) - 1 - (p - str));
2282 if ((p - cfg.environmt) + strlen(str) + 2 <
2283 sizeof(cfg.environmt)) {
2285 p[strlen(str) + 1] = '\0';
2286 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2288 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2289 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2291 MessageBox(hwnd, "Environment too big",
2292 "PuTTY Error", MB_OK | MB_ICONERROR);
2297 if (HIWORD(wParam) != BN_CLICKED &&
2298 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2300 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2307 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2334 if (HIWORD(wParam) == BN_CLICKED ||
2335 HIWORD(wParam) == BN_DOUBLECLICKED)
2336 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2339 if (HIWORD(wParam) == BN_CLICKED ||
2340 HIWORD(wParam) == BN_DOUBLECLICKED)
2342 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2345 if (HIWORD(wParam) == BN_CLICKED ||
2346 HIWORD(wParam) == BN_DOUBLECLICKED)
2348 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2351 if (HIWORD(wParam) == BN_CLICKED ||
2352 HIWORD(wParam) == BN_DOUBLECLICKED)
2354 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2356 case IDC_CIPHERLIST:
2359 handle_prefslist(&cipherlist,
2360 cfg.ssh_cipherlist, CIPHER_MAX,
2361 0, hwnd, wParam, lParam);
2365 if (HIWORD(wParam) == BN_CLICKED ||
2366 HIWORD(wParam) == BN_DOUBLECLICKED) {
2367 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2369 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2374 if (HIWORD(wParam) == BN_CLICKED ||
2375 HIWORD(wParam) == BN_DOUBLECLICKED)
2377 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2380 if (HIWORD(wParam) == EN_CHANGE)
2381 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2382 sizeof(cfg.keyfile) - 1);
2385 if (HIWORD(wParam) == EN_CHANGE)
2386 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2387 sizeof(cfg.remote_cmd) - 1);
2390 memset(&of, 0, sizeof(of));
2391 #ifdef OPENFILENAME_SIZE_VERSION_400
2392 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2394 of.lStructSize = sizeof(of);
2396 of.hwndOwner = hwnd;
2397 of.lpstrFilter = "All Files\0*\0\0\0";
2398 of.lpstrCustomFilter = NULL;
2399 of.nFilterIndex = 1;
2400 of.lpstrFile = filename;
2401 strcpy(filename, cfg.keyfile);
2402 of.nMaxFile = sizeof(filename);
2403 of.lpstrFileTitle = NULL;
2404 of.lpstrInitialDir = NULL;
2405 of.lpstrTitle = "Select Private Key File";
2407 if (GetOpenFileName(&of)) {
2408 strcpy(cfg.keyfile, filename);
2409 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2413 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2417 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2419 case IDC_SELTYPELEX:
2420 case IDC_SELTYPERECT:
2421 cfg.rect_select = IsDlgButtonChecked(hwnd, IDC_SELTYPERECT);
2423 case IDC_MOUSEOVERRIDE:
2424 cfg.mouse_override = IsDlgButtonChecked(hwnd, IDC_MOUSEOVERRIDE);
2430 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2435 for (i = 0; i < 128; i++)
2436 if (SendDlgItemMessage
2437 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2439 cfg.wordness[i] = n;
2440 SendDlgItemMessage(hwnd, IDC_CCLIST,
2441 LB_DELETESTRING, i, 0);
2442 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2443 (i >= 0x21 && i != 0x7F) ? i : ' ',
2445 SendDlgItemMessage(hwnd, IDC_CCLIST,
2452 case IDC_BOLDCOLOUR:
2453 if (HIWORD(wParam) == BN_CLICKED ||
2454 HIWORD(wParam) == BN_DOUBLECLICKED) {
2457 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2458 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2461 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2463 if (n != 12 + 10 * cfg.bold_colour) {
2464 for (i = n; i-- > 0;)
2465 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2466 LB_DELETESTRING, i, 0);
2467 for (i = 0; i < 22; i++)
2468 if (cfg.bold_colour || permcolour[i])
2469 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2471 (LPARAM) colours[i]);
2473 SendDlgItemMessage(hwnd, IDC_COLOURLIST, WM_SETREDRAW,
2475 InvalidateRect(GetDlgItem(hwnd, IDC_COLOURLIST), NULL,
2480 if (HIWORD(wParam) == BN_CLICKED ||
2481 HIWORD(wParam) == BN_DOUBLECLICKED)
2483 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2485 case IDC_COLOURLIST:
2486 if (HIWORD(wParam) == LBN_DBLCLK ||
2487 HIWORD(wParam) == LBN_SELCHANGE) {
2489 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2492 if (!cfg.bold_colour)
2493 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2494 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2496 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2498 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2503 if (HIWORD(wParam) == BN_CLICKED ||
2504 HIWORD(wParam) == BN_DOUBLECLICKED) {
2505 static CHOOSECOLOR cc;
2506 static DWORD custom[16] = { 0 }; /* zero initialisers */
2508 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2511 if (!cfg.bold_colour)
2512 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2513 cc.lStructSize = sizeof(cc);
2514 cc.hwndOwner = hwnd;
2515 cc.hInstance = (HWND) hinst;
2516 cc.lpCustColors = custom;
2518 RGB(cfg.colours[i][0], cfg.colours[i][1],
2520 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2521 if (ChooseColor(&cc)) {
2523 (unsigned char) (cc.rgbResult & 0xFF);
2525 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2527 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2528 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2530 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2532 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2538 if (HIWORD(wParam) == CBN_SELCHANGE) {
2539 int index = SendDlgItemMessage(hwnd, IDC_CODEPAGE,
2540 CB_GETCURSEL, 0, 0);
2541 SendDlgItemMessage(hwnd, IDC_CODEPAGE, CB_GETLBTEXT,
2542 index, (LPARAM)cfg.line_codepage);
2543 } else if (HIWORD(wParam) == CBN_EDITCHANGE) {
2544 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2545 sizeof(cfg.line_codepage) - 1);
2546 } else if (HIWORD(wParam) == CBN_KILLFOCUS) {
2547 strcpy(cfg.line_codepage,
2548 cp_name(decode_codepage(cfg.line_codepage)));
2549 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2552 case IDC_CAPSLOCKCYR:
2553 if (HIWORD(wParam) == BN_CLICKED ||
2554 HIWORD(wParam) == BN_DOUBLECLICKED) {
2555 cfg.xlat_capslockcyr =
2556 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
2559 case IDC_VTXWINDOWS:
2565 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2566 : IsDlgButtonChecked(hwnd,
2567 IDC_VTOEMANSI) ? VT_OEMANSI :
2568 IsDlgButtonChecked(hwnd,
2569 IDC_VTOEMONLY) ? VT_OEMONLY :
2570 IsDlgButtonChecked(hwnd,
2571 IDC_VTUNICODE) ? VT_UNICODE :
2574 case IDC_X11_FORWARD:
2575 if (HIWORD(wParam) == BN_CLICKED ||
2576 HIWORD(wParam) == BN_DOUBLECLICKED)
2578 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2581 if (HIWORD(wParam) == BN_CLICKED ||
2582 HIWORD(wParam) == BN_DOUBLECLICKED)
2583 cfg.lport_acceptall =
2584 IsDlgButtonChecked(hwnd, IDC_LPORT_ALL);
2586 case IDC_X11_DISPLAY:
2587 if (HIWORD(wParam) == EN_CHANGE)
2588 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2589 sizeof(cfg.x11_display) - 1);
2592 if (HIWORD(wParam) == BN_CLICKED ||
2593 HIWORD(wParam) == BN_DOUBLECLICKED) {
2594 char str[sizeof(cfg.portfwd)];
2596 if (IsDlgButtonChecked(hwnd, IDC_PFWDLOCAL))
2600 GetDlgItemText(hwnd, IDC_SPORTEDIT, str+1,
2604 "You need to specify a source port number",
2605 "PuTTY Error", MB_OK | MB_ICONERROR);
2608 p = str + strlen(str);
2610 GetDlgItemText(hwnd, IDC_DPORTEDIT, p,
2611 sizeof(str) - 1 - (p - str));
2612 if (!*p || !strchr(p, ':')) {
2614 "You need to specify a destination address\n"
2615 "in the form \"host.name:port\"",
2616 "PuTTY Error", MB_OK | MB_ICONERROR);
2625 if ((p - cfg.portfwd) + strlen(str) + 2 <
2626 sizeof(cfg.portfwd)) {
2628 p[strlen(str) + 1] = '\0';
2629 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_ADDSTRING,
2631 SetDlgItemText(hwnd, IDC_SPORTEDIT, "");
2632 SetDlgItemText(hwnd, IDC_DPORTEDIT, "");
2634 MessageBox(hwnd, "Too many forwardings",
2635 "PuTTY Error", MB_OK | MB_ICONERROR);
2639 case IDC_PFWDREMOVE:
2640 if (HIWORD(wParam) != BN_CLICKED &&
2641 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2642 i = SendDlgItemMessage(hwnd, IDC_PFWDLIST,
2643 LB_GETCURSEL, 0, 0);
2649 SendDlgItemMessage(hwnd, IDC_PFWDLIST, LB_DELETESTRING,
2681 /* Grrr Explorer will maximize Dialogs! */
2683 if (wParam == SIZE_MAXIMIZED)
2689 * Handle application-defined messages eg. DragListBox
2691 /* First find out what the number is (once). */
2692 if (draglistmsg == WM_NULL)
2693 draglistmsg = RegisterWindowMessage (DRAGLISTMSGSTRING);
2695 if (msg == draglistmsg) {
2696 /* Only process once dialog is fully formed. */
2697 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
2698 case IDC_CIPHERLIST:
2699 return handle_prefslist(&cipherlist,
2700 cfg.ssh_cipherlist, CIPHER_MAX,
2701 1, hwnd, wParam, lParam);
2710 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2711 WPARAM wParam, LPARAM lParam)
2713 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2715 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2716 EnableWindow(hwnd, 0);
2717 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2718 EnableWindow(hwnd, 1);
2719 SetActiveWindow(hwnd);
2721 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2724 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2725 WPARAM wParam, LPARAM lParam)
2727 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2730 void defuse_showwindow(void)
2733 * Work around the fact that the app's first call to ShowWindow
2734 * will ignore the default in favour of the shell-provided
2739 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2741 ShowWindow(hwnd, SW_HIDE);
2742 SetActiveWindow(hwnd);
2743 DestroyWindow(hwnd);
2752 savedsession[0] = '\0';
2754 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2755 get_sesslist(FALSE);
2760 int do_reconfig(HWND hwnd)
2765 backup_cfg = cfg; /* structure copy */
2767 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2769 cfg = backup_cfg; /* structure copy */
2774 void logevent(char *string)
2779 if (nevents >= negsize) {
2781 events = srealloc(events, negsize * sizeof(*events));
2785 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2788 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2789 strcpy(events[nevents], timebuf);
2790 strcat(events[nevents], string);
2793 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2794 0, (LPARAM) events[nevents]);
2795 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2796 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2801 void showeventlog(HWND hwnd)
2804 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2806 ShowWindow(logbox, SW_SHOWNORMAL);
2808 SetActiveWindow(logbox);
2811 void showabout(HWND hwnd)
2813 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2816 void verify_ssh_host_key(char *host, int port, char *keytype,
2817 char *keystr, char *fingerprint)
2821 static const char absentmsg[] =
2822 "The server's host key is not cached in the registry. You\n"
2823 "have no guarantee that the server is the computer you\n"
2825 "The server's key fingerprint is:\n"
2827 "If you trust this host, hit Yes to add the key to\n"
2828 "PuTTY's cache and carry on connecting.\n"
2829 "If you want to carry on connecting just once, without\n"
2830 "adding the key to the cache, hit No.\n"
2831 "If you do not trust this host, hit Cancel to abandon the\n"
2834 static const char wrongmsg[] =
2835 "WARNING - POTENTIAL SECURITY BREACH!\n"
2837 "The server's host key does not match the one PuTTY has\n"
2838 "cached in the registry. This means that either the\n"
2839 "server administrator has changed the host key, or you\n"
2840 "have actually connected to another computer pretending\n"
2841 "to be the server.\n"
2842 "The new key fingerprint is:\n"
2844 "If you were expecting this change and trust the new key,\n"
2845 "hit Yes to update PuTTY's cache and continue connecting.\n"
2846 "If you want to carry on connecting but without updating\n"
2847 "the cache, hit No.\n"
2848 "If you want to abandon the connection completely, hit\n"
2849 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2851 static const char mbtitle[] = "PuTTY Security Alert";
2854 /* sensible fingerprint max size */
2855 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2856 sizeof(absentmsg) : sizeof(wrongmsg))];
2859 * Verify the key against the registry.
2861 ret = verify_host_key(host, port, keytype, keystr);
2863 if (ret == 0) /* success - key matched OK */
2865 if (ret == 2) { /* key was different */
2867 sprintf(message, wrongmsg, fingerprint);
2868 mbret = MessageBox(NULL, message, mbtitle,
2869 MB_ICONWARNING | MB_YESNOCANCEL);
2871 store_host_key(host, port, keytype, keystr);
2872 if (mbret == IDCANCEL)
2875 if (ret == 1) { /* key was absent */
2877 sprintf(message, absentmsg, fingerprint);
2878 mbret = MessageBox(NULL, message, mbtitle,
2879 MB_ICONWARNING | MB_YESNOCANCEL);
2881 store_host_key(host, port, keytype, keystr);
2882 if (mbret == IDCANCEL)
2888 * Ask whether the selected cipher is acceptable (since it was
2889 * below the configured 'warn' threshold).
2890 * cs: 0 = both ways, 1 = client->server, 2 = server->client
2892 void askcipher(char *ciphername, int cs)
2894 static const char mbtitle[] = "PuTTY Security Alert";
2895 static const char msg[] =
2896 "The first %.35scipher supported by the server\n"
2897 "is %.64s, which is below the configured\n"
2898 "warning threshold.\n"
2899 "Do you want to continue with this connection?\n";
2900 /* guessed cipher name + type max length */
2901 char message[100 + sizeof(msg)];
2904 sprintf(message, msg,
2906 (cs == 1) ? "client-to-server " :
2907 "server-to-client ",
2909 mbret = MessageBox(NULL, message, mbtitle,
2910 MB_ICONWARNING | MB_YESNO);
2918 * Ask whether to wipe a session log file before writing to it.
2919 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2921 int askappend(char *filename)
2923 static const char mbtitle[] = "PuTTY Log to File";
2924 static const char msgtemplate[] =
2925 "The session log file \"%.*s\" already exists.\n"
2926 "You can overwrite it with a new session log,\n"
2927 "append your session log to the end of it,\n"
2928 "or disable session logging for this session.\n"
2929 "Hit Yes to wipe the file, No to append to it,\n"
2930 "or Cancel to disable logging.";
2931 char message[sizeof(msgtemplate) + FILENAME_MAX];
2933 if (cfg.logxfovr != LGXF_ASK) {
2934 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2936 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2938 mbret = MessageBox(NULL, message, mbtitle,
2939 MB_ICONQUESTION | MB_YESNOCANCEL);
2942 else if (mbret == IDNO)