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