13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
16 static HWND logbox = NULL, abtbox = NULL;
20 static void force_normal(HWND hwnd)
22 static int recurse = 0;
29 wp.length = sizeof(wp);
30 if (GetWindowPlacement(hwnd, &wp))
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
38 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
46 static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
52 for (i=0; i<nevents; i++)
53 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
54 0, (LPARAM)events[i]);
57 switch (LOWORD(wParam)) {
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
69 selitems = malloc(selcount * sizeof(int));
71 int count = SendDlgItemMessage(hwnd, IDN_LIST,
73 selcount, (LPARAM)selitems);
77 static unsigned char sel_nl[] = SEL_NL;
79 if (count == 0) { /* can't copy zero stuff */
85 for (i = 0; i < count; i++)
86 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
88 clipdata = malloc(size);
91 for (i = 0; i < count; i++) {
92 char *q = events[selitems[i]];
96 memcpy(p, sel_nl, sizeof(sel_nl));
99 write_clip(clipdata, size, TRUE);
104 for (i = 0; i < nevents; i++)
105 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
114 DestroyWindow (hwnd);
120 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
121 WPARAM wParam, LPARAM lParam) {
126 switch (LOWORD(wParam)) {
139 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
140 WPARAM wParam, LPARAM lParam) {
143 SetDlgItemText (hwnd, IDA_VERSION, ver);
146 switch (LOWORD(wParam)) {
149 DestroyWindow (hwnd);
152 EnableWindow(hwnd, 0);
153 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
155 EnableWindow(hwnd, 1);
156 SetActiveWindow(hwnd);
162 DestroyWindow (hwnd);
169 * Null dialog procedure.
171 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
172 WPARAM wParam, LPARAM lParam) {
176 static char savedsession[2048];
178 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
182 IDC_BOX_SESSION1, IDC_BOXT_SESSION1,
183 IDC_BOX_SESSION2, IDC_BOXT_SESSION2,
204 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1,
205 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2,
206 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3,
230 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
231 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2,
232 IDC_BOX_TERMINAL3, IDC_BOXT_TERMINAL3,
252 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
253 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
254 IDC_BOX_WINDOW3, IDC_BOXT_WINDOW3,
271 connectionpanelstart,
272 IDC_TITLE_CONNECTION,
273 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
274 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
285 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
286 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
304 IDC_BOX_SSH1, IDC_BOXT_SSH1,
305 IDC_BOX_SSH2, IDC_BOXT_SSH2,
306 IDC_BOX_SSH3, IDC_BOXT_SSH3,
327 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
328 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
341 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
342 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
356 translationpanelstart,
357 IDC_TITLE_TRANSLATION,
358 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
359 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
360 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
377 static const char *const colours[] = {
378 "Default Foreground", "Default Bold Foreground",
379 "Default Background", "Default Bold Background",
380 "Cursor Text", "Cursor Colour",
381 "ANSI Black", "ANSI Black Bold",
382 "ANSI Red", "ANSI Red Bold",
383 "ANSI Green", "ANSI Green Bold",
384 "ANSI Yellow", "ANSI Yellow Bold",
385 "ANSI Blue", "ANSI Blue Bold",
386 "ANSI Magenta", "ANSI Magenta Bold",
387 "ANSI Cyan", "ANSI Cyan Bold",
388 "ANSI White", "ANSI White Bold"
390 static const int permcolour[] = {
391 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
392 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
393 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
396 static void fmtfont (char *buf) {
397 sprintf (buf, "Font: %s, ", cfg.font);
399 strcat(buf, "bold, ");
400 if (cfg.fontheight == 0)
401 strcat (buf, "default height");
403 sprintf (buf+strlen(buf), "%d-%s",
404 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
405 (cfg.fontheight < 0 ? "pixel" : "point"));
408 static void init_dlg_ctrls(HWND hwnd) {
410 char fontstatic[256];
412 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
413 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
414 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
415 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
416 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
417 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : IDC_PROTRAW );
418 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
420 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
421 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
422 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
423 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
424 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
425 cfg.funky_type == 0 ? IDC_FUNCTILDE :
426 cfg.funky_type == 1 ? IDC_FUNCLINUX :
427 cfg.funky_type == 2 ? IDC_FUNCXTERM :
428 cfg.funky_type == 3 ? IDC_FUNCVT400 :
430 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
431 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
432 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
433 cfg.nethack_keypad ? IDC_KPNH :
434 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
435 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
436 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
437 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
438 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
439 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
440 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
441 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
443 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
444 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
445 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
446 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
447 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
448 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
449 fmtfont (fontstatic);
450 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
451 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
452 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
453 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
455 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
456 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
457 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
458 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
459 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
460 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
461 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
463 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
464 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
465 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
467 char *p = cfg.environmt;
469 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
474 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
475 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
477 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
478 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
479 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
480 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
481 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
482 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
483 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
484 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
486 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
487 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
488 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
489 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
490 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
492 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
493 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
495 static int tabs[4] = {25, 61, 96, 128};
496 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
499 for (i=0; i<256; i++) {
501 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
502 (i>=0x21 && i != 0x7F) ? i : ' ',
504 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
508 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
509 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
513 if (cfg.bold_colour || permcolour[i])
514 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
515 (LPARAM) colours[i]);
517 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
518 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
519 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
520 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
522 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
523 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
524 cfg.xlat_88592cp852 ? IDC_88592CP852 :
525 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
527 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
528 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
529 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
530 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
531 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
535 static void hide(HWND hwnd, int hide, int minid, int maxid) {
537 for (i = minid; i < maxid; i++) {
538 HWND ctl = GetDlgItem(hwnd, i);
540 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
545 struct treeview_faff {
550 static HTREEITEM treeview_insert(struct treeview_faff *faff,
551 int level, char *text) {
555 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
556 ins.hInsertAfter = faff->lastat[level];
557 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
558 #define INSITEM DUMMYUNIONNAME.item
562 ins.INSITEM.mask = TVIF_TEXT;
563 ins.INSITEM.pszText = text;
564 newitem = TreeView_InsertItem(faff->treeview, &ins);
566 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
567 faff->lastat[level] = newitem;
568 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
573 * This _huge_ function is the configuration box.
575 static int GenericMainDlgProc (HWND hwnd, UINT msg,
576 WPARAM wParam, LPARAM lParam,
579 struct treeview_faff tvfaff;
582 char filename[sizeof(cfg.keyfile)];
585 char fontstatic[256];
591 SetWindowLong(hwnd, GWL_USERDATA, 0);
595 { /* centre the window */
598 hw = GetDesktopWindow();
599 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
600 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
601 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
602 rd.right-rd.left, rd.bottom-rd.top, TRUE);
606 * Create the tree view.
613 r.left = 3; r.right = r.left + 75;
614 r.top = 3; r.bottom = r.top + 10;
615 MapDialogRect(hwnd, &r);
616 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
617 WS_CHILD | WS_VISIBLE,
619 r.right-r.left, r.bottom-r.top,
620 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
621 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
622 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
624 r.left = 3; r.right = r.left + 75;
625 r.top = 13; r.bottom = r.top + 196;
626 MapDialogRect(hwnd, &r);
627 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
628 WS_CHILD | WS_VISIBLE |
629 WS_TABSTOP | TVS_HASLINES |
630 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
631 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
633 r.right-r.left, r.bottom-r.top,
634 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
635 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
636 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
637 tvfaff.treeview = treeview;
638 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
642 * Create the various panelfuls of controls.
645 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
648 ctlposinit(&cp, hwnd, 80, 3, 13);
649 bartitle(&cp, "Basic options for your PuTTY session",
652 beginbox(&cp, "Specify your connection by host name",
653 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
655 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
656 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
657 if (backends[2].backend == NULL) {
658 /* this is PuTTYtel, so only two protocols available */
659 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
661 "&Telnet", IDC_PROTTELNET, NULL);
663 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
665 "&Telnet", IDC_PROTTELNET,
674 beginbox(&cp, "Load, save or delete a stored session",
675 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
676 sesssaver(&cp, "Sav&ed Sessions",
677 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
678 "&Load", IDC_SESSLOAD,
679 "&Save", IDC_SESSSAVE,
680 "&Delete", IDC_SESSDEL, NULL);
683 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
684 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
687 hsession = treeview_insert(&tvfaff, 0, "Session");
690 /* The Terminal panel. Accelerators used: [acgo] rmkh&dlbenu */
693 ctlposinit(&cp, hwnd, 80, 3, 13);
694 bartitle(&cp, "Options controlling the terminal emulation",
696 beginbox(&cp, "Set the size of the terminal window",
697 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
699 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
700 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
702 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
704 beginbox(&cp, "Set the font used in the terminal window",
705 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2);
706 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
708 beginbox(&cp, "Set various terminal options",
709 IDC_BOX_TERMINAL3, IDC_BOXT_TERMINAL3);
710 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
711 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
712 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
713 checkbox(&cp, "&Beep enabled", IDC_BEEP);
714 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
715 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
716 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
719 treeview_insert(&tvfaff, 0, "Terminal");
722 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmiet */
725 ctlposinit(&cp, hwnd, 80, 3, 13);
726 bartitle(&cp, "Options controlling the effects of keys",
728 beginbox(&cp, "Change the sequences sent by:",
729 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
730 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
731 "Control-&H", IDC_DEL008,
732 "Control-&? (127)", IDC_DEL127, NULL);
733 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
734 "&Standard", IDC_HOMETILDE,
735 "&rxvt", IDC_HOMERXVT, NULL);
736 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
737 "ESC[n&~", IDC_FUNCTILDE,
738 "&Linux", IDC_FUNCLINUX,
739 "&Xterm R6", IDC_FUNCXTERM,
740 "&VT400", IDC_FUNCVT400, NULL);
742 beginbox(&cp, "Change the initial state of:",
743 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
744 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
745 "&Normal", IDC_CURNORMAL,
746 "A&pplication", IDC_CURAPPLIC, NULL);
747 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
748 "Nor&mal", IDC_KPNORMAL,
749 "Appl&ication", IDC_KPAPPLIC,
750 "N&etHack", IDC_KPNH, NULL);
752 beginbox(&cp, "Enable extra keyboard features:",
753 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
754 checkbox(&cp, "Application and AltGr ac&t as Compose key",
758 treeview_insert(&tvfaff, 1, "Keyboard");
761 /* The Window panel. Accelerators used: [acgo] tibsdkw4ylp */
764 ctlposinit(&cp, hwnd, 80, 3, 13);
765 bartitle(&cp, "Options controlling PuTTY's window",
767 beginbox(&cp, "Adjust the use of the window title",
768 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
771 "Initial window &title:", IDC_WINTITLE,
772 IDC_WINEDIT, 100, NULL);
773 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
775 beginbox(&cp, "Adjust the use of the cursor",
776 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
777 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
779 beginbox(&cp, "Control the scrollback in the window",
780 IDC_BOX_WINDOW3, IDC_BOXT_WINDOW3);
781 staticedit(&cp, "Lines of &scrollback",
782 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
783 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
784 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
785 checkbox(&cp, "Reset scrollback on dis&play activity",
788 beginbox(&cp, NULL, IDC_BOX_WINDOW4, 0);
789 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
790 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
791 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
792 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
795 treeview_insert(&tvfaff, 0, "Window");
798 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
801 ctlposinit(&cp, hwnd, 80, 3, 13);
802 bartitle(&cp, "Options controlling character set translation",
803 IDC_TITLE_TRANSLATION);
804 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
805 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
807 "Handling of line drawing characters:", IDC_VTSTATIC,
808 "Font has &XWindows encoding", IDC_VTXWINDOWS,
809 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
810 "Use font in O&EM mode only", IDC_VTOEMONLY,
811 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
812 IDC_VTPOORMAN, NULL);
814 beginbox(&cp, "Enable character set translation on received data",
815 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
817 "Character set translation:", IDC_XLATSTATIC,
819 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
820 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
821 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
823 beginbox(&cp, "Enable character set translation on input data",
824 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
825 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
829 treeview_insert(&tvfaff, 1, "Translation");
832 /* The Selection panel. Accelerators used: [acgo] wxst */
835 ctlposinit(&cp, hwnd, 80, 3, 13);
836 bartitle(&cp, "Options controlling copy and paste",
837 IDC_TITLE_SELECTION);
838 beginbox(&cp, "Control which mouse button does which thing",
839 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
840 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
841 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
842 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
845 beginbox(&cp, "Control the select-one-word-at-a-time mode",
846 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
847 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
848 "&Set", IDC_CCSET, IDC_CCEDIT,
849 "&to class", IDC_CCSTATIC2);
852 treeview_insert(&tvfaff, 1, "Selection");
855 /* The Colours panel. Accelerators used: [acgo] blum */
858 ctlposinit(&cp, hwnd, 80, 3, 13);
859 bartitle(&cp, "Options controlling use of colours",
861 beginbox(&cp, "General options for colour usage",
862 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
863 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
864 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
866 beginbox(&cp, "Adjust the precise colours PuTTY displays",
867 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
868 colouredit(&cp, "Select a colo&ur and then click to modify it:",
869 IDC_COLOURSTATIC, IDC_COLOURLIST,
870 "&Modify...", IDC_CHANGE,
871 "Red:", IDC_RSTATIC, IDC_RVALUE,
872 "Green:", IDC_GSTATIC, IDC_GVALUE,
873 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
876 treeview_insert(&tvfaff, 1, "Colours");
879 /* The Connection panel. Accelerators used: [acgo] tuk */
882 ctlposinit(&cp, hwnd, 80, 3, 13);
883 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
885 beginbox(&cp, "Data to send to the server",
886 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
887 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
888 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
891 beginbox(&cp, "Sending of null packets to keep session active",
892 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
893 staticedit(&cp, "Minutes between &keepalives (0 to turn off)",
894 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
897 treeview_insert(&tvfaff, 0, "Connection");
900 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
903 ctlposinit(&cp, hwnd, 80, 3, 13);
905 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
906 beginbox(&cp, "Data to send to the server",
907 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
908 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
909 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
910 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
911 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
913 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
915 beginbox(&cp, "Telnet protocol adjustments",
916 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
917 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
918 "&BSD (commonplace)", IDC_EMBSD,
919 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
922 treeview_insert(&tvfaff, 1, "Telnet");
926 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
927 if (backends[2].backend != NULL) {
929 ctlposinit(&cp, hwnd, 80, 3, 13);
931 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
932 beginbox(&cp, "Data to send to the server",
933 IDC_BOX_SSH1, IDC_BOXT_SSH1);
935 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
938 beginbox(&cp, "Authentication options",
939 IDC_BOX_SSH2, IDC_BOXT_SSH2);
940 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
942 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
943 editbutton(&cp, "Private &key file for authentication:",
944 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
946 beginbox(&cp, "Protocol options",
947 IDC_BOX_SSH3, IDC_BOXT_SSH3);
948 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
949 radioline(&cp, "Preferred SSH protocol version:",
950 IDC_SSHPROTSTATIC, 2,
951 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
952 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
953 "&3DES", IDC_CIPHER3DES,
954 "&Blowfish", IDC_CIPHERBLOWF,
955 "&DES", IDC_CIPHERDES, NULL);
956 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
960 treeview_insert(&tvfaff, 1, "SSH");
964 init_dlg_ctrls(hwnd);
965 for (i = 0; i < nsessions; i++)
966 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
967 0, (LPARAM) (sessions[i]));
970 * Hide all the controls to start with.
972 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
975 * Put the treeview selection on to the Session panel. This
976 * should also cause unhiding of the relevant controls.
978 TreeView_SelectItem(treeview, hsession);
981 * Set focus into the first available control.
985 ctl = GetDlgItem(hwnd, IDC_HOST);
986 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
990 SetWindowLong(hwnd, GWL_USERDATA, 1);
994 * Button release should trigger WM_OK if there was a
995 * previous double click on the session list.
999 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1002 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1003 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1004 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1008 item.pszText = buffer;
1009 item.cchTextMax = sizeof(buffer);
1010 item.mask = TVIF_TEXT;
1011 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1012 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1013 if (!strcmp(buffer, "Session"))
1014 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1015 if (!strcmp(buffer, "Keyboard"))
1016 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1017 if (!strcmp(buffer, "Terminal"))
1018 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1019 if (!strcmp(buffer, "Window"))
1020 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1021 if (!strcmp(buffer, "Connection"))
1022 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1023 if (!strcmp(buffer, "Telnet"))
1024 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1025 if (!strcmp(buffer, "SSH"))
1026 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1027 if (!strcmp(buffer, "Selection"))
1028 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1029 if (!strcmp(buffer, "Colours"))
1030 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1031 if (!strcmp(buffer, "Translation"))
1032 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1034 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1040 * Only process WM_COMMAND once the dialog is fully formed.
1042 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1045 EndDialog (hwnd, 1);
1050 EndDialog (hwnd, 0);
1052 case IDC_PROTTELNET:
1055 if (HIWORD(wParam) == BN_CLICKED ||
1056 HIWORD(wParam) == BN_DOUBLECLICKED) {
1057 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1058 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1059 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1060 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1061 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1062 cfg.port = i ? 22 : 23;
1063 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1068 if (HIWORD(wParam) == EN_CHANGE)
1069 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1070 sizeof(cfg.host)-1);
1073 if (HIWORD(wParam) == EN_CHANGE)
1074 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1077 if (HIWORD(wParam) == EN_CHANGE) {
1078 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1080 GetDlgItemText (hwnd, IDC_SESSEDIT,
1081 savedsession, sizeof(savedsession)-1);
1082 savedsession[sizeof(savedsession)-1] = '\0';
1086 if (HIWORD(wParam) == BN_CLICKED ||
1087 HIWORD(wParam) == BN_DOUBLECLICKED) {
1092 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1094 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1095 LB_GETCURSEL, 0, 0);
1100 strcpy (str, sessions[n]);
1102 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1103 get_sesslist (FALSE);
1104 get_sesslist (TRUE);
1105 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1107 for (i = 0; i < nsessions; i++)
1108 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1109 0, (LPARAM) (sessions[i]));
1110 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1116 if (LOWORD(wParam) == IDC_SESSLOAD &&
1117 HIWORD(wParam) != BN_CLICKED &&
1118 HIWORD(wParam) != BN_DOUBLECLICKED)
1120 if (LOWORD(wParam) == IDC_SESSLIST &&
1121 HIWORD(wParam) != LBN_DBLCLK)
1124 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1125 LB_GETCURSEL, 0, 0);
1131 isdef = !strcmp(sessions[n], "Default Settings");
1132 load_settings (sessions[n], !isdef, &cfg);
1133 init_dlg_ctrls(hwnd);
1135 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1137 if (LOWORD(wParam) == IDC_SESSLIST) {
1139 * A double-click on a saved session should
1140 * actually start the session, not just load it.
1141 * Unless it's Default Settings or some other
1142 * host-less set of saved settings.
1151 if (HIWORD(wParam) == BN_CLICKED ||
1152 HIWORD(wParam) == BN_DOUBLECLICKED) {
1153 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1154 LB_GETCURSEL, 0, 0);
1155 if (n == LB_ERR || n == 0) {
1159 del_settings(sessions[n]);
1160 get_sesslist (FALSE);
1161 get_sesslist (TRUE);
1162 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1164 for (i = 0; i < nsessions; i++)
1165 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1166 0, (LPARAM) (sessions[i]));
1167 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1171 if (HIWORD(wParam) == EN_CHANGE)
1172 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1176 if (HIWORD(wParam) == BN_CLICKED ||
1177 HIWORD(wParam) == BN_DOUBLECLICKED)
1178 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1182 if (HIWORD(wParam) == BN_CLICKED ||
1183 HIWORD(wParam) == BN_DOUBLECLICKED)
1184 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1187 if (HIWORD(wParam) == BN_CLICKED ||
1188 HIWORD(wParam) == BN_DOUBLECLICKED)
1192 if (HIWORD(wParam) == BN_CLICKED ||
1193 HIWORD(wParam) == BN_DOUBLECLICKED)
1198 if (HIWORD(wParam) == BN_CLICKED ||
1199 HIWORD(wParam) == BN_DOUBLECLICKED)
1200 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1204 if (HIWORD(wParam) == BN_CLICKED ||
1205 HIWORD(wParam) == BN_DOUBLECLICKED) {
1206 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1207 cfg.nethack_keypad = FALSE;
1211 if (HIWORD(wParam) == BN_CLICKED ||
1212 HIWORD(wParam) == BN_DOUBLECLICKED) {
1213 cfg.app_keypad = FALSE;
1214 cfg.nethack_keypad = TRUE;
1219 if (HIWORD(wParam) == BN_CLICKED ||
1220 HIWORD(wParam) == BN_DOUBLECLICKED)
1221 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1224 if (HIWORD(wParam) == BN_CLICKED ||
1225 HIWORD(wParam) == BN_DOUBLECLICKED)
1226 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1229 if (HIWORD(wParam) == BN_CLICKED ||
1230 HIWORD(wParam) == BN_DOUBLECLICKED)
1231 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1234 if (HIWORD(wParam) == BN_CLICKED ||
1235 HIWORD(wParam) == BN_DOUBLECLICKED)
1236 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1239 if (HIWORD(wParam) == BN_CLICKED ||
1240 HIWORD(wParam) == BN_DOUBLECLICKED)
1241 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1244 if (HIWORD(wParam) == BN_CLICKED ||
1245 HIWORD(wParam) == BN_DOUBLECLICKED)
1246 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1248 case IDC_SCROLLDISP:
1249 if (HIWORD(wParam) == BN_CLICKED ||
1250 HIWORD(wParam) == BN_DOUBLECLICKED)
1251 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1253 case IDC_COMPOSEKEY:
1254 if (HIWORD(wParam) == BN_CLICKED ||
1255 HIWORD(wParam) == BN_DOUBLECLICKED)
1256 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1259 if (HIWORD(wParam) == BN_CLICKED ||
1260 HIWORD(wParam) == BN_DOUBLECLICKED)
1261 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1264 if (HIWORD(wParam) == BN_CLICKED ||
1265 HIWORD(wParam) == BN_DOUBLECLICKED)
1266 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1269 if (HIWORD(wParam) == BN_CLICKED ||
1270 HIWORD(wParam) == BN_DOUBLECLICKED)
1271 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1274 if (HIWORD(wParam) == EN_CHANGE)
1275 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1278 if (HIWORD(wParam) == EN_CHANGE)
1279 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1282 if (HIWORD(wParam) == EN_CHANGE)
1283 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1285 case IDC_CHOOSEFONT:
1286 lf.lfHeight = cfg.fontheight;
1287 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1288 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1289 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1290 lf.lfCharSet = cfg.fontcharset;
1291 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1292 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1293 lf.lfQuality = DEFAULT_QUALITY;
1294 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1295 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1296 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1298 cf.lStructSize = sizeof(cf);
1299 cf.hwndOwner = hwnd;
1301 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1302 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1304 if (ChooseFont (&cf)) {
1305 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1306 cfg.font[sizeof(cfg.font)-1] = '\0';
1307 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1308 cfg.fontcharset = lf.lfCharSet;
1309 cfg.fontheight = lf.lfHeight;
1310 fmtfont (fontstatic);
1311 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1315 if (HIWORD(wParam) == BN_CLICKED ||
1316 HIWORD(wParam) == BN_DOUBLECLICKED)
1317 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1320 if (HIWORD(wParam) == BN_CLICKED ||
1321 HIWORD(wParam) == BN_DOUBLECLICKED)
1322 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1325 if (HIWORD(wParam) == BN_CLICKED ||
1326 HIWORD(wParam) == BN_DOUBLECLICKED)
1327 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1330 if (HIWORD(wParam) == BN_CLICKED ||
1331 HIWORD(wParam) == BN_DOUBLECLICKED)
1332 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1335 if (HIWORD(wParam) == BN_CLICKED ||
1336 HIWORD(wParam) == BN_DOUBLECLICKED)
1337 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1340 if (HIWORD(wParam) == BN_CLICKED ||
1341 HIWORD(wParam) == BN_DOUBLECLICKED)
1342 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1345 if (HIWORD(wParam) == BN_CLICKED ||
1346 HIWORD(wParam) == BN_DOUBLECLICKED)
1347 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1350 if (HIWORD(wParam) == EN_CHANGE)
1351 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1352 sizeof(cfg.wintitle)-1);
1355 if (HIWORD(wParam) == BN_CLICKED ||
1356 HIWORD(wParam) == BN_DOUBLECLICKED)
1357 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1360 if (HIWORD(wParam) == BN_CLICKED ||
1361 HIWORD(wParam) == BN_DOUBLECLICKED)
1362 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1365 if (HIWORD(wParam) == EN_CHANGE)
1366 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1367 sizeof(cfg.termtype)-1);
1370 if (HIWORD(wParam) == EN_CHANGE)
1371 GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
1372 sizeof(cfg.termspeed)-1);
1375 if (HIWORD(wParam) == EN_CHANGE)
1376 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1377 sizeof(cfg.username)-1);
1381 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1384 if (HIWORD(wParam) == BN_CLICKED ||
1385 HIWORD(wParam) == BN_DOUBLECLICKED) {
1386 char str[sizeof(cfg.environmt)];
1388 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1393 p = str + strlen(str);
1395 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1405 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1407 p[strlen(str)+1] = '\0';
1408 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1410 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1411 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1413 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1414 MB_OK | MB_ICONERROR);
1419 if (HIWORD(wParam) != BN_CLICKED &&
1420 HIWORD(wParam) != BN_DOUBLECLICKED)
1422 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1428 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1453 if (HIWORD(wParam) == BN_CLICKED ||
1454 HIWORD(wParam) == BN_DOUBLECLICKED)
1455 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1458 if (HIWORD(wParam) == BN_CLICKED ||
1459 HIWORD(wParam) == BN_DOUBLECLICKED)
1460 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1463 if (HIWORD(wParam) == BN_CLICKED ||
1464 HIWORD(wParam) == BN_DOUBLECLICKED)
1465 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1467 case IDC_CIPHER3DES:
1468 case IDC_CIPHERBLOWF:
1470 if (HIWORD(wParam) == BN_CLICKED ||
1471 HIWORD(wParam) == BN_DOUBLECLICKED) {
1472 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1473 cfg.cipher = CIPHER_3DES;
1474 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1475 cfg.cipher = CIPHER_BLOWFISH;
1476 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1477 cfg.cipher = CIPHER_DES;
1482 if (HIWORD(wParam) == BN_CLICKED ||
1483 HIWORD(wParam) == BN_DOUBLECLICKED) {
1484 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1486 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1491 if (HIWORD(wParam) == BN_CLICKED ||
1492 HIWORD(wParam) == BN_DOUBLECLICKED)
1493 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1496 if (HIWORD(wParam) == EN_CHANGE)
1497 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1498 sizeof(cfg.keyfile)-1);
1501 if (HIWORD(wParam) == EN_CHANGE)
1502 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1503 sizeof(cfg.remote_cmd)-1);
1506 memset(&of, 0, sizeof(of));
1507 #ifdef OPENFILENAME_SIZE_VERSION_400
1508 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1510 of.lStructSize = sizeof(of);
1512 of.hwndOwner = hwnd;
1513 of.lpstrFilter = "All Files\0*\0\0\0";
1514 of.lpstrCustomFilter = NULL;
1515 of.nFilterIndex = 1;
1516 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1517 of.nMaxFile = sizeof(filename);
1518 of.lpstrFileTitle = NULL;
1519 of.lpstrInitialDir = NULL;
1520 of.lpstrTitle = "Select Public Key File";
1522 if (GetOpenFileName(&of)) {
1523 strcpy(cfg.keyfile, filename);
1524 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1529 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1535 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1540 for (i=0; i<256; i++)
1541 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1544 cfg.wordness[i] = n;
1545 SendDlgItemMessage (hwnd, IDC_CCLIST,
1546 LB_DELETESTRING, i, 0);
1547 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1548 (i>=0x21 && i != 0x7F) ? i : ' ',
1550 SendDlgItemMessage (hwnd, IDC_CCLIST,
1557 case IDC_BOLDCOLOUR:
1558 if (HIWORD(wParam) == BN_CLICKED ||
1559 HIWORD(wParam) == BN_DOUBLECLICKED) {
1561 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1562 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1563 if (cfg.bold_colour && n!=22) {
1564 for (i=0; i<22; i++)
1566 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1568 (LPARAM) colours[i]);
1569 } else if (!cfg.bold_colour && n!=12) {
1572 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1573 LB_DELETESTRING, i, 0);
1578 if (HIWORD(wParam) == BN_CLICKED ||
1579 HIWORD(wParam) == BN_DOUBLECLICKED)
1580 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1582 case IDC_COLOURLIST:
1583 if (HIWORD(wParam) == LBN_DBLCLK ||
1584 HIWORD(wParam) == LBN_SELCHANGE) {
1585 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1587 if (!cfg.bold_colour)
1588 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1590 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1591 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1592 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1596 if (HIWORD(wParam) == BN_CLICKED ||
1597 HIWORD(wParam) == BN_DOUBLECLICKED) {
1598 static CHOOSECOLOR cc;
1599 static DWORD custom[16] = {0}; /* zero initialisers */
1600 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1602 if (!cfg.bold_colour)
1603 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1604 cc.lStructSize = sizeof(cc);
1605 cc.hwndOwner = hwnd;
1606 cc.hInstance = (HWND)hinst;
1607 cc.lpCustColors = custom;
1608 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1610 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1611 if (ChooseColor(&cc)) {
1613 (unsigned char) (cc.rgbResult & 0xFF);
1615 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1617 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1618 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1620 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1622 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1628 case IDC_KOI8WIN1251:
1629 case IDC_88592WIN1250:
1630 case IDC_88592CP852:
1631 cfg.xlat_enablekoiwin =
1632 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1633 cfg.xlat_88592w1250 =
1634 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1635 cfg.xlat_88592cp852 =
1636 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1638 case IDC_CAPSLOCKCYR:
1639 if (HIWORD(wParam) == BN_CLICKED ||
1640 HIWORD(wParam) == BN_DOUBLECLICKED) {
1641 cfg.xlat_capslockcyr =
1642 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1645 case IDC_VTXWINDOWS:
1650 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1651 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1652 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1658 EndDialog (hwnd, 0);
1661 /* Grrr Explorer will maximize Dialogs! */
1663 if (wParam == SIZE_MAXIMIZED)
1670 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1671 WPARAM wParam, LPARAM lParam) {
1672 static HWND page = NULL;
1674 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1676 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1677 EnableWindow(hwnd, 0);
1678 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1679 GetParent(hwnd), AboutProc);
1680 EnableWindow(hwnd, 1);
1681 SetActiveWindow(hwnd);
1683 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1686 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1687 WPARAM wParam, LPARAM lParam) {
1689 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1692 void defuse_showwindow(void) {
1694 * Work around the fact that the app's first call to ShowWindow
1695 * will ignore the default in favour of the shell-provided
1700 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1702 ShowWindow(hwnd, SW_HIDE);
1703 DestroyWindow(hwnd);
1707 int do_config (void) {
1711 savedsession[0] = '\0';
1712 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1713 get_sesslist(FALSE);
1718 int do_reconfig (HWND hwnd) {
1722 backup_cfg = cfg; /* structure copy */
1723 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1725 cfg = backup_cfg; /* structure copy */
1732 void logevent (char *string) {
1733 if (nevents >= negsize) {
1735 events = srealloc (events, negsize * sizeof(*events));
1737 events[nevents] = smalloc(1+strlen(string));
1738 strcpy (events[nevents], string);
1742 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1744 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1745 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1749 void showeventlog (HWND hwnd) {
1751 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1753 ShowWindow (logbox, SW_SHOWNORMAL);
1757 void showabout (HWND hwnd) {
1759 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1761 ShowWindow (abtbox, SW_SHOWNORMAL);
1765 void verify_ssh_host_key(char *host, int port, char *keytype,
1766 char *keystr, char *fingerprint) {
1769 static const char absentmsg[] =
1770 "The server's host key is not cached in the registry. You\n"
1771 "have no guarantee that the server is the computer you\n"
1773 "The server's key fingerprint is:\n"
1775 "If you trust this host, hit Yes to add the key to\n"
1776 "PuTTY's cache and carry on connecting.\n"
1777 "If you do not trust this host, hit No to abandon the\n"
1780 static const char wrongmsg[] =
1781 "WARNING - POTENTIAL SECURITY BREACH!\n"
1783 "The server's host key does not match the one PuTTY has\n"
1784 "cached in the registry. This means that either the\n"
1785 "server administrator has changed the host key, or you\n"
1786 "have actually connected to another computer pretending\n"
1787 "to be the server.\n"
1788 "The new key fingerprint is:\n"
1790 "If you were expecting this change and trust the new key,\n"
1791 "hit Yes to update PuTTY's cache and continue connecting.\n"
1792 "If you want to carry on connecting but without updating\n"
1793 "the cache, hit No.\n"
1794 "If you want to abandon the connection completely, hit\n"
1795 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1798 static const char mbtitle[] = "PuTTY Security Alert";
1801 char message[160+ /* sensible fingerprint max size */
1802 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1803 sizeof(absentmsg) : sizeof(wrongmsg))];
1806 * Verify the key against the registry.
1808 ret = verify_host_key(host, port, keytype, keystr);
1810 if (ret == 0) /* success - key matched OK */
1812 if (ret == 2) { /* key was different */
1814 sprintf(message, wrongmsg, fingerprint);
1815 mbret = MessageBox(NULL, message, mbtitle,
1816 MB_ICONWARNING | MB_YESNOCANCEL);
1818 store_host_key(host, port, keytype, keystr);
1819 if (mbret == IDCANCEL)
1822 if (ret == 1) { /* key was absent */
1824 sprintf(message, absentmsg, fingerprint);
1825 mbret = MessageBox(NULL, message, mbtitle,
1826 MB_ICONWARNING | MB_YESNO);
1829 store_host_key(host, port, keytype, keystr);