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);
481 SetActiveWindow(hwnd
);
487 DestroyWindow (hwnd
);
493 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
494 WPARAM wParam
, LPARAM lParam
) {
497 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
499 /* case WM_CTLCOLORDLG: */
500 /* return (int) GetStockObject (LTGRAY_BRUSH); */
501 /* case WM_CTLCOLORSTATIC: */
502 /* case WM_CTLCOLORBTN: */
503 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
504 /* return (int) GetStockObject (LTGRAY_BRUSH); */
506 DestroyWindow (hwnd
);
512 static char savedsession
[2048];
514 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
515 WPARAM wParam
, LPARAM lParam
) {
520 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
521 SetDlgItemText (hwnd
, IDC0_SESSEDIT
, savedsession
);
522 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
523 for (i
= 0; i
< nsessions
; i
++)
524 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
525 0, (LPARAM
) (sessions
[i
]));
526 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
527 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
528 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
529 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
530 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
534 * Button release should trigger WM_OK if there was a
535 * previous double click on the session list.
539 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
542 switch (LOWORD(wParam
)) {
543 case IDC0_PROTTELNET
:
546 if (HIWORD(wParam
) == BN_CLICKED
||
547 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
548 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
549 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
550 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
551 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
552 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
553 cfg
.port
= i ?
22 : 23;
554 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
559 if (HIWORD(wParam
) == EN_CHANGE
)
560 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
564 if (HIWORD(wParam
) == EN_CHANGE
)
565 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
568 if (HIWORD(wParam
) == BN_CLICKED
||
569 HIWORD(wParam
) == BN_DOUBLECLICKED
)
570 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
573 if (HIWORD(wParam
) == BN_CLICKED
||
574 HIWORD(wParam
) == BN_DOUBLECLICKED
)
575 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
578 if (HIWORD(wParam
) == EN_CHANGE
) {
579 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
581 GetDlgItemText (hwnd
, IDC0_SESSEDIT
,
582 savedsession
, sizeof(savedsession
)-1);
583 savedsession
[sizeof(savedsession
)-1] = '\0';
587 if (HIWORD(wParam
) == BN_CLICKED
||
588 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
593 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
595 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
601 strcpy (str
, sessions
[n
]);
603 save_settings (str
, !!strcmp(str
, "Default Settings"));
604 get_sesslist (FALSE
);
606 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
608 for (i
= 0; i
< nsessions
; i
++)
609 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
610 0, (LPARAM
) (sessions
[i
]));
611 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
617 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
618 HIWORD(wParam
) != BN_CLICKED
&&
619 HIWORD(wParam
) != BN_DOUBLECLICKED
)
621 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
622 HIWORD(wParam
) != LBN_DBLCLK
)
625 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
631 load_settings (sessions
[n
],
632 !!strcmp(sessions
[n
], "Default Settings"));
633 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
634 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
635 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
636 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
637 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
638 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
639 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
640 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
643 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
645 * A double-click on a saved session should
646 * actually start the session, not just load it.
647 * Unless it's Default Settings or some other
648 * host-less set of saved settings.
657 if (HIWORD(wParam
) == BN_CLICKED
||
658 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
659 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
661 if (n
== LB_ERR
|| n
== 0) {
665 del_session(sessions
[n
]);
666 get_sesslist (FALSE
);
668 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
670 for (i
= 0; i
< nsessions
; i
++)
671 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
672 0, (LPARAM
) (sessions
[i
]));
673 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
678 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
681 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
682 WPARAM wParam
, LPARAM lParam
) {
685 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
686 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
687 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
688 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
689 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
691 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
694 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
695 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
696 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
697 cfg
.nethack_keypad ? IDC1_KPNH
:
698 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
699 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
700 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
701 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
702 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
705 if (HIWORD(wParam
) == BN_CLICKED
||
706 HIWORD(wParam
) == BN_DOUBLECLICKED
)
707 switch (LOWORD(wParam
)) {
710 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
714 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
721 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
725 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
726 cfg
.nethack_keypad
= FALSE
;
729 cfg
.app_keypad
= FALSE
;
730 cfg
.nethack_keypad
= TRUE
;
734 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
737 if (HIWORD(wParam
) == BN_CLICKED
||
738 HIWORD(wParam
) == BN_DOUBLECLICKED
)
739 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
742 if (HIWORD(wParam
) == BN_CLICKED
||
743 HIWORD(wParam
) == BN_DOUBLECLICKED
)
744 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
747 if (HIWORD(wParam
) == BN_CLICKED
||
748 HIWORD(wParam
) == BN_DOUBLECLICKED
)
749 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
752 if (HIWORD(wParam
) == BN_CLICKED
||
753 HIWORD(wParam
) == BN_DOUBLECLICKED
)
754 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
758 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
761 static void fmtfont (char *buf
) {
762 sprintf (buf
, "Font: %s, ", cfg
.font
);
764 strcat(buf
, "bold, ");
765 if (cfg
.fontheight
== 0)
766 strcat (buf
, "default height");
768 sprintf (buf
+strlen(buf
), "%d-%s",
769 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
770 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
773 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
774 WPARAM wParam
, LPARAM lParam
) {
777 char fontstatic
[256];
781 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
782 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
783 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
784 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
785 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
786 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
787 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
788 fmtfont (fontstatic
);
789 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
790 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
791 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
792 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
793 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
794 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
795 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
798 switch (LOWORD(wParam
)) {
800 if (HIWORD(wParam
) == BN_CLICKED
||
801 HIWORD(wParam
) == BN_DOUBLECLICKED
)
802 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
805 if (HIWORD(wParam
) == BN_CLICKED
||
806 HIWORD(wParam
) == BN_DOUBLECLICKED
)
807 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
810 if (HIWORD(wParam
) == BN_CLICKED
||
811 HIWORD(wParam
) == BN_DOUBLECLICKED
)
812 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
815 if (HIWORD(wParam
) == BN_CLICKED
||
816 HIWORD(wParam
) == BN_DOUBLECLICKED
)
817 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
820 if (HIWORD(wParam
) == EN_CHANGE
)
821 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
824 if (HIWORD(wParam
) == EN_CHANGE
)
825 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
828 if (HIWORD(wParam
) == EN_CHANGE
)
829 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
831 case IDC2_CHOOSEFONT
:
832 lf
.lfHeight
= cfg
.fontheight
;
833 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
834 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
835 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
836 lf
.lfCharSet
= cfg
.fontcharset
;
837 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
838 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
839 lf
.lfQuality
= DEFAULT_QUALITY
;
840 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
841 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
842 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
844 cf
.lStructSize
= sizeof(cf
);
847 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
848 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
850 if (ChooseFont (&cf
)) {
851 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
852 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
853 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
854 cfg
.fontcharset
= lf
.lfCharSet
;
855 cfg
.fontheight
= lf
.lfHeight
;
856 fmtfont (fontstatic
);
857 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
861 if (HIWORD(wParam
) == BN_CLICKED
||
862 HIWORD(wParam
) == BN_DOUBLECLICKED
)
863 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
866 if (HIWORD(wParam
) == BN_CLICKED
||
867 HIWORD(wParam
) == BN_DOUBLECLICKED
)
868 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
871 if (HIWORD(wParam
) == BN_CLICKED
||
872 HIWORD(wParam
) == BN_DOUBLECLICKED
)
873 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
876 if (HIWORD(wParam
) == BN_CLICKED
||
877 HIWORD(wParam
) == BN_DOUBLECLICKED
)
878 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
881 if (HIWORD(wParam
) == BN_CLICKED
||
882 HIWORD(wParam
) == BN_DOUBLECLICKED
)
883 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
886 if (HIWORD(wParam
) == BN_CLICKED
||
887 HIWORD(wParam
) == BN_DOUBLECLICKED
)
888 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
893 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
896 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
897 WPARAM wParam
, LPARAM lParam
) {
902 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
903 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
904 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
906 char *p
= cfg
.environmt
;
908 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
913 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
914 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
917 switch (LOWORD(wParam
)) {
919 if (HIWORD(wParam
) == EN_CHANGE
)
920 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
921 sizeof(cfg
.termtype
)-1);
924 if (HIWORD(wParam
) == EN_CHANGE
)
925 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
926 sizeof(cfg
.termspeed
)-1);
929 if (HIWORD(wParam
) == EN_CHANGE
)
930 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
931 sizeof(cfg
.username
)-1);
935 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
938 if (HIWORD(wParam
) == BN_CLICKED
||
939 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
940 char str
[sizeof(cfg
.environmt
)];
942 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
947 p
= str
+ strlen(str
);
949 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
959 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
961 p
[strlen(str
)+1] = '\0';
962 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
964 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
965 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
967 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
968 MB_OK
| MB_ICONERROR
);
973 if (HIWORD(wParam
) != BN_CLICKED
&&
974 HIWORD(wParam
) != BN_DOUBLECLICKED
)
976 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
982 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
1009 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1012 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
1013 WPARAM wParam
, LPARAM lParam
) {
1015 char filename
[sizeof(cfg
.keyfile
)];
1019 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
1020 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
1021 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
1022 CheckDlgButton (hwnd
, IDC3_AGENTFWD
, cfg
.agentfwd
);
1023 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
1024 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
1025 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
1027 CheckRadioButton (hwnd
, IDC3_SSHPROT1
, IDC3_SSHPROT2
,
1028 cfg
.sshprot
== 1 ? IDC3_SSHPROT1
: IDC3_SSHPROT2
);
1029 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
1030 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1033 switch (LOWORD(wParam
)) {
1035 if (HIWORD(wParam
) == EN_CHANGE
)
1036 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
1037 sizeof(cfg
.termtype
)-1);
1040 if (HIWORD(wParam
) == EN_CHANGE
)
1041 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
1042 sizeof(cfg
.username
)-1);
1045 if (HIWORD(wParam
) == BN_CLICKED
||
1046 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1047 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
1050 if (HIWORD(wParam
) == BN_CLICKED
||
1051 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1052 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC3_AGENTFWD
);
1054 case IDC3_CIPHER3DES
:
1055 case IDC3_CIPHERBLOWF
:
1056 case IDC3_CIPHERDES
:
1057 if (HIWORD(wParam
) == BN_CLICKED
||
1058 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1059 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1060 cfg
.cipher
= CIPHER_3DES
;
1061 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1062 cfg
.cipher
= CIPHER_BLOWFISH
;
1063 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1064 cfg
.cipher
= CIPHER_DES
;
1069 if (HIWORD(wParam
) == BN_CLICKED
||
1070 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1071 if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT1
))
1073 else if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT2
))
1078 if (HIWORD(wParam
) == BN_CLICKED
||
1079 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1080 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1083 if (HIWORD(wParam
) == EN_CHANGE
)
1084 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1085 sizeof(cfg
.keyfile
)-1);
1089 * FIXME: this crashes. Find out why.
1091 memset(&of
, 0, sizeof(of
));
1092 #ifdef OPENFILENAME_SIZE_VERSION_400
1093 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1095 of
.lStructSize
= sizeof(of
);
1097 of
.hwndOwner
= hwnd
;
1098 of
.lpstrFilter
= "All Files\0*\0\0\0";
1099 of
.lpstrCustomFilter
= NULL
;
1100 of
.nFilterIndex
= 1;
1101 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1102 of
.nMaxFile
= sizeof(filename
);
1103 of
.lpstrFileTitle
= NULL
;
1104 of
.lpstrInitialDir
= NULL
;
1105 of
.lpstrTitle
= "Select Public Key File";
1107 if (GetOpenFileName(&of
)) {
1108 strcpy(cfg
.keyfile
, filename
);
1109 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1115 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1118 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1119 WPARAM wParam
, LPARAM lParam
) {
1124 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1125 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1127 static int tabs
[4] = {25, 61, 96, 128};
1128 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1131 for (i
=0; i
<256; i
++) {
1133 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1134 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1136 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1141 switch (LOWORD(wParam
)) {
1142 case IDC4_MBWINDOWS
:
1144 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1150 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1155 for (i
=0; i
<256; i
++)
1156 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1159 cfg
.wordness
[i
] = n
;
1160 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1161 LB_DELETESTRING
, i
, 0);
1162 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1163 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1165 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1175 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1178 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1179 WPARAM wParam
, LPARAM lParam
) {
1180 static const char *const colours
[] = {
1181 "Default Foreground", "Default Bold Foreground",
1182 "Default Background", "Default Bold Background",
1183 "Cursor Text", "Cursor Colour",
1184 "ANSI Black", "ANSI Black Bold",
1185 "ANSI Red", "ANSI Red Bold",
1186 "ANSI Green", "ANSI Green Bold",
1187 "ANSI Yellow", "ANSI Yellow Bold",
1188 "ANSI Blue", "ANSI Blue Bold",
1189 "ANSI Magenta", "ANSI Magenta Bold",
1190 "ANSI Cyan", "ANSI Cyan Bold",
1191 "ANSI White", "ANSI White Bold"
1193 static const int permanent
[] = {
1194 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1195 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1196 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1200 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1201 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1204 for (i
=0; i
<22; i
++)
1205 if (cfg
.bold_colour
|| permanent
[i
])
1206 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1207 (LPARAM
) colours
[i
]);
1209 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1210 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1211 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1212 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1215 switch (LOWORD(wParam
)) {
1216 case IDC5_BOLDCOLOUR
:
1217 if (HIWORD(wParam
) == BN_CLICKED
||
1218 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1220 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1221 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1222 if (cfg
.bold_colour
&& n
!=22) {
1223 for (i
=0; i
<22; i
++)
1225 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1227 (LPARAM
) colours
[i
]);
1228 } else if (!cfg
.bold_colour
&& n
!=12) {
1231 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1232 LB_DELETESTRING
, i
, 0);
1237 if (HIWORD(wParam
) == BN_CLICKED
||
1238 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1239 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1242 if (HIWORD(wParam
) == LBN_DBLCLK
||
1243 HIWORD(wParam
) == LBN_SELCHANGE
) {
1244 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1246 if (!cfg
.bold_colour
)
1247 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1248 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1249 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1250 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1254 if (HIWORD(wParam
) == BN_CLICKED
||
1255 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1256 static CHOOSECOLOR cc
;
1257 static DWORD custom
[16] = {0}; /* zero initialisers */
1258 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1260 if (!cfg
.bold_colour
)
1261 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1262 cc
.lStructSize
= sizeof(cc
);
1263 cc
.hwndOwner
= hwnd
;
1264 cc
.hInstance
= (HWND
)hinst
;
1265 cc
.lpCustColors
= custom
;
1266 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1268 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1269 if (ChooseColor(&cc
)) {
1271 (unsigned char) (cc
.rgbResult
& 0xFF);
1273 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1275 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1276 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1278 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1280 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1288 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1291 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1292 WPARAM wParam
, LPARAM lParam
) {
1295 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1296 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1297 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1299 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1300 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1301 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1302 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1303 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1306 switch (LOWORD(wParam
)) {
1308 case IDC6_KOI8WIN1251
:
1309 case IDC6_88592WIN1250
:
1310 cfg
.xlat_enablekoiwin
=
1311 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1312 cfg
.xlat_88592w1250
=
1313 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1315 case IDC6_CAPSLOCKCYR
:
1316 if (HIWORD(wParam
) == BN_CLICKED
||
1317 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1318 cfg
.xlat_capslockcyr
=
1319 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1322 case IDC2_VTXWINDOWS
:
1323 case IDC2_VTOEMANSI
:
1324 case IDC2_VTOEMONLY
:
1325 case IDC2_VTPOORMAN
:
1327 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1328 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1329 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1334 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1337 static DLGPROC panelproc
[NPANELS
] = {
1338 ConnectionProc
, KeyboardProc
, TerminalProc
,
1339 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1341 static char *panelids
[NPANELS
] = {
1342 MAKEINTRESOURCE(IDD_PANEL0
),
1343 MAKEINTRESOURCE(IDD_PANEL1
),
1344 MAKEINTRESOURCE(IDD_PANEL2
),
1345 MAKEINTRESOURCE(IDD_PANEL3
),
1346 MAKEINTRESOURCE(IDD_PANEL35
),
1347 MAKEINTRESOURCE(IDD_PANEL4
),
1348 MAKEINTRESOURCE(IDD_PANEL5
),
1349 MAKEINTRESOURCE(IDD_PANEL6
)
1352 static char *names
[NPANELS
] = {
1353 "Connection", "Keyboard", "Terminal", "Telnet",
1354 "SSH", "Selection", "Colours", "Translation"
1357 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1358 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1360 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1361 WPARAM wParam
, LPARAM lParam
,
1362 int npanels
, int *panelnums
, HWND
*page
) {
1367 { /* centre the window */
1370 hw
= GetDesktopWindow();
1371 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1372 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1373 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1374 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1377 { /* initialise the tab control */
1381 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1382 for (i
=0; i
<npanels
; i
++) {
1383 tab
.mask
= TCIF_TEXT
;
1384 tab
.pszText
= names
[panelnums
[i
]];
1385 TabCtrl_InsertItem (hw
, i
, &tab
);
1387 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1388 hwnd, panelproc[panelnums[0]]);*/
1389 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1390 hwnd
, panelproc
[panelnums
[0]]);
1391 SetWindowLong (*page
, GWL_EXSTYLE
,
1392 GetWindowLong (*page
, GWL_EXSTYLE
) |
1393 WS_EX_CONTROLPARENT
);
1398 if (LOWORD(wParam
) == IDC_TAB
&&
1399 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1400 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1402 DestroyWindow (*page
);
1403 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1404 hwnd, panelproc[panelnums[i]]);*/
1405 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1406 hwnd
, panelproc
[panelnums
[i
]]);
1407 SetWindowLong (*page
, GWL_EXSTYLE
,
1408 GetWindowLong (*page
, GWL_EXSTYLE
) |
1409 WS_EX_CONTROLPARENT
);
1410 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1414 /* case WM_CTLCOLORDLG: */
1415 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1417 switch (LOWORD(wParam
)) {
1420 EndDialog (hwnd
, 1);
1425 EndDialog (hwnd
, 0);
1430 EndDialog (hwnd
, 0);
1433 /* Grrr Explorer will maximize Dialogs! */
1435 if (wParam
== SIZE_MAXIMIZED
)
1442 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1443 WPARAM wParam
, LPARAM lParam
) {
1448 static HWND page
= NULL
;
1450 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1453 * If the Connection panel is active and the Session List
1454 * box is selected, we treat a press of Open to have an
1455 * implicit press of Load preceding it.
1457 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1458 i
= TabCtrl_GetCurSel(hw
);
1459 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1460 page
&& implicit_load_ok
) {
1461 SendMessage (page
, WM_COMMAND
,
1462 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1466 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1467 EnableWindow(hwnd
, 0);
1468 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1469 GetParent(hwnd
), AboutProc
);
1470 EnableWindow(hwnd
, 1);
1471 SetActiveWindow(hwnd
);
1473 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1474 MAIN_NPANELS
, mainp
, &page
);
1477 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1478 WPARAM wParam
, LPARAM lParam
) {
1480 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1481 RECONF_NPANELS
, reconfp
, &page
);
1484 void get_sesslist(int allocate
) {
1485 static char *buffer
;
1486 int buflen
, bufsize
, i
, ret
;
1487 char otherbuf
[2048];
1492 if (RegCreateKey(HKEY_CURRENT_USER
,
1493 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1496 buflen
= bufsize
= 0;
1500 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1501 if (ret
== ERROR_SUCCESS
) {
1502 bufsize
= buflen
+ 2048;
1503 buffer
= srealloc(buffer
, bufsize
);
1504 unmungestr(otherbuf
, buffer
+buflen
);
1505 buflen
+= strlen(buffer
+buflen
)+1;
1507 } while (ret
== ERROR_SUCCESS
);
1508 buffer
= srealloc(buffer
, buflen
+1);
1509 buffer
[buflen
] = '\0';
1512 nsessions
= 1; /* "Default Settings" counts as one */
1514 if (strcmp(p
, "Default Settings"))
1520 sessions
= smalloc(nsessions
* sizeof(char *));
1521 sessions
[0] = "Default Settings";
1525 if (strcmp(p
, "Default Settings"))
1536 int do_config (void) {
1540 savedsession
[0] = '\0';
1541 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1542 get_sesslist(FALSE
);
1547 int do_reconfig (HWND hwnd
) {
1551 backup_cfg
= cfg
; /* structure copy */
1552 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1554 cfg
= backup_cfg
; /* structure copy */
1561 void do_defaults (char *session
) {
1563 load_settings (session
, TRUE
);
1565 load_settings ("Default Settings", FALSE
);
1568 void logevent (char *string
) {
1569 if (nevents
>= negsize
) {
1571 events
= srealloc (events
, negsize
* sizeof(*events
));
1573 events
[nevents
] = smalloc(1+strlen(string
));
1574 strcpy (events
[nevents
], string
);
1577 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1581 void showeventlog (HWND hwnd
) {
1583 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1585 ShowWindow (logbox
, SW_SHOWNORMAL
);
1589 void showabout (HWND hwnd
) {
1591 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1593 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1597 void verify_ssh_host_key(char *host
, char *keystr
) {
1598 char *otherstr
, *mungedhost
;
1602 len
= 1 + strlen(keystr
);
1605 * Now read a saved key in from the registry and see what it
1608 otherstr
= smalloc(len
);
1609 mungedhost
= smalloc(3*strlen(host
)+1);
1610 if (!otherstr
|| !mungedhost
)
1611 fatalbox("Out of memory");
1613 mungestr(host
, mungedhost
);
1615 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1616 &rkey
) != ERROR_SUCCESS
) {
1617 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1618 "in the registry. There is thus no way to tell\n"
1619 "if the remote host is what you think it is.\n"
1620 "Connect anyway?", "PuTTY Problem",
1621 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1624 DWORD readlen
= len
;
1628 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1629 &type
, otherstr
, &readlen
);
1631 if (ret
== ERROR_MORE_DATA
||
1632 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1633 strcmp(otherstr
, keystr
))) {
1634 if (MessageBox(NULL
,
1635 "This host's host key is different from the\n"
1636 "one cached in the registry! Someone may be\n"
1637 "impersonating this host for malicious reasons;\n"
1638 "alternatively, the host key may have changed\n"
1639 "due to sloppy system administration.\n"
1640 "Replace key in registry and connect?",
1641 "PuTTY: Security Warning",
1642 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1644 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1646 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1647 if (MessageBox(NULL
,
1648 "This host's host key is not cached in the\n"
1649 "registry. Do you want to add it to the cache\n"
1650 "and carry on connecting?",
1652 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1654 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,