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