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