Added a new large icon for the PuTTY config box. Doesn't show up in
[sgt/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);
648947d4 1218 SendMessage(hwnd, WM_SETICON, (WPARAM) ICON_BIG,
1219 (LPARAM) LoadIcon(hinst, MAKEINTRESOURCE(IDI_CFGICON)));
c96a8fef 1220 /*
1221 * Centre the window.
1222 */
1223 { /* centre the window */
1224 RECT rs, rd;
1225
1226 hw = GetDesktopWindow();
32874aea 1227 if (GetWindowRect(hw, &rs) && GetWindowRect(hwnd, &rd))
1228 MoveWindow(hwnd,
1229 (rs.right + rs.left + rd.left - rd.right) / 2,
1230 (rs.bottom + rs.top + rd.top - rd.bottom) / 2,
1231 rd.right - rd.left, rd.bottom - rd.top, TRUE);
c96a8fef 1232 }
1233
1234 /*
927d4fc5 1235 * Create the tree view.
c96a8fef 1236 */
32874aea 1237 {
1238 RECT r;
c96a8fef 1239 WPARAM font;
32874aea 1240 HWND tvstatic;
1241
1242 r.left = 3;
1243 r.right = r.left + 75;
1244 r.top = 3;
1245 r.bottom = r.top + 10;
1246 MapDialogRect(hwnd, &r);
1247 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
1248 WS_CHILD | WS_VISIBLE,
1249 r.left, r.top,
1250 r.right - r.left, r.bottom - r.top,
1251 hwnd, (HMENU) IDCX_TVSTATIC, hinst,
1252 NULL);
c96a8fef 1253 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
927d4fc5 1254 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1255
32874aea 1256 r.left = 3;
1257 r.right = r.left + 75;
1258 r.top = 13;
1259 r.bottom = r.top + 206;
1260 MapDialogRect(hwnd, &r);
1261 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
1262 WS_CHILD | WS_VISIBLE |
1263 WS_TABSTOP | TVS_HASLINES |
1264 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS
1265 | TVS_LINESATROOT |
1266 TVS_SHOWSELALWAYS, r.left, r.top,
1267 r.right - r.left, r.bottom - r.top,
1268 hwnd, (HMENU) IDCX_TREEVIEW, hinst,
1269 NULL);
927d4fc5 1270 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1271 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
32874aea 1272 tvfaff.treeview = treeview;
1273 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
1274 }
c96a8fef 1275
1276 /*
3ac9cd9f 1277 * Set up the tree view contents.
c96a8fef 1278 */
32874aea 1279 hsession = treeview_insert(&tvfaff, 0, "Session");
1280 treeview_insert(&tvfaff, 1, "Logging");
1281 treeview_insert(&tvfaff, 0, "Terminal");
1282 treeview_insert(&tvfaff, 1, "Keyboard");
1283 treeview_insert(&tvfaff, 1, "Bell");
1284 treeview_insert(&tvfaff, 0, "Window");
1285 treeview_insert(&tvfaff, 1, "Appearance");
1286 treeview_insert(&tvfaff, 1, "Translation");
1287 treeview_insert(&tvfaff, 1, "Selection");
1288 treeview_insert(&tvfaff, 1, "Colours");
1289 treeview_insert(&tvfaff, 0, "Connection");
1290 if (dlgtype == 0) {
1291 treeview_insert(&tvfaff, 1, "Telnet");
1292 treeview_insert(&tvfaff, 1, "Rlogin");
1293 if (backends[3].backend != NULL) {
1294 treeview_insert(&tvfaff, 1, "SSH");
1295 treeview_insert(&tvfaff, 2, "Tunnels");
1296 }
1297 }
1298
1299 /*
1300 * Put the treeview selection on to the Session panel. This
1301 * should also cause creation of the relevant controls.
1302 */
1303 TreeView_SelectItem(treeview, hsession);
1304
1305 /*
1306 * Set focus into the first available control.
1307 */
1308 {
1309 HWND ctl;
1310 ctl = GetDlgItem(hwnd, IDC_HOST);
1311 if (!ctl)
1312 ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
1313 SetFocus(ctl);
1314 }
c96a8fef 1315
1316 SetWindowLong(hwnd, GWL_USERDATA, 1);
1317 return 0;
1cd246bb 1318 case WM_LBUTTONUP:
32874aea 1319 /*
1320 * Button release should trigger WM_OK if there was a
1321 * previous double click on the session list.
1322 */
1323 ReleaseCapture();
1324 if (readytogo)
1325 SendMessage(hwnd, WM_COMMAND, IDOK, 0);
1326 break;
c96a8fef 1327 case WM_NOTIFY:
927d4fc5 1328 if (LOWORD(wParam) == IDCX_TREEVIEW &&
32874aea 1329 ((LPNMHDR) lParam)->code == TVN_SELCHANGED) {
1330 HTREEITEM i =
1331 TreeView_GetSelection(((LPNMHDR) lParam)->hwndFrom);
927d4fc5 1332 TVITEM item;
32874aea 1333 int j;
c96a8fef 1334 char buffer[64];
32874aea 1335 item.hItem = i;
c96a8fef 1336 item.pszText = buffer;
1337 item.cchTextMax = sizeof(buffer);
927d4fc5 1338 item.mask = TVIF_TEXT;
32874aea 1339 TreeView_GetItem(((LPNMHDR) lParam)->hwndFrom, &item);
3ac9cd9f 1340 for (j = controlstartvalue; j < controlendvalue; j++) {
32874aea 1341 HWND item = GetDlgItem(hwnd, j);
1342 if (item)
1343 DestroyWindow(item);
1344 }
927d4fc5 1345 if (!strcmp(buffer, "Session"))
3ac9cd9f 1346 create_controls(hwnd, dlgtype, sessionpanelstart);
0965bee0 1347 if (!strcmp(buffer, "Logging"))
1348 create_controls(hwnd, dlgtype, loggingpanelstart);
c96a8fef 1349 if (!strcmp(buffer, "Keyboard"))
3ac9cd9f 1350 create_controls(hwnd, dlgtype, keyboardpanelstart);
c96a8fef 1351 if (!strcmp(buffer, "Terminal"))
3ac9cd9f 1352 create_controls(hwnd, dlgtype, terminalpanelstart);
156686ef 1353 if (!strcmp(buffer, "Bell"))
1354 create_controls(hwnd, dlgtype, bellpanelstart);
c96a8fef 1355 if (!strcmp(buffer, "Window"))
3ac9cd9f 1356 create_controls(hwnd, dlgtype, windowpanelstart);
4c4f2716 1357 if (!strcmp(buffer, "Appearance"))
3ac9cd9f 1358 create_controls(hwnd, dlgtype, appearancepanelstart);
9c964e85 1359 if (!strcmp(buffer, "Tunnels"))
3ac9cd9f 1360 create_controls(hwnd, dlgtype, tunnelspanelstart);
927d4fc5 1361 if (!strcmp(buffer, "Connection"))
3ac9cd9f 1362 create_controls(hwnd, dlgtype, connectionpanelstart);
c96a8fef 1363 if (!strcmp(buffer, "Telnet"))
3ac9cd9f 1364 create_controls(hwnd, dlgtype, telnetpanelstart);
c91409da 1365 if (!strcmp(buffer, "Rlogin"))
3ac9cd9f 1366 create_controls(hwnd, dlgtype, rloginpanelstart);
c96a8fef 1367 if (!strcmp(buffer, "SSH"))
3ac9cd9f 1368 create_controls(hwnd, dlgtype, sshpanelstart);
c96a8fef 1369 if (!strcmp(buffer, "Selection"))
3ac9cd9f 1370 create_controls(hwnd, dlgtype, selectionpanelstart);
c96a8fef 1371 if (!strcmp(buffer, "Colours"))
3ac9cd9f 1372 create_controls(hwnd, dlgtype, colourspanelstart);
c96a8fef 1373 if (!strcmp(buffer, "Translation"))
3ac9cd9f 1374 create_controls(hwnd, dlgtype, translationpanelstart);
1375
32874aea 1376 init_dlg_ctrls(hwnd);
c96a8fef 1377
32874aea 1378 SetFocus(((LPNMHDR) lParam)->hwndFrom); /* ensure focus stays */
c96a8fef 1379 return 0;
1380 }
1381 break;
374330e2 1382 case WM_COMMAND:
c96a8fef 1383 /*
1384 * Only process WM_COMMAND once the dialog is fully formed.
1385 */
32874aea 1386 if (GetWindowLong(hwnd, GWL_USERDATA) == 1)
1387 switch (LOWORD(wParam)) {
1388 case IDOK:
1389 if (*cfg.host)
1390 EndDialog(hwnd, 1);
1391 else
1392 MessageBeep(0);
1393 return 0;
1394 case IDCANCEL:
1395 EndDialog(hwnd, 0);
1396 return 0;
1397 case IDC_PROTTELNET:
1398 case IDC_PROTRLOGIN:
1399 case IDC_PROTSSH:
1400 case IDC_PROTRAW:
1401 if (HIWORD(wParam) == BN_CLICKED ||
1402 HIWORD(wParam) == BN_DOUBLECLICKED) {
1403 int i = IsDlgButtonChecked(hwnd, IDC_PROTSSH);
1404 int j = IsDlgButtonChecked(hwnd, IDC_PROTTELNET);
1405 int k = IsDlgButtonChecked(hwnd, IDC_PROTRLOGIN);
1406 cfg.protocol =
1407 i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN :
1408 PROT_RAW;
1409 if ((cfg.protocol == PROT_SSH && cfg.port != 22)
1410 || (cfg.protocol == PROT_TELNET && cfg.port != 23)
1411 || (cfg.protocol == PROT_RLOGIN
1412 && cfg.port != 513)) {
1413 cfg.port = i ? 22 : j ? 23 : 513;
1414 SetDlgItemInt(hwnd, IDC_PORT, cfg.port, FALSE);
1415 }
374330e2 1416 }
32874aea 1417 break;
1418 case IDC_HOST:
1419 if (HIWORD(wParam) == EN_CHANGE)
1420 GetDlgItemText(hwnd, IDC_HOST, cfg.host,
1421 sizeof(cfg.host) - 1);
1422 break;
1423 case IDC_PORT:
1424 if (HIWORD(wParam) == EN_CHANGE) {
1425 GetDlgItemText(hwnd, IDC_PORT, portname, 31);
1426 if (isdigit(portname[0]))
1427 MyGetDlgItemInt(hwnd, IDC_PORT, &cfg.port);
1428 else {
1429 service = getservbyname(portname, NULL);
1430 if (service)
1431 cfg.port = ntohs(service->s_port);
1432 else
1433 cfg.port = 0;
1434 }
b278b14a 1435 }
32874aea 1436 break;
1437 case IDC_SESSEDIT:
1438 if (HIWORD(wParam) == EN_CHANGE) {
1439 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1440 (WPARAM) - 1, 0);
1441 GetDlgItemText(hwnd, IDC_SESSEDIT,
1442 savedsession, sizeof(savedsession) - 1);
1443 savedsession[sizeof(savedsession) - 1] = '\0';
1444 }
1445 break;
1446 case IDC_SESSSAVE:
1447 if (HIWORD(wParam) == BN_CLICKED ||
1448 HIWORD(wParam) == BN_DOUBLECLICKED) {
1449 /*
1450 * Save a session
1451 */
1452 char str[2048];
1453 GetDlgItemText(hwnd, IDC_SESSEDIT, str,
1454 sizeof(str) - 1);
1455 if (!*str) {
1456 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1457 LB_GETCURSEL, 0, 0);
1458 if (n == LB_ERR) {
1459 MessageBeep(0);
1460 break;
1461 }
1462 strcpy(str, sessions[n]);
1463 }
1464 save_settings(str, !!strcmp(str, "Default Settings"),
1465 &cfg);
1466 get_sesslist(FALSE);
1467 get_sesslist(TRUE);
1468 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1469 0, 0);
1470 for (i = 0; i < nsessions; i++)
1471 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1472 LB_ADDSTRING, 0,
1473 (LPARAM) (sessions[i]));
1474 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1475 (WPARAM) - 1, 0);
1476 }
1477 break;
1478 case IDC_SESSLIST:
1479 case IDC_SESSLOAD:
1480 if (LOWORD(wParam) == IDC_SESSLOAD &&
1481 HIWORD(wParam) != BN_CLICKED &&
1482 HIWORD(wParam) != BN_DOUBLECLICKED) break;
1483 if (LOWORD(wParam) == IDC_SESSLIST &&
1484 HIWORD(wParam) != LBN_DBLCLK) break;
1485 {
1486 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1487 LB_GETCURSEL, 0, 0);
1488 int isdef;
374330e2 1489 if (n == LB_ERR) {
1490 MessageBeep(0);
1491 break;
1492 }
32874aea 1493 isdef = !strcmp(sessions[n], "Default Settings");
1494 load_settings(sessions[n], !isdef, &cfg);
1495 init_dlg_ctrls(hwnd);
1496 if (!isdef)
1497 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
1498 else
1499 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
374330e2 1500 }
32874aea 1501 if (LOWORD(wParam) == IDC_SESSLIST) {
1502 /*
1503 * A double-click on a saved session should
1504 * actually start the session, not just load it.
1505 * Unless it's Default Settings or some other
1506 * host-less set of saved settings.
1507 */
1508 if (*cfg.host) {
1509 readytogo = TRUE;
1510 SetCapture(hwnd);
1511 }
374330e2 1512 }
32874aea 1513 break;
1514 case IDC_SESSDEL:
1515 if (HIWORD(wParam) == BN_CLICKED ||
1516 HIWORD(wParam) == BN_DOUBLECLICKED) {
1517 int n = SendDlgItemMessage(hwnd, IDC_SESSLIST,
1518 LB_GETCURSEL, 0, 0);
1519 if (n == LB_ERR || n == 0) {
1520 MessageBeep(0);
1521 break;
1522 }
1523 del_settings(sessions[n]);
1524 get_sesslist(FALSE);
1525 get_sesslist(TRUE);
1526 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_RESETCONTENT,
1527 0, 0);
1528 for (i = 0; i < nsessions; i++)
1529 SendDlgItemMessage(hwnd, IDC_SESSLIST,
1530 LB_ADDSTRING, 0,
1531 (LPARAM) (sessions[i]));
1532 SendDlgItemMessage(hwnd, IDC_SESSLIST, LB_SETCURSEL,
1533 (WPARAM) - 1, 0);
374330e2 1534 }
32874aea 1535 case IDC_PINGEDIT:
1536 if (HIWORD(wParam) == EN_CHANGE)
1537 MyGetDlgItemInt(hwnd, IDC_PINGEDIT,
1538 &cfg.ping_interval);
1539 break;
1540 case IDC_DEL008:
1541 case IDC_DEL127:
1542 if (HIWORD(wParam) == BN_CLICKED ||
1543 HIWORD(wParam) == BN_DOUBLECLICKED)
1544 cfg.bksp_is_delete =
1545 IsDlgButtonChecked(hwnd, IDC_DEL127);
1546 break;
1547 case IDC_HOMETILDE:
1548 case IDC_HOMERXVT:
1549 if (HIWORD(wParam) == BN_CLICKED ||
1550 HIWORD(wParam) == BN_DOUBLECLICKED)
1551 cfg.rxvt_homeend =
1552 IsDlgButtonChecked(hwnd, IDC_HOMERXVT);
1553 break;
1554 case IDC_FUNCTILDE:
1555 case IDC_FUNCLINUX:
1556 case IDC_FUNCXTERM:
1557 case IDC_FUNCVT400:
1558 case IDC_FUNCVT100P:
1559 case IDC_FUNCSCO:
1560 if (HIWORD(wParam) == BN_CLICKED ||
1561 HIWORD(wParam) == BN_DOUBLECLICKED)
1562 switch (LOWORD(wParam)) {
1563 case IDC_FUNCTILDE:
1564 cfg.funky_type = 0;
1565 break;
1566 case IDC_FUNCLINUX:
1567 cfg.funky_type = 1;
1568 break;
1569 case IDC_FUNCXTERM:
1570 cfg.funky_type = 2;
1571 break;
1572 case IDC_FUNCVT400:
1573 cfg.funky_type = 3;
1574 break;
1575 case IDC_FUNCVT100P:
1576 cfg.funky_type = 4;
1577 break;
1578 case IDC_FUNCSCO:
1579 cfg.funky_type = 5;
1580 break;
1581 }
1582 break;
1583 case IDC_KPNORMAL:
1584 case IDC_KPAPPLIC:
1585 if (HIWORD(wParam) == BN_CLICKED ||
1586 HIWORD(wParam) == BN_DOUBLECLICKED) {
1587 cfg.app_keypad =
1588 IsDlgButtonChecked(hwnd, IDC_KPAPPLIC);
1589 cfg.nethack_keypad = FALSE;
f37caa11 1590 }
32874aea 1591 break;
1592 case IDC_KPNH:
1593 if (HIWORD(wParam) == BN_CLICKED ||
1594 HIWORD(wParam) == BN_DOUBLECLICKED) {
1595 cfg.app_keypad = FALSE;
1596 cfg.nethack_keypad = TRUE;
1597 }
1598 break;
1599 case IDC_CURNORMAL:
1600 case IDC_CURAPPLIC:
1601 if (HIWORD(wParam) == BN_CLICKED ||
1602 HIWORD(wParam) == BN_DOUBLECLICKED)
1603 cfg.app_cursor =
1604 IsDlgButtonChecked(hwnd, IDC_CURAPPLIC);
1605 break;
1606 case IDC_NOAPPLICC:
1607 if (HIWORD(wParam) == BN_CLICKED ||
1608 HIWORD(wParam) == BN_DOUBLECLICKED)
1609 cfg.no_applic_c =
1610 IsDlgButtonChecked(hwnd, IDC_NOAPPLICC);
1611 break;
1612 case IDC_NOAPPLICK:
1613 if (HIWORD(wParam) == BN_CLICKED ||
1614 HIWORD(wParam) == BN_DOUBLECLICKED)
1615 cfg.no_applic_k =
1616 IsDlgButtonChecked(hwnd, IDC_NOAPPLICK);
1617 break;
1618 case IDC_ALTF4:
1619 if (HIWORD(wParam) == BN_CLICKED ||
1620 HIWORD(wParam) == BN_DOUBLECLICKED)
1621 cfg.alt_f4 = IsDlgButtonChecked(hwnd, IDC_ALTF4);
1622 break;
1623 case IDC_ALTSPACE:
1624 if (HIWORD(wParam) == BN_CLICKED ||
1625 HIWORD(wParam) == BN_DOUBLECLICKED)
1626 cfg.alt_space =
1627 IsDlgButtonChecked(hwnd, IDC_ALTSPACE);
1628 break;
1629 case IDC_ALTONLY:
1630 if (HIWORD(wParam) == BN_CLICKED ||
1631 HIWORD(wParam) == BN_DOUBLECLICKED)
1632 cfg.alt_only =
1633 IsDlgButtonChecked(hwnd, IDC_ALTONLY);
1634 break;
1635 case IDC_ECHOBACKEND:
1636 case IDC_ECHOYES:
1637 case IDC_ECHONO:
1638 if (HIWORD(wParam) == BN_CLICKED ||
1639 HIWORD(wParam) == BN_DOUBLECLICKED) {
1640 if (LOWORD(wParam) == IDC_ECHOBACKEND)
1641 cfg.localecho = LD_BACKEND;
1642 if (LOWORD(wParam) == IDC_ECHOYES)
1643 cfg.localecho = LD_YES;
1644 if (LOWORD(wParam) == IDC_ECHONO)
1645 cfg.localecho = LD_NO;
1646 }
1647 break;
1648 case IDC_EDITBACKEND:
1649 case IDC_EDITYES:
1650 case IDC_EDITNO:
1651 if (HIWORD(wParam) == BN_CLICKED ||
1652 HIWORD(wParam) == BN_DOUBLECLICKED) {
1653 if (LOWORD(wParam) == IDC_EDITBACKEND)
1654 cfg.localedit = LD_BACKEND;
1655 if (LOWORD(wParam) == IDC_EDITYES)
1656 cfg.localedit = LD_YES;
1657 if (LOWORD(wParam) == IDC_EDITNO)
1658 cfg.localedit = LD_NO;
1659 }
1660 break;
1661 case IDC_ANSWEREDIT:
1662 if (HIWORD(wParam) == EN_CHANGE)
1663 GetDlgItemText(hwnd, IDC_ANSWEREDIT, cfg.answerback,
1664 sizeof(cfg.answerback) - 1);
1665 break;
1666 case IDC_ALWAYSONTOP:
1667 if (HIWORD(wParam) == BN_CLICKED ||
1668 HIWORD(wParam) == BN_DOUBLECLICKED)
1669 cfg.alwaysontop =
1670 IsDlgButtonChecked(hwnd, IDC_ALWAYSONTOP);
1671 break;
1672 case IDC_SCROLLKEY:
1673 if (HIWORD(wParam) == BN_CLICKED ||
1674 HIWORD(wParam) == BN_DOUBLECLICKED)
1675 cfg.scroll_on_key =
1676 IsDlgButtonChecked(hwnd, IDC_SCROLLKEY);
1677 break;
1678 case IDC_SCROLLDISP:
1679 if (HIWORD(wParam) == BN_CLICKED ||
1680 HIWORD(wParam) == BN_DOUBLECLICKED)
1681 cfg.scroll_on_disp =
1682 IsDlgButtonChecked(hwnd, IDC_SCROLLDISP);
1683 break;
1684 case IDC_COMPOSEKEY:
1685 if (HIWORD(wParam) == BN_CLICKED ||
1686 HIWORD(wParam) == BN_DOUBLECLICKED)
1687 cfg.compose_key =
1688 IsDlgButtonChecked(hwnd, IDC_COMPOSEKEY);
1689 break;
1690 case IDC_CTRLALTKEYS:
1691 if (HIWORD(wParam) == BN_CLICKED ||
1692 HIWORD(wParam) == BN_DOUBLECLICKED)
1693 cfg.ctrlaltkeys =
1694 IsDlgButtonChecked(hwnd, IDC_CTRLALTKEYS);
1695 break;
a5f3e637 1696 case IDC_TELNETKEY:
1697 if (HIWORD(wParam) == BN_CLICKED ||
1698 HIWORD(wParam) == BN_DOUBLECLICKED)
1699 cfg.telnet_keyboard =
1700 IsDlgButtonChecked(hwnd, IDC_TELNETKEY);
1701 break;
32874aea 1702 case IDC_WRAPMODE:
1703 if (HIWORD(wParam) == BN_CLICKED ||
1704 HIWORD(wParam) == BN_DOUBLECLICKED)
1705 cfg.wrap_mode =
1706 IsDlgButtonChecked(hwnd, IDC_WRAPMODE);
1707 break;
1708 case IDC_DECOM:
1709 if (HIWORD(wParam) == BN_CLICKED ||
1710 HIWORD(wParam) == BN_DOUBLECLICKED)
1711 cfg.dec_om = IsDlgButtonChecked(hwnd, IDC_DECOM);
1712 break;
1713 case IDC_LFHASCR:
1714 if (HIWORD(wParam) == BN_CLICKED ||
1715 HIWORD(wParam) == BN_DOUBLECLICKED)
1716 cfg.lfhascr =
1717 IsDlgButtonChecked(hwnd, IDC_LFHASCR);
1718 break;
1719 case IDC_ROWSEDIT:
1720 if (HIWORD(wParam) == EN_CHANGE)
1721 MyGetDlgItemInt(hwnd, IDC_ROWSEDIT, &cfg.height);
1722 break;
1723 case IDC_COLSEDIT:
1724 if (HIWORD(wParam) == EN_CHANGE)
1725 MyGetDlgItemInt(hwnd, IDC_COLSEDIT, &cfg.width);
1726 break;
1727 case IDC_SAVEEDIT:
1728 if (HIWORD(wParam) == EN_CHANGE)
1729 MyGetDlgItemInt(hwnd, IDC_SAVEEDIT, &cfg.savelines);
1730 break;
1731 case IDC_CHOOSEFONT:
c0a18295 1732 {
1733 HDC hdc = GetDC(0);
1734 lf.lfHeight = -MulDiv(cfg.fontheight,
1735 GetDeviceCaps(hdc, LOGPIXELSY),
1736 72);
1737 ReleaseDC(0, hdc);
1738 }
32874aea 1739 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1740 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1741 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1742 lf.lfCharSet = cfg.fontcharset;
1743 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1744 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1745 lf.lfQuality = DEFAULT_QUALITY;
1746 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1747 strncpy(lf.lfFaceName, cfg.font,
1748 sizeof(lf.lfFaceName) - 1);
1749 lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0';
1750
1751 cf.lStructSize = sizeof(cf);
1752 cf.hwndOwner = hwnd;
1753 cf.lpLogFont = &lf;
1754 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1755 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1756
1757 if (ChooseFont(&cf)) {
1758 strncpy(cfg.font, lf.lfFaceName, sizeof(cfg.font) - 1);
1759 cfg.font[sizeof(cfg.font) - 1] = '\0';
1760 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1761 cfg.fontcharset = lf.lfCharSet;
1762 cfg.fontheight = cf.iPointSize / 10;
1763 fmtfont(fontstatic);
1764 SetDlgItemText(hwnd, IDC_FONTSTATIC, fontstatic);
1765 }
1766 break;
1767 case IDC_BELL_DISABLED:
1768 case IDC_BELL_DEFAULT:
1769 case IDC_BELL_WAVEFILE:
1770 case IDC_BELL_VISUAL:
1771 if (HIWORD(wParam) == BN_CLICKED ||
1772 HIWORD(wParam) == BN_DOUBLECLICKED) {
1773 if (LOWORD(wParam) == IDC_BELL_DISABLED)
1774 cfg.beep = BELL_DISABLED;
1775 if (LOWORD(wParam) == IDC_BELL_DEFAULT)
1776 cfg.beep = BELL_DEFAULT;
1777 if (LOWORD(wParam) == IDC_BELL_WAVEFILE)
1778 cfg.beep = BELL_WAVEFILE;
1779 if (LOWORD(wParam) == IDC_BELL_VISUAL)
1780 cfg.beep = BELL_VISUAL;
1781 }
1782 break;
1783 case IDC_BELL_WAVEBROWSE:
1784 memset(&of, 0, sizeof(of));
03169ad0 1785#ifdef OPENFILENAME_SIZE_VERSION_400
32874aea 1786 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
03169ad0 1787#else
32874aea 1788 of.lStructSize = sizeof(of);
03169ad0 1789#endif
32874aea 1790 of.hwndOwner = hwnd;
1791 of.lpstrFilter = "Wave Files\0*.WAV\0AllFiles\0*\0\0\0";
1792 of.lpstrCustomFilter = NULL;
1793 of.nFilterIndex = 1;
1794 of.lpstrFile = filename;
1795 strcpy(filename, cfg.bell_wavefile);
1796 of.nMaxFile = sizeof(filename);
1797 of.lpstrFileTitle = NULL;
1798 of.lpstrInitialDir = NULL;
1799 of.lpstrTitle = "Select Bell Sound File";
1800 of.Flags = 0;
1801 if (GetOpenFileName(&of)) {
1802 strcpy(cfg.bell_wavefile, filename);
1803 SetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1804 cfg.bell_wavefile);
1805 }
1806 break;
1807 case IDC_BELL_WAVEEDIT:
1808 if (HIWORD(wParam) == EN_CHANGE)
1809 GetDlgItemText(hwnd, IDC_BELL_WAVEEDIT,
1810 cfg.bell_wavefile,
1811 sizeof(cfg.bell_wavefile) - 1);
1812 break;
1813 case IDC_BELLOVL:
1814 if (HIWORD(wParam) == BN_CLICKED ||
1815 HIWORD(wParam) == BN_DOUBLECLICKED)
1816 cfg.bellovl =
1817 IsDlgButtonChecked(hwnd, IDC_BELLOVL);
1818 break;
1819 case IDC_BELLOVLN:
1820 if (HIWORD(wParam) == EN_CHANGE)
1821 MyGetDlgItemInt(hwnd, IDC_BELLOVLN, &cfg.bellovl_n);
1822 break;
1823 case IDC_BELLOVLT:
1824 if (HIWORD(wParam) == EN_CHANGE)
1825 MyGetDlgItemFlt(hwnd, IDC_BELLOVLT, &cfg.bellovl_t,
1826 1000);
1827 break;
1828 case IDC_BELLOVLS:
1829 if (HIWORD(wParam) == EN_CHANGE)
1830 MyGetDlgItemFlt(hwnd, IDC_BELLOVLS, &cfg.bellovl_s,
1831 1000);
1832 break;
1833 case IDC_BLINKTEXT:
1834 if (HIWORD(wParam) == BN_CLICKED ||
1835 HIWORD(wParam) == BN_DOUBLECLICKED)
1836 cfg.blinktext =
1837 IsDlgButtonChecked(hwnd, IDC_BLINKTEXT);
1838 break;
1839 case IDC_BCE:
1840 if (HIWORD(wParam) == BN_CLICKED ||
1841 HIWORD(wParam) == BN_DOUBLECLICKED)
1842 cfg.bce = IsDlgButtonChecked(hwnd, IDC_BCE);
1843 break;
1844 case IDC_WINNAME:
1845 if (HIWORD(wParam) == BN_CLICKED ||
1846 HIWORD(wParam) == BN_DOUBLECLICKED)
1847 cfg.win_name_always =
1848 IsDlgButtonChecked(hwnd, IDC_WINNAME);
1849 break;
1850 case IDC_HIDEMOUSE:
1851 if (HIWORD(wParam) == BN_CLICKED ||
1852 HIWORD(wParam) == BN_DOUBLECLICKED)
1853 cfg.hide_mouseptr =
1854 IsDlgButtonChecked(hwnd, IDC_HIDEMOUSE);
1855 break;
1856 case IDC_SUNKENEDGE:
1857 if (HIWORD(wParam) == BN_CLICKED ||
1858 HIWORD(wParam) == BN_DOUBLECLICKED)
1859 cfg.sunken_edge =
1860 IsDlgButtonChecked(hwnd, IDC_SUNKENEDGE);
1861 break;
1862 case IDC_CURBLOCK:
1863 if (HIWORD(wParam) == BN_CLICKED ||
1864 HIWORD(wParam) == BN_DOUBLECLICKED)
1865 cfg.cursor_type = 0;
1866 break;
1867 case IDC_CURUNDER:
1868 if (HIWORD(wParam) == BN_CLICKED ||
1869 HIWORD(wParam) == BN_DOUBLECLICKED)
1870 cfg.cursor_type = 1;
1871 break;
1872 case IDC_CURVERT:
1873 if (HIWORD(wParam) == BN_CLICKED ||
1874 HIWORD(wParam) == BN_DOUBLECLICKED)
1875 cfg.cursor_type = 2;
1876 break;
1877 case IDC_BLINKCUR:
1878 if (HIWORD(wParam) == BN_CLICKED ||
1879 HIWORD(wParam) == BN_DOUBLECLICKED)
1880 cfg.blink_cur =
1881 IsDlgButtonChecked(hwnd, IDC_BLINKCUR);
1882 break;
1883 case IDC_SCROLLBAR:
1884 if (HIWORD(wParam) == BN_CLICKED ||
1885 HIWORD(wParam) == BN_DOUBLECLICKED)
1886 cfg.scrollbar =
1887 IsDlgButtonChecked(hwnd, IDC_SCROLLBAR);
1888 break;
1889 case IDC_LOCKSIZE:
1890 if (HIWORD(wParam) == BN_CLICKED ||
1891 HIWORD(wParam) == BN_DOUBLECLICKED)
1892 cfg.locksize =
1893 IsDlgButtonChecked(hwnd, IDC_LOCKSIZE);
1894 break;
1895 case IDC_WINEDIT:
1896 if (HIWORD(wParam) == EN_CHANGE)
1897 GetDlgItemText(hwnd, IDC_WINEDIT, cfg.wintitle,
1898 sizeof(cfg.wintitle) - 1);
1899 break;
1900 case IDC_COEALWAYS:
1901 case IDC_COENEVER:
1902 case IDC_COENORMAL:
1903 if (HIWORD(wParam) == BN_CLICKED ||
1904 HIWORD(wParam) == BN_DOUBLECLICKED) {
1905 cfg.close_on_exit =
1906 IsDlgButtonChecked(hwnd,
1907 IDC_COEALWAYS) ? COE_ALWAYS :
1908 IsDlgButtonChecked(hwnd,
1909 IDC_COENEVER) ? COE_NEVER :
1910 COE_NORMAL;
1911 }
1912 break;
1913 case IDC_CLOSEWARN:
1914 if (HIWORD(wParam) == BN_CLICKED ||
1915 HIWORD(wParam) == BN_DOUBLECLICKED)
1916 cfg.warn_on_close =
1917 IsDlgButtonChecked(hwnd, IDC_CLOSEWARN);
1918 break;
1919 case IDC_TTEDIT:
1920 if (HIWORD(wParam) == EN_CHANGE)
1921 GetDlgItemText(hwnd, IDC_TTEDIT, cfg.termtype,
1922 sizeof(cfg.termtype) - 1);
1923 break;
1924 case IDC_LGFEDIT:
1925 if (HIWORD(wParam) == EN_CHANGE)
1926 GetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename,
1927 sizeof(cfg.logfilename) - 1);
1928 break;
1929 case IDC_LGFBUTTON:
1930 memset(&of, 0, sizeof(of));
e1c8e0ed 1931#ifdef OPENFILENAME_SIZE_VERSION_400
32874aea 1932 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
e1c8e0ed 1933#else
32874aea 1934 of.lStructSize = sizeof(of);
e1c8e0ed 1935#endif
32874aea 1936 of.hwndOwner = hwnd;
1937 of.lpstrFilter = "All Files\0*\0\0\0";
1938 of.lpstrCustomFilter = NULL;
1939 of.nFilterIndex = 1;
1940 of.lpstrFile = filename;
1941 strcpy(filename, cfg.logfilename);
1942 of.nMaxFile = sizeof(filename);
1943 of.lpstrFileTitle = NULL;
1944 of.lpstrInitialDir = NULL;
1945 of.lpstrTitle = "Select session log file";
1946 of.Flags = 0;
1947 if (GetSaveFileName(&of)) {
1948 strcpy(cfg.logfilename, filename);
1949 SetDlgItemText(hwnd, IDC_LGFEDIT, cfg.logfilename);
374330e2 1950 }
32874aea 1951 break;
1952 case IDC_LSTATOFF:
1953 case IDC_LSTATASCII:
1954 case IDC_LSTATRAW:
1955 if (HIWORD(wParam) == BN_CLICKED ||
1956 HIWORD(wParam) == BN_DOUBLECLICKED) {
1957 if (IsDlgButtonChecked(hwnd, IDC_LSTATOFF))
1958 cfg.logtype = 0;
1959 if (IsDlgButtonChecked(hwnd, IDC_LSTATASCII))
1960 cfg.logtype = 1;
1961 if (IsDlgButtonChecked(hwnd, IDC_LSTATRAW))
1962 cfg.logtype = 2;
374330e2 1963 }
32874aea 1964 break;
1965 case IDC_LSTATXASK:
1966 case IDC_LSTATXAPN:
1967 case IDC_LSTATXOVR:
1968 if (HIWORD(wParam) == BN_CLICKED ||
1969 HIWORD(wParam) == BN_DOUBLECLICKED) {
1970 if (IsDlgButtonChecked(hwnd, IDC_LSTATXASK))
1971 cfg.logxfovr = LGXF_ASK;
1972 if (IsDlgButtonChecked(hwnd, IDC_LSTATXAPN))
1973 cfg.logxfovr = LGXF_APN;
1974 if (IsDlgButtonChecked(hwnd, IDC_LSTATXOVR))
1975 cfg.logxfovr = LGXF_OVR;
374330e2 1976 }
32874aea 1977 break;
1978 case IDC_TSEDIT:
1979 case IDC_R_TSEDIT:
1980 if (HIWORD(wParam) == EN_CHANGE)
1981 GetDlgItemText(hwnd, LOWORD(wParam), cfg.termspeed,
1982 sizeof(cfg.termspeed) - 1);
1983 break;
1984 case IDC_LOGEDIT:
1985 if (HIWORD(wParam) == EN_CHANGE)
1986 GetDlgItemText(hwnd, IDC_LOGEDIT, cfg.username,
1987 sizeof(cfg.username) - 1);
1988 break;
1989 case IDC_RLLUSEREDIT:
1990 if (HIWORD(wParam) == EN_CHANGE)
1991 GetDlgItemText(hwnd, IDC_RLLUSEREDIT,
1992 cfg.localusername,
1993 sizeof(cfg.localusername) - 1);
1994 break;
1995 case IDC_EMBSD:
1996 case IDC_EMRFC:
1997 cfg.rfc_environ = IsDlgButtonChecked(hwnd, IDC_EMRFC);
1998 break;
8faa456c 1999 case IDC_TPASSIVE:
2000 case IDC_TACTIVE:
2001 cfg.passive_telnet =
2002 IsDlgButtonChecked(hwnd, IDC_TPASSIVE);
2003 break;
32874aea 2004 case IDC_ENVADD:
2005 if (HIWORD(wParam) == BN_CLICKED ||
2006 HIWORD(wParam) == BN_DOUBLECLICKED) {
2007 char str[sizeof(cfg.environmt)];
2008 char *p;
2009 GetDlgItemText(hwnd, IDC_VAREDIT, str,
2010 sizeof(str) - 1);
2011 if (!*str) {
2012 MessageBeep(0);
2013 break;
2014 }
2015 p = str + strlen(str);
2016 *p++ = '\t';
2017 GetDlgItemText(hwnd, IDC_VALEDIT, p,
2018 sizeof(str) - 1 - (p - str));
2019 if (!*p) {
2020 MessageBeep(0);
2021 break;
2022 }
2023 p = cfg.environmt;
2024 while (*p) {
2025 while (*p)
2026 p++;
2027 p++;
2028 }
2029 if ((p - cfg.environmt) + strlen(str) + 2 <
2030 sizeof(cfg.environmt)) {
2031 strcpy(p, str);
2032 p[strlen(str) + 1] = '\0';
2033 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_ADDSTRING,
2034 0, (LPARAM) str);
2035 SetDlgItemText(hwnd, IDC_VAREDIT, "");
2036 SetDlgItemText(hwnd, IDC_VALEDIT, "");
2037 } else {
2038 MessageBox(hwnd, "Environment too big",
2039 "PuTTY Error", MB_OK | MB_ICONERROR);
2040 }
374330e2 2041 }
32874aea 2042 break;
2043 case IDC_ENVREMOVE:
2044 if (HIWORD(wParam) != BN_CLICKED &&
2045 HIWORD(wParam) != BN_DOUBLECLICKED) break;
2046 i =
2047 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_GETCURSEL, 0,
2048 0);
2049 if (i == LB_ERR)
2050 MessageBeep(0);
2051 else {
2052 char *p, *q;
2053
2054 SendDlgItemMessage(hwnd, IDC_ENVLIST, LB_DELETESTRING,
2055 i, 0);
2056 p = cfg.environmt;
2057 while (i > 0) {
2058 if (!*p)
2059 goto disaster;
2060 while (*p)
2061 p++;
2062 p++;
2063 i--;
2064 }
2065 q = p;
374330e2 2066 if (!*p)
2067 goto disaster;
374330e2 2068 while (*p)
32874aea 2069 p++;
2070 p++;
2071 while (*p) {
2072 while (*p)
2073 *q++ = *p++;
374330e2 2074 *q++ = *p++;
32874aea 2075 }
2076 *q = '\0';
2077 disaster:;
374330e2 2078 }
32874aea 2079 break;
2080 case IDC_NOPTY:
2081 if (HIWORD(wParam) == BN_CLICKED ||
2082 HIWORD(wParam) == BN_DOUBLECLICKED)
2083 cfg.nopty = IsDlgButtonChecked(hwnd, IDC_NOPTY);
2084 break;
2085 case IDC_COMPRESS:
2086 if (HIWORD(wParam) == BN_CLICKED ||
2087 HIWORD(wParam) == BN_DOUBLECLICKED)
2088 cfg.compression =
2089 IsDlgButtonChecked(hwnd, IDC_COMPRESS);
2090 break;
2091 case IDC_BUGGYMAC:
2092 if (HIWORD(wParam) == BN_CLICKED ||
2093 HIWORD(wParam) == BN_DOUBLECLICKED)
2094 cfg.buggymac =
2095 IsDlgButtonChecked(hwnd, IDC_BUGGYMAC);
2096 break;
2097 case IDC_AGENTFWD:
2098 if (HIWORD(wParam) == BN_CLICKED ||
2099 HIWORD(wParam) == BN_DOUBLECLICKED)
2100 cfg.agentfwd =
2101 IsDlgButtonChecked(hwnd, IDC_AGENTFWD);
2102 break;
2103 case IDC_CIPHER3DES:
2104 case IDC_CIPHERBLOWF:
2105 case IDC_CIPHERDES:
2106 case IDC_CIPHERAES:
2107 if (HIWORD(wParam) == BN_CLICKED ||
2108 HIWORD(wParam) == BN_DOUBLECLICKED) {
2109 if (IsDlgButtonChecked(hwnd, IDC_CIPHER3DES))
2110 cfg.cipher = CIPHER_3DES;
2111 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERBLOWF))
2112 cfg.cipher = CIPHER_BLOWFISH;
2113 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERDES))
2114 cfg.cipher = CIPHER_DES;
2115 else if (IsDlgButtonChecked(hwnd, IDC_CIPHERAES))
2116 cfg.cipher = CIPHER_AES;
2117 }
2118 break;
2119 case IDC_SSHPROT1:
2120 case IDC_SSHPROT2:
2121 if (HIWORD(wParam) == BN_CLICKED ||
2122 HIWORD(wParam) == BN_DOUBLECLICKED) {
2123 if (IsDlgButtonChecked(hwnd, IDC_SSHPROT1))
2124 cfg.sshprot = 1;
2125 else if (IsDlgButtonChecked(hwnd, IDC_SSHPROT2))
2126 cfg.sshprot = 2;
2127 }
2128 break;
2129 case IDC_AUTHTIS:
2130 if (HIWORD(wParam) == BN_CLICKED ||
2131 HIWORD(wParam) == BN_DOUBLECLICKED)
2132 cfg.try_tis_auth =
2133 IsDlgButtonChecked(hwnd, IDC_AUTHTIS);
2134 break;
2135 case IDC_PKEDIT:
2136 if (HIWORD(wParam) == EN_CHANGE)
2137 GetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile,
2138 sizeof(cfg.keyfile) - 1);
2139 break;
2140 case IDC_CMDEDIT:
2141 if (HIWORD(wParam) == EN_CHANGE)
2142 GetDlgItemText(hwnd, IDC_CMDEDIT, cfg.remote_cmd,
2143 sizeof(cfg.remote_cmd) - 1);
2144 break;
2145 case IDC_PKBUTTON:
2146 memset(&of, 0, sizeof(of));
7cca0d81 2147#ifdef OPENFILENAME_SIZE_VERSION_400
32874aea 2148 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
7cca0d81 2149#else
32874aea 2150 of.lStructSize = sizeof(of);
7cca0d81 2151#endif
32874aea 2152 of.hwndOwner = hwnd;
2153 of.lpstrFilter = "All Files\0*\0\0\0";
2154 of.lpstrCustomFilter = NULL;
2155 of.nFilterIndex = 1;
2156 of.lpstrFile = filename;
2157 strcpy(filename, cfg.keyfile);
2158 of.nMaxFile = sizeof(filename);
2159 of.lpstrFileTitle = NULL;
2160 of.lpstrInitialDir = NULL;
2161 of.lpstrTitle = "Select Public Key File";
2162 of.Flags = 0;
2163 if (GetOpenFileName(&of)) {
2164 strcpy(cfg.keyfile, filename);
2165 SetDlgItemText(hwnd, IDC_PKEDIT, cfg.keyfile);
374330e2 2166 }
32874aea 2167 break;
2168 case IDC_RAWCNP:
2169 cfg.rawcnp = IsDlgButtonChecked(hwnd, IDC_RAWCNP);
2170 case IDC_MBWINDOWS:
2171 case IDC_MBXTERM:
2172 cfg.mouse_is_xterm = IsDlgButtonChecked(hwnd, IDC_MBXTERM);
2173 break;
2174 case IDC_CCSET:
2175 {
2176 BOOL ok;
2177 int i;
2178 int n = GetDlgItemInt(hwnd, IDC_CCEDIT, &ok, FALSE);
2179
2180 if (!ok)
2181 MessageBeep(0);
2182 else {
4eeb7d09 2183 for (i = 0; i < 128; i++)
32874aea 2184 if (SendDlgItemMessage
2185 (hwnd, IDC_CCLIST, LB_GETSEL, i, 0)) {
2186 char str[100];
2187 cfg.wordness[i] = n;
2188 SendDlgItemMessage(hwnd, IDC_CCLIST,
2189 LB_DELETESTRING, i, 0);
2190 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
2191 (i >= 0x21 && i != 0x7F) ? i : ' ',
2192 cfg.wordness[i]);
2193 SendDlgItemMessage(hwnd, IDC_CCLIST,
2194 LB_INSERTSTRING, i,
2195 (LPARAM) str);
2196 }
2197 }
374330e2 2198 }
32874aea 2199 break;
2200 case IDC_BOLDCOLOUR:
2201 if (HIWORD(wParam) == BN_CLICKED ||
2202 HIWORD(wParam) == BN_DOUBLECLICKED) {
2203 int n, i;
2204 cfg.bold_colour =
2205 IsDlgButtonChecked(hwnd, IDC_BOLDCOLOUR);
2206 n =
2207 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2208 LB_GETCOUNT, 0, 0);
2209 if (n != 12 + 10 * cfg.bold_colour) {
2210 for (i = n; i-- > 0;)
2211 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2212 LB_DELETESTRING, i, 0);
2213 for (i = 0; i < 22; i++)
2214 if (cfg.bold_colour || permcolour[i])
2215 SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2216 LB_ADDSTRING, 0,
2217 (LPARAM) colours[i]);
2218 }
374330e2 2219 }
32874aea 2220 break;
2221 case IDC_PALETTE:
2222 if (HIWORD(wParam) == BN_CLICKED ||
2223 HIWORD(wParam) == BN_DOUBLECLICKED)
2224 cfg.try_palette =
2225 IsDlgButtonChecked(hwnd, IDC_PALETTE);
2226 break;
2227 case IDC_COLOURLIST:
2228 if (HIWORD(wParam) == LBN_DBLCLK ||
2229 HIWORD(wParam) == LBN_SELCHANGE) {
2230 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2231 LB_GETCURSEL,
2232 0, 0);
2233 if (!cfg.bold_colour)
2234 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2235 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2236 FALSE);
2237 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2238 FALSE);
2239 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2240 FALSE);
2241 }
2242 break;
2243 case IDC_CHANGE:
2244 if (HIWORD(wParam) == BN_CLICKED ||
2245 HIWORD(wParam) == BN_DOUBLECLICKED) {
2246 static CHOOSECOLOR cc;
2247 static DWORD custom[16] = { 0 }; /* zero initialisers */
2248 int i = SendDlgItemMessage(hwnd, IDC_COLOURLIST,
2249 LB_GETCURSEL,
2250 0, 0);
2251 if (!cfg.bold_colour)
2252 i = (i < 3 ? i * 2 : i == 3 ? 5 : i * 2 - 2);
2253 cc.lStructSize = sizeof(cc);
2254 cc.hwndOwner = hwnd;
2255 cc.hInstance = (HWND) hinst;
2256 cc.lpCustColors = custom;
2257 cc.rgbResult =
2258 RGB(cfg.colours[i][0], cfg.colours[i][1],
2259 cfg.colours[i][2]);
2260 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
2261 if (ChooseColor(&cc)) {
2262 cfg.colours[i][0] =
2263 (unsigned char) (cc.rgbResult & 0xFF);
2264 cfg.colours[i][1] =
2265 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
2266 cfg.colours[i][2] =
2267 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
2268 SetDlgItemInt(hwnd, IDC_RVALUE, cfg.colours[i][0],
2269 FALSE);
2270 SetDlgItemInt(hwnd, IDC_GVALUE, cfg.colours[i][1],
2271 FALSE);
2272 SetDlgItemInt(hwnd, IDC_BVALUE, cfg.colours[i][2],
2273 FALSE);
2274 }
2275 }
2276 break;
4eeb7d09 2277 case IDC_CODEPAGE:
2278 if (HIWORD(wParam) == EN_CHANGE)
2279 GetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage,
2280 sizeof(cfg.line_codepage) - 1);
2281 if (HIWORD(wParam) == EN_KILLFOCUS) {
2282 int cp = decode_codepage(cfg.line_codepage);
2283 char buf[256];
2284 if (cp < -1) {
2285 if (cp == -2)
2286 sprintf(buf,
2287 "Unable to identify character set '%s', "
2288 "translation disabled.",
2289 cfg.line_codepage);
2290 if (cp == -3)
2291 sprintf(buf,
2292 "Character set '%s' is a DBCS, "
2293 "translation is not available.",
2294 cfg.line_codepage);
2295 MessageBox(hwnd, buf, "PuTTY Error",
2296 MB_ICONERROR | MB_OK);
2297 }
2298 strcpy(cfg.line_codepage, cp_name(cp));
2299 SetDlgItemText(hwnd, IDC_CODEPAGE, cfg.line_codepage);
32874aea 2300 }
2301 break;
2302 case IDC_VTXWINDOWS:
2303 case IDC_VTOEMANSI:
2304 case IDC_VTOEMONLY:
2305 case IDC_VTPOORMAN:
4eeb7d09 2306 case IDC_VTUNICODE:
32874aea 2307 cfg.vtmode =
2308 (IsDlgButtonChecked(hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS
2309 : IsDlgButtonChecked(hwnd,
2310 IDC_VTOEMANSI) ? VT_OEMANSI :
2311 IsDlgButtonChecked(hwnd,
2312 IDC_VTOEMONLY) ? VT_OEMONLY :
4eeb7d09 2313 IsDlgButtonChecked(hwnd,
2314 IDC_VTUNICODE) ? VT_UNICODE :
32874aea 2315 VT_POORMAN);
2316 break;
2317 case IDC_X11_FORWARD:
2318 if (HIWORD(wParam) == BN_CLICKED ||
2319 HIWORD(wParam) == BN_DOUBLECLICKED)
2320 cfg.x11_forward =
2321 IsDlgButtonChecked(hwnd, IDC_X11_FORWARD);
2322 break;
2323 case IDC_X11_DISPLAY:
2324 if (HIWORD(wParam) == EN_CHANGE)
2325 GetDlgItemText(hwnd, IDC_X11_DISPLAY, cfg.x11_display,
2326 sizeof(cfg.x11_display) - 1);
2327 break;
374330e2 2328 }
374330e2 2329 return 0;
2330 case WM_CLOSE:
32874aea 2331 EndDialog(hwnd, 0);
374330e2 2332 return 0;
c9def1b8 2333
2334 /* Grrr Explorer will maximize Dialogs! */
2335 case WM_SIZE:
2336 if (wParam == SIZE_MAXIMIZED)
32874aea 2337 force_normal(hwnd);
c9def1b8 2338 return 0;
374330e2 2339 }
2340 return 0;
2341}
2342
32874aea 2343static int CALLBACK MainDlgProc(HWND hwnd, UINT msg,
2344 WPARAM wParam, LPARAM lParam)
2345{
374330e2 2346 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
374330e2 2347 }
c96a8fef 2348 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
374330e2 2349 EnableWindow(hwnd, 0);
2350 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2351 GetParent(hwnd), AboutProc);
2352 EnableWindow(hwnd, 1);
32874aea 2353 SetActiveWindow(hwnd);
374330e2 2354 }
32874aea 2355 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 0);
374330e2 2356}
2357
32874aea 2358static int CALLBACK ReconfDlgProc(HWND hwnd, UINT msg,
2359 WPARAM wParam, LPARAM lParam)
2360{
2361 return GenericMainDlgProc(hwnd, msg, wParam, lParam, 1);
374330e2 2362}
2363
32874aea 2364void defuse_showwindow(void)
2365{
301b66db 2366 /*
2367 * Work around the fact that the app's first call to ShowWindow
2368 * will ignore the default in favour of the shell-provided
2369 * setting.
2370 */
2371 {
32874aea 2372 HWND hwnd;
2373 hwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2374 NULL, NullDlgProc);
2375 ShowWindow(hwnd, SW_HIDE);
2376 DestroyWindow(hwnd);
301b66db 2377 }
2378}
2379
32874aea 2380int do_config(void)
2381{
374330e2 2382 int ret;
2383
2384 get_sesslist(TRUE);
6584031a 2385 savedsession[0] = '\0';
32874aea 2386 ret =
2387 DialogBox(hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
374330e2 2388 get_sesslist(FALSE);
2389
2390 return ret;
2391}
2392
32874aea 2393int do_reconfig(HWND hwnd)
2394{
374330e2 2395 Config backup_cfg;
2396 int ret;
2397
2398 backup_cfg = cfg; /* structure copy */
32874aea 2399 ret =
2400 DialogBox(hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
374330e2 2401 if (!ret)
2402 cfg = backup_cfg; /* structure copy */
c9def1b8 2403
374330e2 2404 return ret;
2405}
2406
32874aea 2407void logevent(char *string)
2408{
71346075 2409 char timebuf[40];
2410 time_t t;
2411
c5e9c988 2412 if (nevents >= negsize) {
374330e2 2413 negsize += 64;
32874aea 2414 events = srealloc(events, negsize * sizeof(*events));
374330e2 2415 }
71346075 2416
2417 time(&t);
32874aea 2418 strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S\t",
2419 localtime(&t));
71346075 2420
32874aea 2421 events[nevents] = smalloc(strlen(timebuf) + strlen(string) + 1);
71346075 2422 strcpy(events[nevents], timebuf);
2423 strcat(events[nevents], string);
9ad90448 2424 if (logbox) {
32874aea 2425 int count;
2426 SendDlgItemMessage(logbox, IDN_LIST, LB_ADDSTRING,
2427 0, (LPARAM) events[nevents]);
2428 count = SendDlgItemMessage(logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2429 SendDlgItemMessage(logbox, IDN_LIST, LB_SETTOPINDEX, count - 1, 0);
9ad90448 2430 }
bce816e7 2431 nevents++;
374330e2 2432}
2433
32874aea 2434void showeventlog(HWND hwnd)
2435{
374330e2 2436 if (!logbox) {
32874aea 2437 logbox = CreateDialog(hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2438 hwnd, LogProc);
2439 ShowWindow(logbox, SW_SHOWNORMAL);
374330e2 2440 }
9ecf8e5a 2441 SetActiveWindow(logbox);
374330e2 2442}
2443
32874aea 2444void showabout(HWND hwnd)
2445{
2446 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwnd, AboutProc);
374330e2 2447}
2448
d4857987 2449void verify_ssh_host_key(char *host, int port, char *keytype,
32874aea 2450 char *keystr, char *fingerprint)
2451{
d5859615 2452 int ret;
374330e2 2453
d5859615 2454 static const char absentmsg[] =
32874aea 2455 "The server's host key is not cached in the registry. You\n"
2456 "have no guarantee that the server is the computer you\n"
2457 "think it is.\n"
2458 "The server's key fingerprint is:\n"
2459 "%s\n"
2460 "If you trust this host, hit Yes to add the key to\n"
2461 "PuTTY's cache and carry on connecting.\n"
2462 "If you do not trust this host, hit No to abandon the\n"
2463 "connection.\n";
d5859615 2464
2465 static const char wrongmsg[] =
32874aea 2466 "WARNING - POTENTIAL SECURITY BREACH!\n"
2467 "\n"
2468 "The server's host key does not match the one PuTTY has\n"
2469 "cached in the registry. This means that either the\n"
2470 "server administrator has changed the host key, or you\n"
2471 "have actually connected to another computer pretending\n"
2472 "to be the server.\n"
2473 "The new key fingerprint is:\n"
2474 "%s\n"
2475 "If you were expecting this change and trust the new key,\n"
2476 "hit Yes to update PuTTY's cache and continue connecting.\n"
2477 "If you want to carry on connecting but without updating\n"
2478 "the cache, hit No.\n"
2479 "If you want to abandon the connection completely, hit\n"
2480 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n" "choice.\n";
d5859615 2481
2482 static const char mbtitle[] = "PuTTY Security Alert";
de3df031 2483
32874aea 2484
2485 char message[160 +
2486 /* sensible fingerprint max size */
2487 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2488 sizeof(absentmsg) : sizeof(wrongmsg))];
de3df031 2489
2490 /*
d5859615 2491 * Verify the key against the registry.
de3df031 2492 */
d4857987 2493 ret = verify_host_key(host, port, keytype, keystr);
d5859615 2494
32874aea 2495 if (ret == 0) /* success - key matched OK */
2496 return;
2497 if (ret == 2) { /* key was different */
2498 int mbret;
2499 sprintf(message, wrongmsg, fingerprint);
2500 mbret = MessageBox(NULL, message, mbtitle,
2501 MB_ICONWARNING | MB_YESNOCANCEL);
2502 if (mbret == IDYES)
2503 store_host_key(host, port, keytype, keystr);
2504 if (mbret == IDCANCEL)
2505 exit(0);
de3df031 2506 }
32874aea 2507 if (ret == 1) { /* key was absent */
2508 int mbret;
2509 sprintf(message, absentmsg, fingerprint);
2510 mbret = MessageBox(NULL, message, mbtitle,
2511 MB_ICONWARNING | MB_YESNO);
2512 if (mbret == IDNO)
2513 exit(0);
2514 store_host_key(host, port, keytype, keystr);
de3df031 2515 }
de3df031 2516}
e1c8e0ed 2517
2518/*
2519 * Ask whether to wipe a session log file before writing to it.
2520 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2521 */
32874aea 2522int askappend(char *filename)
2523{
e1c8e0ed 2524 static const char mbtitle[] = "PuTTY Log to File";
2525 static const char msgtemplate[] =
2526 "The session log file \"%.*s\" already exists.\n"
2527 "You can overwrite it with a new session log,\n"
2528 "append your session log to the end of it,\n"
2529 "or disable session logging for this session.\n"
2530 "Hit Yes to wipe the file, No to append to it,\n"
2531 "or Cancel to disable logging.";
2532 char message[sizeof(msgtemplate) + FILENAME_MAX];
2533 int mbret;
32874aea 2534 if (cfg.logxfovr != LGXF_ASK) {
2535 return ((cfg.logxfovr == LGXF_OVR) ? 2 : 1);
9f89f96e 2536 }
e1c8e0ed 2537 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2538
2539 mbret = MessageBox(NULL, message, mbtitle,
32874aea 2540 MB_ICONQUESTION | MB_YESNOCANCEL);
e1c8e0ed 2541 if (mbret == IDYES)
2542 return 2;
2543 else if (mbret == IDNO)
2544 return 1;
2545 else
2546 return 0;
2547}