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_clip(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,
361 appearancepanelstart,
362 IDC_TITLE_APPEARANCE,
382 connectionpanelstart,
383 IDC_TITLE_CONNECTION,
481 translationpanelstart,
482 IDC_TITLE_TRANSLATION,
483 IDC_BOX_TRANSLATION1,
484 IDC_BOX_TRANSLATION2,
485 IDC_BOX_TRANSLATION3,
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 CheckRadioButton(hwnd, IDC_ECHOBACKEND, IDC_ECHONO,
589 cfg.localecho == LD_BACKEND ? IDC_ECHOBACKEND :
590 cfg.localecho == LD_YES ? IDC_ECHOYES : IDC_ECHONO);
591 CheckRadioButton(hwnd, IDC_EDITBACKEND, IDC_EDITNO,
592 cfg.localedit == LD_BACKEND ? IDC_EDITBACKEND :
593 cfg.localedit == LD_YES ? IDC_EDITYES : IDC_EDITNO);
594 SetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback);
595 CheckDlgButton(hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
596 CheckDlgButton(hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
597 CheckDlgButton(hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
599 CheckDlgButton(hwnd, IDC_WRAPMODE, cfg.wrap_mode);
600 CheckDlgButton(hwnd, IDC_DECOM, cfg.dec_om);
601 CheckDlgButton(hwnd, IDC_LFHASCR, cfg.lfhascr);
602 SetDlgItemInt(hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
603 SetDlgItemInt(hwnd, IDC_COLSEDIT, cfg.width, FALSE);
604 SetDlgItemInt(hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
606 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
607 CheckRadioButton(hwnd, IDC_BELL_DISABLED, IDC_BELL_VISUAL,
608 cfg.beep == BELL_DISABLED ? IDC_BELL_DISABLED :
609 cfg.beep == BELL_DEFAULT ? IDC_BELL_DEFAULT :
610 cfg.beep == BELL_WAVEFILE ? IDC_BELL_WAVEFILE :
612 BELL_VISUAL ? IDC_BELL_VISUAL : IDC_BELL_DEFAULT);
613 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT, cfg.bell_wavefile);
614 CheckDlgButton(hwnd, IDC_BELLOVL, cfg.bellovl);
615 SetDlgItemInt(hwnd, IDC_BELLOVLN, cfg.bellovl_n, FALSE);
616 MySetDlgItemFlt(hwnd, IDC_BELLOVLT, cfg.bellovl_t / 1000.0);
617 MySetDlgItemFlt(hwnd, IDC_BELLOVLS, cfg.bellovl_s / 1000.0);
619 CheckDlgButton(hwnd, IDC_BCE, cfg.bce);
620 CheckDlgButton(hwnd, IDC_BLINKTEXT, cfg.blinktext);
622 SetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle);
623 CheckDlgButton(hwnd, IDC_WINNAME, cfg.win_name_always);
624 CheckDlgButton(hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
625 CheckDlgButton(hwnd, IDC_SUNKENEDGE, cfg.sunken_edge);
626 CheckRadioButton(hwnd, IDC_CURBLOCK, IDC_CURVERT,
627 cfg.cursor_type == 0 ? IDC_CURBLOCK :
628 cfg.cursor_type == 1 ? IDC_CURUNDER : IDC_CURVERT);
629 CheckDlgButton(hwnd, IDC_BLINKCUR, cfg.blink_cur);
630 CheckDlgButton(hwnd, IDC_SCROLLBAR, cfg.scrollbar);
631 CheckDlgButton(hwnd, IDC_LOCKSIZE, cfg.locksize);
632 CheckRadioButton(hwnd, IDC_COEALWAYS, IDC_COENORMAL,
633 cfg.close_on_exit == COE_NORMAL ? IDC_COENORMAL :
635 COE_NEVER ? IDC_COENEVER : IDC_COEALWAYS);
636 CheckDlgButton(hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
638 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
639 SetDlgItemText(hwnd, IDC_TSEDIT, cfg.termspeed);
640 SetDlgItemText(hwnd, IDC_R_TSEDIT, cfg.termspeed);
641 SetDlgItemText(hwnd, IDC_RLLUSEREDIT, cfg.localusername);
642 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
643 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
644 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
645 cfg.logtype == 0 ? IDC_LSTATOFF :
646 cfg.logtype == 1 ? IDC_LSTATASCII : IDC_LSTATRAW);
647 CheckRadioButton(hwnd, IDC_LSTATXOVR, IDC_LSTATXASK,
648 cfg.logxfovr == LGXF_OVR ? IDC_LSTATXOVR :
649 cfg.logxfovr == LGXF_ASK ? IDC_LSTATXASK :
652 char *p = cfg.environmt;
654 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
659 CheckRadioButton(hwnd, IDC_EMBSD, IDC_EMRFC,
660 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
662 SetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype);
663 SetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username);
664 CheckDlgButton(hwnd, IDC_NOPTY, cfg.nopty);
665 CheckDlgButton(hwnd, IDC_COMPRESS, cfg.compression);
666 CheckDlgButton(hwnd, IDC_BUGGYMAC, cfg.buggymac);
667 CheckDlgButton(hwnd, IDC_AGENTFWD, cfg.agentfwd);
668 CheckRadioButton(hwnd, IDC_CIPHER3DES, IDC_CIPHERAES,
669 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
670 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
671 cfg.cipher == CIPHER_AES ? IDC_CIPHERAES :
673 CheckRadioButton(hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
674 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
675 CheckDlgButton(hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
676 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
677 SetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd);
679 CheckRadioButton(hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
680 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
681 CheckDlgButton(hwnd, IDC_RAWCNP, cfg.rawcnp);
683 static int tabs[4] = { 25, 61, 96, 128 };
684 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
687 for (i = 0; i < 256; i++) {
689 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
690 (i >= 0x21 && i != 0x7F) ? i : ' ', cfg.wordness[i]);
691 SendDlgItemMessage(hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
695 CheckDlgButton(hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
696 CheckDlgButton(hwnd, IDC_PALETTE, cfg.try_palette);
699 n = SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
700 for (i = n; i-- > 0;)
701 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
702 LB_DELETESTRING, i, 0);
703 for (i = 0; i < 22; i++)
704 if (cfg.bold_colour || permcolour[i])
705 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
706 (LPARAM) colours[i]);
708 SendDlgItemMessage(hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
709 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
710 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
711 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
713 CheckRadioButton(hwnd, IDC_NOXLAT, IDC_88592CP852,
714 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
715 cfg.xlat_88592cp852 ? IDC_88592CP852 :
716 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 : IDC_NOXLAT);
717 CheckDlgButton(hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
718 CheckRadioButton(hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
719 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
720 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
721 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
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, 4,
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, NULL);
1016 beginbox(&cp, "Enable character set translation on received data",
1017 IDC_BOX_TRANSLATION2);
1019 "Character set &translation:", IDC_XLATSTATIC,
1021 "KOI8 / Win-1251", IDC_KOI8WIN1251,
1022 "ISO-8859-2 / Win-1250", IDC_88592WIN1250,
1023 "ISO-8859-2 / CP852", IDC_88592CP852, NULL);
1025 beginbox(&cp, "Enable character set translation on input data",
1026 IDC_BOX_TRANSLATION3);
1027 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
1032 if (panel == selectionpanelstart) {
1033 /* The Selection panel. Accelerators used: [acgo] d wx hst */
1035 ctlposinit(&cp, hwnd, 80, 3, 13);
1036 bartitle(&cp, "Options controlling copy and paste",
1037 IDC_TITLE_SELECTION);
1038 beginbox(&cp, "Translation of pasted characters",
1039 IDC_BOX_SELECTION1);
1041 "&Don't translate line drawing chars into +, - and |",
1044 beginbox(&cp, "Control which mouse button does which thing",
1045 IDC_BOX_SELECTION2);
1046 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
1047 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
1048 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
1051 beginbox(&cp, "Control the select-one-word-at-a-time mode",
1052 IDC_BOX_SELECTION3);
1053 charclass(&cp, "C&haracter classes:", IDC_CCSTATIC, IDC_CCLIST,
1054 "&Set", IDC_CCSET, IDC_CCEDIT,
1055 "&to class", IDC_CCSTATIC2);
1059 if (panel == colourspanelstart) {
1060 /* The Colours panel. Accelerators used: [acgo] blum */
1062 ctlposinit(&cp, hwnd, 80, 3, 13);
1063 bartitle(&cp, "Options controlling use of colours",
1065 beginbox(&cp, "General options for colour usage",
1067 checkbox(&cp, "&Bolded text is a different colour",
1069 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
1071 beginbox(&cp, "Adjust the precise colours PuTTY displays",
1073 colouredit(&cp, "Select a colo&ur and then click to modify it:",
1074 IDC_COLOURSTATIC, IDC_COLOURLIST,
1075 "&Modify...", IDC_CHANGE,
1076 "Red:", IDC_RSTATIC, IDC_RVALUE,
1077 "Green:", IDC_GSTATIC, IDC_GVALUE,
1078 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
1082 if (panel == connectionpanelstart) {
1083 /* The Connection panel. Accelerators used: [acgo] tuk */
1085 ctlposinit(&cp, hwnd, 80, 3, 13);
1086 bartitle(&cp, "Options controlling the connection",
1087 IDC_TITLE_CONNECTION);
1089 beginbox(&cp, "Data to send to the server",
1090 IDC_BOX_CONNECTION1);
1091 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC,
1093 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC,
1097 beginbox(&cp, "Sending of null packets to keep session active",
1098 IDC_BOX_CONNECTION2);
1099 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1100 IDC_PINGSTATIC, IDC_PINGEDIT, 20);
1104 if (panel == telnetpanelstart) {
1105 /* The Telnet panel. Accelerators used: [acgo] svldr bf */
1107 ctlposinit(&cp, hwnd, 80, 3, 13);
1109 bartitle(&cp, "Options controlling Telnet connections",
1111 beginbox(&cp, "Data to send to the server", IDC_BOX_TELNET1);
1112 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC,
1114 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1115 "&Variable", IDC_VARSTATIC, IDC_VAREDIT, "Va&lue",
1116 IDC_VALSTATIC, IDC_VALEDIT, IDC_ENVLIST, "A&dd",
1117 IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1119 beginbox(&cp, "Telnet protocol adjustments", IDC_BOX_TELNET2);
1120 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:",
1121 IDC_EMSTATIC, 2, "&BSD (commonplace)", IDC_EMBSD,
1122 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1127 if (panel == rloginpanelstart) {
1128 /* The Rlogin panel. Accelerators used: [acgo] sl */
1130 ctlposinit(&cp, hwnd, 80, 3, 13);
1132 bartitle(&cp, "Options controlling Rlogin connections",
1134 beginbox(&cp, "Data to send to the server", IDC_BOX_RLOGIN1);
1135 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC,
1137 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC,
1138 IDC_RLLUSEREDIT, 50);
1143 if (panel == sshpanelstart) {
1144 /* The SSH panel. Accelerators used: [acgo] rmfkw pe123bds i */
1146 ctlposinit(&cp, hwnd, 80, 3, 13);
1148 bartitle(&cp, "Options controlling SSH connections",
1150 beginbox(&cp, "Data to send to the server", IDC_BOX_SSH1);
1152 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1155 beginbox(&cp, "Authentication options", IDC_BOX_SSH2);
1156 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1158 checkbox(&cp, "Allow agent &forwarding", IDC_AGENTFWD);
1159 editbutton(&cp, "Private &key file for authentication:",
1160 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...",
1163 beginbox(&cp, "Protocol options", IDC_BOX_SSH3);
1164 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1165 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1166 radioline(&cp, "Preferred SSH protocol version:",
1167 IDC_SSHPROTSTATIC, 2,
1168 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1169 radioline(&cp, "Preferred encryption algorithm:",
1170 IDC_CIPHERSTATIC, 4, "&3DES", IDC_CIPHER3DES,
1171 "&Blowfish", IDC_CIPHERBLOWF, "&DES", IDC_CIPHERDES,
1172 "AE&S", IDC_CIPHERAES, NULL);
1173 checkbox(&cp, "&Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1179 if (panel == tunnelspanelstart) {
1180 /* The Tunnels panel. Accelerators used: [acgo] ex */
1182 ctlposinit(&cp, hwnd, 80, 3, 13);
1184 bartitle(&cp, "Options controlling SSH tunnelling",
1186 beginbox(&cp, "X11 forwarding options", IDC_BOX_TUNNELS);
1187 checkbox(&cp, "&Enable X11 forwarding", IDC_X11_FORWARD);
1188 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1189 IDC_X11_DISPLAY, 50, NULL);
1196 * This function is the configuration box.
1198 static int GenericMainDlgProc(HWND hwnd, UINT msg,
1199 WPARAM wParam, LPARAM lParam, int dlgtype)
1202 struct treeview_faff tvfaff;
1205 char filename[sizeof(cfg.keyfile)];
1208 char fontstatic[256];
1210 struct servent *service;
1216 SetWindowLong(hwnd, GWL_USERDATA, 0);
1218 * Centre the window.
1220 { /* centre the window */
1223 hw = GetDesktopWindow();
1224 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1226 (rs.right + rs.left + rd.left - rd.right) / 2,
1227 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1228 rd.right - rd.left, rd.bottom - rd.top, TRUE);
1232 * Create the tree view.
1240 r.right = r.left + 75;
1242 r.bottom = r.top + 10;
1243 MapDialogRect(hwnd, &r);
1244 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1245 WS_CHILD | WS_VISIBLE,
1247 r.right - r.left, r.bottom - r.top,
1248 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1250 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1251 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1254 r.right = r.left + 75;
1256 r.bottom = r.top + 206;
1257 MapDialogRect(hwnd, &r);
1258 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1259 WS_CHILD | WS_VISIBLE |
1260 WS_TABSTOP | TVS_HASLINES |
1261 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1263 TVS_SHOWSELALWAYS, r.left, r.top,
1264 r.right - r.left, r.bottom - r.top,
1265 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1267 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1268 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1269 tvfaff.treeview = treeview;
1270 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1274 * Set up the tree view contents.
1276 hsession = treeview_insert(&tvfaff, 0, "Session");
1277 treeview_insert(&tvfaff, 1, "Logging");
1278 treeview_insert(&tvfaff, 0, "Terminal");
1279 treeview_insert(&tvfaff, 1, "Keyboard");
1280 treeview_insert(&tvfaff, 1, "Bell");
1281 treeview_insert(&tvfaff, 0, "Window");
1282 treeview_insert(&tvfaff, 1, "Appearance");
1283 treeview_insert(&tvfaff, 1, "Translation");
1284 treeview_insert(&tvfaff, 1, "Selection");
1285 treeview_insert(&tvfaff, 1, "Colours");
1286 treeview_insert(&tvfaff, 0, "Connection");
1288 treeview_insert(&tvfaff, 1, "Telnet");
1289 treeview_insert(&tvfaff, 1, "Rlogin");
1290 if (backends[3].backend != NULL) {
1291 treeview_insert(&tvfaff, 1, "SSH");
1292 treeview_insert(&tvfaff, 2, "Tunnels");
1297 * Put the treeview selection on to the Session panel. This
1298 * should also cause creation of the relevant controls.
1300 TreeView_SelectItem(treeview, hsession);
1303 * Set focus into the first available control.
1307 ctl = GetDlgItem(hwnd, IDC_HOST);
1309 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1313 SetWindowLong(hwnd, GWL_USERDATA, 1);
1317 * Button release should trigger WM_OK if there was a
1318 * previous double click on the session list.
1322 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1325 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1326 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1328 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
1333 item.pszText = buffer;
1334 item.cchTextMax = sizeof(buffer);
1335 item.mask = TVIF_TEXT;
1336 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
1337 for (j = controlstartvalue; j < controlendvalue; j++) {
1338 HWND item = GetDlgItem(hwnd, j);
1340 DestroyWindow(item);
1342 if (!strcmp(buffer, "Session"))
1343 create_controls(hwnd, dlgtype, sessionpanelstart);
1344 if (!strcmp(buffer, "Logging"))
1345 create_controls(hwnd, dlgtype, loggingpanelstart);
1346 if (!strcmp(buffer, "Keyboard"))
1347 create_controls(hwnd, dlgtype, keyboardpanelstart);
1348 if (!strcmp(buffer, "Terminal"))
1349 create_controls(hwnd, dlgtype, terminalpanelstart);
1350 if (!strcmp(buffer, "Bell"))
1351 create_controls(hwnd, dlgtype, bellpanelstart);
1352 if (!strcmp(buffer, "Window"))
1353 create_controls(hwnd, dlgtype, windowpanelstart);
1354 if (!strcmp(buffer, "Appearance"))
1355 create_controls(hwnd, dlgtype, appearancepanelstart);
1356 if (!strcmp(buffer, "Tunnels"))
1357 create_controls(hwnd, dlgtype, tunnelspanelstart);
1358 if (!strcmp(buffer, "Connection"))
1359 create_controls(hwnd, dlgtype, connectionpanelstart);
1360 if (!strcmp(buffer, "Telnet"))
1361 create_controls(hwnd, dlgtype, telnetpanelstart);
1362 if (!strcmp(buffer, "Rlogin"))
1363 create_controls(hwnd, dlgtype, rloginpanelstart);
1364 if (!strcmp(buffer, "SSH"))
1365 create_controls(hwnd, dlgtype, sshpanelstart);
1366 if (!strcmp(buffer, "Selection"))
1367 create_controls(hwnd, dlgtype, selectionpanelstart);
1368 if (!strcmp(buffer, "Colours"))
1369 create_controls(hwnd, dlgtype, colourspanelstart);
1370 if (!strcmp(buffer, "Translation"))
1371 create_controls(hwnd, dlgtype, translationpanelstart);
1373 init_dlg_ctrls(hwnd);
1375 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
1381 * Only process WM_COMMAND once the dialog is fully formed.
1383 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1384 switch (LOWORD(wParam)) {
1394 case IDC_PROTTELNET:
1395 case IDC_PROTRLOGIN:
1398 if (HIWORD(wParam) == BN_CLICKED ||
1399 HIWORD(wParam) == BN_DOUBLECLICKED) {
1400 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1401 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1402 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1404 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1406 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1407 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1408 || (cfg.protocol == PROT_RLOGIN
1409 && cfg.port != 513)) {
1410 cfg.port = i ? 22 : j ? 23 : 513;
1411 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1416 if (HIWORD(wParam) == EN_CHANGE)
1417 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1418 sizeof(cfg.host) - 1);
1421 if (HIWORD(wParam) == EN_CHANGE) {
1422 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1423 if (isdigit(portname[0]))
1424 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1426 service = getservbyname(portname, NULL);
1428 cfg.port = ntohs(service->s_port);
1435 if (HIWORD(wParam) == EN_CHANGE) {
1436 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1438 GetDlgItemText(hwnd, IDC_SESSEDIT,
1439 savedsession, sizeof(savedsession) - 1);
1440 savedsession[sizeof(savedsession) - 1] = '\0';
1444 if (HIWORD(wParam) == BN_CLICKED ||
1445 HIWORD(wParam) == BN_DOUBLECLICKED) {
1450 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1453 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1454 LB_GETCURSEL, 0, 0);
1459 strcpy(str, sessions[n]);
1461 save_settings(str, !!strcmp(str, "Default Settings"),
1463 get_sesslist(FALSE);
1465 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1467 for (i = 0; i < nsessions; i++)
1468 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1470 (LPARAM) (sessions[i]));
1471 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1477 if (LOWORD(wParam) == IDC_SESSLOAD &&
1478 HIWORD(wParam) != BN_CLICKED &&
1479 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1480 if (LOWORD(wParam) == IDC_SESSLIST &&
1481 HIWORD(wParam) != LBN_DBLCLK) break;
1483 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1484 LB_GETCURSEL, 0, 0);
1490 isdef = !strcmp(sessions[n], "Default Settings");
1491 load_settings(sessions[n], !isdef, &cfg);
1492 init_dlg_ctrls(hwnd);
1494 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1496 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1498 if (LOWORD(wParam) == IDC_SESSLIST) {
1500 * A double-click on a saved session should
1501 * actually start the session, not just load it.
1502 * Unless it's Default Settings or some other
1503 * host-less set of saved settings.
1512 if (HIWORD(wParam) == BN_CLICKED ||
1513 HIWORD(wParam) == BN_DOUBLECLICKED) {
1514 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1515 LB_GETCURSEL, 0, 0);
1516 if (n == LB_ERR || n == 0) {
1520 del_settings(sessions[n]);
1521 get_sesslist(FALSE);
1523 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1525 for (i = 0; i < nsessions; i++)
1526 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1528 (LPARAM) (sessions[i]));
1529 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1533 if (HIWORD(wParam) == EN_CHANGE)
1534 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1535 &cfg.ping_interval);
1539 if (HIWORD(wParam) == BN_CLICKED ||
1540 HIWORD(wParam) == BN_DOUBLECLICKED)
1541 cfg.bksp_is_delete =
1542 IsDlgButtonChecked(hwnd, IDC_DEL127);
1546 if (HIWORD(wParam) == BN_CLICKED ||
1547 HIWORD(wParam) == BN_DOUBLECLICKED)
1549 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1555 case IDC_FUNCVT100P:
1557 if (HIWORD(wParam) == BN_CLICKED ||
1558 HIWORD(wParam) == BN_DOUBLECLICKED)
1559 switch (LOWORD(wParam)) {
1572 case IDC_FUNCVT100P:
1582 if (HIWORD(wParam) == BN_CLICKED ||
1583 HIWORD(wParam) == BN_DOUBLECLICKED) {
1585 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1586 cfg.nethack_keypad = FALSE;
1590 if (HIWORD(wParam) == BN_CLICKED ||
1591 HIWORD(wParam) == BN_DOUBLECLICKED) {
1592 cfg.app_keypad = FALSE;
1593 cfg.nethack_keypad = TRUE;
1598 if (HIWORD(wParam) == BN_CLICKED ||
1599 HIWORD(wParam) == BN_DOUBLECLICKED)
1601 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1604 if (HIWORD(wParam) == BN_CLICKED ||
1605 HIWORD(wParam) == BN_DOUBLECLICKED)
1607 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1610 if (HIWORD(wParam) == BN_CLICKED ||
1611 HIWORD(wParam) == BN_DOUBLECLICKED)
1613 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1616 if (HIWORD(wParam) == BN_CLICKED ||
1617 HIWORD(wParam) == BN_DOUBLECLICKED)
1618 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1621 if (HIWORD(wParam) == BN_CLICKED ||
1622 HIWORD(wParam) == BN_DOUBLECLICKED)
1624 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1627 if (HIWORD(wParam) == BN_CLICKED ||
1628 HIWORD(wParam) == BN_DOUBLECLICKED)
1630 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1632 case IDC_ECHOBACKEND:
1635 if (HIWORD(wParam) == BN_CLICKED ||
1636 HIWORD(wParam) == BN_DOUBLECLICKED) {
1637 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1638 cfg.localecho = LD_BACKEND;
1639 if (LOWORD(wParam) == IDC_ECHOYES)
1640 cfg.localecho = LD_YES;
1641 if (LOWORD(wParam) == IDC_ECHONO)
1642 cfg.localecho = LD_NO;
1645 case IDC_EDITBACKEND:
1648 if (HIWORD(wParam) == BN_CLICKED ||
1649 HIWORD(wParam) == BN_DOUBLECLICKED) {
1650 if (LOWORD(wParam) == IDC_EDITBACKEND)
1651 cfg.localedit = LD_BACKEND;
1652 if (LOWORD(wParam) == IDC_EDITYES)
1653 cfg.localedit = LD_YES;
1654 if (LOWORD(wParam) == IDC_EDITNO)
1655 cfg.localedit = LD_NO;
1658 case IDC_ANSWEREDIT:
1659 if (HIWORD(wParam) == EN_CHANGE)
1660 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1661 sizeof(cfg.answerback) - 1);
1663 case IDC_ALWAYSONTOP:
1664 if (HIWORD(wParam) == BN_CLICKED ||
1665 HIWORD(wParam) == BN_DOUBLECLICKED)
1667 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1670 if (HIWORD(wParam) == BN_CLICKED ||
1671 HIWORD(wParam) == BN_DOUBLECLICKED)
1673 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1675 case IDC_SCROLLDISP:
1676 if (HIWORD(wParam) == BN_CLICKED ||
1677 HIWORD(wParam) == BN_DOUBLECLICKED)
1678 cfg.scroll_on_disp =
1679 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1681 case IDC_COMPOSEKEY:
1682 if (HIWORD(wParam) == BN_CLICKED ||
1683 HIWORD(wParam) == BN_DOUBLECLICKED)
1685 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1687 case IDC_CTRLALTKEYS:
1688 if (HIWORD(wParam) == BN_CLICKED ||
1689 HIWORD(wParam) == BN_DOUBLECLICKED)
1691 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1694 if (HIWORD(wParam) == BN_CLICKED ||
1695 HIWORD(wParam) == BN_DOUBLECLICKED)
1697 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1700 if (HIWORD(wParam) == BN_CLICKED ||
1701 HIWORD(wParam) == BN_DOUBLECLICKED)
1702 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1705 if (HIWORD(wParam) == BN_CLICKED ||
1706 HIWORD(wParam) == BN_DOUBLECLICKED)
1708 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1711 if (HIWORD(wParam) == EN_CHANGE)
1712 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1715 if (HIWORD(wParam) == EN_CHANGE)
1716 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1719 if (HIWORD(wParam) == EN_CHANGE)
1720 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1722 case IDC_CHOOSEFONT:
1725 lf.lfHeight = -MulDiv(cfg.fontheight,
1726 GetDeviceCaps(hdc, LOGPIXELSY),
1730 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1731 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1732 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1733 lf.lfCharSet = cfg.fontcharset;
1734 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1735 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1736 lf.lfQuality = DEFAULT_QUALITY;
1737 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1738 strncpy(lf.lfFaceName, cfg.font,
1739 sizeof(lf.lfFaceName) - 1);
1740 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1742 cf.lStructSize = sizeof(cf);
1743 cf.hwndOwner = hwnd;
1745 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1746 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1748 if (ChooseFont(&cf)) {
1749 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1750 cfg.font[sizeof(cfg.font) - 1] = '\0';
1751 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1752 cfg.fontcharset = lf.lfCharSet;
1753 cfg.fontheight = cf.iPointSize / 10;
1754 fmtfont(fontstatic);
1755 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1758 case IDC_BELL_DISABLED:
1759 case IDC_BELL_DEFAULT:
1760 case IDC_BELL_WAVEFILE:
1761 case IDC_BELL_VISUAL:
1762 if (HIWORD(wParam) == BN_CLICKED ||
1763 HIWORD(wParam) == BN_DOUBLECLICKED) {
1764 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1765 cfg.beep = BELL_DISABLED;
1766 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1767 cfg.beep = BELL_DEFAULT;
1768 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1769 cfg.beep = BELL_WAVEFILE;
1770 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1771 cfg.beep = BELL_VISUAL;
1774 case IDC_BELL_WAVEBROWSE:
1775 memset(&of, 0, sizeof(of));
1776 #ifdef OPENFILENAME_SIZE_VERSION_400
1777 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1779 of.lStructSize = sizeof(of);
1781 of.hwndOwner = hwnd;
1782 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1783 of.lpstrCustomFilter = NULL;
1784 of.nFilterIndex = 1;
1785 of.lpstrFile = filename;
1786 strcpy(filename, cfg.bell_wavefile);
1787 of.nMaxFile = sizeof(filename);
1788 of.lpstrFileTitle = NULL;
1789 of.lpstrInitialDir = NULL;
1790 of.lpstrTitle = "Select Bell Sound File";
1792 if (GetOpenFileName(&of)) {
1793 strcpy(cfg.bell_wavefile, filename);
1794 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1798 case IDC_BELL_WAVEEDIT:
1799 if (HIWORD(wParam) == EN_CHANGE)
1800 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1802 sizeof(cfg.bell_wavefile) - 1);
1805 if (HIWORD(wParam) == BN_CLICKED ||
1806 HIWORD(wParam) == BN_DOUBLECLICKED)
1808 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1811 if (HIWORD(wParam) == EN_CHANGE)
1812 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
1815 if (HIWORD(wParam) == EN_CHANGE)
1816 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
1820 if (HIWORD(wParam) == EN_CHANGE)
1821 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
1825 if (HIWORD(wParam) == BN_CLICKED ||
1826 HIWORD(wParam) == BN_DOUBLECLICKED)
1828 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
1831 if (HIWORD(wParam) == BN_CLICKED ||
1832 HIWORD(wParam) == BN_DOUBLECLICKED)
1833 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
1836 if (HIWORD(wParam) == BN_CLICKED ||
1837 HIWORD(wParam) == BN_DOUBLECLICKED)
1838 cfg.win_name_always =
1839 IsDlgButtonChecked(hwnd, IDC_WINNAME);
1842 if (HIWORD(wParam) == BN_CLICKED ||
1843 HIWORD(wParam) == BN_DOUBLECLICKED)
1845 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
1847 case IDC_SUNKENEDGE:
1848 if (HIWORD(wParam) == BN_CLICKED ||
1849 HIWORD(wParam) == BN_DOUBLECLICKED)
1851 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
1854 if (HIWORD(wParam) == BN_CLICKED ||
1855 HIWORD(wParam) == BN_DOUBLECLICKED)
1856 cfg.cursor_type = 0;
1859 if (HIWORD(wParam) == BN_CLICKED ||
1860 HIWORD(wParam) == BN_DOUBLECLICKED)
1861 cfg.cursor_type = 1;
1864 if (HIWORD(wParam) == BN_CLICKED ||
1865 HIWORD(wParam) == BN_DOUBLECLICKED)
1866 cfg.cursor_type = 2;
1869 if (HIWORD(wParam) == BN_CLICKED ||
1870 HIWORD(wParam) == BN_DOUBLECLICKED)
1872 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
1875 if (HIWORD(wParam) == BN_CLICKED ||
1876 HIWORD(wParam) == BN_DOUBLECLICKED)
1878 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
1881 if (HIWORD(wParam) == BN_CLICKED ||
1882 HIWORD(wParam) == BN_DOUBLECLICKED)
1884 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
1887 if (HIWORD(wParam) == EN_CHANGE)
1888 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
1889 sizeof(cfg.wintitle) - 1);
1894 if (HIWORD(wParam) == BN_CLICKED ||
1895 HIWORD(wParam) == BN_DOUBLECLICKED) {
1897 IsDlgButtonChecked(hwnd,
1898 IDC_COEALWAYS) ? COE_ALWAYS :
1899 IsDlgButtonChecked(hwnd,
1900 IDC_COENEVER) ? COE_NEVER :
1905 if (HIWORD(wParam) == BN_CLICKED ||
1906 HIWORD(wParam) == BN_DOUBLECLICKED)
1908 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
1911 if (HIWORD(wParam) == EN_CHANGE)
1912 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
1913 sizeof(cfg.termtype) - 1);
1916 if (HIWORD(wParam) == EN_CHANGE)
1917 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
1918 sizeof(cfg.logfilename) - 1);
1921 memset(&of, 0, sizeof(of));
1922 #ifdef OPENFILENAME_SIZE_VERSION_400
1923 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1925 of.lStructSize = sizeof(of);
1927 of.hwndOwner = hwnd;
1928 of.lpstrFilter = "All Files\0*\0\0\0";
1929 of.lpstrCustomFilter = NULL;
1930 of.nFilterIndex = 1;
1931 of.lpstrFile = filename;
1932 strcpy(filename, cfg.logfilename);
1933 of.nMaxFile = sizeof(filename);
1934 of.lpstrFileTitle = NULL;
1935 of.lpstrInitialDir = NULL;
1936 of.lpstrTitle = "Select session log file";
1938 if (GetSaveFileName(&of)) {
1939 strcpy(cfg.logfilename, filename);
1940 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
1944 case IDC_LSTATASCII:
1946 if (HIWORD(wParam) == BN_CLICKED ||
1947 HIWORD(wParam) == BN_DOUBLECLICKED) {
1948 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
1950 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
1952 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
1959 if (HIWORD(wParam) == BN_CLICKED ||
1960 HIWORD(wParam) == BN_DOUBLECLICKED) {
1961 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
1962 cfg.logxfovr = LGXF_ASK;
1963 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
1964 cfg.logxfovr = LGXF_APN;
1965 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
1966 cfg.logxfovr = LGXF_OVR;
1971 if (HIWORD(wParam) == EN_CHANGE)
1972 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
1973 sizeof(cfg.termspeed) - 1);
1976 if (HIWORD(wParam) == EN_CHANGE)
1977 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
1978 sizeof(cfg.username) - 1);
1980 case IDC_RLLUSEREDIT:
1981 if (HIWORD(wParam) == EN_CHANGE)
1982 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
1984 sizeof(cfg.localusername) - 1);
1988 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
1991 if (HIWORD(wParam) == BN_CLICKED ||
1992 HIWORD(wParam) == BN_DOUBLECLICKED) {
1993 char str[sizeof(cfg.environmt)];
1995 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2001 p = str + strlen(str);
2003 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2004 sizeof(str) - 1 - (p - str));
2015 if ((p - cfg.environmt) + strlen(str) + 2 <
2016 sizeof(cfg.environmt)) {
2018 p[strlen(str) + 1] = '\0';
2019 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2021 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2022 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2024 MessageBox(hwnd, "Environment too big",
2025 "PuTTY Error", MB_OK | MB_ICONERROR);
2030 if (HIWORD(wParam) != BN_CLICKED &&
2031 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2033 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2040 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2067 if (HIWORD(wParam) == BN_CLICKED ||
2068 HIWORD(wParam) == BN_DOUBLECLICKED)
2069 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2072 if (HIWORD(wParam) == BN_CLICKED ||
2073 HIWORD(wParam) == BN_DOUBLECLICKED)
2075 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2078 if (HIWORD(wParam) == BN_CLICKED ||
2079 HIWORD(wParam) == BN_DOUBLECLICKED)
2081 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2084 if (HIWORD(wParam) == BN_CLICKED ||
2085 HIWORD(wParam) == BN_DOUBLECLICKED)
2087 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2089 case IDC_CIPHER3DES:
2090 case IDC_CIPHERBLOWF:
2093 if (HIWORD(wParam) == BN_CLICKED ||
2094 HIWORD(wParam) == BN_DOUBLECLICKED) {
2095 if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES))
2096 cfg.cipher = CIPHER_3DES;
2097 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF))
2098 cfg.cipher = CIPHER_BLOWFISH;
2099 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES))
2100 cfg.cipher = CIPHER_DES;
2101 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES))
2102 cfg.cipher = CIPHER_AES;
2107 if (HIWORD(wParam) == BN_CLICKED ||
2108 HIWORD(wParam) == BN_DOUBLECLICKED) {
2109 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2111 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2116 if (HIWORD(wParam) == BN_CLICKED ||
2117 HIWORD(wParam) == BN_DOUBLECLICKED)
2119 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2122 if (HIWORD(wParam) == EN_CHANGE)
2123 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2124 sizeof(cfg.keyfile) - 1);
2127 if (HIWORD(wParam) == EN_CHANGE)
2128 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2129 sizeof(cfg.remote_cmd) - 1);
2132 memset(&of, 0, sizeof(of));
2133 #ifdef OPENFILENAME_SIZE_VERSION_400
2134 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
2136 of.lStructSize = sizeof(of);
2138 of.hwndOwner = hwnd;
2139 of.lpstrFilter = "All Files\0*\0\0\0";
2140 of.lpstrCustomFilter = NULL;
2141 of.nFilterIndex = 1;
2142 of.lpstrFile = filename;
2143 strcpy(filename, cfg.keyfile);
2144 of.nMaxFile = sizeof(filename);
2145 of.lpstrFileTitle = NULL;
2146 of.lpstrInitialDir = NULL;
2147 of.lpstrTitle = "Select Public Key File";
2149 if (GetOpenFileName(&of)) {
2150 strcpy(cfg.keyfile, filename);
2151 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
2155 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2158 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2164 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2169 for (i = 0; i < 256; i++)
2170 if (SendDlgItemMessage
2171 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2173 cfg.wordness[i] = n;
2174 SendDlgItemMessage(hwnd, IDC_CCLIST,
2175 LB_DELETESTRING, i, 0);
2176 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2177 (i >= 0x21 && i != 0x7F) ? i : ' ',
2179 SendDlgItemMessage(hwnd, IDC_CCLIST,
2186 case IDC_BOLDCOLOUR:
2187 if (HIWORD(wParam) == BN_CLICKED ||
2188 HIWORD(wParam) == BN_DOUBLECLICKED) {
2191 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2193 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2195 if (n != 12 + 10 * cfg.bold_colour) {
2196 for (i = n; i-- > 0;)
2197 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2198 LB_DELETESTRING, i, 0);
2199 for (i = 0; i < 22; i++)
2200 if (cfg.bold_colour || permcolour[i])
2201 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2203 (LPARAM) colours[i]);
2208 if (HIWORD(wParam) == BN_CLICKED ||
2209 HIWORD(wParam) == BN_DOUBLECLICKED)
2211 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2213 case IDC_COLOURLIST:
2214 if (HIWORD(wParam) == LBN_DBLCLK ||
2215 HIWORD(wParam) == LBN_SELCHANGE) {
2216 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2219 if (!cfg.bold_colour)
2220 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2221 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2223 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2225 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2230 if (HIWORD(wParam) == BN_CLICKED ||
2231 HIWORD(wParam) == BN_DOUBLECLICKED) {
2232 static CHOOSECOLOR cc;
2233 static DWORD custom[16] = { 0 }; /* zero initialisers */
2234 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2237 if (!cfg.bold_colour)
2238 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2239 cc.lStructSize = sizeof(cc);
2240 cc.hwndOwner = hwnd;
2241 cc.hInstance = (HWND) hinst;
2242 cc.lpCustColors = custom;
2244 RGB(cfg.colours[i][0], cfg.colours[i][1],
2246 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2247 if (ChooseColor(&cc)) {
2249 (unsigned char) (cc.rgbResult & 0xFF);
2251 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2253 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2254 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2256 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2258 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2264 case IDC_KOI8WIN1251:
2265 case IDC_88592WIN1250:
2266 case IDC_88592CP852:
2267 cfg.xlat_enablekoiwin =
2268 IsDlgButtonChecked(hwnd, IDC_KOI8WIN1251);
2269 cfg.xlat_88592w1250 =
2270 IsDlgButtonChecked(hwnd, IDC_88592WIN1250);
2271 cfg.xlat_88592cp852 =
2272 IsDlgButtonChecked(hwnd, IDC_88592CP852);
2274 case IDC_CAPSLOCKCYR:
2275 if (HIWORD(wParam) == BN_CLICKED ||
2276 HIWORD(wParam) == BN_DOUBLECLICKED) {
2277 cfg.xlat_capslockcyr =
2278 IsDlgButtonChecked(hwnd, IDC_CAPSLOCKCYR);
2281 case IDC_VTXWINDOWS:
2286 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2287 : IsDlgButtonChecked(hwnd,
2288 IDC_VTOEMANSI) ? VT_OEMANSI :
2289 IsDlgButtonChecked(hwnd,
2290 IDC_VTOEMONLY) ? VT_OEMONLY :
2293 case IDC_X11_FORWARD:
2294 if (HIWORD(wParam) == BN_CLICKED ||
2295 HIWORD(wParam) == BN_DOUBLECLICKED)
2297 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2299 case IDC_X11_DISPLAY:
2300 if (HIWORD(wParam) == EN_CHANGE)
2301 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2302 sizeof(cfg.x11_display) - 1);
2310 /* Grrr Explorer will maximize Dialogs! */
2312 if (wParam == SIZE_MAXIMIZED)
2319 static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2320 WPARAM wParam, LPARAM lParam)
2322 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2324 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2325 EnableWindow(hwnd, 0);
2326 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2327 GetParent(hwnd), AboutProc);
2328 EnableWindow(hwnd, 1);
2329 SetActiveWindow(hwnd);
2331 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
2334 static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2335 WPARAM wParam, LPARAM lParam)
2337 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
2340 void defuse_showwindow(void)
2343 * Work around the fact that the app's first call to ShowWindow
2344 * will ignore the default in favour of the shell-provided
2349 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2351 ShowWindow(hwnd, SW_HIDE);
2352 DestroyWindow(hwnd);
2361 savedsession[0] = '\0';
2363 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2364 get_sesslist(FALSE);
2369 int do_reconfig(HWND hwnd)
2374 backup_cfg = cfg; /* structure copy */
2376 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2378 cfg = backup_cfg; /* structure copy */
2383 void logevent(char *string)
2388 if (nevents >= negsize) {
2390 events = srealloc(events, negsize * sizeof(*events));
2394 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2397 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
2398 strcpy(events[nevents], timebuf);
2399 strcat(events[nevents], string);
2402 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2403 0, (LPARAM) events[nevents]);
2404 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2405 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
2410 void showeventlog(HWND hwnd)
2413 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2415 ShowWindow(logbox, SW_SHOWNORMAL);
2417 SetActiveWindow(logbox);
2420 void showabout(HWND hwnd)
2422 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
2425 void verify_ssh_host_key(char *host, int port, char *keytype,
2426 char *keystr, char *fingerprint)
2430 static const char absentmsg[] =
2431 "The server's host key is not cached in the registry. You\n"
2432 "have no guarantee that the server is the computer you\n"
2434 "The server's key fingerprint is:\n"
2436 "If you trust this host, hit Yes to add the key to\n"
2437 "PuTTY's cache and carry on connecting.\n"
2438 "If you do not trust this host, hit No to abandon the\n"
2441 static const char wrongmsg[] =
2442 "WARNING - POTENTIAL SECURITY BREACH!\n"
2444 "The server's host key does not match the one PuTTY has\n"
2445 "cached in the registry. This means that either the\n"
2446 "server administrator has changed the host key, or you\n"
2447 "have actually connected to another computer pretending\n"
2448 "to be the server.\n"
2449 "The new key fingerprint is:\n"
2451 "If you were expecting this change and trust the new key,\n"
2452 "hit Yes to update PuTTY's cache and continue connecting.\n"
2453 "If you want to carry on connecting but without updating\n"
2454 "the cache, hit No.\n"
2455 "If you want to abandon the connection completely, hit\n"
2456 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
2458 static const char mbtitle[] = "PuTTY Security Alert";
2462 /* sensible fingerprint max size */
2463 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2464 sizeof(absentmsg) : sizeof(wrongmsg))];
2467 * Verify the key against the registry.
2469 ret = verify_host_key(host, port, keytype, keystr);
2471 if (ret == 0) /* success - key matched OK */
2473 if (ret == 2) { /* key was different */
2475 sprintf(message, wrongmsg, fingerprint);
2476 mbret = MessageBox(NULL, message, mbtitle,
2477 MB_ICONWARNING | MB_YESNOCANCEL);
2479 store_host_key(host, port, keytype, keystr);
2480 if (mbret == IDCANCEL)
2483 if (ret == 1) { /* key was absent */
2485 sprintf(message, absentmsg, fingerprint);
2486 mbret = MessageBox(NULL, message, mbtitle,
2487 MB_ICONWARNING | MB_YESNO);
2490 store_host_key(host, port, keytype, keystr);
2495 * Ask whether to wipe a session log file before writing to it.
2496 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2498 int askappend(char *filename)
2500 static const char mbtitle[] = "PuTTY Log to File";
2501 static const char msgtemplate[] =
2502 "The session log file \"%.*s\" already exists.\n"
2503 "You can overwrite it with a new session log,\n"
2504 "append your session log to the end of it,\n"
2505 "or disable session logging for this session.\n"
2506 "Hit Yes to wipe the file, No to append to it,\n"
2507 "or Cancel to disable logging.";
2508 char message[sizeof(msgtemplate) + FILENAME_MAX];
2510 if (cfg.logxfovr != LGXF_ASK) {
2511 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
2513 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2515 mbret = MessageBox(NULL, message, mbtitle,
2516 MB_ICONQUESTION | MB_YESNOCANCEL);
2519 else if (mbret == IDNO)