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
,
232 IDC_BOX_TERMINAL1
, IDC_BOXT_TERMINAL1
,
244 IDC_BOX_WINDOW1
, IDC_BOXT_WINDOW1
,
245 IDC_BOX_WINDOW2
, IDC_BOXT_WINDOW2
,
264 appearancepanelstart
,
265 IDC_TITLE_APPEARANCE
,
266 IDC_BOX_APPEARANCE1
, IDC_BOXT_APPEARANCE1
,
267 IDC_BOX_APPEARANCE2
, IDC_BOXT_APPEARANCE2
,
268 IDC_BOX_APPEARANCE3
, IDC_BOXT_APPEARANCE3
,
277 connectionpanelstart
,
278 IDC_TITLE_CONNECTION
,
279 IDC_BOX_CONNECTION1
, IDC_BOXT_CONNECTION1
,
280 IDC_BOX_CONNECTION2
, IDC_BOXT_CONNECTION2
,
291 IDC_BOX_TELNET1
, IDC_BOXT_TELNET1
,
292 IDC_BOX_TELNET2
, IDC_BOXT_TELNET2
,
310 IDC_BOX_SSH1
, IDC_BOXT_SSH1
,
311 IDC_BOX_SSH2
, IDC_BOXT_SSH2
,
312 IDC_BOX_SSH3
, IDC_BOXT_SSH3
,
333 IDC_BOX_SELECTION1
, IDC_BOXT_SELECTION1
,
334 IDC_BOX_SELECTION2
, IDC_BOXT_SELECTION2
,
347 IDC_BOX_COLOURS1
, IDC_BOXT_COLOURS1
,
348 IDC_BOX_COLOURS2
, IDC_BOXT_COLOURS2
,
362 translationpanelstart
,
363 IDC_TITLE_TRANSLATION
,
364 IDC_BOX_TRANSLATION1
, IDC_BOXT_TRANSLATION1
,
365 IDC_BOX_TRANSLATION2
, IDC_BOXT_TRANSLATION2
,
366 IDC_BOX_TRANSLATION3
, IDC_BOXT_TRANSLATION3
,
383 static const char *const colours
[] = {
384 "Default Foreground", "Default Bold Foreground",
385 "Default Background", "Default Bold Background",
386 "Cursor Text", "Cursor Colour",
387 "ANSI Black", "ANSI Black Bold",
388 "ANSI Red", "ANSI Red Bold",
389 "ANSI Green", "ANSI Green Bold",
390 "ANSI Yellow", "ANSI Yellow Bold",
391 "ANSI Blue", "ANSI Blue Bold",
392 "ANSI Magenta", "ANSI Magenta Bold",
393 "ANSI Cyan", "ANSI Cyan Bold",
394 "ANSI White", "ANSI White Bold"
396 static const int permcolour
[] = {
397 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
398 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
399 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
402 static void fmtfont (char *buf
) {
403 sprintf (buf
, "Font: %s, ", cfg
.font
);
405 strcat(buf
, "bold, ");
406 if (cfg
.fontheight
== 0)
407 strcat (buf
, "default height");
409 sprintf (buf
+strlen(buf
), "%d-%s",
410 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
411 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
414 static void init_dlg_ctrls(HWND hwnd
) {
416 char fontstatic
[256];
418 SetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
);
419 SetDlgItemText (hwnd
, IDC_SESSEDIT
, savedsession
);
420 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
421 CheckRadioButton (hwnd
, IDC_PROTRAW
, IDC_PROTSSH
,
422 cfg
.protocol
==PROT_SSH ? IDC_PROTSSH
:
423 cfg
.protocol
==PROT_TELNET ? IDC_PROTTELNET
: IDC_PROTRAW
);
424 SetDlgItemInt (hwnd
, IDC_PINGEDIT
, cfg
.ping_interval
, FALSE
);
426 CheckRadioButton (hwnd
, IDC_DEL008
, IDC_DEL127
,
427 cfg
.bksp_is_delete ? IDC_DEL127
: IDC_DEL008
);
428 CheckRadioButton (hwnd
, IDC_HOMETILDE
, IDC_HOMERXVT
,
429 cfg
.rxvt_homeend ? IDC_HOMERXVT
: IDC_HOMETILDE
);
430 CheckRadioButton (hwnd
, IDC_FUNCTILDE
, IDC_FUNCVT400
,
431 cfg
.funky_type
== 0 ? IDC_FUNCTILDE
:
432 cfg
.funky_type
== 1 ? IDC_FUNCLINUX
:
433 cfg
.funky_type
== 2 ? IDC_FUNCXTERM
:
434 cfg
.funky_type
== 3 ? IDC_FUNCVT400
:
436 CheckDlgButton (hwnd
, IDC_NOAPPLICC
, cfg
.no_applic_c
);
437 CheckDlgButton (hwnd
, IDC_NOAPPLICK
, cfg
.no_applic_k
);
438 CheckRadioButton (hwnd
, IDC_CURNORMAL
, IDC_CURAPPLIC
,
439 cfg
.app_cursor ? IDC_CURAPPLIC
: IDC_CURNORMAL
);
440 CheckRadioButton (hwnd
, IDC_KPNORMAL
, IDC_KPNH
,
441 cfg
.nethack_keypad ? IDC_KPNH
:
442 cfg
.app_keypad ? IDC_KPAPPLIC
: IDC_KPNORMAL
);
443 CheckDlgButton (hwnd
, IDC_ALTF4
, cfg
.alt_f4
);
444 CheckDlgButton (hwnd
, IDC_ALTSPACE
, cfg
.alt_space
);
445 CheckDlgButton (hwnd
, IDC_ALTONLY
, cfg
.alt_only
);
446 CheckDlgButton (hwnd
, IDC_COMPOSEKEY
, cfg
.compose_key
);
447 CheckDlgButton (hwnd
, IDC_LDISCTERM
, cfg
.ldisc_term
);
448 CheckDlgButton (hwnd
, IDC_ALWAYSONTOP
, cfg
.alwaysontop
);
449 CheckDlgButton (hwnd
, IDC_SCROLLKEY
, cfg
.scroll_on_key
);
450 CheckDlgButton (hwnd
, IDC_SCROLLDISP
, cfg
.scroll_on_disp
);
452 CheckDlgButton (hwnd
, IDC_WRAPMODE
, cfg
.wrap_mode
);
453 CheckDlgButton (hwnd
, IDC_DECOM
, cfg
.dec_om
);
454 CheckDlgButton (hwnd
, IDC_LFHASCR
, cfg
.lfhascr
);
455 SetDlgItemInt (hwnd
, IDC_ROWSEDIT
, cfg
.height
, FALSE
);
456 SetDlgItemInt (hwnd
, IDC_COLSEDIT
, cfg
.width
, FALSE
);
457 SetDlgItemInt (hwnd
, IDC_SAVEEDIT
, cfg
.savelines
, FALSE
);
458 fmtfont (fontstatic
);
459 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
460 CheckDlgButton (hwnd
, IDC_BEEP
, cfg
.beep
);
461 CheckDlgButton (hwnd
, IDC_BCE
, cfg
.bce
);
462 CheckDlgButton (hwnd
, IDC_BLINKTEXT
, cfg
.blinktext
);
464 SetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
);
465 CheckDlgButton (hwnd
, IDC_WINNAME
, cfg
.win_name_always
);
466 CheckDlgButton (hwnd
, IDC_BLINKCUR
, cfg
.blink_cur
);
467 CheckDlgButton (hwnd
, IDC_SCROLLBAR
, cfg
.scrollbar
);
468 CheckDlgButton (hwnd
, IDC_LOCKSIZE
, cfg
.locksize
);
469 CheckDlgButton (hwnd
, IDC_CLOSEEXIT
, cfg
.close_on_exit
);
470 CheckDlgButton (hwnd
, IDC_CLOSEWARN
, cfg
.warn_on_close
);
472 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
473 SetDlgItemText (hwnd
, IDC_TSEDIT
, cfg
.termspeed
);
474 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
476 char *p
= cfg
.environmt
;
478 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
, 0,
483 CheckRadioButton (hwnd
, IDC_EMBSD
, IDC_EMRFC
,
484 cfg
.rfc_environ ? IDC_EMRFC
: IDC_EMBSD
);
486 SetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
);
487 SetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
);
488 CheckDlgButton (hwnd
, IDC_NOPTY
, cfg
.nopty
);
489 CheckDlgButton (hwnd
, IDC_BUGGYMAC
, cfg
.buggymac
);
490 CheckDlgButton (hwnd
, IDC_AGENTFWD
, cfg
.agentfwd
);
491 CheckRadioButton (hwnd
, IDC_CIPHER3DES
, IDC_CIPHERDES
,
492 cfg
.cipher
== CIPHER_BLOWFISH ? IDC_CIPHERBLOWF
:
493 cfg
.cipher
== CIPHER_DES ? IDC_CIPHERDES
:
495 CheckRadioButton (hwnd
, IDC_SSHPROT1
, IDC_SSHPROT2
,
496 cfg
.sshprot
== 1 ? IDC_SSHPROT1
: IDC_SSHPROT2
);
497 CheckDlgButton (hwnd
, IDC_AUTHTIS
, cfg
.try_tis_auth
);
498 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
499 SetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
);
501 CheckRadioButton (hwnd
, IDC_MBWINDOWS
, IDC_MBXTERM
,
502 cfg
.mouse_is_xterm ? IDC_MBXTERM
: IDC_MBWINDOWS
);
504 static int tabs
[4] = {25, 61, 96, 128};
505 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_SETTABSTOPS
, 4,
508 for (i
=0; i
<256; i
++) {
510 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
511 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
513 SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_ADDSTRING
, 0,
517 CheckDlgButton (hwnd
, IDC_BOLDCOLOUR
, cfg
.bold_colour
);
518 CheckDlgButton (hwnd
, IDC_PALETTE
, cfg
.try_palette
);
522 if (cfg
.bold_colour
|| permcolour
[i
])
523 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_ADDSTRING
, 0,
524 (LPARAM
) colours
[i
]);
526 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_SETCURSEL
, 0, 0);
527 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[0][0], FALSE
);
528 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[0][1], FALSE
);
529 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[0][2], FALSE
);
531 CheckRadioButton (hwnd
, IDC_NOXLAT
, IDC_88592CP852
,
532 cfg
.xlat_88592w1250 ? IDC_88592WIN1250
:
533 cfg
.xlat_88592cp852 ? IDC_88592CP852
:
534 cfg
.xlat_enablekoiwin ? IDC_KOI8WIN1251
:
536 CheckDlgButton (hwnd
, IDC_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
537 CheckRadioButton (hwnd
, IDC_VTXWINDOWS
, IDC_VTPOORMAN
,
538 cfg
.vtmode
== VT_XWINDOWS ? IDC_VTXWINDOWS
:
539 cfg
.vtmode
== VT_OEMANSI ? IDC_VTOEMANSI
:
540 cfg
.vtmode
== VT_OEMONLY ? IDC_VTOEMONLY
:
544 static void hide(HWND hwnd
, int hide
, int minid
, int maxid
) {
546 for (i
= minid
; i
< maxid
; i
++) {
547 HWND ctl
= GetDlgItem(hwnd
, i
);
549 ShowWindow(ctl
, hide ? SW_HIDE
: SW_SHOW
);
554 struct treeview_faff
{
559 static HTREEITEM
treeview_insert(struct treeview_faff
*faff
,
560 int level
, char *text
) {
564 ins
.hParent
= (level
> 0 ? faff
->lastat
[level
-1] : TVI_ROOT
);
565 ins
.hInsertAfter
= faff
->lastat
[level
];
566 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
567 #define INSITEM DUMMYUNIONNAME.item
571 ins
.INSITEM
.mask
= TVIF_TEXT
;
572 ins
.INSITEM
.pszText
= text
;
573 newitem
= TreeView_InsertItem(faff
->treeview
, &ins
);
575 TreeView_Expand(faff
->treeview
, faff
->lastat
[level
-1], TVE_EXPAND
);
576 faff
->lastat
[level
] = newitem
;
577 for (i
= level
+1; i
< 4; i
++) faff
->lastat
[i
] = NULL
;
582 * This _huge_ function is the configuration box.
584 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
585 WPARAM wParam
, LPARAM lParam
,
588 struct treeview_faff tvfaff
;
591 char filename
[sizeof(cfg
.keyfile
)];
594 char fontstatic
[256];
600 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
604 { /* centre the window */
607 hw
= GetDesktopWindow();
608 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
609 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
610 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
611 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
615 * Create the tree view.
622 r
.left
= 3; r
.right
= r
.left
+ 75;
623 r
.top
= 3; r
.bottom
= r
.top
+ 10;
624 MapDialogRect(hwnd
, &r
);
625 tvstatic
= CreateWindowEx(0, "STATIC", "Cate&gory:",
626 WS_CHILD
| WS_VISIBLE
,
628 r
.right
-r
.left
, r
.bottom
-r
.top
,
629 hwnd
, (HMENU
)IDCX_TVSTATIC
, hinst
, NULL
);
630 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
631 SendMessage(tvstatic
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
633 r
.left
= 3; r
.right
= r
.left
+ 75;
634 r
.top
= 13; r
.bottom
= r
.top
+ 196;
635 MapDialogRect(hwnd
, &r
);
636 treeview
= CreateWindowEx(WS_EX_CLIENTEDGE
, WC_TREEVIEW
, "",
637 WS_CHILD
| WS_VISIBLE
|
638 WS_TABSTOP
| TVS_HASLINES
|
639 TVS_DISABLEDRAGDROP
| TVS_HASBUTTONS
|
640 TVS_LINESATROOT
| TVS_SHOWSELALWAYS
,
642 r
.right
-r
.left
, r
.bottom
-r
.top
,
643 hwnd
, (HMENU
)IDCX_TREEVIEW
, hinst
, NULL
);
644 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
645 SendMessage(treeview
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
646 tvfaff
.treeview
= treeview
;
647 memset(tvfaff
.lastat
, 0, sizeof(tvfaff
.lastat
));
651 * Create the various panelfuls of controls.
654 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
657 ctlposinit(&cp
, hwnd
, 80, 3, 13);
658 bartitle(&cp
, "Basic options for your PuTTY session",
661 beginbox(&cp
, "Specify your connection by host name",
662 IDC_BOX_SESSION1
, IDC_BOXT_SESSION1
);
664 "Host &Name", IDC_HOSTSTATIC
, IDC_HOST
, 75,
665 "&Port", IDC_PORTSTATIC
, IDC_PORT
, 25, NULL
);
666 if (backends
[2].backend
== NULL
) {
667 /* this is PuTTYtel, so only two protocols available */
668 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
670 "&Telnet", IDC_PROTTELNET
, NULL
);
672 radioline(&cp
, "Protocol:", IDC_PROTSTATIC
, 3,
674 "&Telnet", IDC_PROTTELNET
,
683 beginbox(&cp
, "Load, save or delete a stored session",
684 IDC_BOX_SESSION2
, IDC_BOXT_SESSION2
);
685 sesssaver(&cp
, "Sav&ed Sessions",
686 IDC_SESSSTATIC
, IDC_SESSEDIT
, IDC_SESSLIST
,
687 "&Load", IDC_SESSLOAD
,
688 "&Save", IDC_SESSSAVE
,
689 "&Delete", IDC_SESSDEL
, NULL
);
692 beginbox(&cp
, NULL
, IDC_BOX_SESSION3
, 0);
693 checkbox(&cp
, "Close Window on E&xit", IDC_CLOSEEXIT
);
696 hsession
= treeview_insert(&tvfaff
, 0, "Session");
699 /* The Terminal panel. Accelerators used: [acgo] &dlbenu */
702 ctlposinit(&cp
, hwnd
, 80, 3, 13);
703 bartitle(&cp
, "Options controlling the terminal emulation",
705 beginbox(&cp
, "Set various terminal options",
706 IDC_BOX_TERMINAL1
, IDC_BOXT_TERMINAL1
);
707 checkbox(&cp
, "Auto &wrap mode initially on", IDC_WRAPMODE
);
708 checkbox(&cp
, "&DEC Origin Mode initially on", IDC_DECOM
);
709 checkbox(&cp
, "Implicit CR in every &LF", IDC_LFHASCR
);
710 checkbox(&cp
, "&Beep enabled", IDC_BEEP
);
711 checkbox(&cp
, "Use background colour to &erase screen", IDC_BCE
);
712 checkbox(&cp
, "Enable bli&nking text", IDC_BLINKTEXT
);
713 checkbox(&cp
, "&Use local terminal line discipline", IDC_LDISCTERM
);
716 treeview_insert(&tvfaff
, 0, "Terminal");
719 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
722 ctlposinit(&cp
, hwnd
, 80, 3, 13);
723 bartitle(&cp
, "Options controlling the effects of keys",
725 beginbox(&cp
, "Change the sequences sent by:",
726 IDC_BOX_KEYBOARD1
, IDC_BOXT_KEYBOARD1
);
727 radioline(&cp
, "The Backspace key", IDC_DELSTATIC
, 2,
728 "Control-&H", IDC_DEL008
,
729 "Control-&? (127)", IDC_DEL127
, NULL
);
730 radioline(&cp
, "The Home and End keys", IDC_HOMESTATIC
, 2,
731 "&Standard", IDC_HOMETILDE
,
732 "&rxvt", IDC_HOMERXVT
, NULL
);
733 radioline(&cp
, "The Function keys and keypad", IDC_FUNCSTATIC
, 4,
734 "ESC[n&~", IDC_FUNCTILDE
,
735 "&Linux", IDC_FUNCLINUX
,
736 "&Xterm R6", IDC_FUNCXTERM
,
737 "&VT400", IDC_FUNCVT400
, NULL
);
739 beginbox(&cp
, "Application keypad settings:",
740 IDC_BOX_KEYBOARD2
, IDC_BOXT_KEYBOARD2
);
742 "Application c&ursor keys totally disabled",
744 radioline(&cp
, "Initial state of cursor keys:", IDC_CURSTATIC
, 2,
745 "&Normal", IDC_CURNORMAL
,
746 "A&pplication", IDC_CURAPPLIC
, NULL
);
748 "Application ke&ypad keys totally disabled",
750 radioline(&cp
, "Initial state of numeric keypad:", IDC_KPSTATIC
, 3,
751 "Nor&mal", IDC_KPNORMAL
,
752 "Appl&ication", IDC_KPAPPLIC
,
753 "N&etHack", IDC_KPNH
, NULL
);
755 beginbox(&cp
, "Enable extra keyboard features:",
756 IDC_BOX_KEYBOARD3
, IDC_BOXT_KEYBOARD3
);
757 checkbox(&cp
, "Application and AltGr ac&t as Compose key",
761 treeview_insert(&tvfaff
, 1, "Keyboard");
764 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
767 ctlposinit(&cp
, hwnd
, 80, 3, 13);
768 bartitle(&cp
, "Options controlling PuTTY's window",
770 beginbox(&cp
, "Set the size of the window",
771 IDC_BOX_WINDOW1
, IDC_BOXT_WINDOW1
);
773 "&Rows", IDC_ROWSSTATIC
, IDC_ROWSEDIT
, 50,
774 "Colu&mns", IDC_COLSSTATIC
, IDC_COLSEDIT
, 50,
776 checkbox(&cp
, "Loc&k window size against resizing", IDC_LOCKSIZE
);
778 beginbox(&cp
, "Control the scrollback in the window",
779 IDC_BOX_WINDOW2
, IDC_BOXT_WINDOW2
);
780 staticedit(&cp
, "Lines of &scrollback",
781 IDC_SAVESTATIC
, IDC_SAVEEDIT
, 50);
782 checkbox(&cp
, "&Display scrollbar", IDC_SCROLLBAR
);
783 checkbox(&cp
, "Reset scrollback on &keypress", IDC_SCROLLKEY
);
784 checkbox(&cp
, "Reset scrollback on dis&play activity",
787 beginbox(&cp
, NULL
, IDC_BOX_WINDOW3
, 0);
788 checkbox(&cp
, "&Warn before closing window", IDC_CLOSEWARN
);
789 checkbox(&cp
, "Window closes on ALT-F&4", IDC_ALTF4
);
790 checkbox(&cp
, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE
);
791 checkbox(&cp
, "System menu appears on A< alone", IDC_ALTONLY
);
792 checkbox(&cp
, "Ensure window is always on &top", IDC_ALWAYSONTOP
);
795 treeview_insert(&tvfaff
, 0, "Window");
798 /* The Appearance panel. Accelerators used: [acgo] rmkhti */
801 ctlposinit(&cp
, hwnd
, 80, 3, 13);
802 bartitle(&cp
, "Options controlling PuTTY's appearance",
803 IDC_TITLE_APPEARANCE
);
804 beginbox(&cp
, "Adjust the use of the cursor",
805 IDC_BOX_APPEARANCE1
, IDC_BOXT_APPEARANCE1
);
806 checkbox(&cp
, "Cursor &blinks", IDC_BLINKCUR
);
808 beginbox(&cp
, "Set the font used in the terminal window",
809 IDC_BOX_APPEARANCE2
, IDC_BOXT_APPEARANCE2
);
810 staticbtn(&cp
, "", IDC_FONTSTATIC
, "C&hange...", IDC_CHOOSEFONT
);
812 beginbox(&cp
, "Adjust the use of the window title",
813 IDC_BOX_APPEARANCE3
, IDC_BOXT_APPEARANCE3
);
816 "Initial window &title:", IDC_WINTITLE
,
817 IDC_WINEDIT
, 100, NULL
);
818 checkbox(&cp
, "Avoid ever using &icon title", IDC_WINNAME
);
821 treeview_insert(&tvfaff
, 1, "Appearance");
824 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
827 ctlposinit(&cp
, hwnd
, 80, 3, 13);
828 bartitle(&cp
, "Options controlling character set translation",
829 IDC_TITLE_TRANSLATION
);
830 beginbox(&cp
, "Adjust how PuTTY displays line drawing characters",
831 IDC_BOX_TRANSLATION1
, IDC_BOXT_TRANSLATION1
);
833 "Handling of line drawing characters:", IDC_VTSTATIC
,
834 "Font has &XWindows encoding", IDC_VTXWINDOWS
,
835 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI
,
836 "Use font in O&EM mode only", IDC_VTOEMONLY
,
837 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
838 IDC_VTPOORMAN
, NULL
);
840 beginbox(&cp
, "Enable character set translation on received data",
841 IDC_BOX_TRANSLATION2
, IDC_BOXT_TRANSLATION2
);
843 "Character set translation:", IDC_XLATSTATIC
,
845 "&KOI8 / Win-1251", IDC_KOI8WIN1251
,
846 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250
,
847 "&ISO-8859-2 / CP852", IDC_88592CP852
, NULL
);
849 beginbox(&cp
, "Enable character set translation on input data",
850 IDC_BOX_TRANSLATION3
, IDC_BOXT_TRANSLATION3
);
851 checkbox(&cp
, "CAP&S LOCK acts as cyrillic switch",
855 treeview_insert(&tvfaff
, 1, "Translation");
858 /* The Selection panel. Accelerators used: [acgo] wxst */
861 ctlposinit(&cp
, hwnd
, 80, 3, 13);
862 bartitle(&cp
, "Options controlling copy and paste",
863 IDC_TITLE_SELECTION
);
864 beginbox(&cp
, "Control which mouse button does which thing",
865 IDC_BOX_SELECTION1
, IDC_BOXT_SELECTION1
);
866 radiobig(&cp
, "Action of mouse buttons:", IDC_MBSTATIC
,
867 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS
,
868 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM
,
871 beginbox(&cp
, "Control the select-one-word-at-a-time mode",
872 IDC_BOX_SELECTION2
, IDC_BOXT_SELECTION2
);
873 charclass(&cp
, "Character classes:", IDC_CCSTATIC
, IDC_CCLIST
,
874 "&Set", IDC_CCSET
, IDC_CCEDIT
,
875 "&to class", IDC_CCSTATIC2
);
878 treeview_insert(&tvfaff
, 1, "Selection");
881 /* The Colours panel. Accelerators used: [acgo] blum */
884 ctlposinit(&cp
, hwnd
, 80, 3, 13);
885 bartitle(&cp
, "Options controlling use of colours",
887 beginbox(&cp
, "General options for colour usage",
888 IDC_BOX_COLOURS1
, IDC_BOXT_COLOURS1
);
889 checkbox(&cp
, "&Bolded text is a different colour", IDC_BOLDCOLOUR
);
890 checkbox(&cp
, "Attempt to use &logical palettes", IDC_PALETTE
);
892 beginbox(&cp
, "Adjust the precise colours PuTTY displays",
893 IDC_BOX_COLOURS2
, IDC_BOXT_COLOURS2
);
894 colouredit(&cp
, "Select a colo&ur and then click to modify it:",
895 IDC_COLOURSTATIC
, IDC_COLOURLIST
,
896 "&Modify...", IDC_CHANGE
,
897 "Red:", IDC_RSTATIC
, IDC_RVALUE
,
898 "Green:", IDC_GSTATIC
, IDC_GVALUE
,
899 "Blue:", IDC_BSTATIC
, IDC_BVALUE
, NULL
);
902 treeview_insert(&tvfaff
, 1, "Colours");
905 /* The Connection panel. Accelerators used: [acgo] tuk */
908 ctlposinit(&cp
, hwnd
, 80, 3, 13);
909 bartitle(&cp
, "Options controlling the connection", IDC_TITLE_CONNECTION
);
911 beginbox(&cp
, "Data to send to the server",
912 IDC_BOX_CONNECTION1
, IDC_BOXT_CONNECTION1
);
913 staticedit(&cp
, "Terminal-&type string", IDC_TTSTATIC
, IDC_TTEDIT
, 50);
914 staticedit(&cp
, "Auto-login &username", IDC_LOGSTATIC
, IDC_LOGEDIT
, 50);
917 beginbox(&cp
, "Sending of null packets to keep session active",
918 IDC_BOX_CONNECTION2
, IDC_BOXT_CONNECTION2
);
919 staticedit(&cp
, "Minutes between &keepalives (0 to turn off)",
920 IDC_PINGSTATIC
, IDC_PINGEDIT
, 25);
923 treeview_insert(&tvfaff
, 0, "Connection");
926 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
929 ctlposinit(&cp
, hwnd
, 80, 3, 13);
931 bartitle(&cp
, "Options controlling Telnet connections", IDC_TITLE_TELNET
);
932 beginbox(&cp
, "Data to send to the server",
933 IDC_BOX_TELNET1
, IDC_BOXT_TELNET1
);
934 staticedit(&cp
, "Terminal-&speed string", IDC_TSSTATIC
, IDC_TSEDIT
, 50);
935 envsetter(&cp
, "Environment variables:", IDC_ENVSTATIC
,
936 "&Variable", IDC_VARSTATIC
, IDC_VAREDIT
,
937 "Va&lue", IDC_VALSTATIC
, IDC_VALEDIT
,
939 "A&dd", IDC_ENVADD
, "&Remove", IDC_ENVREMOVE
);
941 beginbox(&cp
, "Telnet protocol adjustments",
942 IDC_BOX_TELNET2
, IDC_BOXT_TELNET2
);
943 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC
, 2,
944 "&BSD (commonplace)", IDC_EMBSD
,
945 "R&FC 1408 (unusual)", IDC_EMRFC
, NULL
);
948 treeview_insert(&tvfaff
, 1, "Telnet");
952 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
953 if (backends
[2].backend
!= NULL
) {
955 ctlposinit(&cp
, hwnd
, 80, 3, 13);
957 bartitle(&cp
, "Options controlling SSH connections", IDC_TITLE_SSH
);
958 beginbox(&cp
, "Data to send to the server",
959 IDC_BOX_SSH1
, IDC_BOXT_SSH1
);
961 "&Remote command:", IDC_CMDSTATIC
, IDC_CMDEDIT
, 100,
964 beginbox(&cp
, "Authentication options",
965 IDC_BOX_SSH2
, IDC_BOXT_SSH2
);
966 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
968 checkbox(&cp
, "Allow &agent forwarding", IDC_AGENTFWD
);
969 editbutton(&cp
, "Private &key file for authentication:",
970 IDC_PKSTATIC
, IDC_PKEDIT
, "Bro&wse...", IDC_PKBUTTON
);
972 beginbox(&cp
, "Protocol options",
973 IDC_BOX_SSH3
, IDC_BOXT_SSH3
);
974 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC_NOPTY
);
975 radioline(&cp
, "Preferred SSH protocol version:",
976 IDC_SSHPROTSTATIC
, 2,
977 "&1", IDC_SSHPROT1
, "&2", IDC_SSHPROT2
, NULL
);
978 radioline(&cp
, "Preferred encryption algorithm:", IDC_CIPHERSTATIC
, 3,
979 "&3DES", IDC_CIPHER3DES
,
980 "&Blowfish", IDC_CIPHERBLOWF
,
981 "&DES", IDC_CIPHERDES
, NULL
);
982 checkbox(&cp
, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
986 treeview_insert(&tvfaff
, 1, "SSH");
990 init_dlg_ctrls(hwnd
);
991 for (i
= 0; i
< nsessions
; i
++)
992 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
993 0, (LPARAM
) (sessions
[i
]));
996 * Hide all the controls to start with.
998 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
1001 * Put the treeview selection on to the Session panel. This
1002 * should also cause unhiding of the relevant controls.
1004 TreeView_SelectItem(treeview
, hsession
);
1007 * Set focus into the first available control.
1011 ctl
= GetDlgItem(hwnd
, IDC_HOST
);
1012 if (!ctl
) ctl
= GetDlgItem(hwnd
, IDC_CLOSEEXIT
);
1016 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1020 * Button release should trigger WM_OK if there was a
1021 * previous double click on the session list.
1025 SendMessage (hwnd
, WM_COMMAND
, IDOK
, 0);
1028 if (LOWORD(wParam
) == IDCX_TREEVIEW
&&
1029 ((LPNMHDR
)lParam
)->code
== TVN_SELCHANGED
) {
1030 HTREEITEM i
= TreeView_GetSelection(((LPNMHDR
)lParam
)->hwndFrom
);
1034 item
.pszText
= buffer
;
1035 item
.cchTextMax
= sizeof(buffer
);
1036 item
.mask
= TVIF_TEXT
;
1037 TreeView_GetItem(((LPNMHDR
)lParam
)->hwndFrom
, &item
);
1038 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
1039 if (!strcmp(buffer
, "Session"))
1040 hide(hwnd
, FALSE
, sessionpanelstart
, sessionpanelend
);
1041 if (!strcmp(buffer
, "Keyboard"))
1042 hide(hwnd
, FALSE
, keyboardpanelstart
, keyboardpanelend
);
1043 if (!strcmp(buffer
, "Terminal"))
1044 hide(hwnd
, FALSE
, terminalpanelstart
, terminalpanelend
);
1045 if (!strcmp(buffer
, "Window"))
1046 hide(hwnd
, FALSE
, windowpanelstart
, windowpanelend
);
1047 if (!strcmp(buffer
, "Appearance"))
1048 hide(hwnd
, FALSE
, appearancepanelstart
, appearancepanelend
);
1049 if (!strcmp(buffer
, "Connection"))
1050 hide(hwnd
, FALSE
, connectionpanelstart
, connectionpanelend
);
1051 if (!strcmp(buffer
, "Telnet"))
1052 hide(hwnd
, FALSE
, telnetpanelstart
, telnetpanelend
);
1053 if (!strcmp(buffer
, "SSH"))
1054 hide(hwnd
, FALSE
, sshpanelstart
, sshpanelend
);
1055 if (!strcmp(buffer
, "Selection"))
1056 hide(hwnd
, FALSE
, selectionpanelstart
, selectionpanelend
);
1057 if (!strcmp(buffer
, "Colours"))
1058 hide(hwnd
, FALSE
, colourspanelstart
, colourspanelend
);
1059 if (!strcmp(buffer
, "Translation"))
1060 hide(hwnd
, FALSE
, translationpanelstart
, translationpanelend
);
1062 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1068 * Only process WM_COMMAND once the dialog is fully formed.
1070 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1) switch (LOWORD(wParam
)) {
1073 EndDialog (hwnd
, 1);
1078 EndDialog (hwnd
, 0);
1080 case IDC_PROTTELNET
:
1083 if (HIWORD(wParam
) == BN_CLICKED
||
1084 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1085 int i
= IsDlgButtonChecked (hwnd
, IDC_PROTSSH
);
1086 int j
= IsDlgButtonChecked (hwnd
, IDC_PROTTELNET
);
1087 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
1088 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
1089 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
1090 cfg
.port
= i ?
22 : 23;
1091 SetDlgItemInt (hwnd
, IDC_PORT
, cfg
.port
, FALSE
);
1096 if (HIWORD(wParam
) == EN_CHANGE
)
1097 GetDlgItemText (hwnd
, IDC_HOST
, cfg
.host
,
1098 sizeof(cfg
.host
)-1);
1101 if (HIWORD(wParam
) == EN_CHANGE
)
1102 MyGetDlgItemInt (hwnd
, IDC_PORT
, &cfg
.port
);
1105 if (HIWORD(wParam
) == EN_CHANGE
) {
1106 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1108 GetDlgItemText (hwnd
, IDC_SESSEDIT
,
1109 savedsession
, sizeof(savedsession
)-1);
1110 savedsession
[sizeof(savedsession
)-1] = '\0';
1114 if (HIWORD(wParam
) == BN_CLICKED
||
1115 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1120 GetDlgItemText (hwnd
, IDC_SESSEDIT
, str
, sizeof(str
)-1);
1122 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1123 LB_GETCURSEL
, 0, 0);
1128 strcpy (str
, sessions
[n
]);
1130 save_settings (str
, !!strcmp(str
, "Default Settings"), &cfg
);
1131 get_sesslist (FALSE
);
1132 get_sesslist (TRUE
);
1133 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1135 for (i
= 0; i
< nsessions
; i
++)
1136 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1137 0, (LPARAM
) (sessions
[i
]));
1138 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1144 if (LOWORD(wParam
) == IDC_SESSLOAD
&&
1145 HIWORD(wParam
) != BN_CLICKED
&&
1146 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1148 if (LOWORD(wParam
) == IDC_SESSLIST
&&
1149 HIWORD(wParam
) != LBN_DBLCLK
)
1152 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1153 LB_GETCURSEL
, 0, 0);
1159 isdef
= !strcmp(sessions
[n
], "Default Settings");
1160 load_settings (sessions
[n
], !isdef
, &cfg
);
1161 init_dlg_ctrls(hwnd
);
1163 SetDlgItemText(hwnd
, IDC_SESSEDIT
, sessions
[n
]);
1165 if (LOWORD(wParam
) == IDC_SESSLIST
) {
1167 * A double-click on a saved session should
1168 * actually start the session, not just load it.
1169 * Unless it's Default Settings or some other
1170 * host-less set of saved settings.
1179 if (HIWORD(wParam
) == BN_CLICKED
||
1180 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1181 int n
= SendDlgItemMessage (hwnd
, IDC_SESSLIST
,
1182 LB_GETCURSEL
, 0, 0);
1183 if (n
== LB_ERR
|| n
== 0) {
1187 del_settings(sessions
[n
]);
1188 get_sesslist (FALSE
);
1189 get_sesslist (TRUE
);
1190 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_RESETCONTENT
,
1192 for (i
= 0; i
< nsessions
; i
++)
1193 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_ADDSTRING
,
1194 0, (LPARAM
) (sessions
[i
]));
1195 SendDlgItemMessage (hwnd
, IDC_SESSLIST
, LB_SETCURSEL
,
1199 if (HIWORD(wParam
) == EN_CHANGE
)
1200 MyGetDlgItemInt (hwnd
, IDC_PINGEDIT
, &cfg
.ping_interval
);
1204 if (HIWORD(wParam
) == BN_CLICKED
||
1205 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1206 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC_DEL127
);
1210 if (HIWORD(wParam
) == BN_CLICKED
||
1211 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1212 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC_HOMERXVT
);
1215 if (HIWORD(wParam
) == BN_CLICKED
||
1216 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1220 if (HIWORD(wParam
) == BN_CLICKED
||
1221 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1226 if (HIWORD(wParam
) == BN_CLICKED
||
1227 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1228 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC_FUNCLINUX
);
1232 if (HIWORD(wParam
) == BN_CLICKED
||
1233 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1234 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC_KPAPPLIC
);
1235 cfg
.nethack_keypad
= FALSE
;
1239 if (HIWORD(wParam
) == BN_CLICKED
||
1240 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1241 cfg
.app_keypad
= FALSE
;
1242 cfg
.nethack_keypad
= TRUE
;
1247 if (HIWORD(wParam
) == BN_CLICKED
||
1248 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1249 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC_CURAPPLIC
);
1252 if (HIWORD(wParam
) == BN_CLICKED
||
1253 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1254 cfg
.no_applic_c
= IsDlgButtonChecked (hwnd
, IDC_NOAPPLICC
);
1257 if (HIWORD(wParam
) == BN_CLICKED
||
1258 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1259 cfg
.no_applic_k
= IsDlgButtonChecked (hwnd
, IDC_NOAPPLICK
);
1262 if (HIWORD(wParam
) == BN_CLICKED
||
1263 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1264 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC_ALTF4
);
1267 if (HIWORD(wParam
) == BN_CLICKED
||
1268 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1269 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC_ALTSPACE
);
1272 if (HIWORD(wParam
) == BN_CLICKED
||
1273 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1274 cfg
.alt_only
= IsDlgButtonChecked (hwnd
, IDC_ALTONLY
);
1277 if (HIWORD(wParam
) == BN_CLICKED
||
1278 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1279 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC_LDISCTERM
);
1281 case IDC_ALWAYSONTOP
:
1282 if (HIWORD(wParam
) == BN_CLICKED
||
1283 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1284 cfg
.alwaysontop
= IsDlgButtonChecked (hwnd
, IDC_ALWAYSONTOP
);
1287 if (HIWORD(wParam
) == BN_CLICKED
||
1288 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1289 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC_SCROLLKEY
);
1291 case IDC_SCROLLDISP
:
1292 if (HIWORD(wParam
) == BN_CLICKED
||
1293 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1294 cfg
.scroll_on_disp
= IsDlgButtonChecked (hwnd
, IDC_SCROLLDISP
);
1296 case IDC_COMPOSEKEY
:
1297 if (HIWORD(wParam
) == BN_CLICKED
||
1298 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1299 cfg
.compose_key
= IsDlgButtonChecked (hwnd
, IDC_COMPOSEKEY
);
1302 if (HIWORD(wParam
) == BN_CLICKED
||
1303 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1304 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC_WRAPMODE
);
1307 if (HIWORD(wParam
) == BN_CLICKED
||
1308 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1309 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC_DECOM
);
1312 if (HIWORD(wParam
) == BN_CLICKED
||
1313 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1314 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC_LFHASCR
);
1317 if (HIWORD(wParam
) == EN_CHANGE
)
1318 MyGetDlgItemInt (hwnd
, IDC_ROWSEDIT
, &cfg
.height
);
1321 if (HIWORD(wParam
) == EN_CHANGE
)
1322 MyGetDlgItemInt (hwnd
, IDC_COLSEDIT
, &cfg
.width
);
1325 if (HIWORD(wParam
) == EN_CHANGE
)
1326 MyGetDlgItemInt (hwnd
, IDC_SAVEEDIT
, &cfg
.savelines
);
1328 case IDC_CHOOSEFONT
:
1329 lf
.lfHeight
= cfg
.fontheight
;
1330 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1331 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1332 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1333 lf
.lfCharSet
= cfg
.fontcharset
;
1334 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1335 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1336 lf
.lfQuality
= DEFAULT_QUALITY
;
1337 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1338 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
1339 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
1341 cf
.lStructSize
= sizeof(cf
);
1342 cf
.hwndOwner
= hwnd
;
1344 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1345 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1347 if (ChooseFont (&cf
)) {
1348 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
1349 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
1350 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1351 cfg
.fontcharset
= lf
.lfCharSet
;
1352 cfg
.fontheight
= lf
.lfHeight
;
1353 fmtfont (fontstatic
);
1354 SetDlgItemText (hwnd
, IDC_FONTSTATIC
, fontstatic
);
1358 if (HIWORD(wParam
) == BN_CLICKED
||
1359 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1360 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC_BEEP
);
1363 if (HIWORD(wParam
) == BN_CLICKED
||
1364 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1365 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC_BLINKTEXT
);
1368 if (HIWORD(wParam
) == BN_CLICKED
||
1369 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1370 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC_BCE
);
1373 if (HIWORD(wParam
) == BN_CLICKED
||
1374 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1375 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC_WINNAME
);
1378 if (HIWORD(wParam
) == BN_CLICKED
||
1379 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1380 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC_BLINKCUR
);
1383 if (HIWORD(wParam
) == BN_CLICKED
||
1384 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1385 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC_SCROLLBAR
);
1388 if (HIWORD(wParam
) == BN_CLICKED
||
1389 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1390 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC_LOCKSIZE
);
1393 if (HIWORD(wParam
) == EN_CHANGE
)
1394 GetDlgItemText (hwnd
, IDC_WINEDIT
, cfg
.wintitle
,
1395 sizeof(cfg
.wintitle
)-1);
1398 if (HIWORD(wParam
) == BN_CLICKED
||
1399 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1400 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC_CLOSEEXIT
);
1403 if (HIWORD(wParam
) == BN_CLICKED
||
1404 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1405 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC_CLOSEWARN
);
1408 if (HIWORD(wParam
) == EN_CHANGE
)
1409 GetDlgItemText (hwnd
, IDC_TTEDIT
, cfg
.termtype
,
1410 sizeof(cfg
.termtype
)-1);
1413 if (HIWORD(wParam
) == EN_CHANGE
)
1414 GetDlgItemText (hwnd
, IDC_TSEDIT
, cfg
.termspeed
,
1415 sizeof(cfg
.termspeed
)-1);
1418 if (HIWORD(wParam
) == EN_CHANGE
)
1419 GetDlgItemText (hwnd
, IDC_LOGEDIT
, cfg
.username
,
1420 sizeof(cfg
.username
)-1);
1424 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC_EMRFC
);
1427 if (HIWORD(wParam
) == BN_CLICKED
||
1428 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1429 char str
[sizeof(cfg
.environmt
)];
1431 GetDlgItemText (hwnd
, IDC_VAREDIT
, str
, sizeof(str
)-1);
1436 p
= str
+ strlen(str
);
1438 GetDlgItemText (hwnd
, IDC_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
1448 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
1450 p
[strlen(str
)+1] = '\0';
1451 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_ADDSTRING
,
1453 SetDlgItemText (hwnd
, IDC_VAREDIT
, "");
1454 SetDlgItemText (hwnd
, IDC_VALEDIT
, "");
1456 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
1457 MB_OK
| MB_ICONERROR
);
1462 if (HIWORD(wParam
) != BN_CLICKED
&&
1463 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1465 i
= SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_GETCURSEL
, 0, 0);
1471 SendDlgItemMessage (hwnd
, IDC_ENVLIST
, LB_DELETESTRING
,
1496 if (HIWORD(wParam
) == BN_CLICKED
||
1497 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1498 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC_NOPTY
);
1501 if (HIWORD(wParam
) == BN_CLICKED
||
1502 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1503 cfg
.buggymac
= IsDlgButtonChecked (hwnd
, IDC_BUGGYMAC
);
1506 if (HIWORD(wParam
) == BN_CLICKED
||
1507 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1508 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC_AGENTFWD
);
1510 case IDC_CIPHER3DES
:
1511 case IDC_CIPHERBLOWF
:
1513 if (HIWORD(wParam
) == BN_CLICKED
||
1514 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1515 if (IsDlgButtonChecked (hwnd
, IDC_CIPHER3DES
))
1516 cfg
.cipher
= CIPHER_3DES
;
1517 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERBLOWF
))
1518 cfg
.cipher
= CIPHER_BLOWFISH
;
1519 else if (IsDlgButtonChecked (hwnd
, IDC_CIPHERDES
))
1520 cfg
.cipher
= CIPHER_DES
;
1525 if (HIWORD(wParam
) == BN_CLICKED
||
1526 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1527 if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT1
))
1529 else if (IsDlgButtonChecked (hwnd
, IDC_SSHPROT2
))
1534 if (HIWORD(wParam
) == BN_CLICKED
||
1535 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1536 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC_AUTHTIS
);
1539 if (HIWORD(wParam
) == EN_CHANGE
)
1540 GetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
,
1541 sizeof(cfg
.keyfile
)-1);
1544 if (HIWORD(wParam
) == EN_CHANGE
)
1545 GetDlgItemText (hwnd
, IDC_CMDEDIT
, cfg
.remote_cmd
,
1546 sizeof(cfg
.remote_cmd
)-1);
1549 memset(&of
, 0, sizeof(of
));
1550 #ifdef OPENFILENAME_SIZE_VERSION_400
1551 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1553 of
.lStructSize
= sizeof(of
);
1555 of
.hwndOwner
= hwnd
;
1556 of
.lpstrFilter
= "All Files\0*\0\0\0";
1557 of
.lpstrCustomFilter
= NULL
;
1558 of
.nFilterIndex
= 1;
1559 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1560 of
.nMaxFile
= sizeof(filename
);
1561 of
.lpstrFileTitle
= NULL
;
1562 of
.lpstrInitialDir
= NULL
;
1563 of
.lpstrTitle
= "Select Public Key File";
1565 if (GetOpenFileName(&of
)) {
1566 strcpy(cfg
.keyfile
, filename
);
1567 SetDlgItemText (hwnd
, IDC_PKEDIT
, cfg
.keyfile
);
1572 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC_MBXTERM
);
1578 int n
= GetDlgItemInt (hwnd
, IDC_CCEDIT
, &ok
, FALSE
);
1583 for (i
=0; i
<256; i
++)
1584 if (SendDlgItemMessage (hwnd
, IDC_CCLIST
, LB_GETSEL
,
1587 cfg
.wordness
[i
] = n
;
1588 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
1589 LB_DELETESTRING
, i
, 0);
1590 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1591 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1593 SendDlgItemMessage (hwnd
, IDC_CCLIST
,
1600 case IDC_BOLDCOLOUR
:
1601 if (HIWORD(wParam
) == BN_CLICKED
||
1602 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1604 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC_BOLDCOLOUR
);
1605 n
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCOUNT
, 0, 0);
1606 if (cfg
.bold_colour
&& n
!=22) {
1607 for (i
=0; i
<22; i
++)
1609 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
1611 (LPARAM
) colours
[i
]);
1612 } else if (!cfg
.bold_colour
&& n
!=12) {
1615 SendDlgItemMessage (hwnd
, IDC_COLOURLIST
,
1616 LB_DELETESTRING
, i
, 0);
1621 if (HIWORD(wParam
) == BN_CLICKED
||
1622 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1623 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC_PALETTE
);
1625 case IDC_COLOURLIST
:
1626 if (HIWORD(wParam
) == LBN_DBLCLK
||
1627 HIWORD(wParam
) == LBN_SELCHANGE
) {
1628 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
1630 if (!cfg
.bold_colour
)
1631 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1632 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1633 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1634 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1638 if (HIWORD(wParam
) == BN_CLICKED
||
1639 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1640 static CHOOSECOLOR cc
;
1641 static DWORD custom
[16] = {0}; /* zero initialisers */
1642 int i
= SendDlgItemMessage (hwnd
, IDC_COLOURLIST
, LB_GETCURSEL
,
1644 if (!cfg
.bold_colour
)
1645 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1646 cc
.lStructSize
= sizeof(cc
);
1647 cc
.hwndOwner
= hwnd
;
1648 cc
.hInstance
= (HWND
)hinst
;
1649 cc
.lpCustColors
= custom
;
1650 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1652 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1653 if (ChooseColor(&cc
)) {
1655 (unsigned char) (cc
.rgbResult
& 0xFF);
1657 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1659 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1660 SetDlgItemInt (hwnd
, IDC_RVALUE
, cfg
.colours
[i
][0],
1662 SetDlgItemInt (hwnd
, IDC_GVALUE
, cfg
.colours
[i
][1],
1664 SetDlgItemInt (hwnd
, IDC_BVALUE
, cfg
.colours
[i
][2],
1670 case IDC_KOI8WIN1251
:
1671 case IDC_88592WIN1250
:
1672 case IDC_88592CP852
:
1673 cfg
.xlat_enablekoiwin
=
1674 IsDlgButtonChecked (hwnd
, IDC_KOI8WIN1251
);
1675 cfg
.xlat_88592w1250
=
1676 IsDlgButtonChecked (hwnd
, IDC_88592WIN1250
);
1677 cfg
.xlat_88592cp852
=
1678 IsDlgButtonChecked (hwnd
, IDC_88592CP852
);
1680 case IDC_CAPSLOCKCYR
:
1681 if (HIWORD(wParam
) == BN_CLICKED
||
1682 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1683 cfg
.xlat_capslockcyr
=
1684 IsDlgButtonChecked (hwnd
, IDC_CAPSLOCKCYR
);
1687 case IDC_VTXWINDOWS
:
1692 (IsDlgButtonChecked (hwnd
, IDC_VTXWINDOWS
) ? VT_XWINDOWS
:
1693 IsDlgButtonChecked (hwnd
, IDC_VTOEMANSI
) ? VT_OEMANSI
:
1694 IsDlgButtonChecked (hwnd
, IDC_VTOEMONLY
) ? VT_OEMONLY
:
1700 EndDialog (hwnd
, 0);
1703 /* Grrr Explorer will maximize Dialogs! */
1705 if (wParam
== SIZE_MAXIMIZED
)
1712 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1713 WPARAM wParam
, LPARAM lParam
) {
1714 static HWND page
= NULL
;
1716 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1718 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
1719 EnableWindow(hwnd
, 0);
1720 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1721 GetParent(hwnd
), AboutProc
);
1722 EnableWindow(hwnd
, 1);
1723 SetActiveWindow(hwnd
);
1725 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 0);
1728 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1729 WPARAM wParam
, LPARAM lParam
) {
1731 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 1);
1734 void defuse_showwindow(void) {
1736 * Work around the fact that the app's first call to ShowWindow
1737 * will ignore the default in favour of the shell-provided
1742 hwnd
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1744 ShowWindow(hwnd
, SW_HIDE
);
1745 DestroyWindow(hwnd
);
1749 int do_config (void) {
1753 savedsession
[0] = '\0';
1754 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1755 get_sesslist(FALSE
);
1760 int do_reconfig (HWND hwnd
) {
1764 backup_cfg
= cfg
; /* structure copy */
1765 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1767 cfg
= backup_cfg
; /* structure copy */
1774 void logevent (char *string
) {
1775 if (nevents
>= negsize
) {
1777 events
= srealloc (events
, negsize
* sizeof(*events
));
1779 events
[nevents
] = smalloc(1+strlen(string
));
1780 strcpy (events
[nevents
], string
);
1784 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1786 count
= SendDlgItemMessage (logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
1787 SendDlgItemMessage (logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
-1, 0);
1791 void showeventlog (HWND hwnd
) {
1793 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1795 ShowWindow (logbox
, SW_SHOWNORMAL
);
1799 void showabout (HWND hwnd
) {
1801 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1803 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1807 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
1808 char *keystr
, char *fingerprint
) {
1811 static const char absentmsg
[] =
1812 "The server's host key is not cached in the registry. You\n"
1813 "have no guarantee that the server is the computer you\n"
1815 "The server's key fingerprint is:\n"
1817 "If you trust this host, hit Yes to add the key to\n"
1818 "PuTTY's cache and carry on connecting.\n"
1819 "If you do not trust this host, hit No to abandon the\n"
1822 static const char wrongmsg
[] =
1823 "WARNING - POTENTIAL SECURITY BREACH!\n"
1825 "The server's host key does not match the one PuTTY has\n"
1826 "cached in the registry. This means that either the\n"
1827 "server administrator has changed the host key, or you\n"
1828 "have actually connected to another computer pretending\n"
1829 "to be the server.\n"
1830 "The new key fingerprint is:\n"
1832 "If you were expecting this change and trust the new key,\n"
1833 "hit Yes to update PuTTY's cache and continue connecting.\n"
1834 "If you want to carry on connecting but without updating\n"
1835 "the cache, hit No.\n"
1836 "If you want to abandon the connection completely, hit\n"
1837 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1840 static const char mbtitle
[] = "PuTTY Security Alert";
1843 char message
[160+ /* sensible fingerprint max size */
1844 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
1845 sizeof(absentmsg
) : sizeof(wrongmsg
))];
1848 * Verify the key against the registry.
1850 ret
= verify_host_key(host
, port
, keytype
, keystr
);
1852 if (ret
== 0) /* success - key matched OK */
1854 if (ret
== 2) { /* key was different */
1856 sprintf(message
, wrongmsg
, fingerprint
);
1857 mbret
= MessageBox(NULL
, message
, mbtitle
,
1858 MB_ICONWARNING
| MB_YESNOCANCEL
);
1860 store_host_key(host
, port
, keytype
, keystr
);
1861 if (mbret
== IDCANCEL
)
1864 if (ret
== 1) { /* key was absent */
1866 sprintf(message
, absentmsg
, fingerprint
);
1867 mbret
= MessageBox(NULL
, message
, mbtitle
,
1868 MB_ICONWARNING
| MB_YESNO
);
1871 store_host_key(host
, port
, keytype
, keystr
);