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