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