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
)) {
396 DestroyWindow (hwnd
);
402 DestroyWindow (hwnd
);
408 static int CALLBACK
AboutProc (HWND hwnd
, UINT msg
,
409 WPARAM wParam
, LPARAM lParam
) {
412 SetDlgItemText (hwnd
, IDA_VERSION
, ver
);
414 /* case WM_CTLCOLORDLG: */
415 /* return (int) GetStockObject (LTGRAY_BRUSH); */
416 /* case WM_CTLCOLORSTATIC: */
417 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
418 /* return (int) GetStockObject (LTGRAY_BRUSH); */
420 switch (LOWORD(wParam
)) {
423 DestroyWindow (hwnd
);
426 EnableWindow(hwnd
, 0);
427 DialogBox (hinst
, MAKEINTRESOURCE(IDD_LICENCEBOX
),
429 EnableWindow(hwnd
, 1);
430 SetActiveWindow(hwnd
);
436 DestroyWindow (hwnd
);
442 static int GeneralPanelProc (HWND hwnd
, UINT msg
,
443 WPARAM wParam
, LPARAM lParam
) {
446 SetWindowPos (hwnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
| SWP_NOSIZE
);
448 /* case WM_CTLCOLORDLG: */
449 /* return (int) GetStockObject (LTGRAY_BRUSH); */
450 /* case WM_CTLCOLORSTATIC: */
451 /* case WM_CTLCOLORBTN: */
452 /* SetBkColor ((HDC)wParam, RGB(192,192,192)); */
453 /* return (int) GetStockObject (LTGRAY_BRUSH); */
455 DestroyWindow (hwnd
);
461 static char savedsession
[2048];
463 static int CALLBACK
ConnectionProc (HWND hwnd
, UINT msg
,
464 WPARAM wParam
, LPARAM lParam
) {
469 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
470 SetDlgItemText (hwnd
, IDC0_SESSEDIT
, savedsession
);
471 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
472 for (i
= 0; i
< nsessions
; i
++)
473 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
474 0, (LPARAM
) (sessions
[i
]));
475 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
476 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
477 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
478 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
479 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
483 * Button release should trigger WM_OK if there was a
484 * previous double click on the session list.
488 SendMessage (GetParent(hwnd
), WM_COMMAND
, IDOK
, 0);
491 switch (LOWORD(wParam
)) {
492 case IDC0_PROTTELNET
:
495 if (HIWORD(wParam
) == BN_CLICKED
||
496 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
497 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
498 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
499 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
500 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
501 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
502 cfg
.port
= i ?
22 : 23;
503 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
508 if (HIWORD(wParam
) == EN_CHANGE
)
509 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
513 if (HIWORD(wParam
) == EN_CHANGE
)
514 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
517 if (HIWORD(wParam
) == BN_CLICKED
||
518 HIWORD(wParam
) == BN_DOUBLECLICKED
)
519 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
522 if (HIWORD(wParam
) == BN_CLICKED
||
523 HIWORD(wParam
) == BN_DOUBLECLICKED
)
524 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
527 if (HIWORD(wParam
) == EN_CHANGE
) {
528 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
530 GetDlgItemText (hwnd
, IDC0_SESSEDIT
,
531 savedsession
, sizeof(savedsession
)-1);
532 savedsession
[sizeof(savedsession
)-1] = '\0';
536 if (HIWORD(wParam
) == BN_CLICKED
||
537 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
542 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
544 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
550 strcpy (str
, sessions
[n
]);
552 save_settings (str
, !!strcmp(str
, "Default Settings"));
553 get_sesslist (FALSE
);
555 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
557 for (i
= 0; i
< nsessions
; i
++)
558 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
559 0, (LPARAM
) (sessions
[i
]));
560 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
566 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
567 HIWORD(wParam
) != BN_CLICKED
&&
568 HIWORD(wParam
) != BN_DOUBLECLICKED
)
570 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
571 HIWORD(wParam
) != LBN_DBLCLK
)
574 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
580 load_settings (sessions
[n
],
581 !!strcmp(sessions
[n
], "Default Settings"));
582 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
583 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
584 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
585 (cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
586 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
));
587 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
588 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
589 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
592 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
594 * A double-click on a saved session should
595 * actually start the session, not just load it.
596 * Unless it's Default Settings or some other
597 * host-less set of saved settings.
606 if (HIWORD(wParam
) == BN_CLICKED
||
607 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
608 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
610 if (n
== LB_ERR
|| n
== 0) {
614 del_settings(sessions
[n
]);
615 get_sesslist (FALSE
);
617 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
619 for (i
= 0; i
< nsessions
; i
++)
620 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
621 0, (LPARAM
) (sessions
[i
]));
622 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
627 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
630 static int CALLBACK
KeyboardProc (HWND hwnd
, UINT msg
,
631 WPARAM wParam
, LPARAM lParam
) {
634 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
635 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
636 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
637 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
638 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
640 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
643 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
644 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
645 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
646 cfg
.nethack_keypad ? IDC1_KPNH
:
647 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
648 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
649 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
650 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
651 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
654 if (HIWORD(wParam
) == BN_CLICKED
||
655 HIWORD(wParam
) == BN_DOUBLECLICKED
)
656 switch (LOWORD(wParam
)) {
659 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
663 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
670 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
674 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
675 cfg
.nethack_keypad
= FALSE
;
678 cfg
.app_keypad
= FALSE
;
679 cfg
.nethack_keypad
= TRUE
;
683 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
686 if (HIWORD(wParam
) == BN_CLICKED
||
687 HIWORD(wParam
) == BN_DOUBLECLICKED
)
688 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
691 if (HIWORD(wParam
) == BN_CLICKED
||
692 HIWORD(wParam
) == BN_DOUBLECLICKED
)
693 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
696 if (HIWORD(wParam
) == BN_CLICKED
||
697 HIWORD(wParam
) == BN_DOUBLECLICKED
)
698 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
701 if (HIWORD(wParam
) == BN_CLICKED
||
702 HIWORD(wParam
) == BN_DOUBLECLICKED
)
703 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
707 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
710 static void fmtfont (char *buf
) {
711 sprintf (buf
, "Font: %s, ", cfg
.font
);
713 strcat(buf
, "bold, ");
714 if (cfg
.fontheight
== 0)
715 strcat (buf
, "default height");
717 sprintf (buf
+strlen(buf
), "%d-%s",
718 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
719 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
722 static int CALLBACK
TerminalProc (HWND hwnd
, UINT msg
,
723 WPARAM wParam
, LPARAM lParam
) {
726 char fontstatic
[256];
730 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
731 CheckDlgButton (hwnd
, IDC2_WINNAME
, cfg
.win_name_always
);
732 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
733 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
734 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
735 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
736 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
737 fmtfont (fontstatic
);
738 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
739 CheckDlgButton (hwnd
, IDC1_BLINKCUR
, cfg
.blink_cur
);
740 CheckDlgButton (hwnd
, IDC1_BEEP
, cfg
.beep
);
741 CheckDlgButton (hwnd
, IDC2_SCROLLBAR
, cfg
.scrollbar
);
742 CheckDlgButton (hwnd
, IDC2_LOCKSIZE
, cfg
.locksize
);
743 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
744 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
747 switch (LOWORD(wParam
)) {
749 if (HIWORD(wParam
) == BN_CLICKED
||
750 HIWORD(wParam
) == BN_DOUBLECLICKED
)
751 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
754 if (HIWORD(wParam
) == BN_CLICKED
||
755 HIWORD(wParam
) == BN_DOUBLECLICKED
)
756 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC2_WINNAME
);
759 if (HIWORD(wParam
) == BN_CLICKED
||
760 HIWORD(wParam
) == BN_DOUBLECLICKED
)
761 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
764 if (HIWORD(wParam
) == BN_CLICKED
||
765 HIWORD(wParam
) == BN_DOUBLECLICKED
)
766 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
769 if (HIWORD(wParam
) == EN_CHANGE
)
770 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
773 if (HIWORD(wParam
) == EN_CHANGE
)
774 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
777 if (HIWORD(wParam
) == EN_CHANGE
)
778 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
780 case IDC2_CHOOSEFONT
:
781 lf
.lfHeight
= cfg
.fontheight
;
782 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
783 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
784 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
785 lf
.lfCharSet
= cfg
.fontcharset
;
786 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
787 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
788 lf
.lfQuality
= DEFAULT_QUALITY
;
789 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
790 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
791 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
793 cf
.lStructSize
= sizeof(cf
);
796 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
797 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
799 if (ChooseFont (&cf
)) {
800 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
801 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
802 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
803 cfg
.fontcharset
= lf
.lfCharSet
;
804 cfg
.fontheight
= lf
.lfHeight
;
805 fmtfont (fontstatic
);
806 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
810 if (HIWORD(wParam
) == BN_CLICKED
||
811 HIWORD(wParam
) == BN_DOUBLECLICKED
)
812 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC1_BLINKCUR
);
815 if (HIWORD(wParam
) == BN_CLICKED
||
816 HIWORD(wParam
) == BN_DOUBLECLICKED
)
817 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC1_BEEP
);
820 if (HIWORD(wParam
) == BN_CLICKED
||
821 HIWORD(wParam
) == BN_DOUBLECLICKED
)
822 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC2_SCROLLBAR
);
825 if (HIWORD(wParam
) == BN_CLICKED
||
826 HIWORD(wParam
) == BN_DOUBLECLICKED
)
827 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC2_LOCKSIZE
);
830 if (HIWORD(wParam
) == BN_CLICKED
||
831 HIWORD(wParam
) == BN_DOUBLECLICKED
)
832 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
835 if (HIWORD(wParam
) == BN_CLICKED
||
836 HIWORD(wParam
) == BN_DOUBLECLICKED
)
837 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
842 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
845 static int CALLBACK
TelnetProc (HWND hwnd
, UINT msg
,
846 WPARAM wParam
, LPARAM lParam
) {
851 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
852 SetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
);
853 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
855 char *p
= cfg
.environmt
;
857 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
, 0,
862 CheckRadioButton (hwnd
, IDC3_EMBSD
, IDC3_EMRFC
,
863 cfg
.rfc_environ ? IDC3_EMRFC
: IDC3_EMBSD
);
866 switch (LOWORD(wParam
)) {
868 if (HIWORD(wParam
) == EN_CHANGE
)
869 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
870 sizeof(cfg
.termtype
)-1);
873 if (HIWORD(wParam
) == EN_CHANGE
)
874 GetDlgItemText (hwnd
, IDC3_TSEDIT
, cfg
.termspeed
,
875 sizeof(cfg
.termspeed
)-1);
878 if (HIWORD(wParam
) == EN_CHANGE
)
879 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
880 sizeof(cfg
.username
)-1);
884 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC3_EMRFC
);
887 if (HIWORD(wParam
) == BN_CLICKED
||
888 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
889 char str
[sizeof(cfg
.environmt
)];
891 GetDlgItemText (hwnd
, IDC3_VAREDIT
, str
, sizeof(str
)-1);
896 p
= str
+ strlen(str
);
898 GetDlgItemText (hwnd
, IDC3_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
908 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
910 p
[strlen(str
)+1] = '\0';
911 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_ADDSTRING
,
913 SetDlgItemText (hwnd
, IDC3_VAREDIT
, "");
914 SetDlgItemText (hwnd
, IDC3_VALEDIT
, "");
916 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
917 MB_OK
| MB_ICONERROR
);
922 if (HIWORD(wParam
) != BN_CLICKED
&&
923 HIWORD(wParam
) != BN_DOUBLECLICKED
)
925 i
= SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_GETCURSEL
, 0, 0);
931 SendDlgItemMessage (hwnd
, IDC3_ENVLIST
, LB_DELETESTRING
,
958 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
961 static int CALLBACK
SshProc (HWND hwnd
, UINT msg
,
962 WPARAM wParam
, LPARAM lParam
) {
964 char filename
[sizeof(cfg
.keyfile
)];
968 SetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
);
969 SetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
);
970 CheckDlgButton (hwnd
, IDC3_NOPTY
, cfg
.nopty
);
971 CheckDlgButton (hwnd
, IDC3_AGENTFWD
, cfg
.agentfwd
);
972 CheckRadioButton (hwnd
, IDC3_CIPHER3DES
, IDC3_CIPHERDES
,
973 cfg
.cipher
== CIPHER_BLOWFISH ? IDC3_CIPHERBLOWF
:
974 cfg
.cipher
== CIPHER_DES ? IDC3_CIPHERDES
:
976 CheckRadioButton (hwnd
, IDC3_SSHPROT1
, IDC3_SSHPROT2
,
977 cfg
.sshprot
== 1 ? IDC3_SSHPROT1
: IDC3_SSHPROT2
);
978 CheckDlgButton (hwnd
, IDC3_AUTHTIS
, cfg
.try_tis_auth
);
979 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
982 switch (LOWORD(wParam
)) {
984 if (HIWORD(wParam
) == EN_CHANGE
)
985 GetDlgItemText (hwnd
, IDC3_TTEDIT
, cfg
.termtype
,
986 sizeof(cfg
.termtype
)-1);
989 if (HIWORD(wParam
) == EN_CHANGE
)
990 GetDlgItemText (hwnd
, IDC3_LOGEDIT
, cfg
.username
,
991 sizeof(cfg
.username
)-1);
994 if (HIWORD(wParam
) == BN_CLICKED
||
995 HIWORD(wParam
) == BN_DOUBLECLICKED
)
996 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC3_NOPTY
);
999 if (HIWORD(wParam
) == BN_CLICKED
||
1000 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1001 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC3_AGENTFWD
);
1003 case IDC3_CIPHER3DES
:
1004 case IDC3_CIPHERBLOWF
:
1005 case IDC3_CIPHERDES
:
1006 if (HIWORD(wParam
) == BN_CLICKED
||
1007 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1008 if (IsDlgButtonChecked (hwnd
, IDC3_CIPHER3DES
))
1009 cfg
.cipher
= CIPHER_3DES
;
1010 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERBLOWF
))
1011 cfg
.cipher
= CIPHER_BLOWFISH
;
1012 else if (IsDlgButtonChecked (hwnd
, IDC3_CIPHERDES
))
1013 cfg
.cipher
= CIPHER_DES
;
1018 if (HIWORD(wParam
) == BN_CLICKED
||
1019 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1020 if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT1
))
1022 else if (IsDlgButtonChecked (hwnd
, IDC3_SSHPROT2
))
1027 if (HIWORD(wParam
) == BN_CLICKED
||
1028 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1029 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC3_AUTHTIS
);
1032 if (HIWORD(wParam
) == EN_CHANGE
)
1033 GetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
,
1034 sizeof(cfg
.keyfile
)-1);
1038 * FIXME: this crashes. Find out why.
1040 memset(&of
, 0, sizeof(of
));
1041 #ifdef OPENFILENAME_SIZE_VERSION_400
1042 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1044 of
.lStructSize
= sizeof(of
);
1046 of
.hwndOwner
= hwnd
;
1047 of
.lpstrFilter
= "All Files\0*\0\0\0";
1048 of
.lpstrCustomFilter
= NULL
;
1049 of
.nFilterIndex
= 1;
1050 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1051 of
.nMaxFile
= sizeof(filename
);
1052 of
.lpstrFileTitle
= NULL
;
1053 of
.lpstrInitialDir
= NULL
;
1054 of
.lpstrTitle
= "Select Public Key File";
1056 if (GetOpenFileName(&of
)) {
1057 strcpy(cfg
.keyfile
, filename
);
1058 SetDlgItemText (hwnd
, IDC3_PKEDIT
, cfg
.keyfile
);
1064 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1067 static int CALLBACK
SelectionProc (HWND hwnd
, UINT msg
,
1068 WPARAM wParam
, LPARAM lParam
) {
1073 CheckRadioButton (hwnd
, IDC4_MBWINDOWS
, IDC4_MBXTERM
,
1074 cfg
.mouse_is_xterm ? IDC4_MBXTERM
: IDC4_MBWINDOWS
);
1076 static int tabs
[4] = {25, 61, 96, 128};
1077 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_SETTABSTOPS
, 4,
1080 for (i
=0; i
<256; i
++) {
1082 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1083 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1085 SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_ADDSTRING
, 0,
1090 switch (LOWORD(wParam
)) {
1091 case IDC4_MBWINDOWS
:
1093 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC4_MBXTERM
);
1099 int n
= GetDlgItemInt (hwnd
, IDC4_CCEDIT
, &ok
, FALSE
);
1104 for (i
=0; i
<256; i
++)
1105 if (SendDlgItemMessage (hwnd
, IDC4_CCLIST
, LB_GETSEL
,
1108 cfg
.wordness
[i
] = n
;
1109 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1110 LB_DELETESTRING
, i
, 0);
1111 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1112 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1114 SendDlgItemMessage (hwnd
, IDC4_CCLIST
,
1124 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1127 static int CALLBACK
ColourProc (HWND hwnd
, UINT msg
,
1128 WPARAM wParam
, LPARAM lParam
) {
1129 static const char *const colours
[] = {
1130 "Default Foreground", "Default Bold Foreground",
1131 "Default Background", "Default Bold Background",
1132 "Cursor Text", "Cursor Colour",
1133 "ANSI Black", "ANSI Black Bold",
1134 "ANSI Red", "ANSI Red Bold",
1135 "ANSI Green", "ANSI Green Bold",
1136 "ANSI Yellow", "ANSI Yellow Bold",
1137 "ANSI Blue", "ANSI Blue Bold",
1138 "ANSI Magenta", "ANSI Magenta Bold",
1139 "ANSI Cyan", "ANSI Cyan Bold",
1140 "ANSI White", "ANSI White Bold"
1142 static const int permanent
[] = {
1143 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
1144 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
1145 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
1149 CheckDlgButton (hwnd
, IDC5_BOLDCOLOUR
, cfg
.bold_colour
);
1150 CheckDlgButton (hwnd
, IDC5_PALETTE
, cfg
.try_palette
);
1153 for (i
=0; i
<22; i
++)
1154 if (cfg
.bold_colour
|| permanent
[i
])
1155 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_ADDSTRING
, 0,
1156 (LPARAM
) colours
[i
]);
1158 SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_SETCURSEL
, 0, 0);
1159 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[0][0], FALSE
);
1160 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[0][1], FALSE
);
1161 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[0][2], FALSE
);
1164 switch (LOWORD(wParam
)) {
1165 case IDC5_BOLDCOLOUR
:
1166 if (HIWORD(wParam
) == BN_CLICKED
||
1167 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1169 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC5_BOLDCOLOUR
);
1170 n
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCOUNT
, 0, 0);
1171 if (cfg
.bold_colour
&& n
!=22) {
1172 for (i
=0; i
<22; i
++)
1174 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1176 (LPARAM
) colours
[i
]);
1177 } else if (!cfg
.bold_colour
&& n
!=12) {
1180 SendDlgItemMessage (hwnd
, IDC5_LIST
,
1181 LB_DELETESTRING
, i
, 0);
1186 if (HIWORD(wParam
) == BN_CLICKED
||
1187 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1188 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC5_PALETTE
);
1191 if (HIWORD(wParam
) == LBN_DBLCLK
||
1192 HIWORD(wParam
) == LBN_SELCHANGE
) {
1193 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1195 if (!cfg
.bold_colour
)
1196 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1197 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1198 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1199 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1203 if (HIWORD(wParam
) == BN_CLICKED
||
1204 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1205 static CHOOSECOLOR cc
;
1206 static DWORD custom
[16] = {0}; /* zero initialisers */
1207 int i
= SendDlgItemMessage (hwnd
, IDC5_LIST
, LB_GETCURSEL
,
1209 if (!cfg
.bold_colour
)
1210 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1211 cc
.lStructSize
= sizeof(cc
);
1212 cc
.hwndOwner
= hwnd
;
1213 cc
.hInstance
= (HWND
)hinst
;
1214 cc
.lpCustColors
= custom
;
1215 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1217 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1218 if (ChooseColor(&cc
)) {
1220 (unsigned char) (cc
.rgbResult
& 0xFF);
1222 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1224 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1225 SetDlgItemInt (hwnd
, IDC5_RVALUE
, cfg
.colours
[i
][0],
1227 SetDlgItemInt (hwnd
, IDC5_GVALUE
, cfg
.colours
[i
][1],
1229 SetDlgItemInt (hwnd
, IDC5_BVALUE
, cfg
.colours
[i
][2],
1237 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1240 static int CALLBACK
TranslationProc (HWND hwnd
, UINT msg
,
1241 WPARAM wParam
, LPARAM lParam
) {
1244 CheckRadioButton (hwnd
, IDC6_NOXLAT
, IDC6_88592WIN1250
,
1245 cfg
.xlat_88592w1250 ? IDC6_88592WIN1250
:
1246 cfg
.xlat_enablekoiwin ? IDC6_KOI8WIN1251
:
1248 CheckDlgButton (hwnd
, IDC6_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1249 CheckRadioButton (hwnd
, IDC2_VTXWINDOWS
, IDC2_VTPOORMAN
,
1250 cfg
.vtmode
== VT_XWINDOWS ? IDC2_VTXWINDOWS
:
1251 cfg
.vtmode
== VT_OEMANSI ? IDC2_VTOEMANSI
:
1252 cfg
.vtmode
== VT_OEMONLY ? IDC2_VTOEMONLY
:
1255 switch (LOWORD(wParam
)) {
1257 case IDC6_KOI8WIN1251
:
1258 case IDC6_88592WIN1250
:
1259 cfg
.xlat_enablekoiwin
=
1260 IsDlgButtonChecked (hwnd
, IDC6_KOI8WIN1251
);
1261 cfg
.xlat_88592w1250
=
1262 IsDlgButtonChecked (hwnd
, IDC6_88592WIN1250
);
1264 case IDC6_CAPSLOCKCYR
:
1265 if (HIWORD(wParam
) == BN_CLICKED
||
1266 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1267 cfg
.xlat_capslockcyr
=
1268 IsDlgButtonChecked (hwnd
, IDC6_CAPSLOCKCYR
);
1271 case IDC2_VTXWINDOWS
:
1272 case IDC2_VTOEMANSI
:
1273 case IDC2_VTOEMONLY
:
1274 case IDC2_VTPOORMAN
:
1276 (IsDlgButtonChecked (hwnd
, IDC2_VTXWINDOWS
) ? VT_XWINDOWS
:
1277 IsDlgButtonChecked (hwnd
, IDC2_VTOEMANSI
) ? VT_OEMANSI
:
1278 IsDlgButtonChecked (hwnd
, IDC2_VTOEMONLY
) ? VT_OEMONLY
:
1283 return GeneralPanelProc (hwnd
, msg
, wParam
, lParam
);
1286 static DLGPROC panelproc
[NPANELS
] = {
1287 ConnectionProc
, KeyboardProc
, TerminalProc
,
1288 TelnetProc
, SshProc
, SelectionProc
, ColourProc
, TranslationProc
1290 static char *panelids
[NPANELS
] = {
1291 MAKEINTRESOURCE(IDD_PANEL0
),
1292 MAKEINTRESOURCE(IDD_PANEL1
),
1293 MAKEINTRESOURCE(IDD_PANEL2
),
1294 MAKEINTRESOURCE(IDD_PANEL3
),
1295 MAKEINTRESOURCE(IDD_PANEL35
),
1296 MAKEINTRESOURCE(IDD_PANEL4
),
1297 MAKEINTRESOURCE(IDD_PANEL5
),
1298 MAKEINTRESOURCE(IDD_PANEL6
)
1301 static char *names
[NPANELS
] = {
1302 "Connection", "Keyboard", "Terminal", "Telnet",
1303 "SSH", "Selection", "Colours", "Translation"
1306 static int mainp
[MAIN_NPANELS
] = { 0, 1, 2, 3, 4, 5, 6, 7};
1307 static int reconfp
[RECONF_NPANELS
] = { 1, 2, 5, 6, 7};
1309 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1310 WPARAM wParam
, LPARAM lParam
,
1311 int npanels
, int *panelnums
, HWND
*page
) {
1316 { /* centre the window */
1319 hw
= GetDesktopWindow();
1320 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1321 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1322 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1323 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1326 { /* initialise the tab control */
1330 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1331 for (i
=0; i
<npanels
; i
++) {
1332 tab
.mask
= TCIF_TEXT
;
1333 tab
.pszText
= names
[panelnums
[i
]];
1334 TabCtrl_InsertItem (hw
, i
, &tab
);
1336 /* *page = CreateDialogIndirect (hinst, panels[panelnums[0]].temp,
1337 hwnd, panelproc[panelnums[0]]);*/
1338 *page
= CreateDialog (hinst
, panelids
[panelnums
[0]],
1339 hwnd
, panelproc
[panelnums
[0]]);
1340 SetWindowLong (*page
, GWL_EXSTYLE
,
1341 GetWindowLong (*page
, GWL_EXSTYLE
) |
1342 WS_EX_CONTROLPARENT
);
1347 if (LOWORD(wParam
) == IDC_TAB
&&
1348 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1349 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1351 DestroyWindow (*page
);
1352 /* *page = CreateDialogIndirect (hinst, panels[panelnums[i]].temp,
1353 hwnd, panelproc[panelnums[i]]);*/
1354 *page
= CreateDialog (hinst
, panelids
[panelnums
[i
]],
1355 hwnd
, panelproc
[panelnums
[i
]]);
1356 SetWindowLong (*page
, GWL_EXSTYLE
,
1357 GetWindowLong (*page
, GWL_EXSTYLE
) |
1358 WS_EX_CONTROLPARENT
);
1359 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1363 /* case WM_CTLCOLORDLG: */
1364 /* return (int) GetStockObject (LTGRAY_BRUSH); */
1366 switch (LOWORD(wParam
)) {
1369 EndDialog (hwnd
, 1);
1374 EndDialog (hwnd
, 0);
1379 EndDialog (hwnd
, 0);
1382 /* Grrr Explorer will maximize Dialogs! */
1384 if (wParam
== SIZE_MAXIMIZED
)
1391 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
1392 WPARAM wParam
, LPARAM lParam
) {
1397 static HWND page
= NULL
;
1399 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
1402 * If the Connection panel is active and the Session List
1403 * box is selected, we treat a press of Open to have an
1404 * implicit press of Load preceding it.
1406 hw
= GetDlgItem (hwnd
, IDC_TAB
);
1407 i
= TabCtrl_GetCurSel(hw
);
1408 if (panelproc
[mainp
[i
]] == ConnectionProc
&&
1409 page
&& implicit_load_ok
) {
1410 SendMessage (page
, WM_COMMAND
,
1411 MAKELONG(IDC0_SESSLOAD
, BN_CLICKED
), 0);
1415 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDC_ABOUT
) {
1416 EnableWindow(hwnd
, 0);
1417 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1418 GetParent(hwnd
), AboutProc
);
1419 EnableWindow(hwnd
, 1);
1420 SetActiveWindow(hwnd
);
1422 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1423 MAIN_NPANELS
, mainp
, &page
);
1426 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
1427 WPARAM wParam
, LPARAM lParam
) {
1429 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
,
1430 RECONF_NPANELS
, reconfp
, &page
);
1433 void get_sesslist(int allocate
) {
1434 static char otherbuf
[2048];
1435 static char *buffer
;
1436 int buflen
, bufsize
, i
;
1442 if ((handle
= enum_settings_start()) == NULL
)
1445 buflen
= bufsize
= 0;
1448 ret
= enum_settings_next(handle
, otherbuf
, sizeof(otherbuf
));
1450 int len
= strlen(otherbuf
)+1;
1451 if (bufsize
< buflen
+len
) {
1452 bufsize
= buflen
+ len
+ 2048;
1453 buffer
= srealloc(buffer
, bufsize
);
1455 strcpy(buffer
+buflen
, otherbuf
);
1456 buflen
+= strlen(buffer
+buflen
)+1;
1459 enum_settings_finish(handle
);
1460 buffer
= srealloc(buffer
, buflen
+1);
1461 buffer
[buflen
] = '\0';
1464 nsessions
= 1; /* "Default Settings" counts as one */
1466 if (strcmp(p
, "Default Settings"))
1472 sessions
= smalloc(nsessions
* sizeof(char *));
1473 sessions
[0] = "Default Settings";
1477 if (strcmp(p
, "Default Settings"))
1488 int do_config (void) {
1492 savedsession
[0] = '\0';
1493 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
1494 get_sesslist(FALSE
);
1499 int do_reconfig (HWND hwnd
) {
1503 backup_cfg
= cfg
; /* structure copy */
1504 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
1506 cfg
= backup_cfg
; /* structure copy */
1513 void do_defaults (char *session
) {
1515 load_settings (session
, TRUE
);
1517 load_settings ("Default Settings", FALSE
);
1520 void logevent (char *string
) {
1521 if (nevents
>= negsize
) {
1523 events
= srealloc (events
, negsize
* sizeof(*events
));
1525 events
[nevents
] = smalloc(1+strlen(string
));
1526 strcpy (events
[nevents
], string
);
1530 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
1532 count
= SendDlgItemMessage (logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
1533 SendDlgItemMessage (logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
-1, 0);
1537 void showeventlog (HWND hwnd
) {
1539 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
1541 ShowWindow (logbox
, SW_SHOWNORMAL
);
1545 void showabout (HWND hwnd
) {
1547 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
1549 ShowWindow (abtbox
, SW_SHOWNORMAL
);
1553 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
1554 char *keystr
, char *fingerprint
) {
1557 static const char absentmsg
[] =
1558 "The server's host key is not cached in the registry. You\n"
1559 "have no guarantee that the server is the computer you\n"
1561 "The server's key fingerprint is:\n"
1563 "If you trust this host, hit Yes to add the key to\n"
1564 "PuTTY's cache and carry on connecting.\n"
1565 "If you do not trust this host, hit No to abandon the\n"
1568 static const char wrongmsg
[] =
1569 "WARNING - POTENTIAL SECURITY BREACH!\n"
1571 "The server's host key does not match the one PuTTY has\n"
1572 "cached in the registry. This means that either the\n"
1573 "server administrator has changed the host key, or you\n"
1574 "have actually connected to another computer pretending\n"
1575 "to be the server.\n"
1576 "The new key fingerprint is:\n"
1578 "If you were expecting this change and trust the new key,\n"
1579 "hit Yes to update PuTTY's cache and continue connecting.\n"
1580 "If you want to carry on connecting but without updating\n"
1581 "the cache, hit No.\n"
1582 "If you want to abandon the connection completely, hit\n"
1583 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
1586 static const char mbtitle
[] = "PuTTY Security Alert";
1589 char message
[160+ /* sensible fingerprint max size */
1590 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
1591 sizeof(absentmsg
) : sizeof(wrongmsg
))];
1594 * Verify the key against the registry.
1596 ret
= verify_host_key(host
, port
, keytype
, keystr
);
1598 if (ret
== 0) /* success - key matched OK */
1600 if (ret
== 2) { /* key was different */
1602 sprintf(message
, wrongmsg
, fingerprint
);
1603 mbret
= MessageBox(NULL
, message
, mbtitle
,
1604 MB_ICONWARNING
| MB_YESNOCANCEL
);
1606 store_host_key(host
, port
, keytype
, keystr
);
1607 if (mbret
== IDCANCEL
)
1610 if (ret
== 1) { /* key was absent */
1612 sprintf(message
, absentmsg
, fingerprint
);
1613 mbret
= MessageBox(NULL
, message
, mbtitle
,
1614 MB_ICONWARNING
| MB_YESNO
);
1617 store_host_key(host
, port
, keytype
, keystr
);