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
, "88592Xlat", cfg
.xlat_88592w1250
);
196 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
198 RegCloseKey(sesskey
);
201 static void del_session (char *section
) {
205 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
208 p
= malloc(3*strlen(section
)+1);
209 mungestr(section
, p
);
210 RegDeleteKey(subkey1
, p
);
213 RegCloseKey(subkey1
);
216 static void load_settings (char *section
, int do_host
) {
218 HKEY subkey1
, sesskey
;
222 p
= malloc(3*strlen(section
)+1);
223 mungestr(section
, p
);
225 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
228 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
231 RegCloseKey(subkey1
);
236 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
237 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
238 gpps (sesskey
, "Protocol", "default", prot
, 10);
239 if (!strcmp(prot
, "ssh"))
240 cfg
.protocol
= PROT_SSH
;
241 else if (!strcmp(prot
, "telnet"))
242 cfg
.protocol
= PROT_TELNET
;
243 else if (!strcmp(prot
, "raw"))
244 cfg
.protocol
= PROT_RAW
;
246 cfg
.protocol
= default_protocol
;
248 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
249 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
250 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
251 sizeof(cfg
.termtype
));
252 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
253 sizeof(cfg
.termspeed
));
255 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
256 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
260 while (*p
&& *p
!= ',') {
273 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
274 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
277 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
278 if (!strcmp(cipher
, "blowfish"))
279 cfg
.cipher
= CIPHER_BLOWFISH
;
280 else if (!strcmp(cipher
, "des"))
281 cfg
.cipher
= CIPHER_DES
;
283 cfg
.cipher
= CIPHER_3DES
;
285 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
286 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
287 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
288 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
289 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
290 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
291 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
292 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
293 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
294 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
295 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
296 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
297 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
298 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
299 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
300 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
301 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
302 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
303 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
304 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
305 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
306 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
307 gppi (sesskey
, "FontVTMode", VT_POORMAN
, (int *)&cfg
.vtmode
);
308 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
309 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
310 for (i
=0; i
<22; i
++) {
311 static char *defaults
[] = {
312 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
313 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
314 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
315 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
316 "85,255,255", "187,187,187", "255,255,255"
318 char buf
[20], buf2
[30];
320 sprintf(buf
, "Colour%d", i
);
321 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
322 if(sscanf(buf2
, "%d,%d,%d", &c0
, &c1
, &c2
) == 3) {
323 cfg
.colours
[i
][0] = c0
;
324 cfg
.colours
[i
][1] = c1
;
325 cfg
.colours
[i
][2] = c2
;
328 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
329 for (i
=0; i
<256; i
+=32) {
330 static char *defaults
[] = {
331 "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",
332 "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",
333 "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",
334 "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",
335 "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",
336 "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",
337 "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",
338 "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"
340 char buf
[20], buf2
[256], *p
;
342 sprintf(buf
, "Wordness%d", i
);
343 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
345 for (j
=i
; j
<i
+32; j
++) {
347 while (*p
&& *p
!= ',') p
++;
348 if (*p
== ',') *p
++ = '\0';
349 cfg
.wordness
[j
] = atoi(q
);
352 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
353 gppi (sesskey
, "88592Xlat", 0, &cfg
.xlat_88592w1250
);
354 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
356 RegCloseKey(sesskey
);
359 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
362 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
367 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
368 WPARAM wParam
, LPARAM lParam
) {
373 for (i
=0; i
<nevents
; i
++)
374 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
375 0, (LPARAM
)events
[i
]);
377 /* case WM_CTLCOLORDLG: */
378 /* return (int) GetStockObject (LTGRAY_BRUSH); */
380 switch (LOWORD(wParam
)) {
383 DestroyWindow (hwnd
);
389 DestroyWindow (hwnd
);
395 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
396 WPARAM wParam
, LPARAM lParam
) {
401 switch (LOWORD(wParam
)) {
404 DestroyWindow (hwnd
);
410 DestroyWindow (hwnd
);
416 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
417 WPARAM wParam
, LPARAM lParam
) {
420 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
422 /* case WM_CTLCOLORDLG: */
423 /* return (int) GetStockObject (LTGRAY_BRUSH); */
424 /* case WM_CTLCOLORSTATIC: */
425 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
426 /* return (int) GetStockObject (LTGRAY_BRUSH); */
428 switch (LOWORD(wParam
)) {
431 DestroyWindow (hwnd
);
434 EnableWindow(hwnd
, 0);
435 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
437 EnableWindow(hwnd
, 1);
443 DestroyWindow (hwnd
);
449 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
450 WPARAM wParam
, LPARAM lParam
) {
453 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
455 /* case WM_CTLCOLORDLG: */
456 /* return (int) GetStockObject (LTGRAY_BRUSH); */
457 /* case WM_CTLCOLORSTATIC: */
458 /* case WM_CTLCOLORBTN: */
459 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
460 /* return (int) GetStockObject (LTGRAY_BRUSH); */
462 DestroyWindow (hwnd
);
468 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
469 WPARAM wParam
, LPARAM lParam
) {
474 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
475 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
476 for (i
= 0; i
< nsessions
; i
++)
477 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
478 0, (LPARAM
) (sessions
[i
]));
479 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
480 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
481 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
482 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
483 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
487 * Button release should trigger WM_OK if there was a
488 * previous double click on the session list.
492 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
495 switch (LOWORD(wParam
)) {
496 case IDC0_PROTTELNET
:
499 if (HIWORD(wParam
) == BN_CLICKED
||
500 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
501 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
502 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
503 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
504 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
505 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
506 cfg
.port
= i ?
22 : 23;
507 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
512 if (HIWORD(wParam
) == EN_CHANGE
)
513 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
517 if (HIWORD(wParam
) == EN_CHANGE
)
518 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
521 if (HIWORD(wParam
) == BN_CLICKED
||
522 HIWORD(wParam
) == BN_DOUBLECLICKED
)
523 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
526 if (HIWORD(wParam
) == BN_CLICKED
||
527 HIWORD(wParam
) == BN_DOUBLECLICKED
)
528 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
531 if (HIWORD(wParam
) == EN_CHANGE
)
532 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
536 if (HIWORD(wParam
) == BN_CLICKED
||
537 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
542 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
544 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
550 strcpy (str
, sessions
[n
]);
552 save_settings (str
, !!strcmp(str
, "Default Settings"));
553 get_sesslist (FALSE
);
555 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
557 for (i
= 0; i
< nsessions
; i
++)
558 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
559 0, (LPARAM
) (sessions
[i
]));
560 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
566 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
567 HIWORD(wParam
) != BN_CLICKED
&&
568 HIWORD(wParam
) != BN_DOUBLECLICKED
)
570 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
571 HIWORD(wParam
) != LBN_DBLCLK
)
574 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
580 load_settings (sessions
[n
],
581 !!strcmp(sessions
[n
], "Default Settings"));
582 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
583 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
584 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
585 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
586 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
587 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
588 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
589 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
592 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
594 * A double-click on a saved session should
595 * actually start the session, not just load it.
596 * Unless it's Default Settings or some other
597 * host-less set of saved settings.
606 if (HIWORD(wParam
) == BN_CLICKED
||
607 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
608 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
610 if (n
== LB_ERR
|| n
== 0) {
614 del_session(sessions
[n
]);
615 get_sesslist (FALSE
);
617 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
619 for (i
= 0; i
< nsessions
; i
++)
620 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
621 0, (LPARAM
) (sessions
[i
]));
622 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
627 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
630 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
631 WPARAM wParam
, LPARAM lParam
) {
634 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
635 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
636 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
637 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
638 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
639 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
640 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
641 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
642 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
643 cfg
.nethack_keypad ? IDC1_KPNH
:
644 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
645 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
646 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
647 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
650 if (HIWORD(wParam
) == BN_CLICKED
||
651 HIWORD(wParam
) == BN_DOUBLECLICKED
)
652 switch (LOWORD(wParam
)) {
655 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
659 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
663 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
667 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
668 cfg
.nethack_keypad
= FALSE
;
671 cfg
.app_keypad
= FALSE
;
672 cfg
.nethack_keypad
= TRUE
;
676 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
679 if (HIWORD(wParam
) == BN_CLICKED
||
680 HIWORD(wParam
) == BN_DOUBLECLICKED
)
681 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
684 if (HIWORD(wParam
) == BN_CLICKED
||
685 HIWORD(wParam
) == BN_DOUBLECLICKED
)
686 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
689 if (HIWORD(wParam
) == BN_CLICKED
||
690 HIWORD(wParam
) == BN_DOUBLECLICKED
)
691 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
695 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
698 static void fmtfont (char *buf
) {
699 sprintf (buf
, "Font: %s, ", cfg
.font
);
701 strcat(buf
, "bold, ");
702 if (cfg
.fontheight
== 0)
703 strcat (buf
, "default height");
705 sprintf (buf
+strlen(buf
), "%d-%s",
706 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
707 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
710 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
711 WPARAM wParam
, LPARAM lParam
) {
714 char fontstatic
[256];
718 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
719 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
720 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
721 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
722 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
723 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
724 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
725 fmtfont (fontstatic
);
726 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
727 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
728 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
729 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
730 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
734 switch (LOWORD(wParam
)) {
736 if (HIWORD(wParam
) == BN_CLICKED
||
737 HIWORD(wParam
) == BN_DOUBLECLICKED
)
738 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
741 if (HIWORD(wParam
) == BN_CLICKED
||
742 HIWORD(wParam
) == BN_DOUBLECLICKED
)
743 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
746 if (HIWORD(wParam
) == BN_CLICKED
||
747 HIWORD(wParam
) == BN_DOUBLECLICKED
)
748 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
751 if (HIWORD(wParam
) == BN_CLICKED
||
752 HIWORD(wParam
) == BN_DOUBLECLICKED
)
753 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
756 if (HIWORD(wParam
) == EN_CHANGE
)
757 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
760 if (HIWORD(wParam
) == EN_CHANGE
)
761 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
764 if (HIWORD(wParam
) == EN_CHANGE
)
765 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
767 case IDC2_CHOOSEFONT
:
768 lf
.lfHeight
= cfg
.fontheight
;
769 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
770 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
771 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
772 lf
.lfCharSet
= cfg
.fontcharset
;
773 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
774 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
775 lf
.lfQuality
= DEFAULT_QUALITY
;
776 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
777 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
778 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
780 cf
.lStructSize
= sizeof(cf
);
783 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
784 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
786 if (ChooseFont (&cf
)) {
787 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
788 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
789 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
790 cfg
.fontcharset
= lf
.lfCharSet
;
791 cfg
.fontheight
= lf
.lfHeight
;
792 fmtfont (fontstatic
);
793 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
796 case IDC2_VTXWINDOWS
:
801 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
802 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
803 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
809 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
812 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
813 WPARAM wParam
, LPARAM lParam
) {
818 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
819 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
820 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
822 char *p
= cfg
.environmt
;
824 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
829 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
830 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
833 switch (LOWORD(wParam
)) {
835 if (HIWORD(wParam
) == EN_CHANGE
)
836 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
837 sizeof(cfg
.termtype
)-1);
840 if (HIWORD(wParam
) == EN_CHANGE
)
841 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
842 sizeof(cfg
.termspeed
)-1);
845 if (HIWORD(wParam
) == EN_CHANGE
)
846 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
847 sizeof(cfg
.username
)-1);
851 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
854 if (HIWORD(wParam
) == BN_CLICKED
||
855 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
856 char str
[sizeof(cfg
.environmt
)];
858 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
863 p
= str
+ strlen(str
);
865 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
875 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
877 p
[strlen(str
)+1] = '\0';
878 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
880 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
881 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
883 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
884 MB_OK
| MB_ICONERROR
);
889 if (HIWORD(wParam
) != BN_CLICKED
&&
890 HIWORD(wParam
) != BN_DOUBLECLICKED
)
892 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
898 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
925 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
928 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
929 WPARAM wParam
, LPARAM lParam
) {
932 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
933 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
934 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
935 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
936 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
937 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
940 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
943 switch (LOWORD(wParam
)) {
945 if (HIWORD(wParam
) == EN_CHANGE
)
946 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
947 sizeof(cfg
.termtype
)-1);
950 if (HIWORD(wParam
) == EN_CHANGE
)
951 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
952 sizeof(cfg
.username
)-1);
955 if (HIWORD(wParam
) == BN_CLICKED
||
956 HIWORD(wParam
) == BN_DOUBLECLICKED
)
957 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
959 case IDC3_CIPHER3DES
:
960 case IDC3_CIPHERBLOWF
:
962 if (HIWORD(wParam
) == BN_CLICKED
||
963 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
964 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
965 cfg
.cipher
= CIPHER_3DES
;
966 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
967 cfg
.cipher
= CIPHER_BLOWFISH
;
968 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
969 cfg
.cipher
= CIPHER_DES
;
973 if (HIWORD(wParam
) == BN_CLICKED
||
974 HIWORD(wParam
) == BN_DOUBLECLICKED
)
975 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
980 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
983 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
984 WPARAM wParam
, LPARAM lParam
) {
989 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
990 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
992 static int tabs
[4] = {25, 61, 96, 128};
993 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
996 for (i
=0; i
<256; i
++) {
998 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
999 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1001 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1006 switch (LOWORD(wParam
)) {
1007 case IDC4_MBWINDOWS
:
1009 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1015 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1020 for (i
=0; i
<256; i
++)
1021 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1024 cfg
.wordness
[i
] = n
;
1025 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1026 LB_DELETESTRING
, i
, 0);
1027 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1028 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1030 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1040 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1043 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1044 WPARAM wParam
, LPARAM lParam
) {
1045 static const char *const colours
[] = {
1046 "Default Foreground", "Default Bold Foreground",
1047 "Default Background", "Default Bold Background",
1048 "Cursor Text", "Cursor Colour",
1049 "ANSI Black", "ANSI Black Bold",
1050 "ANSI Red", "ANSI Red Bold",
1051 "ANSI Green", "ANSI Green Bold",
1052 "ANSI Yellow", "ANSI Yellow Bold",
1053 "ANSI Blue", "ANSI Blue Bold",
1054 "ANSI Magenta", "ANSI Magenta Bold",
1055 "ANSI Cyan", "ANSI Cyan Bold",
1056 "ANSI White", "ANSI White Bold"
1058 static const int permanent
[] = {
1059 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1060 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1061 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1065 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1066 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1069 for (i
=0; i
<22; i
++)
1070 if (cfg
.bold_colour
|| permanent
[i
])
1071 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1072 (LPARAM
) colours
[i
]);
1074 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1075 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1076 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1077 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1080 switch (LOWORD(wParam
)) {
1081 case IDC5_BOLDCOLOUR
:
1082 if (HIWORD(wParam
) == BN_CLICKED
||
1083 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1085 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1086 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1087 if (cfg
.bold_colour
&& n
!=22) {
1088 for (i
=0; i
<22; i
++)
1090 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1092 (LPARAM
) colours
[i
]);
1093 } else if (!cfg
.bold_colour
&& n
!=12) {
1096 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1097 LB_DELETESTRING
, i
, 0);
1102 if (HIWORD(wParam
) == BN_CLICKED
||
1103 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1104 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1107 if (HIWORD(wParam
) == LBN_DBLCLK
||
1108 HIWORD(wParam
) == LBN_SELCHANGE
) {
1109 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1111 if (!cfg
.bold_colour
)
1112 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1113 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1114 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1115 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1119 if (HIWORD(wParam
) == BN_CLICKED
||
1120 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1121 static CHOOSECOLOR cc
;
1122 static DWORD custom
[16] = {0}; /* zero initialisers */
1123 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1125 if (!cfg
.bold_colour
)
1126 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1127 cc
.lStructSize
= sizeof(cc
);
1128 cc
.hwndOwner
= hwnd
;
1129 cc
.hInstance
= (HWND
)hinst
;
1130 cc
.lpCustColors
= custom
;
1131 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1133 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1134 if (ChooseColor(&cc
)) {
1136 (unsigned char) (cc
.rgbResult
& 0xFF);
1138 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1140 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1141 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1143 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1145 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1153 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1156 static int CALLBACK
LanguageProc (HWND hwnd
, UINT msg
,
1157 WPARAM wParam
, LPARAM lParam
) {
1160 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1161 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1162 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1164 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1166 switch (LOWORD(wParam
)) {
1168 case IDC6_KOI8WIN1251
:
1169 case IDC6_88592WIN1250
:
1170 cfg
.xlat_enablekoiwin
=
1171 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1172 cfg
.xlat_88592w1250
=
1173 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1175 case IDC6_CAPSLOCKCYR
:
1176 if (HIWORD(wParam
) == BN_CLICKED
||
1177 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1178 cfg
.xlat_capslockcyr
=
1179 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1184 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1187 static DLGPROC panelproc
[NPANELS
] = {
1188 ConnectionProc
, KeyboardProc
, TerminalProc
,
1189 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, LanguageProc
1191 static char *panelids
[NPANELS
] = {
1192 MAKEINTRESOURCE(IDD_PANEL0
),
1193 MAKEINTRESOURCE(IDD_PANEL1
),
1194 MAKEINTRESOURCE(IDD_PANEL2
),
1195 MAKEINTRESOURCE(IDD_PANEL3
),
1196 MAKEINTRESOURCE(IDD_PANEL35
),
1197 MAKEINTRESOURCE(IDD_PANEL4
),
1198 MAKEINTRESOURCE(IDD_PANEL5
),
1199 MAKEINTRESOURCE(IDD_PANEL6
)
1202 static char *names
[NPANELS
] = {
1203 "Connection", "Keyboard", "Terminal", "Telnet",
1204 "SSH", "Selection", "Colours", "Language"
1207 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1208 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1210 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1211 WPARAM wParam
, LPARAM lParam
,
1212 int npanels
, int *panelnums
, HWND
*page
) {
1217 { /* centre the window */
1220 hw
= GetDesktopWindow();
1221 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1222 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1223 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1224 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1227 { /* initialise the tab control */
1231 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1232 for (i
=0; i
<npanels
; i
++) {
1233 tab
.mask
= TCIF_TEXT
;
1234 tab
.pszText
= names
[panelnums
[i
]];
1235 TabCtrl_InsertItem (hw
, i
, &tab
);
1237 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1238 hwnd, panelproc[panelnums[0]]);*/
1239 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1240 hwnd
, panelproc
[panelnums
[0]]);
1241 SetWindowLong (*page
, GWL_EXSTYLE
,
1242 GetWindowLong (*page
, GWL_EXSTYLE
) |
1243 WS_EX_CONTROLPARENT
);
1248 if (LOWORD(wParam
) == IDC_TAB
&&
1249 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1250 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1252 DestroyWindow (*page
);
1253 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1254 hwnd, panelproc[panelnums[i]]);*/
1255 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1256 hwnd
, panelproc
[panelnums
[i
]]);
1257 SetWindowLong (*page
, GWL_EXSTYLE
,
1258 GetWindowLong (*page
, GWL_EXSTYLE
) |
1259 WS_EX_CONTROLPARENT
);
1260 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1264 /* case WM_CTLCOLORDLG: */
1265 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1267 switch (LOWORD(wParam
)) {
1270 EndDialog (hwnd
, 1);
1275 EndDialog (hwnd
, 0);
1280 EndDialog (hwnd
, 0);
1286 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1287 WPARAM wParam
, LPARAM lParam
) {
1292 static HWND page
= NULL
;
1294 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1297 * If the Connection panel is active and the Session List
1298 * box is selected, we treat a press of Open to have an
1299 * implicit press of Load preceding it.
1301 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1302 i
= TabCtrl_GetCurSel(hw
);
1303 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1304 page
&& implicit_load_ok
) {
1305 SendMessage (page
, WM_COMMAND
,
1306 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1310 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1311 EnableWindow(hwnd
, 0);
1312 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1313 GetParent(hwnd
), AboutProc
);
1314 EnableWindow(hwnd
, 1);
1316 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1317 MAIN_NPANELS
, mainp
, &page
);
1320 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1321 WPARAM wParam
, LPARAM lParam
) {
1323 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1324 RECONF_NPANELS
, reconfp
, &page
);
1327 void get_sesslist(int allocate
) {
1328 static char *buffer
;
1329 int buflen
, bufsize
, i
, ret
;
1330 char otherbuf
[2048];
1335 if (RegCreateKey(HKEY_CURRENT_USER
,
1336 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1339 buflen
= bufsize
= 0;
1343 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1344 if (ret
== ERROR_SUCCESS
) {
1345 bufsize
= buflen
+ 2048;
1346 buffer
= srealloc(buffer
, bufsize
);
1347 unmungestr(otherbuf
, buffer
+buflen
);
1348 buflen
+= strlen(buffer
+buflen
)+1;
1350 } while (ret
== ERROR_SUCCESS
);
1351 buffer
= srealloc(buffer
, buflen
+1);
1352 buffer
[buflen
] = '\0';
1355 nsessions
= 1; /* "Default Settings" counts as one */
1357 if (strcmp(p
, "Default Settings"))
1363 sessions
= smalloc(nsessions
* sizeof(char *));
1364 sessions
[0] = "Default Settings";
1368 if (strcmp(p
, "Default Settings"))
1379 int do_config (void) {
1383 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1384 get_sesslist(FALSE
);
1389 int do_reconfig (HWND hwnd
) {
1393 backup_cfg
= cfg
; /* structure copy */
1394 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1396 cfg
= backup_cfg
; /* structure copy */
1400 void do_defaults (char *session
) {
1402 load_settings (session
, TRUE
);
1404 load_settings ("Default Settings", FALSE
);
1407 void logevent (char *string
) {
1408 if (nevents
>= negsize
) {
1410 events
= srealloc (events
, negsize
* sizeof(*events
));
1412 events
[nevents
] = smalloc(1+strlen(string
));
1413 strcpy (events
[nevents
], string
);
1416 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1420 void showeventlog (HWND hwnd
) {
1422 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1424 ShowWindow (logbox
, SW_SHOWNORMAL
);
1428 void showabout (HWND hwnd
) {
1430 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1432 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1436 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1437 char *keystr
, *otherstr
, *mungedhost
;
1442 * Format the key into a string.
1444 len
= rsastr_len(key
);
1445 keystr
= malloc(len
);
1447 fatalbox("Out of memory");
1448 rsastr_fmt(keystr
, key
);
1451 * Now read a saved key in from the registry and see what it
1454 otherstr
= malloc(len
);
1455 mungedhost
= malloc(3*strlen(host
)+1);
1456 if (!otherstr
|| !mungedhost
)
1457 fatalbox("Out of memory");
1459 mungestr(host
, mungedhost
);
1461 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1462 &rkey
) != ERROR_SUCCESS
) {
1463 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1464 "in the registry. There is thus no way to tell\n"
1465 "if the remote host is what you think it is.\n"
1466 "Connect anyway?", "PuTTY Problem",
1467 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1470 DWORD readlen
= len
;
1474 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1475 &type
, otherstr
, &readlen
);
1477 if (ret
== ERROR_MORE_DATA
||
1478 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1479 strcmp(otherstr
, keystr
))) {
1480 if (MessageBox(NULL
,
1481 "This host's host key is different from the\n"
1482 "one cached in the registry! Someone may be\n"
1483 "impersonating this host for malicious reasons;\n"
1484 "alternatively, the host key may have changed\n"
1485 "due to sloppy system administration.\n"
1486 "Replace key in registry and connect?",
1487 "PuTTY: Security Warning",
1488 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1490 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1492 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1493 if (MessageBox(NULL
,
1494 "This host's host key is not cached in the\n"
1495 "registry. Do you want to add it to the cache\n"
1496 "and carry on connecting?",
1498 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1500 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,