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