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 char savedsession
[2048];
513 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
514 WPARAM wParam
, LPARAM lParam
) {
519 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
520 SetDlgItemText (hwnd
, IDC0_SESSEDIT
, savedsession
);
521 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
522 for (i
= 0; i
< nsessions
; i
++)
523 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
524 0, (LPARAM
) (sessions
[i
]));
525 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
526 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
527 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
528 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
529 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
533 * Button release should trigger WM_OK if there was a
534 * previous double click on the session list.
538 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
541 switch (LOWORD(wParam
)) {
542 case IDC0_PROTTELNET
:
545 if (HIWORD(wParam
) == BN_CLICKED
||
546 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
547 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
548 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
549 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
550 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
551 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
552 cfg
.port
= i ?
22 : 23;
553 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
558 if (HIWORD(wParam
) == EN_CHANGE
)
559 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
563 if (HIWORD(wParam
) == EN_CHANGE
)
564 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
567 if (HIWORD(wParam
) == BN_CLICKED
||
568 HIWORD(wParam
) == BN_DOUBLECLICKED
)
569 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
572 if (HIWORD(wParam
) == BN_CLICKED
||
573 HIWORD(wParam
) == BN_DOUBLECLICKED
)
574 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
577 if (HIWORD(wParam
) == EN_CHANGE
) {
578 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
580 GetDlgItemText (hwnd
, IDC0_SESSEDIT
,
581 savedsession
, sizeof(savedsession
)-1);
582 savedsession
[sizeof(savedsession
)-1] = '\0';
586 if (HIWORD(wParam
) == BN_CLICKED
||
587 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
592 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
594 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
600 strcpy (str
, sessions
[n
]);
602 save_settings (str
, !!strcmp(str
, "Default Settings"));
603 get_sesslist (FALSE
);
605 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
607 for (i
= 0; i
< nsessions
; i
++)
608 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
609 0, (LPARAM
) (sessions
[i
]));
610 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
616 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
617 HIWORD(wParam
) != BN_CLICKED
&&
618 HIWORD(wParam
) != BN_DOUBLECLICKED
)
620 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
621 HIWORD(wParam
) != LBN_DBLCLK
)
624 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
630 load_settings (sessions
[n
],
631 !!strcmp(sessions
[n
], "Default Settings"));
632 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
633 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
634 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
635 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
636 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
637 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
638 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
639 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
642 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
644 * A double-click on a saved session should
645 * actually start the session, not just load it.
646 * Unless it's Default Settings or some other
647 * host-less set of saved settings.
656 if (HIWORD(wParam
) == BN_CLICKED
||
657 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
658 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
660 if (n
== LB_ERR
|| n
== 0) {
664 del_session(sessions
[n
]);
665 get_sesslist (FALSE
);
667 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
669 for (i
= 0; i
< nsessions
; i
++)
670 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
671 0, (LPARAM
) (sessions
[i
]));
672 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
677 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
680 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
681 WPARAM wParam
, LPARAM lParam
) {
684 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
685 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
686 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
687 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
688 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
690 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
693 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
694 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
695 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
696 cfg
.nethack_keypad ? IDC1_KPNH
:
697 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
698 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
699 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
700 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
701 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
704 if (HIWORD(wParam
) == BN_CLICKED
||
705 HIWORD(wParam
) == BN_DOUBLECLICKED
)
706 switch (LOWORD(wParam
)) {
709 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
713 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
720 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
724 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
725 cfg
.nethack_keypad
= FALSE
;
728 cfg
.app_keypad
= FALSE
;
729 cfg
.nethack_keypad
= TRUE
;
733 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
736 if (HIWORD(wParam
) == BN_CLICKED
||
737 HIWORD(wParam
) == BN_DOUBLECLICKED
)
738 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
741 if (HIWORD(wParam
) == BN_CLICKED
||
742 HIWORD(wParam
) == BN_DOUBLECLICKED
)
743 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
746 if (HIWORD(wParam
) == BN_CLICKED
||
747 HIWORD(wParam
) == BN_DOUBLECLICKED
)
748 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
751 if (HIWORD(wParam
) == BN_CLICKED
||
752 HIWORD(wParam
) == BN_DOUBLECLICKED
)
753 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
757 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
760 static void fmtfont (char *buf
) {
761 sprintf (buf
, "Font: %s, ", cfg
.font
);
763 strcat(buf
, "bold, ");
764 if (cfg
.fontheight
== 0)
765 strcat (buf
, "default height");
767 sprintf (buf
+strlen(buf
), "%d-%s",
768 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
769 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
772 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
773 WPARAM wParam
, LPARAM lParam
) {
776 char fontstatic
[256];
780 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
781 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
782 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
783 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
784 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
785 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
786 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
787 fmtfont (fontstatic
);
788 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
789 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
790 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
791 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
792 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
793 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
794 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
797 switch (LOWORD(wParam
)) {
799 if (HIWORD(wParam
) == BN_CLICKED
||
800 HIWORD(wParam
) == BN_DOUBLECLICKED
)
801 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
804 if (HIWORD(wParam
) == BN_CLICKED
||
805 HIWORD(wParam
) == BN_DOUBLECLICKED
)
806 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
809 if (HIWORD(wParam
) == BN_CLICKED
||
810 HIWORD(wParam
) == BN_DOUBLECLICKED
)
811 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
814 if (HIWORD(wParam
) == BN_CLICKED
||
815 HIWORD(wParam
) == BN_DOUBLECLICKED
)
816 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
819 if (HIWORD(wParam
) == EN_CHANGE
)
820 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
823 if (HIWORD(wParam
) == EN_CHANGE
)
824 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
827 if (HIWORD(wParam
) == EN_CHANGE
)
828 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
830 case IDC2_CHOOSEFONT
:
831 lf
.lfHeight
= cfg
.fontheight
;
832 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
833 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
834 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
835 lf
.lfCharSet
= cfg
.fontcharset
;
836 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
837 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
838 lf
.lfQuality
= DEFAULT_QUALITY
;
839 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
840 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
841 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
843 cf
.lStructSize
= sizeof(cf
);
846 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
847 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
849 if (ChooseFont (&cf
)) {
850 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
851 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
852 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
853 cfg
.fontcharset
= lf
.lfCharSet
;
854 cfg
.fontheight
= lf
.lfHeight
;
855 fmtfont (fontstatic
);
856 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
860 if (HIWORD(wParam
) == BN_CLICKED
||
861 HIWORD(wParam
) == BN_DOUBLECLICKED
)
862 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
865 if (HIWORD(wParam
) == BN_CLICKED
||
866 HIWORD(wParam
) == BN_DOUBLECLICKED
)
867 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
870 if (HIWORD(wParam
) == BN_CLICKED
||
871 HIWORD(wParam
) == BN_DOUBLECLICKED
)
872 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
875 if (HIWORD(wParam
) == BN_CLICKED
||
876 HIWORD(wParam
) == BN_DOUBLECLICKED
)
877 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
880 if (HIWORD(wParam
) == BN_CLICKED
||
881 HIWORD(wParam
) == BN_DOUBLECLICKED
)
882 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
885 if (HIWORD(wParam
) == BN_CLICKED
||
886 HIWORD(wParam
) == BN_DOUBLECLICKED
)
887 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
892 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
895 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
896 WPARAM wParam
, LPARAM lParam
) {
901 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
902 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
903 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
905 char *p
= cfg
.environmt
;
907 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
912 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
913 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
916 switch (LOWORD(wParam
)) {
918 if (HIWORD(wParam
) == EN_CHANGE
)
919 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
920 sizeof(cfg
.termtype
)-1);
923 if (HIWORD(wParam
) == EN_CHANGE
)
924 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
925 sizeof(cfg
.termspeed
)-1);
928 if (HIWORD(wParam
) == EN_CHANGE
)
929 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
930 sizeof(cfg
.username
)-1);
934 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
937 if (HIWORD(wParam
) == BN_CLICKED
||
938 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
939 char str
[sizeof(cfg
.environmt
)];
941 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
946 p
= str
+ strlen(str
);
948 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
958 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
960 p
[strlen(str
)+1] = '\0';
961 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
963 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
964 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
966 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
967 MB_OK
| MB_ICONERROR
);
972 if (HIWORD(wParam
) != BN_CLICKED
&&
973 HIWORD(wParam
) != BN_DOUBLECLICKED
)
975 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
981 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
1008 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1011 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
1012 WPARAM wParam
, LPARAM lParam
) {
1014 char filename
[sizeof(cfg
.keyfile
)];
1018 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
1019 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
1020 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
1021 CheckDlgButton (hwnd
, IDC3_AGENTFWD
, cfg
.agentfwd
);
1022 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
1023 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
1024 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
1026 CheckRadioButton (hwnd
, IDC3_SSHPROT1
, IDC3_SSHPROT2
,
1027 cfg
.sshprot
== 1 ? IDC3_SSHPROT1
: IDC3_SSHPROT2
);
1028 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
1029 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1032 switch (LOWORD(wParam
)) {
1034 if (HIWORD(wParam
) == EN_CHANGE
)
1035 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
1036 sizeof(cfg
.termtype
)-1);
1039 if (HIWORD(wParam
) == EN_CHANGE
)
1040 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
1041 sizeof(cfg
.username
)-1);
1044 if (HIWORD(wParam
) == BN_CLICKED
||
1045 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1046 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
1049 if (HIWORD(wParam
) == BN_CLICKED
||
1050 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1051 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC3_AGENTFWD
);
1053 case IDC3_CIPHER3DES
:
1054 case IDC3_CIPHERBLOWF
:
1055 case IDC3_CIPHERDES
:
1056 if (HIWORD(wParam
) == BN_CLICKED
||
1057 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1058 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1059 cfg
.cipher
= CIPHER_3DES
;
1060 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1061 cfg
.cipher
= CIPHER_BLOWFISH
;
1062 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1063 cfg
.cipher
= CIPHER_DES
;
1068 if (HIWORD(wParam
) == BN_CLICKED
||
1069 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1070 if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT1
))
1072 else if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT2
))
1077 if (HIWORD(wParam
) == BN_CLICKED
||
1078 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1079 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1082 if (HIWORD(wParam
) == EN_CHANGE
)
1083 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1084 sizeof(cfg
.keyfile
)-1);
1088 * FIXME: this crashes. Find out why.
1090 memset(&of
, 0, sizeof(of
));
1091 #ifdef OPENFILENAME_SIZE_VERSION_400
1092 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1094 of
.lStructSize
= sizeof(of
);
1096 of
.hwndOwner
= hwnd
;
1097 of
.lpstrFilter
= "All Files\0*\0\0\0";
1098 of
.lpstrCustomFilter
= NULL
;
1099 of
.nFilterIndex
= 1;
1100 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1101 of
.nMaxFile
= sizeof(filename
);
1102 of
.lpstrFileTitle
= NULL
;
1103 of
.lpstrInitialDir
= NULL
;
1104 of
.lpstrTitle
= "Select Public Key File";
1106 if (GetOpenFileName(&of
)) {
1107 strcpy(cfg
.keyfile
, filename
);
1108 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1114 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1117 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1118 WPARAM wParam
, LPARAM lParam
) {
1123 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1124 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1126 static int tabs
[4] = {25, 61, 96, 128};
1127 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1130 for (i
=0; i
<256; i
++) {
1132 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1133 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1135 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1140 switch (LOWORD(wParam
)) {
1141 case IDC4_MBWINDOWS
:
1143 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1149 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1154 for (i
=0; i
<256; i
++)
1155 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1158 cfg
.wordness
[i
] = n
;
1159 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1160 LB_DELETESTRING
, i
, 0);
1161 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1162 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1164 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1174 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1177 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1178 WPARAM wParam
, LPARAM lParam
) {
1179 static const char *const colours
[] = {
1180 "Default Foreground", "Default Bold Foreground",
1181 "Default Background", "Default Bold Background",
1182 "Cursor Text", "Cursor Colour",
1183 "ANSI Black", "ANSI Black Bold",
1184 "ANSI Red", "ANSI Red Bold",
1185 "ANSI Green", "ANSI Green Bold",
1186 "ANSI Yellow", "ANSI Yellow Bold",
1187 "ANSI Blue", "ANSI Blue Bold",
1188 "ANSI Magenta", "ANSI Magenta Bold",
1189 "ANSI Cyan", "ANSI Cyan Bold",
1190 "ANSI White", "ANSI White Bold"
1192 static const int permanent
[] = {
1193 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1194 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1195 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1199 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1200 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1203 for (i
=0; i
<22; i
++)
1204 if (cfg
.bold_colour
|| permanent
[i
])
1205 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1206 (LPARAM
) colours
[i
]);
1208 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1209 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1210 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1211 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1214 switch (LOWORD(wParam
)) {
1215 case IDC5_BOLDCOLOUR
:
1216 if (HIWORD(wParam
) == BN_CLICKED
||
1217 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1219 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1220 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1221 if (cfg
.bold_colour
&& n
!=22) {
1222 for (i
=0; i
<22; i
++)
1224 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1226 (LPARAM
) colours
[i
]);
1227 } else if (!cfg
.bold_colour
&& n
!=12) {
1230 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1231 LB_DELETESTRING
, i
, 0);
1236 if (HIWORD(wParam
) == BN_CLICKED
||
1237 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1238 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1241 if (HIWORD(wParam
) == LBN_DBLCLK
||
1242 HIWORD(wParam
) == LBN_SELCHANGE
) {
1243 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1245 if (!cfg
.bold_colour
)
1246 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1247 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1248 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1249 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1253 if (HIWORD(wParam
) == BN_CLICKED
||
1254 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1255 static CHOOSECOLOR cc
;
1256 static DWORD custom
[16] = {0}; /* zero initialisers */
1257 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1259 if (!cfg
.bold_colour
)
1260 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1261 cc
.lStructSize
= sizeof(cc
);
1262 cc
.hwndOwner
= hwnd
;
1263 cc
.hInstance
= (HWND
)hinst
;
1264 cc
.lpCustColors
= custom
;
1265 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1267 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1268 if (ChooseColor(&cc
)) {
1270 (unsigned char) (cc
.rgbResult
& 0xFF);
1272 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1274 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1275 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1277 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1279 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1287 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1290 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1291 WPARAM wParam
, LPARAM lParam
) {
1294 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1295 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1296 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1298 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1299 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1300 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1301 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1302 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1305 switch (LOWORD(wParam
)) {
1307 case IDC6_KOI8WIN1251
:
1308 case IDC6_88592WIN1250
:
1309 cfg
.xlat_enablekoiwin
=
1310 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1311 cfg
.xlat_88592w1250
=
1312 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1314 case IDC6_CAPSLOCKCYR
:
1315 if (HIWORD(wParam
) == BN_CLICKED
||
1316 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1317 cfg
.xlat_capslockcyr
=
1318 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1321 case IDC2_VTXWINDOWS
:
1322 case IDC2_VTOEMANSI
:
1323 case IDC2_VTOEMONLY
:
1324 case IDC2_VTPOORMAN
:
1326 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1327 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1328 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1333 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1336 static DLGPROC panelproc
[NPANELS
] = {
1337 ConnectionProc
, KeyboardProc
, TerminalProc
,
1338 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1340 static char *panelids
[NPANELS
] = {
1341 MAKEINTRESOURCE(IDD_PANEL0
),
1342 MAKEINTRESOURCE(IDD_PANEL1
),
1343 MAKEINTRESOURCE(IDD_PANEL2
),
1344 MAKEINTRESOURCE(IDD_PANEL3
),
1345 MAKEINTRESOURCE(IDD_PANEL35
),
1346 MAKEINTRESOURCE(IDD_PANEL4
),
1347 MAKEINTRESOURCE(IDD_PANEL5
),
1348 MAKEINTRESOURCE(IDD_PANEL6
)
1351 static char *names
[NPANELS
] = {
1352 "Connection", "Keyboard", "Terminal", "Telnet",
1353 "SSH", "Selection", "Colours", "Translation"
1356 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1357 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1359 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1360 WPARAM wParam
, LPARAM lParam
,
1361 int npanels
, int *panelnums
, HWND
*page
) {
1366 { /* centre the window */
1369 hw
= GetDesktopWindow();
1370 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1371 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1372 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1373 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1376 { /* initialise the tab control */
1380 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1381 for (i
=0; i
<npanels
; i
++) {
1382 tab
.mask
= TCIF_TEXT
;
1383 tab
.pszText
= names
[panelnums
[i
]];
1384 TabCtrl_InsertItem (hw
, i
, &tab
);
1386 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1387 hwnd, panelproc[panelnums[0]]);*/
1388 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1389 hwnd
, panelproc
[panelnums
[0]]);
1390 SetWindowLong (*page
, GWL_EXSTYLE
,
1391 GetWindowLong (*page
, GWL_EXSTYLE
) |
1392 WS_EX_CONTROLPARENT
);
1397 if (LOWORD(wParam
) == IDC_TAB
&&
1398 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1399 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1401 DestroyWindow (*page
);
1402 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1403 hwnd, panelproc[panelnums[i]]);*/
1404 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1405 hwnd
, panelproc
[panelnums
[i
]]);
1406 SetWindowLong (*page
, GWL_EXSTYLE
,
1407 GetWindowLong (*page
, GWL_EXSTYLE
) |
1408 WS_EX_CONTROLPARENT
);
1409 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1413 /* case WM_CTLCOLORDLG: */
1414 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1416 switch (LOWORD(wParam
)) {
1419 EndDialog (hwnd
, 1);
1424 EndDialog (hwnd
, 0);
1429 EndDialog (hwnd
, 0);
1432 /* Grrr Explorer will maximize Dialogs! */
1434 if (wParam
== SIZE_MAXIMIZED
)
1441 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1442 WPARAM wParam
, LPARAM lParam
) {
1447 static HWND page
= NULL
;
1449 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1452 * If the Connection panel is active and the Session List
1453 * box is selected, we treat a press of Open to have an
1454 * implicit press of Load preceding it.
1456 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1457 i
= TabCtrl_GetCurSel(hw
);
1458 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1459 page
&& implicit_load_ok
) {
1460 SendMessage (page
, WM_COMMAND
,
1461 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1465 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1466 EnableWindow(hwnd
, 0);
1467 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1468 GetParent(hwnd
), AboutProc
);
1469 EnableWindow(hwnd
, 1);
1471 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1472 MAIN_NPANELS
, mainp
, &page
);
1475 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1476 WPARAM wParam
, LPARAM lParam
) {
1478 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1479 RECONF_NPANELS
, reconfp
, &page
);
1482 void get_sesslist(int allocate
) {
1483 static char *buffer
;
1484 int buflen
, bufsize
, i
, ret
;
1485 char otherbuf
[2048];
1490 if (RegCreateKey(HKEY_CURRENT_USER
,
1491 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1494 buflen
= bufsize
= 0;
1498 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1499 if (ret
== ERROR_SUCCESS
) {
1500 bufsize
= buflen
+ 2048;
1501 buffer
= srealloc(buffer
, bufsize
);
1502 unmungestr(otherbuf
, buffer
+buflen
);
1503 buflen
+= strlen(buffer
+buflen
)+1;
1505 } while (ret
== ERROR_SUCCESS
);
1506 buffer
= srealloc(buffer
, buflen
+1);
1507 buffer
[buflen
] = '\0';
1510 nsessions
= 1; /* "Default Settings" counts as one */
1512 if (strcmp(p
, "Default Settings"))
1518 sessions
= smalloc(nsessions
* sizeof(char *));
1519 sessions
[0] = "Default Settings";
1523 if (strcmp(p
, "Default Settings"))
1534 int do_config (void) {
1538 savedsession
[0] = '\0';
1539 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1540 get_sesslist(FALSE
);
1545 int do_reconfig (HWND hwnd
) {
1549 backup_cfg
= cfg
; /* structure copy */
1550 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1552 cfg
= backup_cfg
; /* structure copy */
1559 void do_defaults (char *session
) {
1561 load_settings (session
, TRUE
);
1563 load_settings ("Default Settings", FALSE
);
1566 void logevent (char *string
) {
1567 if (nevents
>= negsize
) {
1569 events
= srealloc (events
, negsize
* sizeof(*events
));
1571 events
[nevents
] = smalloc(1+strlen(string
));
1572 strcpy (events
[nevents
], string
);
1575 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1579 void showeventlog (HWND hwnd
) {
1581 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1583 ShowWindow (logbox
, SW_SHOWNORMAL
);
1587 void showabout (HWND hwnd
) {
1589 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1591 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1595 void verify_ssh_host_key(char *host
, char *keystr
) {
1596 char *otherstr
, *mungedhost
;
1600 len
= 1 + strlen(keystr
);
1603 * Now read a saved key in from the registry and see what it
1606 otherstr
= smalloc(len
);
1607 mungedhost
= smalloc(3*strlen(host
)+1);
1608 if (!otherstr
|| !mungedhost
)
1609 fatalbox("Out of memory");
1611 mungestr(host
, mungedhost
);
1613 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1614 &rkey
) != ERROR_SUCCESS
) {
1615 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1616 "in the registry. There is thus no way to tell\n"
1617 "if the remote host is what you think it is.\n"
1618 "Connect anyway?", "PuTTY Problem",
1619 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1622 DWORD readlen
= len
;
1626 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1627 &type
, otherstr
, &readlen
);
1629 if (ret
== ERROR_MORE_DATA
||
1630 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1631 strcmp(otherstr
, keystr
))) {
1632 if (MessageBox(NULL
,
1633 "This host's host key is different from the\n"
1634 "one cached in the registry! Someone may be\n"
1635 "impersonating this host for malicious reasons;\n"
1636 "alternatively, the host key may have changed\n"
1637 "due to sloppy system administration.\n"
1638 "Replace key in registry and connect?",
1639 "PuTTY: Security Warning",
1640 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1642 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1644 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1645 if (MessageBox(NULL
,
1646 "This host's host key is not cached in the\n"
1647 "registry. Do you want to add it to the cache\n"
1648 "and carry on connecting?",
1650 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1652 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,