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,
242 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
243 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
261 appearancepanelstart,
262 IDC_TITLE_APPEARANCE,
263 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1,
264 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2,
265 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3,
274 connectionpanelstart,
275 IDC_TITLE_CONNECTION,
276 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
277 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
288 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
289 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
307 IDC_BOX_SSH1, IDC_BOXT_SSH1,
308 IDC_BOX_SSH2, IDC_BOXT_SSH2,
309 IDC_BOX_SSH3, IDC_BOXT_SSH3,
330 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
331 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
344 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
345 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
359 translationpanelstart,
360 IDC_TITLE_TRANSLATION,
361 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
362 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
363 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
380 static const char *const colours[] = {
381 "Default Foreground", "Default Bold Foreground",
382 "Default Background", "Default Bold Background",
383 "Cursor Text", "Cursor Colour",
384 "ANSI Black", "ANSI Black Bold",
385 "ANSI Red", "ANSI Red Bold",
386 "ANSI Green", "ANSI Green Bold",
387 "ANSI Yellow", "ANSI Yellow Bold",
388 "ANSI Blue", "ANSI Blue Bold",
389 "ANSI Magenta", "ANSI Magenta Bold",
390 "ANSI Cyan", "ANSI Cyan Bold",
391 "ANSI White", "ANSI White Bold"
393 static const int permcolour[] = {
394 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
395 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
396 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
399 static void fmtfont (char *buf) {
400 sprintf (buf, "Font: %s, ", cfg.font);
402 strcat(buf, "bold, ");
403 if (cfg.fontheight == 0)
404 strcat (buf, "default height");
406 sprintf (buf+strlen(buf), "%d-%s",
407 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
408 (cfg.fontheight < 0 ? "pixel" : "point"));
411 static void init_dlg_ctrls(HWND hwnd) {
413 char fontstatic[256];
415 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
416 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
417 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
418 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
419 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
420 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET : IDC_PROTRAW );
421 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
423 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
424 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
425 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
426 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
427 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
428 cfg.funky_type == 0 ? IDC_FUNCTILDE :
429 cfg.funky_type == 1 ? IDC_FUNCLINUX :
430 cfg.funky_type == 2 ? IDC_FUNCXTERM :
431 cfg.funky_type == 3 ? IDC_FUNCVT400 :
433 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
434 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
435 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
436 cfg.nethack_keypad ? IDC_KPNH :
437 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
438 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
439 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
440 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
441 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
442 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
443 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
444 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
446 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
447 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
448 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
449 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
450 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
451 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
452 fmtfont (fontstatic);
453 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
454 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
455 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
456 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
458 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
459 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
460 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
461 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
462 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
463 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
464 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
466 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
467 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
468 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
470 char *p = cfg.environmt;
472 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
477 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
478 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
480 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
481 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
482 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
483 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
484 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
485 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
486 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
487 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
489 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
490 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
491 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
492 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
493 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
495 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
496 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
498 static int tabs[4] = {25, 61, 96, 128};
499 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
502 for (i=0; i<256; i++) {
504 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
505 (i>=0x21 && i != 0x7F) ? i : ' ',
507 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
511 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
512 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
516 if (cfg.bold_colour || permcolour[i])
517 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
518 (LPARAM) colours[i]);
520 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
521 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
522 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
523 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
525 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
526 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
527 cfg.xlat_88592cp852 ? IDC_88592CP852 :
528 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
530 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
531 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
532 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
533 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
534 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
538 static void hide(HWND hwnd, int hide, int minid, int maxid) {
540 for (i = minid; i < maxid; i++) {
541 HWND ctl = GetDlgItem(hwnd, i);
543 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
548 struct treeview_faff {
553 static HTREEITEM treeview_insert(struct treeview_faff *faff,
554 int level, char *text) {
558 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
559 ins.hInsertAfter = faff->lastat[level];
560 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
561 #define INSITEM DUMMYUNIONNAME.item
565 ins.INSITEM.mask = TVIF_TEXT;
566 ins.INSITEM.pszText = text;
567 newitem = TreeView_InsertItem(faff->treeview, &ins);
569 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
570 faff->lastat[level] = newitem;
571 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
576 * This _huge_ function is the configuration box.
578 static int GenericMainDlgProc (HWND hwnd, UINT msg,
579 WPARAM wParam, LPARAM lParam,
582 struct treeview_faff tvfaff;
585 char filename[sizeof(cfg.keyfile)];
588 char fontstatic[256];
594 SetWindowLong(hwnd, GWL_USERDATA, 0);
598 { /* centre the window */
601 hw = GetDesktopWindow();
602 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
603 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
604 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
605 rd.right-rd.left, rd.bottom-rd.top, TRUE);
609 * Create the tree view.
616 r.left = 3; r.right = r.left + 75;
617 r.top = 3; r.bottom = r.top + 10;
618 MapDialogRect(hwnd, &r);
619 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
620 WS_CHILD | WS_VISIBLE,
622 r.right-r.left, r.bottom-r.top,
623 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
624 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
625 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
627 r.left = 3; r.right = r.left + 75;
628 r.top = 13; r.bottom = r.top + 196;
629 MapDialogRect(hwnd, &r);
630 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
631 WS_CHILD | WS_VISIBLE |
632 WS_TABSTOP | TVS_HASLINES |
633 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
634 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
636 r.right-r.left, r.bottom-r.top,
637 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
638 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
639 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
640 tvfaff.treeview = treeview;
641 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
645 * Create the various panelfuls of controls.
648 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
651 ctlposinit(&cp, hwnd, 80, 3, 13);
652 bartitle(&cp, "Basic options for your PuTTY session",
655 beginbox(&cp, "Specify your connection by host name",
656 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
658 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
659 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
660 if (backends[2].backend == NULL) {
661 /* this is PuTTYtel, so only two protocols available */
662 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
664 "&Telnet", IDC_PROTTELNET, NULL);
666 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 3,
668 "&Telnet", IDC_PROTTELNET,
677 beginbox(&cp, "Load, save or delete a stored session",
678 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
679 sesssaver(&cp, "Sav&ed Sessions",
680 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
681 "&Load", IDC_SESSLOAD,
682 "&Save", IDC_SESSSAVE,
683 "&Delete", IDC_SESSDEL, NULL);
686 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
687 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
690 hsession = treeview_insert(&tvfaff, 0, "Session");
693 /* The Terminal panel. Accelerators used: [acgo] &dlbenu */
696 ctlposinit(&cp, hwnd, 80, 3, 13);
697 bartitle(&cp, "Options controlling the terminal emulation",
699 beginbox(&cp, "Set various terminal options",
700 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
701 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
702 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
703 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
704 checkbox(&cp, "&Beep enabled", IDC_BEEP);
705 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
706 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
707 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
710 treeview_insert(&tvfaff, 0, "Terminal");
713 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmiet */
716 ctlposinit(&cp, hwnd, 80, 3, 13);
717 bartitle(&cp, "Options controlling the effects of keys",
719 beginbox(&cp, "Change the sequences sent by:",
720 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
721 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
722 "Control-&H", IDC_DEL008,
723 "Control-&? (127)", IDC_DEL127, NULL);
724 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
725 "&Standard", IDC_HOMETILDE,
726 "&rxvt", IDC_HOMERXVT, NULL);
727 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
728 "ESC[n&~", IDC_FUNCTILDE,
729 "&Linux", IDC_FUNCLINUX,
730 "&Xterm R6", IDC_FUNCXTERM,
731 "&VT400", IDC_FUNCVT400, NULL);
733 beginbox(&cp, "Change the initial state of:",
734 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
735 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
736 "&Normal", IDC_CURNORMAL,
737 "A&pplication", IDC_CURAPPLIC, NULL);
738 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
739 "Nor&mal", IDC_KPNORMAL,
740 "Appl&ication", IDC_KPAPPLIC,
741 "N&etHack", IDC_KPNH, NULL);
743 beginbox(&cp, "Enable extra keyboard features:",
744 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
745 checkbox(&cp, "Application and AltGr ac&t as Compose key",
749 treeview_insert(&tvfaff, 1, "Keyboard");
752 /* The Window panel. Accelerators used: [acgo] bsdkw4ylp */
755 ctlposinit(&cp, hwnd, 80, 3, 13);
756 bartitle(&cp, "Options controlling PuTTY's window",
758 beginbox(&cp, "Set the size of the window",
759 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
761 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
762 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
764 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
766 beginbox(&cp, "Control the scrollback in the window",
767 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
768 staticedit(&cp, "Lines of &scrollback",
769 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
770 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
771 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
772 checkbox(&cp, "Reset scrollback on dis&play activity",
775 beginbox(&cp, NULL, IDC_BOX_WINDOW3, 0);
776 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
777 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
778 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
779 checkbox(&cp, "System menu appears on A< alone", IDC_ALTONLY);
782 treeview_insert(&tvfaff, 0, "Window");
785 /* The Appearance panel. Accelerators used: [acgo] rmkhti */
788 ctlposinit(&cp, hwnd, 80, 3, 13);
789 bartitle(&cp, "Options controlling PuTTY's appearance",
791 beginbox(&cp, "Adjust the use of the cursor",
792 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1);
793 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
795 beginbox(&cp, "Set the font used in the terminal window",
796 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2);
797 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
799 beginbox(&cp, "Adjust the use of the window title",
800 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3);
803 "Initial window &title:", IDC_WINTITLE,
804 IDC_WINEDIT, 100, NULL);
805 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
808 treeview_insert(&tvfaff, 1, "Appearance");
811 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
814 ctlposinit(&cp, hwnd, 80, 3, 13);
815 bartitle(&cp, "Options controlling character set translation",
816 IDC_TITLE_TRANSLATION);
817 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
818 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
820 "Handling of line drawing characters:", IDC_VTSTATIC,
821 "Font has &XWindows encoding", IDC_VTXWINDOWS,
822 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
823 "Use font in O&EM mode only", IDC_VTOEMONLY,
824 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
825 IDC_VTPOORMAN, NULL);
827 beginbox(&cp, "Enable character set translation on received data",
828 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
830 "Character set translation:", IDC_XLATSTATIC,
832 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
833 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
834 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
836 beginbox(&cp, "Enable character set translation on input data",
837 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
838 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
842 treeview_insert(&tvfaff, 1, "Translation");
845 /* The Selection panel. Accelerators used: [acgo] wxst */
848 ctlposinit(&cp, hwnd, 80, 3, 13);
849 bartitle(&cp, "Options controlling copy and paste",
850 IDC_TITLE_SELECTION);
851 beginbox(&cp, "Control which mouse button does which thing",
852 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
853 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
854 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
855 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
858 beginbox(&cp, "Control the select-one-word-at-a-time mode",
859 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
860 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
861 "&Set", IDC_CCSET, IDC_CCEDIT,
862 "&to class", IDC_CCSTATIC2);
865 treeview_insert(&tvfaff, 1, "Selection");
868 /* The Colours panel. Accelerators used: [acgo] blum */
871 ctlposinit(&cp, hwnd, 80, 3, 13);
872 bartitle(&cp, "Options controlling use of colours",
874 beginbox(&cp, "General options for colour usage",
875 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
876 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
877 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
879 beginbox(&cp, "Adjust the precise colours PuTTY displays",
880 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
881 colouredit(&cp, "Select a colo&ur and then click to modify it:",
882 IDC_COLOURSTATIC, IDC_COLOURLIST,
883 "&Modify...", IDC_CHANGE,
884 "Red:", IDC_RSTATIC, IDC_RVALUE,
885 "Green:", IDC_GSTATIC, IDC_GVALUE,
886 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
889 treeview_insert(&tvfaff, 1, "Colours");
892 /* The Connection panel. Accelerators used: [acgo] tuk */
895 ctlposinit(&cp, hwnd, 80, 3, 13);
896 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
898 beginbox(&cp, "Data to send to the server",
899 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
900 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
901 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
904 beginbox(&cp, "Sending of null packets to keep session active",
905 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
906 staticedit(&cp, "Minutes between &keepalives (0 to turn off)",
907 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
910 treeview_insert(&tvfaff, 0, "Connection");
913 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
916 ctlposinit(&cp, hwnd, 80, 3, 13);
918 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
919 beginbox(&cp, "Data to send to the server",
920 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
921 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
922 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
923 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
924 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
926 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
928 beginbox(&cp, "Telnet protocol adjustments",
929 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
930 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
931 "&BSD (commonplace)", IDC_EMBSD,
932 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
935 treeview_insert(&tvfaff, 1, "Telnet");
939 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
940 if (backends[2].backend != NULL) {
942 ctlposinit(&cp, hwnd, 80, 3, 13);
944 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
945 beginbox(&cp, "Data to send to the server",
946 IDC_BOX_SSH1, IDC_BOXT_SSH1);
948 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
951 beginbox(&cp, "Authentication options",
952 IDC_BOX_SSH2, IDC_BOXT_SSH2);
953 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
955 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
956 editbutton(&cp, "Private &key file for authentication:",
957 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
959 beginbox(&cp, "Protocol options",
960 IDC_BOX_SSH3, IDC_BOXT_SSH3);
961 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
962 radioline(&cp, "Preferred SSH protocol version:",
963 IDC_SSHPROTSTATIC, 2,
964 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
965 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
966 "&3DES", IDC_CIPHER3DES,
967 "&Blowfish", IDC_CIPHERBLOWF,
968 "&DES", IDC_CIPHERDES, NULL);
969 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
973 treeview_insert(&tvfaff, 1, "SSH");
977 init_dlg_ctrls(hwnd);
978 for (i = 0; i < nsessions; i++)
979 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
980 0, (LPARAM) (sessions[i]));
983 * Hide all the controls to start with.
985 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
988 * Put the treeview selection on to the Session panel. This
989 * should also cause unhiding of the relevant controls.
991 TreeView_SelectItem(treeview, hsession);
994 * Set focus into the first available control.
998 ctl = GetDlgItem(hwnd, IDC_HOST);
999 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1003 SetWindowLong(hwnd, GWL_USERDATA, 1);
1007 * Button release should trigger WM_OK if there was a
1008 * previous double click on the session list.
1012 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1015 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1016 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1017 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1021 item.pszText = buffer;
1022 item.cchTextMax = sizeof(buffer);
1023 item.mask = TVIF_TEXT;
1024 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1025 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1026 if (!strcmp(buffer, "Session"))
1027 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1028 if (!strcmp(buffer, "Keyboard"))
1029 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1030 if (!strcmp(buffer, "Terminal"))
1031 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1032 if (!strcmp(buffer, "Window"))
1033 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1034 if (!strcmp(buffer, "Appearance"))
1035 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
1036 if (!strcmp(buffer, "Connection"))
1037 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1038 if (!strcmp(buffer, "Telnet"))
1039 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1040 if (!strcmp(buffer, "SSH"))
1041 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1042 if (!strcmp(buffer, "Selection"))
1043 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1044 if (!strcmp(buffer, "Colours"))
1045 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1046 if (!strcmp(buffer, "Translation"))
1047 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1049 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1055 * Only process WM_COMMAND once the dialog is fully formed.
1057 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1060 EndDialog (hwnd, 1);
1065 EndDialog (hwnd, 0);
1067 case IDC_PROTTELNET:
1070 if (HIWORD(wParam) == BN_CLICKED ||
1071 HIWORD(wParam) == BN_DOUBLECLICKED) {
1072 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1073 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1074 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1075 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1076 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1077 cfg.port = i ? 22 : 23;
1078 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1083 if (HIWORD(wParam) == EN_CHANGE)
1084 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1085 sizeof(cfg.host)-1);
1088 if (HIWORD(wParam) == EN_CHANGE)
1089 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1092 if (HIWORD(wParam) == EN_CHANGE) {
1093 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1095 GetDlgItemText (hwnd, IDC_SESSEDIT,
1096 savedsession, sizeof(savedsession)-1);
1097 savedsession[sizeof(savedsession)-1] = '\0';
1101 if (HIWORD(wParam) == BN_CLICKED ||
1102 HIWORD(wParam) == BN_DOUBLECLICKED) {
1107 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1109 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1110 LB_GETCURSEL, 0, 0);
1115 strcpy (str, sessions[n]);
1117 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1118 get_sesslist (FALSE);
1119 get_sesslist (TRUE);
1120 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1122 for (i = 0; i < nsessions; i++)
1123 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1124 0, (LPARAM) (sessions[i]));
1125 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1131 if (LOWORD(wParam) == IDC_SESSLOAD &&
1132 HIWORD(wParam) != BN_CLICKED &&
1133 HIWORD(wParam) != BN_DOUBLECLICKED)
1135 if (LOWORD(wParam) == IDC_SESSLIST &&
1136 HIWORD(wParam) != LBN_DBLCLK)
1139 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1140 LB_GETCURSEL, 0, 0);
1146 isdef = !strcmp(sessions[n], "Default Settings");
1147 load_settings (sessions[n], !isdef, &cfg);
1148 init_dlg_ctrls(hwnd);
1150 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1152 if (LOWORD(wParam) == IDC_SESSLIST) {
1154 * A double-click on a saved session should
1155 * actually start the session, not just load it.
1156 * Unless it's Default Settings or some other
1157 * host-less set of saved settings.
1166 if (HIWORD(wParam) == BN_CLICKED ||
1167 HIWORD(wParam) == BN_DOUBLECLICKED) {
1168 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1169 LB_GETCURSEL, 0, 0);
1170 if (n == LB_ERR || n == 0) {
1174 del_settings(sessions[n]);
1175 get_sesslist (FALSE);
1176 get_sesslist (TRUE);
1177 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1179 for (i = 0; i < nsessions; i++)
1180 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1181 0, (LPARAM) (sessions[i]));
1182 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1186 if (HIWORD(wParam) == EN_CHANGE)
1187 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1191 if (HIWORD(wParam) == BN_CLICKED ||
1192 HIWORD(wParam) == BN_DOUBLECLICKED)
1193 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1197 if (HIWORD(wParam) == BN_CLICKED ||
1198 HIWORD(wParam) == BN_DOUBLECLICKED)
1199 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1202 if (HIWORD(wParam) == BN_CLICKED ||
1203 HIWORD(wParam) == BN_DOUBLECLICKED)
1207 if (HIWORD(wParam) == BN_CLICKED ||
1208 HIWORD(wParam) == BN_DOUBLECLICKED)
1213 if (HIWORD(wParam) == BN_CLICKED ||
1214 HIWORD(wParam) == BN_DOUBLECLICKED)
1215 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1219 if (HIWORD(wParam) == BN_CLICKED ||
1220 HIWORD(wParam) == BN_DOUBLECLICKED) {
1221 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1222 cfg.nethack_keypad = FALSE;
1226 if (HIWORD(wParam) == BN_CLICKED ||
1227 HIWORD(wParam) == BN_DOUBLECLICKED) {
1228 cfg.app_keypad = FALSE;
1229 cfg.nethack_keypad = TRUE;
1234 if (HIWORD(wParam) == BN_CLICKED ||
1235 HIWORD(wParam) == BN_DOUBLECLICKED)
1236 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1239 if (HIWORD(wParam) == BN_CLICKED ||
1240 HIWORD(wParam) == BN_DOUBLECLICKED)
1241 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1244 if (HIWORD(wParam) == BN_CLICKED ||
1245 HIWORD(wParam) == BN_DOUBLECLICKED)
1246 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1249 if (HIWORD(wParam) == BN_CLICKED ||
1250 HIWORD(wParam) == BN_DOUBLECLICKED)
1251 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1254 if (HIWORD(wParam) == BN_CLICKED ||
1255 HIWORD(wParam) == BN_DOUBLECLICKED)
1256 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1259 if (HIWORD(wParam) == BN_CLICKED ||
1260 HIWORD(wParam) == BN_DOUBLECLICKED)
1261 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1263 case IDC_SCROLLDISP:
1264 if (HIWORD(wParam) == BN_CLICKED ||
1265 HIWORD(wParam) == BN_DOUBLECLICKED)
1266 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1268 case IDC_COMPOSEKEY:
1269 if (HIWORD(wParam) == BN_CLICKED ||
1270 HIWORD(wParam) == BN_DOUBLECLICKED)
1271 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1274 if (HIWORD(wParam) == BN_CLICKED ||
1275 HIWORD(wParam) == BN_DOUBLECLICKED)
1276 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1279 if (HIWORD(wParam) == BN_CLICKED ||
1280 HIWORD(wParam) == BN_DOUBLECLICKED)
1281 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1284 if (HIWORD(wParam) == BN_CLICKED ||
1285 HIWORD(wParam) == BN_DOUBLECLICKED)
1286 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1289 if (HIWORD(wParam) == EN_CHANGE)
1290 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1293 if (HIWORD(wParam) == EN_CHANGE)
1294 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1297 if (HIWORD(wParam) == EN_CHANGE)
1298 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1300 case IDC_CHOOSEFONT:
1301 lf.lfHeight = cfg.fontheight;
1302 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1303 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1304 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1305 lf.lfCharSet = cfg.fontcharset;
1306 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1307 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1308 lf.lfQuality = DEFAULT_QUALITY;
1309 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1310 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1311 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1313 cf.lStructSize = sizeof(cf);
1314 cf.hwndOwner = hwnd;
1316 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1317 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1319 if (ChooseFont (&cf)) {
1320 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1321 cfg.font[sizeof(cfg.font)-1] = '\0';
1322 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1323 cfg.fontcharset = lf.lfCharSet;
1324 cfg.fontheight = lf.lfHeight;
1325 fmtfont (fontstatic);
1326 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1330 if (HIWORD(wParam) == BN_CLICKED ||
1331 HIWORD(wParam) == BN_DOUBLECLICKED)
1332 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1335 if (HIWORD(wParam) == BN_CLICKED ||
1336 HIWORD(wParam) == BN_DOUBLECLICKED)
1337 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1340 if (HIWORD(wParam) == BN_CLICKED ||
1341 HIWORD(wParam) == BN_DOUBLECLICKED)
1342 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1345 if (HIWORD(wParam) == BN_CLICKED ||
1346 HIWORD(wParam) == BN_DOUBLECLICKED)
1347 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1350 if (HIWORD(wParam) == BN_CLICKED ||
1351 HIWORD(wParam) == BN_DOUBLECLICKED)
1352 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1355 if (HIWORD(wParam) == BN_CLICKED ||
1356 HIWORD(wParam) == BN_DOUBLECLICKED)
1357 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1360 if (HIWORD(wParam) == BN_CLICKED ||
1361 HIWORD(wParam) == BN_DOUBLECLICKED)
1362 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1365 if (HIWORD(wParam) == EN_CHANGE)
1366 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1367 sizeof(cfg.wintitle)-1);
1370 if (HIWORD(wParam) == BN_CLICKED ||
1371 HIWORD(wParam) == BN_DOUBLECLICKED)
1372 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1375 if (HIWORD(wParam) == BN_CLICKED ||
1376 HIWORD(wParam) == BN_DOUBLECLICKED)
1377 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1380 if (HIWORD(wParam) == EN_CHANGE)
1381 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1382 sizeof(cfg.termtype)-1);
1385 if (HIWORD(wParam) == EN_CHANGE)
1386 GetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed,
1387 sizeof(cfg.termspeed)-1);
1390 if (HIWORD(wParam) == EN_CHANGE)
1391 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1392 sizeof(cfg.username)-1);
1396 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1399 if (HIWORD(wParam) == BN_CLICKED ||
1400 HIWORD(wParam) == BN_DOUBLECLICKED) {
1401 char str[sizeof(cfg.environmt)];
1403 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1408 p = str + strlen(str);
1410 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1420 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1422 p[strlen(str)+1] = '\0';
1423 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1425 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1426 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1428 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1429 MB_OK | MB_ICONERROR);
1434 if (HIWORD(wParam) != BN_CLICKED &&
1435 HIWORD(wParam) != BN_DOUBLECLICKED)
1437 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1443 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1468 if (HIWORD(wParam) == BN_CLICKED ||
1469 HIWORD(wParam) == BN_DOUBLECLICKED)
1470 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1473 if (HIWORD(wParam) == BN_CLICKED ||
1474 HIWORD(wParam) == BN_DOUBLECLICKED)
1475 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1478 if (HIWORD(wParam) == BN_CLICKED ||
1479 HIWORD(wParam) == BN_DOUBLECLICKED)
1480 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1482 case IDC_CIPHER3DES:
1483 case IDC_CIPHERBLOWF:
1485 if (HIWORD(wParam) == BN_CLICKED ||
1486 HIWORD(wParam) == BN_DOUBLECLICKED) {
1487 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1488 cfg.cipher = CIPHER_3DES;
1489 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1490 cfg.cipher = CIPHER_BLOWFISH;
1491 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1492 cfg.cipher = CIPHER_DES;
1497 if (HIWORD(wParam) == BN_CLICKED ||
1498 HIWORD(wParam) == BN_DOUBLECLICKED) {
1499 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1501 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1506 if (HIWORD(wParam) == BN_CLICKED ||
1507 HIWORD(wParam) == BN_DOUBLECLICKED)
1508 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1511 if (HIWORD(wParam) == EN_CHANGE)
1512 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1513 sizeof(cfg.keyfile)-1);
1516 if (HIWORD(wParam) == EN_CHANGE)
1517 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1518 sizeof(cfg.remote_cmd)-1);
1521 memset(&of, 0, sizeof(of));
1522 #ifdef OPENFILENAME_SIZE_VERSION_400
1523 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1525 of.lStructSize = sizeof(of);
1527 of.hwndOwner = hwnd;
1528 of.lpstrFilter = "All Files\0*\0\0\0";
1529 of.lpstrCustomFilter = NULL;
1530 of.nFilterIndex = 1;
1531 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1532 of.nMaxFile = sizeof(filename);
1533 of.lpstrFileTitle = NULL;
1534 of.lpstrInitialDir = NULL;
1535 of.lpstrTitle = "Select Public Key File";
1537 if (GetOpenFileName(&of)) {
1538 strcpy(cfg.keyfile, filename);
1539 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1544 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1550 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1555 for (i=0; i<256; i++)
1556 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1559 cfg.wordness[i] = n;
1560 SendDlgItemMessage (hwnd, IDC_CCLIST,
1561 LB_DELETESTRING, i, 0);
1562 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1563 (i>=0x21 && i != 0x7F) ? i : ' ',
1565 SendDlgItemMessage (hwnd, IDC_CCLIST,
1572 case IDC_BOLDCOLOUR:
1573 if (HIWORD(wParam) == BN_CLICKED ||
1574 HIWORD(wParam) == BN_DOUBLECLICKED) {
1576 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1577 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1578 if (cfg.bold_colour && n!=22) {
1579 for (i=0; i<22; i++)
1581 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1583 (LPARAM) colours[i]);
1584 } else if (!cfg.bold_colour && n!=12) {
1587 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1588 LB_DELETESTRING, i, 0);
1593 if (HIWORD(wParam) == BN_CLICKED ||
1594 HIWORD(wParam) == BN_DOUBLECLICKED)
1595 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1597 case IDC_COLOURLIST:
1598 if (HIWORD(wParam) == LBN_DBLCLK ||
1599 HIWORD(wParam) == LBN_SELCHANGE) {
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);
1605 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1606 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1607 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1611 if (HIWORD(wParam) == BN_CLICKED ||
1612 HIWORD(wParam) == BN_DOUBLECLICKED) {
1613 static CHOOSECOLOR cc;
1614 static DWORD custom[16] = {0}; /* zero initialisers */
1615 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1617 if (!cfg.bold_colour)
1618 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1619 cc.lStructSize = sizeof(cc);
1620 cc.hwndOwner = hwnd;
1621 cc.hInstance = (HWND)hinst;
1622 cc.lpCustColors = custom;
1623 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1625 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1626 if (ChooseColor(&cc)) {
1628 (unsigned char) (cc.rgbResult & 0xFF);
1630 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1632 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1633 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1635 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1637 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1643 case IDC_KOI8WIN1251:
1644 case IDC_88592WIN1250:
1645 case IDC_88592CP852:
1646 cfg.xlat_enablekoiwin =
1647 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1648 cfg.xlat_88592w1250 =
1649 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1650 cfg.xlat_88592cp852 =
1651 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1653 case IDC_CAPSLOCKCYR:
1654 if (HIWORD(wParam) == BN_CLICKED ||
1655 HIWORD(wParam) == BN_DOUBLECLICKED) {
1656 cfg.xlat_capslockcyr =
1657 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1660 case IDC_VTXWINDOWS:
1665 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1666 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1667 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1673 EndDialog (hwnd, 0);
1676 /* Grrr Explorer will maximize Dialogs! */
1678 if (wParam == SIZE_MAXIMIZED)
1685 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1686 WPARAM wParam, LPARAM lParam) {
1687 static HWND page = NULL;
1689 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1691 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1692 EnableWindow(hwnd, 0);
1693 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1694 GetParent(hwnd), AboutProc);
1695 EnableWindow(hwnd, 1);
1696 SetActiveWindow(hwnd);
1698 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1701 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1702 WPARAM wParam, LPARAM lParam) {
1704 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1707 void defuse_showwindow(void) {
1709 * Work around the fact that the app's first call to ShowWindow
1710 * will ignore the default in favour of the shell-provided
1715 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1717 ShowWindow(hwnd, SW_HIDE);
1718 DestroyWindow(hwnd);
1722 int do_config (void) {
1726 savedsession[0] = '\0';
1727 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1728 get_sesslist(FALSE);
1733 int do_reconfig (HWND hwnd) {
1737 backup_cfg = cfg; /* structure copy */
1738 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1740 cfg = backup_cfg; /* structure copy */
1747 void logevent (char *string) {
1748 if (nevents >= negsize) {
1750 events = srealloc (events, negsize * sizeof(*events));
1752 events[nevents] = smalloc(1+strlen(string));
1753 strcpy (events[nevents], string);
1757 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1759 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1760 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1764 void showeventlog (HWND hwnd) {
1766 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1768 ShowWindow (logbox, SW_SHOWNORMAL);
1772 void showabout (HWND hwnd) {
1774 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1776 ShowWindow (abtbox, SW_SHOWNORMAL);
1780 void verify_ssh_host_key(char *host, int port, char *keytype,
1781 char *keystr, char *fingerprint) {
1784 static const char absentmsg[] =
1785 "The server's host key is not cached in the registry. You\n"
1786 "have no guarantee that the server is the computer you\n"
1788 "The server's key fingerprint is:\n"
1790 "If you trust this host, hit Yes to add the key to\n"
1791 "PuTTY's cache and carry on connecting.\n"
1792 "If you do not trust this host, hit No to abandon the\n"
1795 static const char wrongmsg[] =
1796 "WARNING - POTENTIAL SECURITY BREACH!\n"
1798 "The server's host key does not match the one PuTTY has\n"
1799 "cached in the registry. This means that either the\n"
1800 "server administrator has changed the host key, or you\n"
1801 "have actually connected to another computer pretending\n"
1802 "to be the server.\n"
1803 "The new key fingerprint is:\n"
1805 "If you were expecting this change and trust the new key,\n"
1806 "hit Yes to update PuTTY's cache and continue connecting.\n"
1807 "If you want to carry on connecting but without updating\n"
1808 "the cache, hit No.\n"
1809 "If you want to abandon the connection completely, hit\n"
1810 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1813 static const char mbtitle[] = "PuTTY Security Alert";
1816 char message[160+ /* sensible fingerprint max size */
1817 (sizeof(absentmsg) > sizeof(wrongmsg) ?
1818 sizeof(absentmsg) : sizeof(wrongmsg))];
1821 * Verify the key against the registry.
1823 ret = verify_host_key(host, port, keytype, keystr);
1825 if (ret == 0) /* success - key matched OK */
1827 if (ret == 2) { /* key was different */
1829 sprintf(message, wrongmsg, fingerprint);
1830 mbret = MessageBox(NULL, message, mbtitle,
1831 MB_ICONWARNING | MB_YESNOCANCEL);
1833 store_host_key(host, port, keytype, keystr);
1834 if (mbret == IDCANCEL)
1837 if (ret == 1) { /* key was absent */
1839 sprintf(message, absentmsg, fingerprint);
1840 mbret = MessageBox(NULL, message, mbtitle,
1841 MB_ICONWARNING | MB_YESNO);
1844 store_host_key(host, port, keytype, keystr);