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