20 #define MAIN_NPANELS 8
21 #define RECONF_NPANELS 5
23 static char **events
= NULL
;
24 static int nevents
= 0, negsize
= 0;
26 static HWND logbox
= NULL
, abtbox
= NULL
;
28 static void gpps(void *handle
, char *name
, char *def
, char *val
, int len
) {
29 if (!read_setting_s(handle
, name
, val
, len
)) {
30 strncpy(val
, def
, len
);
35 static void gppi(void *handle
, char *name
, int def
, int *i
) {
36 *i
= read_setting_i(handle
, name
, def
);
39 static HINSTANCE hinst
;
43 static void save_settings (char *section
, int do_host
) {
48 sesskey
= open_settings_w(section
);
52 write_setting_i (sesskey
, "Present", 1);
54 write_setting_s (sesskey
, "HostName", cfg
.host
);
55 write_setting_i (sesskey
, "PortNumber", cfg
.port
);
57 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
58 if (backends
[i
].protocol
== cfg
.protocol
) {
62 write_setting_s (sesskey
, "Protocol", p
);
64 write_setting_i (sesskey
, "CloseOnExit", !!cfg
.close_on_exit
);
65 write_setting_i (sesskey
, "WarnOnClose", !!cfg
.warn_on_close
);
66 write_setting_s (sesskey
, "TerminalType", cfg
.termtype
);
67 write_setting_s (sesskey
, "TerminalSpeed", cfg
.termspeed
);
69 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
75 if (c
== '=' || c
== ',' || c
== '\\')
85 write_setting_s (sesskey
, "Environment", buf
);
87 write_setting_s (sesskey
, "UserName", cfg
.username
);
88 write_setting_i (sesskey
, "NoPTY", cfg
.nopty
);
89 write_setting_i (sesskey
, "AgentFwd", cfg
.agentfwd
);
90 write_setting_s (sesskey
, "RemoteCmd", cfg
.remote_cmd
);
91 write_setting_s (sesskey
, "Cipher", cfg
.cipher
== CIPHER_BLOWFISH ?
"blowfish" :
92 cfg
.cipher
== CIPHER_DES ?
"des" : "3des");
93 write_setting_i (sesskey
, "AuthTIS", cfg
.try_tis_auth
);
94 write_setting_i (sesskey
, "SshProt", cfg
.sshprot
);
95 write_setting_s (sesskey
, "PublicKeyFile", cfg
.keyfile
);
96 write_setting_i (sesskey
, "RFCEnviron", cfg
.rfc_environ
);
97 write_setting_i (sesskey
, "BackspaceIsDelete", cfg
.bksp_is_delete
);
98 write_setting_i (sesskey
, "RXVTHomeEnd", cfg
.rxvt_homeend
);
99 write_setting_i (sesskey
, "LinuxFunctionKeys", cfg
.funky_type
);
100 write_setting_i (sesskey
, "ApplicationCursorKeys", cfg
.app_cursor
);
101 write_setting_i (sesskey
, "ApplicationKeypad", cfg
.app_keypad
);
102 write_setting_i (sesskey
, "NetHackKeypad", cfg
.nethack_keypad
);
103 write_setting_i (sesskey
, "AltF4", cfg
.alt_f4
);
104 write_setting_i (sesskey
, "AltSpace", cfg
.alt_space
);
105 write_setting_i (sesskey
, "LdiscTerm", cfg
.ldisc_term
);
106 write_setting_i (sesskey
, "BlinkCur", cfg
.blink_cur
);
107 write_setting_i (sesskey
, "Beep", cfg
.beep
);
108 write_setting_i (sesskey
, "ScrollbackLines", cfg
.savelines
);
109 write_setting_i (sesskey
, "DECOriginMode", cfg
.dec_om
);
110 write_setting_i (sesskey
, "AutoWrapMode", cfg
.wrap_mode
);
111 write_setting_i (sesskey
, "LFImpliesCR", cfg
.lfhascr
);
112 write_setting_i (sesskey
, "WinNameAlways", cfg
.win_name_always
);
113 write_setting_i (sesskey
, "TermWidth", cfg
.width
);
114 write_setting_i (sesskey
, "TermHeight", cfg
.height
);
115 write_setting_s (sesskey
, "Font", cfg
.font
);
116 write_setting_i (sesskey
, "FontIsBold", cfg
.fontisbold
);
117 write_setting_i (sesskey
, "FontCharSet", cfg
.fontcharset
);
118 write_setting_i (sesskey
, "FontHeight", cfg
.fontheight
);
119 write_setting_i (sesskey
, "FontVTMode", cfg
.vtmode
);
120 write_setting_i (sesskey
, "TryPalette", cfg
.try_palette
);
121 write_setting_i (sesskey
, "BoldAsColour", cfg
.bold_colour
);
122 for (i
=0; i
<22; i
++) {
123 char buf
[20], buf2
[30];
124 sprintf(buf
, "Colour%d", i
);
125 sprintf(buf2
, "%d,%d,%d", cfg
.colours
[i
][0],
126 cfg
.colours
[i
][1], cfg
.colours
[i
][2]);
127 write_setting_s (sesskey
, buf
, buf2
);
129 write_setting_i (sesskey
, "MouseIsXterm", cfg
.mouse_is_xterm
);
130 for (i
=0; i
<256; i
+=32) {
131 char buf
[20], buf2
[256];
133 sprintf(buf
, "Wordness%d", i
);
135 for (j
=i
; j
<i
+32; j
++) {
136 sprintf(buf2
+strlen(buf2
), "%s%d",
137 (*buf2 ?
"," : ""), cfg
.wordness
[j
]);
139 write_setting_s (sesskey
, buf
, buf2
);
141 write_setting_i (sesskey
, "KoiWinXlat", cfg
.xlat_enablekoiwin
);
142 write_setting_i (sesskey
, "88592Xlat", cfg
.xlat_88592w1250
);
143 write_setting_i (sesskey
, "CapsLockCyr", cfg
.xlat_capslockcyr
);
144 write_setting_i (sesskey
, "ScrollBar", cfg
.scrollbar
);
145 write_setting_i (sesskey
, "ScrollOnKey", cfg
.scroll_on_key
);
146 write_setting_i (sesskey
, "LockSize", cfg
.locksize
);
147 write_setting_i (sesskey
, "BCE", cfg
.bce
);
148 write_setting_i (sesskey
, "BlinkText", cfg
.blinktext
);
150 close_settings_w(sesskey
);
153 static void load_settings (char *section
, int do_host
) {
158 sesskey
= open_settings_r(section
);
160 gpps (sesskey
, "HostName", "", cfg
.host
, sizeof(cfg
.host
));
161 gppi (sesskey
, "PortNumber", default_port
, &cfg
.port
);
163 gpps (sesskey
, "Protocol", "default", prot
, 10);
164 cfg
.protocol
= default_protocol
;
165 for (i
= 0; backends
[i
].name
!= NULL
; i
++)
166 if (!strcmp(prot
, backends
[i
].name
)) {
167 cfg
.protocol
= backends
[i
].protocol
;
171 gppi (sesskey
, "CloseOnExit", 1, &cfg
.close_on_exit
);
172 gppi (sesskey
, "WarnOnClose", 1, &cfg
.warn_on_close
);
173 gpps (sesskey
, "TerminalType", "xterm", cfg
.termtype
,
174 sizeof(cfg
.termtype
));
175 gpps (sesskey
, "TerminalSpeed", "38400,38400", cfg
.termspeed
,
176 sizeof(cfg
.termspeed
));
178 char buf
[2*sizeof(cfg
.environmt
)], *p
, *q
;
179 gpps (sesskey
, "Environment", "", buf
, sizeof(buf
));
183 while (*p
&& *p
!= ',') {
196 gpps (sesskey
, "UserName", "", cfg
.username
, sizeof(cfg
.username
));
197 gppi (sesskey
, "NoPTY", 0, &cfg
.nopty
);
198 gppi (sesskey
, "AgentFwd", 0, &cfg
.agentfwd
);
199 gpps (sesskey
, "RemoteCmd", "", cfg
.remote_cmd
, sizeof(cfg
.remote_cmd
));
202 gpps (sesskey
, "Cipher", "3des", cipher
, 10);
203 if (!strcmp(cipher
, "blowfish"))
204 cfg
.cipher
= CIPHER_BLOWFISH
;
205 else if (!strcmp(cipher
, "des"))
206 cfg
.cipher
= CIPHER_DES
;
208 cfg
.cipher
= CIPHER_3DES
;
210 gppi (sesskey
, "SshProt", 1, &cfg
.sshprot
);
211 gppi (sesskey
, "AuthTIS", 0, &cfg
.try_tis_auth
);
212 gpps (sesskey
, "PublicKeyFile", "", cfg
.keyfile
, sizeof(cfg
.keyfile
));
213 gppi (sesskey
, "RFCEnviron", 0, &cfg
.rfc_environ
);
214 gppi (sesskey
, "BackspaceIsDelete", 1, &cfg
.bksp_is_delete
);
215 gppi (sesskey
, "RXVTHomeEnd", 0, &cfg
.rxvt_homeend
);
216 gppi (sesskey
, "LinuxFunctionKeys", 0, &cfg
.funky_type
);
217 gppi (sesskey
, "ApplicationCursorKeys", 0, &cfg
.app_cursor
);
218 gppi (sesskey
, "ApplicationKeypad", 0, &cfg
.app_keypad
);
219 gppi (sesskey
, "NetHackKeypad", 0, &cfg
.nethack_keypad
);
220 gppi (sesskey
, "AltF4", 1, &cfg
.alt_f4
);
221 gppi (sesskey
, "AltSpace", 0, &cfg
.alt_space
);
222 gppi (sesskey
, "LdiscTerm", 0, &cfg
.ldisc_term
);
223 gppi (sesskey
, "BlinkCur", 0, &cfg
.blink_cur
);
224 gppi (sesskey
, "Beep", 1, &cfg
.beep
);
225 gppi (sesskey
, "ScrollbackLines", 200, &cfg
.savelines
);
226 gppi (sesskey
, "DECOriginMode", 0, &cfg
.dec_om
);
227 gppi (sesskey
, "AutoWrapMode", 1, &cfg
.wrap_mode
);
228 gppi (sesskey
, "LFImpliesCR", 0, &cfg
.lfhascr
);
229 gppi (sesskey
, "WinNameAlways", 0, &cfg
.win_name_always
);
230 gppi (sesskey
, "TermWidth", 80, &cfg
.width
);
231 gppi (sesskey
, "TermHeight", 24, &cfg
.height
);
232 gpps (sesskey
, "Font", "Courier", cfg
.font
, sizeof(cfg
.font
));
233 gppi (sesskey
, "FontIsBold", 0, &cfg
.fontisbold
);
234 gppi (sesskey
, "FontCharSet", ANSI_CHARSET
, &cfg
.fontcharset
);
235 gppi (sesskey
, "FontHeight", 10, &cfg
.fontheight
);
236 gppi (sesskey
, "FontVTMode", VT_OEMANSI
, (int *)&cfg
.vtmode
);
237 gppi (sesskey
, "TryPalette", 0, &cfg
.try_palette
);
238 gppi (sesskey
, "BoldAsColour", 1, &cfg
.bold_colour
);
239 for (i
=0; i
<22; i
++) {
240 static char *defaults
[] = {
241 "187,187,187", "255,255,255", "0,0,0", "85,85,85", "0,0,0",
242 "0,255,0", "0,0,0", "85,85,85", "187,0,0", "255,85,85",
243 "0,187,0", "85,255,85", "187,187,0", "255,255,85", "0,0,187",
244 "85,85,255", "187,0,187", "255,85,255", "0,187,187",
245 "85,255,255", "187,187,187", "255,255,255"
247 char buf
[20], buf2
[30];
249 sprintf(buf
, "Colour%d", i
);
250 gpps (sesskey
, buf
, defaults
[i
], buf2
, sizeof(buf2
));
251 if(sscanf(buf2
, "%d,%d,%d", &c0
, &c1
, &c2
) == 3) {
252 cfg
.colours
[i
][0] = c0
;
253 cfg
.colours
[i
][1] = c1
;
254 cfg
.colours
[i
][2] = c2
;
257 gppi (sesskey
, "MouseIsXterm", 0, &cfg
.mouse_is_xterm
);
258 for (i
=0; i
<256; i
+=32) {
259 static char *defaults
[] = {
260 "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",
261 "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",
262 "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",
263 "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",
264 "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",
265 "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",
266 "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",
267 "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"
269 char buf
[20], buf2
[256], *p
;
271 sprintf(buf
, "Wordness%d", i
);
272 gpps (sesskey
, buf
, defaults
[i
/32], buf2
, sizeof(buf2
));
274 for (j
=i
; j
<i
+32; j
++) {
276 while (*p
&& *p
!= ',') p
++;
277 if (*p
== ',') *p
++ = '\0';
278 cfg
.wordness
[j
] = atoi(q
);
281 gppi (sesskey
, "KoiWinXlat", 0, &cfg
.xlat_enablekoiwin
);
282 gppi (sesskey
, "88592Xlat", 0, &cfg
.xlat_88592w1250
);
283 gppi (sesskey
, "CapsLockCyr", 0, &cfg
.xlat_capslockcyr
);
284 gppi (sesskey
, "ScrollBar", 1, &cfg
.scrollbar
);
285 gppi (sesskey
, "ScrollOnKey", 0, &cfg
.scroll_on_key
);
286 gppi (sesskey
, "LockSize", 0, &cfg
.locksize
);
287 gppi (sesskey
, "BCE", 0, &cfg
.bce
);
288 gppi (sesskey
, "BlinkText", 0, &cfg
.blinktext
);
290 close_settings_r(sesskey
);
293 static void force_normal(HWND hwnd
)
295 static int recurse
= 0;
302 wp
.length
= sizeof(wp
);
303 if (GetWindowPlacement(hwnd
, &wp
))
305 wp
.showCmd
= SW_SHOWNORMAL
;
306 SetWindowPlacement(hwnd
, &wp
);
311 static void MyGetDlgItemInt (HWND hwnd
, int id
, int *result
) {
314 n
= GetDlgItemInt (hwnd
, id
, &ok
, FALSE
);
319 static int CALLBACK
LogProc (HWND hwnd
, UINT msg
,
320 WPARAM wParam
, LPARAM lParam
) {
325 for (i
=0; i
<nevents
; i
++)
326 SendDlgItemMessage (hwnd
, IDN_LIST
, LB_ADDSTRING
,
327 0, (LPARAM
)events
[i
]);
329 /* case WM_CTLCOLORDLG: */
330 /* return (int) GetStockObject (LTGRAY_BRUSH); */
332 switch (LOWORD(wParam
)) {
335 DestroyWindow (hwnd
);
338 if (HIWORD(wParam
) == BN_CLICKED
||
339 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
342 selcount
= SendDlgItemMessage(hwnd
, IDN_LIST
,
343 LB_GETSELCOUNT
, 0, 0);
344 selitems
= malloc(selcount
* sizeof(int));
346 int count
= SendDlgItemMessage(hwnd
, IDN_LIST
,
348 selcount
, (LPARAM
)selitems
);
352 static unsigned char sel_nl
[] = SEL_NL
;
355 for (i
= 0; i
< count
; i
++)
356 size
+= strlen(events
[selitems
[i
]]) + sizeof(sel_nl
);
358 clipdata
= malloc(size
);
361 for (i
= 0; i
< count
; i
++) {
362 char *q
= events
[selitems
[i
]];
363 int qlen
= strlen(q
);
366 memcpy(p
, sel_nl
, sizeof(sel_nl
));
369 write_clip(clipdata
, size
);
381 DestroyWindow (hwnd
);
387 static int CALLBACK
LicenceProc (HWND hwnd
, UINT msg
,
388 WPARAM wParam
, LPARAM lParam
) {
393 switch (LOWORD(wParam
)) {
406 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
407 WPARAM wParam
, LPARAM lParam
) {
410 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
412 /* case WM_CTLCOLORDLG: */
413 /* return (int) GetStockObject (LTGRAY_BRUSH); */
414 /* case WM_CTLCOLORSTATIC: */
415 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
416 /* return (int) GetStockObject (LTGRAY_BRUSH); */
418 switch (LOWORD(wParam
)) {
421 DestroyWindow (hwnd
);
424 EnableWindow(hwnd
, 0);
425 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
427 EnableWindow(hwnd
, 1);
428 SetActiveWindow(hwnd
);
434 DestroyWindow (hwnd
);
440 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
441 WPARAM wParam
, LPARAM lParam
) {
444 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
446 /* case WM_CTLCOLORDLG: */
447 /* return (int) GetStockObject (LTGRAY_BRUSH); */
448 /* case WM_CTLCOLORSTATIC: */
449 /* case WM_CTLCOLORBTN: */
450 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
451 /* return (int) GetStockObject (LTGRAY_BRUSH); */
453 DestroyWindow (hwnd
);
459 static char savedsession
[2048];
461 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
462 WPARAM wParam
, LPARAM lParam
) {
467 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
468 SetDlgItemText (hwnd
, IDC0_SESSEDIT
, savedsession
);
469 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
470 for (i
= 0; i
< nsessions
; i
++)
471 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
472 0, (LPARAM
) (sessions
[i
]));
473 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
474 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
475 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
476 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
477 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
481 * Button release should trigger WM_OK if there was a
482 * previous double click on the session list.
486 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
489 switch (LOWORD(wParam
)) {
490 case IDC0_PROTTELNET
:
493 if (HIWORD(wParam
) == BN_CLICKED
||
494 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
495 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
496 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
497 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
498 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
499 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
500 cfg
.port
= i ?
22 : 23;
501 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
506 if (HIWORD(wParam
) == EN_CHANGE
)
507 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
511 if (HIWORD(wParam
) == EN_CHANGE
)
512 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
515 if (HIWORD(wParam
) == BN_CLICKED
||
516 HIWORD(wParam
) == BN_DOUBLECLICKED
)
517 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
520 if (HIWORD(wParam
) == BN_CLICKED
||
521 HIWORD(wParam
) == BN_DOUBLECLICKED
)
522 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
525 if (HIWORD(wParam
) == EN_CHANGE
) {
526 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
528 GetDlgItemText (hwnd
, IDC0_SESSEDIT
,
529 savedsession
, sizeof(savedsession
)-1);
530 savedsession
[sizeof(savedsession
)-1] = '\0';
534 if (HIWORD(wParam
) == BN_CLICKED
||
535 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
540 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
542 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
548 strcpy (str
, sessions
[n
]);
550 save_settings (str
, !!strcmp(str
, "Default Settings"));
551 get_sesslist (FALSE
);
553 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
555 for (i
= 0; i
< nsessions
; i
++)
556 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
557 0, (LPARAM
) (sessions
[i
]));
558 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
564 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
565 HIWORD(wParam
) != BN_CLICKED
&&
566 HIWORD(wParam
) != BN_DOUBLECLICKED
)
568 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
569 HIWORD(wParam
) != LBN_DBLCLK
)
572 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
578 load_settings (sessions
[n
],
579 !!strcmp(sessions
[n
], "Default Settings"));
580 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
581 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
582 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
583 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
584 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
585 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
586 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
587 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
590 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
592 * A double-click on a saved session should
593 * actually start the session, not just load it.
594 * Unless it's Default Settings or some other
595 * host-less set of saved settings.
604 if (HIWORD(wParam
) == BN_CLICKED
||
605 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
606 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
608 if (n
== LB_ERR
|| n
== 0) {
612 del_settings(sessions
[n
]);
613 get_sesslist (FALSE
);
615 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
617 for (i
= 0; i
< nsessions
; i
++)
618 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
619 0, (LPARAM
) (sessions
[i
]));
620 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
625 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
628 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
629 WPARAM wParam
, LPARAM lParam
) {
632 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
633 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
634 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
635 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
636 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
638 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
641 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
642 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
643 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
644 cfg
.nethack_keypad ? IDC1_KPNH
:
645 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
646 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
647 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
648 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
649 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
652 if (HIWORD(wParam
) == BN_CLICKED
||
653 HIWORD(wParam
) == BN_DOUBLECLICKED
)
654 switch (LOWORD(wParam
)) {
657 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
661 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
668 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
672 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
673 cfg
.nethack_keypad
= FALSE
;
676 cfg
.app_keypad
= FALSE
;
677 cfg
.nethack_keypad
= TRUE
;
681 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
684 if (HIWORD(wParam
) == BN_CLICKED
||
685 HIWORD(wParam
) == BN_DOUBLECLICKED
)
686 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
689 if (HIWORD(wParam
) == BN_CLICKED
||
690 HIWORD(wParam
) == BN_DOUBLECLICKED
)
691 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
694 if (HIWORD(wParam
) == BN_CLICKED
||
695 HIWORD(wParam
) == BN_DOUBLECLICKED
)
696 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
699 if (HIWORD(wParam
) == BN_CLICKED
||
700 HIWORD(wParam
) == BN_DOUBLECLICKED
)
701 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
705 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
708 static void fmtfont (char *buf
) {
709 sprintf (buf
, "Font: %s, ", cfg
.font
);
711 strcat(buf
, "bold, ");
712 if (cfg
.fontheight
== 0)
713 strcat (buf
, "default height");
715 sprintf (buf
+strlen(buf
), "%d-%s",
716 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
717 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
720 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
721 WPARAM wParam
, LPARAM lParam
) {
724 char fontstatic
[256];
728 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
729 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
730 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
731 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
732 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
733 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
734 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
735 fmtfont (fontstatic
);
736 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
737 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
738 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
739 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
740 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
741 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
742 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
745 switch (LOWORD(wParam
)) {
747 if (HIWORD(wParam
) == BN_CLICKED
||
748 HIWORD(wParam
) == BN_DOUBLECLICKED
)
749 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
752 if (HIWORD(wParam
) == BN_CLICKED
||
753 HIWORD(wParam
) == BN_DOUBLECLICKED
)
754 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
757 if (HIWORD(wParam
) == BN_CLICKED
||
758 HIWORD(wParam
) == BN_DOUBLECLICKED
)
759 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
762 if (HIWORD(wParam
) == BN_CLICKED
||
763 HIWORD(wParam
) == BN_DOUBLECLICKED
)
764 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
767 if (HIWORD(wParam
) == EN_CHANGE
)
768 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
771 if (HIWORD(wParam
) == EN_CHANGE
)
772 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
775 if (HIWORD(wParam
) == EN_CHANGE
)
776 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
778 case IDC2_CHOOSEFONT
:
779 lf
.lfHeight
= cfg
.fontheight
;
780 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
781 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
782 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
783 lf
.lfCharSet
= cfg
.fontcharset
;
784 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
785 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
786 lf
.lfQuality
= DEFAULT_QUALITY
;
787 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
788 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
789 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
791 cf
.lStructSize
= sizeof(cf
);
794 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
795 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
797 if (ChooseFont (&cf
)) {
798 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
799 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
800 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
801 cfg
.fontcharset
= lf
.lfCharSet
;
802 cfg
.fontheight
= lf
.lfHeight
;
803 fmtfont (fontstatic
);
804 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
808 if (HIWORD(wParam
) == BN_CLICKED
||
809 HIWORD(wParam
) == BN_DOUBLECLICKED
)
810 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
813 if (HIWORD(wParam
) == BN_CLICKED
||
814 HIWORD(wParam
) == BN_DOUBLECLICKED
)
815 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
818 if (HIWORD(wParam
) == BN_CLICKED
||
819 HIWORD(wParam
) == BN_DOUBLECLICKED
)
820 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
823 if (HIWORD(wParam
) == BN_CLICKED
||
824 HIWORD(wParam
) == BN_DOUBLECLICKED
)
825 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
828 if (HIWORD(wParam
) == BN_CLICKED
||
829 HIWORD(wParam
) == BN_DOUBLECLICKED
)
830 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
833 if (HIWORD(wParam
) == BN_CLICKED
||
834 HIWORD(wParam
) == BN_DOUBLECLICKED
)
835 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
840 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
843 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
844 WPARAM wParam
, LPARAM lParam
) {
849 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
850 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
851 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
853 char *p
= cfg
.environmt
;
855 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
860 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
861 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
864 switch (LOWORD(wParam
)) {
866 if (HIWORD(wParam
) == EN_CHANGE
)
867 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
868 sizeof(cfg
.termtype
)-1);
871 if (HIWORD(wParam
) == EN_CHANGE
)
872 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
873 sizeof(cfg
.termspeed
)-1);
876 if (HIWORD(wParam
) == EN_CHANGE
)
877 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
878 sizeof(cfg
.username
)-1);
882 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
885 if (HIWORD(wParam
) == BN_CLICKED
||
886 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
887 char str
[sizeof(cfg
.environmt
)];
889 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
894 p
= str
+ strlen(str
);
896 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
906 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
908 p
[strlen(str
)+1] = '\0';
909 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
911 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
912 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
914 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
915 MB_OK
| MB_ICONERROR
);
920 if (HIWORD(wParam
) != BN_CLICKED
&&
921 HIWORD(wParam
) != BN_DOUBLECLICKED
)
923 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
929 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
956 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
959 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
960 WPARAM wParam
, LPARAM lParam
) {
962 char filename
[sizeof(cfg
.keyfile
)];
966 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
967 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
968 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
969 CheckDlgButton (hwnd
, IDC3_AGENTFWD
, cfg
.agentfwd
);
970 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
971 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
972 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
974 CheckRadioButton (hwnd
, IDC3_SSHPROT1
, IDC3_SSHPROT2
,
975 cfg
.sshprot
== 1 ? IDC3_SSHPROT1
: IDC3_SSHPROT2
);
976 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
977 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
980 switch (LOWORD(wParam
)) {
982 if (HIWORD(wParam
) == EN_CHANGE
)
983 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
984 sizeof(cfg
.termtype
)-1);
987 if (HIWORD(wParam
) == EN_CHANGE
)
988 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
989 sizeof(cfg
.username
)-1);
992 if (HIWORD(wParam
) == BN_CLICKED
||
993 HIWORD(wParam
) == BN_DOUBLECLICKED
)
994 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
997 if (HIWORD(wParam
) == BN_CLICKED
||
998 HIWORD(wParam
) == BN_DOUBLECLICKED
)
999 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC3_AGENTFWD
);
1001 case IDC3_CIPHER3DES
:
1002 case IDC3_CIPHERBLOWF
:
1003 case IDC3_CIPHERDES
:
1004 if (HIWORD(wParam
) == BN_CLICKED
||
1005 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1006 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1007 cfg
.cipher
= CIPHER_3DES
;
1008 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1009 cfg
.cipher
= CIPHER_BLOWFISH
;
1010 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1011 cfg
.cipher
= CIPHER_DES
;
1016 if (HIWORD(wParam
) == BN_CLICKED
||
1017 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1018 if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT1
))
1020 else if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT2
))
1025 if (HIWORD(wParam
) == BN_CLICKED
||
1026 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1027 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1030 if (HIWORD(wParam
) == EN_CHANGE
)
1031 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1032 sizeof(cfg
.keyfile
)-1);
1036 * FIXME: this crashes. Find out why.
1038 memset(&of
, 0, sizeof(of
));
1039 #ifdef OPENFILENAME_SIZE_VERSION_400
1040 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1042 of
.lStructSize
= sizeof(of
);
1044 of
.hwndOwner
= hwnd
;
1045 of
.lpstrFilter
= "All Files\0*\0\0\0";
1046 of
.lpstrCustomFilter
= NULL
;
1047 of
.nFilterIndex
= 1;
1048 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1049 of
.nMaxFile
= sizeof(filename
);
1050 of
.lpstrFileTitle
= NULL
;
1051 of
.lpstrInitialDir
= NULL
;
1052 of
.lpstrTitle
= "Select Public Key File";
1054 if (GetOpenFileName(&of
)) {
1055 strcpy(cfg
.keyfile
, filename
);
1056 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1062 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1065 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1066 WPARAM wParam
, LPARAM lParam
) {
1071 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1072 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1074 static int tabs
[4] = {25, 61, 96, 128};
1075 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1078 for (i
=0; i
<256; i
++) {
1080 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1081 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1083 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1088 switch (LOWORD(wParam
)) {
1089 case IDC4_MBWINDOWS
:
1091 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1097 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1102 for (i
=0; i
<256; i
++)
1103 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1106 cfg
.wordness
[i
] = n
;
1107 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1108 LB_DELETESTRING
, i
, 0);
1109 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1110 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1112 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1122 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1125 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1126 WPARAM wParam
, LPARAM lParam
) {
1127 static const char *const colours
[] = {
1128 "Default Foreground", "Default Bold Foreground",
1129 "Default Background", "Default Bold Background",
1130 "Cursor Text", "Cursor Colour",
1131 "ANSI Black", "ANSI Black Bold",
1132 "ANSI Red", "ANSI Red Bold",
1133 "ANSI Green", "ANSI Green Bold",
1134 "ANSI Yellow", "ANSI Yellow Bold",
1135 "ANSI Blue", "ANSI Blue Bold",
1136 "ANSI Magenta", "ANSI Magenta Bold",
1137 "ANSI Cyan", "ANSI Cyan Bold",
1138 "ANSI White", "ANSI White Bold"
1140 static const int permanent
[] = {
1141 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1142 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1143 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1147 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1148 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1151 for (i
=0; i
<22; i
++)
1152 if (cfg
.bold_colour
|| permanent
[i
])
1153 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1154 (LPARAM
) colours
[i
]);
1156 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1157 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1158 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1159 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1162 switch (LOWORD(wParam
)) {
1163 case IDC5_BOLDCOLOUR
:
1164 if (HIWORD(wParam
) == BN_CLICKED
||
1165 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1167 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1168 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1169 if (cfg
.bold_colour
&& n
!=22) {
1170 for (i
=0; i
<22; i
++)
1172 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1174 (LPARAM
) colours
[i
]);
1175 } else if (!cfg
.bold_colour
&& n
!=12) {
1178 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1179 LB_DELETESTRING
, i
, 0);
1184 if (HIWORD(wParam
) == BN_CLICKED
||
1185 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1186 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1189 if (HIWORD(wParam
) == LBN_DBLCLK
||
1190 HIWORD(wParam
) == LBN_SELCHANGE
) {
1191 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1193 if (!cfg
.bold_colour
)
1194 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1195 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1196 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1197 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1201 if (HIWORD(wParam
) == BN_CLICKED
||
1202 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1203 static CHOOSECOLOR cc
;
1204 static DWORD custom
[16] = {0}; /* zero initialisers */
1205 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1207 if (!cfg
.bold_colour
)
1208 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1209 cc
.lStructSize
= sizeof(cc
);
1210 cc
.hwndOwner
= hwnd
;
1211 cc
.hInstance
= (HWND
)hinst
;
1212 cc
.lpCustColors
= custom
;
1213 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1215 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1216 if (ChooseColor(&cc
)) {
1218 (unsigned char) (cc
.rgbResult
& 0xFF);
1220 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1222 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1223 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1225 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1227 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1235 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1238 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1239 WPARAM wParam
, LPARAM lParam
) {
1242 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1243 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1244 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1246 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1247 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1248 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1249 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1250 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1253 switch (LOWORD(wParam
)) {
1255 case IDC6_KOI8WIN1251
:
1256 case IDC6_88592WIN1250
:
1257 cfg
.xlat_enablekoiwin
=
1258 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1259 cfg
.xlat_88592w1250
=
1260 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1262 case IDC6_CAPSLOCKCYR
:
1263 if (HIWORD(wParam
) == BN_CLICKED
||
1264 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1265 cfg
.xlat_capslockcyr
=
1266 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1269 case IDC2_VTXWINDOWS
:
1270 case IDC2_VTOEMANSI
:
1271 case IDC2_VTOEMONLY
:
1272 case IDC2_VTPOORMAN
:
1274 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1275 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1276 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1281 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1284 static DLGPROC panelproc
[NPANELS
] = {
1285 ConnectionProc
, KeyboardProc
, TerminalProc
,
1286 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1288 static char *panelids
[NPANELS
] = {
1289 MAKEINTRESOURCE(IDD_PANEL0
),
1290 MAKEINTRESOURCE(IDD_PANEL1
),
1291 MAKEINTRESOURCE(IDD_PANEL2
),
1292 MAKEINTRESOURCE(IDD_PANEL3
),
1293 MAKEINTRESOURCE(IDD_PANEL35
),
1294 MAKEINTRESOURCE(IDD_PANEL4
),
1295 MAKEINTRESOURCE(IDD_PANEL5
),
1296 MAKEINTRESOURCE(IDD_PANEL6
)
1299 static char *names
[NPANELS
] = {
1300 "Connection", "Keyboard", "Terminal", "Telnet",
1301 "SSH", "Selection", "Colours", "Translation"
1304 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1305 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1307 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1308 WPARAM wParam
, LPARAM lParam
,
1309 int npanels
, int *panelnums
, HWND
*page
) {
1314 { /* centre the window */
1317 hw
= GetDesktopWindow();
1318 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1319 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1320 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1321 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1324 { /* initialise the tab control */
1328 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1329 for (i
=0; i
<npanels
; i
++) {
1330 tab
.mask
= TCIF_TEXT
;
1331 tab
.pszText
= names
[panelnums
[i
]];
1332 TabCtrl_InsertItem (hw
, i
, &tab
);
1334 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1335 hwnd, panelproc[panelnums[0]]);*/
1336 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1337 hwnd
, panelproc
[panelnums
[0]]);
1338 SetWindowLong (*page
, GWL_EXSTYLE
,
1339 GetWindowLong (*page
, GWL_EXSTYLE
) |
1340 WS_EX_CONTROLPARENT
);
1345 if (LOWORD(wParam
) == IDC_TAB
&&
1346 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1347 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1349 DestroyWindow (*page
);
1350 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1351 hwnd, panelproc[panelnums[i]]);*/
1352 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1353 hwnd
, panelproc
[panelnums
[i
]]);
1354 SetWindowLong (*page
, GWL_EXSTYLE
,
1355 GetWindowLong (*page
, GWL_EXSTYLE
) |
1356 WS_EX_CONTROLPARENT
);
1357 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1361 /* case WM_CTLCOLORDLG: */
1362 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1364 switch (LOWORD(wParam
)) {
1367 EndDialog (hwnd
, 1);
1372 EndDialog (hwnd
, 0);
1377 EndDialog (hwnd
, 0);
1380 /* Grrr Explorer will maximize Dialogs! */
1382 if (wParam
== SIZE_MAXIMIZED
)
1389 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1390 WPARAM wParam
, LPARAM lParam
) {
1395 static HWND page
= NULL
;
1397 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1400 * If the Connection panel is active and the Session List
1401 * box is selected, we treat a press of Open to have an
1402 * implicit press of Load preceding it.
1404 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1405 i
= TabCtrl_GetCurSel(hw
);
1406 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1407 page
&& implicit_load_ok
) {
1408 SendMessage (page
, WM_COMMAND
,
1409 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1413 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1414 EnableWindow(hwnd
, 0);
1415 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1416 GetParent(hwnd
), AboutProc
);
1417 EnableWindow(hwnd
, 1);
1418 SetActiveWindow(hwnd
);
1420 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1421 MAIN_NPANELS
, mainp
, &page
);
1424 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1425 WPARAM wParam
, LPARAM lParam
) {
1427 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1428 RECONF_NPANELS
, reconfp
, &page
);
1431 void get_sesslist(int allocate
) {
1432 static char otherbuf
[2048];
1433 static char *buffer
;
1434 int buflen
, bufsize
, i
;
1440 if ((handle
= enum_settings_start()) == NULL
)
1443 buflen
= bufsize
= 0;
1446 ret
= enum_settings_next(handle
, otherbuf
, sizeof(otherbuf
));
1448 int len
= strlen(otherbuf
)+1;
1449 if (bufsize
< buflen
+len
) {
1450 bufsize
= buflen
+ len
+ 2048;
1451 buffer
= srealloc(buffer
, bufsize
);
1453 strcpy(buffer
+buflen
, otherbuf
);
1454 buflen
+= strlen(buffer
+buflen
)+1;
1457 enum_settings_finish(handle
);
1458 buffer
= srealloc(buffer
, buflen
+1);
1459 buffer
[buflen
] = '\0';
1462 nsessions
= 1; /* "Default Settings" counts as one */
1464 if (strcmp(p
, "Default Settings"))
1470 sessions
= smalloc(nsessions
* sizeof(char *));
1471 sessions
[0] = "Default Settings";
1475 if (strcmp(p
, "Default Settings"))
1486 int do_config (void) {
1490 savedsession
[0] = '\0';
1491 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1492 get_sesslist(FALSE
);
1497 int do_reconfig (HWND hwnd
) {
1501 backup_cfg
= cfg
; /* structure copy */
1502 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1504 cfg
= backup_cfg
; /* structure copy */
1511 void do_defaults (char *session
) {
1513 load_settings (session
, TRUE
);
1515 load_settings ("Default Settings", FALSE
);
1518 void logevent (char *string
) {
1519 if (nevents
>= negsize
) {
1521 events
= srealloc (events
, negsize
* sizeof(*events
));
1523 events
[nevents
] = smalloc(1+strlen(string
));
1524 strcpy (events
[nevents
], string
);
1528 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1530 count
= SendDlgItemMessage (logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
1531 SendDlgItemMessage (logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
-1, 0);
1535 void showeventlog (HWND hwnd
) {
1537 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1539 ShowWindow (logbox
, SW_SHOWNORMAL
);
1543 void showabout (HWND hwnd
) {
1545 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1547 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1551 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
1552 char *keystr
, char *fingerprint
) {
1555 static const char absentmsg
[] =
1556 "The server's host key is not cached in the registry. You\n"
1557 "have no guarantee that the server is the computer you\n"
1559 "The server's key fingerprint is:\n"
1561 "If you trust this host, hit Yes to add the key to\n"
1562 "PuTTY's cache and carry on connecting.\n"
1563 "If you do not trust this host, hit No to abandon the\n"
1566 static const char wrongmsg
[] =
1567 "WARNING - POTENTIAL SECURITY BREACH!\n"
1569 "The server's host key does not match the one PuTTY has\n"
1570 "cached in the registry. This means that either the\n"
1571 "server administrator has changed the host key, or you\n"
1572 "have actually connected to another computer pretending\n"
1573 "to be the server.\n"
1574 "The new key fingerprint is:\n"
1576 "If you were expecting this change and trust the new key,\n"
1577 "hit Yes to update PuTTY's cache and continue connecting.\n"
1578 "If you want to carry on connecting but without updating\n"
1579 "the cache, hit No.\n"
1580 "If you want to abandon the connection completely, hit\n"
1581 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1584 static const char mbtitle
[] = "PuTTY Security Alert";
1587 char message
[160+ /* sensible fingerprint max size */
1588 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
1589 sizeof(absentmsg
) : sizeof(wrongmsg
))];
1592 * Verify the key against the registry.
1594 ret
= verify_host_key(host
, port
, keytype
, keystr
);
1596 if (ret
== 0) /* success - key matched OK */
1598 if (ret
== 2) { /* key was different */
1600 sprintf(message
, wrongmsg
, fingerprint
);
1601 mbret
= MessageBox(NULL
, message
, mbtitle
,
1602 MB_ICONWARNING
| MB_YESNOCANCEL
);
1604 store_host_key(host
, port
, keytype
, keystr
);
1605 if (mbret
== IDCANCEL
)
1608 if (ret
== 1) { /* key was absent */
1610 sprintf(message
, absentmsg
, fingerprint
);
1611 mbret
= MessageBox(NULL
, message
, mbtitle
,
1612 MB_ICONWARNING
| MB_YESNO
);
1615 store_host_key(host
, port
, keytype
, keystr
);