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
);
120 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
121 if (backends
[i
].protocol
== cfg
.protocol
) {
122 p
= backends
[i
].name
;
125 wpps (sesskey
, "Protocol", p
);
127 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
128 wppi (sesskey
, "WarnOnClose", !!cfg
.warn_on_close
);
129 wpps (sesskey
, "TerminalType", cfg
.termtype
);
130 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
132 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
138 if (c
== '=' || c
== ',' || c
== '\\')
148 wpps (sesskey
, "Environment", buf
);
150 wpps (sesskey
, "UserName", cfg
.username
);
151 wppi (sesskey
, "NoPTY", cfg
.nopty
);
152 wpps (sesskey
, "RemoteCmd", cfg
.remote_cmd
);
153 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
154 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
155 wppi (sesskey
, "AuthTIS", cfg
.try_tis_auth
);
156 wppi (sesskey
, "SshProt", cfg
.sshprot
);
157 wpps (sesskey
, "PublicKeyFile", cfg
.keyfile
);
158 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
159 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
160 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
161 wppi (sesskey
, "LinuxFunctionKeys", cfg
.funky_type
);
162 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
163 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
164 wppi (sesskey
, "NetHackKeypad", cfg
.nethack_keypad
);
165 wppi (sesskey
, "AltF4", cfg
.alt_f4
);
166 wppi (sesskey
, "AltSpace", cfg
.alt_space
);
167 wppi (sesskey
, "LdiscTerm", cfg
.ldisc_term
);
168 wppi (sesskey
, "BlinkCur", cfg
.blink_cur
);
169 wppi (sesskey
, "Beep", cfg
.beep
);
170 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
171 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
172 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
173 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
174 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
175 wppi (sesskey
, "TermWidth", cfg
.width
);
176 wppi (sesskey
, "TermHeight", cfg
.height
);
177 wpps (sesskey
, "Font", cfg
.font
);
178 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
179 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
180 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
181 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
182 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
183 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
184 for (i
=0; i
<22; i
++) {
185 char buf
[20], buf2
[30];
186 sprintf(buf
, "Colour%d", i
);
187 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
188 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
189 wpps (sesskey
, buf
, buf2
);
191 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
192 for (i
=0; i
<256; i
+=32) {
193 char buf
[20], buf2
[256];
195 sprintf(buf
, "Wordness%d", i
);
197 for (j
=i
; j
<i
+32; j
++) {
198 sprintf(buf2
+strlen(buf2
), "%s%d",
199 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
201 wpps (sesskey
, buf
, buf2
);
203 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
204 wppi (sesskey
, "88592Xlat", cfg
.xlat_88592w1250
);
205 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
206 wppi (sesskey
, "ScrollBar", cfg
.scrollbar
);
207 wppi (sesskey
, "ScrollOnKey", cfg
.scroll_on_key
);
208 wppi (sesskey
, "LockSize", cfg
.locksize
);
209 wppi (sesskey
, "BCE", cfg
.bce
);
210 wppi (sesskey
, "BlinkText", cfg
.blinktext
);
212 RegCloseKey(sesskey
);
215 static void del_session (char *section
) {
219 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
222 p
= malloc(3*strlen(section
)+1);
223 mungestr(section
, p
);
224 RegDeleteKey(subkey1
, p
);
227 RegCloseKey(subkey1
);
230 static void load_settings (char *section
, int do_host
) {
232 HKEY subkey1
, sesskey
;
236 p
= malloc(3*strlen(section
)+1);
237 mungestr(section
, p
);
239 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
242 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
245 RegCloseKey(subkey1
);
250 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
251 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
253 gpps (sesskey
, "Protocol", "default", prot
, 10);
254 cfg
.protocol
= default_protocol
;
255 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
256 if (!strcmp(prot
, backends
[i
].name
)) {
257 cfg
.protocol
= backends
[i
].protocol
;
261 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
262 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
263 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
264 sizeof(cfg
.termtype
));
265 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
266 sizeof(cfg
.termspeed
));
268 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
269 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
273 while (*p
&& *p
!= ',') {
286 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
287 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
288 gpps (sesskey
, "RemoteCmd", "", cfg
.remote_cmd
, sizeof(cfg
.remote_cmd
));
291 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
292 if (!strcmp(cipher
, "blowfish"))
293 cfg
.cipher
= CIPHER_BLOWFISH
;
294 else if (!strcmp(cipher
, "des"))
295 cfg
.cipher
= CIPHER_DES
;
297 cfg
.cipher
= CIPHER_3DES
;
299 gppi (sesskey
, "SshProt", 1, &cfg
.sshprot
);
300 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
301 gpps (sesskey
, "PublicKeyFile", "", cfg
.keyfile
, sizeof(cfg
.keyfile
));
302 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
303 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
304 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
305 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.funky_type
);
306 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
307 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
308 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
309 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
310 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
311 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
312 gppi (sesskey
, "BlinkCur", 0, &cfg
.blink_cur
);
313 gppi (sesskey
, "Beep", 1, &cfg
.beep
);
314 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
315 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
316 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
317 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
318 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
319 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
320 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
321 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
322 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
323 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
324 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
325 gppi (sesskey
, "FontVTMode", VT_OEMANSI
, (int *)&cfg
.vtmode
);
326 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
327 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
328 for (i
=0; i
<22; i
++) {
329 static char *defaults
[] = {
330 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
331 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
332 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
333 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
334 "85,255,255", "187,187,187", "255,255,255"
336 char buf
[20], buf2
[30];
338 sprintf(buf
, "Colour%d", i
);
339 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
340 if(sscanf(buf2
, "%d,%d,%d", &c0
, &c1
, &c2
) == 3) {
341 cfg
.colours
[i
][0] = c0
;
342 cfg
.colours
[i
][1] = c1
;
343 cfg
.colours
[i
][2] = c2
;
346 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
347 for (i
=0; i
<256; i
+=32) {
348 static char *defaults
[] = {
349 "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",
350 "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",
351 "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",
352 "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",
353 "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",
354 "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",
355 "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",
356 "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"
358 char buf
[20], buf2
[256], *p
;
360 sprintf(buf
, "Wordness%d", i
);
361 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
363 for (j
=i
; j
<i
+32; j
++) {
365 while (*p
&& *p
!= ',') p
++;
366 if (*p
== ',') *p
++ = '\0';
367 cfg
.wordness
[j
] = atoi(q
);
370 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
371 gppi (sesskey
, "88592Xlat", 0, &cfg
.xlat_88592w1250
);
372 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
373 gppi (sesskey
, "ScrollBar", 1, &cfg
.scrollbar
);
374 gppi (sesskey
, "ScrollOnKey", 0, &cfg
.scroll_on_key
);
375 gppi (sesskey
, "LockSize", 0, &cfg
.locksize
);
376 gppi (sesskey
, "BCE", 0, &cfg
.bce
);
377 gppi (sesskey
, "BlinkText", 0, &cfg
.blinktext
);
379 RegCloseKey(sesskey
);
382 static void force_normal(HWND hwnd
)
384 static int recurse
= 0;
391 wp
.length
= sizeof(wp
);
392 if (GetWindowPlacement(hwnd
, &wp
))
394 wp
.showCmd
= SW_SHOWNORMAL
;
395 SetWindowPlacement(hwnd
, &wp
);
400 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
403 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
408 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
409 WPARAM wParam
, LPARAM lParam
) {
414 for (i
=0; i
<nevents
; i
++)
415 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
416 0, (LPARAM
)events
[i
]);
418 /* case WM_CTLCOLORDLG: */
419 /* return (int) GetStockObject (LTGRAY_BRUSH); */
421 switch (LOWORD(wParam
)) {
424 DestroyWindow (hwnd
);
430 DestroyWindow (hwnd
);
436 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
437 WPARAM wParam
, LPARAM lParam
) {
442 switch (LOWORD(wParam
)) {
445 DestroyWindow (hwnd
);
451 DestroyWindow (hwnd
);
457 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
458 WPARAM wParam
, LPARAM lParam
) {
461 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
463 /* case WM_CTLCOLORDLG: */
464 /* return (int) GetStockObject (LTGRAY_BRUSH); */
465 /* case WM_CTLCOLORSTATIC: */
466 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
467 /* return (int) GetStockObject (LTGRAY_BRUSH); */
469 switch (LOWORD(wParam
)) {
472 DestroyWindow (hwnd
);
475 EnableWindow(hwnd
, 0);
476 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
478 EnableWindow(hwnd
, 1);
484 DestroyWindow (hwnd
);
490 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
491 WPARAM wParam
, LPARAM lParam
) {
494 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
496 /* case WM_CTLCOLORDLG: */
497 /* return (int) GetStockObject (LTGRAY_BRUSH); */
498 /* case WM_CTLCOLORSTATIC: */
499 /* case WM_CTLCOLORBTN: */
500 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
501 /* return (int) GetStockObject (LTGRAY_BRUSH); */
503 DestroyWindow (hwnd
);
509 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
510 WPARAM wParam
, LPARAM lParam
) {
515 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
516 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
517 for (i
= 0; i
< nsessions
; i
++)
518 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
519 0, (LPARAM
) (sessions
[i
]));
520 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
521 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
522 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
523 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
524 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
528 * Button release should trigger WM_OK if there was a
529 * previous double click on the session list.
533 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
536 switch (LOWORD(wParam
)) {
537 case IDC0_PROTTELNET
:
540 if (HIWORD(wParam
) == BN_CLICKED
||
541 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
542 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
543 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
544 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
545 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
546 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
547 cfg
.port
= i ?
22 : 23;
548 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
553 if (HIWORD(wParam
) == EN_CHANGE
)
554 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
558 if (HIWORD(wParam
) == EN_CHANGE
)
559 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
562 if (HIWORD(wParam
) == BN_CLICKED
||
563 HIWORD(wParam
) == BN_DOUBLECLICKED
)
564 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
567 if (HIWORD(wParam
) == BN_CLICKED
||
568 HIWORD(wParam
) == BN_DOUBLECLICKED
)
569 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
572 if (HIWORD(wParam
) == EN_CHANGE
)
573 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
577 if (HIWORD(wParam
) == BN_CLICKED
||
578 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
583 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
585 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
591 strcpy (str
, sessions
[n
]);
593 save_settings (str
, !!strcmp(str
, "Default Settings"));
594 get_sesslist (FALSE
);
596 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
598 for (i
= 0; i
< nsessions
; i
++)
599 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
600 0, (LPARAM
) (sessions
[i
]));
601 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
607 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
608 HIWORD(wParam
) != BN_CLICKED
&&
609 HIWORD(wParam
) != BN_DOUBLECLICKED
)
611 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
612 HIWORD(wParam
) != LBN_DBLCLK
)
615 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
621 load_settings (sessions
[n
],
622 !!strcmp(sessions
[n
], "Default Settings"));
623 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
624 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
625 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
626 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
627 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
628 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
629 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
630 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
633 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
635 * A double-click on a saved session should
636 * actually start the session, not just load it.
637 * Unless it's Default Settings or some other
638 * host-less set of saved settings.
647 if (HIWORD(wParam
) == BN_CLICKED
||
648 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
649 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
651 if (n
== LB_ERR
|| n
== 0) {
655 del_session(sessions
[n
]);
656 get_sesslist (FALSE
);
658 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
660 for (i
= 0; i
< nsessions
; i
++)
661 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
662 0, (LPARAM
) (sessions
[i
]));
663 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
668 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
671 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
672 WPARAM wParam
, LPARAM lParam
) {
675 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
676 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
677 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
678 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
679 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
681 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
684 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
685 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
686 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
687 cfg
.nethack_keypad ? IDC1_KPNH
:
688 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
689 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
690 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
691 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
692 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
695 if (HIWORD(wParam
) == BN_CLICKED
||
696 HIWORD(wParam
) == BN_DOUBLECLICKED
)
697 switch (LOWORD(wParam
)) {
700 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
704 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
711 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
715 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
716 cfg
.nethack_keypad
= FALSE
;
719 cfg
.app_keypad
= FALSE
;
720 cfg
.nethack_keypad
= TRUE
;
724 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
727 if (HIWORD(wParam
) == BN_CLICKED
||
728 HIWORD(wParam
) == BN_DOUBLECLICKED
)
729 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
732 if (HIWORD(wParam
) == BN_CLICKED
||
733 HIWORD(wParam
) == BN_DOUBLECLICKED
)
734 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
737 if (HIWORD(wParam
) == BN_CLICKED
||
738 HIWORD(wParam
) == BN_DOUBLECLICKED
)
739 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
742 if (HIWORD(wParam
) == BN_CLICKED
||
743 HIWORD(wParam
) == BN_DOUBLECLICKED
)
744 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
748 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
751 static void fmtfont (char *buf
) {
752 sprintf (buf
, "Font: %s, ", cfg
.font
);
754 strcat(buf
, "bold, ");
755 if (cfg
.fontheight
== 0)
756 strcat (buf
, "default height");
758 sprintf (buf
+strlen(buf
), "%d-%s",
759 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
760 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
763 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
764 WPARAM wParam
, LPARAM lParam
) {
767 char fontstatic
[256];
771 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
772 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
773 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
774 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
775 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
776 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
777 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
778 fmtfont (fontstatic
);
779 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
780 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
781 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
782 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
783 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
784 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
785 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
788 switch (LOWORD(wParam
)) {
790 if (HIWORD(wParam
) == BN_CLICKED
||
791 HIWORD(wParam
) == BN_DOUBLECLICKED
)
792 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
795 if (HIWORD(wParam
) == BN_CLICKED
||
796 HIWORD(wParam
) == BN_DOUBLECLICKED
)
797 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
800 if (HIWORD(wParam
) == BN_CLICKED
||
801 HIWORD(wParam
) == BN_DOUBLECLICKED
)
802 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
805 if (HIWORD(wParam
) == BN_CLICKED
||
806 HIWORD(wParam
) == BN_DOUBLECLICKED
)
807 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
810 if (HIWORD(wParam
) == EN_CHANGE
)
811 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
814 if (HIWORD(wParam
) == EN_CHANGE
)
815 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
818 if (HIWORD(wParam
) == EN_CHANGE
)
819 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
821 case IDC2_CHOOSEFONT
:
822 lf
.lfHeight
= cfg
.fontheight
;
823 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
824 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
825 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
826 lf
.lfCharSet
= cfg
.fontcharset
;
827 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
828 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
829 lf
.lfQuality
= DEFAULT_QUALITY
;
830 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
831 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
832 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
834 cf
.lStructSize
= sizeof(cf
);
837 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
838 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
840 if (ChooseFont (&cf
)) {
841 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
842 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
843 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
844 cfg
.fontcharset
= lf
.lfCharSet
;
845 cfg
.fontheight
= lf
.lfHeight
;
846 fmtfont (fontstatic
);
847 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
851 if (HIWORD(wParam
) == BN_CLICKED
||
852 HIWORD(wParam
) == BN_DOUBLECLICKED
)
853 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
856 if (HIWORD(wParam
) == BN_CLICKED
||
857 HIWORD(wParam
) == BN_DOUBLECLICKED
)
858 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
861 if (HIWORD(wParam
) == BN_CLICKED
||
862 HIWORD(wParam
) == BN_DOUBLECLICKED
)
863 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
866 if (HIWORD(wParam
) == BN_CLICKED
||
867 HIWORD(wParam
) == BN_DOUBLECLICKED
)
868 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
871 if (HIWORD(wParam
) == BN_CLICKED
||
872 HIWORD(wParam
) == BN_DOUBLECLICKED
)
873 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
876 if (HIWORD(wParam
) == BN_CLICKED
||
877 HIWORD(wParam
) == BN_DOUBLECLICKED
)
878 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
883 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
886 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
887 WPARAM wParam
, LPARAM lParam
) {
892 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
893 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
894 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
896 char *p
= cfg
.environmt
;
898 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
903 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
904 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
907 switch (LOWORD(wParam
)) {
909 if (HIWORD(wParam
) == EN_CHANGE
)
910 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
911 sizeof(cfg
.termtype
)-1);
914 if (HIWORD(wParam
) == EN_CHANGE
)
915 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
916 sizeof(cfg
.termspeed
)-1);
919 if (HIWORD(wParam
) == EN_CHANGE
)
920 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
921 sizeof(cfg
.username
)-1);
925 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
928 if (HIWORD(wParam
) == BN_CLICKED
||
929 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
930 char str
[sizeof(cfg
.environmt
)];
932 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
937 p
= str
+ strlen(str
);
939 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
949 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
951 p
[strlen(str
)+1] = '\0';
952 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
954 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
955 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
957 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
958 MB_OK
| MB_ICONERROR
);
963 if (HIWORD(wParam
) != BN_CLICKED
&&
964 HIWORD(wParam
) != BN_DOUBLECLICKED
)
966 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
972 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
999 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1002 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
1003 WPARAM wParam
, LPARAM lParam
) {
1005 char filename
[sizeof(cfg
.keyfile
)];
1009 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
1010 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
1011 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
1012 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
1013 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
1014 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
1016 CheckRadioButton (hwnd
, IDC3_SSHPROT1
, IDC3_SSHPROT2
,
1017 cfg
.sshprot
== 1 ? IDC3_SSHPROT1
: IDC3_SSHPROT2
);
1018 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
1019 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1022 switch (LOWORD(wParam
)) {
1024 if (HIWORD(wParam
) == EN_CHANGE
)
1025 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
1026 sizeof(cfg
.termtype
)-1);
1029 if (HIWORD(wParam
) == EN_CHANGE
)
1030 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
1031 sizeof(cfg
.username
)-1);
1034 if (HIWORD(wParam
) == BN_CLICKED
||
1035 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1036 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
1038 case IDC3_CIPHER3DES
:
1039 case IDC3_CIPHERBLOWF
:
1040 case IDC3_CIPHERDES
:
1041 if (HIWORD(wParam
) == BN_CLICKED
||
1042 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1043 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1044 cfg
.cipher
= CIPHER_3DES
;
1045 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1046 cfg
.cipher
= CIPHER_BLOWFISH
;
1047 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1048 cfg
.cipher
= CIPHER_DES
;
1053 if (HIWORD(wParam
) == BN_CLICKED
||
1054 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1055 if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT1
))
1057 else if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT2
))
1062 if (HIWORD(wParam
) == BN_CLICKED
||
1063 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1064 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1067 if (HIWORD(wParam
) == EN_CHANGE
)
1068 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1069 sizeof(cfg
.keyfile
)-1);
1073 * FIXME: this crashes. Find out why.
1075 memset(&of
, 0, sizeof(of
));
1076 #ifdef OPENFILENAME_SIZE_VERSION_400
1077 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1079 of
.lStructSize
= sizeof(of
);
1081 of
.hwndOwner
= hwnd
;
1082 of
.lpstrFilter
= "All Files\0*\0\0\0";
1083 of
.lpstrCustomFilter
= NULL
;
1084 of
.nFilterIndex
= 1;
1085 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1086 of
.nMaxFile
= sizeof(filename
);
1087 of
.lpstrFileTitle
= NULL
;
1088 of
.lpstrInitialDir
= NULL
;
1089 of
.lpstrTitle
= "Select Public Key File";
1091 if (GetOpenFileName(&of
)) {
1092 strcpy(cfg
.keyfile
, filename
);
1093 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1099 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1102 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1103 WPARAM wParam
, LPARAM lParam
) {
1108 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1109 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1111 static int tabs
[4] = {25, 61, 96, 128};
1112 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1115 for (i
=0; i
<256; i
++) {
1117 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1118 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1120 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1125 switch (LOWORD(wParam
)) {
1126 case IDC4_MBWINDOWS
:
1128 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1134 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1139 for (i
=0; i
<256; i
++)
1140 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1143 cfg
.wordness
[i
] = n
;
1144 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1145 LB_DELETESTRING
, i
, 0);
1146 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1147 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1149 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1159 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1162 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1163 WPARAM wParam
, LPARAM lParam
) {
1164 static const char *const colours
[] = {
1165 "Default Foreground", "Default Bold Foreground",
1166 "Default Background", "Default Bold Background",
1167 "Cursor Text", "Cursor Colour",
1168 "ANSI Black", "ANSI Black Bold",
1169 "ANSI Red", "ANSI Red Bold",
1170 "ANSI Green", "ANSI Green Bold",
1171 "ANSI Yellow", "ANSI Yellow Bold",
1172 "ANSI Blue", "ANSI Blue Bold",
1173 "ANSI Magenta", "ANSI Magenta Bold",
1174 "ANSI Cyan", "ANSI Cyan Bold",
1175 "ANSI White", "ANSI White Bold"
1177 static const int permanent
[] = {
1178 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1179 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1180 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1184 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1185 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1188 for (i
=0; i
<22; i
++)
1189 if (cfg
.bold_colour
|| permanent
[i
])
1190 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1191 (LPARAM
) colours
[i
]);
1193 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1194 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1195 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1196 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1199 switch (LOWORD(wParam
)) {
1200 case IDC5_BOLDCOLOUR
:
1201 if (HIWORD(wParam
) == BN_CLICKED
||
1202 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1204 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1205 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1206 if (cfg
.bold_colour
&& n
!=22) {
1207 for (i
=0; i
<22; i
++)
1209 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1211 (LPARAM
) colours
[i
]);
1212 } else if (!cfg
.bold_colour
&& n
!=12) {
1215 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1216 LB_DELETESTRING
, i
, 0);
1221 if (HIWORD(wParam
) == BN_CLICKED
||
1222 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1223 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1226 if (HIWORD(wParam
) == LBN_DBLCLK
||
1227 HIWORD(wParam
) == LBN_SELCHANGE
) {
1228 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1230 if (!cfg
.bold_colour
)
1231 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1232 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1233 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1234 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1238 if (HIWORD(wParam
) == BN_CLICKED
||
1239 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1240 static CHOOSECOLOR cc
;
1241 static DWORD custom
[16] = {0}; /* zero initialisers */
1242 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1244 if (!cfg
.bold_colour
)
1245 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1246 cc
.lStructSize
= sizeof(cc
);
1247 cc
.hwndOwner
= hwnd
;
1248 cc
.hInstance
= (HWND
)hinst
;
1249 cc
.lpCustColors
= custom
;
1250 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1252 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1253 if (ChooseColor(&cc
)) {
1255 (unsigned char) (cc
.rgbResult
& 0xFF);
1257 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1259 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1260 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1262 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1264 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1272 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1275 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1276 WPARAM wParam
, LPARAM lParam
) {
1279 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1280 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1281 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1283 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1284 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1285 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1286 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1287 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1290 switch (LOWORD(wParam
)) {
1292 case IDC6_KOI8WIN1251
:
1293 case IDC6_88592WIN1250
:
1294 cfg
.xlat_enablekoiwin
=
1295 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1296 cfg
.xlat_88592w1250
=
1297 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1299 case IDC6_CAPSLOCKCYR
:
1300 if (HIWORD(wParam
) == BN_CLICKED
||
1301 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1302 cfg
.xlat_capslockcyr
=
1303 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1306 case IDC2_VTXWINDOWS
:
1307 case IDC2_VTOEMANSI
:
1308 case IDC2_VTOEMONLY
:
1309 case IDC2_VTPOORMAN
:
1311 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1312 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1313 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1318 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1321 static DLGPROC panelproc
[NPANELS
] = {
1322 ConnectionProc
, KeyboardProc
, TerminalProc
,
1323 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1325 static char *panelids
[NPANELS
] = {
1326 MAKEINTRESOURCE(IDD_PANEL0
),
1327 MAKEINTRESOURCE(IDD_PANEL1
),
1328 MAKEINTRESOURCE(IDD_PANEL2
),
1329 MAKEINTRESOURCE(IDD_PANEL3
),
1330 MAKEINTRESOURCE(IDD_PANEL35
),
1331 MAKEINTRESOURCE(IDD_PANEL4
),
1332 MAKEINTRESOURCE(IDD_PANEL5
),
1333 MAKEINTRESOURCE(IDD_PANEL6
)
1336 static char *names
[NPANELS
] = {
1337 "Connection", "Keyboard", "Terminal", "Telnet",
1338 "SSH", "Selection", "Colours", "Translation"
1341 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1342 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1344 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1345 WPARAM wParam
, LPARAM lParam
,
1346 int npanels
, int *panelnums
, HWND
*page
) {
1351 { /* centre the window */
1354 hw
= GetDesktopWindow();
1355 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1356 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1357 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1358 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1361 { /* initialise the tab control */
1365 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1366 for (i
=0; i
<npanels
; i
++) {
1367 tab
.mask
= TCIF_TEXT
;
1368 tab
.pszText
= names
[panelnums
[i
]];
1369 TabCtrl_InsertItem (hw
, i
, &tab
);
1371 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1372 hwnd, panelproc[panelnums[0]]);*/
1373 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1374 hwnd
, panelproc
[panelnums
[0]]);
1375 SetWindowLong (*page
, GWL_EXSTYLE
,
1376 GetWindowLong (*page
, GWL_EXSTYLE
) |
1377 WS_EX_CONTROLPARENT
);
1382 if (LOWORD(wParam
) == IDC_TAB
&&
1383 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1384 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1386 DestroyWindow (*page
);
1387 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1388 hwnd, panelproc[panelnums[i]]);*/
1389 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1390 hwnd
, panelproc
[panelnums
[i
]]);
1391 SetWindowLong (*page
, GWL_EXSTYLE
,
1392 GetWindowLong (*page
, GWL_EXSTYLE
) |
1393 WS_EX_CONTROLPARENT
);
1394 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1398 /* case WM_CTLCOLORDLG: */
1399 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1401 switch (LOWORD(wParam
)) {
1404 EndDialog (hwnd
, 1);
1409 EndDialog (hwnd
, 0);
1414 EndDialog (hwnd
, 0);
1417 /* Grrr Explorer will maximize Dialogs! */
1419 if (wParam
== SIZE_MAXIMIZED
)
1426 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1427 WPARAM wParam
, LPARAM lParam
) {
1432 static HWND page
= NULL
;
1434 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1437 * If the Connection panel is active and the Session List
1438 * box is selected, we treat a press of Open to have an
1439 * implicit press of Load preceding it.
1441 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1442 i
= TabCtrl_GetCurSel(hw
);
1443 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1444 page
&& implicit_load_ok
) {
1445 SendMessage (page
, WM_COMMAND
,
1446 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1450 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1451 EnableWindow(hwnd
, 0);
1452 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1453 GetParent(hwnd
), AboutProc
);
1454 EnableWindow(hwnd
, 1);
1456 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1457 MAIN_NPANELS
, mainp
, &page
);
1460 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1461 WPARAM wParam
, LPARAM lParam
) {
1463 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1464 RECONF_NPANELS
, reconfp
, &page
);
1467 void get_sesslist(int allocate
) {
1468 static char *buffer
;
1469 int buflen
, bufsize
, i
, ret
;
1470 char otherbuf
[2048];
1475 if (RegCreateKey(HKEY_CURRENT_USER
,
1476 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1479 buflen
= bufsize
= 0;
1483 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1484 if (ret
== ERROR_SUCCESS
) {
1485 bufsize
= buflen
+ 2048;
1486 buffer
= srealloc(buffer
, bufsize
);
1487 unmungestr(otherbuf
, buffer
+buflen
);
1488 buflen
+= strlen(buffer
+buflen
)+1;
1490 } while (ret
== ERROR_SUCCESS
);
1491 buffer
= srealloc(buffer
, buflen
+1);
1492 buffer
[buflen
] = '\0';
1495 nsessions
= 1; /* "Default Settings" counts as one */
1497 if (strcmp(p
, "Default Settings"))
1503 sessions
= smalloc(nsessions
* sizeof(char *));
1504 sessions
[0] = "Default Settings";
1508 if (strcmp(p
, "Default Settings"))
1519 int do_config (void) {
1523 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1524 get_sesslist(FALSE
);
1529 int do_reconfig (HWND hwnd
) {
1533 backup_cfg
= cfg
; /* structure copy */
1534 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1536 cfg
= backup_cfg
; /* structure copy */
1543 void do_defaults (char *session
) {
1545 load_settings (session
, TRUE
);
1547 load_settings ("Default Settings", FALSE
);
1550 void logevent (char *string
) {
1551 if (nevents
>= negsize
) {
1553 events
= srealloc (events
, negsize
* sizeof(*events
));
1555 events
[nevents
] = smalloc(1+strlen(string
));
1556 strcpy (events
[nevents
], string
);
1559 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1563 void showeventlog (HWND hwnd
) {
1565 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1567 ShowWindow (logbox
, SW_SHOWNORMAL
);
1571 void showabout (HWND hwnd
) {
1573 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1575 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1579 void verify_ssh_host_key(char *host
, char *keystr
) {
1580 char *otherstr
, *mungedhost
;
1584 len
= 1 + strlen(keystr
);
1587 * Now read a saved key in from the registry and see what it
1590 otherstr
= smalloc(len
);
1591 mungedhost
= smalloc(3*strlen(host
)+1);
1592 if (!otherstr
|| !mungedhost
)
1593 fatalbox("Out of memory");
1595 mungestr(host
, mungedhost
);
1597 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1598 &rkey
) != ERROR_SUCCESS
) {
1599 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1600 "in the registry. There is thus no way to tell\n"
1601 "if the remote host is what you think it is.\n"
1602 "Connect anyway?", "PuTTY Problem",
1603 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1606 DWORD readlen
= len
;
1610 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1611 &type
, otherstr
, &readlen
);
1613 if (ret
== ERROR_MORE_DATA
||
1614 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1615 strcmp(otherstr
, keystr
))) {
1616 if (MessageBox(NULL
,
1617 "This host's host key is different from the\n"
1618 "one cached in the registry! Someone may be\n"
1619 "impersonating this host for malicious reasons;\n"
1620 "alternatively, the host key may have changed\n"
1621 "due to sloppy system administration.\n"
1622 "Replace key in registry and connect?",
1623 "PuTTY: Security Warning",
1624 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1626 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1628 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1629 if (MessageBox(NULL
,
1630 "This host's host key is not cached in the\n"
1631 "registry. Do you want to add it to the cache\n"
1632 "and carry on connecting?",
1634 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1636 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,