20 static char **events
= NULL
;
21 static int nevents
= 0, negsize
= 0;
23 static HWND logbox
= NULL
, abtbox
= NULL
;
27 static void force_normal(HWND hwnd
)
29 static int recurse
= 0;
36 wp
.length
= sizeof(wp
);
37 if (GetWindowPlacement(hwnd
, &wp
))
39 wp
.showCmd
= SW_SHOWNORMAL
;
40 SetWindowPlacement(hwnd
, &wp
);
45 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
48 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
53 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
54 WPARAM wParam
, LPARAM lParam
) {
59 for (i
=0; i
<nevents
; i
++)
60 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
61 0, (LPARAM
)events
[i
]);
64 switch (LOWORD(wParam
)) {
70 if (HIWORD(wParam
) == BN_CLICKED
||
71 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
74 selcount
= SendDlgItemMessage(hwnd
, IDN_LIST
,
75 LB_GETSELCOUNT
, 0, 0);
76 selitems
= malloc(selcount
* sizeof(int));
78 int count
= SendDlgItemMessage(hwnd
, IDN_LIST
,
80 selcount
, (LPARAM
)selitems
);
84 static unsigned char sel_nl
[] = SEL_NL
;
86 if (count
== 0) { /* can't copy zero stuff */
92 for (i
= 0; i
< count
; i
++)
93 size
+= strlen(events
[selitems
[i
]]) + sizeof(sel_nl
);
95 clipdata
= malloc(size
);
98 for (i
= 0; i
< count
; i
++) {
99 char *q
= events
[selitems
[i
]];
100 int qlen
= strlen(q
);
103 memcpy(p
, sel_nl
, sizeof(sel_nl
));
106 write_clip(clipdata
, size
, TRUE
);
111 for (i
= 0; i
< nevents
; i
++)
112 SendDlgItemMessage(hwnd
, IDN_LIST
, LB_SETSEL
,
121 DestroyWindow (hwnd
);
127 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
128 WPARAM wParam
, LPARAM lParam
) {
133 switch (LOWORD(wParam
)) {
146 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
147 WPARAM wParam
, LPARAM lParam
) {
150 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
153 switch (LOWORD(wParam
)) {
156 DestroyWindow (hwnd
);
159 EnableWindow(hwnd
, 0);
160 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
162 EnableWindow(hwnd
, 1);
163 SetActiveWindow(hwnd
);
169 DestroyWindow (hwnd
);
176 * Null dialog procedure.
178 static int CALLBACK
NullDlgProc (HWND hwnd
, UINT msg
,
179 WPARAM wParam
, LPARAM lParam
) {
183 static char savedsession
[2048];
185 enum { IDCX_ABOUT
= IDC_ABOUT
, IDCX_TVSTATIC
, IDCX_TREEVIEW
, controlstartvalue
,
189 IDC_BOX_SESSION1
, IDC_BOXT_SESSION1
,
190 IDC_BOX_SESSION2
, IDC_BOXT_SESSION2
,
211 IDC_BOX_KEYBOARD1
, IDC_BOXT_KEYBOARD1
,
212 IDC_BOX_KEYBOARD2
, IDC_BOXT_KEYBOARD2
,
213 IDC_BOX_KEYBOARD3
, IDC_BOXT_KEYBOARD3
,
237 IDC_BOX_TERMINAL1
, IDC_BOXT_TERMINAL1
,
238 IDC_BOX_TERMINAL2
, IDC_BOXT_TERMINAL2
,
239 IDC_BOX_TERMINAL3
, IDC_BOXT_TERMINAL3
,
259 IDC_BOX_WINDOW1
, IDC_BOXT_WINDOW1
,
260 IDC_BOX_WINDOW2
, IDC_BOXT_WINDOW2
,
261 IDC_BOX_WINDOW3
, IDC_BOXT_WINDOW3
,
278 connectionpanelstart
,
279 IDC_TITLE_CONNECTION
,
280 IDC_BOX_CONNECTION1
, IDC_BOXT_CONNECTION1
,
281 IDC_BOX_CONNECTION2
, IDC_BOXT_CONNECTION2
,
292 IDC_BOX_TELNET1
, IDC_BOXT_TELNET1
,
293 IDC_BOX_TELNET2
, IDC_BOXT_TELNET2
,
311 IDC_BOX_SSH1
, IDC_BOXT_SSH1
,
312 IDC_BOX_SSH2
, IDC_BOXT_SSH2
,
313 IDC_BOX_SSH3
, IDC_BOXT_SSH3
,
334 IDC_BOX_SELECTION1
, IDC_BOXT_SELECTION1
,
335 IDC_BOX_SELECTION2
, IDC_BOXT_SELECTION2
,
348 IDC_BOX_COLOURS1
, IDC_BOXT_COLOURS1
,
349 IDC_BOX_COLOURS2
, IDC_BOXT_COLOURS2
,
363 translationpanelstart
,
364 IDC_TITLE_TRANSLATION
,
365 IDC_BOX_TRANSLATION1
, IDC_BOXT_TRANSLATION1
,
366 IDC_BOX_TRANSLATION2
, IDC_BOXT_TRANSLATION2
,
367 IDC_BOX_TRANSLATION3
, IDC_BOXT_TRANSLATION3
,
384 static const char *const colours
[] = {
385 "Default Foreground", "Default Bold Foreground",
386 "Default Background", "Default Bold Background",
387 "Cursor Text", "Cursor Colour",
388 "ANSI Black", "ANSI Black Bold",
389 "ANSI Red", "ANSI Red Bold",
390 "ANSI Green", "ANSI Green Bold",
391 "ANSI Yellow", "ANSI Yellow Bold",
392 "ANSI Blue", "ANSI Blue Bold",
393 "ANSI Magenta", "ANSI Magenta Bold",
394 "ANSI Cyan", "ANSI Cyan Bold",
395 "ANSI White", "ANSI White Bold"
397 static const int permcolour
[] = {
398 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
399 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
400 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
403 static void fmtfont (char *buf
) {
404 sprintf (buf
, "Font: %s, ", cfg
.font
);
406 strcat(buf
, "bold, ");
407 if (cfg
.fontheight
== 0)
408 strcat (buf
, "default height");
410 sprintf (buf
+strlen(buf
), "%d-%s",
411 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
412 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
415 static void init_dlg_ctrls(HWND hwnd
) {
417 char fontstatic
[256];
419 SetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
);
420 SetDlgItemText (hwnd
, IDC_SESSEDIT
, savedsession
);
421 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
422 CheckRadioButton (hwnd
, IDC_PROTRAW
, IDC_PROTSSH
,
423 cfg
.protocol
==PROT_SSH ? IDC_PROTSSH
:
424 cfg
.protocol
==PROT_TELNET ? IDC_PROTTELNET
: IDC_PROTRAW
);
425 SetDlgItemInt (hwnd
, IDC_PINGEDIT
, cfg
.ping_interval
, FALSE
);
427 CheckRadioButton (hwnd
, IDC_DEL008
, IDC_DEL127
,
428 cfg
.bksp_is_delete ? IDC_DEL127
: IDC_DEL008
);
429 CheckRadioButton (hwnd
, IDC_HOMETILDE
, IDC_HOMERXVT
,
430 cfg
.rxvt_homeend ? IDC_HOMERXVT
: IDC_HOMETILDE
);
431 CheckRadioButton (hwnd
, IDC_FUNCTILDE
, IDC_FUNCVT400
,
432 cfg
.funky_type
== 0 ? IDC_FUNCTILDE
:
433 cfg
.funky_type
== 1 ? IDC_FUNCLINUX
:
434 cfg
.funky_type
== 2 ? IDC_FUNCXTERM
:
435 cfg
.funky_type
== 3 ? IDC_FUNCVT400
:
437 CheckRadioButton (hwnd
, IDC_CURNORMAL
, IDC_CURAPPLIC
,
438 cfg
.app_cursor ? IDC_CURAPPLIC
: IDC_CURNORMAL
);
439 CheckRadioButton (hwnd
, IDC_KPNORMAL
, IDC_KPNH
,
440 cfg
.nethack_keypad ? IDC_KPNH
:
441 cfg
.app_keypad ? IDC_KPAPPLIC
: IDC_KPNORMAL
);
442 CheckDlgButton (hwnd
, IDC_ALTF4
, cfg
.alt_f4
);
443 CheckDlgButton (hwnd
, IDC_ALTSPACE
, cfg
.alt_space
);
444 CheckDlgButton (hwnd
, IDC_ALTONLY
, cfg
.alt_only
);
445 CheckDlgButton (hwnd
, IDC_COMPOSEKEY
, cfg
.compose_key
);
446 CheckDlgButton (hwnd
, IDC_LDISCTERM
, cfg
.ldisc_term
);
447 CheckDlgButton (hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
448 CheckDlgButton (hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
450 CheckDlgButton (hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
451 CheckDlgButton (hwnd
, IDC_DECOM
, cfg
.dec_om
);
452 CheckDlgButton (hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
453 SetDlgItemInt (hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
454 SetDlgItemInt (hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
455 SetDlgItemInt (hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
456 fmtfont (fontstatic
);
457 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
458 CheckDlgButton (hwnd
, IDC_BEEP
, cfg
.beep
);
459 CheckDlgButton (hwnd
, IDC_BCE
, cfg
.bce
);
460 CheckDlgButton (hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
462 SetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
463 CheckDlgButton (hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
464 CheckDlgButton (hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
465 CheckDlgButton (hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
466 CheckDlgButton (hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
467 CheckDlgButton (hwnd
, IDC_CLOSEEXIT
, cfg
.close_on_exit
);
468 CheckDlgButton (hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
470 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
471 SetDlgItemText (hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
472 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
474 char *p
= cfg
.environmt
;
476 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
481 CheckRadioButton (hwnd
, IDC_EMBSD
, IDC_EMRFC
,
482 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
484 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
485 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
486 CheckDlgButton (hwnd
, IDC_NOPTY
, cfg
.nopty
);
487 CheckDlgButton (hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
488 CheckDlgButton (hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
489 CheckRadioButton (hwnd
, IDC_CIPHER3DES
, IDC_CIPHERDES
,
490 cfg
.cipher
== CIPHER_BLOWFISH ? IDC_CIPHERBLOWF
:
491 cfg
.cipher
== CIPHER_DES ? IDC_CIPHERDES
:
493 CheckRadioButton (hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
494 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
495 CheckDlgButton (hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
496 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
497 SetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
499 CheckRadioButton (hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
500 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
502 static int tabs
[4] = {25, 61, 96, 128};
503 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
506 for (i
=0; i
<256; i
++) {
508 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
509 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
511 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
515 CheckDlgButton (hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
516 CheckDlgButton (hwnd
, IDC_PALETTE
, cfg
.try_palette
);
520 if (cfg
.bold_colour
|| permcolour
[i
])
521 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
522 (LPARAM
) colours
[i
]);
524 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
525 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
526 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
527 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
529 CheckRadioButton (hwnd
, IDC_NOXLAT
, IDC_88592CP852
,
530 cfg
.xlat_88592w1250 ? IDC_88592WIN1250
:
531 cfg
.xlat_88592cp852 ? IDC_88592CP852
:
532 cfg
.xlat_enablekoiwin ? IDC_KOI8WIN1251
:
534 CheckDlgButton (hwnd
, IDC_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
535 CheckRadioButton (hwnd
, IDC_VTXWINDOWS
, IDC_VTPOORMAN
,
536 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
537 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
538 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
542 static void hide(HWND hwnd
, int hide
, int minid
, int maxid
) {
544 for (i
= minid
; i
< maxid
; i
++) {
545 HWND ctl
= GetDlgItem(hwnd
, i
);
547 ShowWindow(ctl
, hide ? SW_HIDE
: SW_SHOW
);
552 struct treeview_faff
{
557 static HTREEITEM
treeview_insert(struct treeview_faff
*faff
,
558 int level
, char *text
) {
562 ins
.hParent
= (level
> 0 ? faff
->lastat
[level
-1] : TVI_ROOT
);
563 ins
.hInsertAfter
= faff
->lastat
[level
];
564 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
565 #define INSITEM DUMMYUNIONNAME.item
569 ins
.INSITEM
.mask
= TVIF_TEXT
;
570 ins
.INSITEM
.pszText
= text
;
571 newitem
= TreeView_InsertItem(faff
->treeview
, &ins
);
573 TreeView_Expand(faff
->treeview
, faff
->lastat
[level
-1], TVE_EXPAND
);
574 faff
->lastat
[level
] = newitem
;
575 for (i
= level
+1; i
< 4; i
++) faff
->lastat
[i
] = NULL
;
580 * This _huge_ function is the configuration box.
582 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
583 WPARAM wParam
, LPARAM lParam
,
586 struct treeview_faff tvfaff
;
589 char filename
[sizeof(cfg
.keyfile
)];
592 char fontstatic
[256];
598 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
602 { /* centre the window */
605 hw
= GetDesktopWindow();
606 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
607 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
608 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
609 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
613 * Create the tree view.
620 r
.left
= 3; r
.right
= r
.left
+ 75;
621 r
.top
= 3; r
.bottom
= r
.top
+ 10;
622 MapDialogRect(hwnd
, &r
);
623 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
624 WS_CHILD
| WS_VISIBLE
,
626 r
.right
-r
.left
, r
.bottom
-r
.top
,
627 hwnd
, (HMENU
)IDCX_TVSTATIC
, hinst
, NULL
);
628 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
629 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
631 r
.left
= 3; r
.right
= r
.left
+ 75;
632 r
.top
= 13; r
.bottom
= r
.top
+ 196;
633 MapDialogRect(hwnd
, &r
);
634 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
635 WS_CHILD
| WS_VISIBLE
|
636 WS_TABSTOP
| TVS_HASLINES
|
637 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
|
638 TVS_LINESATROOT
| TVS_SHOWSELALWAYS
,
640 r
.right
-r
.left
, r
.bottom
-r
.top
,
641 hwnd
, (HMENU
)IDCX_TREEVIEW
, hinst
, NULL
);
642 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
643 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
644 tvfaff
.treeview
= treeview
;
645 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
649 * Create the various panelfuls of controls.
652 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
655 ctlposinit(&cp
, hwnd
, 80, 3, 13);
656 bartitle(&cp
, "Basic options for your PuTTY session",
659 beginbox(&cp
, "Specify your connection by host name",
660 IDC_BOX_SESSION1
, IDC_BOXT_SESSION1
);
662 "Host &Name", IDC_HOSTSTATIC
, IDC_HOST
, 75,
663 "&Port", IDC_PORTSTATIC
, IDC_PORT
, 25, NULL
);
664 if (backends
[2].backend
== NULL
) {
665 /* this is PuTTYtel, so only two protocols available */
666 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
668 "&Telnet", IDC_PROTTELNET
, NULL
);
670 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
672 "&Telnet", IDC_PROTTELNET
,
681 beginbox(&cp
, "Load, save or delete a stored session",
682 IDC_BOX_SESSION2
, IDC_BOXT_SESSION2
);
683 sesssaver(&cp
, "Sav&ed Sessions",
684 IDC_SESSSTATIC
, IDC_SESSEDIT
, IDC_SESSLIST
,
685 "&Load", IDC_SESSLOAD
,
686 "&Save", IDC_SESSSAVE
,
687 "&Delete", IDC_SESSDEL
, NULL
);
690 beginbox(&cp
, NULL
, IDC_BOX_SESSION3
, 0);
691 checkbox(&cp
, "Close Window on E&xit", IDC_CLOSEEXIT
);
694 hsession
= treeview_insert(&tvfaff
, 0, "Session");
697 /* The Terminal panel. Accelerators used: [acgo] rmkh&dlbenu */
700 ctlposinit(&cp
, hwnd
, 80, 3, 13);
701 bartitle(&cp
, "Options controlling the terminal emulation",
703 beginbox(&cp
, "Set the size of the terminal window",
704 IDC_BOX_TERMINAL1
, IDC_BOXT_TERMINAL1
);
706 "&Rows", IDC_ROWSSTATIC
, IDC_ROWSEDIT
, 50,
707 "Colu&mns", IDC_COLSSTATIC
, IDC_COLSEDIT
, 50,
709 checkbox(&cp
, "Loc&k window size against resizing", IDC_LOCKSIZE
);
711 beginbox(&cp
, "Set the font used in the terminal window",
712 IDC_BOX_TERMINAL2
, IDC_BOXT_TERMINAL2
);
713 staticbtn(&cp
, "", IDC_FONTSTATIC
, "C&hange...", IDC_CHOOSEFONT
);
715 beginbox(&cp
, "Set various terminal options",
716 IDC_BOX_TERMINAL3
, IDC_BOXT_TERMINAL3
);
717 checkbox(&cp
, "Auto &wrap mode initially on", IDC_WRAPMODE
);
718 checkbox(&cp
, "&DEC Origin Mode initially on", IDC_DECOM
);
719 checkbox(&cp
, "Implicit CR in every &LF", IDC_LFHASCR
);
720 checkbox(&cp
, "&Beep enabled", IDC_BEEP
);
721 checkbox(&cp
, "Use background colour to &erase screen", IDC_BCE
);
722 checkbox(&cp
, "Enable bli&nking text", IDC_BLINKTEXT
);
723 checkbox(&cp
, "&Use local terminal line discipline", IDC_LDISCTERM
);
726 treeview_insert(&tvfaff
, 0, "Terminal");
729 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmiet */
732 ctlposinit(&cp
, hwnd
, 80, 3, 13);
733 bartitle(&cp
, "Options controlling the effects of keys",
735 beginbox(&cp
, "Change the sequences sent by:",
736 IDC_BOX_KEYBOARD1
, IDC_BOXT_KEYBOARD1
);
737 radioline(&cp
, "The Backspace key", IDC_DELSTATIC
, 2,
738 "Control-&H", IDC_DEL008
,
739 "Control-&? (127)", IDC_DEL127
, NULL
);
740 radioline(&cp
, "The Home and End keys", IDC_HOMESTATIC
, 2,
741 "&Standard", IDC_HOMETILDE
,
742 "&rxvt", IDC_HOMERXVT
, NULL
);
743 radioline(&cp
, "The Function keys and keypad", IDC_FUNCSTATIC
, 4,
744 "ESC[n&~", IDC_FUNCTILDE
,
745 "&Linux", IDC_FUNCLINUX
,
746 "&Xterm R6", IDC_FUNCXTERM
,
747 "&VT400", IDC_FUNCVT400
, NULL
);
749 beginbox(&cp
, "Change the initial state of:",
750 IDC_BOX_KEYBOARD2
, IDC_BOXT_KEYBOARD2
);
751 radioline(&cp
, "Initial state of cursor keys:", IDC_CURSTATIC
, 2,
752 "&Normal", IDC_CURNORMAL
,
753 "A&pplication", IDC_CURAPPLIC
, NULL
);
754 radioline(&cp
, "Initial state of numeric keypad:", IDC_KPSTATIC
, 3,
755 "Nor&mal", IDC_KPNORMAL
,
756 "Appl&ication", IDC_KPAPPLIC
,
757 "N&etHack", IDC_KPNH
, NULL
);
759 beginbox(&cp
, "Enable extra keyboard features:",
760 IDC_BOX_KEYBOARD3
, IDC_BOXT_KEYBOARD3
);
761 checkbox(&cp
, "Application and AltGr ac&t as Compose key",
765 treeview_insert(&tvfaff
, 1, "Keyboard");
768 /* The Window panel. Accelerators used: [acgo] tibsdkw4ylp */
771 ctlposinit(&cp
, hwnd
, 80, 3, 13);
772 bartitle(&cp
, "Options controlling PuTTY's window",
774 beginbox(&cp
, "Adjust the use of the window title",
775 IDC_BOX_WINDOW1
, IDC_BOXT_WINDOW1
);
778 "Initial window &title:", IDC_WINTITLE
,
779 IDC_WINEDIT
, 100, NULL
);
780 checkbox(&cp
, "Avoid ever using &icon title", IDC_WINNAME
);
782 beginbox(&cp
, "Adjust the use of the cursor",
783 IDC_BOX_WINDOW2
, IDC_BOXT_WINDOW2
);
784 checkbox(&cp
, "Cursor &blinks", IDC_BLINKCUR
);
786 beginbox(&cp
, "Control the scrollback in the window",
787 IDC_BOX_WINDOW3
, IDC_BOXT_WINDOW3
);
788 staticedit(&cp
, "Lines of &scrollback",
789 IDC_SAVESTATIC
, IDC_SAVEEDIT
, 50);
790 checkbox(&cp
, "&Display scrollbar", IDC_SCROLLBAR
);
791 checkbox(&cp
, "Reset scrollback on &keypress", IDC_SCROLLKEY
);
792 checkbox(&cp
, "Reset scrollback on dis&play activity",
795 beginbox(&cp
, NULL
, IDC_BOX_WINDOW4
, 0);
796 checkbox(&cp
, "&Warn before closing window", IDC_CLOSEWARN
);
797 checkbox(&cp
, "Window closes on ALT-F&4", IDC_ALTF4
);
798 checkbox(&cp
, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE
);
799 checkbox(&cp
, "System menu appears on A< alone", IDC_ALTONLY
);
802 treeview_insert(&tvfaff
, 0, "Window");
805 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
808 ctlposinit(&cp
, hwnd
, 80, 3, 13);
809 bartitle(&cp
, "Options controlling character set translation",
810 IDC_TITLE_TRANSLATION
);
811 beginbox(&cp
, "Adjust how PuTTY displays line drawing characters",
812 IDC_BOX_TRANSLATION1
, IDC_BOXT_TRANSLATION1
);
814 "Handling of line drawing characters:", IDC_VTSTATIC
,
815 "Font has &XWindows encoding", IDC_VTXWINDOWS
,
816 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI
,
817 "Use font in O&EM mode only", IDC_VTOEMONLY
,
818 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
819 IDC_VTPOORMAN
, NULL
);
821 beginbox(&cp
, "Enable character set translation on received data",
822 IDC_BOX_TRANSLATION2
, IDC_BOXT_TRANSLATION2
);
824 "Character set translation:", IDC_XLATSTATIC
,
826 "&KOI8 / Win-1251", IDC_KOI8WIN1251
,
827 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250
,
828 "&ISO-8859-2 / CP852", IDC_88592CP852
, NULL
);
830 beginbox(&cp
, "Enable character set translation on input data",
831 IDC_BOX_TRANSLATION3
, IDC_BOXT_TRANSLATION3
);
832 checkbox(&cp
, "CAP&S LOCK acts as cyrillic switch",
836 treeview_insert(&tvfaff
, 1, "Translation");
839 /* The Selection panel. Accelerators used: [acgo] wxst */
842 ctlposinit(&cp
, hwnd
, 80, 3, 13);
843 bartitle(&cp
, "Options controlling copy and paste",
844 IDC_TITLE_SELECTION
);
845 beginbox(&cp
, "Control which mouse button does which thing",
846 IDC_BOX_SELECTION1
, IDC_BOXT_SELECTION1
);
847 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
848 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
849 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
852 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
853 IDC_BOX_SELECTION2
, IDC_BOXT_SELECTION2
);
854 charclass(&cp
, "Character classes:", IDC_CCSTATIC
, IDC_CCLIST
,
855 "&Set", IDC_CCSET
, IDC_CCEDIT
,
856 "&to class", IDC_CCSTATIC2
);
859 treeview_insert(&tvfaff
, 1, "Selection");
862 /* The Colours panel. Accelerators used: [acgo] blum */
865 ctlposinit(&cp
, hwnd
, 80, 3, 13);
866 bartitle(&cp
, "Options controlling use of colours",
868 beginbox(&cp
, "General options for colour usage",
869 IDC_BOX_COLOURS1
, IDC_BOXT_COLOURS1
);
870 checkbox(&cp
, "&Bolded text is a different colour", IDC_BOLDCOLOUR
);
871 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
873 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
874 IDC_BOX_COLOURS2
, IDC_BOXT_COLOURS2
);
875 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
876 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
877 "&Modify...", IDC_CHANGE
,
878 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
879 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
880 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
883 treeview_insert(&tvfaff
, 1, "Colours");
886 /* The Connection panel. Accelerators used: [acgo] tuk */
889 ctlposinit(&cp
, hwnd
, 80, 3, 13);
890 bartitle(&cp
, "Options controlling the connection", IDC_TITLE_CONNECTION
);
892 beginbox(&cp
, "Data to send to the server",
893 IDC_BOX_CONNECTION1
, IDC_BOXT_CONNECTION1
);
894 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
, IDC_TTEDIT
, 50);
895 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
, IDC_LOGEDIT
, 50);
898 beginbox(&cp
, "Sending of null packets to keep session active",
899 IDC_BOX_CONNECTION2
, IDC_BOXT_CONNECTION2
);
900 staticedit(&cp
, "Minutes between &keepalives (0 to turn off)",
901 IDC_PINGSTATIC
, IDC_PINGEDIT
, 25);
904 treeview_insert(&tvfaff
, 0, "Connection");
907 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
910 ctlposinit(&cp
, hwnd
, 80, 3, 13);
912 bartitle(&cp
, "Options controlling Telnet connections", IDC_TITLE_TELNET
);
913 beginbox(&cp
, "Data to send to the server",
914 IDC_BOX_TELNET1
, IDC_BOXT_TELNET1
);
915 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
, IDC_TSEDIT
, 50);
916 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
917 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
,
918 "Va&lue", IDC_VALSTATIC
, IDC_VALEDIT
,
920 "A&dd", IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
922 beginbox(&cp
, "Telnet protocol adjustments",
923 IDC_BOX_TELNET2
, IDC_BOXT_TELNET2
);
924 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC
, 2,
925 "&BSD (commonplace)", IDC_EMBSD
,
926 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
929 treeview_insert(&tvfaff
, 1, "Telnet");
933 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
934 if (backends
[2].backend
!= NULL
) {
936 ctlposinit(&cp
, hwnd
, 80, 3, 13);
938 bartitle(&cp
, "Options controlling SSH connections", IDC_TITLE_SSH
);
939 beginbox(&cp
, "Data to send to the server",
940 IDC_BOX_SSH1
, IDC_BOXT_SSH1
);
942 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
945 beginbox(&cp
, "Authentication options",
946 IDC_BOX_SSH2
, IDC_BOXT_SSH2
);
947 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
949 checkbox(&cp
, "Allow &agent forwarding", IDC_AGENTFWD
);
950 editbutton(&cp
, "Private &key file for authentication:",
951 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...", IDC_PKBUTTON
);
953 beginbox(&cp
, "Protocol options",
954 IDC_BOX_SSH3
, IDC_BOXT_SSH3
);
955 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
956 radioline(&cp
, "Preferred SSH protocol version:",
957 IDC_SSHPROTSTATIC
, 2,
958 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
959 radioline(&cp
, "Preferred encryption algorithm:", IDC_CIPHERSTATIC
, 3,
960 "&3DES", IDC_CIPHER3DES
,
961 "&Blowfish", IDC_CIPHERBLOWF
,
962 "&DES", IDC_CIPHERDES
, NULL
);
963 checkbox(&cp
, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
967 treeview_insert(&tvfaff
, 1, "SSH");
971 init_dlg_ctrls(hwnd
);
972 for (i
= 0; i
< nsessions
; i
++)
973 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
974 0, (LPARAM
) (sessions
[i
]));
977 * Hide all the controls to start with.
979 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
982 * Put the treeview selection on to the Session panel. This
983 * should also cause unhiding of the relevant controls.
985 TreeView_SelectItem(treeview
, hsession
);
988 * Set focus into the first available control.
992 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
993 if (!ctl
) ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
997 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1001 * Button release should trigger WM_OK if there was a
1002 * previous double click on the session list.
1006 SendMessage (hwnd
, WM_COMMAND
, IDOK
, 0);
1009 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1010 ((LPNMHDR
)lParam
)->code
== TVN_SELCHANGED
) {
1011 HTREEITEM i
= TreeView_GetSelection(((LPNMHDR
)lParam
)->hwndFrom
);
1015 item
.pszText
= buffer
;
1016 item
.cchTextMax
= sizeof(buffer
);
1017 item
.mask
= TVIF_TEXT
;
1018 TreeView_GetItem(((LPNMHDR
)lParam
)->hwndFrom
, &item
);
1019 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
1020 if (!strcmp(buffer
, "Session"))
1021 hide(hwnd
, FALSE
, sessionpanelstart
, sessionpanelend
);
1022 if (!strcmp(buffer
, "Keyboard"))
1023 hide(hwnd
, FALSE
, keyboardpanelstart
, keyboardpanelend
);
1024 if (!strcmp(buffer
, "Terminal"))
1025 hide(hwnd
, FALSE
, terminalpanelstart
, terminalpanelend
);
1026 if (!strcmp(buffer
, "Window"))
1027 hide(hwnd
, FALSE
, windowpanelstart
, windowpanelend
);
1028 if (!strcmp(buffer
, "Connection"))
1029 hide(hwnd
, FALSE
, connectionpanelstart
, connectionpanelend
);
1030 if (!strcmp(buffer
, "Telnet"))
1031 hide(hwnd
, FALSE
, telnetpanelstart
, telnetpanelend
);
1032 if (!strcmp(buffer
, "SSH"))
1033 hide(hwnd
, FALSE
, sshpanelstart
, sshpanelend
);
1034 if (!strcmp(buffer
, "Selection"))
1035 hide(hwnd
, FALSE
, selectionpanelstart
, selectionpanelend
);
1036 if (!strcmp(buffer
, "Colours"))
1037 hide(hwnd
, FALSE
, colourspanelstart
, colourspanelend
);
1038 if (!strcmp(buffer
, "Translation"))
1039 hide(hwnd
, FALSE
, translationpanelstart
, translationpanelend
);
1041 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1047 * Only process WM_COMMAND once the dialog is fully formed.
1049 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1) switch (LOWORD(wParam
)) {
1052 EndDialog (hwnd
, 1);
1057 EndDialog (hwnd
, 0);
1059 case IDC_PROTTELNET
:
1062 if (HIWORD(wParam
) == BN_CLICKED
||
1063 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1064 int i
= IsDlgButtonChecked (hwnd
, IDC_PROTSSH
);
1065 int j
= IsDlgButtonChecked (hwnd
, IDC_PROTTELNET
);
1066 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
1067 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
1068 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
1069 cfg
.port
= i ?
22 : 23;
1070 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1075 if (HIWORD(wParam
) == EN_CHANGE
)
1076 GetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
,
1077 sizeof(cfg
.host
)-1);
1080 if (HIWORD(wParam
) == EN_CHANGE
)
1081 MyGetDlgItemInt (hwnd
, IDC_PORT
, &cfg
.port
);
1084 if (HIWORD(wParam
) == EN_CHANGE
) {
1085 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1087 GetDlgItemText (hwnd
, IDC_SESSEDIT
,
1088 savedsession
, sizeof(savedsession
)-1);
1089 savedsession
[sizeof(savedsession
)-1] = '\0';
1093 if (HIWORD(wParam
) == BN_CLICKED
||
1094 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1099 GetDlgItemText (hwnd
, IDC_SESSEDIT
, str
, sizeof(str
)-1);
1101 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1102 LB_GETCURSEL
, 0, 0);
1107 strcpy (str
, sessions
[n
]);
1109 save_settings (str
, !!strcmp(str
, "Default Settings"), &cfg
);
1110 get_sesslist (FALSE
);
1111 get_sesslist (TRUE
);
1112 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1114 for (i
= 0; i
< nsessions
; i
++)
1115 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1116 0, (LPARAM
) (sessions
[i
]));
1117 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1123 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1124 HIWORD(wParam
) != BN_CLICKED
&&
1125 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1127 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1128 HIWORD(wParam
) != LBN_DBLCLK
)
1131 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1132 LB_GETCURSEL
, 0, 0);
1138 isdef
= !strcmp(sessions
[n
], "Default Settings");
1139 load_settings (sessions
[n
], !isdef
, &cfg
);
1140 init_dlg_ctrls(hwnd
);
1142 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1144 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1146 * A double-click on a saved session should
1147 * actually start the session, not just load it.
1148 * Unless it's Default Settings or some other
1149 * host-less set of saved settings.
1158 if (HIWORD(wParam
) == BN_CLICKED
||
1159 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1160 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1161 LB_GETCURSEL
, 0, 0);
1162 if (n
== LB_ERR
|| n
== 0) {
1166 del_settings(sessions
[n
]);
1167 get_sesslist (FALSE
);
1168 get_sesslist (TRUE
);
1169 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1171 for (i
= 0; i
< nsessions
; i
++)
1172 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1173 0, (LPARAM
) (sessions
[i
]));
1174 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1178 if (HIWORD(wParam
) == EN_CHANGE
)
1179 MyGetDlgItemInt (hwnd
, IDC_PINGEDIT
, &cfg
.ping_interval
);
1183 if (HIWORD(wParam
) == BN_CLICKED
||
1184 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1185 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC_DEL127
);
1189 if (HIWORD(wParam
) == BN_CLICKED
||
1190 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1191 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC_HOMERXVT
);
1194 if (HIWORD(wParam
) == BN_CLICKED
||
1195 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1199 if (HIWORD(wParam
) == BN_CLICKED
||
1200 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1205 if (HIWORD(wParam
) == BN_CLICKED
||
1206 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1207 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC_FUNCLINUX
);
1211 if (HIWORD(wParam
) == BN_CLICKED
||
1212 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1213 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC_KPAPPLIC
);
1214 cfg
.nethack_keypad
= FALSE
;
1218 if (HIWORD(wParam
) == BN_CLICKED
||
1219 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1220 cfg
.app_keypad
= FALSE
;
1221 cfg
.nethack_keypad
= TRUE
;
1226 if (HIWORD(wParam
) == BN_CLICKED
||
1227 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1228 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC_CURAPPLIC
);
1231 if (HIWORD(wParam
) == BN_CLICKED
||
1232 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1233 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC_ALTF4
);
1236 if (HIWORD(wParam
) == BN_CLICKED
||
1237 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1238 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC_ALTSPACE
);
1241 if (HIWORD(wParam
) == BN_CLICKED
||
1242 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1243 cfg
.alt_only
= IsDlgButtonChecked (hwnd
, IDC_ALTONLY
);
1246 if (HIWORD(wParam
) == BN_CLICKED
||
1247 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1248 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC_LDISCTERM
);
1251 if (HIWORD(wParam
) == BN_CLICKED
||
1252 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1253 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC_SCROLLKEY
);
1255 case IDC_SCROLLDISP
:
1256 if (HIWORD(wParam
) == BN_CLICKED
||
1257 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1258 cfg
.scroll_on_disp
= IsDlgButtonChecked (hwnd
, IDC_SCROLLDISP
);
1260 case IDC_COMPOSEKEY
:
1261 if (HIWORD(wParam
) == BN_CLICKED
||
1262 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1263 cfg
.compose_key
= IsDlgButtonChecked (hwnd
, IDC_COMPOSEKEY
);
1266 if (HIWORD(wParam
) == BN_CLICKED
||
1267 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1268 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC_WRAPMODE
);
1271 if (HIWORD(wParam
) == BN_CLICKED
||
1272 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1273 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC_DECOM
);
1276 if (HIWORD(wParam
) == BN_CLICKED
||
1277 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1278 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC_LFHASCR
);
1281 if (HIWORD(wParam
) == EN_CHANGE
)
1282 MyGetDlgItemInt (hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1285 if (HIWORD(wParam
) == EN_CHANGE
)
1286 MyGetDlgItemInt (hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1289 if (HIWORD(wParam
) == EN_CHANGE
)
1290 MyGetDlgItemInt (hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1292 case IDC_CHOOSEFONT
:
1293 lf
.lfHeight
= cfg
.fontheight
;
1294 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1295 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1296 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1297 lf
.lfCharSet
= cfg
.fontcharset
;
1298 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1299 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1300 lf
.lfQuality
= DEFAULT_QUALITY
;
1301 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1302 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
1303 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
1305 cf
.lStructSize
= sizeof(cf
);
1306 cf
.hwndOwner
= hwnd
;
1308 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1309 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1311 if (ChooseFont (&cf
)) {
1312 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
1313 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
1314 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1315 cfg
.fontcharset
= lf
.lfCharSet
;
1316 cfg
.fontheight
= lf
.lfHeight
;
1317 fmtfont (fontstatic
);
1318 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
1322 if (HIWORD(wParam
) == BN_CLICKED
||
1323 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1324 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC_BEEP
);
1327 if (HIWORD(wParam
) == BN_CLICKED
||
1328 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1329 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC_BLINKTEXT
);
1332 if (HIWORD(wParam
) == BN_CLICKED
||
1333 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1334 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC_BCE
);
1337 if (HIWORD(wParam
) == BN_CLICKED
||
1338 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1339 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC_WINNAME
);
1342 if (HIWORD(wParam
) == BN_CLICKED
||
1343 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1344 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC_BLINKCUR
);
1347 if (HIWORD(wParam
) == BN_CLICKED
||
1348 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1349 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC_SCROLLBAR
);
1352 if (HIWORD(wParam
) == BN_CLICKED
||
1353 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1354 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC_LOCKSIZE
);
1357 if (HIWORD(wParam
) == EN_CHANGE
)
1358 GetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
1359 sizeof(cfg
.wintitle
)-1);
1362 if (HIWORD(wParam
) == BN_CLICKED
||
1363 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1364 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC_CLOSEEXIT
);
1367 if (HIWORD(wParam
) == BN_CLICKED
||
1368 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1369 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC_CLOSEWARN
);
1372 if (HIWORD(wParam
) == EN_CHANGE
)
1373 GetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
,
1374 sizeof(cfg
.termtype
)-1);
1377 if (HIWORD(wParam
) == EN_CHANGE
)
1378 GetDlgItemText (hwnd
, IDC_TSEDIT
, cfg
.termspeed
,
1379 sizeof(cfg
.termspeed
)-1);
1382 if (HIWORD(wParam
) == EN_CHANGE
)
1383 GetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
,
1384 sizeof(cfg
.username
)-1);
1388 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC_EMRFC
);
1391 if (HIWORD(wParam
) == BN_CLICKED
||
1392 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1393 char str
[sizeof(cfg
.environmt
)];
1395 GetDlgItemText (hwnd
, IDC_VAREDIT
, str
, sizeof(str
)-1);
1400 p
= str
+ strlen(str
);
1402 GetDlgItemText (hwnd
, IDC_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
1412 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
1414 p
[strlen(str
)+1] = '\0';
1415 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
1417 SetDlgItemText (hwnd
, IDC_VAREDIT
, "");
1418 SetDlgItemText (hwnd
, IDC_VALEDIT
, "");
1420 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
1421 MB_OK
| MB_ICONERROR
);
1426 if (HIWORD(wParam
) != BN_CLICKED
&&
1427 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1429 i
= SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0, 0);
1435 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
1460 if (HIWORD(wParam
) == BN_CLICKED
||
1461 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1462 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC_NOPTY
);
1465 if (HIWORD(wParam
) == BN_CLICKED
||
1466 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1467 cfg
.buggymac
= IsDlgButtonChecked (hwnd
, IDC_BUGGYMAC
);
1470 if (HIWORD(wParam
) == BN_CLICKED
||
1471 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1472 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC_AGENTFWD
);
1474 case IDC_CIPHER3DES
:
1475 case IDC_CIPHERBLOWF
:
1477 if (HIWORD(wParam
) == BN_CLICKED
||
1478 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1479 if (IsDlgButtonChecked (hwnd
, IDC_CIPHER3DES
))
1480 cfg
.cipher
= CIPHER_3DES
;
1481 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERBLOWF
))
1482 cfg
.cipher
= CIPHER_BLOWFISH
;
1483 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERDES
))
1484 cfg
.cipher
= CIPHER_DES
;
1489 if (HIWORD(wParam
) == BN_CLICKED
||
1490 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1491 if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT1
))
1493 else if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT2
))
1498 if (HIWORD(wParam
) == BN_CLICKED
||
1499 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1500 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC_AUTHTIS
);
1503 if (HIWORD(wParam
) == EN_CHANGE
)
1504 GetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
1505 sizeof(cfg
.keyfile
)-1);
1508 if (HIWORD(wParam
) == EN_CHANGE
)
1509 GetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
1510 sizeof(cfg
.remote_cmd
)-1);
1513 memset(&of
, 0, sizeof(of
));
1514 #ifdef OPENFILENAME_SIZE_VERSION_400
1515 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1517 of
.lStructSize
= sizeof(of
);
1519 of
.hwndOwner
= hwnd
;
1520 of
.lpstrFilter
= "All Files\0*\0\0\0";
1521 of
.lpstrCustomFilter
= NULL
;
1522 of
.nFilterIndex
= 1;
1523 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1524 of
.nMaxFile
= sizeof(filename
);
1525 of
.lpstrFileTitle
= NULL
;
1526 of
.lpstrInitialDir
= NULL
;
1527 of
.lpstrTitle
= "Select Public Key File";
1529 if (GetOpenFileName(&of
)) {
1530 strcpy(cfg
.keyfile
, filename
);
1531 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
1536 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC_MBXTERM
);
1542 int n
= GetDlgItemInt (hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
1547 for (i
=0; i
<256; i
++)
1548 if (SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_GETSEL
,
1551 cfg
.wordness
[i
] = n
;
1552 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
1553 LB_DELETESTRING
, i
, 0);
1554 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1555 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1557 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
1564 case IDC_BOLDCOLOUR
:
1565 if (HIWORD(wParam
) == BN_CLICKED
||
1566 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1568 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC_BOLDCOLOUR
);
1569 n
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
1570 if (cfg
.bold_colour
&& n
!=22) {
1571 for (i
=0; i
<22; i
++)
1573 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
1575 (LPARAM
) colours
[i
]);
1576 } else if (!cfg
.bold_colour
&& n
!=12) {
1579 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
1580 LB_DELETESTRING
, i
, 0);
1585 if (HIWORD(wParam
) == BN_CLICKED
||
1586 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1587 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC_PALETTE
);
1589 case IDC_COLOURLIST
:
1590 if (HIWORD(wParam
) == LBN_DBLCLK
||
1591 HIWORD(wParam
) == LBN_SELCHANGE
) {
1592 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
1594 if (!cfg
.bold_colour
)
1595 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1597 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1598 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1599 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1603 if (HIWORD(wParam
) == BN_CLICKED
||
1604 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1605 static CHOOSECOLOR cc
;
1606 static DWORD custom
[16] = {0}; /* zero initialisers */
1607 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
1609 if (!cfg
.bold_colour
)
1610 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1611 cc
.lStructSize
= sizeof(cc
);
1612 cc
.hwndOwner
= hwnd
;
1613 cc
.hInstance
= (HWND
)hinst
;
1614 cc
.lpCustColors
= custom
;
1615 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1617 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1618 if (ChooseColor(&cc
)) {
1620 (unsigned char) (cc
.rgbResult
& 0xFF);
1622 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1624 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1625 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
1627 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
1629 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
1635 case IDC_KOI8WIN1251
:
1636 case IDC_88592WIN1250
:
1637 case IDC_88592CP852
:
1638 cfg
.xlat_enablekoiwin
=
1639 IsDlgButtonChecked (hwnd
, IDC_KOI8WIN1251
);
1640 cfg
.xlat_88592w1250
=
1641 IsDlgButtonChecked (hwnd
, IDC_88592WIN1250
);
1642 cfg
.xlat_88592cp852
=
1643 IsDlgButtonChecked (hwnd
, IDC_88592CP852
);
1645 case IDC_CAPSLOCKCYR
:
1646 if (HIWORD(wParam
) == BN_CLICKED
||
1647 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1648 cfg
.xlat_capslockcyr
=
1649 IsDlgButtonChecked (hwnd
, IDC_CAPSLOCKCYR
);
1652 case IDC_VTXWINDOWS
:
1657 (IsDlgButtonChecked (hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
:
1658 IsDlgButtonChecked (hwnd
, IDC_VTOEMANSI
) ? VT_OEMANSI
:
1659 IsDlgButtonChecked (hwnd
, IDC_VTOEMONLY
) ? VT_OEMONLY
:
1665 EndDialog (hwnd
, 0);
1668 /* Grrr Explorer will maximize Dialogs! */
1670 if (wParam
== SIZE_MAXIMIZED
)
1677 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1678 WPARAM wParam
, LPARAM lParam
) {
1679 static HWND page
= NULL
;
1681 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1683 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
1684 EnableWindow(hwnd
, 0);
1685 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1686 GetParent(hwnd
), AboutProc
);
1687 EnableWindow(hwnd
, 1);
1688 SetActiveWindow(hwnd
);
1690 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 0);
1693 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1694 WPARAM wParam
, LPARAM lParam
) {
1696 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 1);
1699 void defuse_showwindow(void) {
1701 * Work around the fact that the app's first call to ShowWindow
1702 * will ignore the default in favour of the shell-provided
1707 hwnd
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1709 ShowWindow(hwnd
, SW_HIDE
);
1710 DestroyWindow(hwnd
);
1714 int do_config (void) {
1718 savedsession
[0] = '\0';
1719 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1720 get_sesslist(FALSE
);
1725 int do_reconfig (HWND hwnd
) {
1729 backup_cfg
= cfg
; /* structure copy */
1730 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1732 cfg
= backup_cfg
; /* structure copy */
1739 void logevent (char *string
) {
1740 if (nevents
>= negsize
) {
1742 events
= srealloc (events
, negsize
* sizeof(*events
));
1744 events
[nevents
] = smalloc(1+strlen(string
));
1745 strcpy (events
[nevents
], string
);
1749 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1751 count
= SendDlgItemMessage (logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
1752 SendDlgItemMessage (logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
-1, 0);
1756 void showeventlog (HWND hwnd
) {
1758 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1760 ShowWindow (logbox
, SW_SHOWNORMAL
);
1764 void showabout (HWND hwnd
) {
1766 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1768 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1772 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
1773 char *keystr
, char *fingerprint
) {
1776 static const char absentmsg
[] =
1777 "The server's host key is not cached in the registry. You\n"
1778 "have no guarantee that the server is the computer you\n"
1780 "The server's key fingerprint is:\n"
1782 "If you trust this host, hit Yes to add the key to\n"
1783 "PuTTY's cache and carry on connecting.\n"
1784 "If you do not trust this host, hit No to abandon the\n"
1787 static const char wrongmsg
[] =
1788 "WARNING - POTENTIAL SECURITY BREACH!\n"
1790 "The server's host key does not match the one PuTTY has\n"
1791 "cached in the registry. This means that either the\n"
1792 "server administrator has changed the host key, or you\n"
1793 "have actually connected to another computer pretending\n"
1794 "to be the server.\n"
1795 "The new key fingerprint is:\n"
1797 "If you were expecting this change and trust the new key,\n"
1798 "hit Yes to update PuTTY's cache and continue connecting.\n"
1799 "If you want to carry on connecting but without updating\n"
1800 "the cache, hit No.\n"
1801 "If you want to abandon the connection completely, hit\n"
1802 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1805 static const char mbtitle
[] = "PuTTY Security Alert";
1808 char message
[160+ /* sensible fingerprint max size */
1809 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
1810 sizeof(absentmsg
) : sizeof(wrongmsg
))];
1813 * Verify the key against the registry.
1815 ret
= verify_host_key(host
, port
, keytype
, keystr
);
1817 if (ret
== 0) /* success - key matched OK */
1819 if (ret
== 2) { /* key was different */
1821 sprintf(message
, wrongmsg
, fingerprint
);
1822 mbret
= MessageBox(NULL
, message
, mbtitle
,
1823 MB_ICONWARNING
| MB_YESNOCANCEL
);
1825 store_host_key(host
, port
, keytype
, keystr
);
1826 if (mbret
== IDCANCEL
)
1829 if (ret
== 1) { /* key was absent */
1831 sprintf(message
, absentmsg
, fingerprint
);
1832 mbret
= MessageBox(NULL
, message
, mbtitle
,
1833 MB_ICONWARNING
| MB_YESNO
);
1836 store_host_key(host
, port
, keytype
, keystr
);