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
, "ScrollbackLines", cfg
.savelines
);
161 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
162 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
163 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
164 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
165 wppi (sesskey
, "TermWidth", cfg
.width
);
166 wppi (sesskey
, "TermHeight", cfg
.height
);
167 wpps (sesskey
, "Font", cfg
.font
);
168 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
169 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
170 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
171 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
172 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
173 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
174 for (i
=0; i
<22; i
++) {
175 char buf
[20], buf2
[30];
176 sprintf(buf
, "Colour%d", i
);
177 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
178 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
179 wpps (sesskey
, buf
, buf2
);
181 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
182 for (i
=0; i
<256; i
+=32) {
183 char buf
[20], buf2
[256];
185 sprintf(buf
, "Wordness%d", i
);
187 for (j
=i
; j
<i
+32; j
++) {
188 sprintf(buf2
+strlen(buf2
), "%s%d",
189 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
191 wpps (sesskey
, buf
, buf2
);
193 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
194 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
196 RegCloseKey(sesskey
);
199 static void del_session (char *section
) {
203 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
206 p
= malloc(3*strlen(section
)+1);
207 mungestr(section
, p
);
208 RegDeleteKey(subkey1
, p
);
211 RegCloseKey(subkey1
);
214 static void load_settings (char *section
, int do_host
) {
216 HKEY subkey1
, sesskey
;
220 p
= malloc(3*strlen(section
)+1);
221 mungestr(section
, p
);
223 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
226 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
229 RegCloseKey(subkey1
);
234 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
235 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
236 gpps (sesskey
, "Protocol", "default", prot
, 10);
237 if (!strcmp(prot
, "ssh"))
238 cfg
.protocol
= PROT_SSH
;
239 else if (!strcmp(prot
, "telnet"))
240 cfg
.protocol
= PROT_TELNET
;
241 else if (!strcmp(prot
, "raw"))
242 cfg
.protocol
= PROT_RAW
;
244 cfg
.protocol
= default_protocol
;
246 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
247 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
248 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
249 sizeof(cfg
.termtype
));
250 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
251 sizeof(cfg
.termspeed
));
253 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
254 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
258 while (*p
&& *p
!= ',') {
271 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
272 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
275 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
276 if (!strcmp(cipher
, "blowfish"))
277 cfg
.cipher
= CIPHER_BLOWFISH
;
278 else if (!strcmp(cipher
, "des"))
279 cfg
.cipher
= CIPHER_DES
;
281 cfg
.cipher
= CIPHER_3DES
;
283 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
284 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
285 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
286 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
287 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.linux_funkeys
);
288 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
289 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
290 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
291 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
292 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
293 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
294 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
295 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
296 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
297 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
298 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
299 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
300 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
301 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
302 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
303 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
304 gppi (sesskey
, "FontVTMode", VT_POORMAN
, &cfg
.vtmode
);
305 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
306 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
307 for (i
=0; i
<22; i
++) {
308 static char *defaults
[] = {
309 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
310 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
311 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
312 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
313 "85,255,255", "187,187,187", "255,255,255"
315 char buf
[20], buf2
[30];
316 sprintf(buf
, "Colour%d", i
);
317 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
318 sscanf(buf2
, "%d,%d,%d", &cfg
.colours
[i
][0],
319 &cfg
.colours
[i
][1], &cfg
.colours
[i
][2]);
321 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
322 for (i
=0; i
<256; i
+=32) {
323 static char *defaults
[] = {
324 "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",
325 "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",
326 "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",
327 "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",
328 "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",
329 "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",
330 "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",
331 "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 char buf
[20], buf2
[256], *p
;
335 sprintf(buf
, "Wordness%d", i
);
336 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
338 for (j
=i
; j
<i
+32; j
++) {
340 while (*p
&& *p
!= ',') p
++;
341 if (*p
== ',') *p
++ = '\0';
342 cfg
.wordness
[j
] = atoi(q
);
345 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
346 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
348 RegCloseKey(sesskey
);
351 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
354 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
359 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
360 WPARAM wParam
, LPARAM lParam
) {
365 for (i
=0; i
<nevents
; i
++)
366 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
367 0, (LPARAM
)events
[i
]);
369 /* case WM_CTLCOLORDLG: */
370 /* return (int) GetStockObject (LTGRAY_BRUSH); */
372 switch (LOWORD(wParam
)) {
375 DestroyWindow (hwnd
);
381 DestroyWindow (hwnd
);
387 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
388 WPARAM wParam
, LPARAM lParam
) {
393 switch (LOWORD(wParam
)) {
396 DestroyWindow (hwnd
);
402 DestroyWindow (hwnd
);
408 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
409 WPARAM wParam
, LPARAM lParam
) {
412 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
414 /* case WM_CTLCOLORDLG: */
415 /* return (int) GetStockObject (LTGRAY_BRUSH); */
416 /* case WM_CTLCOLORSTATIC: */
417 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
418 /* return (int) GetStockObject (LTGRAY_BRUSH); */
420 switch (LOWORD(wParam
)) {
423 DestroyWindow (hwnd
);
426 EnableWindow(hwnd
, 0);
427 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
429 EnableWindow(hwnd
, 1);
435 DestroyWindow (hwnd
);
441 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
442 WPARAM wParam
, LPARAM lParam
) {
445 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
447 /* case WM_CTLCOLORDLG: */
448 /* return (int) GetStockObject (LTGRAY_BRUSH); */
449 /* case WM_CTLCOLORSTATIC: */
450 /* case WM_CTLCOLORBTN: */
451 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
452 /* return (int) GetStockObject (LTGRAY_BRUSH); */
454 DestroyWindow (hwnd
);
460 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
461 WPARAM wParam
, LPARAM lParam
) {
466 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
467 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
468 for (i
= 0; i
< nsessions
; i
++)
469 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
470 0, (LPARAM
) (sessions
[i
]));
471 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
472 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
473 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
474 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
475 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
479 * Button release should trigger WM_OK if there was a
480 * previous double click on the session list.
484 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
487 switch (LOWORD(wParam
)) {
488 case IDC0_PROTTELNET
:
491 if (HIWORD(wParam
) == BN_CLICKED
||
492 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
493 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
494 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
495 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
496 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
497 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
498 cfg
.port
= i ?
22 : 23;
499 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
504 if (HIWORD(wParam
) == EN_CHANGE
)
505 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
509 if (HIWORD(wParam
) == EN_CHANGE
)
510 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
513 if (HIWORD(wParam
) == BN_CLICKED
||
514 HIWORD(wParam
) == BN_DOUBLECLICKED
)
515 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
518 if (HIWORD(wParam
) == BN_CLICKED
||
519 HIWORD(wParam
) == BN_DOUBLECLICKED
)
520 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
523 if (HIWORD(wParam
) == EN_CHANGE
)
524 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
528 if (HIWORD(wParam
) == BN_CLICKED
||
529 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
534 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
536 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
542 strcpy (str
, sessions
[n
]);
544 save_settings (str
, !!strcmp(str
, "Default Settings"));
545 get_sesslist (FALSE
);
547 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
549 for (i
= 0; i
< nsessions
; i
++)
550 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
551 0, (LPARAM
) (sessions
[i
]));
552 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
558 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
559 HIWORD(wParam
) != BN_CLICKED
&&
560 HIWORD(wParam
) != BN_DOUBLECLICKED
)
562 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
563 HIWORD(wParam
) != LBN_DBLCLK
)
566 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
572 load_settings (sessions
[n
],
573 !!strcmp(sessions
[n
], "Default Settings"));
574 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
575 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
576 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
577 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
578 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
579 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
580 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
581 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
584 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
586 * A double-click on a saved session should
587 * actually start the session, not just load it.
588 * Unless it's Default Settings or some other
589 * host-less set of saved settings.
598 if (HIWORD(wParam
) == BN_CLICKED
||
599 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
600 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
602 if (n
== LB_ERR
|| n
== 0) {
606 del_session(sessions
[n
]);
607 get_sesslist (FALSE
);
609 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
611 for (i
= 0; i
< nsessions
; i
++)
612 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
613 0, (LPARAM
) (sessions
[i
]));
614 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
619 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
622 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
623 WPARAM wParam
, LPARAM lParam
) {
626 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
627 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
628 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
629 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
630 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCLINUX
,
631 cfg
.linux_funkeys ? IDC1_FUNCLINUX
: IDC1_FUNCTILDE
);
632 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
633 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
634 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
635 cfg
.nethack_keypad ? IDC1_KPNH
:
636 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
637 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
638 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
641 if (HIWORD(wParam
) == BN_CLICKED
||
642 HIWORD(wParam
) == BN_DOUBLECLICKED
)
643 switch (LOWORD(wParam
)) {
646 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
650 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
654 cfg
.linux_funkeys
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
658 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
659 cfg
.nethack_keypad
= FALSE
;
662 cfg
.app_keypad
= FALSE
;
663 cfg
.nethack_keypad
= TRUE
;
667 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
670 if (HIWORD(wParam
) == BN_CLICKED
||
671 HIWORD(wParam
) == BN_DOUBLECLICKED
)
672 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
675 if (HIWORD(wParam
) == BN_CLICKED
||
676 HIWORD(wParam
) == BN_DOUBLECLICKED
)
677 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
681 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
684 static void fmtfont (char *buf
) {
685 sprintf (buf
, "Font: %s, ", cfg
.font
);
687 strcat(buf
, "bold, ");
688 if (cfg
.fontheight
== 0)
689 strcat (buf
, "default height");
691 sprintf (buf
+strlen(buf
), "%d-%s",
692 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
693 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
696 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
697 WPARAM wParam
, LPARAM lParam
) {
700 char fontstatic
[256];
704 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
705 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
706 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
707 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
708 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
709 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
710 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
711 fmtfont (fontstatic
);
712 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
713 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
714 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
715 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
716 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
720 switch (LOWORD(wParam
)) {
722 if (HIWORD(wParam
) == BN_CLICKED
||
723 HIWORD(wParam
) == BN_DOUBLECLICKED
)
724 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
727 if (HIWORD(wParam
) == BN_CLICKED
||
728 HIWORD(wParam
) == BN_DOUBLECLICKED
)
729 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
732 if (HIWORD(wParam
) == BN_CLICKED
||
733 HIWORD(wParam
) == BN_DOUBLECLICKED
)
734 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
737 if (HIWORD(wParam
) == BN_CLICKED
||
738 HIWORD(wParam
) == BN_DOUBLECLICKED
)
739 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
742 if (HIWORD(wParam
) == EN_CHANGE
)
743 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
746 if (HIWORD(wParam
) == EN_CHANGE
)
747 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
750 if (HIWORD(wParam
) == EN_CHANGE
)
751 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
753 case IDC2_CHOOSEFONT
:
754 lf
.lfHeight
= cfg
.fontheight
;
755 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
756 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
757 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
758 lf
.lfCharSet
= cfg
.fontcharset
;
759 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
760 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
761 lf
.lfQuality
= DEFAULT_QUALITY
;
762 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
763 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
764 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
766 cf
.lStructSize
= sizeof(cf
);
769 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
770 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
772 if (ChooseFont (&cf
)) {
773 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
774 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
775 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
776 cfg
.fontcharset
= lf
.lfCharSet
;
777 cfg
.fontheight
= lf
.lfHeight
;
778 fmtfont (fontstatic
);
779 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
782 case IDC2_VTXWINDOWS
:
787 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
788 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
789 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
795 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
798 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
799 WPARAM wParam
, LPARAM lParam
) {
804 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
805 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
806 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
808 char *p
= cfg
.environmt
;
810 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
815 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
816 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
819 switch (LOWORD(wParam
)) {
821 if (HIWORD(wParam
) == EN_CHANGE
)
822 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
823 sizeof(cfg
.termtype
)-1);
826 if (HIWORD(wParam
) == EN_CHANGE
)
827 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
828 sizeof(cfg
.termspeed
)-1);
831 if (HIWORD(wParam
) == EN_CHANGE
)
832 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
833 sizeof(cfg
.username
)-1);
837 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
840 if (HIWORD(wParam
) == BN_CLICKED
||
841 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
842 char str
[sizeof(cfg
.environmt
)];
844 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
849 p
= str
+ strlen(str
);
851 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
861 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
863 p
[strlen(str
)+1] = '\0';
864 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
866 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
867 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
869 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
870 MB_OK
| MB_ICONERROR
);
875 if (HIWORD(wParam
) != BN_CLICKED
&&
876 HIWORD(wParam
) != BN_DOUBLECLICKED
)
878 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
884 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
911 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
914 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
915 WPARAM wParam
, LPARAM lParam
) {
918 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
919 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
920 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
921 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
922 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
923 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
926 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
929 switch (LOWORD(wParam
)) {
931 if (HIWORD(wParam
) == EN_CHANGE
)
932 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
933 sizeof(cfg
.termtype
)-1);
936 if (HIWORD(wParam
) == EN_CHANGE
)
937 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
938 sizeof(cfg
.username
)-1);
941 if (HIWORD(wParam
) == BN_CLICKED
||
942 HIWORD(wParam
) == BN_DOUBLECLICKED
)
943 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
945 case IDC3_CIPHER3DES
:
946 case IDC3_CIPHERBLOWF
:
948 if (HIWORD(wParam
) == BN_CLICKED
||
949 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
950 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
951 cfg
.cipher
= CIPHER_3DES
;
952 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
953 cfg
.cipher
= CIPHER_BLOWFISH
;
954 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
955 cfg
.cipher
= CIPHER_DES
;
959 if (HIWORD(wParam
) == BN_CLICKED
||
960 HIWORD(wParam
) == BN_DOUBLECLICKED
)
961 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
966 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
969 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
970 WPARAM wParam
, LPARAM lParam
) {
975 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
976 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
978 static int tabs
[4] = {25, 61, 96, 128};
979 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
982 for (i
=0; i
<256; i
++) {
984 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
985 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
987 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
992 switch (LOWORD(wParam
)) {
995 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1001 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1006 for (i
=0; i
<256; i
++)
1007 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1010 cfg
.wordness
[i
] = n
;
1011 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1012 LB_DELETESTRING
, i
, 0);
1013 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1014 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1016 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1026 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1029 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1030 WPARAM wParam
, LPARAM lParam
) {
1031 static const char *const colours
[] = {
1032 "Default Foreground", "Default Bold Foreground",
1033 "Default Background", "Default Bold Background",
1034 "Cursor Text", "Cursor Colour",
1035 "ANSI Black", "ANSI Black Bold",
1036 "ANSI Red", "ANSI Red Bold",
1037 "ANSI Green", "ANSI Green Bold",
1038 "ANSI Yellow", "ANSI Yellow Bold",
1039 "ANSI Blue", "ANSI Blue Bold",
1040 "ANSI Magenta", "ANSI Magenta Bold",
1041 "ANSI Cyan", "ANSI Cyan Bold",
1042 "ANSI White", "ANSI White Bold"
1044 static const int permanent
[] = {
1045 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1046 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1047 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1051 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1052 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1055 for (i
=0; i
<22; i
++)
1056 if (cfg
.bold_colour
|| permanent
[i
])
1057 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1058 (LPARAM
) colours
[i
]);
1060 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1061 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1062 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1063 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1066 switch (LOWORD(wParam
)) {
1067 case IDC5_BOLDCOLOUR
:
1068 if (HIWORD(wParam
) == BN_CLICKED
||
1069 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1071 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1072 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1073 if (cfg
.bold_colour
&& n
!=22) {
1074 for (i
=0; i
<22; i
++)
1076 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1078 (LPARAM
) colours
[i
]);
1079 } else if (!cfg
.bold_colour
&& n
!=12) {
1082 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1083 LB_DELETESTRING
, i
, 0);
1088 if (HIWORD(wParam
) == BN_CLICKED
||
1089 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1090 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1093 if (HIWORD(wParam
) == LBN_DBLCLK
||
1094 HIWORD(wParam
) == LBN_SELCHANGE
) {
1095 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1097 if (!cfg
.bold_colour
)
1098 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1099 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1100 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1101 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1105 if (HIWORD(wParam
) == BN_CLICKED
||
1106 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1107 static CHOOSECOLOR cc
;
1108 static DWORD custom
[16] = {0}; /* zero initialisers */
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 cc
.lStructSize
= sizeof(cc
);
1114 cc
.hwndOwner
= hwnd
;
1115 cc
.hInstance
= hinst
;
1116 cc
.lpCustColors
= custom
;
1117 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1119 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1120 if (ChooseColor(&cc
)) {
1122 (unsigned char) (cc
.rgbResult
& 0xFF);
1124 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1126 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1127 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1129 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1131 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1139 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1142 static int CALLBACK
LanguageProc (HWND hwnd
, UINT msg
,
1143 WPARAM wParam
, LPARAM lParam
) {
1146 CheckDlgButton (hwnd
, IDC6_ENABLEKOIWINXLAT
, cfg
.xlat_enablekoiwin
);
1147 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1149 switch (LOWORD(wParam
)) {
1150 case IDC6_ENABLEKOIWINXLAT
:
1151 if (HIWORD(wParam
) == BN_CLICKED
||
1152 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1153 cfg
.xlat_enablekoiwin
=
1154 IsDlgButtonChecked (hwnd
, IDC6_ENABLEKOIWINXLAT
);
1157 case IDC6_CAPSLOCKCYR
:
1158 if (HIWORD(wParam
) == BN_CLICKED
||
1159 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1160 cfg
.xlat_capslockcyr
=
1161 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1166 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1169 static DLGPROC panelproc
[NPANELS
] = {
1170 ConnectionProc
, KeyboardProc
, TerminalProc
,
1171 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, LanguageProc
1173 static char *panelids
[NPANELS
] = {
1174 MAKEINTRESOURCE(IDD_PANEL0
),
1175 MAKEINTRESOURCE(IDD_PANEL1
),
1176 MAKEINTRESOURCE(IDD_PANEL2
),
1177 MAKEINTRESOURCE(IDD_PANEL3
),
1178 MAKEINTRESOURCE(IDD_PANEL35
),
1179 MAKEINTRESOURCE(IDD_PANEL4
),
1180 MAKEINTRESOURCE(IDD_PANEL5
),
1181 MAKEINTRESOURCE(IDD_PANEL6
)
1184 static char *names
[NPANELS
] = {
1185 "Connection", "Keyboard", "Terminal", "Telnet",
1186 "SSH", "Selection", "Colours", "Language"
1189 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1190 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1192 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1193 WPARAM wParam
, LPARAM lParam
,
1194 int npanels
, int *panelnums
, HWND
*page
) {
1199 { /* centre the window */
1202 hw
= GetDesktopWindow();
1203 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1204 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1205 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1206 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1209 { /* initialise the tab control */
1213 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1214 for (i
=0; i
<npanels
; i
++) {
1215 tab
.mask
= TCIF_TEXT
;
1216 tab
.pszText
= names
[panelnums
[i
]];
1217 TabCtrl_InsertItem (hw
, i
, &tab
);
1219 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1220 hwnd, panelproc[panelnums[0]]);*/
1221 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1222 hwnd
, panelproc
[panelnums
[0]]);
1223 SetWindowLong (*page
, GWL_EXSTYLE
,
1224 GetWindowLong (*page
, GWL_EXSTYLE
) |
1225 WS_EX_CONTROLPARENT
);
1230 if (LOWORD(wParam
) == IDC_TAB
&&
1231 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1232 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1234 DestroyWindow (*page
);
1235 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1236 hwnd, panelproc[panelnums[i]]);*/
1237 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1238 hwnd
, panelproc
[panelnums
[i
]]);
1239 SetWindowLong (*page
, GWL_EXSTYLE
,
1240 GetWindowLong (*page
, GWL_EXSTYLE
) |
1241 WS_EX_CONTROLPARENT
);
1242 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1246 /* case WM_CTLCOLORDLG: */
1247 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1249 switch (LOWORD(wParam
)) {
1252 EndDialog (hwnd
, 1);
1257 EndDialog (hwnd
, 0);
1262 EndDialog (hwnd
, 0);
1268 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1269 WPARAM wParam
, LPARAM lParam
) {
1274 static HWND page
= NULL
;
1276 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1279 * If the Connection panel is active and the Session List
1280 * box is selected, we treat a press of Open to have an
1281 * implicit press of Load preceding it.
1283 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1284 i
= TabCtrl_GetCurSel(hw
);
1285 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1286 page
&& implicit_load_ok
) {
1287 SendMessage (page
, WM_COMMAND
,
1288 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1292 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1293 EnableWindow(hwnd
, 0);
1294 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1295 GetParent(hwnd
), AboutProc
);
1296 EnableWindow(hwnd
, 1);
1298 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1299 MAIN_NPANELS
, mainp
, &page
);
1302 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1303 WPARAM wParam
, LPARAM lParam
) {
1305 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1306 RECONF_NPANELS
, reconfp
, &page
);
1309 void get_sesslist(int allocate
) {
1310 static char *buffer
;
1311 int buflen
, bufsize
, i
, ret
;
1312 char otherbuf
[2048];
1317 if (RegCreateKey(HKEY_CURRENT_USER
,
1318 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1321 buflen
= bufsize
= 0;
1325 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1326 if (ret
== ERROR_SUCCESS
) {
1327 bufsize
= buflen
+ 2048;
1328 buffer
= srealloc(buffer
, bufsize
);
1329 unmungestr(otherbuf
, buffer
+buflen
);
1330 buflen
+= strlen(buffer
+buflen
)+1;
1332 } while (ret
== ERROR_SUCCESS
);
1333 buffer
= srealloc(buffer
, buflen
+1);
1334 buffer
[buflen
] = '\0';
1337 nsessions
= 1; /* "Default Settings" counts as one */
1339 if (strcmp(p
, "Default Settings"))
1345 sessions
= smalloc(nsessions
* sizeof(char *));
1346 sessions
[0] = "Default Settings";
1350 if (strcmp(p
, "Default Settings"))
1361 int do_config (void) {
1365 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1366 get_sesslist(FALSE
);
1371 int do_reconfig (HWND hwnd
) {
1375 backup_cfg
= cfg
; /* structure copy */
1376 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1378 cfg
= backup_cfg
; /* structure copy */
1382 void do_defaults (char *session
) {
1384 load_settings (session
, TRUE
);
1386 load_settings ("Default Settings", FALSE
);
1389 void logevent (char *string
) {
1390 if (nevents
>= negsize
) {
1392 events
= srealloc (events
, negsize
* sizeof(*events
));
1394 events
[nevents
] = smalloc(1+strlen(string
));
1395 strcpy (events
[nevents
], string
);
1398 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1402 void showeventlog (HWND hwnd
) {
1404 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1406 ShowWindow (logbox
, SW_SHOWNORMAL
);
1410 void showabout (HWND hwnd
) {
1412 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1414 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1418 void verify_ssh_host_key(char *host
, struct RSAKey
*key
) {
1419 char *keystr
, *otherstr
, *mungedhost
;
1424 * Format the key into a string.
1426 len
= rsastr_len(key
);
1427 keystr
= malloc(len
);
1429 fatalbox("Out of memory");
1430 rsastr_fmt(keystr
, key
);
1433 * Now read a saved key in from the registry and see what it
1436 otherstr
= malloc(len
);
1437 mungedhost
= malloc(3*strlen(host
)+1);
1438 if (!otherstr
|| !mungedhost
)
1439 fatalbox("Out of memory");
1441 mungestr(host
, mungedhost
);
1443 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1444 &rkey
) != ERROR_SUCCESS
) {
1445 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1446 "in the registry. There is thus no way to tell\n"
1447 "if the remote host is what you think it is.\n"
1448 "Connect anyway?", "PuTTY Problem",
1449 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1452 DWORD readlen
= len
;
1456 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1457 &type
, otherstr
, &readlen
);
1459 if (ret
== ERROR_MORE_DATA
||
1460 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1461 strcmp(otherstr
, keystr
))) {
1462 if (MessageBox(NULL
,
1463 "This host's host key is different from the\n"
1464 "one cached in the registry! Someone may be\n"
1465 "impersonating this host for malicious reasons;\n"
1466 "alternatively, the host key may have changed\n"
1467 "due to sloppy system administration.\n"
1468 "Replace key in registry and connect?",
1469 "PuTTY: Security Warning",
1470 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1472 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1474 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1475 if (MessageBox(NULL
,
1476 "This host's host key is not cached in the\n"
1477 "registry. Do you want to add it to the cache\n"
1478 "and carry on connecting?",
1480 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1482 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,