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