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 wppi (sesskey
, "AgentFwd", cfg
.agentfwd
);
153 wpps (sesskey
, "RemoteCmd", cfg
.remote_cmd
);
154 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
155 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
156 wppi (sesskey
, "AuthTIS", cfg
.try_tis_auth
);
157 wppi (sesskey
, "SshProt", cfg
.sshprot
);
158 wpps (sesskey
, "PublicKeyFile", cfg
.keyfile
);
159 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
160 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
161 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
162 wppi (sesskey
, "LinuxFunctionKeys", cfg
.funky_type
);
163 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
164 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
165 wppi (sesskey
, "NetHackKeypad", cfg
.nethack_keypad
);
166 wppi (sesskey
, "AltF4", cfg
.alt_f4
);
167 wppi (sesskey
, "AltSpace", cfg
.alt_space
);
168 wppi (sesskey
, "LdiscTerm", cfg
.ldisc_term
);
169 wppi (sesskey
, "BlinkCur", cfg
.blink_cur
);
170 wppi (sesskey
, "Beep", cfg
.beep
);
171 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
172 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
173 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
174 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
175 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
176 wppi (sesskey
, "TermWidth", cfg
.width
);
177 wppi (sesskey
, "TermHeight", cfg
.height
);
178 wpps (sesskey
, "Font", cfg
.font
);
179 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
180 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
181 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
182 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
183 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
184 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
185 for (i
=0; i
<22; i
++) {
186 char buf
[20], buf2
[30];
187 sprintf(buf
, "Colour%d", i
);
188 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
189 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
190 wpps (sesskey
, buf
, buf2
);
192 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
193 for (i
=0; i
<256; i
+=32) {
194 char buf
[20], buf2
[256];
196 sprintf(buf
, "Wordness%d", i
);
198 for (j
=i
; j
<i
+32; j
++) {
199 sprintf(buf2
+strlen(buf2
), "%s%d",
200 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
202 wpps (sesskey
, buf
, buf2
);
204 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
205 wppi (sesskey
, "88592Xlat", cfg
.xlat_88592w1250
);
206 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
207 wppi (sesskey
, "ScrollBar", cfg
.scrollbar
);
208 wppi (sesskey
, "ScrollOnKey", cfg
.scroll_on_key
);
209 wppi (sesskey
, "LockSize", cfg
.locksize
);
210 wppi (sesskey
, "BCE", cfg
.bce
);
211 wppi (sesskey
, "BlinkText", cfg
.blinktext
);
213 RegCloseKey(sesskey
);
216 static void del_session (char *section
) {
220 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
223 p
= malloc(3*strlen(section
)+1);
224 mungestr(section
, p
);
225 RegDeleteKey(subkey1
, p
);
228 RegCloseKey(subkey1
);
231 static void load_settings (char *section
, int do_host
) {
233 HKEY subkey1
, sesskey
;
237 p
= malloc(3*strlen(section
)+1);
238 mungestr(section
, p
);
240 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
243 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
246 RegCloseKey(subkey1
);
251 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
252 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
254 gpps (sesskey
, "Protocol", "default", prot
, 10);
255 cfg
.protocol
= default_protocol
;
256 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
257 if (!strcmp(prot
, backends
[i
].name
)) {
258 cfg
.protocol
= backends
[i
].protocol
;
262 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
263 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
264 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
265 sizeof(cfg
.termtype
));
266 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
267 sizeof(cfg
.termspeed
));
269 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
270 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
274 while (*p
&& *p
!= ',') {
287 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
288 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
289 gppi (sesskey
, "AgentFwd", 0, &cfg
.agentfwd
);
290 gpps (sesskey
, "RemoteCmd", "", cfg
.remote_cmd
, sizeof(cfg
.remote_cmd
));
293 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
294 if (!strcmp(cipher
, "blowfish"))
295 cfg
.cipher
= CIPHER_BLOWFISH
;
296 else if (!strcmp(cipher
, "des"))
297 cfg
.cipher
= CIPHER_DES
;
299 cfg
.cipher
= CIPHER_3DES
;
301 gppi (sesskey
, "SshProt", 1, &cfg
.sshprot
);
302 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
303 gpps (sesskey
, "PublicKeyFile", "", cfg
.keyfile
, sizeof(cfg
.keyfile
));
304 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
305 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
306 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
307 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.funky_type
);
308 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
309 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
310 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
311 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
312 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
313 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
314 gppi (sesskey
, "BlinkCur", 0, &cfg
.blink_cur
);
315 gppi (sesskey
, "Beep", 1, &cfg
.beep
);
316 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
317 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
318 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
319 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
320 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
321 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
322 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
323 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
324 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
325 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
326 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
327 gppi (sesskey
, "FontVTMode", VT_OEMANSI
, (int *)&cfg
.vtmode
);
328 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
329 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
330 for (i
=0; i
<22; i
++) {
331 static char *defaults
[] = {
332 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
333 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
334 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
335 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
336 "85,255,255", "187,187,187", "255,255,255"
338 char buf
[20], buf2
[30];
340 sprintf(buf
, "Colour%d", i
);
341 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
342 if(sscanf(buf2
, "%d,%d,%d", &c0
, &c1
, &c2
) == 3) {
343 cfg
.colours
[i
][0] = c0
;
344 cfg
.colours
[i
][1] = c1
;
345 cfg
.colours
[i
][2] = c2
;
348 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
349 for (i
=0; i
<256; i
+=32) {
350 static char *defaults
[] = {
351 "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",
352 "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",
353 "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",
354 "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",
355 "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",
356 "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",
357 "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 "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"
360 char buf
[20], buf2
[256], *p
;
362 sprintf(buf
, "Wordness%d", i
);
363 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
365 for (j
=i
; j
<i
+32; j
++) {
367 while (*p
&& *p
!= ',') p
++;
368 if (*p
== ',') *p
++ = '\0';
369 cfg
.wordness
[j
] = atoi(q
);
372 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
373 gppi (sesskey
, "88592Xlat", 0, &cfg
.xlat_88592w1250
);
374 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
375 gppi (sesskey
, "ScrollBar", 1, &cfg
.scrollbar
);
376 gppi (sesskey
, "ScrollOnKey", 0, &cfg
.scroll_on_key
);
377 gppi (sesskey
, "LockSize", 0, &cfg
.locksize
);
378 gppi (sesskey
, "BCE", 0, &cfg
.bce
);
379 gppi (sesskey
, "BlinkText", 0, &cfg
.blinktext
);
381 RegCloseKey(sesskey
);
384 static void force_normal(HWND hwnd
)
386 static int recurse
= 0;
393 wp
.length
= sizeof(wp
);
394 if (GetWindowPlacement(hwnd
, &wp
))
396 wp
.showCmd
= SW_SHOWNORMAL
;
397 SetWindowPlacement(hwnd
, &wp
);
402 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
405 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
410 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
411 WPARAM wParam
, LPARAM lParam
) {
416 for (i
=0; i
<nevents
; i
++)
417 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
418 0, (LPARAM
)events
[i
]);
420 /* case WM_CTLCOLORDLG: */
421 /* return (int) GetStockObject (LTGRAY_BRUSH); */
423 switch (LOWORD(wParam
)) {
426 DestroyWindow (hwnd
);
432 DestroyWindow (hwnd
);
438 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
439 WPARAM wParam
, LPARAM lParam
) {
444 switch (LOWORD(wParam
)) {
447 DestroyWindow (hwnd
);
453 DestroyWindow (hwnd
);
459 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
460 WPARAM wParam
, LPARAM lParam
) {
463 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
465 /* case WM_CTLCOLORDLG: */
466 /* return (int) GetStockObject (LTGRAY_BRUSH); */
467 /* case WM_CTLCOLORSTATIC: */
468 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
469 /* return (int) GetStockObject (LTGRAY_BRUSH); */
471 switch (LOWORD(wParam
)) {
474 DestroyWindow (hwnd
);
477 EnableWindow(hwnd
, 0);
478 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
480 EnableWindow(hwnd
, 1);
486 DestroyWindow (hwnd
);
492 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
493 WPARAM wParam
, LPARAM lParam
) {
496 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
498 /* case WM_CTLCOLORDLG: */
499 /* return (int) GetStockObject (LTGRAY_BRUSH); */
500 /* case WM_CTLCOLORSTATIC: */
501 /* case WM_CTLCOLORBTN: */
502 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
503 /* return (int) GetStockObject (LTGRAY_BRUSH); */
505 DestroyWindow (hwnd
);
511 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
512 WPARAM wParam
, LPARAM lParam
) {
517 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
518 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
519 for (i
= 0; i
< nsessions
; i
++)
520 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
521 0, (LPARAM
) (sessions
[i
]));
522 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
523 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
524 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
525 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
526 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
530 * Button release should trigger WM_OK if there was a
531 * previous double click on the session list.
535 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
538 switch (LOWORD(wParam
)) {
539 case IDC0_PROTTELNET
:
542 if (HIWORD(wParam
) == BN_CLICKED
||
543 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
544 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
545 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
546 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
547 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
548 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
549 cfg
.port
= i ?
22 : 23;
550 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
555 if (HIWORD(wParam
) == EN_CHANGE
)
556 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
560 if (HIWORD(wParam
) == EN_CHANGE
)
561 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
564 if (HIWORD(wParam
) == BN_CLICKED
||
565 HIWORD(wParam
) == BN_DOUBLECLICKED
)
566 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
569 if (HIWORD(wParam
) == BN_CLICKED
||
570 HIWORD(wParam
) == BN_DOUBLECLICKED
)
571 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
574 if (HIWORD(wParam
) == EN_CHANGE
)
575 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
579 if (HIWORD(wParam
) == BN_CLICKED
||
580 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
585 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
587 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
593 strcpy (str
, sessions
[n
]);
595 save_settings (str
, !!strcmp(str
, "Default Settings"));
596 get_sesslist (FALSE
);
598 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
600 for (i
= 0; i
< nsessions
; i
++)
601 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
602 0, (LPARAM
) (sessions
[i
]));
603 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
609 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
610 HIWORD(wParam
) != BN_CLICKED
&&
611 HIWORD(wParam
) != BN_DOUBLECLICKED
)
613 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
614 HIWORD(wParam
) != LBN_DBLCLK
)
617 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
623 load_settings (sessions
[n
],
624 !!strcmp(sessions
[n
], "Default Settings"));
625 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
626 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
627 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
628 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
629 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
630 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
631 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
632 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
635 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
637 * A double-click on a saved session should
638 * actually start the session, not just load it.
639 * Unless it's Default Settings or some other
640 * host-less set of saved settings.
649 if (HIWORD(wParam
) == BN_CLICKED
||
650 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
651 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
653 if (n
== LB_ERR
|| n
== 0) {
657 del_session(sessions
[n
]);
658 get_sesslist (FALSE
);
660 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
662 for (i
= 0; i
< nsessions
; i
++)
663 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
664 0, (LPARAM
) (sessions
[i
]));
665 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
670 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
673 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
674 WPARAM wParam
, LPARAM lParam
) {
677 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
678 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
679 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
680 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
681 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
683 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
686 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
687 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
688 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
689 cfg
.nethack_keypad ? IDC1_KPNH
:
690 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
691 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
692 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
693 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
694 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
697 if (HIWORD(wParam
) == BN_CLICKED
||
698 HIWORD(wParam
) == BN_DOUBLECLICKED
)
699 switch (LOWORD(wParam
)) {
702 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
706 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
713 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
717 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
718 cfg
.nethack_keypad
= FALSE
;
721 cfg
.app_keypad
= FALSE
;
722 cfg
.nethack_keypad
= TRUE
;
726 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
729 if (HIWORD(wParam
) == BN_CLICKED
||
730 HIWORD(wParam
) == BN_DOUBLECLICKED
)
731 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
734 if (HIWORD(wParam
) == BN_CLICKED
||
735 HIWORD(wParam
) == BN_DOUBLECLICKED
)
736 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
739 if (HIWORD(wParam
) == BN_CLICKED
||
740 HIWORD(wParam
) == BN_DOUBLECLICKED
)
741 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
744 if (HIWORD(wParam
) == BN_CLICKED
||
745 HIWORD(wParam
) == BN_DOUBLECLICKED
)
746 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
750 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
753 static void fmtfont (char *buf
) {
754 sprintf (buf
, "Font: %s, ", cfg
.font
);
756 strcat(buf
, "bold, ");
757 if (cfg
.fontheight
== 0)
758 strcat (buf
, "default height");
760 sprintf (buf
+strlen(buf
), "%d-%s",
761 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
762 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
765 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
766 WPARAM wParam
, LPARAM lParam
) {
769 char fontstatic
[256];
773 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
774 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
775 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
776 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
777 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
778 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
779 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
780 fmtfont (fontstatic
);
781 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
782 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
783 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
784 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
785 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
786 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
787 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
790 switch (LOWORD(wParam
)) {
792 if (HIWORD(wParam
) == BN_CLICKED
||
793 HIWORD(wParam
) == BN_DOUBLECLICKED
)
794 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
797 if (HIWORD(wParam
) == BN_CLICKED
||
798 HIWORD(wParam
) == BN_DOUBLECLICKED
)
799 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
802 if (HIWORD(wParam
) == BN_CLICKED
||
803 HIWORD(wParam
) == BN_DOUBLECLICKED
)
804 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
807 if (HIWORD(wParam
) == BN_CLICKED
||
808 HIWORD(wParam
) == BN_DOUBLECLICKED
)
809 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
812 if (HIWORD(wParam
) == EN_CHANGE
)
813 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
816 if (HIWORD(wParam
) == EN_CHANGE
)
817 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
820 if (HIWORD(wParam
) == EN_CHANGE
)
821 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
823 case IDC2_CHOOSEFONT
:
824 lf
.lfHeight
= cfg
.fontheight
;
825 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
826 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
827 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
828 lf
.lfCharSet
= cfg
.fontcharset
;
829 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
830 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
831 lf
.lfQuality
= DEFAULT_QUALITY
;
832 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
833 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
834 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
836 cf
.lStructSize
= sizeof(cf
);
839 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
840 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
842 if (ChooseFont (&cf
)) {
843 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
844 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
845 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
846 cfg
.fontcharset
= lf
.lfCharSet
;
847 cfg
.fontheight
= lf
.lfHeight
;
848 fmtfont (fontstatic
);
849 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
853 if (HIWORD(wParam
) == BN_CLICKED
||
854 HIWORD(wParam
) == BN_DOUBLECLICKED
)
855 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
858 if (HIWORD(wParam
) == BN_CLICKED
||
859 HIWORD(wParam
) == BN_DOUBLECLICKED
)
860 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
863 if (HIWORD(wParam
) == BN_CLICKED
||
864 HIWORD(wParam
) == BN_DOUBLECLICKED
)
865 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
868 if (HIWORD(wParam
) == BN_CLICKED
||
869 HIWORD(wParam
) == BN_DOUBLECLICKED
)
870 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
873 if (HIWORD(wParam
) == BN_CLICKED
||
874 HIWORD(wParam
) == BN_DOUBLECLICKED
)
875 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
878 if (HIWORD(wParam
) == BN_CLICKED
||
879 HIWORD(wParam
) == BN_DOUBLECLICKED
)
880 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
885 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
888 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
889 WPARAM wParam
, LPARAM lParam
) {
894 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
895 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
896 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
898 char *p
= cfg
.environmt
;
900 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
905 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
906 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
909 switch (LOWORD(wParam
)) {
911 if (HIWORD(wParam
) == EN_CHANGE
)
912 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
913 sizeof(cfg
.termtype
)-1);
916 if (HIWORD(wParam
) == EN_CHANGE
)
917 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
918 sizeof(cfg
.termspeed
)-1);
921 if (HIWORD(wParam
) == EN_CHANGE
)
922 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
923 sizeof(cfg
.username
)-1);
927 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
930 if (HIWORD(wParam
) == BN_CLICKED
||
931 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
932 char str
[sizeof(cfg
.environmt
)];
934 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
939 p
= str
+ strlen(str
);
941 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
951 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
953 p
[strlen(str
)+1] = '\0';
954 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
956 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
957 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
959 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
960 MB_OK
| MB_ICONERROR
);
965 if (HIWORD(wParam
) != BN_CLICKED
&&
966 HIWORD(wParam
) != BN_DOUBLECLICKED
)
968 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
974 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
1001 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1004 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
1005 WPARAM wParam
, LPARAM lParam
) {
1007 char filename
[sizeof(cfg
.keyfile
)];
1011 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
1012 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
1013 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
1014 CheckDlgButton (hwnd
, IDC3_AGENTFWD
, cfg
.agentfwd
);
1015 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
1016 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
1017 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
1019 CheckRadioButton (hwnd
, IDC3_SSHPROT1
, IDC3_SSHPROT2
,
1020 cfg
.sshprot
== 1 ? IDC3_SSHPROT1
: IDC3_SSHPROT2
);
1021 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
1022 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1025 switch (LOWORD(wParam
)) {
1027 if (HIWORD(wParam
) == EN_CHANGE
)
1028 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
1029 sizeof(cfg
.termtype
)-1);
1032 if (HIWORD(wParam
) == EN_CHANGE
)
1033 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
1034 sizeof(cfg
.username
)-1);
1037 if (HIWORD(wParam
) == BN_CLICKED
||
1038 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1039 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
1042 if (HIWORD(wParam
) == BN_CLICKED
||
1043 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1044 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC3_AGENTFWD
);
1046 case IDC3_CIPHER3DES
:
1047 case IDC3_CIPHERBLOWF
:
1048 case IDC3_CIPHERDES
:
1049 if (HIWORD(wParam
) == BN_CLICKED
||
1050 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1051 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1052 cfg
.cipher
= CIPHER_3DES
;
1053 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1054 cfg
.cipher
= CIPHER_BLOWFISH
;
1055 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1056 cfg
.cipher
= CIPHER_DES
;
1061 if (HIWORD(wParam
) == BN_CLICKED
||
1062 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1063 if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT1
))
1065 else if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT2
))
1070 if (HIWORD(wParam
) == BN_CLICKED
||
1071 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1072 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1075 if (HIWORD(wParam
) == EN_CHANGE
)
1076 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1077 sizeof(cfg
.keyfile
)-1);
1081 * FIXME: this crashes. Find out why.
1083 memset(&of
, 0, sizeof(of
));
1084 #ifdef OPENFILENAME_SIZE_VERSION_400
1085 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1087 of
.lStructSize
= sizeof(of
);
1089 of
.hwndOwner
= hwnd
;
1090 of
.lpstrFilter
= "All Files\0*\0\0\0";
1091 of
.lpstrCustomFilter
= NULL
;
1092 of
.nFilterIndex
= 1;
1093 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1094 of
.nMaxFile
= sizeof(filename
);
1095 of
.lpstrFileTitle
= NULL
;
1096 of
.lpstrInitialDir
= NULL
;
1097 of
.lpstrTitle
= "Select Public Key File";
1099 if (GetOpenFileName(&of
)) {
1100 strcpy(cfg
.keyfile
, filename
);
1101 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1107 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1110 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1111 WPARAM wParam
, LPARAM lParam
) {
1116 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1117 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1119 static int tabs
[4] = {25, 61, 96, 128};
1120 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1123 for (i
=0; i
<256; i
++) {
1125 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1126 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1128 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1133 switch (LOWORD(wParam
)) {
1134 case IDC4_MBWINDOWS
:
1136 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1142 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1147 for (i
=0; i
<256; i
++)
1148 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1151 cfg
.wordness
[i
] = n
;
1152 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1153 LB_DELETESTRING
, i
, 0);
1154 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1155 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1157 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1167 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1170 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1171 WPARAM wParam
, LPARAM lParam
) {
1172 static const char *const colours
[] = {
1173 "Default Foreground", "Default Bold Foreground",
1174 "Default Background", "Default Bold Background",
1175 "Cursor Text", "Cursor Colour",
1176 "ANSI Black", "ANSI Black Bold",
1177 "ANSI Red", "ANSI Red Bold",
1178 "ANSI Green", "ANSI Green Bold",
1179 "ANSI Yellow", "ANSI Yellow Bold",
1180 "ANSI Blue", "ANSI Blue Bold",
1181 "ANSI Magenta", "ANSI Magenta Bold",
1182 "ANSI Cyan", "ANSI Cyan Bold",
1183 "ANSI White", "ANSI White Bold"
1185 static const int permanent
[] = {
1186 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1187 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1188 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1192 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1193 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1196 for (i
=0; i
<22; i
++)
1197 if (cfg
.bold_colour
|| permanent
[i
])
1198 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1199 (LPARAM
) colours
[i
]);
1201 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1202 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1203 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1204 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1207 switch (LOWORD(wParam
)) {
1208 case IDC5_BOLDCOLOUR
:
1209 if (HIWORD(wParam
) == BN_CLICKED
||
1210 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1212 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1213 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1214 if (cfg
.bold_colour
&& n
!=22) {
1215 for (i
=0; i
<22; i
++)
1217 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1219 (LPARAM
) colours
[i
]);
1220 } else if (!cfg
.bold_colour
&& n
!=12) {
1223 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1224 LB_DELETESTRING
, i
, 0);
1229 if (HIWORD(wParam
) == BN_CLICKED
||
1230 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1231 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1234 if (HIWORD(wParam
) == LBN_DBLCLK
||
1235 HIWORD(wParam
) == LBN_SELCHANGE
) {
1236 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1238 if (!cfg
.bold_colour
)
1239 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1240 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1241 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1242 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1246 if (HIWORD(wParam
) == BN_CLICKED
||
1247 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1248 static CHOOSECOLOR cc
;
1249 static DWORD custom
[16] = {0}; /* zero initialisers */
1250 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1252 if (!cfg
.bold_colour
)
1253 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1254 cc
.lStructSize
= sizeof(cc
);
1255 cc
.hwndOwner
= hwnd
;
1256 cc
.hInstance
= (HWND
)hinst
;
1257 cc
.lpCustColors
= custom
;
1258 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1260 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1261 if (ChooseColor(&cc
)) {
1263 (unsigned char) (cc
.rgbResult
& 0xFF);
1265 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1267 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1268 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1270 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1272 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1280 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1283 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1284 WPARAM wParam
, LPARAM lParam
) {
1287 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1288 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1289 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1291 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1292 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1293 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1294 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1295 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1298 switch (LOWORD(wParam
)) {
1300 case IDC6_KOI8WIN1251
:
1301 case IDC6_88592WIN1250
:
1302 cfg
.xlat_enablekoiwin
=
1303 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1304 cfg
.xlat_88592w1250
=
1305 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1307 case IDC6_CAPSLOCKCYR
:
1308 if (HIWORD(wParam
) == BN_CLICKED
||
1309 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1310 cfg
.xlat_capslockcyr
=
1311 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1314 case IDC2_VTXWINDOWS
:
1315 case IDC2_VTOEMANSI
:
1316 case IDC2_VTOEMONLY
:
1317 case IDC2_VTPOORMAN
:
1319 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1320 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1321 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1326 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1329 static DLGPROC panelproc
[NPANELS
] = {
1330 ConnectionProc
, KeyboardProc
, TerminalProc
,
1331 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1333 static char *panelids
[NPANELS
] = {
1334 MAKEINTRESOURCE(IDD_PANEL0
),
1335 MAKEINTRESOURCE(IDD_PANEL1
),
1336 MAKEINTRESOURCE(IDD_PANEL2
),
1337 MAKEINTRESOURCE(IDD_PANEL3
),
1338 MAKEINTRESOURCE(IDD_PANEL35
),
1339 MAKEINTRESOURCE(IDD_PANEL4
),
1340 MAKEINTRESOURCE(IDD_PANEL5
),
1341 MAKEINTRESOURCE(IDD_PANEL6
)
1344 static char *names
[NPANELS
] = {
1345 "Connection", "Keyboard", "Terminal", "Telnet",
1346 "SSH", "Selection", "Colours", "Translation"
1349 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1350 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1352 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1353 WPARAM wParam
, LPARAM lParam
,
1354 int npanels
, int *panelnums
, HWND
*page
) {
1359 { /* centre the window */
1362 hw
= GetDesktopWindow();
1363 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1364 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1365 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1366 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1369 { /* initialise the tab control */
1373 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1374 for (i
=0; i
<npanels
; i
++) {
1375 tab
.mask
= TCIF_TEXT
;
1376 tab
.pszText
= names
[panelnums
[i
]];
1377 TabCtrl_InsertItem (hw
, i
, &tab
);
1379 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1380 hwnd, panelproc[panelnums[0]]);*/
1381 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1382 hwnd
, panelproc
[panelnums
[0]]);
1383 SetWindowLong (*page
, GWL_EXSTYLE
,
1384 GetWindowLong (*page
, GWL_EXSTYLE
) |
1385 WS_EX_CONTROLPARENT
);
1390 if (LOWORD(wParam
) == IDC_TAB
&&
1391 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1392 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1394 DestroyWindow (*page
);
1395 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1396 hwnd, panelproc[panelnums[i]]);*/
1397 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1398 hwnd
, panelproc
[panelnums
[i
]]);
1399 SetWindowLong (*page
, GWL_EXSTYLE
,
1400 GetWindowLong (*page
, GWL_EXSTYLE
) |
1401 WS_EX_CONTROLPARENT
);
1402 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1406 /* case WM_CTLCOLORDLG: */
1407 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1409 switch (LOWORD(wParam
)) {
1412 EndDialog (hwnd
, 1);
1417 EndDialog (hwnd
, 0);
1422 EndDialog (hwnd
, 0);
1425 /* Grrr Explorer will maximize Dialogs! */
1427 if (wParam
== SIZE_MAXIMIZED
)
1434 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1435 WPARAM wParam
, LPARAM lParam
) {
1440 static HWND page
= NULL
;
1442 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1445 * If the Connection panel is active and the Session List
1446 * box is selected, we treat a press of Open to have an
1447 * implicit press of Load preceding it.
1449 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1450 i
= TabCtrl_GetCurSel(hw
);
1451 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1452 page
&& implicit_load_ok
) {
1453 SendMessage (page
, WM_COMMAND
,
1454 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1458 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1459 EnableWindow(hwnd
, 0);
1460 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1461 GetParent(hwnd
), AboutProc
);
1462 EnableWindow(hwnd
, 1);
1464 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1465 MAIN_NPANELS
, mainp
, &page
);
1468 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1469 WPARAM wParam
, LPARAM lParam
) {
1471 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1472 RECONF_NPANELS
, reconfp
, &page
);
1475 void get_sesslist(int allocate
) {
1476 static char *buffer
;
1477 int buflen
, bufsize
, i
, ret
;
1478 char otherbuf
[2048];
1483 if (RegCreateKey(HKEY_CURRENT_USER
,
1484 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1487 buflen
= bufsize
= 0;
1491 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1492 if (ret
== ERROR_SUCCESS
) {
1493 bufsize
= buflen
+ 2048;
1494 buffer
= srealloc(buffer
, bufsize
);
1495 unmungestr(otherbuf
, buffer
+buflen
);
1496 buflen
+= strlen(buffer
+buflen
)+1;
1498 } while (ret
== ERROR_SUCCESS
);
1499 buffer
= srealloc(buffer
, buflen
+1);
1500 buffer
[buflen
] = '\0';
1503 nsessions
= 1; /* "Default Settings" counts as one */
1505 if (strcmp(p
, "Default Settings"))
1511 sessions
= smalloc(nsessions
* sizeof(char *));
1512 sessions
[0] = "Default Settings";
1516 if (strcmp(p
, "Default Settings"))
1527 int do_config (void) {
1531 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1532 get_sesslist(FALSE
);
1537 int do_reconfig (HWND hwnd
) {
1541 backup_cfg
= cfg
; /* structure copy */
1542 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1544 cfg
= backup_cfg
; /* structure copy */
1551 void do_defaults (char *session
) {
1553 load_settings (session
, TRUE
);
1555 load_settings ("Default Settings", FALSE
);
1558 void logevent (char *string
) {
1559 if (nevents
>= negsize
) {
1561 events
= srealloc (events
, negsize
* sizeof(*events
));
1563 events
[nevents
] = smalloc(1+strlen(string
));
1564 strcpy (events
[nevents
], string
);
1567 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1571 void showeventlog (HWND hwnd
) {
1573 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1575 ShowWindow (logbox
, SW_SHOWNORMAL
);
1579 void showabout (HWND hwnd
) {
1581 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1583 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1587 void verify_ssh_host_key(char *host
, char *keystr
) {
1588 char *otherstr
, *mungedhost
;
1592 len
= 1 + strlen(keystr
);
1595 * Now read a saved key in from the registry and see what it
1598 otherstr
= smalloc(len
);
1599 mungedhost
= smalloc(3*strlen(host
)+1);
1600 if (!otherstr
|| !mungedhost
)
1601 fatalbox("Out of memory");
1603 mungestr(host
, mungedhost
);
1605 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1606 &rkey
) != ERROR_SUCCESS
) {
1607 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1608 "in the registry. There is thus no way to tell\n"
1609 "if the remote host is what you think it is.\n"
1610 "Connect anyway?", "PuTTY Problem",
1611 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1614 DWORD readlen
= len
;
1618 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1619 &type
, otherstr
, &readlen
);
1621 if (ret
== ERROR_MORE_DATA
||
1622 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1623 strcmp(otherstr
, keystr
))) {
1624 if (MessageBox(NULL
,
1625 "This host's host key is different from the\n"
1626 "one cached in the registry! Someone may be\n"
1627 "impersonating this host for malicious reasons;\n"
1628 "alternatively, the host key may have changed\n"
1629 "due to sloppy system administration.\n"
1630 "Replace key in registry and connect?",
1631 "PuTTY: Security Warning",
1632 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1634 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1636 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1637 if (MessageBox(NULL
,
1638 "This host's host key is not cached in the\n"
1639 "registry. Do you want to add it to the cache\n"
1640 "and carry on connecting?",
1642 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1644 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,