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