15 static char **events = NULL;
16 static int nevents = 0, negsize = 0;
20 void force_normal(HWND hwnd)
22 static int recurse = 0;
30 wp.length = sizeof(wp);
31 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED) {
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
38 static void MyGetDlgItemInt(HWND hwnd, int id, int *result)
42 n = GetDlgItemInt(hwnd, id, &ok, FALSE);
47 static void MyGetDlgItemFlt(HWND hwnd, int id, int *result, int scale)
51 ok = GetDlgItemText(hwnd, id, text, sizeof(text) - 1);
53 *result = (int) (scale * atof(text));
56 static void MySetDlgItemFlt(HWND hwnd, int id, double value)
59 sprintf(text, "%g", value);
60 SetDlgItemText(hwnd, id, text);
63 static int CALLBACK LogProc(HWND hwnd, UINT msg,
64 WPARAM wParam, LPARAM lParam)
71 static int tabs[4] = { 78, 108 };
72 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETTABSTOPS, 2,
75 for (i = 0; i < nevents; i++)
76 SendDlgItemMessage(hwnd, IDN_LIST, LB_ADDSTRING,
77 0, (LPARAM) events[i]);
80 switch (LOWORD(wParam)) {
84 SetActiveWindow(GetParent(hwnd));
88 if (HIWORD(wParam) == BN_CLICKED ||
89 HIWORD(wParam) == BN_DOUBLECLICKED) {
92 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
93 LB_GETSELCOUNT, 0, 0);
94 if (selcount == 0) { /* don't even try to copy zero items */
99 selitems = smalloc(selcount * sizeof(int));
101 int count = SendDlgItemMessage(hwnd, IDN_LIST,
108 static unsigned char sel_nl[] = SEL_NL;
110 if (count == 0) { /* can't copy zero stuff */
116 for (i = 0; i < count; i++)
118 strlen(events[selitems[i]]) + sizeof(sel_nl);
120 clipdata = smalloc(size);
123 for (i = 0; i < count; i++) {
124 char *q = events[selitems[i]];
125 int qlen = strlen(q);
128 memcpy(p, sel_nl, sizeof(sel_nl));
131 write_aclip(clipdata, size, TRUE);
136 for (i = 0; i < nevents; i++)
137 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
146 SetActiveWindow(GetParent(hwnd));
153 static int CALLBACK LicenceProc(HWND hwnd, UINT msg,
154 WPARAM wParam, LPARAM lParam)
160 switch (LOWORD(wParam)) {
173 static int CALLBACK AboutProc(HWND hwnd, UINT msg,
174 WPARAM wParam, LPARAM lParam)
178 SetDlgItemText(hwnd, IDA_VERSION, ver);
181 switch (LOWORD(wParam)) {
184 EndDialog(hwnd, TRUE);
187 EnableWindow(hwnd, 0);
188 DialogBox(hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
190 EnableWindow(hwnd, 1);
191 SetActiveWindow(hwnd);
195 /* Load web browser */
196 ShellExecute(hwnd, "open",
197 "http://www.chiark.greenend.org.uk/~sgtatham/putty/",
198 0, 0, SW_SHOWDEFAULT);
203 EndDialog(hwnd, TRUE);
210 * Null dialog procedure.
212 static int CALLBACK NullDlgProc(HWND hwnd, UINT msg,
213 WPARAM wParam, LPARAM lParam)
218 static char savedsession[2048];
221 IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
362 appearancepanelstart,
363 IDC_TITLE_APPEARANCE,
383 connectionpanelstart,
384 IDC_TITLE_CONNECTION,
485 translationpanelstart,
486 IDC_TITLE_TRANSLATION,
487 IDC_BOX_TRANSLATION1,
488 IDC_BOX_TRANSLATION2,
510 static const char *const colours[] = {
511 "Default Foreground", "Default Bold Foreground",
512 "Default Background", "Default Bold Background",
513 "Cursor Text", "Cursor Colour",
514 "ANSI Black", "ANSI Black Bold",
515 "ANSI Red", "ANSI Red Bold",
516 "ANSI Green", "ANSI Green Bold",
517 "ANSI Yellow", "ANSI Yellow Bold",
518 "ANSI Blue", "ANSI Blue Bold",
519 "ANSI Magenta", "ANSI Magenta Bold",
520 "ANSI Cyan", "ANSI Cyan Bold",
521 "ANSI White", "ANSI White Bold"
523 static const int permcolour[] = {
524 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
525 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
526 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
529 static void fmtfont(char *buf)
531 sprintf(buf, "Font: %s, ", cfg.font);
533 strcat(buf, "bold, ");
534 if (cfg.fontheight == 0)
535 strcat(buf, "default height");
537 sprintf(buf + strlen(buf), "%d-point",
538 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight));
541 static void init_dlg_ctrls(HWND hwnd)
544 char fontstatic[256];
546 SetDlgItemText(hwnd, IDC_HOST, cfg.host);
547 SetDlgItemText(hwnd, IDC_SESSEDIT, savedsession);
550 n = SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_GETCOUNT, 0, 0);
551 for (i = n; i-- > 0;)
552 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_DELETESTRING, i, 0);
553 for (i = 0; i < nsessions; i++)
554 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_ADDSTRING,
555 0, (LPARAM) (sessions[i]));
557 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
558 CheckRadioButton(hwnd, IDC_PROTRAW, IDC_PROTSSH,
559 cfg.protocol == PROT_SSH ? IDC_PROTSSH :
560 cfg.protocol == PROT_TELNET ? IDC_PROTTELNET :
562 PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW);
563 SetDlgItemInt(hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
565 CheckRadioButton(hwnd, IDC_DEL008, IDC_DEL127,
566 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
567 CheckRadioButton(hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
568 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
569 CheckRadioButton(hwnd, IDC_FUNCTILDE, IDC_FUNCSCO,
570 cfg.funky_type == 0 ? IDC_FUNCTILDE :
571 cfg.funky_type == 1 ? IDC_FUNCLINUX :
572 cfg.funky_type == 2 ? IDC_FUNCXTERM :
573 cfg.funky_type == 3 ? IDC_FUNCVT400 :
574 cfg.funky_type == 4 ? IDC_FUNCVT100P :
575 cfg.funky_type == 5 ? IDC_FUNCSCO : IDC_FUNCTILDE);
576 CheckDlgButton(hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
577 CheckDlgButton(hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
578 CheckRadioButton(hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
579 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
580 CheckRadioButton(hwnd, IDC_KPNORMAL, IDC_KPNH,
581 cfg.nethack_keypad ? IDC_KPNH :
582 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
583 CheckDlgButton(hwnd, IDC_ALTF4, cfg.alt_f4);
584 CheckDlgButton(hwnd, IDC_ALTSPACE, cfg.alt_space);
585 CheckDlgButton(hwnd, IDC_ALTONLY, cfg.alt_only);
586 CheckDlgButton(hwnd, IDC_COMPOSEKEY, cfg.compose_key);
587 CheckDlgButton(hwnd, IDC_CTRLALTKEYS, cfg.ctrlaltkeys);
588 CheckDlgButton(hwnd, IDC_TELNETKEY, cfg.telnet_keyboard);
589 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
590 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
591 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
592 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
593 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
594 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
595 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
596 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
597 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
598 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
600 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
601 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
602 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
603 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
604 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
605 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
607 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
608 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
609 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
610 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
611 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
613 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
614 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
615 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
616 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
617 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
618 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
620 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
621 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
623 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
624 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
625 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
626 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
627 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
628 cfg.cursor_type == 0 ? IDC_CURBLOCK :
629 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
630 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
631 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
632 CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize);
633 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
634 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
636 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
637 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
639 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
640 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
641 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
642 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
643 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
644 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
645 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
646 cfg.logtype == 0 ? IDC_LSTATOFF :
647 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
648 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
649 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
650 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
653 char *p = cfg.environmt;
655 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
660 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
661 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
662 CheckRadioButton(hwnd, IDC_TPASSIVE, IDC_TACTIVE,
663 cfg.passive_telnet ? IDC_TPASSIVE : IDC_TACTIVE);
665 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
666 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
667 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
668 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
669 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
670 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
671 CheckRadioButton(hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
672 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
673 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
674 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
676 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
677 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
678 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
679 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
680 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
682 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
683 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
684 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
686 static int tabs[4] = { 25, 61, 96, 128 };
687 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
690 for (i = 0; i < 128; i++) {
692 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
693 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
694 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
698 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
699 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
702 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
703 for (i = n; i-- > 0;)
704 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
705 LB_DELETESTRING, i, 0);
706 for (i = 0; i < 22; i++)
707 if (cfg.bold_colour || permcolour[i])
708 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
709 (LPARAM) colours[i]);
711 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
712 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
713 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
714 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
716 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
717 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTUNICODE,
718 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
719 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
720 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
721 cfg.vtmode == VT_UNICODE ? IDC_VTUNICODE :
724 CheckDlgButton(hwnd, IDC_X11_FORWARD, cfg.x11_forward);
725 SetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display);
728 struct treeview_faff {
733 static HTREEITEM treeview_insert(struct treeview_faff *faff,
734 int level, char *text)
739 ins.hParent = (level > 0 ? faff->lastat[level - 1] : TVI_ROOT);
740 ins.hInsertAfter = faff->lastat[level];
741 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
742 #define INSITEM DUMMYUNIONNAME.item
746 ins.INSITEM.mask = TVIF_TEXT;
747 ins.INSITEM.pszText = text;
748 newitem = TreeView_InsertItem(faff->treeview, &ins);
750 TreeView_Expand(faff->treeview, faff->lastat[level - 1],
752 faff->lastat[level] = newitem;
753 for (i = level + 1; i < 4; i++)
754 faff->lastat[i] = NULL;
759 * Create the panelfuls of controls in the configuration box.
761 static void create_controls(HWND hwnd, int dlgtype, int panel)
763 if (panel == sessionpanelstart) {
764 /* The Session panel. Accelerators used: [acgo] nprtih elsd w */
766 ctlposinit(&cp, hwnd, 80, 3, 13);
767 bartitle(&cp, "Basic options for your PuTTY session",
770 beginbox(&cp, "Specify your connection by host name",
773 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
774 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
775 if (backends[3].backend == NULL) {
776 /* this is PuTTYtel, so only three protocols available */
777 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
779 "&Telnet", IDC_PROTTELNET,
780 "Rlog&in", IDC_PROTRLOGIN, NULL);
782 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
784 "&Telnet", IDC_PROTTELNET,
785 "Rlog&in", IDC_PROTRLOGIN,
794 beginbox(&cp, "Load, save or delete a stored session",
796 sesssaver(&cp, "Sav&ed Sessions",
797 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
798 "&Load", IDC_SESSLOAD,
799 "&Save", IDC_SESSSAVE, "&Delete", IDC_SESSDEL, NULL);
802 beginbox(&cp, NULL, IDC_BOX_SESSION3);
803 radioline(&cp, "Close &window on exit:", IDC_CLOSEEXIT, 4,
804 "Always", IDC_COEALWAYS,
805 "Never", IDC_COENEVER,
806 "Only on clean exit", IDC_COENORMAL, NULL);
810 if (panel == loggingpanelstart) {
811 /* The Logging panel. Accelerators used: [acgo] tplfwe */
813 ctlposinit(&cp, hwnd, 80, 3, 13);
814 bartitle(&cp, "Options controlling session logging",
816 beginbox(&cp, NULL, IDC_BOX_LOGGING1);
818 "Session logging:", IDC_LSTATSTATIC,
819 "Logging &turned off completely", IDC_LSTATOFF,
820 "Log &printable output only", IDC_LSTATASCII,
821 "&Log all session output", IDC_LSTATRAW, NULL);
822 editbutton(&cp, "Log &file name:",
823 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
826 "What to do if the log file already &exists:",
827 IDC_LSTATXIST, "Always overwrite it", IDC_LSTATXOVR,
828 "Always append to the end of it", IDC_LSTATXAPN,
829 "Ask the user every time", IDC_LSTATXASK, NULL);
833 if (panel == terminalpanelstart) {
834 /* The Terminal panel. Accelerators used: [acgo] wdlen hts */
836 ctlposinit(&cp, hwnd, 80, 3, 13);
837 bartitle(&cp, "Options controlling the terminal emulation",
839 beginbox(&cp, "Set various terminal options", IDC_BOX_TERMINAL1);
840 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
841 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
842 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
843 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
844 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
846 "An&swerback to ^E:", IDC_ANSWERBACK,
847 IDC_ANSWEREDIT, 100, NULL);
850 beginbox(&cp, "Line discipline options", IDC_BOX_TERMINAL2);
851 radioline(&cp, "Local ec&ho:", IDC_ECHOSTATIC, 3,
852 "Auto", IDC_ECHOBACKEND,
853 "Force on", IDC_ECHOYES, "Force off", IDC_ECHONO, NULL);
854 radioline(&cp, "Local line edi&ting:", IDC_EDITSTATIC, 3,
855 "Auto", IDC_EDITBACKEND,
856 "Force on", IDC_EDITYES, "Force off", IDC_EDITNO, NULL);
860 if (panel == bellpanelstart) {
861 /* The Bell panel. Accelerators used: [acgo] bdsm wt */
863 ctlposinit(&cp, hwnd, 80, 3, 13);
864 bartitle(&cp, "Options controlling the terminal bell",
866 beginbox(&cp, "Set the style of bell", IDC_BOX_BELL1);
868 "Action to happen when a &bell occurs:", IDC_BELLSTATIC,
869 "None (bell disabled)", IDC_BELL_DISABLED,
870 "Play Windows Default Sound", IDC_BELL_DEFAULT,
871 "Play a custom sound file", IDC_BELL_WAVEFILE,
872 "Visual bell (flash window)", IDC_BELL_VISUAL, NULL);
873 editbutton(&cp, "Custom sound file to play as a bell:",
874 IDC_BELL_WAVESTATIC, IDC_BELL_WAVEEDIT,
875 "Bro&wse...", IDC_BELL_WAVEBROWSE);
877 beginbox(&cp, "Control the bell overload behaviour",
879 checkbox(&cp, "Bell is temporarily &disabled when over-used",
881 staticedit(&cp, "Over-use means this &many bells...",
882 IDC_BELLOVLNSTATIC, IDC_BELLOVLN, 20);
883 staticedit(&cp, "... in &this many seconds",
884 IDC_BELLOVLTSTATIC, IDC_BELLOVLT, 20);
886 "The bell is re-enabled after a few seconds of silence.",
888 staticedit(&cp, "Seconds of &silence required", IDC_BELLOVLSSTATIC,
893 if (panel == keyboardpanelstart) {
894 /* The Keyboard panel. Accelerators used: [acgo] bhf ruyntd */
896 ctlposinit(&cp, hwnd, 80, 3, 13);
898 bartitle(&cp, "Options controlling the effects of keys",
901 beginbox(&cp, "Change the sequences sent by:", IDC_BOX_KEYBOARD1);
902 radioline(&cp, "The &Backspace key", IDC_DELSTATIC, 2,
903 "Control-H", IDC_DEL008,
904 "Control-? (127)", IDC_DEL127, NULL);
905 radioline(&cp, "The &Home and End keys", IDC_HOMESTATIC, 2,
906 "Standard", IDC_HOMETILDE, "rxvt", IDC_HOMERXVT, NULL);
907 radioline(&cp, "The &Function keys and keypad", IDC_FUNCSTATIC, 3,
908 "ESC[n~", IDC_FUNCTILDE,
909 "Linux", IDC_FUNCLINUX,
910 "Xterm R6", IDC_FUNCXTERM,
911 "VT400", IDC_FUNCVT400,
912 "VT100+", IDC_FUNCVT100P, "SCO", IDC_FUNCSCO, NULL);
914 beginbox(&cp, "Application keypad settings:", IDC_BOX_KEYBOARD2);
916 "Application c&ursor keys totally disabled",
918 radioline(&cp, "Initial state of cu&rsor keys:", IDC_CURSTATIC, 2,
919 "Normal", IDC_CURNORMAL,
920 "Application", IDC_CURAPPLIC, NULL);
922 "Application ke&ypad keys totally disabled",
924 radioline(&cp, "Initial state of &numeric keypad:", IDC_KPSTATIC,
925 3, "Normal", IDC_KPNORMAL, "Application", IDC_KPAPPLIC,
926 "NetHack", IDC_KPNH, NULL);
928 beginbox(&cp, "Enable extra keyboard features:",
930 checkbox(&cp, "AltGr ac&ts as Compose key", IDC_COMPOSEKEY);
931 checkbox(&cp, "Control-Alt is &different from AltGr",
936 if (panel == windowpanelstart) {
937 /* The Window panel. Accelerators used: [acgo] rmz sdkp w4ylt */
939 ctlposinit(&cp, hwnd, 80, 3, 13);
940 bartitle(&cp, "Options controlling PuTTY's window",
942 beginbox(&cp, "Set the size of the window", IDC_BOX_WINDOW1);
944 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
945 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50, NULL);
946 checkbox(&cp, "Lock window size against resi&zing", IDC_LOCKSIZE);
948 beginbox(&cp, "Control the scrollback in the window",
950 staticedit(&cp, "Lines of &scrollback",
951 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
952 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
953 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
954 checkbox(&cp, "Reset scrollback on dis&play activity",
957 beginbox(&cp, NULL, IDC_BOX_WINDOW3);
958 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
959 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
960 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
961 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
962 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
966 if (panel == appearancepanelstart) {
967 /* The Appearance panel. Accelerators used: [acgo] luvb h ti p s */
969 ctlposinit(&cp, hwnd, 80, 3, 13);
970 bartitle(&cp, "Options controlling PuTTY's appearance",
971 IDC_TITLE_APPEARANCE);
972 beginbox(&cp, "Adjust the use of the cursor", IDC_BOX_APPEARANCE1);
973 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
974 "B&lock", IDC_CURBLOCK,
975 "&Underline", IDC_CURUNDER,
976 "&Vertical line", IDC_CURVERT, NULL);
977 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
979 beginbox(&cp, "Set the font used in the terminal window",
980 IDC_BOX_APPEARANCE2);
981 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
983 beginbox(&cp, "Adjust the use of the window title",
984 IDC_BOX_APPEARANCE3);
986 "Window &title:", IDC_WINTITLE, IDC_WINEDIT, 100, NULL);
987 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
989 beginbox(&cp, "Adjust the use of the mouse pointer",
990 IDC_BOX_APPEARANCE4);
991 checkbox(&cp, "Hide mouse &pointer when typing in window",
994 beginbox(&cp, "Adjust the window border", IDC_BOX_APPEARANCE5);
995 checkbox(&cp, "&Sunken-edge border (slightly thicker)",
1000 if (panel == translationpanelstart) {
1001 /* The Translation panel. Accelerators used: [acgo] xbep t s */
1003 ctlposinit(&cp, hwnd, 80, 3, 13);
1004 bartitle(&cp, "Options controlling character set translation",
1005 IDC_TITLE_TRANSLATION);
1006 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
1007 IDC_BOX_TRANSLATION1);
1009 "Handling of line drawing characters:", IDC_VTSTATIC,
1010 "Font has &XWindows encoding", IDC_VTXWINDOWS,
1011 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
1012 "Use font in O&EM mode only", IDC_VTOEMONLY,
1013 "&Poor man's line drawing (" "+" ", " "-" " and " "|" ")",
1014 IDC_VTPOORMAN, "&Unicode mode", IDC_VTUNICODE, NULL);
1016 beginbox(&cp, "Enable character set translation on received data",
1017 IDC_BOX_TRANSLATION2);
1018 multiedit(&cp, "Line codepage:", IDC_CODEPAGESTATIC,
1019 IDC_CODEPAGE, 100, NULL);
1023 if (panel == selectionpanelstart) {
1024 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1026 ctlposinit(&cp, hwnd, 80, 3, 13);
1027 bartitle(&cp, "Options controlling copy and paste",
1028 IDC_TITLE_SELECTION);
1029 beginbox(&cp, "Translation of pasted characters",
1030 IDC_BOX_SELECTION1);
1032 "&Don't translate line drawing chars into +, - and |",
1035 beginbox(&cp, "Control which mouse button does which thing",
1036 IDC_BOX_SELECTION2);
1037 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1038 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1039 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1042 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1043 IDC_BOX_SELECTION3);
1044 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1045 "&Set", IDC_CCSET, IDC_CCEDIT,
1046 "&to class", IDC_CCSTATIC2);
1050 if (panel == colourspanelstart) {
1051 /* The Colours panel. Accelerators used: [acgo] blum */
1053 ctlposinit(&cp, hwnd, 80, 3, 13);
1054 bartitle(&cp, "Options controlling use of colours",
1056 beginbox(&cp, "General options for colour usage",
1058 checkbox(&cp, "&Bolded text is a different colour",
1060 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1062 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1064 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1065 IDC_COLOURSTATIC, IDC_COLOURLIST,
1066 "&Modify...", IDC_CHANGE,
1067 "Red:", IDC_RSTATIC, IDC_RVALUE,
1068 "Green:", IDC_GSTATIC, IDC_GVALUE,
1069 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1073 if (panel == connectionpanelstart) {
1074 /* The Connection panel. Accelerators used: [acgo] tuk */
1076 ctlposinit(&cp, hwnd, 80, 3, 13);
1077 bartitle(&cp, "Options controlling the connection",
1078 IDC_TITLE_CONNECTION);
1080 beginbox(&cp, "Data to send to the server",
1081 IDC_BOX_CONNECTION1);
1082 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1084 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1088 beginbox(&cp, "Adjust telnet session.", IDC_BOX_CONNECTION1);
1089 checkbox(&cp, "Keyboard sends telnet Backspace and Interrupt",
1093 beginbox(&cp, "Sending of null packets to keep session active",
1094 IDC_BOX_CONNECTION2);
1095 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1096 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1100 if (panel == telnetpanelstart) {
1101 /* The Telnet panel. Accelerators used: [acgo] svldr bftk */
1103 ctlposinit(&cp, hwnd, 80, 3, 13);
1105 bartitle(&cp, "Options controlling Telnet connections",
1107 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1108 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1110 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1111 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1112 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1113 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1115 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1116 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1117 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1118 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1119 radioline(&cp, "&Telnet negotiation mode:", IDC_ACTSTATIC, 2,
1120 "Passive", IDC_TPASSIVE, "Active",
1122 checkbox(&cp, "&Keyboard sends telnet Backspace and Interrupt",
1128 if (panel == rloginpanelstart) {
1129 /* The Rlogin panel. Accelerators used: [acgo] sl */
1131 ctlposinit(&cp, hwnd, 80, 3, 13);
1133 bartitle(&cp, "Options controlling Rlogin connections",
1135 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1136 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1138 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1139 IDC_RLLUSEREDIT, 50);
1144 if (panel == sshpanelstart) {
1145 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1147 ctlposinit(&cp, hwnd, 80, 3, 13);
1149 bartitle(&cp, "Options controlling SSH connections",
1151 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1153 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1156 beginbox(&cp, "Authentication options", IDC_BOX_SSH2);
1157 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1159 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1160 editbutton(&cp, "Private &key file for authentication:",
1161 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1164 beginbox(&cp, "Protocol options", IDC_BOX_SSH3);
1165 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1166 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1167 radioline(&cp, "Preferred SSH protocol version:",
1168 IDC_SSHPROTSTATIC, 2,
1169 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1170 radioline(&cp, "Preferred encryption algorithm:",
1171 IDC_CIPHERSTATIC, 4, "&3DES", IDC_CIPHER3DES,
1172 "&Blowfish", IDC_CIPHERBLOWF, "&DES", IDC_CIPHERDES,
1173 "AE&S", IDC_CIPHERAES, NULL);
1174 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1180 if (panel == tunnelspanelstart) {
1181 /* The Tunnels panel. Accelerators used: [acgo] ex */
1183 ctlposinit(&cp, hwnd, 80, 3, 13);
1185 bartitle(&cp, "Options controlling SSH tunnelling",
1187 beginbox(&cp, "X11 forwarding options", IDC_BOX_TUNNELS);
1188 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1189 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1190 IDC_X11_DISPLAY, 50, NULL);
1197 * This function is the configuration box.
1199 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1200 WPARAM wParam, LPARAM lParam, int dlgtype)
1203 struct treeview_faff tvfaff;
1206 char filename[sizeof(cfg.keyfile)];
1209 char fontstatic[256];
1211 struct servent *service;
1217 SetWindowLong(hwnd, GWL_USERDATA, 0);
1218 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1219 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
1221 * Centre the window.
1223 { /* centre the window */
1226 hw = GetDesktopWindow();
1227 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1229 (rs.right + rs.left + rd.left - rd.right) / 2,
1230 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1231 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1235 * Create the tree view.
1243 r.right = r.left + 75;
1245 r.bottom = r.top + 10;
1246 MapDialogRect(hwnd, &r);
1247 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1248 WS_CHILD | WS_VISIBLE,
1250 r.right - r.left, r.bottom - r.top,
1251 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1253 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1254 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1257 r.right = r.left + 75;
1259 r.bottom = r.top + 206;
1260 MapDialogRect(hwnd, &r);
1261 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1262 WS_CHILD | WS_VISIBLE |
1263 WS_TABSTOP | TVS_HASLINES |
1264 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1266 TVS_SHOWSELALWAYS, r.left, r.top,
1267 r.right - r.left, r.bottom - r.top,
1268 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1270 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1271 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1272 tvfaff.treeview = treeview;
1273 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1277 * Set up the tree view contents.
1279 hsession = treeview_insert(&tvfaff, 0, "Session");
1280 treeview_insert(&tvfaff, 1, "Logging");
1281 treeview_insert(&tvfaff, 0, "Terminal");
1282 treeview_insert(&tvfaff, 1, "Keyboard");
1283 treeview_insert(&tvfaff, 1, "Bell");
1284 treeview_insert(&tvfaff, 0, "Window");
1285 treeview_insert(&tvfaff, 1, "Appearance");
1286 treeview_insert(&tvfaff, 1, "Translation");
1287 treeview_insert(&tvfaff, 1, "Selection");
1288 treeview_insert(&tvfaff, 1, "Colours");
1289 treeview_insert(&tvfaff, 0, "Connection");
1291 treeview_insert(&tvfaff, 1, "Telnet");
1292 treeview_insert(&tvfaff, 1, "Rlogin");
1293 if (backends[3].backend != NULL) {
1294 treeview_insert(&tvfaff, 1, "SSH");
1295 treeview_insert(&tvfaff, 2, "Tunnels");
1300 * Put the treeview selection on to the Session panel. This
1301 * should also cause creation of the relevant controls.
1303 TreeView_SelectItem(treeview, hsession);
1306 * Set focus into the first available control.
1310 ctl = GetDlgItem(hwnd, IDC_HOST);
1312 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1316 SetWindowLong(hwnd, GWL_USERDATA, 1);
1320 * Button release should trigger WM_OK if there was a
1321 * previous double click on the session list.
1325 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1328 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1329 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1331 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1336 item.pszText = buffer;
1337 item.cchTextMax = sizeof(buffer);
1338 item.mask = TVIF_TEXT;
1339 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1340 for (j = controlstartvalue; j < controlendvalue; j++) {
1341 HWND item = GetDlgItem(hwnd, j);
1343 DestroyWindow(item);
1345 if (!strcmp(buffer, "Session"))
1346 create_controls(hwnd, dlgtype, sessionpanelstart);
1347 if (!strcmp(buffer, "Logging"))
1348 create_controls(hwnd, dlgtype, loggingpanelstart);
1349 if (!strcmp(buffer, "Keyboard"))
1350 create_controls(hwnd, dlgtype, keyboardpanelstart);
1351 if (!strcmp(buffer, "Terminal"))
1352 create_controls(hwnd, dlgtype, terminalpanelstart);
1353 if (!strcmp(buffer, "Bell"))
1354 create_controls(hwnd, dlgtype, bellpanelstart);
1355 if (!strcmp(buffer, "Window"))
1356 create_controls(hwnd, dlgtype, windowpanelstart);
1357 if (!strcmp(buffer, "Appearance"))
1358 create_controls(hwnd, dlgtype, appearancepanelstart);
1359 if (!strcmp(buffer, "Tunnels"))
1360 create_controls(hwnd, dlgtype, tunnelspanelstart);
1361 if (!strcmp(buffer, "Connection"))
1362 create_controls(hwnd, dlgtype, connectionpanelstart);
1363 if (!strcmp(buffer, "Telnet"))
1364 create_controls(hwnd, dlgtype, telnetpanelstart);
1365 if (!strcmp(buffer, "Rlogin"))
1366 create_controls(hwnd, dlgtype, rloginpanelstart);
1367 if (!strcmp(buffer, "SSH"))
1368 create_controls(hwnd, dlgtype, sshpanelstart);
1369 if (!strcmp(buffer, "Selection"))
1370 create_controls(hwnd, dlgtype, selectionpanelstart);
1371 if (!strcmp(buffer, "Colours"))
1372 create_controls(hwnd, dlgtype, colourspanelstart);
1373 if (!strcmp(buffer, "Translation"))
1374 create_controls(hwnd, dlgtype, translationpanelstart);
1376 init_dlg_ctrls(hwnd);
1378 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1384 * Only process WM_COMMAND once the dialog is fully formed.
1386 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1387 switch (LOWORD(wParam)) {
1397 case IDC_PROTTELNET:
1398 case IDC_PROTRLOGIN:
1401 if (HIWORD(wParam) == BN_CLICKED ||
1402 HIWORD(wParam) == BN_DOUBLECLICKED) {
1403 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1404 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1405 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1407 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1409 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1410 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1411 || (cfg.protocol == PROT_RLOGIN
1412 && cfg.port != 513)) {
1413 cfg.port = i ? 22 : j ? 23 : 513;
1414 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1419 if (HIWORD(wParam) == EN_CHANGE)
1420 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1421 sizeof(cfg.host) - 1);
1424 if (HIWORD(wParam) == EN_CHANGE) {
1425 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1426 if (isdigit(portname[0]))
1427 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1429 service = getservbyname(portname, NULL);
1431 cfg.port = ntohs(service->s_port);
1438 if (HIWORD(wParam) == EN_CHANGE) {
1439 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1441 GetDlgItemText(hwnd, IDC_SESSEDIT,
1442 savedsession, sizeof(savedsession) - 1);
1443 savedsession[sizeof(savedsession) - 1] = '\0';
1447 if (HIWORD(wParam) == BN_CLICKED ||
1448 HIWORD(wParam) == BN_DOUBLECLICKED) {
1453 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1456 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1457 LB_GETCURSEL, 0, 0);
1462 strcpy(str, sessions[n]);
1464 save_settings(str, !!strcmp(str, "Default Settings"),
1466 get_sesslist(FALSE);
1468 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1470 for (i = 0; i < nsessions; i++)
1471 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1473 (LPARAM) (sessions[i]));
1474 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1480 if (LOWORD(wParam) == IDC_SESSLOAD &&
1481 HIWORD(wParam) != BN_CLICKED &&
1482 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1483 if (LOWORD(wParam) == IDC_SESSLIST &&
1484 HIWORD(wParam) != LBN_DBLCLK) break;
1486 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1487 LB_GETCURSEL, 0, 0);
1493 isdef = !strcmp(sessions[n], "Default Settings");
1494 load_settings(sessions[n], !isdef, &cfg);
1495 init_dlg_ctrls(hwnd);
1497 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1499 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1501 if (LOWORD(wParam) == IDC_SESSLIST) {
1503 * A double-click on a saved session should
1504 * actually start the session, not just load it.
1505 * Unless it's Default Settings or some other
1506 * host-less set of saved settings.
1515 if (HIWORD(wParam) == BN_CLICKED ||
1516 HIWORD(wParam) == BN_DOUBLECLICKED) {
1517 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1518 LB_GETCURSEL, 0, 0);
1519 if (n == LB_ERR || n == 0) {
1523 del_settings(sessions[n]);
1524 get_sesslist(FALSE);
1526 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1528 for (i = 0; i < nsessions; i++)
1529 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1531 (LPARAM) (sessions[i]));
1532 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1536 if (HIWORD(wParam) == EN_CHANGE)
1537 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1538 &cfg.ping_interval);
1542 if (HIWORD(wParam) == BN_CLICKED ||
1543 HIWORD(wParam) == BN_DOUBLECLICKED)
1544 cfg.bksp_is_delete =
1545 IsDlgButtonChecked(hwnd, IDC_DEL127);
1549 if (HIWORD(wParam) == BN_CLICKED ||
1550 HIWORD(wParam) == BN_DOUBLECLICKED)
1552 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1558 case IDC_FUNCVT100P:
1560 if (HIWORD(wParam) == BN_CLICKED ||
1561 HIWORD(wParam) == BN_DOUBLECLICKED)
1562 switch (LOWORD(wParam)) {
1575 case IDC_FUNCVT100P:
1585 if (HIWORD(wParam) == BN_CLICKED ||
1586 HIWORD(wParam) == BN_DOUBLECLICKED) {
1588 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1589 cfg.nethack_keypad = FALSE;
1593 if (HIWORD(wParam) == BN_CLICKED ||
1594 HIWORD(wParam) == BN_DOUBLECLICKED) {
1595 cfg.app_keypad = FALSE;
1596 cfg.nethack_keypad = TRUE;
1601 if (HIWORD(wParam) == BN_CLICKED ||
1602 HIWORD(wParam) == BN_DOUBLECLICKED)
1604 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1607 if (HIWORD(wParam) == BN_CLICKED ||
1608 HIWORD(wParam) == BN_DOUBLECLICKED)
1610 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1613 if (HIWORD(wParam) == BN_CLICKED ||
1614 HIWORD(wParam) == BN_DOUBLECLICKED)
1616 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1619 if (HIWORD(wParam) == BN_CLICKED ||
1620 HIWORD(wParam) == BN_DOUBLECLICKED)
1621 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1624 if (HIWORD(wParam) == BN_CLICKED ||
1625 HIWORD(wParam) == BN_DOUBLECLICKED)
1627 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1630 if (HIWORD(wParam) == BN_CLICKED ||
1631 HIWORD(wParam) == BN_DOUBLECLICKED)
1633 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1635 case IDC_ECHOBACKEND:
1638 if (HIWORD(wParam) == BN_CLICKED ||
1639 HIWORD(wParam) == BN_DOUBLECLICKED) {
1640 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1641 cfg.localecho = LD_BACKEND;
1642 if (LOWORD(wParam) == IDC_ECHOYES)
1643 cfg.localecho = LD_YES;
1644 if (LOWORD(wParam) == IDC_ECHONO)
1645 cfg.localecho = LD_NO;
1648 case IDC_EDITBACKEND:
1651 if (HIWORD(wParam) == BN_CLICKED ||
1652 HIWORD(wParam) == BN_DOUBLECLICKED) {
1653 if (LOWORD(wParam) == IDC_EDITBACKEND)
1654 cfg.localedit = LD_BACKEND;
1655 if (LOWORD(wParam) == IDC_EDITYES)
1656 cfg.localedit = LD_YES;
1657 if (LOWORD(wParam) == IDC_EDITNO)
1658 cfg.localedit = LD_NO;
1661 case IDC_ANSWEREDIT:
1662 if (HIWORD(wParam) == EN_CHANGE)
1663 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1664 sizeof(cfg.answerback) - 1);
1666 case IDC_ALWAYSONTOP:
1667 if (HIWORD(wParam) == BN_CLICKED ||
1668 HIWORD(wParam) == BN_DOUBLECLICKED)
1670 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1673 if (HIWORD(wParam) == BN_CLICKED ||
1674 HIWORD(wParam) == BN_DOUBLECLICKED)
1676 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1678 case IDC_SCROLLDISP:
1679 if (HIWORD(wParam) == BN_CLICKED ||
1680 HIWORD(wParam) == BN_DOUBLECLICKED)
1681 cfg.scroll_on_disp =
1682 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1684 case IDC_COMPOSEKEY:
1685 if (HIWORD(wParam) == BN_CLICKED ||
1686 HIWORD(wParam) == BN_DOUBLECLICKED)
1688 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1690 case IDC_CTRLALTKEYS:
1691 if (HIWORD(wParam) == BN_CLICKED ||
1692 HIWORD(wParam) == BN_DOUBLECLICKED)
1694 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1697 if (HIWORD(wParam) == BN_CLICKED ||
1698 HIWORD(wParam) == BN_DOUBLECLICKED)
1699 cfg.telnet_keyboard =
1700 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1703 if (HIWORD(wParam) == BN_CLICKED ||
1704 HIWORD(wParam) == BN_DOUBLECLICKED)
1706 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1709 if (HIWORD(wParam) == BN_CLICKED ||
1710 HIWORD(wParam) == BN_DOUBLECLICKED)
1711 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1714 if (HIWORD(wParam) == BN_CLICKED ||
1715 HIWORD(wParam) == BN_DOUBLECLICKED)
1717 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1720 if (HIWORD(wParam) == EN_CHANGE)
1721 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1724 if (HIWORD(wParam) == EN_CHANGE)
1725 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1728 if (HIWORD(wParam) == EN_CHANGE)
1729 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1731 case IDC_CHOOSEFONT:
1734 lf.lfHeight = -MulDiv(cfg.fontheight,
1735 GetDeviceCaps(hdc, LOGPIXELSY),
1739 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1740 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1741 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1742 lf.lfCharSet = cfg.fontcharset;
1743 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1744 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1745 lf.lfQuality = DEFAULT_QUALITY;
1746 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1747 strncpy(lf.lfFaceName, cfg.font,
1748 sizeof(lf.lfFaceName) - 1);
1749 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1751 cf.lStructSize = sizeof(cf);
1752 cf.hwndOwner = hwnd;
1754 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1755 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1757 if (ChooseFont(&cf)) {
1758 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1759 cfg.font[sizeof(cfg.font) - 1] = '\0';
1760 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1761 cfg.fontcharset = lf.lfCharSet;
1762 cfg.fontheight = cf.iPointSize / 10;
1763 fmtfont(fontstatic);
1764 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1767 case IDC_BELL_DISABLED:
1768 case IDC_BELL_DEFAULT:
1769 case IDC_BELL_WAVEFILE:
1770 case IDC_BELL_VISUAL:
1771 if (HIWORD(wParam) == BN_CLICKED ||
1772 HIWORD(wParam) == BN_DOUBLECLICKED) {
1773 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1774 cfg.beep = BELL_DISABLED;
1775 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1776 cfg.beep = BELL_DEFAULT;
1777 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1778 cfg.beep = BELL_WAVEFILE;
1779 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1780 cfg.beep = BELL_VISUAL;
1783 case IDC_BELL_WAVEBROWSE:
1784 memset(&of, 0, sizeof(of));
1785 #ifdef OPENFILENAME_SIZE_VERSION_400
1786 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1788 of.lStructSize = sizeof(of);
1790 of.hwndOwner = hwnd;
1791 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1792 of.lpstrCustomFilter = NULL;
1793 of.nFilterIndex = 1;
1794 of.lpstrFile = filename;
1795 strcpy(filename, cfg.bell_wavefile);
1796 of.nMaxFile = sizeof(filename);
1797 of.lpstrFileTitle = NULL;
1798 of.lpstrInitialDir = NULL;
1799 of.lpstrTitle = "Select Bell Sound File";
1801 if (GetOpenFileName(&of)) {
1802 strcpy(cfg.bell_wavefile, filename);
1803 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1807 case IDC_BELL_WAVEEDIT:
1808 if (HIWORD(wParam) == EN_CHANGE)
1809 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1811 sizeof(cfg.bell_wavefile) - 1);
1814 if (HIWORD(wParam) == BN_CLICKED ||
1815 HIWORD(wParam) == BN_DOUBLECLICKED)
1817 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1820 if (HIWORD(wParam) == EN_CHANGE)
1821 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
1824 if (HIWORD(wParam) == EN_CHANGE)
1825 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
1829 if (HIWORD(wParam) == EN_CHANGE)
1830 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
1834 if (HIWORD(wParam) == BN_CLICKED ||
1835 HIWORD(wParam) == BN_DOUBLECLICKED)
1837 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
1840 if (HIWORD(wParam) == BN_CLICKED ||
1841 HIWORD(wParam) == BN_DOUBLECLICKED)
1842 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
1845 if (HIWORD(wParam) == BN_CLICKED ||
1846 HIWORD(wParam) == BN_DOUBLECLICKED)
1847 cfg.win_name_always =
1848 IsDlgButtonChecked(hwnd, IDC_WINNAME);
1851 if (HIWORD(wParam) == BN_CLICKED ||
1852 HIWORD(wParam) == BN_DOUBLECLICKED)
1854 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
1856 case IDC_SUNKENEDGE:
1857 if (HIWORD(wParam) == BN_CLICKED ||
1858 HIWORD(wParam) == BN_DOUBLECLICKED)
1860 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
1863 if (HIWORD(wParam) == BN_CLICKED ||
1864 HIWORD(wParam) == BN_DOUBLECLICKED)
1865 cfg.cursor_type = 0;
1868 if (HIWORD(wParam) == BN_CLICKED ||
1869 HIWORD(wParam) == BN_DOUBLECLICKED)
1870 cfg.cursor_type = 1;
1873 if (HIWORD(wParam) == BN_CLICKED ||
1874 HIWORD(wParam) == BN_DOUBLECLICKED)
1875 cfg.cursor_type = 2;
1878 if (HIWORD(wParam) == BN_CLICKED ||
1879 HIWORD(wParam) == BN_DOUBLECLICKED)
1881 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
1884 if (HIWORD(wParam) == BN_CLICKED ||
1885 HIWORD(wParam) == BN_DOUBLECLICKED)
1887 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
1890 if (HIWORD(wParam) == BN_CLICKED ||
1891 HIWORD(wParam) == BN_DOUBLECLICKED)
1893 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
1896 if (HIWORD(wParam) == EN_CHANGE)
1897 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
1898 sizeof(cfg.wintitle) - 1);
1903 if (HIWORD(wParam) == BN_CLICKED ||
1904 HIWORD(wParam) == BN_DOUBLECLICKED) {
1906 IsDlgButtonChecked(hwnd,
1907 IDC_COEALWAYS) ? COE_ALWAYS :
1908 IsDlgButtonChecked(hwnd,
1909 IDC_COENEVER) ? COE_NEVER :
1914 if (HIWORD(wParam) == BN_CLICKED ||
1915 HIWORD(wParam) == BN_DOUBLECLICKED)
1917 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
1920 if (HIWORD(wParam) == EN_CHANGE)
1921 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
1922 sizeof(cfg.termtype) - 1);
1925 if (HIWORD(wParam) == EN_CHANGE)
1926 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
1927 sizeof(cfg.logfilename) - 1);
1930 memset(&of, 0, sizeof(of));
1931 #ifdef OPENFILENAME_SIZE_VERSION_400
1932 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1934 of.lStructSize = sizeof(of);
1936 of.hwndOwner = hwnd;
1937 of.lpstrFilter = "All Files\0*\0\0\0";
1938 of.lpstrCustomFilter = NULL;
1939 of.nFilterIndex = 1;
1940 of.lpstrFile = filename;
1941 strcpy(filename, cfg.logfilename);
1942 of.nMaxFile = sizeof(filename);
1943 of.lpstrFileTitle = NULL;
1944 of.lpstrInitialDir = NULL;
1945 of.lpstrTitle = "Select session log file";
1947 if (GetSaveFileName(&of)) {
1948 strcpy(cfg.logfilename, filename);
1949 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
1953 case IDC_LSTATASCII:
1955 if (HIWORD(wParam) == BN_CLICKED ||
1956 HIWORD(wParam) == BN_DOUBLECLICKED) {
1957 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
1959 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
1961 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
1968 if (HIWORD(wParam) == BN_CLICKED ||
1969 HIWORD(wParam) == BN_DOUBLECLICKED) {
1970 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
1971 cfg.logxfovr = LGXF_ASK;
1972 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
1973 cfg.logxfovr = LGXF_APN;
1974 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
1975 cfg.logxfovr = LGXF_OVR;
1980 if (HIWORD(wParam) == EN_CHANGE)
1981 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
1982 sizeof(cfg.termspeed) - 1);
1985 if (HIWORD(wParam) == EN_CHANGE)
1986 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
1987 sizeof(cfg.username) - 1);
1989 case IDC_RLLUSEREDIT:
1990 if (HIWORD(wParam) == EN_CHANGE)
1991 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
1993 sizeof(cfg.localusername) - 1);
1997 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
2001 cfg.passive_telnet =
2002 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2005 if (HIWORD(wParam) == BN_CLICKED ||
2006 HIWORD(wParam) == BN_DOUBLECLICKED) {
2007 char str[sizeof(cfg.environmt)];
2009 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2015 p = str + strlen(str);
2017 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2018 sizeof(str) - 1 - (p - str));
2029 if ((p - cfg.environmt) + strlen(str) + 2 <
2030 sizeof(cfg.environmt)) {
2032 p[strlen(str) + 1] = '\0';
2033 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2035 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2036 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2038 MessageBox(hwnd, "Environment too big",
2039 "PuTTY Error", MB_OK | MB_ICONERROR);
2044 if (HIWORD(wParam) != BN_CLICKED &&
2045 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2047 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2054 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2081 if (HIWORD(wParam) == BN_CLICKED ||
2082 HIWORD(wParam) == BN_DOUBLECLICKED)
2083 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2086 if (HIWORD(wParam) == BN_CLICKED ||
2087 HIWORD(wParam) == BN_DOUBLECLICKED)
2089 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2092 if (HIWORD(wParam) == BN_CLICKED ||
2093 HIWORD(wParam) == BN_DOUBLECLICKED)
2095 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2098 if (HIWORD(wParam) == BN_CLICKED ||
2099 HIWORD(wParam) == BN_DOUBLECLICKED)
2101 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2103 case IDC_CIPHER3DES:
2104 case IDC_CIPHERBLOWF:
2107 if (HIWORD(wParam) == BN_CLICKED ||
2108 HIWORD(wParam) == BN_DOUBLECLICKED) {
2109 if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES))
2110 cfg.cipher = CIPHER_3DES;
2111 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF))
2112 cfg.cipher = CIPHER_BLOWFISH;
2113 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES))
2114 cfg.cipher = CIPHER_DES;
2115 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES))
2116 cfg.cipher = CIPHER_AES;
2121 if (HIWORD(wParam) == BN_CLICKED ||
2122 HIWORD(wParam) == BN_DOUBLECLICKED) {
2123 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2125 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2130 if (HIWORD(wParam) == BN_CLICKED ||
2131 HIWORD(wParam) == BN_DOUBLECLICKED)
2133 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2136 if (HIWORD(wParam) == EN_CHANGE)
2137 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2138 sizeof(cfg.keyfile) - 1);
2141 if (HIWORD(wParam) == EN_CHANGE)
2142 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2143 sizeof(cfg.remote_cmd) - 1);
2146 memset(&of, 0, sizeof(of));
2147 #ifdef OPENFILENAME_SIZE_VERSION_400
2148 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2150 of.lStructSize = sizeof(of);
2152 of.hwndOwner = hwnd;
2153 of.lpstrFilter = "All Files\0*\0\0\0";
2154 of.lpstrCustomFilter = NULL;
2155 of.nFilterIndex = 1;
2156 of.lpstrFile = filename;
2157 strcpy(filename, cfg.keyfile);
2158 of.nMaxFile = sizeof(filename);
2159 of.lpstrFileTitle = NULL;
2160 of.lpstrInitialDir = NULL;
2161 of.lpstrTitle = "Select Public Key File";
2163 if (GetOpenFileName(&of)) {
2164 strcpy(cfg.keyfile, filename);
2165 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2169 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2172 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2178 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2183 for (i = 0; i < 128; i++)
2184 if (SendDlgItemMessage
2185 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2187 cfg.wordness[i] = n;
2188 SendDlgItemMessage(hwnd, IDC_CCLIST,
2189 LB_DELETESTRING, i, 0);
2190 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2191 (i >= 0x21 && i != 0x7F) ? i : ' ',
2193 SendDlgItemMessage(hwnd, IDC_CCLIST,
2200 case IDC_BOLDCOLOUR:
2201 if (HIWORD(wParam) == BN_CLICKED ||
2202 HIWORD(wParam) == BN_DOUBLECLICKED) {
2205 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2207 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2209 if (n != 12 + 10 * cfg.bold_colour) {
2210 for (i = n; i-- > 0;)
2211 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2212 LB_DELETESTRING, i, 0);
2213 for (i = 0; i < 22; i++)
2214 if (cfg.bold_colour || permcolour[i])
2215 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2217 (LPARAM) colours[i]);
2222 if (HIWORD(wParam) == BN_CLICKED ||
2223 HIWORD(wParam) == BN_DOUBLECLICKED)
2225 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2227 case IDC_COLOURLIST:
2228 if (HIWORD(wParam) == LBN_DBLCLK ||
2229 HIWORD(wParam) == LBN_SELCHANGE) {
2230 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2233 if (!cfg.bold_colour)
2234 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2235 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2237 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2239 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2244 if (HIWORD(wParam) == BN_CLICKED ||
2245 HIWORD(wParam) == BN_DOUBLECLICKED) {
2246 static CHOOSECOLOR cc;
2247 static DWORD custom[16] = { 0 }; /* zero initialisers */
2248 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2251 if (!cfg.bold_colour)
2252 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2253 cc.lStructSize = sizeof(cc);
2254 cc.hwndOwner = hwnd;
2255 cc.hInstance = (HWND) hinst;
2256 cc.lpCustColors = custom;
2258 RGB(cfg.colours[i][0], cfg.colours[i][1],
2260 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2261 if (ChooseColor(&cc)) {
2263 (unsigned char) (cc.rgbResult & 0xFF);
2265 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2267 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2268 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2270 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2272 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2278 if (HIWORD(wParam) == EN_CHANGE)
2279 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2280 sizeof(cfg.line_codepage) - 1);
2281 if (HIWORD(wParam) == EN_KILLFOCUS) {
2282 int cp = decode_codepage(cfg.line_codepage);
2287 "Unable to identify character set '%s', "
2288 "translation disabled.",
2292 "Character set '%s' is a DBCS, "
2293 "translation is not available.",
2295 MessageBox(hwnd, buf, "PuTTY Error",
2296 MB_ICONERROR | MB_OK);
2298 strcpy(cfg.line_codepage, cp_name(cp));
2299 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
2302 case IDC_VTXWINDOWS:
2308 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2309 : IsDlgButtonChecked(hwnd,
2310 IDC_VTOEMANSI) ? VT_OEMANSI :
2311 IsDlgButtonChecked(hwnd,
2312 IDC_VTOEMONLY) ? VT_OEMONLY :
2313 IsDlgButtonChecked(hwnd,
2314 IDC_VTUNICODE) ? VT_UNICODE :
2317 case IDC_X11_FORWARD:
2318 if (HIWORD(wParam) == BN_CLICKED ||
2319 HIWORD(wParam) == BN_DOUBLECLICKED)
2321 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2323 case IDC_X11_DISPLAY:
2324 if (HIWORD(wParam) == EN_CHANGE)
2325 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2326 sizeof(cfg.x11_display) - 1);
2334 /* Grrr Explorer will maximize Dialogs! */
2336 if (wParam == SIZE_MAXIMIZED)
2343 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2344 WPARAM wParam, LPARAM lParam)
2346 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2348 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2349 EnableWindow(hwnd, 0);
2350 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2351 GetParent(hwnd), AboutProc);
2352 EnableWindow(hwnd, 1);
2353 SetActiveWindow(hwnd);
2355 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2358 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2359 WPARAM wParam, LPARAM lParam)
2361 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2364 void defuse_showwindow(void)
2367 * Work around the fact that the app's first call to ShowWindow
2368 * will ignore the default in favour of the shell-provided
2373 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2375 ShowWindow(hwnd, SW_HIDE);
2376 DestroyWindow(hwnd);
2385 savedsession[0] = '\0';
2387 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2388 get_sesslist(FALSE);
2393 int do_reconfig(HWND hwnd)
2398 backup_cfg = cfg; /* structure copy */
2400 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2402 cfg = backup_cfg; /* structure copy */
2407 void logevent(char *string)
2412 if (nevents >= negsize) {
2414 events = srealloc(events, negsize * sizeof(*events));
2418 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2421 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2422 strcpy(events[nevents], timebuf);
2423 strcat(events[nevents], string);
2426 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2427 0, (LPARAM) events[nevents]);
2428 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2429 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2434 void showeventlog(HWND hwnd)
2437 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2439 ShowWindow(logbox, SW_SHOWNORMAL);
2441 SetActiveWindow(logbox);
2444 void showabout(HWND hwnd)
2446 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2449 void verify_ssh_host_key(char *host, int port, char *keytype,
2450 char *keystr, char *fingerprint)
2454 static const char absentmsg[] =
2455 "The server's host key is not cached in the registry. You\n"
2456 "have no guarantee that the server is the computer you\n"
2458 "The server's key fingerprint is:\n"
2460 "If you trust this host, hit Yes to add the key to\n"
2461 "PuTTY's cache and carry on connecting.\n"
2462 "If you do not trust this host, hit No to abandon the\n"
2465 static const char wrongmsg[] =
2466 "WARNING - POTENTIAL SECURITY BREACH!\n"
2468 "The server's host key does not match the one PuTTY has\n"
2469 "cached in the registry. This means that either the\n"
2470 "server administrator has changed the host key, or you\n"
2471 "have actually connected to another computer pretending\n"
2472 "to be the server.\n"
2473 "The new key fingerprint is:\n"
2475 "If you were expecting this change and trust the new key,\n"
2476 "hit Yes to update PuTTY's cache and continue connecting.\n"
2477 "If you want to carry on connecting but without updating\n"
2478 "the cache, hit No.\n"
2479 "If you want to abandon the connection completely, hit\n"
2480 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2482 static const char mbtitle[] = "PuTTY Security Alert";
2486 /* sensible fingerprint max size */
2487 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2488 sizeof(absentmsg) : sizeof(wrongmsg))];
2491 * Verify the key against the registry.
2493 ret = verify_host_key(host, port, keytype, keystr);
2495 if (ret == 0) /* success - key matched OK */
2497 if (ret == 2) { /* key was different */
2499 sprintf(message, wrongmsg, fingerprint);
2500 mbret = MessageBox(NULL, message, mbtitle,
2501 MB_ICONWARNING | MB_YESNOCANCEL);
2503 store_host_key(host, port, keytype, keystr);
2504 if (mbret == IDCANCEL)
2507 if (ret == 1) { /* key was absent */
2509 sprintf(message, absentmsg, fingerprint);
2510 mbret = MessageBox(NULL, message, mbtitle,
2511 MB_ICONWARNING | MB_YESNO);
2514 store_host_key(host, port, keytype, keystr);
2519 * Ask whether to wipe a session log file before writing to it.
2520 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2522 int askappend(char *filename)
2524 static const char mbtitle[] = "PuTTY Log to File";
2525 static const char msgtemplate[] =
2526 "The session log file \"%.*s\" already exists.\n"
2527 "You can overwrite it with a new session log,\n"
2528 "append your session log to the end of it,\n"
2529 "or disable session logging for this session.\n"
2530 "Hit Yes to wipe the file, No to append to it,\n"
2531 "or Cancel to disable logging.";
2532 char message[sizeof(msgtemplate) + FILENAME_MAX];
2534 if (cfg.logxfovr != LGXF_ASK) {
2535 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2537 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2539 mbret = MessageBox(NULL, message, mbtitle,
2540 MB_ICONQUESTION | MB_YESNOCANCEL);
2543 else if (mbret == IDNO)