13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
16 static HWND logbox = NULL, abtbox = NULL;
20 static void force_normal(HWND hwnd)
22 static int recurse = 0;
29 wp.length = sizeof(wp);
30 if (GetWindowPlacement(hwnd, &wp))
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
38 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
46 static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
52 for (i=0; i<nevents; i++)
53 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
54 0, (LPARAM)events[i]);
57 switch (LOWORD(wParam)) {
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
69 selitems = malloc(selcount * sizeof(int));
71 int count = SendDlgItemMessage(hwnd, IDN_LIST,
73 selcount, (LPARAM)selitems);
77 static unsigned char sel_nl[] = SEL_NL;
79 if (count == 0) { /* can't copy zero stuff */
85 for (i = 0; i < count; i++)
86 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
88 clipdata = malloc(size);
91 for (i = 0; i < count; i++) {
92 char *q = events[selitems[i]];
96 memcpy(p, sel_nl, sizeof(sel_nl));
99 write_clip(clipdata, size, TRUE);
104 for (i = 0; i < nevents; i++)
105 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
114 DestroyWindow (hwnd);
120 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
121 WPARAM wParam, LPARAM lParam) {
126 switch (LOWORD(wParam)) {
139 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
140 WPARAM wParam, LPARAM lParam) {
143 SetDlgItemText (hwnd, IDA_VERSION, ver);
146 switch (LOWORD(wParam)) {
149 DestroyWindow (hwnd);
152 EnableWindow(hwnd, 0);
153 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
155 EnableWindow(hwnd, 1);
156 SetActiveWindow(hwnd);
162 DestroyWindow (hwnd);
169 * Null dialog procedure.
171 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
172 WPARAM wParam, LPARAM lParam) {
176 static char savedsession[2048];
178 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
182 IDC_BOX_SESSION1, IDC_BOXT_SESSION1,
183 IDC_BOX_SESSION2, IDC_BOXT_SESSION2,
204 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1,
205 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2,
206 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3,
232 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
244 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
245 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
264 appearancepanelstart,
265 IDC_TITLE_APPEARANCE,
266 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1,
267 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2,
268 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3,
277 connectionpanelstart,
278 IDC_TITLE_CONNECTION,
279 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
280 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
291 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
292 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
310 IDC_BOX_SSH1, IDC_BOXT_SSH1,
311 IDC_BOX_SSH2, IDC_BOXT_SSH2,
312 IDC_BOX_SSH3, IDC_BOXT_SSH3,
334 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
335 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
348 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
349 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
363 translationpanelstart,
364 IDC_TITLE_TRANSLATION,
365 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
366 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
367 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
384 static const char *const colours[] = {
385 "Default Foreground", "Default Bold Foreground",
386 "Default Background", "Default Bold Background",
387 "Cursor Text", "Cursor Colour",
388 "ANSI Black", "ANSI Black Bold",
389 "ANSI Red", "ANSI Red Bold",
390 "ANSI Green", "ANSI Green Bold",
391 "ANSI Yellow", "ANSI Yellow Bold",
392 "ANSI Blue", "ANSI Blue Bold",
393 "ANSI Magenta", "ANSI Magenta Bold",
394 "ANSI Cyan", "ANSI Cyan Bold",
395 "ANSI White", "ANSI White Bold"
397 static const int permcolour[] = {
398 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
399 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
400 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
403 static void fmtfont (char *buf) {
404 sprintf (buf, "Font: %s, ", cfg.font);
406 strcat(buf, "bold, ");
407 if (cfg.fontheight == 0)
408 strcat (buf, "default height");
410 sprintf (buf+strlen(buf), "%d-%s",
411 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
412 (cfg.fontheight < 0 ? "pixel" : "point"));
415 static void init_dlg_ctrls(HWND hwnd) {
417 char fontstatic[256];
419 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
420 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
421 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
422 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
423 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
424 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : IDC_PROTRAW );
425 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
427 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
428 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
429 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
430 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
431 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
432 cfg.funky_type == 0 ? IDC_FUNCTILDE :
433 cfg.funky_type == 1 ? IDC_FUNCLINUX :
434 cfg.funky_type == 2 ? IDC_FUNCXTERM :
435 cfg.funky_type == 3 ? IDC_FUNCVT400 :
437 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
438 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
439 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
440 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
441 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
442 cfg.nethack_keypad ? IDC_KPNH :
443 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
444 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
445 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
446 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
447 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
448 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
449 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
450 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
451 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
453 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
454 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
455 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
456 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
457 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
458 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
459 fmtfont (fontstatic);
460 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
461 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
462 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
463 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
465 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
466 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
467 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
468 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
469 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
470 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
471 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
473 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
474 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
475 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
477 char *p = cfg.environmt;
479 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
484 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
485 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
487 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
488 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
489 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
490 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
491 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
492 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
493 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
494 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
495 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
497 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
498 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
499 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
500 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
501 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
503 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
504 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
506 static int tabs[4] = {25, 61, 96, 128};
507 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
510 for (i=0; i<256; i++) {
512 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
513 (i>=0x21 && i != 0x7F) ? i : ' ',
515 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
519 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
520 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
524 if (cfg.bold_colour || permcolour[i])
525 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
526 (LPARAM) colours[i]);
528 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
529 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
530 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
531 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
533 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
534 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
535 cfg.xlat_88592cp852 ? IDC_88592CP852 :
536 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
538 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
539 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
540 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
541 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
542 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
546 static void hide(HWND hwnd, int hide, int minid, int maxid) {
548 for (i = minid; i < maxid; i++) {
549 HWND ctl = GetDlgItem(hwnd, i);
551 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
556 struct treeview_faff {
561 static HTREEITEM treeview_insert(struct treeview_faff *faff,
562 int level, char *text) {
566 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
567 ins.hInsertAfter = faff->lastat[level];
568 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
569 #define INSITEM DUMMYUNIONNAME.item
573 ins.INSITEM.mask = TVIF_TEXT;
574 ins.INSITEM.pszText = text;
575 newitem = TreeView_InsertItem(faff->treeview, &ins);
577 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
578 faff->lastat[level] = newitem;
579 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
584 * This _huge_ function is the configuration box.
586 static int GenericMainDlgProc (HWND hwnd, UINT msg,
587 WPARAM wParam, LPARAM lParam,
590 struct treeview_faff tvfaff;
593 char filename[sizeof(cfg.keyfile)];
596 char fontstatic[256];
602 SetWindowLong(hwnd, GWL_USERDATA, 0);
606 { /* centre the window */
609 hw = GetDesktopWindow();
610 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
611 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
612 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
613 rd.right-rd.left, rd.bottom-rd.top, TRUE);
617 * Create the tree view.
624 r.left = 3; r.right = r.left + 75;
625 r.top = 3; r.bottom = r.top + 10;
626 MapDialogRect(hwnd, &r);
627 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
628 WS_CHILD | WS_VISIBLE,
630 r.right-r.left, r.bottom-r.top,
631 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
632 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
633 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
635 r.left = 3; r.right = r.left + 75;
636 r.top = 13; r.bottom = r.top + 206;
637 MapDialogRect(hwnd, &r);
638 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
639 WS_CHILD | WS_VISIBLE |
640 WS_TABSTOP | TVS_HASLINES |
641 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
642 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
644 r.right-r.left, r.bottom-r.top,
645 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
646 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
647 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
648 tvfaff.treeview = treeview;
649 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
653 * Create the various panelfuls of controls.
656 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
659 ctlposinit(&cp, hwnd, 80, 3, 13);
660 bartitle(&cp, "Basic options for your PuTTY session",
663 beginbox(&cp, "Specify your connection by host name",
664 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
666 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
667 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
668 if (backends[2].backend == NULL) {
669 /* this is PuTTYtel, so only two protocols available */
670 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
672 "&Telnet", IDC_PROTTELNET, NULL);
674 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
676 "&Telnet", IDC_PROTTELNET,
685 beginbox(&cp, "Load, save or delete a stored session",
686 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
687 sesssaver(&cp, "Sav&ed Sessions",
688 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
689 "&Load", IDC_SESSLOAD,
690 "&Save", IDC_SESSSAVE,
691 "&Delete", IDC_SESSDEL, NULL);
694 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
695 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
698 hsession = treeview_insert(&tvfaff, 0, "Session");
701 /* The Terminal panel. Accelerators used: [acgo] &dlbenu */
704 ctlposinit(&cp, hwnd, 80, 3, 13);
705 bartitle(&cp, "Options controlling the terminal emulation",
707 beginbox(&cp, "Set various terminal options",
708 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
709 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
710 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
711 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
712 checkbox(&cp, "&Beep enabled", IDC_BEEP);
713 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
714 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
715 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
718 treeview_insert(&tvfaff, 0, "Terminal");
721 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
724 ctlposinit(&cp, hwnd, 80, 3, 13);
725 bartitle(&cp, "Options controlling the effects of keys",
727 beginbox(&cp, "Change the sequences sent by:",
728 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
729 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
730 "Control-&H", IDC_DEL008,
731 "Control-&? (127)", IDC_DEL127, NULL);
732 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
733 "&Standard", IDC_HOMETILDE,
734 "&rxvt", IDC_HOMERXVT, NULL);
735 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
736 "ESC[n&~", IDC_FUNCTILDE,
737 "&Linux", IDC_FUNCLINUX,
738 "&Xterm R6", IDC_FUNCXTERM,
739 "&VT400", IDC_FUNCVT400, NULL);
741 beginbox(&cp, "Application keypad settings:",
742 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
744 "Application c&ursor keys totally disabled",
746 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
747 "&Normal", IDC_CURNORMAL,
748 "A&pplication", IDC_CURAPPLIC, NULL);
750 "Application ke&ypad keys totally disabled",
752 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
753 "Nor&mal", IDC_KPNORMAL,
754 "Appl&ication", IDC_KPAPPLIC,
755 "N&etHack", IDC_KPNH, NULL);
757 beginbox(&cp, "Enable extra keyboard features:",
758 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
759 checkbox(&cp, "Application and AltGr ac&t as Compose key",
763 treeview_insert(&tvfaff, 1, "Keyboard");
766 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
769 ctlposinit(&cp, hwnd, 80, 3, 13);
770 bartitle(&cp, "Options controlling PuTTY's window",
772 beginbox(&cp, "Set the size of the window",
773 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
775 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
776 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
778 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
780 beginbox(&cp, "Control the scrollback in the window",
781 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
782 staticedit(&cp, "Lines of &scrollback",
783 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
784 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
785 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
786 checkbox(&cp, "Reset scrollback on dis&play activity",
789 beginbox(&cp, NULL, IDC_BOX_WINDOW3, 0);
790 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
791 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
792 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
793 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
794 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
797 treeview_insert(&tvfaff, 0, "Window");
800 /* The Appearance panel. Accelerators used: [acgo] rmkhti */
803 ctlposinit(&cp, hwnd, 80, 3, 13);
804 bartitle(&cp, "Options controlling PuTTY's appearance",
805 IDC_TITLE_APPEARANCE);
806 beginbox(&cp, "Adjust the use of the cursor",
807 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1);
808 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
810 beginbox(&cp, "Set the font used in the terminal window",
811 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2);
812 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
814 beginbox(&cp, "Adjust the use of the window title",
815 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3);
818 "Initial window &title:", IDC_WINTITLE,
819 IDC_WINEDIT, 100, NULL);
820 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
823 treeview_insert(&tvfaff, 1, "Appearance");
826 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
829 ctlposinit(&cp, hwnd, 80, 3, 13);
830 bartitle(&cp, "Options controlling character set translation",
831 IDC_TITLE_TRANSLATION);
832 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
833 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
835 "Handling of line drawing characters:", IDC_VTSTATIC,
836 "Font has &XWindows encoding", IDC_VTXWINDOWS,
837 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
838 "Use font in O&EM mode only", IDC_VTOEMONLY,
839 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
840 IDC_VTPOORMAN, NULL);
842 beginbox(&cp, "Enable character set translation on received data",
843 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
845 "Character set translation:", IDC_XLATSTATIC,
847 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
848 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
849 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
851 beginbox(&cp, "Enable character set translation on input data",
852 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
853 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
857 treeview_insert(&tvfaff, 1, "Translation");
860 /* The Selection panel. Accelerators used: [acgo] wxst */
863 ctlposinit(&cp, hwnd, 80, 3, 13);
864 bartitle(&cp, "Options controlling copy and paste",
865 IDC_TITLE_SELECTION);
866 beginbox(&cp, "Control which mouse button does which thing",
867 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
868 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
869 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
870 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
873 beginbox(&cp, "Control the select-one-word-at-a-time mode",
874 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
875 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
876 "&Set", IDC_CCSET, IDC_CCEDIT,
877 "&to class", IDC_CCSTATIC2);
880 treeview_insert(&tvfaff, 1, "Selection");
883 /* The Colours panel. Accelerators used: [acgo] blum */
886 ctlposinit(&cp, hwnd, 80, 3, 13);
887 bartitle(&cp, "Options controlling use of colours",
889 beginbox(&cp, "General options for colour usage",
890 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
891 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
892 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
894 beginbox(&cp, "Adjust the precise colours PuTTY displays",
895 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
896 colouredit(&cp, "Select a colo&ur and then click to modify it:",
897 IDC_COLOURSTATIC, IDC_COLOURLIST,
898 "&Modify...", IDC_CHANGE,
899 "Red:", IDC_RSTATIC, IDC_RVALUE,
900 "Green:", IDC_GSTATIC, IDC_GVALUE,
901 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
904 treeview_insert(&tvfaff, 1, "Colours");
907 /* The Connection panel. Accelerators used: [acgo] tuk */
910 ctlposinit(&cp, hwnd, 80, 3, 13);
911 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
913 beginbox(&cp, "Data to send to the server",
914 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
915 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
916 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
919 beginbox(&cp, "Sending of null packets to keep session active",
920 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
921 staticedit(&cp, "Minutes between &keepalives (0 to turn off)",
922 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
925 treeview_insert(&tvfaff, 0, "Connection");
928 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
931 ctlposinit(&cp, hwnd, 80, 3, 13);
933 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
934 beginbox(&cp, "Data to send to the server",
935 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
936 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
937 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
938 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
939 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
941 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
943 beginbox(&cp, "Telnet protocol adjustments",
944 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
945 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
946 "&BSD (commonplace)", IDC_EMBSD,
947 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
950 treeview_insert(&tvfaff, 1, "Telnet");
954 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
955 if (backends[2].backend != NULL) {
957 ctlposinit(&cp, hwnd, 80, 3, 13);
959 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
960 beginbox(&cp, "Data to send to the server",
961 IDC_BOX_SSH1, IDC_BOXT_SSH1);
963 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
966 beginbox(&cp, "Authentication options",
967 IDC_BOX_SSH2, IDC_BOXT_SSH2);
968 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
970 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
971 editbutton(&cp, "Private &key file for authentication:",
972 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
974 beginbox(&cp, "Protocol options",
975 IDC_BOX_SSH3, IDC_BOXT_SSH3);
976 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
977 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
978 radioline(&cp, "Preferred SSH protocol version:",
979 IDC_SSHPROTSTATIC, 2,
980 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
981 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
982 "&3DES", IDC_CIPHER3DES,
983 "&Blowfish", IDC_CIPHERBLOWF,
984 "&DES", IDC_CIPHERDES, NULL);
985 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
989 treeview_insert(&tvfaff, 1, "SSH");
993 init_dlg_ctrls(hwnd);
994 for (i = 0; i < nsessions; i++)
995 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
996 0, (LPARAM) (sessions[i]));
999 * Hide all the controls to start with.
1001 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1004 * Put the treeview selection on to the Session panel. This
1005 * should also cause unhiding of the relevant controls.
1007 TreeView_SelectItem(treeview, hsession);
1010 * Set focus into the first available control.
1014 ctl = GetDlgItem(hwnd, IDC_HOST);
1015 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1019 SetWindowLong(hwnd, GWL_USERDATA, 1);
1023 * Button release should trigger WM_OK if there was a
1024 * previous double click on the session list.
1028 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1031 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1032 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1033 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1037 item.pszText = buffer;
1038 item.cchTextMax = sizeof(buffer);
1039 item.mask = TVIF_TEXT;
1040 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1041 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1042 if (!strcmp(buffer, "Session"))
1043 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1044 if (!strcmp(buffer, "Keyboard"))
1045 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1046 if (!strcmp(buffer, "Terminal"))
1047 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1048 if (!strcmp(buffer, "Window"))
1049 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1050 if (!strcmp(buffer, "Appearance"))
1051 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
1052 if (!strcmp(buffer, "Connection"))
1053 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1054 if (!strcmp(buffer, "Telnet"))
1055 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1056 if (!strcmp(buffer, "SSH"))
1057 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1058 if (!strcmp(buffer, "Selection"))
1059 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1060 if (!strcmp(buffer, "Colours"))
1061 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1062 if (!strcmp(buffer, "Translation"))
1063 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1065 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1071 * Only process WM_COMMAND once the dialog is fully formed.
1073 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1076 EndDialog (hwnd, 1);
1081 EndDialog (hwnd, 0);
1083 case IDC_PROTTELNET:
1086 if (HIWORD(wParam) == BN_CLICKED ||
1087 HIWORD(wParam) == BN_DOUBLECLICKED) {
1088 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1089 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1090 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1091 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1092 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1093 cfg.port = i ? 22 : 23;
1094 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1099 if (HIWORD(wParam) == EN_CHANGE)
1100 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1101 sizeof(cfg.host)-1);
1104 if (HIWORD(wParam) == EN_CHANGE)
1105 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1108 if (HIWORD(wParam) == EN_CHANGE) {
1109 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1111 GetDlgItemText (hwnd, IDC_SESSEDIT,
1112 savedsession, sizeof(savedsession)-1);
1113 savedsession[sizeof(savedsession)-1] = '\0';
1117 if (HIWORD(wParam) == BN_CLICKED ||
1118 HIWORD(wParam) == BN_DOUBLECLICKED) {
1123 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1125 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1126 LB_GETCURSEL, 0, 0);
1131 strcpy (str, sessions[n]);
1133 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1134 get_sesslist (FALSE);
1135 get_sesslist (TRUE);
1136 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1138 for (i = 0; i < nsessions; i++)
1139 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1140 0, (LPARAM) (sessions[i]));
1141 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1147 if (LOWORD(wParam) == IDC_SESSLOAD &&
1148 HIWORD(wParam) != BN_CLICKED &&
1149 HIWORD(wParam) != BN_DOUBLECLICKED)
1151 if (LOWORD(wParam) == IDC_SESSLIST &&
1152 HIWORD(wParam) != LBN_DBLCLK)
1155 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1156 LB_GETCURSEL, 0, 0);
1162 isdef = !strcmp(sessions[n], "Default Settings");
1163 load_settings (sessions[n], !isdef, &cfg);
1164 init_dlg_ctrls(hwnd);
1166 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1168 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1170 if (LOWORD(wParam) == IDC_SESSLIST) {
1172 * A double-click on a saved session should
1173 * actually start the session, not just load it.
1174 * Unless it's Default Settings or some other
1175 * host-less set of saved settings.
1184 if (HIWORD(wParam) == BN_CLICKED ||
1185 HIWORD(wParam) == BN_DOUBLECLICKED) {
1186 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1187 LB_GETCURSEL, 0, 0);
1188 if (n == LB_ERR || n == 0) {
1192 del_settings(sessions[n]);
1193 get_sesslist (FALSE);
1194 get_sesslist (TRUE);
1195 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1197 for (i = 0; i < nsessions; i++)
1198 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1199 0, (LPARAM) (sessions[i]));
1200 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1204 if (HIWORD(wParam) == EN_CHANGE)
1205 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1209 if (HIWORD(wParam) == BN_CLICKED ||
1210 HIWORD(wParam) == BN_DOUBLECLICKED)
1211 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1215 if (HIWORD(wParam) == BN_CLICKED ||
1216 HIWORD(wParam) == BN_DOUBLECLICKED)
1217 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1220 if (HIWORD(wParam) == BN_CLICKED ||
1221 HIWORD(wParam) == BN_DOUBLECLICKED)
1225 if (HIWORD(wParam) == BN_CLICKED ||
1226 HIWORD(wParam) == BN_DOUBLECLICKED)
1231 if (HIWORD(wParam) == BN_CLICKED ||
1232 HIWORD(wParam) == BN_DOUBLECLICKED)
1233 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1237 if (HIWORD(wParam) == BN_CLICKED ||
1238 HIWORD(wParam) == BN_DOUBLECLICKED) {
1239 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1240 cfg.nethack_keypad = FALSE;
1244 if (HIWORD(wParam) == BN_CLICKED ||
1245 HIWORD(wParam) == BN_DOUBLECLICKED) {
1246 cfg.app_keypad = FALSE;
1247 cfg.nethack_keypad = TRUE;
1252 if (HIWORD(wParam) == BN_CLICKED ||
1253 HIWORD(wParam) == BN_DOUBLECLICKED)
1254 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1257 if (HIWORD(wParam) == BN_CLICKED ||
1258 HIWORD(wParam) == BN_DOUBLECLICKED)
1259 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1262 if (HIWORD(wParam) == BN_CLICKED ||
1263 HIWORD(wParam) == BN_DOUBLECLICKED)
1264 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1267 if (HIWORD(wParam) == BN_CLICKED ||
1268 HIWORD(wParam) == BN_DOUBLECLICKED)
1269 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1272 if (HIWORD(wParam) == BN_CLICKED ||
1273 HIWORD(wParam) == BN_DOUBLECLICKED)
1274 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1277 if (HIWORD(wParam) == BN_CLICKED ||
1278 HIWORD(wParam) == BN_DOUBLECLICKED)
1279 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1282 if (HIWORD(wParam) == BN_CLICKED ||
1283 HIWORD(wParam) == BN_DOUBLECLICKED)
1284 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1286 case IDC_ALWAYSONTOP:
1287 if (HIWORD(wParam) == BN_CLICKED ||
1288 HIWORD(wParam) == BN_DOUBLECLICKED)
1289 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1292 if (HIWORD(wParam) == BN_CLICKED ||
1293 HIWORD(wParam) == BN_DOUBLECLICKED)
1294 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1296 case IDC_SCROLLDISP:
1297 if (HIWORD(wParam) == BN_CLICKED ||
1298 HIWORD(wParam) == BN_DOUBLECLICKED)
1299 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1301 case IDC_COMPOSEKEY:
1302 if (HIWORD(wParam) == BN_CLICKED ||
1303 HIWORD(wParam) == BN_DOUBLECLICKED)
1304 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1307 if (HIWORD(wParam) == BN_CLICKED ||
1308 HIWORD(wParam) == BN_DOUBLECLICKED)
1309 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1312 if (HIWORD(wParam) == BN_CLICKED ||
1313 HIWORD(wParam) == BN_DOUBLECLICKED)
1314 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1317 if (HIWORD(wParam) == BN_CLICKED ||
1318 HIWORD(wParam) == BN_DOUBLECLICKED)
1319 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1322 if (HIWORD(wParam) == EN_CHANGE)
1323 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1326 if (HIWORD(wParam) == EN_CHANGE)
1327 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1330 if (HIWORD(wParam) == EN_CHANGE)
1331 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1333 case IDC_CHOOSEFONT:
1334 lf.lfHeight = cfg.fontheight;
1335 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1336 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1337 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1338 lf.lfCharSet = cfg.fontcharset;
1339 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1340 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1341 lf.lfQuality = DEFAULT_QUALITY;
1342 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1343 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1344 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1346 cf.lStructSize = sizeof(cf);
1347 cf.hwndOwner = hwnd;
1349 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1350 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1352 if (ChooseFont (&cf)) {
1353 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1354 cfg.font[sizeof(cfg.font)-1] = '\0';
1355 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1356 cfg.fontcharset = lf.lfCharSet;
1357 cfg.fontheight = lf.lfHeight;
1358 fmtfont (fontstatic);
1359 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1363 if (HIWORD(wParam) == BN_CLICKED ||
1364 HIWORD(wParam) == BN_DOUBLECLICKED)
1365 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1368 if (HIWORD(wParam) == BN_CLICKED ||
1369 HIWORD(wParam) == BN_DOUBLECLICKED)
1370 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1373 if (HIWORD(wParam) == BN_CLICKED ||
1374 HIWORD(wParam) == BN_DOUBLECLICKED)
1375 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1378 if (HIWORD(wParam) == BN_CLICKED ||
1379 HIWORD(wParam) == BN_DOUBLECLICKED)
1380 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1383 if (HIWORD(wParam) == BN_CLICKED ||
1384 HIWORD(wParam) == BN_DOUBLECLICKED)
1385 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1388 if (HIWORD(wParam) == BN_CLICKED ||
1389 HIWORD(wParam) == BN_DOUBLECLICKED)
1390 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1393 if (HIWORD(wParam) == BN_CLICKED ||
1394 HIWORD(wParam) == BN_DOUBLECLICKED)
1395 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1398 if (HIWORD(wParam) == EN_CHANGE)
1399 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1400 sizeof(cfg.wintitle)-1);
1403 if (HIWORD(wParam) == BN_CLICKED ||
1404 HIWORD(wParam) == BN_DOUBLECLICKED)
1405 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1408 if (HIWORD(wParam) == BN_CLICKED ||
1409 HIWORD(wParam) == BN_DOUBLECLICKED)
1410 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1413 if (HIWORD(wParam) == EN_CHANGE)
1414 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1415 sizeof(cfg.termtype)-1);
1418 if (HIWORD(wParam) == EN_CHANGE)
1419 GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
1420 sizeof(cfg.termspeed)-1);
1423 if (HIWORD(wParam) == EN_CHANGE)
1424 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1425 sizeof(cfg.username)-1);
1429 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1432 if (HIWORD(wParam) == BN_CLICKED ||
1433 HIWORD(wParam) == BN_DOUBLECLICKED) {
1434 char str[sizeof(cfg.environmt)];
1436 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1441 p = str + strlen(str);
1443 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1453 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1455 p[strlen(str)+1] = '\0';
1456 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1458 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1459 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1461 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1462 MB_OK | MB_ICONERROR);
1467 if (HIWORD(wParam) != BN_CLICKED &&
1468 HIWORD(wParam) != BN_DOUBLECLICKED)
1470 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1476 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1501 if (HIWORD(wParam) == BN_CLICKED ||
1502 HIWORD(wParam) == BN_DOUBLECLICKED)
1503 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1506 if (HIWORD(wParam) == BN_CLICKED ||
1507 HIWORD(wParam) == BN_DOUBLECLICKED)
1508 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1511 if (HIWORD(wParam) == BN_CLICKED ||
1512 HIWORD(wParam) == BN_DOUBLECLICKED)
1513 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1516 if (HIWORD(wParam) == BN_CLICKED ||
1517 HIWORD(wParam) == BN_DOUBLECLICKED)
1518 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1520 case IDC_CIPHER3DES:
1521 case IDC_CIPHERBLOWF:
1523 if (HIWORD(wParam) == BN_CLICKED ||
1524 HIWORD(wParam) == BN_DOUBLECLICKED) {
1525 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1526 cfg.cipher = CIPHER_3DES;
1527 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1528 cfg.cipher = CIPHER_BLOWFISH;
1529 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1530 cfg.cipher = CIPHER_DES;
1535 if (HIWORD(wParam) == BN_CLICKED ||
1536 HIWORD(wParam) == BN_DOUBLECLICKED) {
1537 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1539 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1544 if (HIWORD(wParam) == BN_CLICKED ||
1545 HIWORD(wParam) == BN_DOUBLECLICKED)
1546 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1549 if (HIWORD(wParam) == EN_CHANGE)
1550 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1551 sizeof(cfg.keyfile)-1);
1554 if (HIWORD(wParam) == EN_CHANGE)
1555 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1556 sizeof(cfg.remote_cmd)-1);
1559 memset(&of, 0, sizeof(of));
1560 #ifdef OPENFILENAME_SIZE_VERSION_400
1561 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1563 of.lStructSize = sizeof(of);
1565 of.hwndOwner = hwnd;
1566 of.lpstrFilter = "All Files\0*\0\0\0";
1567 of.lpstrCustomFilter = NULL;
1568 of.nFilterIndex = 1;
1569 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1570 of.nMaxFile = sizeof(filename);
1571 of.lpstrFileTitle = NULL;
1572 of.lpstrInitialDir = NULL;
1573 of.lpstrTitle = "Select Public Key File";
1575 if (GetOpenFileName(&of)) {
1576 strcpy(cfg.keyfile, filename);
1577 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1582 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1588 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1593 for (i=0; i<256; i++)
1594 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1597 cfg.wordness[i] = n;
1598 SendDlgItemMessage (hwnd, IDC_CCLIST,
1599 LB_DELETESTRING, i, 0);
1600 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1601 (i>=0x21 && i != 0x7F) ? i : ' ',
1603 SendDlgItemMessage (hwnd, IDC_CCLIST,
1610 case IDC_BOLDCOLOUR:
1611 if (HIWORD(wParam) == BN_CLICKED ||
1612 HIWORD(wParam) == BN_DOUBLECLICKED) {
1614 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1615 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1616 if (cfg.bold_colour && n!=22) {
1617 for (i=0; i<22; i++)
1619 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1621 (LPARAM) colours[i]);
1622 } else if (!cfg.bold_colour && n!=12) {
1625 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1626 LB_DELETESTRING, i, 0);
1631 if (HIWORD(wParam) == BN_CLICKED ||
1632 HIWORD(wParam) == BN_DOUBLECLICKED)
1633 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1635 case IDC_COLOURLIST:
1636 if (HIWORD(wParam) == LBN_DBLCLK ||
1637 HIWORD(wParam) == LBN_SELCHANGE) {
1638 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1640 if (!cfg.bold_colour)
1641 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1642 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1643 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1644 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1648 if (HIWORD(wParam) == BN_CLICKED ||
1649 HIWORD(wParam) == BN_DOUBLECLICKED) {
1650 static CHOOSECOLOR cc;
1651 static DWORD custom[16] = {0}; /* zero initialisers */
1652 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1654 if (!cfg.bold_colour)
1655 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1656 cc.lStructSize = sizeof(cc);
1657 cc.hwndOwner = hwnd;
1658 cc.hInstance = (HWND)hinst;
1659 cc.lpCustColors = custom;
1660 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1662 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1663 if (ChooseColor(&cc)) {
1665 (unsigned char) (cc.rgbResult & 0xFF);
1667 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1669 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1670 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1672 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1674 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1680 case IDC_KOI8WIN1251:
1681 case IDC_88592WIN1250:
1682 case IDC_88592CP852:
1683 cfg.xlat_enablekoiwin =
1684 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1685 cfg.xlat_88592w1250 =
1686 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1687 cfg.xlat_88592cp852 =
1688 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1690 case IDC_CAPSLOCKCYR:
1691 if (HIWORD(wParam) == BN_CLICKED ||
1692 HIWORD(wParam) == BN_DOUBLECLICKED) {
1693 cfg.xlat_capslockcyr =
1694 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1697 case IDC_VTXWINDOWS:
1702 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1703 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1704 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1710 EndDialog (hwnd, 0);
1713 /* Grrr Explorer will maximize Dialogs! */
1715 if (wParam == SIZE_MAXIMIZED)
1722 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1723 WPARAM wParam, LPARAM lParam) {
1724 static HWND page = NULL;
1726 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1728 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1729 EnableWindow(hwnd, 0);
1730 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1731 GetParent(hwnd), AboutProc);
1732 EnableWindow(hwnd, 1);
1733 SetActiveWindow(hwnd);
1735 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1738 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1739 WPARAM wParam, LPARAM lParam) {
1741 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1744 void defuse_showwindow(void) {
1746 * Work around the fact that the app's first call to ShowWindow
1747 * will ignore the default in favour of the shell-provided
1752 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1754 ShowWindow(hwnd, SW_HIDE);
1755 DestroyWindow(hwnd);
1759 int do_config (void) {
1763 savedsession[0] = '\0';
1764 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1765 get_sesslist(FALSE);
1770 int do_reconfig (HWND hwnd) {
1774 backup_cfg = cfg; /* structure copy */
1775 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1777 cfg = backup_cfg; /* structure copy */
1784 void logevent (char *string) {
1785 if (nevents >= negsize) {
1787 events = srealloc (events, negsize * sizeof(*events));
1789 events[nevents] = smalloc(1+strlen(string));
1790 strcpy (events[nevents], string);
1794 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1796 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1797 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1801 void showeventlog (HWND hwnd) {
1803 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1805 ShowWindow (logbox, SW_SHOWNORMAL);
1809 void showabout (HWND hwnd) {
1811 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1813 ShowWindow (abtbox, SW_SHOWNORMAL);
1817 void verify_ssh_host_key(char *host, int port, char *keytype,
1818 char *keystr, char *fingerprint) {
1821 static const char absentmsg[] =
1822 "The server's host key is not cached in the registry. You\n"
1823 "have no guarantee that the server is the computer you\n"
1825 "The server's key fingerprint is:\n"
1827 "If you trust this host, hit Yes to add the key to\n"
1828 "PuTTY's cache and carry on connecting.\n"
1829 "If you do not trust this host, hit No to abandon the\n"
1832 static const char wrongmsg[] =
1833 "WARNING - POTENTIAL SECURITY BREACH!\n"
1835 "The server's host key does not match the one PuTTY has\n"
1836 "cached in the registry. This means that either the\n"
1837 "server administrator has changed the host key, or you\n"
1838 "have actually connected to another computer pretending\n"
1839 "to be the server.\n"
1840 "The new key fingerprint is:\n"
1842 "If you were expecting this change and trust the new key,\n"
1843 "hit Yes to update PuTTY's cache and continue connecting.\n"
1844 "If you want to carry on connecting but without updating\n"
1845 "the cache, hit No.\n"
1846 "If you want to abandon the connection completely, hit\n"
1847 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1850 static const char mbtitle[] = "PuTTY Security Alert";
1853 char message[160+ /* sensible fingerprint max size */
1854 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1855 sizeof(absentmsg) : sizeof(wrongmsg))];
1858 * Verify the key against the registry.
1860 ret = verify_host_key(host, port, keytype, keystr);
1862 if (ret == 0) /* success - key matched OK */
1864 if (ret == 2) { /* key was different */
1866 sprintf(message, wrongmsg, fingerprint);
1867 mbret = MessageBox(NULL, message, mbtitle,
1868 MB_ICONWARNING | MB_YESNOCANCEL);
1870 store_host_key(host, port, keytype, keystr);
1871 if (mbret == IDCANCEL)
1874 if (ret == 1) { /* key was absent */
1876 sprintf(message, absentmsg, fingerprint);
1877 mbret = MessageBox(NULL, message, mbtitle,
1878 MB_ICONWARNING | MB_YESNO);
1881 store_host_key(host, port, keytype, keystr);