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