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);
848 "Window &title:", IDC_WINTITLE,
849 IDC_WINEDIT, 100, NULL);
850 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
853 treeview_insert(&tvfaff, 1, "Appearance");
856 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
859 ctlposinit(&cp, hwnd, 80, 3, 13);
860 bartitle(&cp, "Options controlling character set translation",
861 IDC_TITLE_TRANSLATION);
862 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
863 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
865 "Handling of line drawing characters:", IDC_VTSTATIC,
866 "Font has &XWindows encoding", IDC_VTXWINDOWS,
867 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
868 "Use font in O&EM mode only", IDC_VTOEMONLY,
869 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
870 IDC_VTPOORMAN, NULL);
872 beginbox(&cp, "Enable character set translation on received data",
873 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
875 "Character set translation:", IDC_XLATSTATIC,
877 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
878 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
879 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
881 beginbox(&cp, "Enable character set translation on input data",
882 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
883 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
887 treeview_insert(&tvfaff, 1, "Translation");
890 /* The Selection panel. Accelerators used: [acgo] wxst */
893 ctlposinit(&cp, hwnd, 80, 3, 13);
894 bartitle(&cp, "Options controlling copy and paste",
895 IDC_TITLE_SELECTION);
896 beginbox(&cp, "Control which mouse button does which thing",
897 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
898 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
899 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
900 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
903 beginbox(&cp, "Control the select-one-word-at-a-time mode",
904 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
905 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
906 "&Set", IDC_CCSET, IDC_CCEDIT,
907 "&to class", IDC_CCSTATIC2);
910 treeview_insert(&tvfaff, 1, "Selection");
913 /* The Colours panel. Accelerators used: [acgo] blum */
916 ctlposinit(&cp, hwnd, 80, 3, 13);
917 bartitle(&cp, "Options controlling use of colours",
919 beginbox(&cp, "General options for colour usage",
920 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
921 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
922 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
924 beginbox(&cp, "Adjust the precise colours PuTTY displays",
925 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
926 colouredit(&cp, "Select a colo&ur and then click to modify it:",
927 IDC_COLOURSTATIC, IDC_COLOURLIST,
928 "&Modify...", IDC_CHANGE,
929 "Red:", IDC_RSTATIC, IDC_RVALUE,
930 "Green:", IDC_GSTATIC, IDC_GVALUE,
931 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
934 treeview_insert(&tvfaff, 1, "Colours");
937 /* The Connection panel. Accelerators used: [acgo] tuk */
940 ctlposinit(&cp, hwnd, 80, 3, 13);
941 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
943 beginbox(&cp, "Data to send to the server",
944 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
945 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
946 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
949 beginbox(&cp, "Sending of null packets to keep session active",
950 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
951 staticedit(&cp, "Minutes between &keepalives (0 to turn off)",
952 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
955 treeview_insert(&tvfaff, 0, "Connection");
958 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
961 ctlposinit(&cp, hwnd, 80, 3, 13);
963 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
964 beginbox(&cp, "Data to send to the server",
965 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
966 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
967 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
968 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
969 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
971 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
973 beginbox(&cp, "Telnet protocol adjustments",
974 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
975 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
976 "&BSD (commonplace)", IDC_EMBSD,
977 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
980 treeview_insert(&tvfaff, 1, "Telnet");
984 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
985 if (backends[2].backend != NULL) {
987 ctlposinit(&cp, hwnd, 80, 3, 13);
989 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
990 beginbox(&cp, "Data to send to the server",
991 IDC_BOX_SSH1, IDC_BOXT_SSH1);
993 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
996 beginbox(&cp, "Authentication options",
997 IDC_BOX_SSH2, IDC_BOXT_SSH2);
998 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1000 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
1001 editbutton(&cp, "Private &key file for authentication:",
1002 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1004 beginbox(&cp, "Protocol options",
1005 IDC_BOX_SSH3, IDC_BOXT_SSH3);
1006 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1007 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1008 radioline(&cp, "Preferred SSH protocol version:",
1009 IDC_SSHPROTSTATIC, 2,
1010 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1011 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
1012 "&3DES", IDC_CIPHER3DES,
1013 "&Blowfish", IDC_CIPHERBLOWF,
1014 "&DES", IDC_CIPHERDES, NULL);
1015 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1019 treeview_insert(&tvfaff, 1, "SSH");
1023 init_dlg_ctrls(hwnd);
1024 for (i = 0; i < nsessions; i++)
1025 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1026 0, (LPARAM) (sessions[i]));
1029 * Hide all the controls to start with.
1031 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1034 * Put the treeview selection on to the Session panel. This
1035 * should also cause unhiding of the relevant controls.
1037 TreeView_SelectItem(treeview, hsession);
1040 * Set focus into the first available control.
1044 ctl = GetDlgItem(hwnd, IDC_HOST);
1045 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1049 SetWindowLong(hwnd, GWL_USERDATA, 1);
1053 * Button release should trigger WM_OK if there was a
1054 * previous double click on the session list.
1058 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1061 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1062 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1063 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1067 item.pszText = buffer;
1068 item.cchTextMax = sizeof(buffer);
1069 item.mask = TVIF_TEXT;
1070 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1071 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1072 if (!strcmp(buffer, "Session"))
1073 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1074 if (!strcmp(buffer, "Keyboard"))
1075 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1076 if (!strcmp(buffer, "Terminal"))
1077 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1078 if (!strcmp(buffer, "Window"))
1079 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1080 if (!strcmp(buffer, "Appearance"))
1081 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
1082 if (!strcmp(buffer, "Connection"))
1083 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1084 if (!strcmp(buffer, "Telnet"))
1085 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1086 if (!strcmp(buffer, "SSH"))
1087 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1088 if (!strcmp(buffer, "Selection"))
1089 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1090 if (!strcmp(buffer, "Colours"))
1091 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1092 if (!strcmp(buffer, "Translation"))
1093 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1095 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1101 * Only process WM_COMMAND once the dialog is fully formed.
1103 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1106 EndDialog (hwnd, 1);
1111 EndDialog (hwnd, 0);
1113 case IDC_PROTTELNET:
1116 if (HIWORD(wParam) == BN_CLICKED ||
1117 HIWORD(wParam) == BN_DOUBLECLICKED) {
1118 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1119 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1120 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1121 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1122 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1123 cfg.port = i ? 22 : 23;
1124 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1129 if (HIWORD(wParam) == EN_CHANGE)
1130 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1131 sizeof(cfg.host)-1);
1134 if (HIWORD(wParam) == EN_CHANGE) {
1135 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1136 if (isdigit(portname[0]))
1137 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1139 service = getservbyname(portname, NULL);
1140 if (service) cfg.port = ntohs(service->s_port);
1146 if (HIWORD(wParam) == EN_CHANGE) {
1147 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1149 GetDlgItemText (hwnd, IDC_SESSEDIT,
1150 savedsession, sizeof(savedsession)-1);
1151 savedsession[sizeof(savedsession)-1] = '\0';
1155 if (HIWORD(wParam) == BN_CLICKED ||
1156 HIWORD(wParam) == BN_DOUBLECLICKED) {
1161 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1163 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1164 LB_GETCURSEL, 0, 0);
1169 strcpy (str, sessions[n]);
1171 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1172 get_sesslist (FALSE);
1173 get_sesslist (TRUE);
1174 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1176 for (i = 0; i < nsessions; i++)
1177 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1178 0, (LPARAM) (sessions[i]));
1179 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1185 if (LOWORD(wParam) == IDC_SESSLOAD &&
1186 HIWORD(wParam) != BN_CLICKED &&
1187 HIWORD(wParam) != BN_DOUBLECLICKED)
1189 if (LOWORD(wParam) == IDC_SESSLIST &&
1190 HIWORD(wParam) != LBN_DBLCLK)
1193 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1194 LB_GETCURSEL, 0, 0);
1200 isdef = !strcmp(sessions[n], "Default Settings");
1201 load_settings (sessions[n], !isdef, &cfg);
1202 init_dlg_ctrls(hwnd);
1204 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1206 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1208 if (LOWORD(wParam) == IDC_SESSLIST) {
1210 * A double-click on a saved session should
1211 * actually start the session, not just load it.
1212 * Unless it's Default Settings or some other
1213 * host-less set of saved settings.
1222 if (HIWORD(wParam) == BN_CLICKED ||
1223 HIWORD(wParam) == BN_DOUBLECLICKED) {
1224 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1225 LB_GETCURSEL, 0, 0);
1226 if (n == LB_ERR || n == 0) {
1230 del_settings(sessions[n]);
1231 get_sesslist (FALSE);
1232 get_sesslist (TRUE);
1233 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1235 for (i = 0; i < nsessions; i++)
1236 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1237 0, (LPARAM) (sessions[i]));
1238 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1242 if (HIWORD(wParam) == EN_CHANGE)
1243 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1247 if (HIWORD(wParam) == BN_CLICKED ||
1248 HIWORD(wParam) == BN_DOUBLECLICKED)
1249 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1253 if (HIWORD(wParam) == BN_CLICKED ||
1254 HIWORD(wParam) == BN_DOUBLECLICKED)
1255 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1258 if (HIWORD(wParam) == BN_CLICKED ||
1259 HIWORD(wParam) == BN_DOUBLECLICKED)
1263 if (HIWORD(wParam) == BN_CLICKED ||
1264 HIWORD(wParam) == BN_DOUBLECLICKED)
1269 if (HIWORD(wParam) == BN_CLICKED ||
1270 HIWORD(wParam) == BN_DOUBLECLICKED)
1271 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1275 if (HIWORD(wParam) == BN_CLICKED ||
1276 HIWORD(wParam) == BN_DOUBLECLICKED) {
1277 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1278 cfg.nethack_keypad = FALSE;
1282 if (HIWORD(wParam) == BN_CLICKED ||
1283 HIWORD(wParam) == BN_DOUBLECLICKED) {
1284 cfg.app_keypad = FALSE;
1285 cfg.nethack_keypad = TRUE;
1290 if (HIWORD(wParam) == BN_CLICKED ||
1291 HIWORD(wParam) == BN_DOUBLECLICKED)
1292 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1295 if (HIWORD(wParam) == BN_CLICKED ||
1296 HIWORD(wParam) == BN_DOUBLECLICKED)
1297 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1300 if (HIWORD(wParam) == BN_CLICKED ||
1301 HIWORD(wParam) == BN_DOUBLECLICKED)
1302 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1305 if (HIWORD(wParam) == BN_CLICKED ||
1306 HIWORD(wParam) == BN_DOUBLECLICKED)
1307 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1310 if (HIWORD(wParam) == BN_CLICKED ||
1311 HIWORD(wParam) == BN_DOUBLECLICKED)
1312 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1315 if (HIWORD(wParam) == BN_CLICKED ||
1316 HIWORD(wParam) == BN_DOUBLECLICKED)
1317 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1320 if (HIWORD(wParam) == BN_CLICKED ||
1321 HIWORD(wParam) == BN_DOUBLECLICKED)
1322 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1324 case IDC_ALWAYSONTOP:
1325 if (HIWORD(wParam) == BN_CLICKED ||
1326 HIWORD(wParam) == BN_DOUBLECLICKED)
1327 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1330 if (HIWORD(wParam) == BN_CLICKED ||
1331 HIWORD(wParam) == BN_DOUBLECLICKED)
1332 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1334 case IDC_SCROLLDISP:
1335 if (HIWORD(wParam) == BN_CLICKED ||
1336 HIWORD(wParam) == BN_DOUBLECLICKED)
1337 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1339 case IDC_COMPOSEKEY:
1340 if (HIWORD(wParam) == BN_CLICKED ||
1341 HIWORD(wParam) == BN_DOUBLECLICKED)
1342 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1345 if (HIWORD(wParam) == BN_CLICKED ||
1346 HIWORD(wParam) == BN_DOUBLECLICKED)
1347 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1350 if (HIWORD(wParam) == BN_CLICKED ||
1351 HIWORD(wParam) == BN_DOUBLECLICKED)
1352 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1355 if (HIWORD(wParam) == BN_CLICKED ||
1356 HIWORD(wParam) == BN_DOUBLECLICKED)
1357 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1360 if (HIWORD(wParam) == EN_CHANGE)
1361 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1364 if (HIWORD(wParam) == EN_CHANGE)
1365 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1368 if (HIWORD(wParam) == EN_CHANGE)
1369 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1371 case IDC_CHOOSEFONT:
1372 lf.lfHeight = cfg.fontheight;
1373 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1374 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1375 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1376 lf.lfCharSet = cfg.fontcharset;
1377 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1378 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1379 lf.lfQuality = DEFAULT_QUALITY;
1380 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1381 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1382 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1384 cf.lStructSize = sizeof(cf);
1385 cf.hwndOwner = hwnd;
1387 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1388 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1390 if (ChooseFont (&cf)) {
1391 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1392 cfg.font[sizeof(cfg.font)-1] = '\0';
1393 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1394 cfg.fontcharset = lf.lfCharSet;
1395 cfg.fontheight = lf.lfHeight;
1396 fmtfont (fontstatic);
1397 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1401 if (HIWORD(wParam) == BN_CLICKED ||
1402 HIWORD(wParam) == BN_DOUBLECLICKED)
1403 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1406 if (HIWORD(wParam) == BN_CLICKED ||
1407 HIWORD(wParam) == BN_DOUBLECLICKED)
1408 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1411 if (HIWORD(wParam) == BN_CLICKED ||
1412 HIWORD(wParam) == BN_DOUBLECLICKED)
1413 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1416 if (HIWORD(wParam) == BN_CLICKED ||
1417 HIWORD(wParam) == BN_DOUBLECLICKED)
1418 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1421 if (HIWORD(wParam) == BN_CLICKED ||
1422 HIWORD(wParam) == BN_DOUBLECLICKED)
1423 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1426 if (HIWORD(wParam) == BN_CLICKED ||
1427 HIWORD(wParam) == BN_DOUBLECLICKED)
1428 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1431 if (HIWORD(wParam) == BN_CLICKED ||
1432 HIWORD(wParam) == BN_DOUBLECLICKED)
1433 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1436 if (HIWORD(wParam) == EN_CHANGE)
1437 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1438 sizeof(cfg.wintitle)-1);
1441 if (HIWORD(wParam) == BN_CLICKED ||
1442 HIWORD(wParam) == BN_DOUBLECLICKED)
1443 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1446 if (HIWORD(wParam) == BN_CLICKED ||
1447 HIWORD(wParam) == BN_DOUBLECLICKED)
1448 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1451 if (HIWORD(wParam) == EN_CHANGE)
1452 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1453 sizeof(cfg.termtype)-1);
1456 if (HIWORD(wParam) == EN_CHANGE)
1457 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1458 sizeof(cfg.logfilename)-1);
1461 memset(&of, 0, sizeof(of));
1462 #ifdef OPENFILENAME_SIZE_VERSION_400
1463 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1465 of.lStructSize = sizeof(of);
1467 of.hwndOwner = hwnd;
1468 of.lpstrFilter = "All Files\0*\0\0\0";
1469 of.lpstrCustomFilter = NULL;
1470 of.nFilterIndex = 1;
1471 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1472 of.nMaxFile = sizeof(filename);
1473 of.lpstrFileTitle = NULL;
1474 of.lpstrInitialDir = NULL;
1475 of.lpstrTitle = "Select session log file";
1477 if (GetSaveFileName(&of)) {
1478 strcpy(cfg.keyfile, filename);
1479 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.keyfile);
1483 case IDC_LSTATASCII:
1485 if (HIWORD(wParam) == BN_CLICKED ||
1486 HIWORD(wParam) == BN_DOUBLECLICKED) {
1487 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1488 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1489 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1493 if (HIWORD(wParam) == EN_CHANGE)
1494 GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
1495 sizeof(cfg.termspeed)-1);
1498 if (HIWORD(wParam) == EN_CHANGE)
1499 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1500 sizeof(cfg.username)-1);
1504 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1507 if (HIWORD(wParam) == BN_CLICKED ||
1508 HIWORD(wParam) == BN_DOUBLECLICKED) {
1509 char str[sizeof(cfg.environmt)];
1511 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1516 p = str + strlen(str);
1518 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1528 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1530 p[strlen(str)+1] = '\0';
1531 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1533 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1534 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1536 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1537 MB_OK | MB_ICONERROR);
1542 if (HIWORD(wParam) != BN_CLICKED &&
1543 HIWORD(wParam) != BN_DOUBLECLICKED)
1545 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1551 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1576 if (HIWORD(wParam) == BN_CLICKED ||
1577 HIWORD(wParam) == BN_DOUBLECLICKED)
1578 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1581 if (HIWORD(wParam) == BN_CLICKED ||
1582 HIWORD(wParam) == BN_DOUBLECLICKED)
1583 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1586 if (HIWORD(wParam) == BN_CLICKED ||
1587 HIWORD(wParam) == BN_DOUBLECLICKED)
1588 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1591 if (HIWORD(wParam) == BN_CLICKED ||
1592 HIWORD(wParam) == BN_DOUBLECLICKED)
1593 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1595 case IDC_CIPHER3DES:
1596 case IDC_CIPHERBLOWF:
1598 if (HIWORD(wParam) == BN_CLICKED ||
1599 HIWORD(wParam) == BN_DOUBLECLICKED) {
1600 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1601 cfg.cipher = CIPHER_3DES;
1602 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1603 cfg.cipher = CIPHER_BLOWFISH;
1604 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1605 cfg.cipher = CIPHER_DES;
1610 if (HIWORD(wParam) == BN_CLICKED ||
1611 HIWORD(wParam) == BN_DOUBLECLICKED) {
1612 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1614 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1619 if (HIWORD(wParam) == BN_CLICKED ||
1620 HIWORD(wParam) == BN_DOUBLECLICKED)
1621 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1624 if (HIWORD(wParam) == EN_CHANGE)
1625 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1626 sizeof(cfg.keyfile)-1);
1629 if (HIWORD(wParam) == EN_CHANGE)
1630 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1631 sizeof(cfg.remote_cmd)-1);
1634 memset(&of, 0, sizeof(of));
1635 #ifdef OPENFILENAME_SIZE_VERSION_400
1636 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1638 of.lStructSize = sizeof(of);
1640 of.hwndOwner = hwnd;
1641 of.lpstrFilter = "All Files\0*\0\0\0";
1642 of.lpstrCustomFilter = NULL;
1643 of.nFilterIndex = 1;
1644 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1645 of.nMaxFile = sizeof(filename);
1646 of.lpstrFileTitle = NULL;
1647 of.lpstrInitialDir = NULL;
1648 of.lpstrTitle = "Select Public Key File";
1650 if (GetOpenFileName(&of)) {
1651 strcpy(cfg.keyfile, filename);
1652 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1657 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1663 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1668 for (i=0; i<256; i++)
1669 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1672 cfg.wordness[i] = n;
1673 SendDlgItemMessage (hwnd, IDC_CCLIST,
1674 LB_DELETESTRING, i, 0);
1675 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1676 (i>=0x21 && i != 0x7F) ? i : ' ',
1678 SendDlgItemMessage (hwnd, IDC_CCLIST,
1685 case IDC_BOLDCOLOUR:
1686 if (HIWORD(wParam) == BN_CLICKED ||
1687 HIWORD(wParam) == BN_DOUBLECLICKED) {
1689 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1690 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1691 if (n != 12+10*cfg.bold_colour) {
1693 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1694 LB_DELETESTRING, i, 0);
1695 for (i=0; i<22; i++)
1696 if (cfg.bold_colour || permcolour[i])
1697 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1699 (LPARAM) colours[i]);
1704 if (HIWORD(wParam) == BN_CLICKED ||
1705 HIWORD(wParam) == BN_DOUBLECLICKED)
1706 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1708 case IDC_COLOURLIST:
1709 if (HIWORD(wParam) == LBN_DBLCLK ||
1710 HIWORD(wParam) == LBN_SELCHANGE) {
1711 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1713 if (!cfg.bold_colour)
1714 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1715 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1716 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1717 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1721 if (HIWORD(wParam) == BN_CLICKED ||
1722 HIWORD(wParam) == BN_DOUBLECLICKED) {
1723 static CHOOSECOLOR cc;
1724 static DWORD custom[16] = {0}; /* zero initialisers */
1725 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1727 if (!cfg.bold_colour)
1728 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1729 cc.lStructSize = sizeof(cc);
1730 cc.hwndOwner = hwnd;
1731 cc.hInstance = (HWND)hinst;
1732 cc.lpCustColors = custom;
1733 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1735 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1736 if (ChooseColor(&cc)) {
1738 (unsigned char) (cc.rgbResult & 0xFF);
1740 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1742 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1743 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1745 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1747 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1753 case IDC_KOI8WIN1251:
1754 case IDC_88592WIN1250:
1755 case IDC_88592CP852:
1756 cfg.xlat_enablekoiwin =
1757 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1758 cfg.xlat_88592w1250 =
1759 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1760 cfg.xlat_88592cp852 =
1761 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1763 case IDC_CAPSLOCKCYR:
1764 if (HIWORD(wParam) == BN_CLICKED ||
1765 HIWORD(wParam) == BN_DOUBLECLICKED) {
1766 cfg.xlat_capslockcyr =
1767 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1770 case IDC_VTXWINDOWS:
1775 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1776 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1777 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1783 EndDialog (hwnd, 0);
1786 /* Grrr Explorer will maximize Dialogs! */
1788 if (wParam == SIZE_MAXIMIZED)
1795 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1796 WPARAM wParam, LPARAM lParam) {
1797 static HWND page = NULL;
1799 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1801 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1802 EnableWindow(hwnd, 0);
1803 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1804 GetParent(hwnd), AboutProc);
1805 EnableWindow(hwnd, 1);
1806 SetActiveWindow(hwnd);
1808 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1811 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1812 WPARAM wParam, LPARAM lParam) {
1814 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1817 void defuse_showwindow(void) {
1819 * Work around the fact that the app's first call to ShowWindow
1820 * will ignore the default in favour of the shell-provided
1825 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1827 ShowWindow(hwnd, SW_HIDE);
1828 DestroyWindow(hwnd);
1832 int do_config (void) {
1836 savedsession[0] = '\0';
1837 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1838 get_sesslist(FALSE);
1843 int do_reconfig (HWND hwnd) {
1847 backup_cfg = cfg; /* structure copy */
1848 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1850 cfg = backup_cfg; /* structure copy */
1855 void logevent (char *string) {
1856 if (nevents >= negsize) {
1858 events = srealloc (events, negsize * sizeof(*events));
1860 events[nevents] = smalloc(1+strlen(string));
1861 strcpy (events[nevents], string);
1865 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1867 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1868 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1872 void showeventlog (HWND hwnd) {
1874 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1876 ShowWindow (logbox, SW_SHOWNORMAL);
1880 void showabout (HWND hwnd) {
1882 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1884 ShowWindow (abtbox, SW_SHOWNORMAL);
1888 void verify_ssh_host_key(char *host, int port, char *keytype,
1889 char *keystr, char *fingerprint) {
1892 static const char absentmsg[] =
1893 "The server's host key is not cached in the registry. You\n"
1894 "have no guarantee that the server is the computer you\n"
1896 "The server's key fingerprint is:\n"
1898 "If you trust this host, hit Yes to add the key to\n"
1899 "PuTTY's cache and carry on connecting.\n"
1900 "If you do not trust this host, hit No to abandon the\n"
1903 static const char wrongmsg[] =
1904 "WARNING - POTENTIAL SECURITY BREACH!\n"
1906 "The server's host key does not match the one PuTTY has\n"
1907 "cached in the registry. This means that either the\n"
1908 "server administrator has changed the host key, or you\n"
1909 "have actually connected to another computer pretending\n"
1910 "to be the server.\n"
1911 "The new key fingerprint is:\n"
1913 "If you were expecting this change and trust the new key,\n"
1914 "hit Yes to update PuTTY's cache and continue connecting.\n"
1915 "If you want to carry on connecting but without updating\n"
1916 "the cache, hit No.\n"
1917 "If you want to abandon the connection completely, hit\n"
1918 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1921 static const char mbtitle[] = "PuTTY Security Alert";
1924 char message[160+ /* sensible fingerprint max size */
1925 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1926 sizeof(absentmsg) : sizeof(wrongmsg))];
1929 * Verify the key against the registry.
1931 ret = verify_host_key(host, port, keytype, keystr);
1933 if (ret == 0) /* success - key matched OK */
1935 if (ret == 2) { /* key was different */
1937 sprintf(message, wrongmsg, fingerprint);
1938 mbret = MessageBox(NULL, message, mbtitle,
1939 MB_ICONWARNING | MB_YESNOCANCEL);
1941 store_host_key(host, port, keytype, keystr);
1942 if (mbret == IDCANCEL)
1945 if (ret == 1) { /* key was absent */
1947 sprintf(message, absentmsg, fingerprint);
1948 mbret = MessageBox(NULL, message, mbtitle,
1949 MB_ICONWARNING | MB_YESNO);
1952 store_host_key(host, port, keytype, keystr);
1957 * Ask whether to wipe a session log file before writing to it.
1958 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
1960 int askappend(char *filename) {
1961 static const char mbtitle[] = "PuTTY Log to File";
1962 static const char msgtemplate[] =
1963 "The session log file \"%.*s\" already exists.\n"
1964 "You can overwrite it with a new session log,\n"
1965 "append your session log to the end of it,\n"
1966 "or disable session logging for this session.\n"
1967 "Hit Yes to wipe the file, No to append to it,\n"
1968 "or Cancel to disable logging.";
1969 char message[sizeof(msgtemplate) + FILENAME_MAX];
1971 sprintf(message, msgtemplate, FILENAME_MAX, filename);
1973 mbret = MessageBox(NULL, message, mbtitle,
1974 MB_ICONQUESTION | MB_YESNOCANCEL);
1977 else if (mbret == IDNO)