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