13 #define MAIN_NPANELS 8
14 #define RECONF_NPANELS 5
16 static const char *const puttystr
= PUTTY_REG_POS
"\\Sessions";
18 static char **events
= NULL
;
19 static int nevents
= 0, negsize
= 0;
21 static HWND logbox
= NULL
, abtbox
= NULL
;
23 static char hex
[16] = "0123456789ABCDEF";
25 static void mungestr(char *in
, char *out
) {
29 if (*in
== ' ' || *in
== '\\' || *in
== '*' || *in
== '?' ||
30 *in
== '%' || *in
< ' ' || *in
> '~' || (*in
== '.' && !candot
)) {
32 *out
++ = hex
[((unsigned char)*in
) >> 4];
33 *out
++ = hex
[((unsigned char)*in
) & 15];
43 static void unmungestr(char *in
, char *out
) {
45 if (*in
== '%' && in
[1] && in
[2]) {
48 i
= in
[1] - '0'; i
-= (i
> 9 ?
7 : 0);
49 j
= in
[2] - '0'; j
-= (j
> 9 ?
7 : 0);
60 static void wpps(HKEY key
, LPCTSTR name
, LPCTSTR value
) {
61 RegSetValueEx(key
, name
, 0, REG_SZ
, value
, 1+strlen(value
));
64 static void wppi(HKEY key
, LPCTSTR name
, int value
) {
65 RegSetValueEx(key
, name
, 0, REG_DWORD
,
66 (CONST BYTE
*)&value
, sizeof(value
));
69 static void gpps(HKEY key
, LPCTSTR name
, LPCTSTR def
,
70 LPTSTR val
, int len
) {
75 RegQueryValueEx(key
, name
, 0, &type
, val
, &size
) != ERROR_SUCCESS
||
77 strncpy(val
, def
, len
);
82 static void gppi(HKEY key
, LPCTSTR name
, int def
, int *i
) {
83 DWORD type
, val
, size
;
87 RegQueryValueEx(key
, name
, 0, &type
,
88 (BYTE
*)&val
, &size
) != ERROR_SUCCESS
||
89 size
!= sizeof(val
) || type
!= REG_DWORD
)
95 static HINSTANCE hinst
;
99 static void save_settings (char *section
, int do_host
) {
101 HKEY subkey1
, sesskey
;
104 p
= malloc(3*strlen(section
)+1);
105 mungestr(section
, p
);
107 if (RegCreateKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
)!=ERROR_SUCCESS
||
108 RegCreateKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
113 RegCloseKey(subkey1
);
115 wppi (sesskey
, "Present", 1);
117 wpps (sesskey
, "HostName", cfg
.host
);
118 wppi (sesskey
, "PortNumber", cfg
.port
);
120 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
121 if (backends
[i
].protocol
== cfg
.protocol
) {
122 p
= backends
[i
].name
;
125 wpps (sesskey
, "Protocol", p
);
127 wppi (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
128 wppi (sesskey
, "WarnOnClose", !!cfg
.warn_on_close
);
129 wpps (sesskey
, "TerminalType", cfg
.termtype
);
130 wpps (sesskey
, "TerminalSpeed", cfg
.termspeed
);
132 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
138 if (c
== '=' || c
== ',' || c
== '\\')
148 wpps (sesskey
, "Environment", buf
);
150 wpps (sesskey
, "UserName", cfg
.username
);
151 wppi (sesskey
, "NoPTY", cfg
.nopty
);
152 wpps (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
153 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
154 wppi (sesskey
, "AuthTIS", cfg
.try_tis_auth
);
155 wpps (sesskey
, "PublicKeyFile", cfg
.keyfile
);
156 wppi (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
157 wppi (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
158 wppi (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
159 wppi (sesskey
, "LinuxFunctionKeys", cfg
.funky_type
);
160 wppi (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
161 wppi (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
162 wppi (sesskey
, "NetHackKeypad", cfg
.nethack_keypad
);
163 wppi (sesskey
, "AltF4", cfg
.alt_f4
);
164 wppi (sesskey
, "AltSpace", cfg
.alt_space
);
165 wppi (sesskey
, "LdiscTerm", cfg
.ldisc_term
);
166 wppi (sesskey
, "BlinkCur", cfg
.blink_cur
);
167 wppi (sesskey
, "Beep", cfg
.beep
);
168 wppi (sesskey
, "ScrollbackLines", cfg
.savelines
);
169 wppi (sesskey
, "DECOriginMode", cfg
.dec_om
);
170 wppi (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
171 wppi (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
172 wppi (sesskey
, "WinNameAlways", cfg
.win_name_always
);
173 wppi (sesskey
, "TermWidth", cfg
.width
);
174 wppi (sesskey
, "TermHeight", cfg
.height
);
175 wpps (sesskey
, "Font", cfg
.font
);
176 wppi (sesskey
, "FontIsBold", cfg
.fontisbold
);
177 wppi (sesskey
, "FontCharSet", cfg
.fontcharset
);
178 wppi (sesskey
, "FontHeight", cfg
.fontheight
);
179 wppi (sesskey
, "FontVTMode", cfg
.vtmode
);
180 wppi (sesskey
, "TryPalette", cfg
.try_palette
);
181 wppi (sesskey
, "BoldAsColour", cfg
.bold_colour
);
182 for (i
=0; i
<22; i
++) {
183 char buf
[20], buf2
[30];
184 sprintf(buf
, "Colour%d", i
);
185 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
186 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
187 wpps (sesskey
, buf
, buf2
);
189 wppi (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
190 for (i
=0; i
<256; i
+=32) {
191 char buf
[20], buf2
[256];
193 sprintf(buf
, "Wordness%d", i
);
195 for (j
=i
; j
<i
+32; j
++) {
196 sprintf(buf2
+strlen(buf2
), "%s%d",
197 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
199 wpps (sesskey
, buf
, buf2
);
201 wppi (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
202 wppi (sesskey
, "88592Xlat", cfg
.xlat_88592w1250
);
203 wppi (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
204 wppi (sesskey
, "ScrollBar", cfg
.scrollbar
);
205 wppi (sesskey
, "ScrollOnKey", cfg
.scroll_on_key
);
206 wppi (sesskey
, "LockSize", cfg
.locksize
);
207 wppi (sesskey
, "BCE", cfg
.bce
);
208 wppi (sesskey
, "BlinkText", cfg
.blinktext
);
210 RegCloseKey(sesskey
);
213 static void del_session (char *section
) {
217 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
)
220 p
= malloc(3*strlen(section
)+1);
221 mungestr(section
, p
);
222 RegDeleteKey(subkey1
, p
);
225 RegCloseKey(subkey1
);
228 static void load_settings (char *section
, int do_host
) {
230 HKEY subkey1
, sesskey
;
234 p
= malloc(3*strlen(section
)+1);
235 mungestr(section
, p
);
237 if (RegOpenKey(HKEY_CURRENT_USER
, puttystr
, &subkey1
) != ERROR_SUCCESS
) {
240 if (RegOpenKey(subkey1
, p
, &sesskey
) != ERROR_SUCCESS
) {
243 RegCloseKey(subkey1
);
248 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
249 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
251 gpps (sesskey
, "Protocol", "default", prot
, 10);
252 cfg
.protocol
= default_protocol
;
253 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
254 if (!strcmp(prot
, backends
[i
].name
)) {
255 cfg
.protocol
= backends
[i
].protocol
;
259 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
260 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
261 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
262 sizeof(cfg
.termtype
));
263 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
264 sizeof(cfg
.termspeed
));
266 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
267 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
271 while (*p
&& *p
!= ',') {
284 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
285 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
288 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
289 if (!strcmp(cipher
, "blowfish"))
290 cfg
.cipher
= CIPHER_BLOWFISH
;
291 else if (!strcmp(cipher
, "des"))
292 cfg
.cipher
= CIPHER_DES
;
294 cfg
.cipher
= CIPHER_3DES
;
296 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
297 gpps (sesskey
, "PublicKeyFile", "", cfg
.keyfile
, sizeof(cfg
.keyfile
));
298 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
299 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
300 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
301 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.funky_type
);
302 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
303 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
304 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
305 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
306 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
307 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
308 gppi (sesskey
, "BlinkCur", 0, &cfg
.blink_cur
);
309 gppi (sesskey
, "Beep", 1, &cfg
.beep
);
310 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
311 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
312 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
313 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
314 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
315 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
316 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
317 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
318 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
319 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
320 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
321 gppi (sesskey
, "FontVTMode", VT_OEMANSI
, (int *)&cfg
.vtmode
);
322 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
323 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
324 for (i
=0; i
<22; i
++) {
325 static char *defaults
[] = {
326 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
327 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
328 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
329 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
330 "85,255,255", "187,187,187", "255,255,255"
332 char buf
[20], buf2
[30];
334 sprintf(buf
, "Colour%d", i
);
335 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
336 if(sscanf(buf2
, "%d,%d,%d", &c0
, &c1
, &c2
) == 3) {
337 cfg
.colours
[i
][0] = c0
;
338 cfg
.colours
[i
][1] = c1
;
339 cfg
.colours
[i
][2] = c2
;
342 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
343 for (i
=0; i
<256; i
+=32) {
344 static char *defaults
[] = {
345 "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",
346 "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",
347 "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",
348 "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",
349 "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",
350 "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",
351 "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",
352 "2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2"
354 char buf
[20], buf2
[256], *p
;
356 sprintf(buf
, "Wordness%d", i
);
357 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
359 for (j
=i
; j
<i
+32; j
++) {
361 while (*p
&& *p
!= ',') p
++;
362 if (*p
== ',') *p
++ = '\0';
363 cfg
.wordness
[j
] = atoi(q
);
366 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
367 gppi (sesskey
, "88592Xlat", 0, &cfg
.xlat_88592w1250
);
368 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
369 gppi (sesskey
, "ScrollBar", 1, &cfg
.scrollbar
);
370 gppi (sesskey
, "ScrollOnKey", 0, &cfg
.scroll_on_key
);
371 gppi (sesskey
, "LockSize", 0, &cfg
.locksize
);
372 gppi (sesskey
, "BCE", 0, &cfg
.bce
);
373 gppi (sesskey
, "BlinkText", 0, &cfg
.blinktext
);
375 RegCloseKey(sesskey
);
378 static void force_normal(HWND hwnd
)
380 static int recurse
= 0;
387 wp
.length
= sizeof(wp
);
388 if (GetWindowPlacement(hwnd
, &wp
))
390 wp
.showCmd
= SW_SHOWNORMAL
;
391 SetWindowPlacement(hwnd
, &wp
);
396 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
399 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
404 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
405 WPARAM wParam
, LPARAM lParam
) {
410 for (i
=0; i
<nevents
; i
++)
411 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
412 0, (LPARAM
)events
[i
]);
414 /* case WM_CTLCOLORDLG: */
415 /* return (int) GetStockObject (LTGRAY_BRUSH); */
417 switch (LOWORD(wParam
)) {
420 DestroyWindow (hwnd
);
426 DestroyWindow (hwnd
);
432 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
433 WPARAM wParam
, LPARAM lParam
) {
438 switch (LOWORD(wParam
)) {
441 DestroyWindow (hwnd
);
447 DestroyWindow (hwnd
);
453 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
454 WPARAM wParam
, LPARAM lParam
) {
457 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
459 /* case WM_CTLCOLORDLG: */
460 /* return (int) GetStockObject (LTGRAY_BRUSH); */
461 /* case WM_CTLCOLORSTATIC: */
462 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
463 /* return (int) GetStockObject (LTGRAY_BRUSH); */
465 switch (LOWORD(wParam
)) {
468 DestroyWindow (hwnd
);
471 EnableWindow(hwnd
, 0);
472 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
474 EnableWindow(hwnd
, 1);
480 DestroyWindow (hwnd
);
486 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
487 WPARAM wParam
, LPARAM lParam
) {
490 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
492 /* case WM_CTLCOLORDLG: */
493 /* return (int) GetStockObject (LTGRAY_BRUSH); */
494 /* case WM_CTLCOLORSTATIC: */
495 /* case WM_CTLCOLORBTN: */
496 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
497 /* return (int) GetStockObject (LTGRAY_BRUSH); */
499 DestroyWindow (hwnd
);
505 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
506 WPARAM wParam
, LPARAM lParam
) {
511 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
512 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
513 for (i
= 0; i
< nsessions
; i
++)
514 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
515 0, (LPARAM
) (sessions
[i
]));
516 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
517 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
518 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
519 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
520 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
524 * Button release should trigger WM_OK if there was a
525 * previous double click on the session list.
529 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
532 switch (LOWORD(wParam
)) {
533 case IDC0_PROTTELNET
:
536 if (HIWORD(wParam
) == BN_CLICKED
||
537 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
538 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
539 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
540 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
541 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
542 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
543 cfg
.port
= i ?
22 : 23;
544 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
549 if (HIWORD(wParam
) == EN_CHANGE
)
550 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
554 if (HIWORD(wParam
) == EN_CHANGE
)
555 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
558 if (HIWORD(wParam
) == BN_CLICKED
||
559 HIWORD(wParam
) == BN_DOUBLECLICKED
)
560 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
563 if (HIWORD(wParam
) == BN_CLICKED
||
564 HIWORD(wParam
) == BN_DOUBLECLICKED
)
565 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
568 if (HIWORD(wParam
) == EN_CHANGE
)
569 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
573 if (HIWORD(wParam
) == BN_CLICKED
||
574 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
579 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
581 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
587 strcpy (str
, sessions
[n
]);
589 save_settings (str
, !!strcmp(str
, "Default Settings"));
590 get_sesslist (FALSE
);
592 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
594 for (i
= 0; i
< nsessions
; i
++)
595 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
596 0, (LPARAM
) (sessions
[i
]));
597 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
603 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
604 HIWORD(wParam
) != BN_CLICKED
&&
605 HIWORD(wParam
) != BN_DOUBLECLICKED
)
607 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
608 HIWORD(wParam
) != LBN_DBLCLK
)
611 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
617 load_settings (sessions
[n
],
618 !!strcmp(sessions
[n
], "Default Settings"));
619 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
620 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
621 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
622 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
623 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
624 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
625 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
626 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
629 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
631 * A double-click on a saved session should
632 * actually start the session, not just load it.
633 * Unless it's Default Settings or some other
634 * host-less set of saved settings.
643 if (HIWORD(wParam
) == BN_CLICKED
||
644 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
645 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
647 if (n
== LB_ERR
|| n
== 0) {
651 del_session(sessions
[n
]);
652 get_sesslist (FALSE
);
654 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
656 for (i
= 0; i
< nsessions
; i
++)
657 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
658 0, (LPARAM
) (sessions
[i
]));
659 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
664 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
667 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
668 WPARAM wParam
, LPARAM lParam
) {
671 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
672 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
673 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
674 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
675 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
677 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
680 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
681 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
682 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
683 cfg
.nethack_keypad ? IDC1_KPNH
:
684 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
685 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
686 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
687 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
688 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
691 if (HIWORD(wParam
) == BN_CLICKED
||
692 HIWORD(wParam
) == BN_DOUBLECLICKED
)
693 switch (LOWORD(wParam
)) {
696 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
700 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
707 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
711 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
712 cfg
.nethack_keypad
= FALSE
;
715 cfg
.app_keypad
= FALSE
;
716 cfg
.nethack_keypad
= TRUE
;
720 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
723 if (HIWORD(wParam
) == BN_CLICKED
||
724 HIWORD(wParam
) == BN_DOUBLECLICKED
)
725 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
728 if (HIWORD(wParam
) == BN_CLICKED
||
729 HIWORD(wParam
) == BN_DOUBLECLICKED
)
730 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
733 if (HIWORD(wParam
) == BN_CLICKED
||
734 HIWORD(wParam
) == BN_DOUBLECLICKED
)
735 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
738 if (HIWORD(wParam
) == BN_CLICKED
||
739 HIWORD(wParam
) == BN_DOUBLECLICKED
)
740 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
744 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
747 static void fmtfont (char *buf
) {
748 sprintf (buf
, "Font: %s, ", cfg
.font
);
750 strcat(buf
, "bold, ");
751 if (cfg
.fontheight
== 0)
752 strcat (buf
, "default height");
754 sprintf (buf
+strlen(buf
), "%d-%s",
755 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
756 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
759 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
760 WPARAM wParam
, LPARAM lParam
) {
763 char fontstatic
[256];
767 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
768 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
769 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
770 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
771 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
772 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
773 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
774 fmtfont (fontstatic
);
775 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
776 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
777 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
778 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
779 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
780 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
781 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
784 switch (LOWORD(wParam
)) {
786 if (HIWORD(wParam
) == BN_CLICKED
||
787 HIWORD(wParam
) == BN_DOUBLECLICKED
)
788 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
791 if (HIWORD(wParam
) == BN_CLICKED
||
792 HIWORD(wParam
) == BN_DOUBLECLICKED
)
793 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
796 if (HIWORD(wParam
) == BN_CLICKED
||
797 HIWORD(wParam
) == BN_DOUBLECLICKED
)
798 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
801 if (HIWORD(wParam
) == BN_CLICKED
||
802 HIWORD(wParam
) == BN_DOUBLECLICKED
)
803 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
806 if (HIWORD(wParam
) == EN_CHANGE
)
807 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
810 if (HIWORD(wParam
) == EN_CHANGE
)
811 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
814 if (HIWORD(wParam
) == EN_CHANGE
)
815 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
817 case IDC2_CHOOSEFONT
:
818 lf
.lfHeight
= cfg
.fontheight
;
819 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
820 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
821 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
822 lf
.lfCharSet
= cfg
.fontcharset
;
823 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
824 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
825 lf
.lfQuality
= DEFAULT_QUALITY
;
826 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
827 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
828 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
830 cf
.lStructSize
= sizeof(cf
);
833 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
834 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
836 if (ChooseFont (&cf
)) {
837 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
838 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
839 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
840 cfg
.fontcharset
= lf
.lfCharSet
;
841 cfg
.fontheight
= lf
.lfHeight
;
842 fmtfont (fontstatic
);
843 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
847 if (HIWORD(wParam
) == BN_CLICKED
||
848 HIWORD(wParam
) == BN_DOUBLECLICKED
)
849 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
852 if (HIWORD(wParam
) == BN_CLICKED
||
853 HIWORD(wParam
) == BN_DOUBLECLICKED
)
854 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
857 if (HIWORD(wParam
) == BN_CLICKED
||
858 HIWORD(wParam
) == BN_DOUBLECLICKED
)
859 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
862 if (HIWORD(wParam
) == BN_CLICKED
||
863 HIWORD(wParam
) == BN_DOUBLECLICKED
)
864 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
867 if (HIWORD(wParam
) == BN_CLICKED
||
868 HIWORD(wParam
) == BN_DOUBLECLICKED
)
869 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
872 if (HIWORD(wParam
) == BN_CLICKED
||
873 HIWORD(wParam
) == BN_DOUBLECLICKED
)
874 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
879 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
882 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
883 WPARAM wParam
, LPARAM lParam
) {
888 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
889 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
890 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
892 char *p
= cfg
.environmt
;
894 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
899 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
900 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
903 switch (LOWORD(wParam
)) {
905 if (HIWORD(wParam
) == EN_CHANGE
)
906 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
907 sizeof(cfg
.termtype
)-1);
910 if (HIWORD(wParam
) == EN_CHANGE
)
911 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
912 sizeof(cfg
.termspeed
)-1);
915 if (HIWORD(wParam
) == EN_CHANGE
)
916 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
917 sizeof(cfg
.username
)-1);
921 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
924 if (HIWORD(wParam
) == BN_CLICKED
||
925 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
926 char str
[sizeof(cfg
.environmt
)];
928 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
933 p
= str
+ strlen(str
);
935 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
945 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
947 p
[strlen(str
)+1] = '\0';
948 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
950 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
951 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
953 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
954 MB_OK
| MB_ICONERROR
);
959 if (HIWORD(wParam
) != BN_CLICKED
&&
960 HIWORD(wParam
) != BN_DOUBLECLICKED
)
962 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
968 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
995 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
998 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
999 WPARAM wParam
, LPARAM lParam
) {
1001 char filename
[sizeof(cfg
.keyfile
)];
1005 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
1006 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
1007 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
1008 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
1009 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
1010 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
1013 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
1014 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1017 switch (LOWORD(wParam
)) {
1019 if (HIWORD(wParam
) == EN_CHANGE
)
1020 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
1021 sizeof(cfg
.termtype
)-1);
1024 if (HIWORD(wParam
) == EN_CHANGE
)
1025 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
1026 sizeof(cfg
.username
)-1);
1029 if (HIWORD(wParam
) == BN_CLICKED
||
1030 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1031 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
1033 case IDC3_CIPHER3DES
:
1034 case IDC3_CIPHERBLOWF
:
1035 case IDC3_CIPHERDES
:
1036 if (HIWORD(wParam
) == BN_CLICKED
||
1037 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1038 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1039 cfg
.cipher
= CIPHER_3DES
;
1040 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1041 cfg
.cipher
= CIPHER_BLOWFISH
;
1042 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1043 cfg
.cipher
= CIPHER_DES
;
1047 if (HIWORD(wParam
) == BN_CLICKED
||
1048 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1049 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1052 if (HIWORD(wParam
) == EN_CHANGE
)
1053 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1054 sizeof(cfg
.keyfile
)-1);
1058 * FIXME: this crashes. Find out why.
1060 memset(&of
, 0, sizeof(of
));
1061 #ifdef OPENFILENAME_SIZE_VERSION_400
1062 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1064 of
.lStructSize
= sizeof(of
);
1066 of
.hwndOwner
= hwnd
;
1067 of
.lpstrFilter
= "All Files\0*\0\0\0";
1068 of
.lpstrCustomFilter
= NULL
;
1069 of
.nFilterIndex
= 1;
1070 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1071 of
.nMaxFile
= sizeof(filename
);
1072 of
.lpstrFileTitle
= NULL
;
1073 of
.lpstrInitialDir
= NULL
;
1074 of
.lpstrTitle
= "Select Public Key File";
1076 if (GetOpenFileName(&of
)) {
1077 strcpy(cfg
.keyfile
, filename
);
1078 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1084 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1087 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1088 WPARAM wParam
, LPARAM lParam
) {
1093 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1094 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1096 static int tabs
[4] = {25, 61, 96, 128};
1097 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1100 for (i
=0; i
<256; i
++) {
1102 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1103 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1105 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1110 switch (LOWORD(wParam
)) {
1111 case IDC4_MBWINDOWS
:
1113 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1119 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1124 for (i
=0; i
<256; i
++)
1125 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1128 cfg
.wordness
[i
] = n
;
1129 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1130 LB_DELETESTRING
, i
, 0);
1131 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1132 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1134 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1144 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1147 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1148 WPARAM wParam
, LPARAM lParam
) {
1149 static const char *const colours
[] = {
1150 "Default Foreground", "Default Bold Foreground",
1151 "Default Background", "Default Bold Background",
1152 "Cursor Text", "Cursor Colour",
1153 "ANSI Black", "ANSI Black Bold",
1154 "ANSI Red", "ANSI Red Bold",
1155 "ANSI Green", "ANSI Green Bold",
1156 "ANSI Yellow", "ANSI Yellow Bold",
1157 "ANSI Blue", "ANSI Blue Bold",
1158 "ANSI Magenta", "ANSI Magenta Bold",
1159 "ANSI Cyan", "ANSI Cyan Bold",
1160 "ANSI White", "ANSI White Bold"
1162 static const int permanent
[] = {
1163 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1164 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1165 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1169 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1170 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1173 for (i
=0; i
<22; i
++)
1174 if (cfg
.bold_colour
|| permanent
[i
])
1175 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1176 (LPARAM
) colours
[i
]);
1178 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1179 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1180 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1181 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1184 switch (LOWORD(wParam
)) {
1185 case IDC5_BOLDCOLOUR
:
1186 if (HIWORD(wParam
) == BN_CLICKED
||
1187 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1189 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1190 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1191 if (cfg
.bold_colour
&& n
!=22) {
1192 for (i
=0; i
<22; i
++)
1194 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1196 (LPARAM
) colours
[i
]);
1197 } else if (!cfg
.bold_colour
&& n
!=12) {
1200 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1201 LB_DELETESTRING
, i
, 0);
1206 if (HIWORD(wParam
) == BN_CLICKED
||
1207 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1208 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1211 if (HIWORD(wParam
) == LBN_DBLCLK
||
1212 HIWORD(wParam
) == LBN_SELCHANGE
) {
1213 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1215 if (!cfg
.bold_colour
)
1216 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1217 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1218 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1219 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1223 if (HIWORD(wParam
) == BN_CLICKED
||
1224 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1225 static CHOOSECOLOR cc
;
1226 static DWORD custom
[16] = {0}; /* zero initialisers */
1227 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1229 if (!cfg
.bold_colour
)
1230 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1231 cc
.lStructSize
= sizeof(cc
);
1232 cc
.hwndOwner
= hwnd
;
1233 cc
.hInstance
= (HWND
)hinst
;
1234 cc
.lpCustColors
= custom
;
1235 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1237 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1238 if (ChooseColor(&cc
)) {
1240 (unsigned char) (cc
.rgbResult
& 0xFF);
1242 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1244 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1245 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1247 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1249 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1257 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1260 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1261 WPARAM wParam
, LPARAM lParam
) {
1264 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1265 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1266 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1268 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1269 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1270 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1271 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1272 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1275 switch (LOWORD(wParam
)) {
1277 case IDC6_KOI8WIN1251
:
1278 case IDC6_88592WIN1250
:
1279 cfg
.xlat_enablekoiwin
=
1280 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1281 cfg
.xlat_88592w1250
=
1282 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1284 case IDC6_CAPSLOCKCYR
:
1285 if (HIWORD(wParam
) == BN_CLICKED
||
1286 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1287 cfg
.xlat_capslockcyr
=
1288 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1291 case IDC2_VTXWINDOWS
:
1292 case IDC2_VTOEMANSI
:
1293 case IDC2_VTOEMONLY
:
1294 case IDC2_VTPOORMAN
:
1296 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1297 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1298 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1303 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1306 static DLGPROC panelproc
[NPANELS
] = {
1307 ConnectionProc
, KeyboardProc
, TerminalProc
,
1308 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1310 static char *panelids
[NPANELS
] = {
1311 MAKEINTRESOURCE(IDD_PANEL0
),
1312 MAKEINTRESOURCE(IDD_PANEL1
),
1313 MAKEINTRESOURCE(IDD_PANEL2
),
1314 MAKEINTRESOURCE(IDD_PANEL3
),
1315 MAKEINTRESOURCE(IDD_PANEL35
),
1316 MAKEINTRESOURCE(IDD_PANEL4
),
1317 MAKEINTRESOURCE(IDD_PANEL5
),
1318 MAKEINTRESOURCE(IDD_PANEL6
)
1321 static char *names
[NPANELS
] = {
1322 "Connection", "Keyboard", "Terminal", "Telnet",
1323 "SSH", "Selection", "Colours", "Translation"
1326 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1327 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1329 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1330 WPARAM wParam
, LPARAM lParam
,
1331 int npanels
, int *panelnums
, HWND
*page
) {
1336 { /* centre the window */
1339 hw
= GetDesktopWindow();
1340 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1341 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1342 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1343 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1346 { /* initialise the tab control */
1350 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1351 for (i
=0; i
<npanels
; i
++) {
1352 tab
.mask
= TCIF_TEXT
;
1353 tab
.pszText
= names
[panelnums
[i
]];
1354 TabCtrl_InsertItem (hw
, i
, &tab
);
1356 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1357 hwnd, panelproc[panelnums[0]]);*/
1358 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1359 hwnd
, panelproc
[panelnums
[0]]);
1360 SetWindowLong (*page
, GWL_EXSTYLE
,
1361 GetWindowLong (*page
, GWL_EXSTYLE
) |
1362 WS_EX_CONTROLPARENT
);
1367 if (LOWORD(wParam
) == IDC_TAB
&&
1368 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1369 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1371 DestroyWindow (*page
);
1372 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1373 hwnd, panelproc[panelnums[i]]);*/
1374 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1375 hwnd
, panelproc
[panelnums
[i
]]);
1376 SetWindowLong (*page
, GWL_EXSTYLE
,
1377 GetWindowLong (*page
, GWL_EXSTYLE
) |
1378 WS_EX_CONTROLPARENT
);
1379 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1383 /* case WM_CTLCOLORDLG: */
1384 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1386 switch (LOWORD(wParam
)) {
1389 EndDialog (hwnd
, 1);
1394 EndDialog (hwnd
, 0);
1399 EndDialog (hwnd
, 0);
1402 /* Grrr Explorer will maximize Dialogs! */
1404 if (wParam
== SIZE_MAXIMIZED
)
1411 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1412 WPARAM wParam
, LPARAM lParam
) {
1417 static HWND page
= NULL
;
1419 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1422 * If the Connection panel is active and the Session List
1423 * box is selected, we treat a press of Open to have an
1424 * implicit press of Load preceding it.
1426 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1427 i
= TabCtrl_GetCurSel(hw
);
1428 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1429 page
&& implicit_load_ok
) {
1430 SendMessage (page
, WM_COMMAND
,
1431 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1435 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1436 EnableWindow(hwnd
, 0);
1437 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1438 GetParent(hwnd
), AboutProc
);
1439 EnableWindow(hwnd
, 1);
1441 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1442 MAIN_NPANELS
, mainp
, &page
);
1445 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1446 WPARAM wParam
, LPARAM lParam
) {
1448 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1449 RECONF_NPANELS
, reconfp
, &page
);
1452 void get_sesslist(int allocate
) {
1453 static char *buffer
;
1454 int buflen
, bufsize
, i
, ret
;
1455 char otherbuf
[2048];
1460 if (RegCreateKey(HKEY_CURRENT_USER
,
1461 puttystr
, &subkey1
) != ERROR_SUCCESS
)
1464 buflen
= bufsize
= 0;
1468 ret
= RegEnumKey(subkey1
, i
++, otherbuf
, sizeof(otherbuf
));
1469 if (ret
== ERROR_SUCCESS
) {
1470 bufsize
= buflen
+ 2048;
1471 buffer
= srealloc(buffer
, bufsize
);
1472 unmungestr(otherbuf
, buffer
+buflen
);
1473 buflen
+= strlen(buffer
+buflen
)+1;
1475 } while (ret
== ERROR_SUCCESS
);
1476 buffer
= srealloc(buffer
, buflen
+1);
1477 buffer
[buflen
] = '\0';
1480 nsessions
= 1; /* "Default Settings" counts as one */
1482 if (strcmp(p
, "Default Settings"))
1488 sessions
= smalloc(nsessions
* sizeof(char *));
1489 sessions
[0] = "Default Settings";
1493 if (strcmp(p
, "Default Settings"))
1504 int do_config (void) {
1508 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1509 get_sesslist(FALSE
);
1514 int do_reconfig (HWND hwnd
) {
1518 backup_cfg
= cfg
; /* structure copy */
1519 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1521 cfg
= backup_cfg
; /* structure copy */
1528 void do_defaults (char *session
) {
1530 load_settings (session
, TRUE
);
1532 load_settings ("Default Settings", FALSE
);
1535 void logevent (char *string
) {
1536 if (nevents
>= negsize
) {
1538 events
= srealloc (events
, negsize
* sizeof(*events
));
1540 events
[nevents
] = smalloc(1+strlen(string
));
1541 strcpy (events
[nevents
], string
);
1544 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1548 void showeventlog (HWND hwnd
) {
1550 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1552 ShowWindow (logbox
, SW_SHOWNORMAL
);
1556 void showabout (HWND hwnd
) {
1558 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1560 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1564 void verify_ssh_host_key(char *host
, char *keystr
) {
1565 char *otherstr
, *mungedhost
;
1569 len
= 1 + strlen(keystr
);
1572 * Now read a saved key in from the registry and see what it
1575 otherstr
= smalloc(len
);
1576 mungedhost
= smalloc(3*strlen(host
)+1);
1577 if (!otherstr
|| !mungedhost
)
1578 fatalbox("Out of memory");
1580 mungestr(host
, mungedhost
);
1582 if (RegCreateKey(HKEY_CURRENT_USER
, PUTTY_REG_POS
"\\SshHostKeys",
1583 &rkey
) != ERROR_SUCCESS
) {
1584 if (MessageBox(NULL
, "PuTTY was unable to open the host key cache\n"
1585 "in the registry. There is thus no way to tell\n"
1586 "if the remote host is what you think it is.\n"
1587 "Connect anyway?", "PuTTY Problem",
1588 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1591 DWORD readlen
= len
;
1595 ret
= RegQueryValueEx(rkey
, mungedhost
, NULL
,
1596 &type
, otherstr
, &readlen
);
1598 if (ret
== ERROR_MORE_DATA
||
1599 (ret
== ERROR_SUCCESS
&& type
== REG_SZ
&&
1600 strcmp(otherstr
, keystr
))) {
1601 if (MessageBox(NULL
,
1602 "This host's host key is different from the\n"
1603 "one cached in the registry! Someone may be\n"
1604 "impersonating this host for malicious reasons;\n"
1605 "alternatively, the host key may have changed\n"
1606 "due to sloppy system administration.\n"
1607 "Replace key in registry and connect?",
1608 "PuTTY: Security Warning",
1609 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1611 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,
1613 } else if (ret
!= ERROR_SUCCESS
|| type
!= REG_SZ
) {
1614 if (MessageBox(NULL
,
1615 "This host's host key is not cached in the\n"
1616 "registry. Do you want to add it to the cache\n"
1617 "and carry on connecting?",
1619 MB_ICONWARNING
| MB_YESNO
) == IDNO
)
1621 RegSetValueEx(rkey
, mungedhost
, 0, REG_SZ
, keystr
,