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 wpps (sesskey
, "PublicKeyFile", cfg
.keyfile
);
157 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
158 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
159 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
160 wppi (sesskey
, "LinuxFunctionKeys", cfg
.funky_type
);
161 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
162 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
163 wppi (sesskey
, "NetHackKeypad", cfg
.nethack_keypad
);
164 wppi (sesskey
, "AltF4", cfg
.alt_f4
);
165 wppi (sesskey
, "AltSpace", cfg
.alt_space
);
166 wppi (sesskey
, "LdiscTerm", cfg
.ldisc_term
);
167 wppi (sesskey
, "BlinkCur", cfg
.blink_cur
);
168 wppi (sesskey
, "Beep", cfg
.beep
);
169 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
170 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
171 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
172 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
173 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
174 wppi (sesskey
, "TermWidth", cfg
.width
);
175 wppi (sesskey
, "TermHeight", cfg
.height
);
176 wpps (sesskey
, "Font", cfg
.font
);
177 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
178 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
179 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
180 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
181 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
182 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
183 for (i
=0; i
<22; i
++) {
184 char buf
[20], buf2
[30];
185 sprintf(buf
, "Colour%d", i
);
186 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
187 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
188 wpps (sesskey
, buf
, buf2
);
190 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
191 for (i
=0; i
<256; i
+=32) {
192 char buf
[20], buf2
[256];
194 sprintf(buf
, "Wordness%d", i
);
196 for (j
=i
; j
<i
+32; j
++) {
197 sprintf(buf2
+strlen(buf2
), "%s%d",
198 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
200 wpps (sesskey
, buf
, buf2
);
202 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
203 wppi (sesskey
, "88592Xlat", cfg
.xlat_88592w1250
);
204 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
205 wppi (sesskey
, "ScrollBar", cfg
.scrollbar
);
206 wppi (sesskey
, "ScrollOnKey", cfg
.scroll_on_key
);
207 wppi (sesskey
, "LockSize", cfg
.locksize
);
208 wppi (sesskey
, "BCE", cfg
.bce
);
209 wppi (sesskey
, "BlinkText", cfg
.blinktext
);
211 RegCloseKey(sesskey
);
214 static void del_session (char *section
) {
218 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
221 p
= malloc(3*strlen(section
)+1);
222 mungestr(section
, p
);
223 RegDeleteKey(subkey1
, p
);
226 RegCloseKey(subkey1
);
229 static void load_settings (char *section
, int do_host
) {
231 HKEY subkey1
, sesskey
;
235 p
= malloc(3*strlen(section
)+1);
236 mungestr(section
, p
);
238 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
241 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
244 RegCloseKey(subkey1
);
249 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
250 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
252 gpps (sesskey
, "Protocol", "default", prot
, 10);
253 cfg
.protocol
= default_protocol
;
254 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
255 if (!strcmp(prot
, backends
[i
].name
)) {
256 cfg
.protocol
= backends
[i
].protocol
;
260 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
261 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
262 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
263 sizeof(cfg
.termtype
));
264 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
265 sizeof(cfg
.termspeed
));
267 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
268 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
272 while (*p
&& *p
!= ',') {
285 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
286 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
287 gpps (sesskey
, "RemoteCmd", "", cfg
.remote_cmd
, sizeof(cfg
.remote_cmd
));
290 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
291 if (!strcmp(cipher
, "blowfish"))
292 cfg
.cipher
= CIPHER_BLOWFISH
;
293 else if (!strcmp(cipher
, "des"))
294 cfg
.cipher
= CIPHER_DES
;
296 cfg
.cipher
= CIPHER_3DES
;
298 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
299 gpps (sesskey
, "PublicKeyFile", "", cfg
.keyfile
, sizeof(cfg
.keyfile
));
300 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
301 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
302 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
303 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.funky_type
);
304 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
305 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
306 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
307 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
308 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
309 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
310 gppi (sesskey
, "BlinkCur", 0, &cfg
.blink_cur
);
311 gppi (sesskey
, "Beep", 1, &cfg
.beep
);
312 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
313 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
314 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
315 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
316 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
317 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
318 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
319 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
320 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
321 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
322 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
323 gppi (sesskey
, "FontVTMode", VT_OEMANSI
, (int *)&cfg
.vtmode
);
324 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
325 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
326 for (i
=0; i
<22; i
++) {
327 static char *defaults
[] = {
328 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
329 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
330 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
331 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
332 "85,255,255", "187,187,187", "255,255,255"
334 char buf
[20], buf2
[30];
336 sprintf(buf
, "Colour%d", i
);
337 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
338 if(sscanf(buf2
, "%d,%d,%d", &c0
, &c1
, &c2
) == 3) {
339 cfg
.colours
[i
][0] = c0
;
340 cfg
.colours
[i
][1] = c1
;
341 cfg
.colours
[i
][2] = c2
;
344 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
345 for (i
=0; i
<256; i
+=32) {
346 static char *defaults
[] = {
347 "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",
348 "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",
349 "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",
350 "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",
351 "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",
352 "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",
353 "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",
354 "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 char buf
[20], buf2
[256], *p
;
358 sprintf(buf
, "Wordness%d", i
);
359 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
361 for (j
=i
; j
<i
+32; j
++) {
363 while (*p
&& *p
!= ',') p
++;
364 if (*p
== ',') *p
++ = '\0';
365 cfg
.wordness
[j
] = atoi(q
);
368 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
369 gppi (sesskey
, "88592Xlat", 0, &cfg
.xlat_88592w1250
);
370 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
371 gppi (sesskey
, "ScrollBar", 1, &cfg
.scrollbar
);
372 gppi (sesskey
, "ScrollOnKey", 0, &cfg
.scroll_on_key
);
373 gppi (sesskey
, "LockSize", 0, &cfg
.locksize
);
374 gppi (sesskey
, "BCE", 0, &cfg
.bce
);
375 gppi (sesskey
, "BlinkText", 0, &cfg
.blinktext
);
377 RegCloseKey(sesskey
);
380 static void force_normal(HWND hwnd
)
382 static int recurse
= 0;
389 wp
.length
= sizeof(wp
);
390 if (GetWindowPlacement(hwnd
, &wp
))
392 wp
.showCmd
= SW_SHOWNORMAL
;
393 SetWindowPlacement(hwnd
, &wp
);
398 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
401 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
406 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
407 WPARAM wParam
, LPARAM lParam
) {
412 for (i
=0; i
<nevents
; i
++)
413 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
414 0, (LPARAM
)events
[i
]);
416 /* case WM_CTLCOLORDLG: */
417 /* return (int) GetStockObject (LTGRAY_BRUSH); */
419 switch (LOWORD(wParam
)) {
422 DestroyWindow (hwnd
);
428 DestroyWindow (hwnd
);
434 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
435 WPARAM wParam
, LPARAM lParam
) {
440 switch (LOWORD(wParam
)) {
443 DestroyWindow (hwnd
);
449 DestroyWindow (hwnd
);
455 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
456 WPARAM wParam
, LPARAM lParam
) {
459 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
461 /* case WM_CTLCOLORDLG: */
462 /* return (int) GetStockObject (LTGRAY_BRUSH); */
463 /* case WM_CTLCOLORSTATIC: */
464 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
465 /* return (int) GetStockObject (LTGRAY_BRUSH); */
467 switch (LOWORD(wParam
)) {
470 DestroyWindow (hwnd
);
473 EnableWindow(hwnd
, 0);
474 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
476 EnableWindow(hwnd
, 1);
482 DestroyWindow (hwnd
);
488 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
489 WPARAM wParam
, LPARAM lParam
) {
492 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
494 /* case WM_CTLCOLORDLG: */
495 /* return (int) GetStockObject (LTGRAY_BRUSH); */
496 /* case WM_CTLCOLORSTATIC: */
497 /* case WM_CTLCOLORBTN: */
498 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
499 /* return (int) GetStockObject (LTGRAY_BRUSH); */
501 DestroyWindow (hwnd
);
507 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
508 WPARAM wParam
, LPARAM lParam
) {
513 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
514 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
515 for (i
= 0; i
< nsessions
; i
++)
516 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
517 0, (LPARAM
) (sessions
[i
]));
518 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
519 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
520 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
521 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
522 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
526 * Button release should trigger WM_OK if there was a
527 * previous double click on the session list.
531 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
534 switch (LOWORD(wParam
)) {
535 case IDC0_PROTTELNET
:
538 if (HIWORD(wParam
) == BN_CLICKED
||
539 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
540 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
541 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
542 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
543 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
544 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
545 cfg
.port
= i ?
22 : 23;
546 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
551 if (HIWORD(wParam
) == EN_CHANGE
)
552 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
556 if (HIWORD(wParam
) == EN_CHANGE
)
557 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
560 if (HIWORD(wParam
) == BN_CLICKED
||
561 HIWORD(wParam
) == BN_DOUBLECLICKED
)
562 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
565 if (HIWORD(wParam
) == BN_CLICKED
||
566 HIWORD(wParam
) == BN_DOUBLECLICKED
)
567 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
570 if (HIWORD(wParam
) == EN_CHANGE
)
571 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
575 if (HIWORD(wParam
) == BN_CLICKED
||
576 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
581 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
583 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
589 strcpy (str
, sessions
[n
]);
591 save_settings (str
, !!strcmp(str
, "Default Settings"));
592 get_sesslist (FALSE
);
594 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
596 for (i
= 0; i
< nsessions
; i
++)
597 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
598 0, (LPARAM
) (sessions
[i
]));
599 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
605 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
606 HIWORD(wParam
) != BN_CLICKED
&&
607 HIWORD(wParam
) != BN_DOUBLECLICKED
)
609 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
610 HIWORD(wParam
) != LBN_DBLCLK
)
613 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
619 load_settings (sessions
[n
],
620 !!strcmp(sessions
[n
], "Default Settings"));
621 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
622 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
623 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
624 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
625 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
626 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
627 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
628 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
631 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
633 * A double-click on a saved session should
634 * actually start the session, not just load it.
635 * Unless it's Default Settings or some other
636 * host-less set of saved settings.
645 if (HIWORD(wParam
) == BN_CLICKED
||
646 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
647 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
649 if (n
== LB_ERR
|| n
== 0) {
653 del_session(sessions
[n
]);
654 get_sesslist (FALSE
);
656 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
658 for (i
= 0; i
< nsessions
; i
++)
659 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
660 0, (LPARAM
) (sessions
[i
]));
661 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
666 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
669 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
670 WPARAM wParam
, LPARAM lParam
) {
673 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
674 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
675 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
676 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
677 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
679 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
682 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
683 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
684 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
685 cfg
.nethack_keypad ? IDC1_KPNH
:
686 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
687 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
688 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
689 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
690 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
693 if (HIWORD(wParam
) == BN_CLICKED
||
694 HIWORD(wParam
) == BN_DOUBLECLICKED
)
695 switch (LOWORD(wParam
)) {
698 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
702 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
709 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
713 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
714 cfg
.nethack_keypad
= FALSE
;
717 cfg
.app_keypad
= FALSE
;
718 cfg
.nethack_keypad
= TRUE
;
722 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
725 if (HIWORD(wParam
) == BN_CLICKED
||
726 HIWORD(wParam
) == BN_DOUBLECLICKED
)
727 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
730 if (HIWORD(wParam
) == BN_CLICKED
||
731 HIWORD(wParam
) == BN_DOUBLECLICKED
)
732 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
735 if (HIWORD(wParam
) == BN_CLICKED
||
736 HIWORD(wParam
) == BN_DOUBLECLICKED
)
737 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
740 if (HIWORD(wParam
) == BN_CLICKED
||
741 HIWORD(wParam
) == BN_DOUBLECLICKED
)
742 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
746 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
749 static void fmtfont (char *buf
) {
750 sprintf (buf
, "Font: %s, ", cfg
.font
);
752 strcat(buf
, "bold, ");
753 if (cfg
.fontheight
== 0)
754 strcat (buf
, "default height");
756 sprintf (buf
+strlen(buf
), "%d-%s",
757 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
758 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
761 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
762 WPARAM wParam
, LPARAM lParam
) {
765 char fontstatic
[256];
769 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
770 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
771 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
772 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
773 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
774 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
775 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
776 fmtfont (fontstatic
);
777 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
778 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
779 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
780 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
781 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
782 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
783 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
786 switch (LOWORD(wParam
)) {
788 if (HIWORD(wParam
) == BN_CLICKED
||
789 HIWORD(wParam
) == BN_DOUBLECLICKED
)
790 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
793 if (HIWORD(wParam
) == BN_CLICKED
||
794 HIWORD(wParam
) == BN_DOUBLECLICKED
)
795 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
798 if (HIWORD(wParam
) == BN_CLICKED
||
799 HIWORD(wParam
) == BN_DOUBLECLICKED
)
800 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
803 if (HIWORD(wParam
) == BN_CLICKED
||
804 HIWORD(wParam
) == BN_DOUBLECLICKED
)
805 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
808 if (HIWORD(wParam
) == EN_CHANGE
)
809 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
812 if (HIWORD(wParam
) == EN_CHANGE
)
813 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
816 if (HIWORD(wParam
) == EN_CHANGE
)
817 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
819 case IDC2_CHOOSEFONT
:
820 lf
.lfHeight
= cfg
.fontheight
;
821 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
822 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
823 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
824 lf
.lfCharSet
= cfg
.fontcharset
;
825 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
826 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
827 lf
.lfQuality
= DEFAULT_QUALITY
;
828 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
829 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
830 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
832 cf
.lStructSize
= sizeof(cf
);
835 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
836 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
838 if (ChooseFont (&cf
)) {
839 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
840 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
841 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
842 cfg
.fontcharset
= lf
.lfCharSet
;
843 cfg
.fontheight
= lf
.lfHeight
;
844 fmtfont (fontstatic
);
845 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
849 if (HIWORD(wParam
) == BN_CLICKED
||
850 HIWORD(wParam
) == BN_DOUBLECLICKED
)
851 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
854 if (HIWORD(wParam
) == BN_CLICKED
||
855 HIWORD(wParam
) == BN_DOUBLECLICKED
)
856 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
859 if (HIWORD(wParam
) == BN_CLICKED
||
860 HIWORD(wParam
) == BN_DOUBLECLICKED
)
861 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
864 if (HIWORD(wParam
) == BN_CLICKED
||
865 HIWORD(wParam
) == BN_DOUBLECLICKED
)
866 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
869 if (HIWORD(wParam
) == BN_CLICKED
||
870 HIWORD(wParam
) == BN_DOUBLECLICKED
)
871 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
874 if (HIWORD(wParam
) == BN_CLICKED
||
875 HIWORD(wParam
) == BN_DOUBLECLICKED
)
876 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
881 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
884 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
885 WPARAM wParam
, LPARAM lParam
) {
890 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
891 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
892 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
894 char *p
= cfg
.environmt
;
896 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
901 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
902 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
905 switch (LOWORD(wParam
)) {
907 if (HIWORD(wParam
) == EN_CHANGE
)
908 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
909 sizeof(cfg
.termtype
)-1);
912 if (HIWORD(wParam
) == EN_CHANGE
)
913 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
914 sizeof(cfg
.termspeed
)-1);
917 if (HIWORD(wParam
) == EN_CHANGE
)
918 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
919 sizeof(cfg
.username
)-1);
923 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
926 if (HIWORD(wParam
) == BN_CLICKED
||
927 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
928 char str
[sizeof(cfg
.environmt
)];
930 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
935 p
= str
+ strlen(str
);
937 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
947 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
949 p
[strlen(str
)+1] = '\0';
950 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
952 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
953 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
955 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
956 MB_OK
| MB_ICONERROR
);
961 if (HIWORD(wParam
) != BN_CLICKED
&&
962 HIWORD(wParam
) != BN_DOUBLECLICKED
)
964 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
970 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
997 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1000 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
1001 WPARAM wParam
, LPARAM lParam
) {
1003 char filename
[sizeof(cfg
.keyfile
)];
1007 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
1008 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
1009 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
1010 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
1011 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
1012 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
1015 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
1016 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1019 switch (LOWORD(wParam
)) {
1021 if (HIWORD(wParam
) == EN_CHANGE
)
1022 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
1023 sizeof(cfg
.termtype
)-1);
1026 if (HIWORD(wParam
) == EN_CHANGE
)
1027 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
1028 sizeof(cfg
.username
)-1);
1031 if (HIWORD(wParam
) == BN_CLICKED
||
1032 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1033 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
1035 case IDC3_CIPHER3DES
:
1036 case IDC3_CIPHERBLOWF
:
1037 case IDC3_CIPHERDES
:
1038 if (HIWORD(wParam
) == BN_CLICKED
||
1039 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1040 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1041 cfg
.cipher
= CIPHER_3DES
;
1042 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1043 cfg
.cipher
= CIPHER_BLOWFISH
;
1044 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1045 cfg
.cipher
= CIPHER_DES
;
1049 if (HIWORD(wParam
) == BN_CLICKED
||
1050 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1051 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1054 if (HIWORD(wParam
) == EN_CHANGE
)
1055 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1056 sizeof(cfg
.keyfile
)-1);
1060 * FIXME: this crashes. Find out why.
1062 memset(&of
, 0, sizeof(of
));
1063 #ifdef OPENFILENAME_SIZE_VERSION_400
1064 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1066 of
.lStructSize
= sizeof(of
);
1068 of
.hwndOwner
= hwnd
;
1069 of
.lpstrFilter
= "All Files\0*\0\0\0";
1070 of
.lpstrCustomFilter
= NULL
;
1071 of
.nFilterIndex
= 1;
1072 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1073 of
.nMaxFile
= sizeof(filename
);
1074 of
.lpstrFileTitle
= NULL
;
1075 of
.lpstrInitialDir
= NULL
;
1076 of
.lpstrTitle
= "Select Public Key File";
1078 if (GetOpenFileName(&of
)) {
1079 strcpy(cfg
.keyfile
, filename
);
1080 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1086 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1089 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1090 WPARAM wParam
, LPARAM lParam
) {
1095 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1096 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1098 static int tabs
[4] = {25, 61, 96, 128};
1099 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1102 for (i
=0; i
<256; i
++) {
1104 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1105 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1107 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1112 switch (LOWORD(wParam
)) {
1113 case IDC4_MBWINDOWS
:
1115 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1121 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1126 for (i
=0; i
<256; i
++)
1127 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1130 cfg
.wordness
[i
] = n
;
1131 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1132 LB_DELETESTRING
, i
, 0);
1133 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1134 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1136 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1146 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1149 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1150 WPARAM wParam
, LPARAM lParam
) {
1151 static const char *const colours
[] = {
1152 "Default Foreground", "Default Bold Foreground",
1153 "Default Background", "Default Bold Background",
1154 "Cursor Text", "Cursor Colour",
1155 "ANSI Black", "ANSI Black Bold",
1156 "ANSI Red", "ANSI Red Bold",
1157 "ANSI Green", "ANSI Green Bold",
1158 "ANSI Yellow", "ANSI Yellow Bold",
1159 "ANSI Blue", "ANSI Blue Bold",
1160 "ANSI Magenta", "ANSI Magenta Bold",
1161 "ANSI Cyan", "ANSI Cyan Bold",
1162 "ANSI White", "ANSI White Bold"
1164 static const int permanent
[] = {
1165 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1166 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1167 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1171 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1172 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1175 for (i
=0; i
<22; i
++)
1176 if (cfg
.bold_colour
|| permanent
[i
])
1177 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1178 (LPARAM
) colours
[i
]);
1180 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1181 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1182 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1183 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1186 switch (LOWORD(wParam
)) {
1187 case IDC5_BOLDCOLOUR
:
1188 if (HIWORD(wParam
) == BN_CLICKED
||
1189 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1191 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1192 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1193 if (cfg
.bold_colour
&& n
!=22) {
1194 for (i
=0; i
<22; i
++)
1196 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1198 (LPARAM
) colours
[i
]);
1199 } else if (!cfg
.bold_colour
&& n
!=12) {
1202 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1203 LB_DELETESTRING
, i
, 0);
1208 if (HIWORD(wParam
) == BN_CLICKED
||
1209 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1210 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1213 if (HIWORD(wParam
) == LBN_DBLCLK
||
1214 HIWORD(wParam
) == LBN_SELCHANGE
) {
1215 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1217 if (!cfg
.bold_colour
)
1218 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1219 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1220 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1221 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1225 if (HIWORD(wParam
) == BN_CLICKED
||
1226 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1227 static CHOOSECOLOR cc
;
1228 static DWORD custom
[16] = {0}; /* zero initialisers */
1229 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1231 if (!cfg
.bold_colour
)
1232 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1233 cc
.lStructSize
= sizeof(cc
);
1234 cc
.hwndOwner
= hwnd
;
1235 cc
.hInstance
= (HWND
)hinst
;
1236 cc
.lpCustColors
= custom
;
1237 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1239 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1240 if (ChooseColor(&cc
)) {
1242 (unsigned char) (cc
.rgbResult
& 0xFF);
1244 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1246 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1247 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1249 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1251 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1259 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1262 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1263 WPARAM wParam
, LPARAM lParam
) {
1266 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1267 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1268 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1270 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1271 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1272 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1273 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1274 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1277 switch (LOWORD(wParam
)) {
1279 case IDC6_KOI8WIN1251
:
1280 case IDC6_88592WIN1250
:
1281 cfg
.xlat_enablekoiwin
=
1282 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1283 cfg
.xlat_88592w1250
=
1284 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1286 case IDC6_CAPSLOCKCYR
:
1287 if (HIWORD(wParam
) == BN_CLICKED
||
1288 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1289 cfg
.xlat_capslockcyr
=
1290 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1293 case IDC2_VTXWINDOWS
:
1294 case IDC2_VTOEMANSI
:
1295 case IDC2_VTOEMONLY
:
1296 case IDC2_VTPOORMAN
:
1298 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1299 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1300 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1305 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1308 static DLGPROC panelproc
[NPANELS
] = {
1309 ConnectionProc
, KeyboardProc
, TerminalProc
,
1310 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1312 static char *panelids
[NPANELS
] = {
1313 MAKEINTRESOURCE(IDD_PANEL0
),
1314 MAKEINTRESOURCE(IDD_PANEL1
),
1315 MAKEINTRESOURCE(IDD_PANEL2
),
1316 MAKEINTRESOURCE(IDD_PANEL3
),
1317 MAKEINTRESOURCE(IDD_PANEL35
),
1318 MAKEINTRESOURCE(IDD_PANEL4
),
1319 MAKEINTRESOURCE(IDD_PANEL5
),
1320 MAKEINTRESOURCE(IDD_PANEL6
)
1323 static char *names
[NPANELS
] = {
1324 "Connection", "Keyboard", "Terminal", "Telnet",
1325 "SSH", "Selection", "Colours", "Translation"
1328 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1329 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1331 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1332 WPARAM wParam
, LPARAM lParam
,
1333 int npanels
, int *panelnums
, HWND
*page
) {
1338 { /* centre the window */
1341 hw
= GetDesktopWindow();
1342 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1343 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1344 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1345 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1348 { /* initialise the tab control */
1352 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1353 for (i
=0; i
<npanels
; i
++) {
1354 tab
.mask
= TCIF_TEXT
;
1355 tab
.pszText
= names
[panelnums
[i
]];
1356 TabCtrl_InsertItem (hw
, i
, &tab
);
1358 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1359 hwnd, panelproc[panelnums[0]]);*/
1360 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1361 hwnd
, panelproc
[panelnums
[0]]);
1362 SetWindowLong (*page
, GWL_EXSTYLE
,
1363 GetWindowLong (*page
, GWL_EXSTYLE
) |
1364 WS_EX_CONTROLPARENT
);
1369 if (LOWORD(wParam
) == IDC_TAB
&&
1370 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1371 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1373 DestroyWindow (*page
);
1374 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1375 hwnd, panelproc[panelnums[i]]);*/
1376 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1377 hwnd
, panelproc
[panelnums
[i
]]);
1378 SetWindowLong (*page
, GWL_EXSTYLE
,
1379 GetWindowLong (*page
, GWL_EXSTYLE
) |
1380 WS_EX_CONTROLPARENT
);
1381 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1385 /* case WM_CTLCOLORDLG: */
1386 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1388 switch (LOWORD(wParam
)) {
1391 EndDialog (hwnd
, 1);
1396 EndDialog (hwnd
, 0);
1401 EndDialog (hwnd
, 0);
1404 /* Grrr Explorer will maximize Dialogs! */
1406 if (wParam
== SIZE_MAXIMIZED
)
1413 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1414 WPARAM wParam
, LPARAM lParam
) {
1419 static HWND page
= NULL
;
1421 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1424 * If the Connection panel is active and the Session List
1425 * box is selected, we treat a press of Open to have an
1426 * implicit press of Load preceding it.
1428 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1429 i
= TabCtrl_GetCurSel(hw
);
1430 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1431 page
&& implicit_load_ok
) {
1432 SendMessage (page
, WM_COMMAND
,
1433 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1437 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1438 EnableWindow(hwnd
, 0);
1439 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1440 GetParent(hwnd
), AboutProc
);
1441 EnableWindow(hwnd
, 1);
1443 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1444 MAIN_NPANELS
, mainp
, &page
);
1447 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1448 WPARAM wParam
, LPARAM lParam
) {
1450 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1451 RECONF_NPANELS
, reconfp
, &page
);
1454 void get_sesslist(int allocate
) {
1455 static char *buffer
;
1456 int buflen
, bufsize
, i
, ret
;
1457 char otherbuf
[2048];
1462 if (RegCreateKey(HKEY_CURRENT_USER
,
1463 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1466 buflen
= bufsize
= 0;
1470 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1471 if (ret
== ERROR_SUCCESS
) {
1472 bufsize
= buflen
+ 2048;
1473 buffer
= srealloc(buffer
, bufsize
);
1474 unmungestr(otherbuf
, buffer
+buflen
);
1475 buflen
+= strlen(buffer
+buflen
)+1;
1477 } while (ret
== ERROR_SUCCESS
);
1478 buffer
= srealloc(buffer
, buflen
+1);
1479 buffer
[buflen
] = '\0';
1482 nsessions
= 1; /* "Default Settings" counts as one */
1484 if (strcmp(p
, "Default Settings"))
1490 sessions
= smalloc(nsessions
* sizeof(char *));
1491 sessions
[0] = "Default Settings";
1495 if (strcmp(p
, "Default Settings"))
1506 int do_config (void) {
1510 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1511 get_sesslist(FALSE
);
1516 int do_reconfig (HWND hwnd
) {
1520 backup_cfg
= cfg
; /* structure copy */
1521 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1523 cfg
= backup_cfg
; /* structure copy */
1530 void do_defaults (char *session
) {
1532 load_settings (session
, TRUE
);
1534 load_settings ("Default Settings", FALSE
);
1537 void logevent (char *string
) {
1538 if (nevents
>= negsize
) {
1540 events
= srealloc (events
, negsize
* sizeof(*events
));
1542 events
[nevents
] = smalloc(1+strlen(string
));
1543 strcpy (events
[nevents
], string
);
1546 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1550 void showeventlog (HWND hwnd
) {
1552 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1554 ShowWindow (logbox
, SW_SHOWNORMAL
);
1558 void showabout (HWND hwnd
) {
1560 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1562 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1566 void verify_ssh_host_key(char *host
, char *keystr
) {
1567 char *otherstr
, *mungedhost
;
1571 len
= 1 + strlen(keystr
);
1574 * Now read a saved key in from the registry and see what it
1577 otherstr
= smalloc(len
);
1578 mungedhost
= smalloc(3*strlen(host
)+1);
1579 if (!otherstr
|| !mungedhost
)
1580 fatalbox("Out of memory");
1582 mungestr(host
, mungedhost
);
1584 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1585 &rkey
) != ERROR_SUCCESS
) {
1586 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1587 "in the registry. There is thus no way to tell\n"
1588 "if the remote host is what you think it is.\n"
1589 "Connect anyway?", "PuTTY Problem",
1590 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1593 DWORD readlen
= len
;
1597 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1598 &type
, otherstr
, &readlen
);
1600 if (ret
== ERROR_MORE_DATA
||
1601 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1602 strcmp(otherstr
, keystr
))) {
1603 if (MessageBox(NULL
,
1604 "This host's host key is different from the\n"
1605 "one cached in the registry! Someone may be\n"
1606 "impersonating this host for malicious reasons;\n"
1607 "alternatively, the host key may have changed\n"
1608 "due to sloppy system administration.\n"
1609 "Replace key in registry and connect?",
1610 "PuTTY: Security Warning",
1611 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1613 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1615 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1616 if (MessageBox(NULL
,
1617 "This host's host key is not cached in the\n"
1618 "registry. Do you want to add it to the cache\n"
1619 "and carry on connecting?",
1621 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1623 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,