Ability to hide the mouse pointer on a keypress a la Word
[sgt/putty] / windlg.c
1 #include <windows.h>
2 #include <commctrl.h>
3 #include <commdlg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #include "ssh.h"
8 #include "putty.h"
9 #include "winstuff.h"
10 #include "win_res.h"
11 #include "storage.h"
12
13 static char **events = NULL;
14 static int nevents = 0, negsize = 0;
15
16 static HWND logbox = NULL, abtbox = NULL;
17
18 static int readytogo;
19
20 void force_normal(HWND hwnd)
21 {
22 static int recurse = 0;
23
24 WINDOWPLACEMENT wp;
25
26 if(recurse) return;
27 recurse = 1;
28
29 wp.length = sizeof(wp);
30 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED)
31 {
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
34 }
35 recurse = 0;
36 }
37
38 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
39 BOOL ok;
40 int n;
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
42 if (ok)
43 *result = n;
44 }
45
46 static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
48 int i;
49
50 switch (msg) {
51 case WM_INITDIALOG:
52 for (i=0; i<nevents; i++)
53 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
54 0, (LPARAM)events[i]);
55 return 1;
56 case WM_COMMAND:
57 switch (LOWORD(wParam)) {
58 case IDOK:
59 logbox = NULL;
60 DestroyWindow (hwnd);
61 return 0;
62 case IDN_COPY:
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
65 int selcount;
66 int *selitems;
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
69 selitems = smalloc(selcount * sizeof(int));
70 if (selitems) {
71 int count = SendDlgItemMessage(hwnd, IDN_LIST,
72 LB_GETSELITEMS,
73 selcount, (LPARAM)selitems);
74 int i;
75 int size;
76 char *clipdata;
77 static unsigned char sel_nl[] = SEL_NL;
78
79 if (count == 0) { /* can't copy zero stuff */
80 MessageBeep(0);
81 break;
82 }
83
84 size = 0;
85 for (i = 0; i < count; i++)
86 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
87
88 clipdata = smalloc(size);
89 if (clipdata) {
90 char *p = clipdata;
91 for (i = 0; i < count; i++) {
92 char *q = events[selitems[i]];
93 int qlen = strlen(q);
94 memcpy(p, q, qlen);
95 p += qlen;
96 memcpy(p, sel_nl, sizeof(sel_nl));
97 p += sizeof(sel_nl);
98 }
99 write_clip(clipdata, size, TRUE);
100 sfree(clipdata);
101 }
102 sfree(selitems);
103
104 for (i = 0; i < nevents; i++)
105 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
106 FALSE, i);
107 }
108 }
109 return 0;
110 }
111 return 0;
112 case WM_CLOSE:
113 logbox = NULL;
114 DestroyWindow (hwnd);
115 return 0;
116 }
117 return 0;
118 }
119
120 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
121 WPARAM wParam, LPARAM lParam) {
122 switch (msg) {
123 case WM_INITDIALOG:
124 return 1;
125 case WM_COMMAND:
126 switch (LOWORD(wParam)) {
127 case IDOK:
128 EndDialog(hwnd, 1);
129 return 0;
130 }
131 return 0;
132 case WM_CLOSE:
133 EndDialog(hwnd, 1);
134 return 0;
135 }
136 return 0;
137 }
138
139 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
140 WPARAM wParam, LPARAM lParam) {
141 switch (msg) {
142 case WM_INITDIALOG:
143 SetDlgItemText (hwnd, IDA_VERSION, ver);
144 return 1;
145 case WM_COMMAND:
146 switch (LOWORD(wParam)) {
147 case IDOK:
148 abtbox = NULL;
149 DestroyWindow (hwnd);
150 return 0;
151 case IDA_LICENCE:
152 EnableWindow(hwnd, 0);
153 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
154 NULL, LicenceProc);
155 EnableWindow(hwnd, 1);
156 SetActiveWindow(hwnd);
157 return 0;
158 }
159 return 0;
160 case WM_CLOSE:
161 abtbox = NULL;
162 DestroyWindow (hwnd);
163 return 0;
164 }
165 return 0;
166 }
167
168 /*
169 * Null dialog procedure.
170 */
171 static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
172 WPARAM wParam, LPARAM lParam) {
173 return 0;
174 }
175
176 static char savedsession[2048];
177
178 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
179
180 sessionpanelstart,
181 IDC_TITLE_SESSION,
182 IDC_BOX_SESSION1, IDC_BOXT_SESSION1,
183 IDC_BOX_SESSION2, IDC_BOXT_SESSION2,
184 IDC_BOX_SESSION3,
185 IDC_HOSTSTATIC,
186 IDC_HOST,
187 IDC_PORTSTATIC,
188 IDC_PORT,
189 IDC_PROTSTATIC,
190 IDC_PROTRAW,
191 IDC_PROTTELNET,
192 IDC_PROTRLOGIN,
193 IDC_PROTSSH,
194 IDC_SESSSTATIC,
195 IDC_SESSEDIT,
196 IDC_SESSLIST,
197 IDC_SESSLOAD,
198 IDC_SESSSAVE,
199 IDC_SESSDEL,
200 IDC_CLOSEEXIT,
201 sessionpanelend,
202
203 keyboardpanelstart,
204 IDC_TITLE_KEYBOARD,
205 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1,
206 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2,
207 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3,
208 IDC_DELSTATIC,
209 IDC_DEL008,
210 IDC_DEL127,
211 IDC_HOMESTATIC,
212 IDC_HOMETILDE,
213 IDC_HOMERXVT,
214 IDC_FUNCSTATIC,
215 IDC_FUNCTILDE,
216 IDC_FUNCLINUX,
217 IDC_FUNCXTERM,
218 IDC_FUNCVT400,
219 IDC_KPSTATIC,
220 IDC_KPNORMAL,
221 IDC_KPAPPLIC,
222 IDC_KPNH,
223 IDC_NOAPPLICK,
224 IDC_NOAPPLICC,
225 IDC_CURSTATIC,
226 IDC_CURNORMAL,
227 IDC_CURAPPLIC,
228 IDC_COMPOSEKEY,
229 keyboardpanelend,
230
231 terminalpanelstart,
232 IDC_TITLE_TERMINAL,
233 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
234 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2,
235 IDC_WRAPMODE,
236 IDC_DECOM,
237 IDC_LFHASCR,
238 IDC_BEEP,
239 IDC_BCE,
240 IDC_BLINKTEXT,
241 IDC_LDISCTERM,
242 IDC_LSTATSTATIC,
243 IDC_LSTATOFF,
244 IDC_LSTATASCII,
245 IDC_LSTATRAW,
246 IDC_LGFSTATIC,
247 IDC_LGFEDIT,
248 IDC_LGFBUTTON,
249 terminalpanelend,
250
251 windowpanelstart,
252 IDC_TITLE_WINDOW,
253 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
254 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
255 IDC_BOX_WINDOW3,
256 IDC_ROWSSTATIC,
257 IDC_ROWSEDIT,
258 IDC_COLSSTATIC,
259 IDC_COLSEDIT,
260 IDC_LOCKSIZE,
261 IDC_SCROLLBAR,
262 IDC_CLOSEWARN,
263 IDC_SAVESTATIC,
264 IDC_SAVEEDIT,
265 IDC_ALTF4,
266 IDC_ALTSPACE,
267 IDC_ALTONLY,
268 IDC_SCROLLKEY,
269 IDC_SCROLLDISP,
270 IDC_ALWAYSONTOP,
271 windowpanelend,
272
273 appearancepanelstart,
274 IDC_TITLE_APPEARANCE,
275 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1,
276 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2,
277 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3,
278 IDC_BOX_APPEARANCE4, IDC_BOXT_APPEARANCE4,
279 IDC_CURSORSTATIC,
280 IDC_CURBLOCK,
281 IDC_CURUNDER,
282 IDC_CURVERT,
283 IDC_BLINKCUR,
284 IDC_FONTSTATIC,
285 IDC_CHOOSEFONT,
286 IDC_WINTITLE,
287 IDC_WINEDIT,
288 IDC_WINNAME,
289 IDC_HIDEMOUSE,
290 appearancepanelend,
291
292 connectionpanelstart,
293 IDC_TITLE_CONNECTION,
294 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
295 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
296 IDC_TTSTATIC,
297 IDC_TTEDIT,
298 IDC_LOGSTATIC,
299 IDC_LOGEDIT,
300 IDC_PINGSTATIC,
301 IDC_PINGEDIT,
302 connectionpanelend,
303
304 telnetpanelstart,
305 IDC_TITLE_TELNET,
306 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
307 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
308 IDC_TSSTATIC,
309 IDC_TSEDIT,
310 IDC_ENVSTATIC,
311 IDC_VARSTATIC,
312 IDC_VAREDIT,
313 IDC_VALSTATIC,
314 IDC_VALEDIT,
315 IDC_ENVLIST,
316 IDC_ENVADD,
317 IDC_ENVREMOVE,
318 IDC_EMSTATIC,
319 IDC_EMBSD,
320 IDC_EMRFC,
321 telnetpanelend,
322
323 rloginpanelstart,
324 IDC_TITLE_RLOGIN,
325 IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1,
326 IDC_BOX_RLOGIN2, IDC_BOXT_RLOGIN2,
327 IDC_R_TSSTATIC,
328 IDC_R_TSEDIT,
329 IDC_RLLUSERSTATIC,
330 IDC_RLLUSEREDIT,
331 rloginpanelend,
332
333 sshpanelstart,
334 IDC_TITLE_SSH,
335 IDC_BOX_SSH1, IDC_BOXT_SSH1,
336 IDC_BOX_SSH2, IDC_BOXT_SSH2,
337 IDC_BOX_SSH3, IDC_BOXT_SSH3,
338 IDC_NOPTY,
339 IDC_CIPHERSTATIC,
340 IDC_CIPHER3DES,
341 IDC_CIPHERBLOWF,
342 IDC_CIPHERDES,
343 IDC_BUGGYMAC,
344 IDC_AUTHTIS,
345 IDC_PKSTATIC,
346 IDC_PKEDIT,
347 IDC_PKBUTTON,
348 IDC_SSHPROTSTATIC,
349 IDC_SSHPROT1,
350 IDC_SSHPROT2,
351 IDC_AGENTFWD,
352 IDC_CMDSTATIC,
353 IDC_CMDEDIT,
354 IDC_COMPRESS,
355 sshpanelend,
356
357 selectionpanelstart,
358 IDC_TITLE_SELECTION,
359 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
360 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
361 IDC_MBSTATIC,
362 IDC_MBWINDOWS,
363 IDC_MBXTERM,
364 IDC_CCSTATIC,
365 IDC_CCLIST,
366 IDC_CCSET,
367 IDC_CCSTATIC2,
368 IDC_CCEDIT,
369 selectionpanelend,
370
371 colourspanelstart,
372 IDC_TITLE_COLOURS,
373 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
374 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
375 IDC_BOLDCOLOUR,
376 IDC_PALETTE,
377 IDC_COLOURSTATIC,
378 IDC_COLOURLIST,
379 IDC_RSTATIC,
380 IDC_GSTATIC,
381 IDC_BSTATIC,
382 IDC_RVALUE,
383 IDC_GVALUE,
384 IDC_BVALUE,
385 IDC_CHANGE,
386 colourspanelend,
387
388 translationpanelstart,
389 IDC_TITLE_TRANSLATION,
390 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
391 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
392 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
393 IDC_XLATSTATIC,
394 IDC_NOXLAT,
395 IDC_KOI8WIN1251,
396 IDC_88592WIN1250,
397 IDC_88592CP852,
398 IDC_CAPSLOCKCYR,
399 IDC_VTSTATIC,
400 IDC_VTXWINDOWS,
401 IDC_VTOEMANSI,
402 IDC_VTOEMONLY,
403 IDC_VTPOORMAN,
404 translationpanelend,
405
406 tunnelspanelstart,
407 IDC_TITLE_TUNNELS,
408 IDC_BOX_TUNNELS, IDC_BOXT_TUNNELS,
409 IDC_X11_FORWARD,
410 IDC_X11_DISPSTATIC,
411 IDC_X11_DISPLAY,
412 tunnelspanelend,
413
414 controlendvalue
415 };
416
417 static const char *const colours[] = {
418 "Default Foreground", "Default Bold Foreground",
419 "Default Background", "Default Bold Background",
420 "Cursor Text", "Cursor Colour",
421 "ANSI Black", "ANSI Black Bold",
422 "ANSI Red", "ANSI Red Bold",
423 "ANSI Green", "ANSI Green Bold",
424 "ANSI Yellow", "ANSI Yellow Bold",
425 "ANSI Blue", "ANSI Blue Bold",
426 "ANSI Magenta", "ANSI Magenta Bold",
427 "ANSI Cyan", "ANSI Cyan Bold",
428 "ANSI White", "ANSI White Bold"
429 };
430 static const int permcolour[] = {
431 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
432 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
433 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
434 };
435
436 static void fmtfont (char *buf) {
437 sprintf (buf, "Font: %s, ", cfg.font);
438 if (cfg.fontisbold)
439 strcat(buf, "bold, ");
440 if (cfg.fontheight == 0)
441 strcat (buf, "default height");
442 else
443 sprintf (buf+strlen(buf), "%d-%s",
444 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
445 (cfg.fontheight < 0 ? "pixel" : "point"));
446 }
447
448 static void init_dlg_ctrls(HWND hwnd) {
449 int i;
450 char fontstatic[256];
451
452 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
453 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
454 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
455 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
456 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
457 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
458 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
459 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
460
461 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
462 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
463 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
464 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
465 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
466 cfg.funky_type == 0 ? IDC_FUNCTILDE :
467 cfg.funky_type == 1 ? IDC_FUNCLINUX :
468 cfg.funky_type == 2 ? IDC_FUNCXTERM :
469 cfg.funky_type == 3 ? IDC_FUNCVT400 :
470 IDC_FUNCTILDE );
471 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
472 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
473 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
474 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
475 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
476 cfg.nethack_keypad ? IDC_KPNH :
477 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
478 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
479 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
480 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
481 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
482 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
483 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
484 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
485 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
486
487 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
488 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
489 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
490 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
491 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
492 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
493 fmtfont (fontstatic);
494 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
495 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
496 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
497 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
498
499 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
500 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
501 CheckDlgButton (hwnd, IDC_HIDEMOUSE, cfg.hide_mouseptr);
502 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
503 cfg.cursor_type==0 ? IDC_CURBLOCK :
504 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
505 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
506 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
507 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
508 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
509 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
510
511 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
512 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
513 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
514 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
515 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
516 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
517 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
518 cfg.logtype == 0 ? IDC_LSTATOFF :
519 cfg.logtype == 1 ? IDC_LSTATASCII :
520 IDC_LSTATRAW);
521 {
522 char *p = cfg.environmt;
523 while (*p) {
524 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
525 (LPARAM) p);
526 p += strlen(p)+1;
527 }
528 }
529 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
530 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
531
532 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
533 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
534 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
535 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
536 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
537 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
538 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
539 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
540 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
541 IDC_CIPHER3DES);
542 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
543 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
544 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
545 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
546 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
547
548 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
549 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
550 {
551 static int tabs[4] = {25, 61, 96, 128};
552 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
553 (LPARAM) tabs);
554 }
555 for (i=0; i<256; i++) {
556 char str[100];
557 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
558 (i>=0x21 && i != 0x7F) ? i : ' ',
559 cfg.wordness[i]);
560 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
561 (LPARAM) str);
562 }
563
564 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
565 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
566 {
567 int i, n;
568 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
569 for (i=n; i-- >0 ;)
570 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
571 LB_DELETESTRING, i, 0);
572 for (i=0; i<22; i++)
573 if (cfg.bold_colour || permcolour[i])
574 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
575 (LPARAM) colours[i]);
576 }
577 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
578 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
579 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
580 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
581
582 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
583 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
584 cfg.xlat_88592cp852 ? IDC_88592CP852 :
585 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
586 IDC_NOXLAT);
587 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
588 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
589 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
590 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
591 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
592 IDC_VTPOORMAN);
593
594 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
595 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
596 }
597
598 static void hide(HWND hwnd, int hide, int minid, int maxid) {
599 int i;
600 for (i = minid; i < maxid; i++) {
601 HWND ctl = GetDlgItem(hwnd, i);
602 if (ctl) {
603 if (!hide)
604 EnableWindow(ctl, 1);
605 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
606 if (hide)
607 EnableWindow(ctl, 0);
608 }
609 }
610 }
611
612 struct treeview_faff {
613 HWND treeview;
614 HTREEITEM lastat[4];
615 };
616
617 static HTREEITEM treeview_insert(struct treeview_faff *faff,
618 int level, char *text) {
619 TVINSERTSTRUCT ins;
620 int i;
621 HTREEITEM newitem;
622 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
623 ins.hInsertAfter = faff->lastat[level];
624 #if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
625 #define INSITEM DUMMYUNIONNAME.item
626 #else
627 #define INSITEM item
628 #endif
629 ins.INSITEM.mask = TVIF_TEXT;
630 ins.INSITEM.pszText = text;
631 newitem = TreeView_InsertItem(faff->treeview, &ins);
632 if (level > 0)
633 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
634 faff->lastat[level] = newitem;
635 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
636 return newitem;
637 }
638
639 /*
640 * This _huge_ function is the configuration box.
641 */
642 static int GenericMainDlgProc (HWND hwnd, UINT msg,
643 WPARAM wParam, LPARAM lParam,
644 int dlgtype) {
645 HWND hw, treeview;
646 struct treeview_faff tvfaff;
647 HTREEITEM hsession;
648 OPENFILENAME of;
649 char filename[sizeof(cfg.keyfile)];
650 CHOOSEFONT cf;
651 LOGFONT lf;
652 char fontstatic[256];
653 char portname[32];
654 struct servent * service;
655 int i;
656
657 switch (msg) {
658 case WM_INITDIALOG:
659 readytogo = 0;
660 SetWindowLong(hwnd, GWL_USERDATA, 0);
661 /*
662 * Centre the window.
663 */
664 { /* centre the window */
665 RECT rs, rd;
666
667 hw = GetDesktopWindow();
668 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
669 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
670 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
671 rd.right-rd.left, rd.bottom-rd.top, TRUE);
672 }
673
674 /*
675 * Create the tree view.
676 */
677 {
678 RECT r;
679 WPARAM font;
680 HWND tvstatic;
681
682 r.left = 3; r.right = r.left + 75;
683 r.top = 3; r.bottom = r.top + 10;
684 MapDialogRect(hwnd, &r);
685 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
686 WS_CHILD | WS_VISIBLE,
687 r.left, r.top,
688 r.right-r.left, r.bottom-r.top,
689 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
690 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
691 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
692
693 r.left = 3; r.right = r.left + 75;
694 r.top = 13; r.bottom = r.top + 206;
695 MapDialogRect(hwnd, &r);
696 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
697 WS_CHILD | WS_VISIBLE |
698 WS_TABSTOP | TVS_HASLINES |
699 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
700 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
701 r.left, r.top,
702 r.right-r.left, r.bottom-r.top,
703 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
704 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
705 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
706 tvfaff.treeview = treeview;
707 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
708 }
709
710 /*
711 * Create the various panelfuls of controls.
712 */
713
714 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
715 {
716 struct ctlpos cp;
717 ctlposinit(&cp, hwnd, 80, 3, 13);
718 bartitle(&cp, "Basic options for your PuTTY session",
719 IDC_TITLE_SESSION);
720 if (dlgtype == 0) {
721 beginbox(&cp, "Specify your connection by host name",
722 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
723 multiedit(&cp,
724 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
725 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
726 if (backends[3].backend == NULL) {
727 /* this is PuTTYtel, so only two protocols available */
728 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
729 "&Raw", IDC_PROTRAW,
730 "&Telnet", IDC_PROTTELNET,
731 "R&login", IDC_PROTRLOGIN, NULL);
732 } else {
733 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
734 "&Raw", IDC_PROTRAW,
735 "&Telnet", IDC_PROTTELNET,
736 "R&login", IDC_PROTRLOGIN,
737 #ifdef FWHACK
738 "SS&H/hack",
739 #else
740 "SS&H",
741 #endif
742 IDC_PROTSSH, NULL);
743 }
744 endbox(&cp);
745 beginbox(&cp, "Load, save or delete a stored session",
746 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
747 sesssaver(&cp, "Sav&ed Sessions",
748 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
749 "&Load", IDC_SESSLOAD,
750 "&Save", IDC_SESSSAVE,
751 "&Delete", IDC_SESSDEL, NULL);
752 endbox(&cp);
753 }
754 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
755 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
756 endbox(&cp);
757
758 hsession = treeview_insert(&tvfaff, 0, "Session");
759 }
760
761 /* The Terminal panel. Accelerators used: [acgo] &dflbenuw */
762 {
763 struct ctlpos cp;
764 ctlposinit(&cp, hwnd, 80, 3, 13);
765 bartitle(&cp, "Options controlling the terminal emulation",
766 IDC_TITLE_TERMINAL);
767 beginbox(&cp, "Set various terminal options",
768 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
769 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
770 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
771 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
772 checkbox(&cp, "&Beep enabled", IDC_BEEP);
773 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
774 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
775 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
776 endbox(&cp);
777
778 beginbox(&cp, "Control session logging",
779 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2);
780 radiobig(&cp,
781 "Session logging:", IDC_LSTATSTATIC,
782 "Logging turned &off completely", IDC_LSTATOFF,
783 "Log printable output only", IDC_LSTATASCII,
784 "Log all session output", IDC_LSTATRAW, NULL);
785 editbutton(&cp, "Log &file name:",
786 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
787 IDC_LGFBUTTON);
788 endbox(&cp);
789
790 treeview_insert(&tvfaff, 0, "Terminal");
791 }
792
793 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
794 {
795 struct ctlpos cp;
796 ctlposinit(&cp, hwnd, 80, 3, 13);
797 bartitle(&cp, "Options controlling the effects of keys",
798 IDC_TITLE_KEYBOARD);
799 beginbox(&cp, "Change the sequences sent by:",
800 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
801 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
802 "Control-&H", IDC_DEL008,
803 "Control-&? (127)", IDC_DEL127, NULL);
804 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
805 "&Standard", IDC_HOMETILDE,
806 "&rxvt", IDC_HOMERXVT, NULL);
807 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
808 "ESC[n&~", IDC_FUNCTILDE,
809 "&Linux", IDC_FUNCLINUX,
810 "&Xterm R6", IDC_FUNCXTERM,
811 "&VT400", IDC_FUNCVT400, NULL);
812 endbox(&cp);
813 beginbox(&cp, "Application keypad settings:",
814 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
815 checkbox(&cp,
816 "Application c&ursor keys totally disabled",
817 IDC_NOAPPLICC);
818 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
819 "&Normal", IDC_CURNORMAL,
820 "A&pplication", IDC_CURAPPLIC, NULL);
821 checkbox(&cp,
822 "Application ke&ypad keys totally disabled",
823 IDC_NOAPPLICK);
824 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
825 "Nor&mal", IDC_KPNORMAL,
826 "Appl&ication", IDC_KPAPPLIC,
827 "N&etHack", IDC_KPNH, NULL);
828 endbox(&cp);
829 beginbox(&cp, "Enable extra keyboard features:",
830 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
831 checkbox(&cp, "Application and AltGr ac&t as Compose key",
832 IDC_COMPOSEKEY);
833 endbox(&cp);
834
835 treeview_insert(&tvfaff, 1, "Keyboard");
836 }
837
838 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
839 {
840 struct ctlpos cp;
841 ctlposinit(&cp, hwnd, 80, 3, 13);
842 bartitle(&cp, "Options controlling PuTTY's window",
843 IDC_TITLE_WINDOW);
844 beginbox(&cp, "Set the size of the window",
845 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
846 multiedit(&cp,
847 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
848 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
849 NULL);
850 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
851 endbox(&cp);
852 beginbox(&cp, "Control the scrollback in the window",
853 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
854 staticedit(&cp, "Lines of &scrollback",
855 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
856 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
857 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
858 checkbox(&cp, "Reset scrollback on dis&play activity",
859 IDC_SCROLLDISP);
860 endbox(&cp);
861 beginbox(&cp, NULL, IDC_BOX_WINDOW3, 0);
862 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
863 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
864 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
865 checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
866 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
867 endbox(&cp);
868
869 treeview_insert(&tvfaff, 0, "Window");
870 }
871
872 /* The Appearance panel. Accelerators used: [acgo] rmkhtibluv */
873 {
874 struct ctlpos cp;
875 ctlposinit(&cp, hwnd, 80, 3, 13);
876 bartitle(&cp, "Options controlling PuTTY's appearance",
877 IDC_TITLE_APPEARANCE);
878 beginbox(&cp, "Adjust the use of the cursor",
879 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1);
880 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
881 "B&lock", IDC_CURBLOCK,
882 "&Underline", IDC_CURUNDER,
883 "&Vertical line", IDC_CURVERT,
884 NULL);
885 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
886 endbox(&cp);
887 beginbox(&cp, "Set the font used in the terminal window",
888 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2);
889 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
890 endbox(&cp);
891 beginbox(&cp, "Adjust the use of the window title",
892 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3);
893 multiedit(&cp,
894 "Window &title:", IDC_WINTITLE,
895 IDC_WINEDIT, 100, NULL);
896 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
897 endbox(&cp);
898 beginbox(&cp, "Adjust the use of the mouse pointer",
899 IDC_BOX_APPEARANCE4, IDC_BOXT_APPEARANCE4);
900 checkbox(&cp, "Hide mouse &pointer when typing in window",
901 IDC_HIDEMOUSE);
902 endbox(&cp);
903
904 treeview_insert(&tvfaff, 1, "Appearance");
905 }
906
907 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
908 {
909 struct ctlpos cp;
910 ctlposinit(&cp, hwnd, 80, 3, 13);
911 bartitle(&cp, "Options controlling character set translation",
912 IDC_TITLE_TRANSLATION);
913 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
914 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
915 radiobig(&cp,
916 "Handling of line drawing characters:", IDC_VTSTATIC,
917 "Font has &XWindows encoding", IDC_VTXWINDOWS,
918 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
919 "Use font in O&EM mode only", IDC_VTOEMONLY,
920 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
921 IDC_VTPOORMAN, NULL);
922 endbox(&cp);
923 beginbox(&cp, "Enable character set translation on received data",
924 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
925 radiobig(&cp,
926 "Character set translation:", IDC_XLATSTATIC,
927 "&None", IDC_NOXLAT,
928 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
929 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
930 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
931 endbox(&cp);
932 beginbox(&cp, "Enable character set translation on input data",
933 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
934 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
935 IDC_CAPSLOCKCYR);
936 endbox(&cp);
937
938 treeview_insert(&tvfaff, 1, "Translation");
939 }
940
941 /* The Selection panel. Accelerators used: [acgo] wxst */
942 {
943 struct ctlpos cp;
944 ctlposinit(&cp, hwnd, 80, 3, 13);
945 bartitle(&cp, "Options controlling copy and paste",
946 IDC_TITLE_SELECTION);
947 beginbox(&cp, "Control which mouse button does which thing",
948 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
949 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
950 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
951 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
952 NULL);
953 endbox(&cp);
954 beginbox(&cp, "Control the select-one-word-at-a-time mode",
955 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
956 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
957 "&Set", IDC_CCSET, IDC_CCEDIT,
958 "&to class", IDC_CCSTATIC2);
959 endbox(&cp);
960
961 treeview_insert(&tvfaff, 1, "Selection");
962 }
963
964 /* The Colours panel. Accelerators used: [acgo] blum */
965 {
966 struct ctlpos cp;
967 ctlposinit(&cp, hwnd, 80, 3, 13);
968 bartitle(&cp, "Options controlling use of colours",
969 IDC_TITLE_COLOURS);
970 beginbox(&cp, "General options for colour usage",
971 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
972 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
973 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
974 endbox(&cp);
975 beginbox(&cp, "Adjust the precise colours PuTTY displays",
976 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
977 colouredit(&cp, "Select a colo&ur and then click to modify it:",
978 IDC_COLOURSTATIC, IDC_COLOURLIST,
979 "&Modify...", IDC_CHANGE,
980 "Red:", IDC_RSTATIC, IDC_RVALUE,
981 "Green:", IDC_GSTATIC, IDC_GVALUE,
982 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
983 endbox(&cp);
984
985 treeview_insert(&tvfaff, 1, "Colours");
986 }
987
988 /* The Connection panel. Accelerators used: [acgo] tuk */
989 {
990 struct ctlpos cp;
991 ctlposinit(&cp, hwnd, 80, 3, 13);
992 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
993 if (dlgtype == 0) {
994 beginbox(&cp, "Data to send to the server",
995 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
996 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
997 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
998 endbox(&cp);
999 }
1000 beginbox(&cp, "Sending of null packets to keep session active",
1001 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
1002 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
1003 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
1004 endbox(&cp);
1005
1006 treeview_insert(&tvfaff, 0, "Connection");
1007 }
1008
1009 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
1010 {
1011 struct ctlpos cp;
1012 ctlposinit(&cp, hwnd, 80, 3, 13);
1013 if (dlgtype == 0) {
1014 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
1015 beginbox(&cp, "Data to send to the server",
1016 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
1017 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
1018 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1019 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
1020 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
1021 IDC_ENVLIST,
1022 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1023 endbox(&cp);
1024 beginbox(&cp, "Telnet protocol adjustments",
1025 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
1026 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
1027 "&BSD (commonplace)", IDC_EMBSD,
1028 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1029 endbox(&cp);
1030
1031 treeview_insert(&tvfaff, 1, "Telnet");
1032 }
1033 }
1034
1035
1036 /* The Rlogin Panel */
1037 {
1038 struct ctlpos cp;
1039 ctlposinit(&cp, hwnd, 80, 3, 13);
1040 if (dlgtype == 0) {
1041 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1042 beginbox(&cp, "Data to send to the server",
1043 IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1);
1044 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1045 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1046 endbox(&cp);
1047
1048 treeview_insert(&tvfaff, 1, "Rlogin");
1049 }
1050 }
1051
1052 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
1053 if (backends[3].backend != NULL) {
1054 struct ctlpos cp;
1055 ctlposinit(&cp, hwnd, 80, 3, 13);
1056 if (dlgtype == 0) {
1057 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1058 beginbox(&cp, "Data to send to the server",
1059 IDC_BOX_SSH1, IDC_BOXT_SSH1);
1060 multiedit(&cp,
1061 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1062 NULL);
1063 endbox(&cp);
1064 beginbox(&cp, "Authentication options",
1065 IDC_BOX_SSH2, IDC_BOXT_SSH2);
1066 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1067 IDC_AUTHTIS);
1068 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
1069 editbutton(&cp, "Private &key file for authentication:",
1070 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1071 endbox(&cp);
1072 beginbox(&cp, "Protocol options",
1073 IDC_BOX_SSH3, IDC_BOXT_SSH3);
1074 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
1075 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
1076 radioline(&cp, "Preferred SSH protocol version:",
1077 IDC_SSHPROTSTATIC, 2,
1078 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1079 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
1080 "&3DES", IDC_CIPHER3DES,
1081 "&Blowfish", IDC_CIPHERBLOWF,
1082 "&DES", IDC_CIPHERDES, NULL);
1083 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1084 IDC_BUGGYMAC);
1085 endbox(&cp);
1086
1087 treeview_insert(&tvfaff, 1, "SSH");
1088 }
1089 }
1090 /* The Tunnels panel. Accelerators used: [acgo] ex */
1091 {
1092 struct ctlpos cp;
1093 ctlposinit(&cp, hwnd, 80, 3, 13);
1094 if (dlgtype == 0) {
1095 bartitle(&cp, "Options controlling SSH tunnelling",
1096 IDC_TITLE_TUNNELS);
1097 beginbox(&cp, "X11 forwarding options",
1098 IDC_BOX_TUNNELS, IDC_BOXT_TUNNELS);
1099 checkbox(&cp, "&Enable X11 forwarding",
1100 IDC_X11_FORWARD);
1101 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1102 IDC_X11_DISPLAY, 50, NULL);
1103 endbox(&cp);
1104
1105 treeview_insert(&tvfaff, 2, "Tunnels");
1106 }
1107 }
1108
1109 init_dlg_ctrls(hwnd);
1110 for (i = 0; i < nsessions; i++)
1111 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1112 0, (LPARAM) (sessions[i]));
1113
1114 /*
1115 * Hide all the controls to start with.
1116 */
1117 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1118
1119 /*
1120 * Put the treeview selection on to the Session panel. This
1121 * should also cause unhiding of the relevant controls.
1122 */
1123 TreeView_SelectItem(treeview, hsession);
1124
1125 /*
1126 * Set focus into the first available control.
1127 */
1128 {
1129 HWND ctl;
1130 ctl = GetDlgItem(hwnd, IDC_HOST);
1131 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1132 SetFocus(ctl);
1133 }
1134
1135 SetWindowLong(hwnd, GWL_USERDATA, 1);
1136 return 0;
1137 case WM_LBUTTONUP:
1138 /*
1139 * Button release should trigger WM_OK if there was a
1140 * previous double click on the session list.
1141 */
1142 ReleaseCapture();
1143 if (readytogo)
1144 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1145 break;
1146 case WM_NOTIFY:
1147 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1148 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1149 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1150 TVITEM item;
1151 char buffer[64];
1152 item.hItem = i;
1153 item.pszText = buffer;
1154 item.cchTextMax = sizeof(buffer);
1155 item.mask = TVIF_TEXT;
1156 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
1157 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1158 if (!strcmp(buffer, "Session"))
1159 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
1160 if (!strcmp(buffer, "Keyboard"))
1161 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1162 if (!strcmp(buffer, "Terminal"))
1163 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1164 if (!strcmp(buffer, "Window"))
1165 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1166 if (!strcmp(buffer, "Appearance"))
1167 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
1168 if (!strcmp(buffer, "Tunnels"))
1169 hide(hwnd, FALSE, tunnelspanelstart, tunnelspanelend);
1170 if (!strcmp(buffer, "Connection"))
1171 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1172 if (!strcmp(buffer, "Telnet"))
1173 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1174 if (!strcmp(buffer, "Rlogin"))
1175 hide(hwnd, FALSE, rloginpanelstart, rloginpanelend);
1176 if (!strcmp(buffer, "SSH"))
1177 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1178 if (!strcmp(buffer, "Selection"))
1179 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1180 if (!strcmp(buffer, "Colours"))
1181 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1182 if (!strcmp(buffer, "Translation"))
1183 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1184
1185 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1186 return 0;
1187 }
1188 break;
1189 case WM_COMMAND:
1190 /*
1191 * Only process WM_COMMAND once the dialog is fully formed.
1192 */
1193 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1194 case IDOK:
1195 if (*cfg.host)
1196 EndDialog (hwnd, 1);
1197 else
1198 MessageBeep (0);
1199 return 0;
1200 case IDCANCEL:
1201 EndDialog (hwnd, 0);
1202 return 0;
1203 case IDC_PROTTELNET:
1204 case IDC_PROTRLOGIN:
1205 case IDC_PROTSSH:
1206 case IDC_PROTRAW:
1207 if (HIWORD(wParam) == BN_CLICKED ||
1208 HIWORD(wParam) == BN_DOUBLECLICKED) {
1209 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1210 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
1211 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1212 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1213 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1214 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1215 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1216 cfg.port = i ? 22 : j ? 23 : 513;
1217 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
1218 }
1219 }
1220 break;
1221 case IDC_HOST:
1222 if (HIWORD(wParam) == EN_CHANGE)
1223 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
1224 sizeof(cfg.host)-1);
1225 break;
1226 case IDC_PORT:
1227 if (HIWORD(wParam) == EN_CHANGE) {
1228 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1229 if (isdigit(portname[0]))
1230 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1231 else {
1232 service = getservbyname(portname, NULL);
1233 if (service) cfg.port = ntohs(service->s_port);
1234 else cfg.port = 0;
1235 }
1236 }
1237 break;
1238 case IDC_SESSEDIT:
1239 if (HIWORD(wParam) == EN_CHANGE) {
1240 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1241 (WPARAM) -1, 0);
1242 GetDlgItemText (hwnd, IDC_SESSEDIT,
1243 savedsession, sizeof(savedsession)-1);
1244 savedsession[sizeof(savedsession)-1] = '\0';
1245 }
1246 break;
1247 case IDC_SESSSAVE:
1248 if (HIWORD(wParam) == BN_CLICKED ||
1249 HIWORD(wParam) == BN_DOUBLECLICKED) {
1250 /*
1251 * Save a session
1252 */
1253 char str[2048];
1254 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
1255 if (!*str) {
1256 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1257 LB_GETCURSEL, 0, 0);
1258 if (n == LB_ERR) {
1259 MessageBeep(0);
1260 break;
1261 }
1262 strcpy (str, sessions[n]);
1263 }
1264 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1265 get_sesslist (FALSE);
1266 get_sesslist (TRUE);
1267 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1268 0, 0);
1269 for (i = 0; i < nsessions; i++)
1270 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1271 0, (LPARAM) (sessions[i]));
1272 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1273 (WPARAM) -1, 0);
1274 }
1275 break;
1276 case IDC_SESSLIST:
1277 case IDC_SESSLOAD:
1278 if (LOWORD(wParam) == IDC_SESSLOAD &&
1279 HIWORD(wParam) != BN_CLICKED &&
1280 HIWORD(wParam) != BN_DOUBLECLICKED)
1281 break;
1282 if (LOWORD(wParam) == IDC_SESSLIST &&
1283 HIWORD(wParam) != LBN_DBLCLK)
1284 break;
1285 {
1286 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1287 LB_GETCURSEL, 0, 0);
1288 int isdef;
1289 if (n == LB_ERR) {
1290 MessageBeep(0);
1291 break;
1292 }
1293 isdef = !strcmp(sessions[n], "Default Settings");
1294 load_settings (sessions[n], !isdef, &cfg);
1295 init_dlg_ctrls(hwnd);
1296 if (!isdef)
1297 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1298 else
1299 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
1300 }
1301 if (LOWORD(wParam) == IDC_SESSLIST) {
1302 /*
1303 * A double-click on a saved session should
1304 * actually start the session, not just load it.
1305 * Unless it's Default Settings or some other
1306 * host-less set of saved settings.
1307 */
1308 if (*cfg.host) {
1309 readytogo = TRUE;
1310 SetCapture(hwnd);
1311 }
1312 }
1313 break;
1314 case IDC_SESSDEL:
1315 if (HIWORD(wParam) == BN_CLICKED ||
1316 HIWORD(wParam) == BN_DOUBLECLICKED) {
1317 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
1318 LB_GETCURSEL, 0, 0);
1319 if (n == LB_ERR || n == 0) {
1320 MessageBeep(0);
1321 break;
1322 }
1323 del_settings(sessions[n]);
1324 get_sesslist (FALSE);
1325 get_sesslist (TRUE);
1326 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1327 0, 0);
1328 for (i = 0; i < nsessions; i++)
1329 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1330 0, (LPARAM) (sessions[i]));
1331 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
1332 (WPARAM) -1, 0);
1333 }
1334 case IDC_PINGEDIT:
1335 if (HIWORD(wParam) == EN_CHANGE)
1336 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
1337 break;
1338 case IDC_DEL008:
1339 case IDC_DEL127:
1340 if (HIWORD(wParam) == BN_CLICKED ||
1341 HIWORD(wParam) == BN_DOUBLECLICKED)
1342 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
1343 break;
1344 case IDC_HOMETILDE:
1345 case IDC_HOMERXVT:
1346 if (HIWORD(wParam) == BN_CLICKED ||
1347 HIWORD(wParam) == BN_DOUBLECLICKED)
1348 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
1349 break;
1350 case IDC_FUNCXTERM:
1351 if (HIWORD(wParam) == BN_CLICKED ||
1352 HIWORD(wParam) == BN_DOUBLECLICKED)
1353 cfg.funky_type = 2;
1354 break;
1355 case IDC_FUNCVT400:
1356 if (HIWORD(wParam) == BN_CLICKED ||
1357 HIWORD(wParam) == BN_DOUBLECLICKED)
1358 cfg.funky_type = 3;
1359 break;
1360 case IDC_FUNCTILDE:
1361 case IDC_FUNCLINUX:
1362 if (HIWORD(wParam) == BN_CLICKED ||
1363 HIWORD(wParam) == BN_DOUBLECLICKED)
1364 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
1365 break;
1366 case IDC_KPNORMAL:
1367 case IDC_KPAPPLIC:
1368 if (HIWORD(wParam) == BN_CLICKED ||
1369 HIWORD(wParam) == BN_DOUBLECLICKED) {
1370 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
1371 cfg.nethack_keypad = FALSE;
1372 }
1373 break;
1374 case IDC_KPNH:
1375 if (HIWORD(wParam) == BN_CLICKED ||
1376 HIWORD(wParam) == BN_DOUBLECLICKED) {
1377 cfg.app_keypad = FALSE;
1378 cfg.nethack_keypad = TRUE;
1379 }
1380 break;
1381 case IDC_CURNORMAL:
1382 case IDC_CURAPPLIC:
1383 if (HIWORD(wParam) == BN_CLICKED ||
1384 HIWORD(wParam) == BN_DOUBLECLICKED)
1385 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
1386 break;
1387 case IDC_NOAPPLICC:
1388 if (HIWORD(wParam) == BN_CLICKED ||
1389 HIWORD(wParam) == BN_DOUBLECLICKED)
1390 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1391 break;
1392 case IDC_NOAPPLICK:
1393 if (HIWORD(wParam) == BN_CLICKED ||
1394 HIWORD(wParam) == BN_DOUBLECLICKED)
1395 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
1396 break;
1397 case IDC_ALTF4:
1398 if (HIWORD(wParam) == BN_CLICKED ||
1399 HIWORD(wParam) == BN_DOUBLECLICKED)
1400 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
1401 break;
1402 case IDC_ALTSPACE:
1403 if (HIWORD(wParam) == BN_CLICKED ||
1404 HIWORD(wParam) == BN_DOUBLECLICKED)
1405 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
1406 break;
1407 case IDC_ALTONLY:
1408 if (HIWORD(wParam) == BN_CLICKED ||
1409 HIWORD(wParam) == BN_DOUBLECLICKED)
1410 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1411 break;
1412 case IDC_LDISCTERM:
1413 if (HIWORD(wParam) == BN_CLICKED ||
1414 HIWORD(wParam) == BN_DOUBLECLICKED)
1415 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
1416 break;
1417 case IDC_ALWAYSONTOP:
1418 if (HIWORD(wParam) == BN_CLICKED ||
1419 HIWORD(wParam) == BN_DOUBLECLICKED)
1420 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1421 break;
1422 case IDC_SCROLLKEY:
1423 if (HIWORD(wParam) == BN_CLICKED ||
1424 HIWORD(wParam) == BN_DOUBLECLICKED)
1425 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
1426 break;
1427 case IDC_SCROLLDISP:
1428 if (HIWORD(wParam) == BN_CLICKED ||
1429 HIWORD(wParam) == BN_DOUBLECLICKED)
1430 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1431 break;
1432 case IDC_COMPOSEKEY:
1433 if (HIWORD(wParam) == BN_CLICKED ||
1434 HIWORD(wParam) == BN_DOUBLECLICKED)
1435 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1436 break;
1437 case IDC_WRAPMODE:
1438 if (HIWORD(wParam) == BN_CLICKED ||
1439 HIWORD(wParam) == BN_DOUBLECLICKED)
1440 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
1441 break;
1442 case IDC_DECOM:
1443 if (HIWORD(wParam) == BN_CLICKED ||
1444 HIWORD(wParam) == BN_DOUBLECLICKED)
1445 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
1446 break;
1447 case IDC_LFHASCR:
1448 if (HIWORD(wParam) == BN_CLICKED ||
1449 HIWORD(wParam) == BN_DOUBLECLICKED)
1450 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
1451 break;
1452 case IDC_ROWSEDIT:
1453 if (HIWORD(wParam) == EN_CHANGE)
1454 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
1455 break;
1456 case IDC_COLSEDIT:
1457 if (HIWORD(wParam) == EN_CHANGE)
1458 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
1459 break;
1460 case IDC_SAVEEDIT:
1461 if (HIWORD(wParam) == EN_CHANGE)
1462 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
1463 break;
1464 case IDC_CHOOSEFONT:
1465 lf.lfHeight = cfg.fontheight;
1466 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1467 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1468 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1469 lf.lfCharSet = cfg.fontcharset;
1470 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1471 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1472 lf.lfQuality = DEFAULT_QUALITY;
1473 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1474 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1475 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1476
1477 cf.lStructSize = sizeof(cf);
1478 cf.hwndOwner = hwnd;
1479 cf.lpLogFont = &lf;
1480 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1481 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1482
1483 if (ChooseFont (&cf)) {
1484 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1485 cfg.font[sizeof(cfg.font)-1] = '\0';
1486 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1487 cfg.fontcharset = lf.lfCharSet;
1488 cfg.fontheight = lf.lfHeight;
1489 fmtfont (fontstatic);
1490 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
1491 }
1492 break;
1493 case IDC_BEEP:
1494 if (HIWORD(wParam) == BN_CLICKED ||
1495 HIWORD(wParam) == BN_DOUBLECLICKED)
1496 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
1497 break;
1498 case IDC_BLINKTEXT:
1499 if (HIWORD(wParam) == BN_CLICKED ||
1500 HIWORD(wParam) == BN_DOUBLECLICKED)
1501 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
1502 break;
1503 case IDC_BCE:
1504 if (HIWORD(wParam) == BN_CLICKED ||
1505 HIWORD(wParam) == BN_DOUBLECLICKED)
1506 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
1507 break;
1508 case IDC_WINNAME:
1509 if (HIWORD(wParam) == BN_CLICKED ||
1510 HIWORD(wParam) == BN_DOUBLECLICKED)
1511 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
1512 break;
1513 case IDC_HIDEMOUSE:
1514 if (HIWORD(wParam) == BN_CLICKED ||
1515 HIWORD(wParam) == BN_DOUBLECLICKED)
1516 cfg.hide_mouseptr = IsDlgButtonChecked (hwnd, IDC_HIDEMOUSE);
1517 break;
1518 case IDC_CURBLOCK:
1519 if (HIWORD(wParam) == BN_CLICKED ||
1520 HIWORD(wParam) == BN_DOUBLECLICKED)
1521 cfg.cursor_type = 0;
1522 break;
1523 case IDC_CURUNDER:
1524 if (HIWORD(wParam) == BN_CLICKED ||
1525 HIWORD(wParam) == BN_DOUBLECLICKED)
1526 cfg.cursor_type = 1;
1527 break;
1528 case IDC_CURVERT:
1529 if (HIWORD(wParam) == BN_CLICKED ||
1530 HIWORD(wParam) == BN_DOUBLECLICKED)
1531 cfg.cursor_type = 2;
1532 break;
1533 case IDC_BLINKCUR:
1534 if (HIWORD(wParam) == BN_CLICKED ||
1535 HIWORD(wParam) == BN_DOUBLECLICKED)
1536 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
1537 break;
1538 case IDC_SCROLLBAR:
1539 if (HIWORD(wParam) == BN_CLICKED ||
1540 HIWORD(wParam) == BN_DOUBLECLICKED)
1541 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
1542 break;
1543 case IDC_LOCKSIZE:
1544 if (HIWORD(wParam) == BN_CLICKED ||
1545 HIWORD(wParam) == BN_DOUBLECLICKED)
1546 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
1547 break;
1548 case IDC_WINEDIT:
1549 if (HIWORD(wParam) == EN_CHANGE)
1550 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
1551 sizeof(cfg.wintitle)-1);
1552 break;
1553 case IDC_CLOSEEXIT:
1554 if (HIWORD(wParam) == BN_CLICKED ||
1555 HIWORD(wParam) == BN_DOUBLECLICKED)
1556 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
1557 break;
1558 case IDC_CLOSEWARN:
1559 if (HIWORD(wParam) == BN_CLICKED ||
1560 HIWORD(wParam) == BN_DOUBLECLICKED)
1561 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
1562 break;
1563 case IDC_TTEDIT:
1564 if (HIWORD(wParam) == EN_CHANGE)
1565 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
1566 sizeof(cfg.termtype)-1);
1567 break;
1568 case IDC_LGFEDIT:
1569 if (HIWORD(wParam) == EN_CHANGE)
1570 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1571 sizeof(cfg.logfilename)-1);
1572 break;
1573 case IDC_LGFBUTTON:
1574 memset(&of, 0, sizeof(of));
1575 #ifdef OPENFILENAME_SIZE_VERSION_400
1576 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1577 #else
1578 of.lStructSize = sizeof(of);
1579 #endif
1580 of.hwndOwner = hwnd;
1581 of.lpstrFilter = "All Files\0*\0\0\0";
1582 of.lpstrCustomFilter = NULL;
1583 of.nFilterIndex = 1;
1584 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1585 of.nMaxFile = sizeof(filename);
1586 of.lpstrFileTitle = NULL;
1587 of.lpstrInitialDir = NULL;
1588 of.lpstrTitle = "Select session log file";
1589 of.Flags = 0;
1590 if (GetSaveFileName(&of)) {
1591 strcpy(cfg.keyfile, filename);
1592 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.keyfile);
1593 }
1594 break;
1595 case IDC_LSTATOFF:
1596 case IDC_LSTATASCII:
1597 case IDC_LSTATRAW:
1598 if (HIWORD(wParam) == BN_CLICKED ||
1599 HIWORD(wParam) == BN_DOUBLECLICKED) {
1600 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1601 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1602 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1603 }
1604 break;
1605 case IDC_TSEDIT:
1606 case IDC_R_TSEDIT:
1607 if (HIWORD(wParam) == EN_CHANGE)
1608 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
1609 sizeof(cfg.termspeed)-1);
1610 break;
1611 case IDC_LOGEDIT:
1612 if (HIWORD(wParam) == EN_CHANGE)
1613 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
1614 sizeof(cfg.username)-1);
1615 break;
1616 case IDC_RLLUSEREDIT:
1617 if (HIWORD(wParam) == EN_CHANGE)
1618 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1619 sizeof(cfg.localusername)-1);
1620 break;
1621 case IDC_EMBSD:
1622 case IDC_EMRFC:
1623 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
1624 break;
1625 case IDC_ENVADD:
1626 if (HIWORD(wParam) == BN_CLICKED ||
1627 HIWORD(wParam) == BN_DOUBLECLICKED) {
1628 char str[sizeof(cfg.environmt)];
1629 char *p;
1630 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
1631 if (!*str) {
1632 MessageBeep(0);
1633 break;
1634 }
1635 p = str + strlen(str);
1636 *p++ = '\t';
1637 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
1638 if (!*p) {
1639 MessageBeep(0);
1640 break;
1641 }
1642 p = cfg.environmt;
1643 while (*p) {
1644 while (*p) p++;
1645 p++;
1646 }
1647 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1648 strcpy (p, str);
1649 p[strlen(str)+1] = '\0';
1650 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
1651 0, (LPARAM)str);
1652 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1653 SetDlgItemText (hwnd, IDC_VALEDIT, "");
1654 } else {
1655 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1656 MB_OK | MB_ICONERROR);
1657 }
1658 }
1659 break;
1660 case IDC_ENVREMOVE:
1661 if (HIWORD(wParam) != BN_CLICKED &&
1662 HIWORD(wParam) != BN_DOUBLECLICKED)
1663 break;
1664 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
1665 if (i == LB_ERR)
1666 MessageBeep (0);
1667 else {
1668 char *p, *q;
1669
1670 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
1671 i, 0);
1672 p = cfg.environmt;
1673 while (i > 0) {
1674 if (!*p)
1675 goto disaster;
1676 while (*p) p++;
1677 p++;
1678 i--;
1679 }
1680 q = p;
1681 if (!*p)
1682 goto disaster;
1683 while (*p) p++;
1684 p++;
1685 while (*p) {
1686 while (*p)
1687 *q++ = *p++;
1688 *q++ = *p++;
1689 }
1690 *q = '\0';
1691 disaster:;
1692 }
1693 break;
1694 case IDC_NOPTY:
1695 if (HIWORD(wParam) == BN_CLICKED ||
1696 HIWORD(wParam) == BN_DOUBLECLICKED)
1697 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
1698 break;
1699 case IDC_COMPRESS:
1700 if (HIWORD(wParam) == BN_CLICKED ||
1701 HIWORD(wParam) == BN_DOUBLECLICKED)
1702 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1703 break;
1704 case IDC_BUGGYMAC:
1705 if (HIWORD(wParam) == BN_CLICKED ||
1706 HIWORD(wParam) == BN_DOUBLECLICKED)
1707 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1708 break;
1709 case IDC_AGENTFWD:
1710 if (HIWORD(wParam) == BN_CLICKED ||
1711 HIWORD(wParam) == BN_DOUBLECLICKED)
1712 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
1713 break;
1714 case IDC_CIPHER3DES:
1715 case IDC_CIPHERBLOWF:
1716 case IDC_CIPHERDES:
1717 if (HIWORD(wParam) == BN_CLICKED ||
1718 HIWORD(wParam) == BN_DOUBLECLICKED) {
1719 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
1720 cfg.cipher = CIPHER_3DES;
1721 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
1722 cfg.cipher = CIPHER_BLOWFISH;
1723 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
1724 cfg.cipher = CIPHER_DES;
1725 }
1726 break;
1727 case IDC_SSHPROT1:
1728 case IDC_SSHPROT2:
1729 if (HIWORD(wParam) == BN_CLICKED ||
1730 HIWORD(wParam) == BN_DOUBLECLICKED) {
1731 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
1732 cfg.sshprot = 1;
1733 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
1734 cfg.sshprot = 2;
1735 }
1736 break;
1737 case IDC_AUTHTIS:
1738 if (HIWORD(wParam) == BN_CLICKED ||
1739 HIWORD(wParam) == BN_DOUBLECLICKED)
1740 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
1741 break;
1742 case IDC_PKEDIT:
1743 if (HIWORD(wParam) == EN_CHANGE)
1744 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
1745 sizeof(cfg.keyfile)-1);
1746 break;
1747 case IDC_CMDEDIT:
1748 if (HIWORD(wParam) == EN_CHANGE)
1749 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
1750 sizeof(cfg.remote_cmd)-1);
1751 break;
1752 case IDC_PKBUTTON:
1753 memset(&of, 0, sizeof(of));
1754 #ifdef OPENFILENAME_SIZE_VERSION_400
1755 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1756 #else
1757 of.lStructSize = sizeof(of);
1758 #endif
1759 of.hwndOwner = hwnd;
1760 of.lpstrFilter = "All Files\0*\0\0\0";
1761 of.lpstrCustomFilter = NULL;
1762 of.nFilterIndex = 1;
1763 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1764 of.nMaxFile = sizeof(filename);
1765 of.lpstrFileTitle = NULL;
1766 of.lpstrInitialDir = NULL;
1767 of.lpstrTitle = "Select Public Key File";
1768 of.Flags = 0;
1769 if (GetOpenFileName(&of)) {
1770 strcpy(cfg.keyfile, filename);
1771 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
1772 }
1773 break;
1774 case IDC_MBWINDOWS:
1775 case IDC_MBXTERM:
1776 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
1777 break;
1778 case IDC_CCSET:
1779 {
1780 BOOL ok;
1781 int i;
1782 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
1783
1784 if (!ok)
1785 MessageBeep (0);
1786 else {
1787 for (i=0; i<256; i++)
1788 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
1789 i, 0)) {
1790 char str[100];
1791 cfg.wordness[i] = n;
1792 SendDlgItemMessage (hwnd, IDC_CCLIST,
1793 LB_DELETESTRING, i, 0);
1794 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1795 (i>=0x21 && i != 0x7F) ? i : ' ',
1796 cfg.wordness[i]);
1797 SendDlgItemMessage (hwnd, IDC_CCLIST,
1798 LB_INSERTSTRING, i,
1799 (LPARAM)str);
1800 }
1801 }
1802 }
1803 break;
1804 case IDC_BOLDCOLOUR:
1805 if (HIWORD(wParam) == BN_CLICKED ||
1806 HIWORD(wParam) == BN_DOUBLECLICKED) {
1807 int n, i;
1808 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
1809 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
1810 if (n != 12+10*cfg.bold_colour) {
1811 for (i=n; i-- >0 ;)
1812 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1813 LB_DELETESTRING, i, 0);
1814 for (i=0; i<22; i++)
1815 if (cfg.bold_colour || permcolour[i])
1816 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1817 LB_ADDSTRING, 0,
1818 (LPARAM) colours[i]);
1819 }
1820 }
1821 break;
1822 case IDC_PALETTE:
1823 if (HIWORD(wParam) == BN_CLICKED ||
1824 HIWORD(wParam) == BN_DOUBLECLICKED)
1825 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
1826 break;
1827 case IDC_COLOURLIST:
1828 if (HIWORD(wParam) == LBN_DBLCLK ||
1829 HIWORD(wParam) == LBN_SELCHANGE) {
1830 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1831 0, 0);
1832 if (!cfg.bold_colour)
1833 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1834 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1835 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1836 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
1837 }
1838 break;
1839 case IDC_CHANGE:
1840 if (HIWORD(wParam) == BN_CLICKED ||
1841 HIWORD(wParam) == BN_DOUBLECLICKED) {
1842 static CHOOSECOLOR cc;
1843 static DWORD custom[16] = {0}; /* zero initialisers */
1844 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
1845 0, 0);
1846 if (!cfg.bold_colour)
1847 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1848 cc.lStructSize = sizeof(cc);
1849 cc.hwndOwner = hwnd;
1850 cc.hInstance = (HWND)hinst;
1851 cc.lpCustColors = custom;
1852 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1853 cfg.colours[i][2]);
1854 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1855 if (ChooseColor(&cc)) {
1856 cfg.colours[i][0] =
1857 (unsigned char) (cc.rgbResult & 0xFF);
1858 cfg.colours[i][1] =
1859 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1860 cfg.colours[i][2] =
1861 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1862 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
1863 FALSE);
1864 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
1865 FALSE);
1866 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
1867 FALSE);
1868 }
1869 }
1870 break;
1871 case IDC_NOXLAT:
1872 case IDC_KOI8WIN1251:
1873 case IDC_88592WIN1250:
1874 case IDC_88592CP852:
1875 cfg.xlat_enablekoiwin =
1876 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
1877 cfg.xlat_88592w1250 =
1878 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
1879 cfg.xlat_88592cp852 =
1880 IsDlgButtonChecked (hwnd, IDC_88592CP852);
1881 break;
1882 case IDC_CAPSLOCKCYR:
1883 if (HIWORD(wParam) == BN_CLICKED ||
1884 HIWORD(wParam) == BN_DOUBLECLICKED) {
1885 cfg.xlat_capslockcyr =
1886 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
1887 }
1888 break;
1889 case IDC_VTXWINDOWS:
1890 case IDC_VTOEMANSI:
1891 case IDC_VTOEMONLY:
1892 case IDC_VTPOORMAN:
1893 cfg.vtmode =
1894 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1895 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1896 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
1897 VT_POORMAN);
1898 break;
1899 case IDC_X11_FORWARD:
1900 if (HIWORD(wParam) == BN_CLICKED ||
1901 HIWORD(wParam) == BN_DOUBLECLICKED)
1902 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1903 break;
1904 case IDC_X11_DISPLAY:
1905 if (HIWORD(wParam) == EN_CHANGE)
1906 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1907 sizeof(cfg.x11_display)-1);
1908 break;
1909 }
1910 return 0;
1911 case WM_CLOSE:
1912 EndDialog (hwnd, 0);
1913 return 0;
1914
1915 /* Grrr Explorer will maximize Dialogs! */
1916 case WM_SIZE:
1917 if (wParam == SIZE_MAXIMIZED)
1918 force_normal(hwnd);
1919 return 0;
1920 }
1921 return 0;
1922 }
1923
1924 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1925 WPARAM wParam, LPARAM lParam) {
1926 static HWND page = NULL;
1927
1928 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
1929 }
1930 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
1931 EnableWindow(hwnd, 0);
1932 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1933 GetParent(hwnd), AboutProc);
1934 EnableWindow(hwnd, 1);
1935 SetActiveWindow(hwnd);
1936 }
1937 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
1938 }
1939
1940 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1941 WPARAM wParam, LPARAM lParam) {
1942 static HWND page;
1943 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
1944 }
1945
1946 void defuse_showwindow(void) {
1947 /*
1948 * Work around the fact that the app's first call to ShowWindow
1949 * will ignore the default in favour of the shell-provided
1950 * setting.
1951 */
1952 {
1953 HWND hwnd;
1954 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1955 NULL, NullDlgProc);
1956 ShowWindow(hwnd, SW_HIDE);
1957 DestroyWindow(hwnd);
1958 }
1959 }
1960
1961 int do_config (void) {
1962 int ret;
1963
1964 get_sesslist(TRUE);
1965 savedsession[0] = '\0';
1966 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1967 get_sesslist(FALSE);
1968
1969 return ret;
1970 }
1971
1972 int do_reconfig (HWND hwnd) {
1973 Config backup_cfg;
1974 int ret;
1975
1976 backup_cfg = cfg; /* structure copy */
1977 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1978 if (!ret)
1979 cfg = backup_cfg; /* structure copy */
1980
1981 return ret;
1982 }
1983
1984 void logevent (char *string) {
1985 if (nevents >= negsize) {
1986 negsize += 64;
1987 events = srealloc (events, negsize * sizeof(*events));
1988 }
1989 events[nevents] = smalloc(1+strlen(string));
1990 strcpy (events[nevents], string);
1991 nevents++;
1992 if (logbox) {
1993 int count;
1994 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1995 0, (LPARAM)string);
1996 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
1997 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
1998 }
1999 }
2000
2001 void showeventlog (HWND hwnd) {
2002 if (!logbox) {
2003 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2004 hwnd, LogProc);
2005 ShowWindow (logbox, SW_SHOWNORMAL);
2006 }
2007 }
2008
2009 void showabout (HWND hwnd) {
2010 if (!abtbox) {
2011 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2012 hwnd, AboutProc);
2013 ShowWindow (abtbox, SW_SHOWNORMAL);
2014 }
2015 }
2016
2017 void verify_ssh_host_key(char *host, int port, char *keytype,
2018 char *keystr, char *fingerprint) {
2019 int ret;
2020
2021 static const char absentmsg[] =
2022 "The server's host key is not cached in the registry. You\n"
2023 "have no guarantee that the server is the computer you\n"
2024 "think it is.\n"
2025 "The server's key fingerprint is:\n"
2026 "%s\n"
2027 "If you trust this host, hit Yes to add the key to\n"
2028 "PuTTY's cache and carry on connecting.\n"
2029 "If you do not trust this host, hit No to abandon the\n"
2030 "connection.\n";
2031
2032 static const char wrongmsg[] =
2033 "WARNING - POTENTIAL SECURITY BREACH!\n"
2034 "\n"
2035 "The server's host key does not match the one PuTTY has\n"
2036 "cached in the registry. This means that either the\n"
2037 "server administrator has changed the host key, or you\n"
2038 "have actually connected to another computer pretending\n"
2039 "to be the server.\n"
2040 "The new key fingerprint is:\n"
2041 "%s\n"
2042 "If you were expecting this change and trust the new key,\n"
2043 "hit Yes to update PuTTY's cache and continue connecting.\n"
2044 "If you want to carry on connecting but without updating\n"
2045 "the cache, hit No.\n"
2046 "If you want to abandon the connection completely, hit\n"
2047 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2048 "choice.\n";
2049
2050 static const char mbtitle[] = "PuTTY Security Alert";
2051
2052
2053 char message[160+ /* sensible fingerprint max size */
2054 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2055 sizeof(absentmsg) : sizeof(wrongmsg))];
2056
2057 /*
2058 * Verify the key against the registry.
2059 */
2060 ret = verify_host_key(host, port, keytype, keystr);
2061
2062 if (ret == 0) /* success - key matched OK */
2063 return;
2064 if (ret == 2) { /* key was different */
2065 int mbret;
2066 sprintf(message, wrongmsg, fingerprint);
2067 mbret = MessageBox(NULL, message, mbtitle,
2068 MB_ICONWARNING | MB_YESNOCANCEL);
2069 if (mbret == IDYES)
2070 store_host_key(host, port, keytype, keystr);
2071 if (mbret == IDCANCEL)
2072 exit(0);
2073 }
2074 if (ret == 1) { /* key was absent */
2075 int mbret;
2076 sprintf(message, absentmsg, fingerprint);
2077 mbret = MessageBox(NULL, message, mbtitle,
2078 MB_ICONWARNING | MB_YESNO);
2079 if (mbret == IDNO)
2080 exit(0);
2081 store_host_key(host, port, keytype, keystr);
2082 }
2083 }
2084
2085 /*
2086 * Ask whether to wipe a session log file before writing to it.
2087 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2088 */
2089 int askappend(char *filename) {
2090 static const char mbtitle[] = "PuTTY Log to File";
2091 static const char msgtemplate[] =
2092 "The session log file \"%.*s\" already exists.\n"
2093 "You can overwrite it with a new session log,\n"
2094 "append your session log to the end of it,\n"
2095 "or disable session logging for this session.\n"
2096 "Hit Yes to wipe the file, No to append to it,\n"
2097 "or Cancel to disable logging.";
2098 char message[sizeof(msgtemplate) + FILENAME_MAX];
2099 int mbret;
2100 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2101
2102 mbret = MessageBox(NULL, message, mbtitle,
2103 MB_ICONQUESTION | MB_YESNOCANCEL);
2104 if (mbret == IDYES)
2105 return 2;
2106 else if (mbret == IDNO)
2107 return 1;
2108 else
2109 return 0;
2110 }