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