13 #define MAIN_NPANELS 8
14 #define RECONF_NPANELS 5
16 static const char *const puttystr
= PUTTY_REG_POS
"\\Sessions";
18 static char **events
= NULL
;
19 static int nevents
= 0, negsize
= 0;
21 static HWND logbox
= NULL
, abtbox
= NULL
;
23 static char hex
[16] = "0123456789ABCDEF";
25 static void mungestr(char *in
, char *out
) {
29 if (*in
== ' ' || *in
== '\\' || *in
== '*' || *in
== '?' ||
30 *in
== '%' || *in
< ' ' || *in
> '~' || (*in
== '.' && !candot
)) {
32 *out
++ = hex
[((unsigned char)*in
) >> 4];
33 *out
++ = hex
[((unsigned char)*in
) & 15];
43 static void unmungestr(char *in
, char *out
) {
45 if (*in
== '%' && in
[1] && in
[2]) {
48 i
= in
[1] - '0'; i
-= (i
> 9 ?
7 : 0);
49 j
= in
[2] - '0'; j
-= (j
> 9 ?
7 : 0);
60 static void wpps(HKEY key
, LPCTSTR name
, LPCTSTR value
) {
61 RegSetValueEx(key
, name
, 0, REG_SZ
, value
, 1+strlen(value
));
64 static void wppi(HKEY key
, LPCTSTR name
, int value
) {
65 RegSetValueEx(key
, name
, 0, REG_DWORD
,
66 (CONST BYTE
*)&value
, sizeof(value
));
69 static void gpps(HKEY key
, LPCTSTR name
, LPCTSTR def
,
70 LPTSTR val
, int len
) {
75 RegQueryValueEx(key
, name
, 0, &type
, val
, &size
) != ERROR_SUCCESS
||
77 strncpy(val
, def
, len
);
82 static void gppi(HKEY key
, LPCTSTR name
, int def
, int *i
) {
83 DWORD type
, val
, size
;
87 RegQueryValueEx(key
, name
, 0, &type
,
88 (BYTE
*)&val
, &size
) != ERROR_SUCCESS
||
89 size
!= sizeof(val
) || type
!= REG_DWORD
)
95 static HINSTANCE hinst
;
99 static void save_settings (char *section
, int do_host
) {
101 HKEY subkey1
, sesskey
;
104 p
= malloc(3*strlen(section
)+1);
105 mungestr(section
, p
);
107 if (RegCreateKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
)!=ERROR_SUCCESS
||
108 RegCreateKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
113 RegCloseKey(subkey1
);
115 wppi (sesskey
, "Present", 1);
117 wpps (sesskey
, "HostName", cfg
.host
);
118 wppi (sesskey
, "PortNumber", cfg
.port
);
119 wpps (sesskey
, "Protocol",
120 cfg
.protocol
== PROT_SSH ?
"ssh" :
121 cfg
.protocol
== PROT_TELNET ?
"telnet" : "raw" );
123 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
124 wppi (sesskey
, "WarnOnClose", !!cfg
.warn_on_close
);
125 wpps (sesskey
, "TerminalType", cfg
.termtype
);
126 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
128 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
134 if (c
== '=' || c
== ',' || c
== '\\')
144 wpps (sesskey
, "Environment", buf
);
146 wpps (sesskey
, "UserName", cfg
.username
);
147 wppi (sesskey
, "NoPTY", cfg
.nopty
);
148 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
149 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
150 wppi (sesskey
, "AuthTIS", cfg
.try_tis_auth
);
151 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
152 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
153 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
154 wppi (sesskey
, "LinuxFunctionKeys", cfg
.linux_funkeys
);
155 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
156 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
157 wppi (sesskey
, "NetHackKeypad", cfg
.nethack_keypad
);
158 wppi (sesskey
, "AltF4", cfg
.alt_f4
);
159 wppi (sesskey
, "AltSpace", cfg
.alt_space
);
160 wppi (sesskey
, "LdiscTerm", cfg
.ldisc_term
);
161 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
162 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
163 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
164 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
165 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
166 wppi (sesskey
, "TermWidth", cfg
.width
);
167 wppi (sesskey
, "TermHeight", cfg
.height
);
168 wpps (sesskey
, "Font", cfg
.font
);
169 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
170 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
171 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
172 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
173 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
174 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
175 for (i
=0; i
<22; i
++) {
176 char buf
[20], buf2
[30];
177 sprintf(buf
, "Colour%d", i
);
178 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
179 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
180 wpps (sesskey
, buf
, buf2
);
182 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
183 for (i
=0; i
<256; i
+=32) {
184 char buf
[20], buf2
[256];
186 sprintf(buf
, "Wordness%d", i
);
188 for (j
=i
; j
<i
+32; j
++) {
189 sprintf(buf2
+strlen(buf2
), "%s%d",
190 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
192 wpps (sesskey
, buf
, buf2
);
194 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
195 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
197 RegCloseKey(sesskey
);
200 static void del_session (char *section
) {
204 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
207 p
= malloc(3*strlen(section
)+1);
208 mungestr(section
, p
);
209 RegDeleteKey(subkey1
, p
);
212 RegCloseKey(subkey1
);
215 static void load_settings (char *section
, int do_host
) {
217 HKEY subkey1
, sesskey
;
221 p
= malloc(3*strlen(section
)+1);
222 mungestr(section
, p
);
224 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
227 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
230 RegCloseKey(subkey1
);
235 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
236 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
237 gpps (sesskey
, "Protocol", "default", prot
, 10);
238 if (!strcmp(prot
, "ssh"))
239 cfg
.protocol
= PROT_SSH
;
240 else if (!strcmp(prot
, "telnet"))
241 cfg
.protocol
= PROT_TELNET
;
242 else if (!strcmp(prot
, "raw"))
243 cfg
.protocol
= PROT_RAW
;
245 cfg
.protocol
= default_protocol
;
247 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
248 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
249 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
250 sizeof(cfg
.termtype
));
251 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
252 sizeof(cfg
.termspeed
));
254 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
255 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
259 while (*p
&& *p
!= ',') {
272 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
273 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
276 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
277 if (!strcmp(cipher
, "blowfish"))
278 cfg
.cipher
= CIPHER_BLOWFISH
;
279 else if (!strcmp(cipher
, "des"))
280 cfg
.cipher
= CIPHER_DES
;
282 cfg
.cipher
= CIPHER_3DES
;
284 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
285 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
286 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
287 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
288 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
289 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
290 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
291 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
292 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
293 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
294 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
295 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
296 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
297 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
298 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
299 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
300 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
301 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
302 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
303 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
304 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
305 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
306 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
307 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
308 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
309 for (i
=0; i
<22; i
++) {
310 static char *defaults
[] = {
311 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
312 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
313 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
314 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
315 "85,255,255", "187,187,187", "255,255,255"
317 char buf
[20], buf2
[30];
318 sprintf(buf
, "Colour%d", i
);
319 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
320 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
321 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
323 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
324 for (i
=0; i
<256; i
+=32) {
325 static char *defaults
[] = {
326 "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
327 "0,1,2,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1",
328 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2",
329 "1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1",
330 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
331 "1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1",
332 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2",
333 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
335 char buf
[20], buf2
[256], *p
;
337 sprintf(buf
, "Wordness%d", i
);
338 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
340 for (j
=i
; j
<i
+32; j
++) {
342 while (*p
&& *p
!= ',') p
++;
343 if (*p
== ',') *p
++ = '\0';
344 cfg
.wordness
[j
] = atoi(q
);
347 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
348 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
350 RegCloseKey(sesskey
);
353 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
356 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
361 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
362 WPARAM wParam
, LPARAM lParam
) {
367 for (i
=0; i
<nevents
; i
++)
368 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
369 0, (LPARAM
)events
[i
]);
371 /* case WM_CTLCOLORDLG: */
372 /* return (int) GetStockObject (LTGRAY_BRUSH); */
374 switch (LOWORD(wParam
)) {
377 DestroyWindow (hwnd
);
383 DestroyWindow (hwnd
);
389 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
390 WPARAM wParam
, LPARAM lParam
) {
395 switch (LOWORD(wParam
)) {
398 DestroyWindow (hwnd
);
404 DestroyWindow (hwnd
);
410 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
411 WPARAM wParam
, LPARAM lParam
) {
414 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
416 /* case WM_CTLCOLORDLG: */
417 /* return (int) GetStockObject (LTGRAY_BRUSH); */
418 /* case WM_CTLCOLORSTATIC: */
419 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
420 /* return (int) GetStockObject (LTGRAY_BRUSH); */
422 switch (LOWORD(wParam
)) {
425 DestroyWindow (hwnd
);
428 EnableWindow(hwnd
, 0);
429 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
431 EnableWindow(hwnd
, 1);
437 DestroyWindow (hwnd
);
443 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
444 WPARAM wParam
, LPARAM lParam
) {
447 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
449 /* case WM_CTLCOLORDLG: */
450 /* return (int) GetStockObject (LTGRAY_BRUSH); */
451 /* case WM_CTLCOLORSTATIC: */
452 /* case WM_CTLCOLORBTN: */
453 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
454 /* return (int) GetStockObject (LTGRAY_BRUSH); */
456 DestroyWindow (hwnd
);
462 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
463 WPARAM wParam
, LPARAM lParam
) {
468 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
469 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
470 for (i
= 0; i
< nsessions
; i
++)
471 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
472 0, (LPARAM
) (sessions
[i
]));
473 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
474 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
475 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
476 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
477 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
481 * Button release should trigger WM_OK if there was a
482 * previous double click on the session list.
486 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
489 switch (LOWORD(wParam
)) {
490 case IDC0_PROTTELNET
:
493 if (HIWORD(wParam
) == BN_CLICKED
||
494 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
495 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
496 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
497 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
498 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
499 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
500 cfg
.port
= i ?
22 : 23;
501 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
506 if (HIWORD(wParam
) == EN_CHANGE
)
507 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
511 if (HIWORD(wParam
) == EN_CHANGE
)
512 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
515 if (HIWORD(wParam
) == BN_CLICKED
||
516 HIWORD(wParam
) == BN_DOUBLECLICKED
)
517 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
520 if (HIWORD(wParam
) == BN_CLICKED
||
521 HIWORD(wParam
) == BN_DOUBLECLICKED
)
522 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
525 if (HIWORD(wParam
) == EN_CHANGE
)
526 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
530 if (HIWORD(wParam
) == BN_CLICKED
||
531 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
536 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
538 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
544 strcpy (str
, sessions
[n
]);
546 save_settings (str
, !!strcmp(str
, "Default Settings"));
547 get_sesslist (FALSE
);
549 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
551 for (i
= 0; i
< nsessions
; i
++)
552 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
553 0, (LPARAM
) (sessions
[i
]));
554 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
560 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
561 HIWORD(wParam
) != BN_CLICKED
&&
562 HIWORD(wParam
) != BN_DOUBLECLICKED
)
564 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
565 HIWORD(wParam
) != LBN_DBLCLK
)
568 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
574 load_settings (sessions
[n
],
575 !!strcmp(sessions
[n
], "Default Settings"));
576 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
577 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
578 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
579 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
580 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
581 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
582 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
583 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
586 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
588 * A double-click on a saved session should
589 * actually start the session, not just load it.
590 * Unless it's Default Settings or some other
591 * host-less set of saved settings.
600 if (HIWORD(wParam
) == BN_CLICKED
||
601 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
602 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
604 if (n
== LB_ERR
|| n
== 0) {
608 del_session(sessions
[n
]);
609 get_sesslist (FALSE
);
611 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
613 for (i
= 0; i
< nsessions
; i
++)
614 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
615 0, (LPARAM
) (sessions
[i
]));
616 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
621 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
624 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
625 WPARAM wParam
, LPARAM lParam
) {
628 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
629 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
630 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
631 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
632 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
633 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
634 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
635 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
636 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
637 cfg
.nethack_keypad ? IDC1_KPNH
:
638 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
639 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
640 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
641 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
644 if (HIWORD(wParam
) == BN_CLICKED
||
645 HIWORD(wParam
) == BN_DOUBLECLICKED
)
646 switch (LOWORD(wParam
)) {
649 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
653 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
657 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
661 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
662 cfg
.nethack_keypad
= FALSE
;
665 cfg
.app_keypad
= FALSE
;
666 cfg
.nethack_keypad
= TRUE
;
670 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
673 if (HIWORD(wParam
) == BN_CLICKED
||
674 HIWORD(wParam
) == BN_DOUBLECLICKED
)
675 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
678 if (HIWORD(wParam
) == BN_CLICKED
||
679 HIWORD(wParam
) == BN_DOUBLECLICKED
)
680 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
683 if (HIWORD(wParam
) == BN_CLICKED
||
684 HIWORD(wParam
) == BN_DOUBLECLICKED
)
685 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
689 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
692 static void fmtfont (char *buf
) {
693 sprintf (buf
, "Font: %s, ", cfg
.font
);
695 strcat(buf
, "bold, ");
696 if (cfg
.fontheight
== 0)
697 strcat (buf
, "default height");
699 sprintf (buf
+strlen(buf
), "%d-%s",
700 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
701 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
704 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
705 WPARAM wParam
, LPARAM lParam
) {
708 char fontstatic
[256];
712 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
713 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
714 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
715 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
716 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
717 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
718 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
719 fmtfont (fontstatic
);
720 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
721 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
722 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
723 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
724 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
728 switch (LOWORD(wParam
)) {
730 if (HIWORD(wParam
) == BN_CLICKED
||
731 HIWORD(wParam
) == BN_DOUBLECLICKED
)
732 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
735 if (HIWORD(wParam
) == BN_CLICKED
||
736 HIWORD(wParam
) == BN_DOUBLECLICKED
)
737 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
740 if (HIWORD(wParam
) == BN_CLICKED
||
741 HIWORD(wParam
) == BN_DOUBLECLICKED
)
742 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
745 if (HIWORD(wParam
) == BN_CLICKED
||
746 HIWORD(wParam
) == BN_DOUBLECLICKED
)
747 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
750 if (HIWORD(wParam
) == EN_CHANGE
)
751 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
754 if (HIWORD(wParam
) == EN_CHANGE
)
755 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
758 if (HIWORD(wParam
) == EN_CHANGE
)
759 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
761 case IDC2_CHOOSEFONT
:
762 lf
.lfHeight
= cfg
.fontheight
;
763 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
764 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
765 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
766 lf
.lfCharSet
= cfg
.fontcharset
;
767 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
768 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
769 lf
.lfQuality
= DEFAULT_QUALITY
;
770 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
771 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
772 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
774 cf
.lStructSize
= sizeof(cf
);
777 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
778 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
780 if (ChooseFont (&cf
)) {
781 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
782 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
783 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
784 cfg
.fontcharset
= lf
.lfCharSet
;
785 cfg
.fontheight
= lf
.lfHeight
;
786 fmtfont (fontstatic
);
787 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
790 case IDC2_VTXWINDOWS
:
795 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
796 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
797 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
803 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
806 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
807 WPARAM wParam
, LPARAM lParam
) {
812 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
813 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
814 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
816 char *p
= cfg
.environmt
;
818 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
823 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
824 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
827 switch (LOWORD(wParam
)) {
829 if (HIWORD(wParam
) == EN_CHANGE
)
830 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
831 sizeof(cfg
.termtype
)-1);
834 if (HIWORD(wParam
) == EN_CHANGE
)
835 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
836 sizeof(cfg
.termspeed
)-1);
839 if (HIWORD(wParam
) == EN_CHANGE
)
840 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
841 sizeof(cfg
.username
)-1);
845 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
848 if (HIWORD(wParam
) == BN_CLICKED
||
849 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
850 char str
[sizeof(cfg
.environmt
)];
852 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
857 p
= str
+ strlen(str
);
859 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
869 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
871 p
[strlen(str
)+1] = '\0';
872 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
874 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
875 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
877 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
878 MB_OK
| MB_ICONERROR
);
883 if (HIWORD(wParam
) != BN_CLICKED
&&
884 HIWORD(wParam
) != BN_DOUBLECLICKED
)
886 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
892 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
919 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
922 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
923 WPARAM wParam
, LPARAM lParam
) {
926 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
927 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
928 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
929 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
930 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
931 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
934 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
937 switch (LOWORD(wParam
)) {
939 if (HIWORD(wParam
) == EN_CHANGE
)
940 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
941 sizeof(cfg
.termtype
)-1);
944 if (HIWORD(wParam
) == EN_CHANGE
)
945 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
946 sizeof(cfg
.username
)-1);
949 if (HIWORD(wParam
) == BN_CLICKED
||
950 HIWORD(wParam
) == BN_DOUBLECLICKED
)
951 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
953 case IDC3_CIPHER3DES
:
954 case IDC3_CIPHERBLOWF
:
956 if (HIWORD(wParam
) == BN_CLICKED
||
957 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
958 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
959 cfg
.cipher
= CIPHER_3DES
;
960 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
961 cfg
.cipher
= CIPHER_BLOWFISH
;
962 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
963 cfg
.cipher
= CIPHER_DES
;
967 if (HIWORD(wParam
) == BN_CLICKED
||
968 HIWORD(wParam
) == BN_DOUBLECLICKED
)
969 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
974 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
977 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
978 WPARAM wParam
, LPARAM lParam
) {
983 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
984 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
986 static int tabs
[4] = {25, 61, 96, 128};
987 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
990 for (i
=0; i
<256; i
++) {
992 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
993 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
995 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1000 switch (LOWORD(wParam
)) {
1001 case IDC4_MBWINDOWS
:
1003 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1009 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1014 for (i
=0; i
<256; i
++)
1015 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1018 cfg
.wordness
[i
] = n
;
1019 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1020 LB_DELETESTRING
, i
, 0);
1021 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1022 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1024 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1034 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1037 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1038 WPARAM wParam
, LPARAM lParam
) {
1039 static const char *const colours
[] = {
1040 "Default Foreground", "Default Bold Foreground",
1041 "Default Background", "Default Bold Background",
1042 "Cursor Text", "Cursor Colour",
1043 "ANSI Black", "ANSI Black Bold",
1044 "ANSI Red", "ANSI Red Bold",
1045 "ANSI Green", "ANSI Green Bold",
1046 "ANSI Yellow", "ANSI Yellow Bold",
1047 "ANSI Blue", "ANSI Blue Bold",
1048 "ANSI Magenta", "ANSI Magenta Bold",
1049 "ANSI Cyan", "ANSI Cyan Bold",
1050 "ANSI White", "ANSI White Bold"
1052 static const int permanent
[] = {
1053 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1054 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1055 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1059 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1060 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1063 for (i
=0; i
<22; i
++)
1064 if (cfg
.bold_colour
|| permanent
[i
])
1065 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1066 (LPARAM
) colours
[i
]);
1068 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1069 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1070 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1071 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1074 switch (LOWORD(wParam
)) {
1075 case IDC5_BOLDCOLOUR
:
1076 if (HIWORD(wParam
) == BN_CLICKED
||
1077 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1079 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1080 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1081 if (cfg
.bold_colour
&& n
!=22) {
1082 for (i
=0; i
<22; i
++)
1084 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1086 (LPARAM
) colours
[i
]);
1087 } else if (!cfg
.bold_colour
&& n
!=12) {
1090 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1091 LB_DELETESTRING
, i
, 0);
1096 if (HIWORD(wParam
) == BN_CLICKED
||
1097 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1098 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1101 if (HIWORD(wParam
) == LBN_DBLCLK
||
1102 HIWORD(wParam
) == LBN_SELCHANGE
) {
1103 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1105 if (!cfg
.bold_colour
)
1106 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1107 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1108 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1109 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1113 if (HIWORD(wParam
) == BN_CLICKED
||
1114 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1115 static CHOOSECOLOR cc
;
1116 static DWORD custom
[16] = {0}; /* zero initialisers */
1117 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1119 if (!cfg
.bold_colour
)
1120 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1121 cc
.lStructSize
= sizeof(cc
);
1122 cc
.hwndOwner
= hwnd
;
1123 cc
.hInstance
= hinst
;
1124 cc
.lpCustColors
= custom
;
1125 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1127 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1128 if (ChooseColor(&cc
)) {
1130 (unsigned char) (cc
.rgbResult
& 0xFF);
1132 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1134 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1135 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1137 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1139 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1147 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1150 static int CALLBACK
LanguageProc (HWND hwnd
, UINT msg
,
1151 WPARAM wParam
, LPARAM lParam
) {
1154 CheckDlgButton (hwnd
, IDC6_ENABLEKOIWINXLAT
, cfg
.xlat_enablekoiwin
);
1155 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1157 switch (LOWORD(wParam
)) {
1158 case IDC6_ENABLEKOIWINXLAT
:
1159 if (HIWORD(wParam
) == BN_CLICKED
||
1160 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1161 cfg
.xlat_enablekoiwin
=
1162 IsDlgButtonChecked (hwnd
, IDC6_ENABLEKOIWINXLAT
);
1165 case IDC6_CAPSLOCKCYR
:
1166 if (HIWORD(wParam
) == BN_CLICKED
||
1167 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1168 cfg
.xlat_capslockcyr
=
1169 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1174 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1177 static DLGPROC panelproc
[NPANELS
] = {
1178 ConnectionProc
, KeyboardProc
, TerminalProc
,
1179 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, LanguageProc
1181 static char *panelids
[NPANELS
] = {
1182 MAKEINTRESOURCE(IDD_PANEL0
),
1183 MAKEINTRESOURCE(IDD_PANEL1
),
1184 MAKEINTRESOURCE(IDD_PANEL2
),
1185 MAKEINTRESOURCE(IDD_PANEL3
),
1186 MAKEINTRESOURCE(IDD_PANEL35
),
1187 MAKEINTRESOURCE(IDD_PANEL4
),
1188 MAKEINTRESOURCE(IDD_PANEL5
),
1189 MAKEINTRESOURCE(IDD_PANEL6
)
1192 static char *names
[NPANELS
] = {
1193 "Connection", "Keyboard", "Terminal", "Telnet",
1194 "SSH", "Selection", "Colours", "Language"
1197 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1198 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1200 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1201 WPARAM wParam
, LPARAM lParam
,
1202 int npanels
, int *panelnums
, HWND
*page
) {
1207 { /* centre the window */
1210 hw
= GetDesktopWindow();
1211 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1212 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1213 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1214 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1217 { /* initialise the tab control */
1221 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1222 for (i
=0; i
<npanels
; i
++) {
1223 tab
.mask
= TCIF_TEXT
;
1224 tab
.pszText
= names
[panelnums
[i
]];
1225 TabCtrl_InsertItem (hw
, i
, &tab
);
1227 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1228 hwnd, panelproc[panelnums[0]]);*/
1229 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1230 hwnd
, panelproc
[panelnums
[0]]);
1231 SetWindowLong (*page
, GWL_EXSTYLE
,
1232 GetWindowLong (*page
, GWL_EXSTYLE
) |
1233 WS_EX_CONTROLPARENT
);
1238 if (LOWORD(wParam
) == IDC_TAB
&&
1239 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1240 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1242 DestroyWindow (*page
);
1243 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1244 hwnd, panelproc[panelnums[i]]);*/
1245 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1246 hwnd
, panelproc
[panelnums
[i
]]);
1247 SetWindowLong (*page
, GWL_EXSTYLE
,
1248 GetWindowLong (*page
, GWL_EXSTYLE
) |
1249 WS_EX_CONTROLPARENT
);
1250 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1254 /* case WM_CTLCOLORDLG: */
1255 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1257 switch (LOWORD(wParam
)) {
1260 EndDialog (hwnd
, 1);
1265 EndDialog (hwnd
, 0);
1270 EndDialog (hwnd
, 0);
1276 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1277 WPARAM wParam
, LPARAM lParam
) {
1282 static HWND page
= NULL
;
1284 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1287 * If the Connection panel is active and the Session List
1288 * box is selected, we treat a press of Open to have an
1289 * implicit press of Load preceding it.
1291 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1292 i
= TabCtrl_GetCurSel(hw
);
1293 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1294 page
&& implicit_load_ok
) {
1295 SendMessage (page
, WM_COMMAND
,
1296 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1300 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1301 EnableWindow(hwnd
, 0);
1302 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1303 GetParent(hwnd
), AboutProc
);
1304 EnableWindow(hwnd
, 1);
1306 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1307 MAIN_NPANELS
, mainp
, &page
);
1310 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1311 WPARAM wParam
, LPARAM lParam
) {
1313 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1314 RECONF_NPANELS
, reconfp
, &page
);
1317 void get_sesslist(int allocate
) {
1318 static char *buffer
;
1319 int buflen
, bufsize
, i
, ret
;
1320 char otherbuf
[2048];
1325 if (RegCreateKey(HKEY_CURRENT_USER
,
1326 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1329 buflen
= bufsize
= 0;
1333 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1334 if (ret
== ERROR_SUCCESS
) {
1335 bufsize
= buflen
+ 2048;
1336 buffer
= srealloc(buffer
, bufsize
);
1337 unmungestr(otherbuf
, buffer
+buflen
);
1338 buflen
+= strlen(buffer
+buflen
)+1;
1340 } while (ret
== ERROR_SUCCESS
);
1341 buffer
= srealloc(buffer
, buflen
+1);
1342 buffer
[buflen
] = '\0';
1345 nsessions
= 1; /* "Default Settings" counts as one */
1347 if (strcmp(p
, "Default Settings"))
1353 sessions
= smalloc(nsessions
* sizeof(char *));
1354 sessions
[0] = "Default Settings";
1358 if (strcmp(p
, "Default Settings"))
1369 int do_config (void) {
1373 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1374 get_sesslist(FALSE
);
1379 int do_reconfig (HWND hwnd
) {
1383 backup_cfg
= cfg
; /* structure copy */
1384 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1386 cfg
= backup_cfg
; /* structure copy */
1390 void do_defaults (char *session
) {
1392 load_settings (session
, TRUE
);
1394 load_settings ("Default Settings", FALSE
);
1397 void logevent (char *string
) {
1398 if (nevents
>= negsize
) {
1400 events
= srealloc (events
, negsize
* sizeof(*events
));
1402 events
[nevents
] = smalloc(1+strlen(string
));
1403 strcpy (events
[nevents
], string
);
1406 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1410 void showeventlog (HWND hwnd
) {
1412 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1414 ShowWindow (logbox
, SW_SHOWNORMAL
);
1418 void showabout (HWND hwnd
) {
1420 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1422 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1426 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1427 char *keystr
, *otherstr
, *mungedhost
;
1432 * Format the key into a string.
1434 len
= rsastr_len(key
);
1435 keystr
= malloc(len
);
1437 fatalbox("Out of memory");
1438 rsastr_fmt(keystr
, key
);
1441 * Now read a saved key in from the registry and see what it
1444 otherstr
= malloc(len
);
1445 mungedhost
= malloc(3*strlen(host
)+1);
1446 if (!otherstr
|| !mungedhost
)
1447 fatalbox("Out of memory");
1449 mungestr(host
, mungedhost
);
1451 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1452 &rkey
) != ERROR_SUCCESS
) {
1453 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1454 "in the registry. There is thus no way to tell\n"
1455 "if the remote host is what you think it is.\n"
1456 "Connect anyway?", "PuTTY Problem",
1457 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1460 DWORD readlen
= len
;
1464 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1465 &type
, otherstr
, &readlen
);
1467 if (ret
== ERROR_MORE_DATA
||
1468 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1469 strcmp(otherstr
, keystr
))) {
1470 if (MessageBox(NULL
,
1471 "This host's host key is different from the\n"
1472 "one cached in the registry! Someone may be\n"
1473 "impersonating this host for malicious reasons;\n"
1474 "alternatively, the host key may have changed\n"
1475 "due to sloppy system administration.\n"
1476 "Replace key in registry and connect?",
1477 "PuTTY: Security Warning",
1478 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1480 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1482 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1483 if (MessageBox(NULL
,
1484 "This host's host key is not cached in the\n"
1485 "registry. Do you want to add it to the cache\n"
1486 "and carry on connecting?",
1488 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1490 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,