20 static char **events = NULL;
21 static int nevents = 0, negsize = 0;
23 static HWND logbox = NULL, abtbox = NULL;
27 static void force_normal(HWND hwnd)
29 static int recurse = 0;
36 wp.length = sizeof(wp);
37 if (GetWindowPlacement(hwnd, &wp))
39 wp.showCmd = SW_SHOWNORMAL;
40 SetWindowPlacement(hwnd, &wp);
45 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
48 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
53 static int CALLBACK LogProc (HWND hwnd, UINT msg,
54 WPARAM wParam, LPARAM lParam) {
59 for (i=0; i<nevents; i++)
60 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
61 0, (LPARAM)events[i]);
64 switch (LOWORD(wParam)) {
70 if (HIWORD(wParam) == BN_CLICKED ||
71 HIWORD(wParam) == BN_DOUBLECLICKED) {
74 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
75 LB_GETSELCOUNT, 0, 0);
76 selitems = malloc(selcount * sizeof(int));
78 int count = SendDlgItemMessage(hwnd, IDN_LIST,
80 selcount, (LPARAM)selitems);
84 static unsigned char sel_nl[] = SEL_NL;
86 if (count == 0) { /* can't copy zero stuff */
92 for (i = 0; i < count; i++)
93 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
95 clipdata = malloc(size);
98 for (i = 0; i < count; i++) {
99 char *q = events[selitems[i]];
100 int qlen = strlen(q);
103 memcpy(p, sel_nl, sizeof(sel_nl));
106 write_clip(clipdata, size, TRUE);
111 for (i = 0; i < nevents; i++)
112 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
121 DestroyWindow (hwnd);
127 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
128 WPARAM wParam, LPARAM lParam) {
133 switch (LOWORD(wParam)) {
146 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
147 WPARAM wParam, LPARAM lParam) {
150 SetDlgItemText (hwnd, IDA_VERSION, ver);
153 switch (LOWORD(wParam)) {
156 DestroyWindow (hwnd);
159 EnableWindow(hwnd, 0);
160 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
162 EnableWindow(hwnd, 1);
163 SetActiveWindow(hwnd);
169 DestroyWindow (hwnd);
176 * Null dialog procedure.
178 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
179 WPARAM wParam, LPARAM lParam) {
183 static char savedsession[2048];
185 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
189 IDC_BOX_SESSION1, IDC_BOXT_SESSION1,
190 IDC_BOX_SESSION2, IDC_BOXT_SESSION2,
211 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1,
212 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2,
235 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
236 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2,
237 IDC_BOX_TERMINAL3, IDC_BOXT_TERMINAL3,
257 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
258 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
259 IDC_BOX_WINDOW3, IDC_BOXT_WINDOW3,
274 connectionpanelstart,
275 IDC_TITLE_CONNECTION,
276 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
277 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
288 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
289 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
307 IDC_BOX_SSH1, IDC_BOXT_SSH1,
308 IDC_BOX_SSH2, IDC_BOXT_SSH2,
309 IDC_BOX_SSH3, IDC_BOXT_SSH3,
330 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
331 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
344 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
345 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
359 translationpanelstart,
360 IDC_TITLE_TRANSLATION,
361 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
362 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
363 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
380 static const char *const colours[] = {
381 "Default Foreground", "Default Bold Foreground",
382 "Default Background", "Default Bold Background",
383 "Cursor Text", "Cursor Colour",
384 "ANSI Black", "ANSI Black Bold",
385 "ANSI Red", "ANSI Red Bold",
386 "ANSI Green", "ANSI Green Bold",
387 "ANSI Yellow", "ANSI Yellow Bold",
388 "ANSI Blue", "ANSI Blue Bold",
389 "ANSI Magenta", "ANSI Magenta Bold",
390 "ANSI Cyan", "ANSI Cyan Bold",
391 "ANSI White", "ANSI White Bold"
393 static const int permcolour[] = {
394 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
395 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
396 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
399 static void fmtfont (char *buf) {
400 sprintf (buf, "Font: %s, ", cfg.font);
402 strcat(buf, "bold, ");
403 if (cfg.fontheight == 0)
404 strcat (buf, "default height");
406 sprintf (buf+strlen(buf), "%d-%s",
407 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
408 (cfg.fontheight < 0 ? "pixel" : "point"));
411 static void init_dlg_ctrls(HWND hwnd) {
413 char fontstatic[256];
415 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
416 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
417 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
418 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
419 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
420 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : IDC_PROTRAW );
421 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
423 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
424 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
425 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
426 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
427 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
428 cfg.funky_type == 0 ? IDC_FUNCTILDE :
429 cfg.funky_type == 1 ? IDC_FUNCLINUX :
430 cfg.funky_type == 2 ? IDC_FUNCXTERM :
431 cfg.funky_type == 3 ? IDC_FUNCVT400 :
433 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
434 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
435 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
436 cfg.nethack_keypad ? IDC_KPNH :
437 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
438 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
439 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
440 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
441 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
443 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
444 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
445 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
446 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
447 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
448 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
449 fmtfont (fontstatic);
450 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
451 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
452 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
453 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
455 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
456 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
457 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
458 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
459 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
460 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
461 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
463 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
464 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
465 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
467 char *p = cfg.environmt;
469 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
474 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
475 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
477 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
478 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
479 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
480 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
481 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
482 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
483 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
484 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
486 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
487 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
488 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
489 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
490 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
492 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
493 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
495 static int tabs[4] = {25, 61, 96, 128};
496 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
499 for (i=0; i<256; i++) {
501 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
502 (i>=0x21 && i != 0x7F) ? i : ' ',
504 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
508 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
509 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
513 if (cfg.bold_colour || permcolour[i])
514 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
515 (LPARAM) colours[i]);
517 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
518 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
519 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
520 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
522 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
523 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
524 cfg.xlat_88592cp852 ? IDC_88592CP852 :
525 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
527 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
528 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
529 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
530 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
531 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
535 static void hide(HWND hwnd, int hide, int minid, int maxid) {
537 for (i = minid; i < maxid; i++) {
538 HWND ctl = GetDlgItem(hwnd, i);
540 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
545 struct treeview_faff {
550 static HTREEITEM treeview_insert(struct treeview_faff *faff,
551 int level, char *text) {
555 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
556 ins.hInsertAfter = faff->lastat[level];
557 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
558 #define INSITEM DUMMYUNIONNAME.item
562 ins.INSITEM.mask = TVIF_TEXT;
563 ins.INSITEM.pszText = text;
564 newitem = TreeView_InsertItem(faff->treeview, &ins);
566 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
567 faff->lastat[level] = newitem;
568 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
573 * This _huge_ function is the configuration box.
575 static int GenericMainDlgProc (HWND hwnd, UINT msg,
576 WPARAM wParam, LPARAM lParam,
579 struct treeview_faff tvfaff;
582 char filename[sizeof(cfg.keyfile)];
585 char fontstatic[256];
590 SetWindowLong(hwnd, GWL_USERDATA, 0);
594 { /* centre the window */
597 hw = GetDesktopWindow();
598 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
599 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
600 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
601 rd.right-rd.left, rd.bottom-rd.top, TRUE);
605 * Create the tree view.
612 r.left = 3; r.right = r.left + 75;
613 r.top = 3; r.bottom = r.top + 10;
614 MapDialogRect(hwnd, &r);
615 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
616 WS_CHILD | WS_VISIBLE,
618 r.right-r.left, r.bottom-r.top,
619 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
620 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
621 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
623 r.left = 3; r.right = r.left + 75;
624 r.top = 13; r.bottom = r.top + 196;
625 MapDialogRect(hwnd, &r);
626 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
627 WS_CHILD | WS_VISIBLE |
628 WS_TABSTOP | TVS_HASLINES |
629 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
630 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
632 r.right-r.left, r.bottom-r.top,
633 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
634 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
635 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
636 tvfaff.treeview = treeview;
637 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
641 * Create the various panelfuls of controls.
644 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
647 ctlposinit(&cp, hwnd, 80, 3, 13);
648 bartitle(&cp, "Basic options for your PuTTY session",
651 beginbox(&cp, "Specify your connection by host name",
652 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
654 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
655 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
656 if (backends[2].backend == NULL) {
657 /* this is PuTTYtel, so only two protocols available */
658 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
660 "&Telnet", IDC_PROTTELNET, NULL);
662 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
664 "&Telnet", IDC_PROTTELNET,
673 beginbox(&cp, "Load, save or delete a stored session",
674 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
675 sesssaver(&cp, "Stor&ed Sessions",
676 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
677 "&Load", IDC_SESSLOAD,
678 "&Save", IDC_SESSSAVE,
679 "&Delete", IDC_SESSDEL, NULL);
682 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
683 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
686 hsession = treeview_insert(&tvfaff, 0, "Session");
689 /* The Terminal panel. Accelerators used: [acgo] rmkh&dlbenu */
692 ctlposinit(&cp, hwnd, 80, 3, 13);
693 bartitle(&cp, "Options controlling the terminal emulation",
695 beginbox(&cp, "Set the size of the terminal window",
696 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
698 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
699 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
701 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
703 beginbox(&cp, "Set the font used in the terminal window",
704 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2);
705 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
707 beginbox(&cp, "Set various terminal options",
708 IDC_BOX_TERMINAL3, IDC_BOXT_TERMINAL3);
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?srvlxvnpmie */
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, "Change the initial state of:",
742 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
743 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
744 "&Normal", IDC_CURNORMAL,
745 "A&pplication", IDC_CURAPPLIC, NULL);
746 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
747 "Nor&mal", IDC_KPNORMAL,
748 "Appl&ication", IDC_KPAPPLIC,
749 "N&etHack", IDC_KPNH, NULL);
752 treeview_insert(&tvfaff, 1, "Keyboard");
755 /* The Window panel. Accelerators used: [acgo] tibsdkw4y */
758 ctlposinit(&cp, hwnd, 80, 3, 13);
759 bartitle(&cp, "Options controlling PuTTY's window",
761 beginbox(&cp, "Adjust the use of the window title",
762 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
765 "Initial window &title:", IDC_WINTITLE,
766 IDC_WINEDIT, 100, NULL);
767 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
769 beginbox(&cp, "Adjust the use of the cursor",
770 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
771 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
773 beginbox(&cp, "Control the scrollback in the window",
774 IDC_BOX_WINDOW3, IDC_BOXT_WINDOW3);
775 staticedit(&cp, "Lines of &scrollback",
776 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
777 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
778 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
780 beginbox(&cp, NULL, IDC_BOX_WINDOW4, 0);
781 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
782 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
783 checkbox(&cp, "S&ystem menu appears on ALT-Space)", IDC_ALTSPACE);
786 treeview_insert(&tvfaff, 0, "Window");
789 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
792 ctlposinit(&cp, hwnd, 80, 3, 13);
793 bartitle(&cp, "Options controlling character set translation",
794 IDC_TITLE_TRANSLATION);
795 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
796 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
798 "Handling of line drawing characters:", IDC_VTSTATIC,
799 "Font has &XWindows encoding", IDC_VTXWINDOWS,
800 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
801 "Use font in O&EM mode only", IDC_VTOEMONLY,
802 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
803 IDC_VTPOORMAN, NULL);
805 beginbox(&cp, "Enable character set translation on received data",
806 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
808 "Character set translation:", IDC_XLATSTATIC,
810 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
811 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
812 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
814 beginbox(&cp, "Enable character set translation on input data",
815 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
816 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
820 treeview_insert(&tvfaff, 1, "Translation");
823 /* The Selection panel. Accelerators used: [acgo] wxst */
826 ctlposinit(&cp, hwnd, 80, 3, 13);
827 bartitle(&cp, "Options controlling copy and paste",
828 IDC_TITLE_SELECTION);
829 beginbox(&cp, "Control which mouse button does which thing",
830 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
831 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
832 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
833 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
836 beginbox(&cp, "Control the select-one-word-at-a-time mode",
837 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
838 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
839 "&Set", IDC_CCSET, IDC_CCEDIT,
840 "&to class", IDC_CCSTATIC2);
843 treeview_insert(&tvfaff, 1, "Selection");
846 /* The Colours panel. Accelerators used: [acgo] blum */
849 ctlposinit(&cp, hwnd, 80, 3, 13);
850 bartitle(&cp, "Options controlling use of colours",
852 beginbox(&cp, "General options for colour usage",
853 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
854 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
855 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
857 beginbox(&cp, "Adjust the precise colours PuTTY displays",
858 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
859 colouredit(&cp, "Select a colo&ur and then click to modify it:",
860 IDC_COLOURSTATIC, IDC_COLOURLIST,
861 "&Modify...", IDC_CHANGE,
862 "Red:", IDC_RSTATIC, IDC_RVALUE,
863 "Green:", IDC_GSTATIC, IDC_GVALUE,
864 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
867 treeview_insert(&tvfaff, 1, "Colours");
870 /* The Connection panel. Accelerators used: [acgo] tuk */
873 ctlposinit(&cp, hwnd, 80, 3, 13);
874 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
876 beginbox(&cp, "Data to send to the server",
877 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
878 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
879 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
882 beginbox(&cp, "Sending of null packets to keep session active",
883 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
884 staticedit(&cp, "Minutes between &keepalives (0 to turn off)",
885 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
888 treeview_insert(&tvfaff, 0, "Connection");
891 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
894 ctlposinit(&cp, hwnd, 80, 3, 13);
896 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
897 beginbox(&cp, "Data to send to the server",
898 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
899 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
900 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
901 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
902 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
904 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
906 beginbox(&cp, "Telnet protocol adjustments",
907 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
908 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
909 "&BSD (commonplace)", IDC_EMBSD,
910 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
913 treeview_insert(&tvfaff, 1, "Telnet");
917 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
918 if (backends[2].backend != NULL) {
920 ctlposinit(&cp, hwnd, 80, 3, 13);
922 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
923 beginbox(&cp, "Data to send to the server",
924 IDC_BOX_SSH1, IDC_BOXT_SSH1);
926 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
929 beginbox(&cp, "Authentication options",
930 IDC_BOX_SSH2, IDC_BOXT_SSH2);
931 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
933 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
934 editbutton(&cp, "Private &key file for authentication:",
935 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
937 beginbox(&cp, "Protocol options",
938 IDC_BOX_SSH3, IDC_BOXT_SSH3);
939 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
940 radioline(&cp, "Preferred SSH protocol version:",
941 IDC_SSHPROTSTATIC, 2,
942 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
943 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
944 "&3DES", IDC_CIPHER3DES,
945 "&Blowfish", IDC_CIPHERBLOWF,
946 "&DES", IDC_CIPHERDES, NULL);
947 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
951 treeview_insert(&tvfaff, 1, "SSH");
955 init_dlg_ctrls(hwnd);
956 for (i = 0; i < nsessions; i++)
957 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
958 0, (LPARAM) (sessions[i]));
961 * Hide all the controls to start with.
963 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
966 * Put the treeview selection on to the Session panel. This
967 * should also cause unhiding of the relevant controls.
969 TreeView_SelectItem(treeview, hsession);
972 * Set focus into the first available control.
976 ctl = GetDlgItem(hwnd, IDC_HOST);
977 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
981 SetWindowLong(hwnd, GWL_USERDATA, 1);
985 * Button release should trigger WM_OK if there was a
986 * previous double click on the session list.
990 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
993 if (LOWORD(wParam) == IDCX_TREEVIEW &&
994 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
995 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
999 item.pszText = buffer;
1000 item.cchTextMax = sizeof(buffer);
1001 item.mask = TVIF_TEXT;
1002 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1003 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1004 if (!strcmp(buffer, "Session"))
1005 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1006 if (!strcmp(buffer, "Keyboard"))
1007 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1008 if (!strcmp(buffer, "Terminal"))
1009 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1010 if (!strcmp(buffer, "Window"))
1011 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1012 if (!strcmp(buffer, "Connection"))
1013 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1014 if (!strcmp(buffer, "Telnet"))
1015 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1016 if (!strcmp(buffer, "SSH"))
1017 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1018 if (!strcmp(buffer, "Selection"))
1019 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1020 if (!strcmp(buffer, "Colours"))
1021 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1022 if (!strcmp(buffer, "Translation"))
1023 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1025 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1031 * Only process WM_COMMAND once the dialog is fully formed.
1033 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1036 EndDialog (hwnd, 1);
1041 EndDialog (hwnd, 0);
1043 case IDC_PROTTELNET:
1046 if (HIWORD(wParam) == BN_CLICKED ||
1047 HIWORD(wParam) == BN_DOUBLECLICKED) {
1048 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1049 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1050 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1051 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1052 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1053 cfg.port = i ? 22 : 23;
1054 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1059 if (HIWORD(wParam) == EN_CHANGE)
1060 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1061 sizeof(cfg.host)-1);
1064 if (HIWORD(wParam) == EN_CHANGE)
1065 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1068 if (HIWORD(wParam) == EN_CHANGE) {
1069 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1071 GetDlgItemText (hwnd, IDC_SESSEDIT,
1072 savedsession, sizeof(savedsession)-1);
1073 savedsession[sizeof(savedsession)-1] = '\0';
1077 if (HIWORD(wParam) == BN_CLICKED ||
1078 HIWORD(wParam) == BN_DOUBLECLICKED) {
1083 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1085 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1086 LB_GETCURSEL, 0, 0);
1091 strcpy (str, sessions[n]);
1093 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1094 get_sesslist (FALSE);
1095 get_sesslist (TRUE);
1096 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1098 for (i = 0; i < nsessions; i++)
1099 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1100 0, (LPARAM) (sessions[i]));
1101 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1107 if (LOWORD(wParam) == IDC_SESSLOAD &&
1108 HIWORD(wParam) != BN_CLICKED &&
1109 HIWORD(wParam) != BN_DOUBLECLICKED)
1111 if (LOWORD(wParam) == IDC_SESSLIST &&
1112 HIWORD(wParam) != LBN_DBLCLK)
1115 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1116 LB_GETCURSEL, 0, 0);
1122 isdef = !strcmp(sessions[n], "Default Settings");
1123 load_settings (sessions[n], !isdef, &cfg);
1124 init_dlg_ctrls(hwnd);
1126 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1128 if (LOWORD(wParam) == IDC_SESSLIST) {
1130 * A double-click on a saved session should
1131 * actually start the session, not just load it.
1132 * Unless it's Default Settings or some other
1133 * host-less set of saved settings.
1142 if (HIWORD(wParam) == BN_CLICKED ||
1143 HIWORD(wParam) == BN_DOUBLECLICKED) {
1144 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1145 LB_GETCURSEL, 0, 0);
1146 if (n == LB_ERR || n == 0) {
1150 del_settings(sessions[n]);
1151 get_sesslist (FALSE);
1152 get_sesslist (TRUE);
1153 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1155 for (i = 0; i < nsessions; i++)
1156 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1157 0, (LPARAM) (sessions[i]));
1158 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1162 if (HIWORD(wParam) == EN_CHANGE)
1163 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1167 if (HIWORD(wParam) == BN_CLICKED ||
1168 HIWORD(wParam) == BN_DOUBLECLICKED)
1169 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1173 if (HIWORD(wParam) == BN_CLICKED ||
1174 HIWORD(wParam) == BN_DOUBLECLICKED)
1175 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1178 if (HIWORD(wParam) == BN_CLICKED ||
1179 HIWORD(wParam) == BN_DOUBLECLICKED)
1183 if (HIWORD(wParam) == BN_CLICKED ||
1184 HIWORD(wParam) == BN_DOUBLECLICKED)
1189 if (HIWORD(wParam) == BN_CLICKED ||
1190 HIWORD(wParam) == BN_DOUBLECLICKED)
1191 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1195 if (HIWORD(wParam) == BN_CLICKED ||
1196 HIWORD(wParam) == BN_DOUBLECLICKED) {
1197 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1198 cfg.nethack_keypad = FALSE;
1202 if (HIWORD(wParam) == BN_CLICKED ||
1203 HIWORD(wParam) == BN_DOUBLECLICKED) {
1204 cfg.app_keypad = FALSE;
1205 cfg.nethack_keypad = TRUE;
1210 if (HIWORD(wParam) == BN_CLICKED ||
1211 HIWORD(wParam) == BN_DOUBLECLICKED)
1212 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1215 if (HIWORD(wParam) == BN_CLICKED ||
1216 HIWORD(wParam) == BN_DOUBLECLICKED)
1217 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1220 if (HIWORD(wParam) == BN_CLICKED ||
1221 HIWORD(wParam) == BN_DOUBLECLICKED)
1222 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1225 if (HIWORD(wParam) == BN_CLICKED ||
1226 HIWORD(wParam) == BN_DOUBLECLICKED)
1227 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1230 if (HIWORD(wParam) == BN_CLICKED ||
1231 HIWORD(wParam) == BN_DOUBLECLICKED)
1232 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1235 if (HIWORD(wParam) == BN_CLICKED ||
1236 HIWORD(wParam) == BN_DOUBLECLICKED)
1237 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1240 if (HIWORD(wParam) == BN_CLICKED ||
1241 HIWORD(wParam) == BN_DOUBLECLICKED)
1242 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1245 if (HIWORD(wParam) == BN_CLICKED ||
1246 HIWORD(wParam) == BN_DOUBLECLICKED)
1247 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1250 if (HIWORD(wParam) == EN_CHANGE)
1251 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1254 if (HIWORD(wParam) == EN_CHANGE)
1255 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1258 if (HIWORD(wParam) == EN_CHANGE)
1259 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1261 case IDC_CHOOSEFONT:
1262 lf.lfHeight = cfg.fontheight;
1263 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1264 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1265 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1266 lf.lfCharSet = cfg.fontcharset;
1267 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1268 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1269 lf.lfQuality = DEFAULT_QUALITY;
1270 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1271 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1272 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1274 cf.lStructSize = sizeof(cf);
1275 cf.hwndOwner = hwnd;
1277 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1278 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1280 if (ChooseFont (&cf)) {
1281 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1282 cfg.font[sizeof(cfg.font)-1] = '\0';
1283 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1284 cfg.fontcharset = lf.lfCharSet;
1285 cfg.fontheight = lf.lfHeight;
1286 fmtfont (fontstatic);
1287 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1291 if (HIWORD(wParam) == BN_CLICKED ||
1292 HIWORD(wParam) == BN_DOUBLECLICKED)
1293 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1296 if (HIWORD(wParam) == BN_CLICKED ||
1297 HIWORD(wParam) == BN_DOUBLECLICKED)
1298 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1301 if (HIWORD(wParam) == BN_CLICKED ||
1302 HIWORD(wParam) == BN_DOUBLECLICKED)
1303 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1306 if (HIWORD(wParam) == BN_CLICKED ||
1307 HIWORD(wParam) == BN_DOUBLECLICKED)
1308 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1311 if (HIWORD(wParam) == BN_CLICKED ||
1312 HIWORD(wParam) == BN_DOUBLECLICKED)
1313 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1316 if (HIWORD(wParam) == BN_CLICKED ||
1317 HIWORD(wParam) == BN_DOUBLECLICKED)
1318 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1321 if (HIWORD(wParam) == BN_CLICKED ||
1322 HIWORD(wParam) == BN_DOUBLECLICKED)
1323 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1326 if (HIWORD(wParam) == EN_CHANGE)
1327 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1328 sizeof(cfg.wintitle)-1);
1331 if (HIWORD(wParam) == BN_CLICKED ||
1332 HIWORD(wParam) == BN_DOUBLECLICKED)
1333 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1336 if (HIWORD(wParam) == BN_CLICKED ||
1337 HIWORD(wParam) == BN_DOUBLECLICKED)
1338 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1341 if (HIWORD(wParam) == EN_CHANGE)
1342 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1343 sizeof(cfg.termtype)-1);
1346 if (HIWORD(wParam) == EN_CHANGE)
1347 GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
1348 sizeof(cfg.termspeed)-1);
1351 if (HIWORD(wParam) == EN_CHANGE)
1352 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1353 sizeof(cfg.username)-1);
1357 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1360 if (HIWORD(wParam) == BN_CLICKED ||
1361 HIWORD(wParam) == BN_DOUBLECLICKED) {
1362 char str[sizeof(cfg.environmt)];
1364 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1369 p = str + strlen(str);
1371 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1381 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1383 p[strlen(str)+1] = '\0';
1384 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1386 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1387 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1389 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1390 MB_OK | MB_ICONERROR);
1395 if (HIWORD(wParam) != BN_CLICKED &&
1396 HIWORD(wParam) != BN_DOUBLECLICKED)
1398 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1404 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1429 if (HIWORD(wParam) == BN_CLICKED ||
1430 HIWORD(wParam) == BN_DOUBLECLICKED)
1431 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1434 if (HIWORD(wParam) == BN_CLICKED ||
1435 HIWORD(wParam) == BN_DOUBLECLICKED)
1436 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1439 if (HIWORD(wParam) == BN_CLICKED ||
1440 HIWORD(wParam) == BN_DOUBLECLICKED)
1441 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1443 case IDC_CIPHER3DES:
1444 case IDC_CIPHERBLOWF:
1446 if (HIWORD(wParam) == BN_CLICKED ||
1447 HIWORD(wParam) == BN_DOUBLECLICKED) {
1448 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1449 cfg.cipher = CIPHER_3DES;
1450 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1451 cfg.cipher = CIPHER_BLOWFISH;
1452 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1453 cfg.cipher = CIPHER_DES;
1458 if (HIWORD(wParam) == BN_CLICKED ||
1459 HIWORD(wParam) == BN_DOUBLECLICKED) {
1460 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1462 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1467 if (HIWORD(wParam) == BN_CLICKED ||
1468 HIWORD(wParam) == BN_DOUBLECLICKED)
1469 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1472 if (HIWORD(wParam) == EN_CHANGE)
1473 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1474 sizeof(cfg.keyfile)-1);
1477 if (HIWORD(wParam) == EN_CHANGE)
1478 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1479 sizeof(cfg.remote_cmd)-1);
1482 memset(&of, 0, sizeof(of));
1483 #ifdef OPENFILENAME_SIZE_VERSION_400
1484 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1486 of.lStructSize = sizeof(of);
1488 of.hwndOwner = hwnd;
1489 of.lpstrFilter = "All Files\0*\0\0\0";
1490 of.lpstrCustomFilter = NULL;
1491 of.nFilterIndex = 1;
1492 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1493 of.nMaxFile = sizeof(filename);
1494 of.lpstrFileTitle = NULL;
1495 of.lpstrInitialDir = NULL;
1496 of.lpstrTitle = "Select Public Key File";
1498 if (GetOpenFileName(&of)) {
1499 strcpy(cfg.keyfile, filename);
1500 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1505 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1511 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1516 for (i=0; i<256; i++)
1517 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1520 cfg.wordness[i] = n;
1521 SendDlgItemMessage (hwnd, IDC_CCLIST,
1522 LB_DELETESTRING, i, 0);
1523 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1524 (i>=0x21 && i != 0x7F) ? i : ' ',
1526 SendDlgItemMessage (hwnd, IDC_CCLIST,
1533 case IDC_BOLDCOLOUR:
1534 if (HIWORD(wParam) == BN_CLICKED ||
1535 HIWORD(wParam) == BN_DOUBLECLICKED) {
1537 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1538 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1539 if (cfg.bold_colour && n!=22) {
1540 for (i=0; i<22; i++)
1542 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1544 (LPARAM) colours[i]);
1545 } else if (!cfg.bold_colour && n!=12) {
1548 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1549 LB_DELETESTRING, i, 0);
1554 if (HIWORD(wParam) == BN_CLICKED ||
1555 HIWORD(wParam) == BN_DOUBLECLICKED)
1556 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1558 case IDC_COLOURLIST:
1559 if (HIWORD(wParam) == LBN_DBLCLK ||
1560 HIWORD(wParam) == LBN_SELCHANGE) {
1561 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1563 if (!cfg.bold_colour)
1564 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1566 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1567 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1568 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1572 if (HIWORD(wParam) == BN_CLICKED ||
1573 HIWORD(wParam) == BN_DOUBLECLICKED) {
1574 static CHOOSECOLOR cc;
1575 static DWORD custom[16] = {0}; /* zero initialisers */
1576 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1578 if (!cfg.bold_colour)
1579 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1580 cc.lStructSize = sizeof(cc);
1581 cc.hwndOwner = hwnd;
1582 cc.hInstance = (HWND)hinst;
1583 cc.lpCustColors = custom;
1584 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1586 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1587 if (ChooseColor(&cc)) {
1589 (unsigned char) (cc.rgbResult & 0xFF);
1591 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1593 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1594 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1596 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1598 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1604 case IDC_KOI8WIN1251:
1605 case IDC_88592WIN1250:
1606 case IDC_88592CP852:
1607 cfg.xlat_enablekoiwin =
1608 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1609 cfg.xlat_88592w1250 =
1610 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1611 cfg.xlat_88592cp852 =
1612 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1614 case IDC_CAPSLOCKCYR:
1615 if (HIWORD(wParam) == BN_CLICKED ||
1616 HIWORD(wParam) == BN_DOUBLECLICKED) {
1617 cfg.xlat_capslockcyr =
1618 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1621 case IDC_VTXWINDOWS:
1626 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1627 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1628 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1634 EndDialog (hwnd, 0);
1637 /* Grrr Explorer will maximize Dialogs! */
1639 if (wParam == SIZE_MAXIMIZED)
1646 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1647 WPARAM wParam, LPARAM lParam) {
1648 static HWND page = NULL;
1650 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1652 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1653 EnableWindow(hwnd, 0);
1654 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1655 GetParent(hwnd), AboutProc);
1656 EnableWindow(hwnd, 1);
1657 SetActiveWindow(hwnd);
1659 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1662 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1663 WPARAM wParam, LPARAM lParam) {
1665 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1668 void defuse_showwindow(void) {
1670 * Work around the fact that the app's first call to ShowWindow
1671 * will ignore the default in favour of the shell-provided
1676 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1678 ShowWindow(hwnd, SW_HIDE);
1679 DestroyWindow(hwnd);
1683 int do_config (void) {
1687 savedsession[0] = '\0';
1688 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1689 get_sesslist(FALSE);
1694 int do_reconfig (HWND hwnd) {
1698 backup_cfg = cfg; /* structure copy */
1699 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1701 cfg = backup_cfg; /* structure copy */
1708 void logevent (char *string) {
1709 if (nevents >= negsize) {
1711 events = srealloc (events, negsize * sizeof(*events));
1713 events[nevents] = smalloc(1+strlen(string));
1714 strcpy (events[nevents], string);
1718 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1720 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1721 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1725 void showeventlog (HWND hwnd) {
1727 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1729 ShowWindow (logbox, SW_SHOWNORMAL);
1733 void showabout (HWND hwnd) {
1735 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1737 ShowWindow (abtbox, SW_SHOWNORMAL);
1741 void verify_ssh_host_key(char *host, int port, char *keytype,
1742 char *keystr, char *fingerprint) {
1745 static const char absentmsg[] =
1746 "The server's host key is not cached in the registry. You\n"
1747 "have no guarantee that the server is the computer you\n"
1749 "The server's key fingerprint is:\n"
1751 "If you trust this host, hit Yes to add the key to\n"
1752 "PuTTY's cache and carry on connecting.\n"
1753 "If you do not trust this host, hit No to abandon the\n"
1756 static const char wrongmsg[] =
1757 "WARNING - POTENTIAL SECURITY BREACH!\n"
1759 "The server's host key does not match the one PuTTY has\n"
1760 "cached in the registry. This means that either the\n"
1761 "server administrator has changed the host key, or you\n"
1762 "have actually connected to another computer pretending\n"
1763 "to be the server.\n"
1764 "The new key fingerprint is:\n"
1766 "If you were expecting this change and trust the new key,\n"
1767 "hit Yes to update PuTTY's cache and continue connecting.\n"
1768 "If you want to carry on connecting but without updating\n"
1769 "the cache, hit No.\n"
1770 "If you want to abandon the connection completely, hit\n"
1771 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1774 static const char mbtitle[] = "PuTTY Security Alert";
1777 char message[160+ /* sensible fingerprint max size */
1778 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1779 sizeof(absentmsg) : sizeof(wrongmsg))];
1782 * Verify the key against the registry.
1784 ret = verify_host_key(host, port, keytype, keystr);
1786 if (ret == 0) /* success - key matched OK */
1788 if (ret == 2) { /* key was different */
1790 sprintf(message, wrongmsg, fingerprint);
1791 mbret = MessageBox(NULL, message, mbtitle,
1792 MB_ICONWARNING | MB_YESNOCANCEL);
1794 store_host_key(host, port, keytype, keystr);
1795 if (mbret == IDCANCEL)
1798 if (ret == 1) { /* key was absent */
1800 sprintf(message, absentmsg, fingerprint);
1801 mbret = MessageBox(NULL, message, mbtitle,
1802 MB_ICONWARNING | MB_YESNO);
1805 store_host_key(host, port, keytype, keystr);