13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
16 static HWND logbox = NULL, abtbox = NULL;
20 void force_normal(HWND hwnd)
22 static int recurse = 0;
29 wp.length = sizeof(wp);
30 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) {
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 = smalloc(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 = smalloc(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,
233 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2,
252 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
253 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
272 appearancepanelstart,
273 IDC_TITLE_APPEARANCE,
274 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1,
275 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2,
276 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3,
285 connectionpanelstart,
286 IDC_TITLE_CONNECTION,
287 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
288 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
299 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
300 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
318 IDC_BOX_SSH1, IDC_BOXT_SSH1,
319 IDC_BOX_SSH2, IDC_BOXT_SSH2,
320 IDC_BOX_SSH3, IDC_BOXT_SSH3,
342 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
343 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
356 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
357 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
371 translationpanelstart,
372 IDC_TITLE_TRANSLATION,
373 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
374 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
375 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
392 static const char *const colours[] = {
393 "Default Foreground", "Default Bold Foreground",
394 "Default Background", "Default Bold Background",
395 "Cursor Text", "Cursor Colour",
396 "ANSI Black", "ANSI Black Bold",
397 "ANSI Red", "ANSI Red Bold",
398 "ANSI Green", "ANSI Green Bold",
399 "ANSI Yellow", "ANSI Yellow Bold",
400 "ANSI Blue", "ANSI Blue Bold",
401 "ANSI Magenta", "ANSI Magenta Bold",
402 "ANSI Cyan", "ANSI Cyan Bold",
403 "ANSI White", "ANSI White Bold"
405 static const int permcolour[] = {
406 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
407 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
408 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
411 static void fmtfont (char *buf) {
412 sprintf (buf, "Font: %s, ", cfg.font);
414 strcat(buf, "bold, ");
415 if (cfg.fontheight == 0)
416 strcat (buf, "default height");
418 sprintf (buf+strlen(buf), "%d-%s",
419 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
420 (cfg.fontheight < 0 ? "pixel" : "point"));
423 static void init_dlg_ctrls(HWND hwnd) {
425 char fontstatic[256];
427 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
428 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
429 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
430 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
431 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
432 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : IDC_PROTRAW );
433 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
435 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
436 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
437 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
438 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
439 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
440 cfg.funky_type == 0 ? IDC_FUNCTILDE :
441 cfg.funky_type == 1 ? IDC_FUNCLINUX :
442 cfg.funky_type == 2 ? IDC_FUNCXTERM :
443 cfg.funky_type == 3 ? IDC_FUNCVT400 :
445 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
446 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
447 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
448 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
449 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
450 cfg.nethack_keypad ? IDC_KPNH :
451 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
452 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
453 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
454 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
455 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
456 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
457 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
458 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
459 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
461 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
462 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
463 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
464 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
465 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
466 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
467 fmtfont (fontstatic);
468 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
469 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
470 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
471 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
473 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
474 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
475 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
476 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
477 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
478 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
479 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
481 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
482 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
483 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
484 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
485 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
486 cfg.logtype == 0 ? IDC_LSTATOFF :
487 cfg.logtype == 1 ? IDC_LSTATASCII :
490 char *p = cfg.environmt;
492 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
497 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
498 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
500 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
501 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
502 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
503 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
504 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
505 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
506 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
507 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
508 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
510 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
511 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
512 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
513 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
514 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
516 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
517 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
519 static int tabs[4] = {25, 61, 96, 128};
520 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
523 for (i=0; i<256; i++) {
525 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
526 (i>=0x21 && i != 0x7F) ? i : ' ',
528 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
532 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
533 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
536 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
538 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
539 LB_DELETESTRING, i, 0);
541 if (cfg.bold_colour || permcolour[i])
542 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
543 (LPARAM) colours[i]);
545 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
546 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
547 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
548 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
550 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
551 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
552 cfg.xlat_88592cp852 ? IDC_88592CP852 :
553 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
555 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
556 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
557 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
558 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
559 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
563 static void hide(HWND hwnd, int hide, int minid, int maxid) {
565 for (i = minid; i < maxid; i++) {
566 HWND ctl = GetDlgItem(hwnd, i);
568 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
573 struct treeview_faff {
578 static HTREEITEM treeview_insert(struct treeview_faff *faff,
579 int level, char *text) {
583 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
584 ins.hInsertAfter = faff->lastat[level];
585 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
586 #define INSITEM DUMMYUNIONNAME.item
590 ins.INSITEM.mask = TVIF_TEXT;
591 ins.INSITEM.pszText = text;
592 newitem = TreeView_InsertItem(faff->treeview, &ins);
594 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
595 faff->lastat[level] = newitem;
596 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
601 * This _huge_ function is the configuration box.
603 static int GenericMainDlgProc (HWND hwnd, UINT msg,
604 WPARAM wParam, LPARAM lParam,
607 struct treeview_faff tvfaff;
610 char filename[sizeof(cfg.keyfile)];
613 char fontstatic[256];
615 struct servent * service;
621 SetWindowLong(hwnd, GWL_USERDATA, 0);
625 { /* centre the window */
628 hw = GetDesktopWindow();
629 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
630 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
631 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
632 rd.right-rd.left, rd.bottom-rd.top, TRUE);
636 * Create the tree view.
643 r.left = 3; r.right = r.left + 75;
644 r.top = 3; r.bottom = r.top + 10;
645 MapDialogRect(hwnd, &r);
646 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
647 WS_CHILD | WS_VISIBLE,
649 r.right-r.left, r.bottom-r.top,
650 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
651 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
652 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
654 r.left = 3; r.right = r.left + 75;
655 r.top = 13; r.bottom = r.top + 206;
656 MapDialogRect(hwnd, &r);
657 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
658 WS_CHILD | WS_VISIBLE |
659 WS_TABSTOP | TVS_HASLINES |
660 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
661 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
663 r.right-r.left, r.bottom-r.top,
664 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
665 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
666 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
667 tvfaff.treeview = treeview;
668 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
672 * Create the various panelfuls of controls.
675 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
678 ctlposinit(&cp, hwnd, 80, 3, 13);
679 bartitle(&cp, "Basic options for your PuTTY session",
682 beginbox(&cp, "Specify your connection by host name",
683 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
685 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
686 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
687 if (backends[2].backend == NULL) {
688 /* this is PuTTYtel, so only two protocols available */
689 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
691 "&Telnet", IDC_PROTTELNET, NULL);
693 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
695 "&Telnet", IDC_PROTTELNET,
704 beginbox(&cp, "Load, save or delete a stored session",
705 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
706 sesssaver(&cp, "Sav&ed Sessions",
707 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
708 "&Load", IDC_SESSLOAD,
709 "&Save", IDC_SESSSAVE,
710 "&Delete", IDC_SESSDEL, NULL);
713 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
714 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
717 hsession = treeview_insert(&tvfaff, 0, "Session");
720 /* The Terminal panel. Accelerators used: [acgo] &dflbenuw */
723 ctlposinit(&cp, hwnd, 80, 3, 13);
724 bartitle(&cp, "Options controlling the terminal emulation",
726 beginbox(&cp, "Set various terminal options",
727 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
728 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
729 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
730 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
731 checkbox(&cp, "&Beep enabled", IDC_BEEP);
732 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
733 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
734 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
737 beginbox(&cp, "Control session logging",
738 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2);
740 "Session logging:", IDC_LSTATSTATIC,
741 "Logging turned &off completely", IDC_LSTATOFF,
742 "Log printable output only", IDC_LSTATASCII,
743 "Log all session output", IDC_LSTATRAW, NULL);
744 editbutton(&cp, "Log &file name:",
745 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
749 treeview_insert(&tvfaff, 0, "Terminal");
752 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
755 ctlposinit(&cp, hwnd, 80, 3, 13);
756 bartitle(&cp, "Options controlling the effects of keys",
758 beginbox(&cp, "Change the sequences sent by:",
759 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
760 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
761 "Control-&H", IDC_DEL008,
762 "Control-&? (127)", IDC_DEL127, NULL);
763 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
764 "&Standard", IDC_HOMETILDE,
765 "&rxvt", IDC_HOMERXVT, NULL);
766 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
767 "ESC[n&~", IDC_FUNCTILDE,
768 "&Linux", IDC_FUNCLINUX,
769 "&Xterm R6", IDC_FUNCXTERM,
770 "&VT400", IDC_FUNCVT400, NULL);
772 beginbox(&cp, "Application keypad settings:",
773 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
775 "Application c&ursor keys totally disabled",
777 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
778 "&Normal", IDC_CURNORMAL,
779 "A&pplication", IDC_CURAPPLIC, NULL);
781 "Application ke&ypad keys totally disabled",
783 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
784 "Nor&mal", IDC_KPNORMAL,
785 "Appl&ication", IDC_KPAPPLIC,
786 "N&etHack", IDC_KPNH, NULL);
788 beginbox(&cp, "Enable extra keyboard features:",
789 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
790 checkbox(&cp, "Application and AltGr ac&t as Compose key",
794 treeview_insert(&tvfaff, 1, "Keyboard");
797 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
800 ctlposinit(&cp, hwnd, 80, 3, 13);
801 bartitle(&cp, "Options controlling PuTTY's window",
803 beginbox(&cp, "Set the size of the window",
804 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
806 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
807 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
809 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
811 beginbox(&cp, "Control the scrollback in the window",
812 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
813 staticedit(&cp, "Lines of &scrollback",
814 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
815 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
816 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
817 checkbox(&cp, "Reset scrollback on dis&play activity",
820 beginbox(&cp, NULL, IDC_BOX_WINDOW3, 0);
821 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
822 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
823 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
824 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
825 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
828 treeview_insert(&tvfaff, 0, "Window");
831 /* The Appearance panel. Accelerators used: [acgo] rmkhti */
834 ctlposinit(&cp, hwnd, 80, 3, 13);
835 bartitle(&cp, "Options controlling PuTTY's appearance",
836 IDC_TITLE_APPEARANCE);
837 beginbox(&cp, "Adjust the use of the cursor",
838 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1);
839 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
841 beginbox(&cp, "Set the font used in the terminal window",
842 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2);
843 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
845 beginbox(&cp, "Adjust the use of the window title",
846 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3);
849 "Initial window &title:", IDC_WINTITLE,
850 IDC_WINEDIT, 100, NULL);
851 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
854 treeview_insert(&tvfaff, 1, "Appearance");
857 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
860 ctlposinit(&cp, hwnd, 80, 3, 13);
861 bartitle(&cp, "Options controlling character set translation",
862 IDC_TITLE_TRANSLATION);
863 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
864 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
866 "Handling of line drawing characters:", IDC_VTSTATIC,
867 "Font has &XWindows encoding", IDC_VTXWINDOWS,
868 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
869 "Use font in O&EM mode only", IDC_VTOEMONLY,
870 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
871 IDC_VTPOORMAN, NULL);
873 beginbox(&cp, "Enable character set translation on received data",
874 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
876 "Character set translation:", IDC_XLATSTATIC,
878 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
879 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
880 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
882 beginbox(&cp, "Enable character set translation on input data",
883 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
884 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
888 treeview_insert(&tvfaff, 1, "Translation");
891 /* The Selection panel. Accelerators used: [acgo] wxst */
894 ctlposinit(&cp, hwnd, 80, 3, 13);
895 bartitle(&cp, "Options controlling copy and paste",
896 IDC_TITLE_SELECTION);
897 beginbox(&cp, "Control which mouse button does which thing",
898 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
899 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
900 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
901 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
904 beginbox(&cp, "Control the select-one-word-at-a-time mode",
905 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
906 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
907 "&Set", IDC_CCSET, IDC_CCEDIT,
908 "&to class", IDC_CCSTATIC2);
911 treeview_insert(&tvfaff, 1, "Selection");
914 /* The Colours panel. Accelerators used: [acgo] blum */
917 ctlposinit(&cp, hwnd, 80, 3, 13);
918 bartitle(&cp, "Options controlling use of colours",
920 beginbox(&cp, "General options for colour usage",
921 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
922 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
923 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
925 beginbox(&cp, "Adjust the precise colours PuTTY displays",
926 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
927 colouredit(&cp, "Select a colo&ur and then click to modify it:",
928 IDC_COLOURSTATIC, IDC_COLOURLIST,
929 "&Modify...", IDC_CHANGE,
930 "Red:", IDC_RSTATIC, IDC_RVALUE,
931 "Green:", IDC_GSTATIC, IDC_GVALUE,
932 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
935 treeview_insert(&tvfaff, 1, "Colours");
938 /* The Connection panel. Accelerators used: [acgo] tuk */
941 ctlposinit(&cp, hwnd, 80, 3, 13);
942 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
944 beginbox(&cp, "Data to send to the server",
945 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
946 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
947 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
950 beginbox(&cp, "Sending of null packets to keep session active",
951 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
952 staticedit(&cp, "Minutes between &keepalives (0 to turn off)",
953 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
956 treeview_insert(&tvfaff, 0, "Connection");
959 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
962 ctlposinit(&cp, hwnd, 80, 3, 13);
964 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
965 beginbox(&cp, "Data to send to the server",
966 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
967 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
968 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
969 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
970 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
972 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
974 beginbox(&cp, "Telnet protocol adjustments",
975 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
976 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
977 "&BSD (commonplace)", IDC_EMBSD,
978 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
981 treeview_insert(&tvfaff, 1, "Telnet");
985 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
986 if (backends[2].backend != NULL) {
988 ctlposinit(&cp, hwnd, 80, 3, 13);
990 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
991 beginbox(&cp, "Data to send to the server",
992 IDC_BOX_SSH1, IDC_BOXT_SSH1);
994 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
997 beginbox(&cp, "Authentication options",
998 IDC_BOX_SSH2, IDC_BOXT_SSH2);
999 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1001 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
1002 editbutton(&cp, "Private &key file for authentication:",
1003 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1005 beginbox(&cp, "Protocol options",
1006 IDC_BOX_SSH3, IDC_BOXT_SSH3);
1007 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1008 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1009 radioline(&cp, "Preferred SSH protocol version:",
1010 IDC_SSHPROTSTATIC, 2,
1011 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1012 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
1013 "&3DES", IDC_CIPHER3DES,
1014 "&Blowfish", IDC_CIPHERBLOWF,
1015 "&DES", IDC_CIPHERDES, NULL);
1016 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1020 treeview_insert(&tvfaff, 1, "SSH");
1024 init_dlg_ctrls(hwnd);
1025 for (i = 0; i < nsessions; i++)
1026 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1027 0, (LPARAM) (sessions[i]));
1030 * Hide all the controls to start with.
1032 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1035 * Put the treeview selection on to the Session panel. This
1036 * should also cause unhiding of the relevant controls.
1038 TreeView_SelectItem(treeview, hsession);
1041 * Set focus into the first available control.
1045 ctl = GetDlgItem(hwnd, IDC_HOST);
1046 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1050 SetWindowLong(hwnd, GWL_USERDATA, 1);
1054 * Button release should trigger WM_OK if there was a
1055 * previous double click on the session list.
1059 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1062 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1063 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1064 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1068 item.pszText = buffer;
1069 item.cchTextMax = sizeof(buffer);
1070 item.mask = TVIF_TEXT;
1071 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1072 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1073 if (!strcmp(buffer, "Session"))
1074 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1075 if (!strcmp(buffer, "Keyboard"))
1076 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1077 if (!strcmp(buffer, "Terminal"))
1078 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1079 if (!strcmp(buffer, "Window"))
1080 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1081 if (!strcmp(buffer, "Appearance"))
1082 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
1083 if (!strcmp(buffer, "Connection"))
1084 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1085 if (!strcmp(buffer, "Telnet"))
1086 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1087 if (!strcmp(buffer, "SSH"))
1088 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1089 if (!strcmp(buffer, "Selection"))
1090 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1091 if (!strcmp(buffer, "Colours"))
1092 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1093 if (!strcmp(buffer, "Translation"))
1094 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1096 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1102 * Only process WM_COMMAND once the dialog is fully formed.
1104 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1107 EndDialog (hwnd, 1);
1112 EndDialog (hwnd, 0);
1114 case IDC_PROTTELNET:
1117 if (HIWORD(wParam) == BN_CLICKED ||
1118 HIWORD(wParam) == BN_DOUBLECLICKED) {
1119 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1120 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1121 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1122 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1123 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1124 cfg.port = i ? 22 : 23;
1125 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1130 if (HIWORD(wParam) == EN_CHANGE)
1131 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1132 sizeof(cfg.host)-1);
1135 if (HIWORD(wParam) == EN_CHANGE) {
1136 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1137 if (isdigit(portname[0]))
1138 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1140 service = getservbyname(portname, NULL);
1141 if (service) cfg.port = ntohs(service->s_port);
1147 if (HIWORD(wParam) == EN_CHANGE) {
1148 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1150 GetDlgItemText (hwnd, IDC_SESSEDIT,
1151 savedsession, sizeof(savedsession)-1);
1152 savedsession[sizeof(savedsession)-1] = '\0';
1156 if (HIWORD(wParam) == BN_CLICKED ||
1157 HIWORD(wParam) == BN_DOUBLECLICKED) {
1162 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1164 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1165 LB_GETCURSEL, 0, 0);
1170 strcpy (str, sessions[n]);
1172 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1173 get_sesslist (FALSE);
1174 get_sesslist (TRUE);
1175 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1177 for (i = 0; i < nsessions; i++)
1178 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1179 0, (LPARAM) (sessions[i]));
1180 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1186 if (LOWORD(wParam) == IDC_SESSLOAD &&
1187 HIWORD(wParam) != BN_CLICKED &&
1188 HIWORD(wParam) != BN_DOUBLECLICKED)
1190 if (LOWORD(wParam) == IDC_SESSLIST &&
1191 HIWORD(wParam) != LBN_DBLCLK)
1194 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1195 LB_GETCURSEL, 0, 0);
1201 isdef = !strcmp(sessions[n], "Default Settings");
1202 load_settings (sessions[n], !isdef, &cfg);
1203 init_dlg_ctrls(hwnd);
1205 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1207 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1209 if (LOWORD(wParam) == IDC_SESSLIST) {
1211 * A double-click on a saved session should
1212 * actually start the session, not just load it.
1213 * Unless it's Default Settings or some other
1214 * host-less set of saved settings.
1223 if (HIWORD(wParam) == BN_CLICKED ||
1224 HIWORD(wParam) == BN_DOUBLECLICKED) {
1225 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1226 LB_GETCURSEL, 0, 0);
1227 if (n == LB_ERR || n == 0) {
1231 del_settings(sessions[n]);
1232 get_sesslist (FALSE);
1233 get_sesslist (TRUE);
1234 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1236 for (i = 0; i < nsessions; i++)
1237 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1238 0, (LPARAM) (sessions[i]));
1239 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1243 if (HIWORD(wParam) == EN_CHANGE)
1244 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1248 if (HIWORD(wParam) == BN_CLICKED ||
1249 HIWORD(wParam) == BN_DOUBLECLICKED)
1250 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1254 if (HIWORD(wParam) == BN_CLICKED ||
1255 HIWORD(wParam) == BN_DOUBLECLICKED)
1256 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1259 if (HIWORD(wParam) == BN_CLICKED ||
1260 HIWORD(wParam) == BN_DOUBLECLICKED)
1264 if (HIWORD(wParam) == BN_CLICKED ||
1265 HIWORD(wParam) == BN_DOUBLECLICKED)
1270 if (HIWORD(wParam) == BN_CLICKED ||
1271 HIWORD(wParam) == BN_DOUBLECLICKED)
1272 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1276 if (HIWORD(wParam) == BN_CLICKED ||
1277 HIWORD(wParam) == BN_DOUBLECLICKED) {
1278 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1279 cfg.nethack_keypad = FALSE;
1283 if (HIWORD(wParam) == BN_CLICKED ||
1284 HIWORD(wParam) == BN_DOUBLECLICKED) {
1285 cfg.app_keypad = FALSE;
1286 cfg.nethack_keypad = TRUE;
1291 if (HIWORD(wParam) == BN_CLICKED ||
1292 HIWORD(wParam) == BN_DOUBLECLICKED)
1293 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1296 if (HIWORD(wParam) == BN_CLICKED ||
1297 HIWORD(wParam) == BN_DOUBLECLICKED)
1298 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1301 if (HIWORD(wParam) == BN_CLICKED ||
1302 HIWORD(wParam) == BN_DOUBLECLICKED)
1303 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1306 if (HIWORD(wParam) == BN_CLICKED ||
1307 HIWORD(wParam) == BN_DOUBLECLICKED)
1308 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1311 if (HIWORD(wParam) == BN_CLICKED ||
1312 HIWORD(wParam) == BN_DOUBLECLICKED)
1313 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1316 if (HIWORD(wParam) == BN_CLICKED ||
1317 HIWORD(wParam) == BN_DOUBLECLICKED)
1318 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1321 if (HIWORD(wParam) == BN_CLICKED ||
1322 HIWORD(wParam) == BN_DOUBLECLICKED)
1323 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1325 case IDC_ALWAYSONTOP:
1326 if (HIWORD(wParam) == BN_CLICKED ||
1327 HIWORD(wParam) == BN_DOUBLECLICKED)
1328 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1331 if (HIWORD(wParam) == BN_CLICKED ||
1332 HIWORD(wParam) == BN_DOUBLECLICKED)
1333 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1335 case IDC_SCROLLDISP:
1336 if (HIWORD(wParam) == BN_CLICKED ||
1337 HIWORD(wParam) == BN_DOUBLECLICKED)
1338 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1340 case IDC_COMPOSEKEY:
1341 if (HIWORD(wParam) == BN_CLICKED ||
1342 HIWORD(wParam) == BN_DOUBLECLICKED)
1343 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1346 if (HIWORD(wParam) == BN_CLICKED ||
1347 HIWORD(wParam) == BN_DOUBLECLICKED)
1348 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1351 if (HIWORD(wParam) == BN_CLICKED ||
1352 HIWORD(wParam) == BN_DOUBLECLICKED)
1353 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1356 if (HIWORD(wParam) == BN_CLICKED ||
1357 HIWORD(wParam) == BN_DOUBLECLICKED)
1358 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1361 if (HIWORD(wParam) == EN_CHANGE)
1362 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1365 if (HIWORD(wParam) == EN_CHANGE)
1366 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1369 if (HIWORD(wParam) == EN_CHANGE)
1370 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1372 case IDC_CHOOSEFONT:
1373 lf.lfHeight = cfg.fontheight;
1374 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1375 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1376 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1377 lf.lfCharSet = cfg.fontcharset;
1378 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1379 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1380 lf.lfQuality = DEFAULT_QUALITY;
1381 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1382 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1383 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1385 cf.lStructSize = sizeof(cf);
1386 cf.hwndOwner = hwnd;
1388 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1389 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1391 if (ChooseFont (&cf)) {
1392 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1393 cfg.font[sizeof(cfg.font)-1] = '\0';
1394 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1395 cfg.fontcharset = lf.lfCharSet;
1396 cfg.fontheight = lf.lfHeight;
1397 fmtfont (fontstatic);
1398 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1402 if (HIWORD(wParam) == BN_CLICKED ||
1403 HIWORD(wParam) == BN_DOUBLECLICKED)
1404 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1407 if (HIWORD(wParam) == BN_CLICKED ||
1408 HIWORD(wParam) == BN_DOUBLECLICKED)
1409 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1412 if (HIWORD(wParam) == BN_CLICKED ||
1413 HIWORD(wParam) == BN_DOUBLECLICKED)
1414 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1417 if (HIWORD(wParam) == BN_CLICKED ||
1418 HIWORD(wParam) == BN_DOUBLECLICKED)
1419 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1422 if (HIWORD(wParam) == BN_CLICKED ||
1423 HIWORD(wParam) == BN_DOUBLECLICKED)
1424 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1427 if (HIWORD(wParam) == BN_CLICKED ||
1428 HIWORD(wParam) == BN_DOUBLECLICKED)
1429 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1432 if (HIWORD(wParam) == BN_CLICKED ||
1433 HIWORD(wParam) == BN_DOUBLECLICKED)
1434 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1437 if (HIWORD(wParam) == EN_CHANGE)
1438 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1439 sizeof(cfg.wintitle)-1);
1442 if (HIWORD(wParam) == BN_CLICKED ||
1443 HIWORD(wParam) == BN_DOUBLECLICKED)
1444 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1447 if (HIWORD(wParam) == BN_CLICKED ||
1448 HIWORD(wParam) == BN_DOUBLECLICKED)
1449 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1452 if (HIWORD(wParam) == EN_CHANGE)
1453 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1454 sizeof(cfg.termtype)-1);
1457 if (HIWORD(wParam) == EN_CHANGE)
1458 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1459 sizeof(cfg.logfilename)-1);
1462 memset(&of, 0, sizeof(of));
1463 #ifdef OPENFILENAME_SIZE_VERSION_400
1464 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1466 of.lStructSize = sizeof(of);
1468 of.hwndOwner = hwnd;
1469 of.lpstrFilter = "All Files\0*\0\0\0";
1470 of.lpstrCustomFilter = NULL;
1471 of.nFilterIndex = 1;
1472 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1473 of.nMaxFile = sizeof(filename);
1474 of.lpstrFileTitle = NULL;
1475 of.lpstrInitialDir = NULL;
1476 of.lpstrTitle = "Select session log file";
1478 if (GetSaveFileName(&of)) {
1479 strcpy(cfg.keyfile, filename);
1480 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.keyfile);
1484 case IDC_LSTATASCII:
1486 if (HIWORD(wParam) == BN_CLICKED ||
1487 HIWORD(wParam) == BN_DOUBLECLICKED) {
1488 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1489 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1490 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1494 if (HIWORD(wParam) == EN_CHANGE)
1495 GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
1496 sizeof(cfg.termspeed)-1);
1499 if (HIWORD(wParam) == EN_CHANGE)
1500 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1501 sizeof(cfg.username)-1);
1505 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1508 if (HIWORD(wParam) == BN_CLICKED ||
1509 HIWORD(wParam) == BN_DOUBLECLICKED) {
1510 char str[sizeof(cfg.environmt)];
1512 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1517 p = str + strlen(str);
1519 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1529 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1531 p[strlen(str)+1] = '\0';
1532 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1534 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1535 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1537 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1538 MB_OK | MB_ICONERROR);
1543 if (HIWORD(wParam) != BN_CLICKED &&
1544 HIWORD(wParam) != BN_DOUBLECLICKED)
1546 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1552 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1577 if (HIWORD(wParam) == BN_CLICKED ||
1578 HIWORD(wParam) == BN_DOUBLECLICKED)
1579 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1582 if (HIWORD(wParam) == BN_CLICKED ||
1583 HIWORD(wParam) == BN_DOUBLECLICKED)
1584 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1587 if (HIWORD(wParam) == BN_CLICKED ||
1588 HIWORD(wParam) == BN_DOUBLECLICKED)
1589 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1592 if (HIWORD(wParam) == BN_CLICKED ||
1593 HIWORD(wParam) == BN_DOUBLECLICKED)
1594 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1596 case IDC_CIPHER3DES:
1597 case IDC_CIPHERBLOWF:
1599 if (HIWORD(wParam) == BN_CLICKED ||
1600 HIWORD(wParam) == BN_DOUBLECLICKED) {
1601 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1602 cfg.cipher = CIPHER_3DES;
1603 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1604 cfg.cipher = CIPHER_BLOWFISH;
1605 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1606 cfg.cipher = CIPHER_DES;
1611 if (HIWORD(wParam) == BN_CLICKED ||
1612 HIWORD(wParam) == BN_DOUBLECLICKED) {
1613 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1615 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1620 if (HIWORD(wParam) == BN_CLICKED ||
1621 HIWORD(wParam) == BN_DOUBLECLICKED)
1622 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1625 if (HIWORD(wParam) == EN_CHANGE)
1626 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1627 sizeof(cfg.keyfile)-1);
1630 if (HIWORD(wParam) == EN_CHANGE)
1631 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1632 sizeof(cfg.remote_cmd)-1);
1635 memset(&of, 0, sizeof(of));
1636 #ifdef OPENFILENAME_SIZE_VERSION_400
1637 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1639 of.lStructSize = sizeof(of);
1641 of.hwndOwner = hwnd;
1642 of.lpstrFilter = "All Files\0*\0\0\0";
1643 of.lpstrCustomFilter = NULL;
1644 of.nFilterIndex = 1;
1645 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1646 of.nMaxFile = sizeof(filename);
1647 of.lpstrFileTitle = NULL;
1648 of.lpstrInitialDir = NULL;
1649 of.lpstrTitle = "Select Public Key File";
1651 if (GetOpenFileName(&of)) {
1652 strcpy(cfg.keyfile, filename);
1653 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1658 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1664 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1669 for (i=0; i<256; i++)
1670 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1673 cfg.wordness[i] = n;
1674 SendDlgItemMessage (hwnd, IDC_CCLIST,
1675 LB_DELETESTRING, i, 0);
1676 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1677 (i>=0x21 && i != 0x7F) ? i : ' ',
1679 SendDlgItemMessage (hwnd, IDC_CCLIST,
1686 case IDC_BOLDCOLOUR:
1687 if (HIWORD(wParam) == BN_CLICKED ||
1688 HIWORD(wParam) == BN_DOUBLECLICKED) {
1690 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1691 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1692 if (n != 12+10*cfg.bold_colour) {
1694 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1695 LB_DELETESTRING, i, 0);
1696 for (i=0; i<22; i++)
1697 if (cfg.bold_colour || permcolour[i])
1698 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1700 (LPARAM) colours[i]);
1705 if (HIWORD(wParam) == BN_CLICKED ||
1706 HIWORD(wParam) == BN_DOUBLECLICKED)
1707 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1709 case IDC_COLOURLIST:
1710 if (HIWORD(wParam) == LBN_DBLCLK ||
1711 HIWORD(wParam) == LBN_SELCHANGE) {
1712 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1714 if (!cfg.bold_colour)
1715 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1716 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1717 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1718 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1722 if (HIWORD(wParam) == BN_CLICKED ||
1723 HIWORD(wParam) == BN_DOUBLECLICKED) {
1724 static CHOOSECOLOR cc;
1725 static DWORD custom[16] = {0}; /* zero initialisers */
1726 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1728 if (!cfg.bold_colour)
1729 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1730 cc.lStructSize = sizeof(cc);
1731 cc.hwndOwner = hwnd;
1732 cc.hInstance = (HWND)hinst;
1733 cc.lpCustColors = custom;
1734 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1736 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1737 if (ChooseColor(&cc)) {
1739 (unsigned char) (cc.rgbResult & 0xFF);
1741 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1743 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1744 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1746 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1748 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1754 case IDC_KOI8WIN1251:
1755 case IDC_88592WIN1250:
1756 case IDC_88592CP852:
1757 cfg.xlat_enablekoiwin =
1758 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1759 cfg.xlat_88592w1250 =
1760 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1761 cfg.xlat_88592cp852 =
1762 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1764 case IDC_CAPSLOCKCYR:
1765 if (HIWORD(wParam) == BN_CLICKED ||
1766 HIWORD(wParam) == BN_DOUBLECLICKED) {
1767 cfg.xlat_capslockcyr =
1768 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1771 case IDC_VTXWINDOWS:
1776 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1777 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1778 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1784 EndDialog (hwnd, 0);
1787 /* Grrr Explorer will maximize Dialogs! */
1789 if (wParam == SIZE_MAXIMIZED)
1796 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1797 WPARAM wParam, LPARAM lParam) {
1798 static HWND page = NULL;
1800 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1802 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1803 EnableWindow(hwnd, 0);
1804 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1805 GetParent(hwnd), AboutProc);
1806 EnableWindow(hwnd, 1);
1807 SetActiveWindow(hwnd);
1809 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1812 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1813 WPARAM wParam, LPARAM lParam) {
1815 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1818 void defuse_showwindow(void) {
1820 * Work around the fact that the app's first call to ShowWindow
1821 * will ignore the default in favour of the shell-provided
1826 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1828 ShowWindow(hwnd, SW_HIDE);
1829 DestroyWindow(hwnd);
1833 int do_config (void) {
1837 savedsession[0] = '\0';
1838 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1839 get_sesslist(FALSE);
1844 int do_reconfig (HWND hwnd) {
1848 backup_cfg = cfg; /* structure copy */
1849 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1851 cfg = backup_cfg; /* structure copy */
1856 void logevent (char *string) {
1857 if (nevents >= negsize) {
1859 events = srealloc (events, negsize * sizeof(*events));
1861 events[nevents] = smalloc(1+strlen(string));
1862 strcpy (events[nevents], string);
1866 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1868 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1869 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1873 void showeventlog (HWND hwnd) {
1875 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1877 ShowWindow (logbox, SW_SHOWNORMAL);
1881 void showabout (HWND hwnd) {
1883 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1885 ShowWindow (abtbox, SW_SHOWNORMAL);
1889 void verify_ssh_host_key(char *host, int port, char *keytype,
1890 char *keystr, char *fingerprint) {
1893 static const char absentmsg[] =
1894 "The server's host key is not cached in the registry. You\n"
1895 "have no guarantee that the server is the computer you\n"
1897 "The server's key fingerprint is:\n"
1899 "If you trust this host, hit Yes to add the key to\n"
1900 "PuTTY's cache and carry on connecting.\n"
1901 "If you do not trust this host, hit No to abandon the\n"
1904 static const char wrongmsg[] =
1905 "WARNING - POTENTIAL SECURITY BREACH!\n"
1907 "The server's host key does not match the one PuTTY has\n"
1908 "cached in the registry. This means that either the\n"
1909 "server administrator has changed the host key, or you\n"
1910 "have actually connected to another computer pretending\n"
1911 "to be the server.\n"
1912 "The new key fingerprint is:\n"
1914 "If you were expecting this change and trust the new key,\n"
1915 "hit Yes to update PuTTY's cache and continue connecting.\n"
1916 "If you want to carry on connecting but without updating\n"
1917 "the cache, hit No.\n"
1918 "If you want to abandon the connection completely, hit\n"
1919 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1922 static const char mbtitle[] = "PuTTY Security Alert";
1925 char message[160+ /* sensible fingerprint max size */
1926 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1927 sizeof(absentmsg) : sizeof(wrongmsg))];
1930 * Verify the key against the registry.
1932 ret = verify_host_key(host, port, keytype, keystr);
1934 if (ret == 0) /* success - key matched OK */
1936 if (ret == 2) { /* key was different */
1938 sprintf(message, wrongmsg, fingerprint);
1939 mbret = MessageBox(NULL, message, mbtitle,
1940 MB_ICONWARNING | MB_YESNOCANCEL);
1942 store_host_key(host, port, keytype, keystr);
1943 if (mbret == IDCANCEL)
1946 if (ret == 1) { /* key was absent */
1948 sprintf(message, absentmsg, fingerprint);
1949 mbret = MessageBox(NULL, message, mbtitle,
1950 MB_ICONWARNING | MB_YESNO);
1953 store_host_key(host, port, keytype, keystr);
1958 * Ask whether to wipe a session log file before writing to it.
1959 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
1961 int askappend(char *filename) {
1962 static const char mbtitle[] = "PuTTY Log to File";
1963 static const char msgtemplate[] =
1964 "The session log file \"%.*s\" already exists.\n"
1965 "You can overwrite it with a new session log,\n"
1966 "append your session log to the end of it,\n"
1967 "or disable session logging for this session.\n"
1968 "Hit Yes to wipe the file, No to append to it,\n"
1969 "or Cancel to disable logging.";
1970 char message[sizeof(msgtemplate) + FILENAME_MAX];
1972 sprintf(message, msgtemplate, FILENAME_MAX, filename);
1974 mbret = MessageBox(NULL, message, mbtitle,
1975 MB_ICONQUESTION | MB_YESNOCANCEL);
1978 else if (mbret == IDNO)