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