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