Bring the SSH2 channel architecture up to scratch, enabling X
[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>
6
374330e2 7#include "ssh.h"
bea1ef5f 8#include "putty.h"
8c3cd914 9#include "winstuff.h"
374330e2 10#include "win_res.h"
d5859615 11#include "storage.h"
374330e2 12
c5e9c988 13static char **events = NULL;
14static int nevents = 0, negsize = 0;
15
374330e2 16static HWND logbox = NULL, abtbox = NULL;
17
1cd246bb 18static int readytogo;
19
3da0b1d2 20void force_normal(HWND hwnd)
c9def1b8 21{
a9422f39 22 static int recurse = 0;
c9def1b8 23
24 WINDOWPLACEMENT wp;
25
26 if(recurse) return;
27 recurse = 1;
28
29 wp.length = sizeof(wp);
3da0b1d2 30 if (GetWindowPlacement(hwnd, &wp) && wp.showCmd == SW_SHOWMAXIMIZED)
c9def1b8 31 {
32 wp.showCmd = SW_SHOWNORMAL;
33 SetWindowPlacement(hwnd, &wp);
34 }
35 recurse = 0;
36}
37
374330e2 38static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
39 BOOL ok;
40 int n;
41 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
42 if (ok)
43 *result = n;
44}
45
46static int CALLBACK LogProc (HWND hwnd, UINT msg,
47 WPARAM wParam, LPARAM lParam) {
48 int i;
49
50 switch (msg) {
51 case WM_INITDIALOG:
c5e9c988 52 for (i=0; i<nevents; i++)
374330e2 53 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
c5e9c988 54 0, (LPARAM)events[i]);
374330e2 55 return 1;
374330e2 56 case WM_COMMAND:
57 switch (LOWORD(wParam)) {
58 case IDOK:
59 logbox = NULL;
60 DestroyWindow (hwnd);
61 return 0;
989b10e9 62 case IDN_COPY:
63 if (HIWORD(wParam) == BN_CLICKED ||
64 HIWORD(wParam) == BN_DOUBLECLICKED) {
65 int selcount;
66 int *selitems;
67 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
68 LB_GETSELCOUNT, 0, 0);
dcbde236 69 selitems = smalloc(selcount * sizeof(int));
989b10e9 70 if (selitems) {
71 int count = SendDlgItemMessage(hwnd, IDN_LIST,
72 LB_GETSELITEMS,
73 selcount, (LPARAM)selitems);
74 int i;
75 int size;
76 char *clipdata;
77 static unsigned char sel_nl[] = SEL_NL;
78
f0df44da 79 if (count == 0) { /* can't copy zero stuff */
80 MessageBeep(0);
81 break;
82 }
83
989b10e9 84 size = 0;
85 for (i = 0; i < count; i++)
86 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
87
dcbde236 88 clipdata = smalloc(size);
989b10e9 89 if (clipdata) {
90 char *p = clipdata;
91 for (i = 0; i < count; i++) {
92 char *q = events[selitems[i]];
93 int qlen = strlen(q);
94 memcpy(p, q, qlen);
95 p += qlen;
96 memcpy(p, sel_nl, sizeof(sel_nl));
97 p += sizeof(sel_nl);
98 }
f0df44da 99 write_clip(clipdata, size, TRUE);
dcbde236 100 sfree(clipdata);
989b10e9 101 }
dcbde236 102 sfree(selitems);
f0df44da 103
104 for (i = 0; i < nevents; i++)
105 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
106 FALSE, i);
989b10e9 107 }
108 }
109 return 0;
374330e2 110 }
111 return 0;
112 case WM_CLOSE:
113 logbox = NULL;
114 DestroyWindow (hwnd);
115 return 0;
116 }
117 return 0;
118}
119
d57835ab 120static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
121 WPARAM wParam, LPARAM lParam) {
122 switch (msg) {
123 case WM_INITDIALOG:
124 return 1;
125 case WM_COMMAND:
126 switch (LOWORD(wParam)) {
127 case IDOK:
97749503 128 EndDialog(hwnd, 1);
d57835ab 129 return 0;
130 }
131 return 0;
132 case WM_CLOSE:
97749503 133 EndDialog(hwnd, 1);
d57835ab 134 return 0;
135 }
136 return 0;
137}
138
374330e2 139static int CALLBACK AboutProc (HWND hwnd, UINT msg,
140 WPARAM wParam, LPARAM lParam) {
141 switch (msg) {
142 case WM_INITDIALOG:
067a15ea 143 SetDlgItemText (hwnd, IDA_VERSION, ver);
374330e2 144 return 1;
374330e2 145 case WM_COMMAND:
146 switch (LOWORD(wParam)) {
147 case IDOK:
148 abtbox = NULL;
149 DestroyWindow (hwnd);
150 return 0;
151 case IDA_LICENCE:
152 EnableWindow(hwnd, 0);
153 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
d57835ab 154 NULL, LicenceProc);
374330e2 155 EnableWindow(hwnd, 1);
9a70ac47 156 SetActiveWindow(hwnd);
374330e2 157 return 0;
158 }
159 return 0;
160 case WM_CLOSE:
161 abtbox = NULL;
162 DestroyWindow (hwnd);
163 return 0;
164 }
165 return 0;
166}
167
301b66db 168/*
169 * Null dialog procedure.
170 */
171static int CALLBACK NullDlgProc (HWND hwnd, UINT msg,
172 WPARAM wParam, LPARAM lParam) {
173 return 0;
174}
175
c96a8fef 176static char savedsession[2048];
177
927d4fc5 178enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
179
180 sessionpanelstart,
181 IDC_TITLE_SESSION,
182 IDC_BOX_SESSION1, IDC_BOXT_SESSION1,
183 IDC_BOX_SESSION2, IDC_BOXT_SESSION2,
184 IDC_BOX_SESSION3,
185 IDC_HOSTSTATIC,
186 IDC_HOST,
187 IDC_PORTSTATIC,
188 IDC_PORT,
189 IDC_PROTSTATIC,
190 IDC_PROTRAW,
191 IDC_PROTTELNET,
c91409da 192 IDC_PROTRLOGIN,
927d4fc5 193 IDC_PROTSSH,
194 IDC_SESSSTATIC,
195 IDC_SESSEDIT,
196 IDC_SESSLIST,
197 IDC_SESSLOAD,
198 IDC_SESSSAVE,
199 IDC_SESSDEL,
200 IDC_CLOSEEXIT,
201 sessionpanelend,
c96a8fef 202
203 keyboardpanelstart,
927d4fc5 204 IDC_TITLE_KEYBOARD,
205 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1,
206 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2,
a094ae43 207 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3,
927d4fc5 208 IDC_DELSTATIC,
209 IDC_DEL008,
210 IDC_DEL127,
211 IDC_HOMESTATIC,
212 IDC_HOMETILDE,
213 IDC_HOMERXVT,
214 IDC_FUNCSTATIC,
215 IDC_FUNCTILDE,
216 IDC_FUNCLINUX,
217 IDC_FUNCXTERM,
218 IDC_FUNCVT400,
219 IDC_KPSTATIC,
220 IDC_KPNORMAL,
221 IDC_KPAPPLIC,
222 IDC_KPNH,
b00f8b34 223 IDC_NOAPPLICK,
224 IDC_NOAPPLICC,
927d4fc5 225 IDC_CURSTATIC,
226 IDC_CURNORMAL,
227 IDC_CURAPPLIC,
a094ae43 228 IDC_COMPOSEKEY,
c96a8fef 229 keyboardpanelend,
230
231 terminalpanelstart,
927d4fc5 232 IDC_TITLE_TERMINAL,
233 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1,
e1c8e0ed 234 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2,
927d4fc5 235 IDC_WRAPMODE,
236 IDC_DECOM,
927d4fc5 237 IDC_LFHASCR,
238 IDC_BEEP,
239 IDC_BCE,
240 IDC_BLINKTEXT,
241 IDC_LDISCTERM,
e1c8e0ed 242 IDC_LSTATSTATIC,
243 IDC_LSTATOFF,
244 IDC_LSTATASCII,
245 IDC_LSTATRAW,
246 IDC_LGFSTATIC,
247 IDC_LGFEDIT,
248 IDC_LGFBUTTON,
c96a8fef 249 terminalpanelend,
250
251 windowpanelstart,
927d4fc5 252 IDC_TITLE_WINDOW,
253 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1,
254 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2,
4c4f2716 255 IDC_BOX_WINDOW3,
256 IDC_ROWSSTATIC,
257 IDC_ROWSEDIT,
258 IDC_COLSSTATIC,
259 IDC_COLSEDIT,
260 IDC_LOCKSIZE,
927d4fc5 261 IDC_SCROLLBAR,
927d4fc5 262 IDC_CLOSEWARN,
263 IDC_SAVESTATIC,
264 IDC_SAVEEDIT,
265 IDC_ALTF4,
266 IDC_ALTSPACE,
a094ae43 267 IDC_ALTONLY,
927d4fc5 268 IDC_SCROLLKEY,
a094ae43 269 IDC_SCROLLDISP,
e95edc00 270 IDC_ALWAYSONTOP,
c96a8fef 271 windowpanelend,
272
4c4f2716 273 appearancepanelstart,
274 IDC_TITLE_APPEARANCE,
275 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1,
276 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2,
277 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3,
2d3411e9 278 IDC_CURSORSTATIC,
4e30ff69 279 IDC_CURBLOCK,
280 IDC_CURUNDER,
281 IDC_CURVERT,
4c4f2716 282 IDC_BLINKCUR,
283 IDC_FONTSTATIC,
284 IDC_CHOOSEFONT,
285 IDC_WINTITLE,
286 IDC_WINEDIT,
287 IDC_WINNAME,
288 appearancepanelend,
289
927d4fc5 290 connectionpanelstart,
291 IDC_TITLE_CONNECTION,
292 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1,
293 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2,
294 IDC_TTSTATIC,
295 IDC_TTEDIT,
296 IDC_LOGSTATIC,
297 IDC_LOGEDIT,
298 IDC_PINGSTATIC,
299 IDC_PINGEDIT,
300 connectionpanelend,
301
c96a8fef 302 telnetpanelstart,
927d4fc5 303 IDC_TITLE_TELNET,
304 IDC_BOX_TELNET1, IDC_BOXT_TELNET1,
305 IDC_BOX_TELNET2, IDC_BOXT_TELNET2,
306 IDC_TSSTATIC,
307 IDC_TSEDIT,
308 IDC_ENVSTATIC,
309 IDC_VARSTATIC,
310 IDC_VAREDIT,
311 IDC_VALSTATIC,
312 IDC_VALEDIT,
313 IDC_ENVLIST,
314 IDC_ENVADD,
315 IDC_ENVREMOVE,
316 IDC_EMSTATIC,
317 IDC_EMBSD,
318 IDC_EMRFC,
c96a8fef 319 telnetpanelend,
320
c91409da 321 rloginpanelstart,
322 IDC_TITLE_RLOGIN,
323 IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1,
324 IDC_BOX_RLOGIN2, IDC_BOXT_RLOGIN2,
325 IDC_R_TSSTATIC,
326 IDC_R_TSEDIT,
327 IDC_RLLUSERSTATIC,
328 IDC_RLLUSEREDIT,
329 rloginpanelend,
330
c96a8fef 331 sshpanelstart,
927d4fc5 332 IDC_TITLE_SSH,
333 IDC_BOX_SSH1, IDC_BOXT_SSH1,
334 IDC_BOX_SSH2, IDC_BOXT_SSH2,
335 IDC_BOX_SSH3, IDC_BOXT_SSH3,
336 IDC_NOPTY,
337 IDC_CIPHERSTATIC,
338 IDC_CIPHER3DES,
339 IDC_CIPHERBLOWF,
340 IDC_CIPHERDES,
7591b9ff 341 IDC_BUGGYMAC,
927d4fc5 342 IDC_AUTHTIS,
343 IDC_PKSTATIC,
344 IDC_PKEDIT,
345 IDC_PKBUTTON,
346 IDC_SSHPROTSTATIC,
347 IDC_SSHPROT1,
348 IDC_SSHPROT2,
349 IDC_AGENTFWD,
350 IDC_CMDSTATIC,
351 IDC_CMDEDIT,
4ba9b64b 352 IDC_COMPRESS,
c96a8fef 353 sshpanelend,
354
355 selectionpanelstart,
927d4fc5 356 IDC_TITLE_SELECTION,
357 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1,
358 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2,
359 IDC_MBSTATIC,
360 IDC_MBWINDOWS,
361 IDC_MBXTERM,
362 IDC_CCSTATIC,
363 IDC_CCLIST,
364 IDC_CCSET,
365 IDC_CCSTATIC2,
366 IDC_CCEDIT,
c96a8fef 367 selectionpanelend,
368
369 colourspanelstart,
927d4fc5 370 IDC_TITLE_COLOURS,
371 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1,
372 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2,
373 IDC_BOLDCOLOUR,
374 IDC_PALETTE,
5055f918 375 IDC_COLOURSTATIC,
376 IDC_COLOURLIST,
927d4fc5 377 IDC_RSTATIC,
378 IDC_GSTATIC,
379 IDC_BSTATIC,
380 IDC_RVALUE,
381 IDC_GVALUE,
382 IDC_BVALUE,
383 IDC_CHANGE,
c96a8fef 384 colourspanelend,
385
386 translationpanelstart,
927d4fc5 387 IDC_TITLE_TRANSLATION,
388 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1,
389 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2,
390 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3,
391 IDC_XLATSTATIC,
392 IDC_NOXLAT,
393 IDC_KOI8WIN1251,
394 IDC_88592WIN1250,
b0faa571 395 IDC_88592CP852,
927d4fc5 396 IDC_CAPSLOCKCYR,
397 IDC_VTSTATIC,
398 IDC_VTXWINDOWS,
399 IDC_VTOEMANSI,
400 IDC_VTOEMONLY,
401 IDC_VTPOORMAN,
c96a8fef 402 translationpanelend,
403
9c964e85 404 tunnelspanelstart,
e6ace450 405 IDC_TITLE_TUNNELS,
9c964e85 406 IDC_BOX_TUNNELS, IDC_BOXT_TUNNELS,
407 IDC_X11_FORWARD,
408 IDC_X11_DISPSTATIC,
409 IDC_X11_DISPLAY,
410 tunnelspanelend,
411
c96a8fef 412 controlendvalue
413};
414
415static const char *const colours[] = {
416 "Default Foreground", "Default Bold Foreground",
417 "Default Background", "Default Bold Background",
418 "Cursor Text", "Cursor Colour",
419 "ANSI Black", "ANSI Black Bold",
420 "ANSI Red", "ANSI Red Bold",
421 "ANSI Green", "ANSI Green Bold",
422 "ANSI Yellow", "ANSI Yellow Bold",
423 "ANSI Blue", "ANSI Blue Bold",
424 "ANSI Magenta", "ANSI Magenta Bold",
425 "ANSI Cyan", "ANSI Cyan Bold",
426 "ANSI White", "ANSI White Bold"
427};
428static const int permcolour[] = {
429 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
430 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
431 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
432};
433
434static void fmtfont (char *buf) {
435 sprintf (buf, "Font: %s, ", cfg.font);
436 if (cfg.fontisbold)
437 strcat(buf, "bold, ");
438 if (cfg.fontheight == 0)
439 strcat (buf, "default height");
440 else
441 sprintf (buf+strlen(buf), "%d-%s",
442 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
443 (cfg.fontheight < 0 ? "pixel" : "point"));
444}
445
446static void init_dlg_ctrls(HWND hwnd) {
447 int i;
448 char fontstatic[256];
449
927d4fc5 450 SetDlgItemText (hwnd, IDC_HOST, cfg.host);
451 SetDlgItemText (hwnd, IDC_SESSEDIT, savedsession);
452 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
927d4fc5 453 CheckRadioButton (hwnd, IDC_PROTRAW, IDC_PROTSSH,
454 cfg.protocol==PROT_SSH ? IDC_PROTSSH :
c91409da 455 cfg.protocol==PROT_TELNET ? IDC_PROTTELNET :
456 cfg.protocol==PROT_RLOGIN ? IDC_PROTRLOGIN : IDC_PROTRAW );
927d4fc5 457 SetDlgItemInt (hwnd, IDC_PINGEDIT, cfg.ping_interval, FALSE);
458
459 CheckRadioButton (hwnd, IDC_DEL008, IDC_DEL127,
460 cfg.bksp_is_delete ? IDC_DEL127 : IDC_DEL008);
461 CheckRadioButton (hwnd, IDC_HOMETILDE, IDC_HOMERXVT,
462 cfg.rxvt_homeend ? IDC_HOMERXVT : IDC_HOMETILDE);
289a50fa 463 CheckRadioButton (hwnd, IDC_FUNCTILDE, IDC_FUNCVT400,
927d4fc5 464 cfg.funky_type == 0 ? IDC_FUNCTILDE :
465 cfg.funky_type == 1 ? IDC_FUNCLINUX :
466 cfg.funky_type == 2 ? IDC_FUNCXTERM :
467 cfg.funky_type == 3 ? IDC_FUNCVT400 :
468 IDC_FUNCTILDE );
b00f8b34 469 CheckDlgButton (hwnd, IDC_NOAPPLICC, cfg.no_applic_c);
470 CheckDlgButton (hwnd, IDC_NOAPPLICK, cfg.no_applic_k);
927d4fc5 471 CheckRadioButton (hwnd, IDC_CURNORMAL, IDC_CURAPPLIC,
472 cfg.app_cursor ? IDC_CURAPPLIC : IDC_CURNORMAL);
473 CheckRadioButton (hwnd, IDC_KPNORMAL, IDC_KPNH,
474 cfg.nethack_keypad ? IDC_KPNH :
475 cfg.app_keypad ? IDC_KPAPPLIC : IDC_KPNORMAL);
476 CheckDlgButton (hwnd, IDC_ALTF4, cfg.alt_f4);
477 CheckDlgButton (hwnd, IDC_ALTSPACE, cfg.alt_space);
a094ae43 478 CheckDlgButton (hwnd, IDC_ALTONLY, cfg.alt_only);
479 CheckDlgButton (hwnd, IDC_COMPOSEKEY, cfg.compose_key);
927d4fc5 480 CheckDlgButton (hwnd, IDC_LDISCTERM, cfg.ldisc_term);
e95edc00 481 CheckDlgButton (hwnd, IDC_ALWAYSONTOP, cfg.alwaysontop);
927d4fc5 482 CheckDlgButton (hwnd, IDC_SCROLLKEY, cfg.scroll_on_key);
a094ae43 483 CheckDlgButton (hwnd, IDC_SCROLLDISP, cfg.scroll_on_disp);
927d4fc5 484
485 CheckDlgButton (hwnd, IDC_WRAPMODE, cfg.wrap_mode);
486 CheckDlgButton (hwnd, IDC_DECOM, cfg.dec_om);
487 CheckDlgButton (hwnd, IDC_LFHASCR, cfg.lfhascr);
488 SetDlgItemInt (hwnd, IDC_ROWSEDIT, cfg.height, FALSE);
489 SetDlgItemInt (hwnd, IDC_COLSEDIT, cfg.width, FALSE);
490 SetDlgItemInt (hwnd, IDC_SAVEEDIT, cfg.savelines, FALSE);
c96a8fef 491 fmtfont (fontstatic);
927d4fc5 492 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
493 CheckDlgButton (hwnd, IDC_BEEP, cfg.beep);
494 CheckDlgButton (hwnd, IDC_BCE, cfg.bce);
495 CheckDlgButton (hwnd, IDC_BLINKTEXT, cfg.blinktext);
496
497 SetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle);
498 CheckDlgButton (hwnd, IDC_WINNAME, cfg.win_name_always);
4e30ff69 499 CheckRadioButton (hwnd, IDC_CURBLOCK, IDC_CURVERT,
500 cfg.cursor_type==0 ? IDC_CURBLOCK :
501 cfg.cursor_type==1 ? IDC_CURUNDER : IDC_CURVERT);
927d4fc5 502 CheckDlgButton (hwnd, IDC_BLINKCUR, cfg.blink_cur);
503 CheckDlgButton (hwnd, IDC_SCROLLBAR, cfg.scrollbar);
504 CheckDlgButton (hwnd, IDC_LOCKSIZE, cfg.locksize);
505 CheckDlgButton (hwnd, IDC_CLOSEEXIT, cfg.close_on_exit);
506 CheckDlgButton (hwnd, IDC_CLOSEWARN, cfg.warn_on_close);
507
508 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
509 SetDlgItemText (hwnd, IDC_TSEDIT, cfg.termspeed);
c91409da 510 SetDlgItemText (hwnd, IDC_R_TSEDIT, cfg.termspeed);
511 SetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername);
927d4fc5 512 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
e1c8e0ed 513 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename);
514 CheckRadioButton(hwnd, IDC_LSTATOFF, IDC_LSTATRAW,
515 cfg.logtype == 0 ? IDC_LSTATOFF :
516 cfg.logtype == 1 ? IDC_LSTATASCII :
517 IDC_LSTATRAW);
c96a8fef 518 {
519 char *p = cfg.environmt;
520 while (*p) {
927d4fc5 521 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING, 0,
c96a8fef 522 (LPARAM) p);
523 p += strlen(p)+1;
524 }
374330e2 525 }
927d4fc5 526 CheckRadioButton (hwnd, IDC_EMBSD, IDC_EMRFC,
527 cfg.rfc_environ ? IDC_EMRFC : IDC_EMBSD);
528
529 SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
530 SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
531 CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
4ba9b64b 532 CheckDlgButton (hwnd, IDC_COMPRESS, cfg.compression);
7591b9ff 533 CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
927d4fc5 534 CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
535 CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
536 cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
537 cfg.cipher == CIPHER_DES ? IDC_CIPHERDES :
538 IDC_CIPHER3DES);
539 CheckRadioButton (hwnd, IDC_SSHPROT1, IDC_SSHPROT2,
540 cfg.sshprot == 1 ? IDC_SSHPROT1 : IDC_SSHPROT2);
541 CheckDlgButton (hwnd, IDC_AUTHTIS, cfg.try_tis_auth);
542 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
543 SetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd);
544
545 CheckRadioButton (hwnd, IDC_MBWINDOWS, IDC_MBXTERM,
546 cfg.mouse_is_xterm ? IDC_MBXTERM : IDC_MBWINDOWS);
c96a8fef 547 {
548 static int tabs[4] = {25, 61, 96, 128};
927d4fc5 549 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_SETTABSTOPS, 4,
c96a8fef 550 (LPARAM) tabs);
551 }
552 for (i=0; i<256; i++) {
553 char str[100];
554 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
555 (i>=0x21 && i != 0x7F) ? i : ' ',
556 cfg.wordness[i]);
927d4fc5 557 SendDlgItemMessage (hwnd, IDC_CCLIST, LB_ADDSTRING, 0,
c96a8fef 558 (LPARAM) str);
559 }
560
927d4fc5 561 CheckDlgButton (hwnd, IDC_BOLDCOLOUR, cfg.bold_colour);
562 CheckDlgButton (hwnd, IDC_PALETTE, cfg.try_palette);
c96a8fef 563 {
2ceb950f 564 int i, n;
565 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
566 for (i=n; i-- >0 ;)
567 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
568 LB_DELETESTRING, i, 0);
c96a8fef 569 for (i=0; i<22; i++)
570 if (cfg.bold_colour || permcolour[i])
5055f918 571 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_ADDSTRING, 0,
c96a8fef 572 (LPARAM) colours[i]);
573 }
5055f918 574 SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_SETCURSEL, 0, 0);
927d4fc5 575 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[0][0], FALSE);
576 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[0][1], FALSE);
577 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[0][2], FALSE);
578
b0faa571 579 CheckRadioButton (hwnd, IDC_NOXLAT, IDC_88592CP852,
927d4fc5 580 cfg.xlat_88592w1250 ? IDC_88592WIN1250 :
b0faa571 581 cfg.xlat_88592cp852 ? IDC_88592CP852 :
927d4fc5 582 cfg.xlat_enablekoiwin ? IDC_KOI8WIN1251 :
583 IDC_NOXLAT);
584 CheckDlgButton (hwnd, IDC_CAPSLOCKCYR, cfg.xlat_capslockcyr);
585 CheckRadioButton (hwnd, IDC_VTXWINDOWS, IDC_VTPOORMAN,
586 cfg.vtmode == VT_XWINDOWS ? IDC_VTXWINDOWS :
587 cfg.vtmode == VT_OEMANSI ? IDC_VTOEMANSI :
588 cfg.vtmode == VT_OEMONLY ? IDC_VTOEMONLY :
589 IDC_VTPOORMAN);
9c964e85 590
591 CheckDlgButton (hwnd, IDC_X11_FORWARD, cfg.x11_forward);
592 SetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display);
374330e2 593}
594
c96a8fef 595static void hide(HWND hwnd, int hide, int minid, int maxid) {
596 int i;
597 for (i = minid; i < maxid; i++) {
598 HWND ctl = GetDlgItem(hwnd, i);
599 if (ctl) {
f419e492 600 if (!hide)
601 EnableWindow(ctl, 1);
c96a8fef 602 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
f419e492 603 if (hide)
604 EnableWindow(ctl, 0);
c96a8fef 605 }
606 }
607}
6584031a 608
927d4fc5 609struct treeview_faff {
610 HWND treeview;
611 HTREEITEM lastat[4];
612};
613
614static HTREEITEM treeview_insert(struct treeview_faff *faff,
615 int level, char *text) {
616 TVINSERTSTRUCT ins;
617 int i;
618 HTREEITEM newitem;
619 ins.hParent = (level > 0 ? faff->lastat[level-1] : TVI_ROOT);
620 ins.hInsertAfter = faff->lastat[level];
06a03685 621#if _WIN32_IE >= 0x0400 && defined NONAMELESSUNION
622#define INSITEM DUMMYUNIONNAME.item
623#else
624#define INSITEM item
625#endif
626 ins.INSITEM.mask = TVIF_TEXT;
627 ins.INSITEM.pszText = text;
927d4fc5 628 newitem = TreeView_InsertItem(faff->treeview, &ins);
629 if (level > 0)
630 TreeView_Expand(faff->treeview, faff->lastat[level-1], TVE_EXPAND);
631 faff->lastat[level] = newitem;
632 for (i = level+1; i < 4; i++) faff->lastat[i] = NULL;
633 return newitem;
634}
635
c96a8fef 636/*
637 * This _huge_ function is the configuration box.
638 */
639static int GenericMainDlgProc (HWND hwnd, UINT msg,
640 WPARAM wParam, LPARAM lParam,
641 int dlgtype) {
927d4fc5 642 HWND hw, treeview;
643 struct treeview_faff tvfaff;
644 HTREEITEM hsession;
c96a8fef 645 OPENFILENAME of;
646 char filename[sizeof(cfg.keyfile)];
647 CHOOSEFONT cf;
648 LOGFONT lf;
649 char fontstatic[256];
b278b14a 650 char portname[32];
651 struct servent * service;
374330e2 652 int i;
653
654 switch (msg) {
655 case WM_INITDIALOG:
a094ae43 656 readytogo = 0;
c96a8fef 657 SetWindowLong(hwnd, GWL_USERDATA, 0);
658 /*
659 * Centre the window.
660 */
661 { /* centre the window */
662 RECT rs, rd;
663
664 hw = GetDesktopWindow();
665 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
666 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
667 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
668 rd.right-rd.left, rd.bottom-rd.top, TRUE);
669 }
670
671 /*
927d4fc5 672 * Create the tree view.
c96a8fef 673 */
674 {
675 RECT r;
676 WPARAM font;
927d4fc5 677 HWND tvstatic;
c96a8fef 678
927d4fc5 679 r.left = 3; r.right = r.left + 75;
680 r.top = 3; r.bottom = r.top + 10;
c96a8fef 681 MapDialogRect(hwnd, &r);
927d4fc5 682 tvstatic = CreateWindowEx(0, "STATIC", "Cate&gory:",
683 WS_CHILD | WS_VISIBLE,
684 r.left, r.top,
685 r.right-r.left, r.bottom-r.top,
686 hwnd, (HMENU)IDCX_TVSTATIC, hinst, NULL);
c96a8fef 687 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
927d4fc5 688 SendMessage(tvstatic, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
689
690 r.left = 3; r.right = r.left + 75;
4ba9b64b 691 r.top = 13; r.bottom = r.top + 206;
927d4fc5 692 MapDialogRect(hwnd, &r);
693 treeview = CreateWindowEx(WS_EX_CLIENTEDGE, WC_TREEVIEW, "",
694 WS_CHILD | WS_VISIBLE |
695 WS_TABSTOP | TVS_HASLINES |
696 TVS_DISABLEDRAGDROP | TVS_HASBUTTONS |
697 TVS_LINESATROOT | TVS_SHOWSELALWAYS,
698 r.left, r.top,
699 r.right-r.left, r.bottom-r.top,
700 hwnd, (HMENU)IDCX_TREEVIEW, hinst, NULL);
701 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
702 SendMessage(treeview, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
703 tvfaff.treeview = treeview;
704 memset(tvfaff.lastat, 0, sizeof(tvfaff.lastat));
c96a8fef 705 }
706
707 /*
708 * Create the various panelfuls of controls.
709 */
710
927d4fc5 711 /* The Session panel. Accelerators used: [acgo] nprthelsdx */
c96a8fef 712 {
713 struct ctlpos cp;
927d4fc5 714 ctlposinit(&cp, hwnd, 80, 3, 13);
715 bartitle(&cp, "Basic options for your PuTTY session",
716 IDC_TITLE_SESSION);
c96a8fef 717 if (dlgtype == 0) {
927d4fc5 718 beginbox(&cp, "Specify your connection by host name",
719 IDC_BOX_SESSION1, IDC_BOXT_SESSION1);
c96a8fef 720 multiedit(&cp,
927d4fc5 721 "Host &Name", IDC_HOSTSTATIC, IDC_HOST, 75,
722 "&Port", IDC_PORTSTATIC, IDC_PORT, 25, NULL);
d8b5ade0 723 if (backends[3].backend == NULL) {
c96a8fef 724 /* this is PuTTYtel, so only two protocols available */
c91409da 725 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
927d4fc5 726 "&Raw", IDC_PROTRAW,
c91409da 727 "&Telnet", IDC_PROTTELNET,
728 "R&login", IDC_PROTRLOGIN, NULL);
c96a8fef 729 } else {
c91409da 730 radioline(&cp, "Protocol:", IDC_PROTSTATIC, 4,
927d4fc5 731 "&Raw", IDC_PROTRAW,
732 "&Telnet", IDC_PROTTELNET,
c91409da 733 "R&login", IDC_PROTRLOGIN,
d4dcbf56 734#ifdef FWHACK
c96a8fef 735 "SS&H/hack",
d4dcbf56 736#else
c96a8fef 737 "SS&H",
d4dcbf56 738#endif
927d4fc5 739 IDC_PROTSSH, NULL);
c96a8fef 740 }
927d4fc5 741 endbox(&cp);
742 beginbox(&cp, "Load, save or delete a stored session",
743 IDC_BOX_SESSION2, IDC_BOXT_SESSION2);
a1594e4b 744 sesssaver(&cp, "Sav&ed Sessions",
927d4fc5 745 IDC_SESSSTATIC, IDC_SESSEDIT, IDC_SESSLIST,
746 "&Load", IDC_SESSLOAD,
747 "&Save", IDC_SESSSAVE,
748 "&Delete", IDC_SESSDEL, NULL);
749 endbox(&cp);
c96a8fef 750 }
927d4fc5 751 beginbox(&cp, NULL, IDC_BOX_SESSION3, 0);
752 checkbox(&cp, "Close Window on E&xit", IDC_CLOSEEXIT);
753 endbox(&cp);
c96a8fef 754
927d4fc5 755 hsession = treeview_insert(&tvfaff, 0, "Session");
c96a8fef 756 }
757
e1c8e0ed 758 /* The Terminal panel. Accelerators used: [acgo] &dflbenuw */
c96a8fef 759 {
760 struct ctlpos cp;
927d4fc5 761 ctlposinit(&cp, hwnd, 80, 3, 13);
762 bartitle(&cp, "Options controlling the terminal emulation",
763 IDC_TITLE_TERMINAL);
927d4fc5 764 beginbox(&cp, "Set various terminal options",
4c4f2716 765 IDC_BOX_TERMINAL1, IDC_BOXT_TERMINAL1);
927d4fc5 766 checkbox(&cp, "Auto &wrap mode initially on", IDC_WRAPMODE);
767 checkbox(&cp, "&DEC Origin Mode initially on", IDC_DECOM);
768 checkbox(&cp, "Implicit CR in every &LF", IDC_LFHASCR);
769 checkbox(&cp, "&Beep enabled", IDC_BEEP);
770 checkbox(&cp, "Use background colour to &erase screen", IDC_BCE);
771 checkbox(&cp, "Enable bli&nking text", IDC_BLINKTEXT);
e95edc00 772 checkbox(&cp, "&Use local terminal line discipline", IDC_LDISCTERM);
927d4fc5 773 endbox(&cp);
774
e1c8e0ed 775 beginbox(&cp, "Control session logging",
776 IDC_BOX_TERMINAL2, IDC_BOXT_TERMINAL2);
777 radiobig(&cp,
778 "Session logging:", IDC_LSTATSTATIC,
779 "Logging turned &off completely", IDC_LSTATOFF,
780 "Log printable output only", IDC_LSTATASCII,
781 "Log all session output", IDC_LSTATRAW, NULL);
782 editbutton(&cp, "Log &file name:",
783 IDC_LGFSTATIC, IDC_LGFEDIT, "Bro&wse...",
784 IDC_LGFBUTTON);
785 endbox(&cp);
786
927d4fc5 787 treeview_insert(&tvfaff, 0, "Terminal");
c96a8fef 788 }
789
b00f8b34 790 /* The Keyboard panel. Accelerators used: [acgo] h?srvlxvnpmietu */
c96a8fef 791 {
792 struct ctlpos cp;
927d4fc5 793 ctlposinit(&cp, hwnd, 80, 3, 13);
794 bartitle(&cp, "Options controlling the effects of keys",
795 IDC_TITLE_KEYBOARD);
796 beginbox(&cp, "Change the sequences sent by:",
797 IDC_BOX_KEYBOARD1, IDC_BOXT_KEYBOARD1);
798 radioline(&cp, "The Backspace key", IDC_DELSTATIC, 2,
799 "Control-&H", IDC_DEL008,
800 "Control-&? (127)", IDC_DEL127, NULL);
801 radioline(&cp, "The Home and End keys", IDC_HOMESTATIC, 2,
802 "&Standard", IDC_HOMETILDE,
803 "&rxvt", IDC_HOMERXVT, NULL);
804 radioline(&cp, "The Function keys and keypad", IDC_FUNCSTATIC, 4,
8ba2df8b 805 "ESC[n&~", IDC_FUNCTILDE,
927d4fc5 806 "&Linux", IDC_FUNCLINUX,
807 "&Xterm R6", IDC_FUNCXTERM,
808 "&VT400", IDC_FUNCVT400, NULL);
809 endbox(&cp);
b1549e9e 810 beginbox(&cp, "Application keypad settings:",
927d4fc5 811 IDC_BOX_KEYBOARD2, IDC_BOXT_KEYBOARD2);
b1549e9e 812 checkbox(&cp,
b00f8b34 813 "Application c&ursor keys totally disabled",
814 IDC_NOAPPLICC);
927d4fc5 815 radioline(&cp, "Initial state of cursor keys:", IDC_CURSTATIC, 2,
816 "&Normal", IDC_CURNORMAL,
817 "A&pplication", IDC_CURAPPLIC, NULL);
b00f8b34 818 checkbox(&cp,
819 "Application ke&ypad keys totally disabled",
820 IDC_NOAPPLICK);
927d4fc5 821 radioline(&cp, "Initial state of numeric keypad:", IDC_KPSTATIC, 3,
822 "Nor&mal", IDC_KPNORMAL,
823 "Appl&ication", IDC_KPAPPLIC,
824 "N&etHack", IDC_KPNH, NULL);
825 endbox(&cp);
a094ae43 826 beginbox(&cp, "Enable extra keyboard features:",
827 IDC_BOX_KEYBOARD3, IDC_BOXT_KEYBOARD3);
828 checkbox(&cp, "Application and AltGr ac&t as Compose key",
829 IDC_COMPOSEKEY);
830 endbox(&cp);
927d4fc5 831
832 treeview_insert(&tvfaff, 1, "Keyboard");
c96a8fef 833 }
834
e95edc00 835 /* The Window panel. Accelerators used: [acgo] bsdkw4ylpt */
c96a8fef 836 {
837 struct ctlpos cp;
927d4fc5 838 ctlposinit(&cp, hwnd, 80, 3, 13);
839 bartitle(&cp, "Options controlling PuTTY's window",
840 IDC_TITLE_WINDOW);
4c4f2716 841 beginbox(&cp, "Set the size of the window",
927d4fc5 842 IDC_BOX_WINDOW1, IDC_BOXT_WINDOW1);
4c4f2716 843 multiedit(&cp,
844 "&Rows", IDC_ROWSSTATIC, IDC_ROWSEDIT, 50,
845 "Colu&mns", IDC_COLSSTATIC, IDC_COLSEDIT, 50,
846 NULL);
847 checkbox(&cp, "Loc&k window size against resizing", IDC_LOCKSIZE);
927d4fc5 848 endbox(&cp);
849 beginbox(&cp, "Control the scrollback in the window",
4c4f2716 850 IDC_BOX_WINDOW2, IDC_BOXT_WINDOW2);
927d4fc5 851 staticedit(&cp, "Lines of &scrollback",
852 IDC_SAVESTATIC, IDC_SAVEEDIT, 50);
853 checkbox(&cp, "&Display scrollbar", IDC_SCROLLBAR);
854 checkbox(&cp, "Reset scrollback on &keypress", IDC_SCROLLKEY);
a094ae43 855 checkbox(&cp, "Reset scrollback on dis&play activity",
856 IDC_SCROLLDISP);
927d4fc5 857 endbox(&cp);
4c4f2716 858 beginbox(&cp, NULL, IDC_BOX_WINDOW3, 0);
927d4fc5 859 checkbox(&cp, "&Warn before closing window", IDC_CLOSEWARN);
860 checkbox(&cp, "Window closes on ALT-F&4", IDC_ALTF4);
a094ae43 861 checkbox(&cp, "S&ystem menu appears on ALT-Space", IDC_ALTSPACE);
862 checkbox(&cp, "System menu appears on A&LT alone", IDC_ALTONLY);
e95edc00 863 checkbox(&cp, "Ensure window is always on &top", IDC_ALWAYSONTOP);
927d4fc5 864 endbox(&cp);
865
866 treeview_insert(&tvfaff, 0, "Window");
c96a8fef 867 }
868
4e30ff69 869 /* The Appearance panel. Accelerators used: [acgo] rmkhtibluv */
4c4f2716 870 {
871 struct ctlpos cp;
872 ctlposinit(&cp, hwnd, 80, 3, 13);
873 bartitle(&cp, "Options controlling PuTTY's appearance",
d7eebffd 874 IDC_TITLE_APPEARANCE);
4c4f2716 875 beginbox(&cp, "Adjust the use of the cursor",
876 IDC_BOX_APPEARANCE1, IDC_BOXT_APPEARANCE1);
2d3411e9 877 radioline(&cp, "Cursor appearance:", IDC_CURSORSTATIC, 3,
4e30ff69 878 "B&lock", IDC_CURBLOCK,
879 "&Underline", IDC_CURUNDER,
880 "&Vertical line", IDC_CURVERT,
881 NULL);
4c4f2716 882 checkbox(&cp, "Cursor &blinks", IDC_BLINKCUR);
883 endbox(&cp);
884 beginbox(&cp, "Set the font used in the terminal window",
885 IDC_BOX_APPEARANCE2, IDC_BOXT_APPEARANCE2);
886 staticbtn(&cp, "", IDC_FONTSTATIC, "C&hange...", IDC_CHOOSEFONT);
887 endbox(&cp);
888 beginbox(&cp, "Adjust the use of the window title",
889 IDC_BOX_APPEARANCE3, IDC_BOXT_APPEARANCE3);
b65d182b 890 multiedit(&cp,
891 "Window &title:", IDC_WINTITLE,
892 IDC_WINEDIT, 100, NULL);
4c4f2716 893 checkbox(&cp, "Avoid ever using &icon title", IDC_WINNAME);
894 endbox(&cp);
895
896 treeview_insert(&tvfaff, 1, "Appearance");
897 }
898
927d4fc5 899 /* The Translation panel. Accelerators used: [acgo] xbepnkis */
c96a8fef 900 {
901 struct ctlpos cp;
927d4fc5 902 ctlposinit(&cp, hwnd, 80, 3, 13);
903 bartitle(&cp, "Options controlling character set translation",
904 IDC_TITLE_TRANSLATION);
905 beginbox(&cp, "Adjust how PuTTY displays line drawing characters",
906 IDC_BOX_TRANSLATION1, IDC_BOXT_TRANSLATION1);
907 radiobig(&cp,
908 "Handling of line drawing characters:", IDC_VTSTATIC,
909 "Font has &XWindows encoding", IDC_VTXWINDOWS,
910 "Use font in &both ANSI and OEM modes", IDC_VTOEMANSI,
911 "Use font in O&EM mode only", IDC_VTOEMONLY,
912 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
913 IDC_VTPOORMAN, NULL);
914 endbox(&cp);
915 beginbox(&cp, "Enable character set translation on received data",
916 IDC_BOX_TRANSLATION2, IDC_BOXT_TRANSLATION2);
917 radiobig(&cp,
918 "Character set translation:", IDC_XLATSTATIC,
919 "&None", IDC_NOXLAT,
920 "&KOI8 / Win-1251", IDC_KOI8WIN1251,
b0faa571 921 "&ISO-8859-2 / Win-1250", IDC_88592WIN1250,
922 "&ISO-8859-2 / CP852", IDC_88592CP852, NULL);
927d4fc5 923 endbox(&cp);
924 beginbox(&cp, "Enable character set translation on input data",
925 IDC_BOX_TRANSLATION3, IDC_BOXT_TRANSLATION3);
926 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch",
927 IDC_CAPSLOCKCYR);
928 endbox(&cp);
929
930 treeview_insert(&tvfaff, 1, "Translation");
c96a8fef 931 }
932
927d4fc5 933 /* The Selection panel. Accelerators used: [acgo] wxst */
c96a8fef 934 {
935 struct ctlpos cp;
927d4fc5 936 ctlposinit(&cp, hwnd, 80, 3, 13);
937 bartitle(&cp, "Options controlling copy and paste",
938 IDC_TITLE_SELECTION);
939 beginbox(&cp, "Control which mouse button does which thing",
940 IDC_BOX_SELECTION1, IDC_BOXT_SELECTION1);
941 radiobig(&cp, "Action of mouse buttons:", IDC_MBSTATIC,
942 "&Windows (Right pastes, Middle extends)", IDC_MBWINDOWS,
943 "&xterm (Right extends, Middle pastes)", IDC_MBXTERM,
944 NULL);
945 endbox(&cp);
946 beginbox(&cp, "Control the select-one-word-at-a-time mode",
947 IDC_BOX_SELECTION2, IDC_BOXT_SELECTION2);
948 charclass(&cp, "Character classes:", IDC_CCSTATIC, IDC_CCLIST,
949 "&Set", IDC_CCSET, IDC_CCEDIT,
950 "&to class", IDC_CCSTATIC2);
951 endbox(&cp);
952
953 treeview_insert(&tvfaff, 1, "Selection");
c96a8fef 954 }
955
927d4fc5 956 /* The Colours panel. Accelerators used: [acgo] blum */
c96a8fef 957 {
958 struct ctlpos cp;
927d4fc5 959 ctlposinit(&cp, hwnd, 80, 3, 13);
960 bartitle(&cp, "Options controlling use of colours",
961 IDC_TITLE_COLOURS);
962 beginbox(&cp, "General options for colour usage",
963 IDC_BOX_COLOURS1, IDC_BOXT_COLOURS1);
964 checkbox(&cp, "&Bolded text is a different colour", IDC_BOLDCOLOUR);
965 checkbox(&cp, "Attempt to use &logical palettes", IDC_PALETTE);
966 endbox(&cp);
967 beginbox(&cp, "Adjust the precise colours PuTTY displays",
968 IDC_BOX_COLOURS2, IDC_BOXT_COLOURS2);
969 colouredit(&cp, "Select a colo&ur and then click to modify it:",
5055f918 970 IDC_COLOURSTATIC, IDC_COLOURLIST,
927d4fc5 971 "&Modify...", IDC_CHANGE,
972 "Red:", IDC_RSTATIC, IDC_RVALUE,
973 "Green:", IDC_GSTATIC, IDC_GVALUE,
974 "Blue:", IDC_BSTATIC, IDC_BVALUE, NULL);
975 endbox(&cp);
976
977 treeview_insert(&tvfaff, 1, "Colours");
c96a8fef 978 }
979
927d4fc5 980 /* The Connection panel. Accelerators used: [acgo] tuk */
981 {
982 struct ctlpos cp;
983 ctlposinit(&cp, hwnd, 80, 3, 13);
984 bartitle(&cp, "Options controlling the connection", IDC_TITLE_CONNECTION);
985 if (dlgtype == 0) {
986 beginbox(&cp, "Data to send to the server",
987 IDC_BOX_CONNECTION1, IDC_BOXT_CONNECTION1);
988 staticedit(&cp, "Terminal-&type string", IDC_TTSTATIC, IDC_TTEDIT, 50);
989 staticedit(&cp, "Auto-login &username", IDC_LOGSTATIC, IDC_LOGEDIT, 50);
990 endbox(&cp);
991 }
992 beginbox(&cp, "Sending of null packets to keep session active",
993 IDC_BOX_CONNECTION2, IDC_BOXT_CONNECTION2);
edce8e45 994 staticedit(&cp, "Seconds between &keepalives (0 to turn off)",
927d4fc5 995 IDC_PINGSTATIC, IDC_PINGEDIT, 25);
996 endbox(&cp);
997
998 treeview_insert(&tvfaff, 0, "Connection");
999 }
1000
1001 /* The Telnet panel. Accelerators used: [acgo] svldrbf */
c96a8fef 1002 {
1003 struct ctlpos cp;
927d4fc5 1004 ctlposinit(&cp, hwnd, 80, 3, 13);
1005 if (dlgtype == 0) {
1006 bartitle(&cp, "Options controlling Telnet connections", IDC_TITLE_TELNET);
1007 beginbox(&cp, "Data to send to the server",
1008 IDC_BOX_TELNET1, IDC_BOXT_TELNET1);
1009 staticedit(&cp, "Terminal-&speed string", IDC_TSSTATIC, IDC_TSEDIT, 50);
1010 envsetter(&cp, "Environment variables:", IDC_ENVSTATIC,
1011 "&Variable", IDC_VARSTATIC, IDC_VAREDIT,
1012 "Va&lue", IDC_VALSTATIC, IDC_VALEDIT,
1013 IDC_ENVLIST,
1014 "A&dd", IDC_ENVADD, "&Remove", IDC_ENVREMOVE);
1015 endbox(&cp);
1016 beginbox(&cp, "Telnet protocol adjustments",
1017 IDC_BOX_TELNET2, IDC_BOXT_TELNET2);
1018 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC_EMSTATIC, 2,
1019 "&BSD (commonplace)", IDC_EMBSD,
1020 "R&FC 1408 (unusual)", IDC_EMRFC, NULL);
1021 endbox(&cp);
1022
1023 treeview_insert(&tvfaff, 1, "Telnet");
1024 }
c96a8fef 1025 }
1026
c91409da 1027
1028 /* The Rlogin Panel */
1029 {
1030 struct ctlpos cp;
1031 ctlposinit(&cp, hwnd, 80, 3, 13);
1032 if (dlgtype == 0) {
1033 bartitle(&cp, "Options controlling Rlogin connections", IDC_TITLE_RLOGIN);
1034 beginbox(&cp, "Data to send to the server",
1035 IDC_BOX_RLOGIN1, IDC_BOXT_RLOGIN1);
1036 staticedit(&cp, "Terminal-&speed string", IDC_R_TSSTATIC, IDC_R_TSEDIT, 50);
1037 staticedit(&cp, "&Local username:", IDC_RLLUSERSTATIC, IDC_RLLUSEREDIT, 50);
1038 endbox(&cp);
1039
1040 treeview_insert(&tvfaff, 1, "Rlogin");
1041 }
1042 }
1043
927d4fc5 1044 /* The SSH panel. Accelerators used: [acgo] rmakwp123bd */
d8b5ade0 1045 if (backends[3].backend != NULL) {
c96a8fef 1046 struct ctlpos cp;
927d4fc5 1047 ctlposinit(&cp, hwnd, 80, 3, 13);
1048 if (dlgtype == 0) {
1049 bartitle(&cp, "Options controlling SSH connections", IDC_TITLE_SSH);
1050 beginbox(&cp, "Data to send to the server",
1051 IDC_BOX_SSH1, IDC_BOXT_SSH1);
1052 multiedit(&cp,
1053 "&Remote command:", IDC_CMDSTATIC, IDC_CMDEDIT, 100,
1054 NULL);
1055 endbox(&cp);
1056 beginbox(&cp, "Authentication options",
1057 IDC_BOX_SSH2, IDC_BOXT_SSH2);
1058 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1059 IDC_AUTHTIS);
1060 checkbox(&cp, "Allow &agent forwarding", IDC_AGENTFWD);
1061 editbutton(&cp, "Private &key file for authentication:",
1062 IDC_PKSTATIC, IDC_PKEDIT, "Bro&wse...", IDC_PKBUTTON);
1063 endbox(&cp);
1064 beginbox(&cp, "Protocol options",
1065 IDC_BOX_SSH3, IDC_BOXT_SSH3);
1066 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC_NOPTY);
4ba9b64b 1067 checkbox(&cp, "Enable compr&ession", IDC_COMPRESS);
927d4fc5 1068 radioline(&cp, "Preferred SSH protocol version:",
1069 IDC_SSHPROTSTATIC, 2,
1070 "&1", IDC_SSHPROT1, "&2", IDC_SSHPROT2, NULL);
1071 radioline(&cp, "Preferred encryption algorithm:", IDC_CIPHERSTATIC, 3,
1072 "&3DES", IDC_CIPHER3DES,
1073 "&Blowfish", IDC_CIPHERBLOWF,
1074 "&DES", IDC_CIPHERDES, NULL);
7591b9ff 1075 checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
1076 IDC_BUGGYMAC);
927d4fc5 1077 endbox(&cp);
1078
1079 treeview_insert(&tvfaff, 1, "SSH");
1080 }
c96a8fef 1081 }
9c964e85 1082 /* The Tunnels panel. Accelerators used: [acgo] ex */
1083 {
e6ace450 1084 struct ctlpos cp;
1085 ctlposinit(&cp, hwnd, 80, 3, 13);
9c964e85 1086 if (dlgtype == 0) {
e6ace450 1087 bartitle(&cp, "Options controlling SSH tunnelling",
1088 IDC_TITLE_TUNNELS);
1089 beginbox(&cp, "X11 forwarding options",
1090 IDC_BOX_TUNNELS, IDC_BOXT_TUNNELS);
1091 checkbox(&cp, "&Enable X11 forwarding",
1092 IDC_X11_FORWARD);
1093 multiedit(&cp, "&X display location", IDC_X11_DISPSTATIC,
1094 IDC_X11_DISPLAY, 50, NULL);
1095 endbox(&cp);
1096
1097 treeview_insert(&tvfaff, 2, "Tunnels");
9c964e85 1098 }
1099 }
c96a8fef 1100
1101 init_dlg_ctrls(hwnd);
052f07e4 1102 for (i = 0; i < nsessions; i++)
1103 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
1104 0, (LPARAM) (sessions[i]));
c96a8fef 1105
927d4fc5 1106 /*
1107 * Hide all the controls to start with.
1108 */
c96a8fef 1109 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
927d4fc5 1110
1111 /*
1112 * Put the treeview selection on to the Session panel. This
1113 * should also cause unhiding of the relevant controls.
1114 */
1115 TreeView_SelectItem(treeview, hsession);
c96a8fef 1116
1117 /*
1118 * Set focus into the first available control.
1119 */
1120 {
1121 HWND ctl;
927d4fc5 1122 ctl = GetDlgItem(hwnd, IDC_HOST);
1123 if (!ctl) ctl = GetDlgItem(hwnd, IDC_CLOSEEXIT);
c96a8fef 1124 SetFocus(ctl);
9d01fc92 1125 }
c96a8fef 1126
1127 SetWindowLong(hwnd, GWL_USERDATA, 1);
1128 return 0;
1cd246bb 1129 case WM_LBUTTONUP:
1130 /*
1131 * Button release should trigger WM_OK if there was a
1132 * previous double click on the session list.
1133 */
1134 ReleaseCapture();
1135 if (readytogo)
c96a8fef 1136 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1cd246bb 1137 break;
c96a8fef 1138 case WM_NOTIFY:
927d4fc5 1139 if (LOWORD(wParam) == IDCX_TREEVIEW &&
1140 ((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
1141 HTREEITEM i = TreeView_GetSelection(((LPNMHDR)lParam)->hwndFrom);
1142 TVITEM item;
c96a8fef 1143 char buffer[64];
927d4fc5 1144 item.hItem = i;
c96a8fef 1145 item.pszText = buffer;
1146 item.cchTextMax = sizeof(buffer);
927d4fc5 1147 item.mask = TVIF_TEXT;
1148 TreeView_GetItem(((LPNMHDR)lParam)->hwndFrom, &item);
c96a8fef 1149 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
927d4fc5 1150 if (!strcmp(buffer, "Session"))
1151 hide(hwnd, FALSE, sessionpanelstart, sessionpanelend);
c96a8fef 1152 if (!strcmp(buffer, "Keyboard"))
1153 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1154 if (!strcmp(buffer, "Terminal"))
1155 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1156 if (!strcmp(buffer, "Window"))
1157 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
4c4f2716 1158 if (!strcmp(buffer, "Appearance"))
1159 hide(hwnd, FALSE, appearancepanelstart, appearancepanelend);
9c964e85 1160 if (!strcmp(buffer, "Tunnels"))
1161 hide(hwnd, FALSE, tunnelspanelstart, tunnelspanelend);
927d4fc5 1162 if (!strcmp(buffer, "Connection"))
1163 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
c96a8fef 1164 if (!strcmp(buffer, "Telnet"))
1165 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
c91409da 1166 if (!strcmp(buffer, "Rlogin"))
1167 hide(hwnd, FALSE, rloginpanelstart, rloginpanelend);
c96a8fef 1168 if (!strcmp(buffer, "SSH"))
1169 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1170 if (!strcmp(buffer, "Selection"))
1171 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1172 if (!strcmp(buffer, "Colours"))
1173 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1174 if (!strcmp(buffer, "Translation"))
1175 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1176
1177 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1178 return 0;
1179 }
1180 break;
374330e2 1181 case WM_COMMAND:
c96a8fef 1182 /*
1183 * Only process WM_COMMAND once the dialog is fully formed.
1184 */
1185 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1186 case IDOK:
1187 if (*cfg.host)
1188 EndDialog (hwnd, 1);
1189 else
1190 MessageBeep (0);
1191 return 0;
1192 case IDCANCEL:
1193 EndDialog (hwnd, 0);
1194 return 0;
927d4fc5 1195 case IDC_PROTTELNET:
c91409da 1196 case IDC_PROTRLOGIN:
927d4fc5 1197 case IDC_PROTSSH:
1198 case IDC_PROTRAW:
374330e2 1199 if (HIWORD(wParam) == BN_CLICKED ||
1200 HIWORD(wParam) == BN_DOUBLECLICKED) {
927d4fc5 1201 int i = IsDlgButtonChecked (hwnd, IDC_PROTSSH);
1202 int j = IsDlgButtonChecked (hwnd, IDC_PROTTELNET);
c91409da 1203 int k = IsDlgButtonChecked (hwnd, IDC_PROTRLOGIN);
1204 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : k ? PROT_RLOGIN : PROT_RAW ;
1205 if ((cfg.protocol == PROT_SSH && cfg.port != 22) ||
1206 (cfg.protocol == PROT_TELNET && cfg.port != 23) ||
1207 (cfg.protocol == PROT_RLOGIN && cfg.port != 513)) {
1208 cfg.port = i ? 22 : j ? 23 : 513;
927d4fc5 1209 SetDlgItemInt (hwnd, IDC_PORT, cfg.port, FALSE);
374330e2 1210 }
1211 }
1212 break;
927d4fc5 1213 case IDC_HOST:
374330e2 1214 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1215 GetDlgItemText (hwnd, IDC_HOST, cfg.host,
374330e2 1216 sizeof(cfg.host)-1);
1217 break;
927d4fc5 1218 case IDC_PORT:
b278b14a 1219 if (HIWORD(wParam) == EN_CHANGE) {
1220 GetDlgItemText (hwnd, IDC_PORT, portname, 31);
1221 if (isdigit(portname[0]))
1222 MyGetDlgItemInt (hwnd, IDC_PORT, &cfg.port);
1223 else {
1224 service = getservbyname(portname, NULL);
1225 if (service) cfg.port = ntohs(service->s_port);
1226 else cfg.port = 0;
1227 }
1228 }
374330e2 1229 break;
927d4fc5 1230 case IDC_SESSEDIT:
6584031a 1231 if (HIWORD(wParam) == EN_CHANGE) {
927d4fc5 1232 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
374330e2 1233 (WPARAM) -1, 0);
927d4fc5 1234 GetDlgItemText (hwnd, IDC_SESSEDIT,
6584031a 1235 savedsession, sizeof(savedsession)-1);
1236 savedsession[sizeof(savedsession)-1] = '\0';
1237 }
374330e2 1238 break;
927d4fc5 1239 case IDC_SESSSAVE:
374330e2 1240 if (HIWORD(wParam) == BN_CLICKED ||
1241 HIWORD(wParam) == BN_DOUBLECLICKED) {
1242 /*
1243 * Save a session
1244 */
1245 char str[2048];
927d4fc5 1246 GetDlgItemText (hwnd, IDC_SESSEDIT, str, sizeof(str)-1);
374330e2 1247 if (!*str) {
927d4fc5 1248 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
374330e2 1249 LB_GETCURSEL, 0, 0);
1250 if (n == LB_ERR) {
1251 MessageBeep(0);
1252 break;
1253 }
1254 strcpy (str, sessions[n]);
1255 }
a9422f39 1256 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
374330e2 1257 get_sesslist (FALSE);
1258 get_sesslist (TRUE);
927d4fc5 1259 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
374330e2 1260 0, 0);
1261 for (i = 0; i < nsessions; i++)
927d4fc5 1262 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
374330e2 1263 0, (LPARAM) (sessions[i]));
927d4fc5 1264 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
374330e2 1265 (WPARAM) -1, 0);
1266 }
1267 break;
927d4fc5 1268 case IDC_SESSLIST:
1269 case IDC_SESSLOAD:
1270 if (LOWORD(wParam) == IDC_SESSLOAD &&
374330e2 1271 HIWORD(wParam) != BN_CLICKED &&
1272 HIWORD(wParam) != BN_DOUBLECLICKED)
1273 break;
927d4fc5 1274 if (LOWORD(wParam) == IDC_SESSLIST &&
374330e2 1275 HIWORD(wParam) != LBN_DBLCLK)
1276 break;
1277 {
927d4fc5 1278 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
374330e2 1279 LB_GETCURSEL, 0, 0);
57b8bf11 1280 int isdef;
374330e2 1281 if (n == LB_ERR) {
1282 MessageBeep(0);
1283 break;
1284 }
57b8bf11 1285 isdef = !strcmp(sessions[n], "Default Settings");
1286 load_settings (sessions[n], !isdef, &cfg);
c96a8fef 1287 init_dlg_ctrls(hwnd);
57b8bf11 1288 if (!isdef)
1289 SetDlgItemText(hwnd, IDC_SESSEDIT, sessions[n]);
05a90c04 1290 else
1291 SetDlgItemText(hwnd, IDC_SESSEDIT, "");
374330e2 1292 }
927d4fc5 1293 if (LOWORD(wParam) == IDC_SESSLIST) {
374330e2 1294 /*
1295 * A double-click on a saved session should
1296 * actually start the session, not just load it.
1297 * Unless it's Default Settings or some other
1298 * host-less set of saved settings.
1299 */
1cd246bb 1300 if (*cfg.host) {
1301 readytogo = TRUE;
1302 SetCapture(hwnd);
1303 }
374330e2 1304 }
1305 break;
927d4fc5 1306 case IDC_SESSDEL:
374330e2 1307 if (HIWORD(wParam) == BN_CLICKED ||
1308 HIWORD(wParam) == BN_DOUBLECLICKED) {
927d4fc5 1309 int n = SendDlgItemMessage (hwnd, IDC_SESSLIST,
374330e2 1310 LB_GETCURSEL, 0, 0);
1311 if (n == LB_ERR || n == 0) {
1312 MessageBeep(0);
1313 break;
1314 }
d1622aed 1315 del_settings(sessions[n]);
374330e2 1316 get_sesslist (FALSE);
1317 get_sesslist (TRUE);
927d4fc5 1318 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_RESETCONTENT,
374330e2 1319 0, 0);
1320 for (i = 0; i < nsessions; i++)
927d4fc5 1321 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_ADDSTRING,
374330e2 1322 0, (LPARAM) (sessions[i]));
927d4fc5 1323 SendDlgItemMessage (hwnd, IDC_SESSLIST, LB_SETCURSEL,
374330e2 1324 (WPARAM) -1, 0);
1325 }
927d4fc5 1326 case IDC_PINGEDIT:
ec55b220 1327 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1328 MyGetDlgItemInt (hwnd, IDC_PINGEDIT, &cfg.ping_interval);
ec55b220 1329 break;
927d4fc5 1330 case IDC_DEL008:
1331 case IDC_DEL127:
c96a8fef 1332 if (HIWORD(wParam) == BN_CLICKED ||
1333 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1334 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC_DEL127);
c96a8fef 1335 break;
927d4fc5 1336 case IDC_HOMETILDE:
1337 case IDC_HOMERXVT:
c96a8fef 1338 if (HIWORD(wParam) == BN_CLICKED ||
1339 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1340 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC_HOMERXVT);
c96a8fef 1341 break;
927d4fc5 1342 case IDC_FUNCXTERM:
c96a8fef 1343 if (HIWORD(wParam) == BN_CLICKED ||
1344 HIWORD(wParam) == BN_DOUBLECLICKED)
c9def1b8 1345 cfg.funky_type = 2;
c96a8fef 1346 break;
927d4fc5 1347 case IDC_FUNCVT400:
ec55b220 1348 if (HIWORD(wParam) == BN_CLICKED ||
1349 HIWORD(wParam) == BN_DOUBLECLICKED)
1350 cfg.funky_type = 3;
1351 break;
927d4fc5 1352 case IDC_FUNCTILDE:
1353 case IDC_FUNCLINUX:
c96a8fef 1354 if (HIWORD(wParam) == BN_CLICKED ||
1355 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1356 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC_FUNCLINUX);
c96a8fef 1357 break;
927d4fc5 1358 case IDC_KPNORMAL:
1359 case IDC_KPAPPLIC:
c96a8fef 1360 if (HIWORD(wParam) == BN_CLICKED ||
1361 HIWORD(wParam) == BN_DOUBLECLICKED) {
927d4fc5 1362 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC_KPAPPLIC);
c5e9c988 1363 cfg.nethack_keypad = FALSE;
c96a8fef 1364 }
1365 break;
927d4fc5 1366 case IDC_KPNH:
c96a8fef 1367 if (HIWORD(wParam) == BN_CLICKED ||
1368 HIWORD(wParam) == BN_DOUBLECLICKED) {
c5e9c988 1369 cfg.app_keypad = FALSE;
1370 cfg.nethack_keypad = TRUE;
374330e2 1371 }
c96a8fef 1372 break;
927d4fc5 1373 case IDC_CURNORMAL:
1374 case IDC_CURAPPLIC:
c96a8fef 1375 if (HIWORD(wParam) == BN_CLICKED ||
1376 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1377 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC_CURAPPLIC);
c96a8fef 1378 break;
b00f8b34 1379 case IDC_NOAPPLICC:
1380 if (HIWORD(wParam) == BN_CLICKED ||
1381 HIWORD(wParam) == BN_DOUBLECLICKED)
1382 cfg.no_applic_c = IsDlgButtonChecked (hwnd, IDC_NOAPPLICC);
1383 break;
1384 case IDC_NOAPPLICK:
b1549e9e 1385 if (HIWORD(wParam) == BN_CLICKED ||
1386 HIWORD(wParam) == BN_DOUBLECLICKED)
b00f8b34 1387 cfg.no_applic_k = IsDlgButtonChecked (hwnd, IDC_NOAPPLICK);
b1549e9e 1388 break;
927d4fc5 1389 case IDC_ALTF4:
c96a8fef 1390 if (HIWORD(wParam) == BN_CLICKED ||
1391 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1392 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC_ALTF4);
c96a8fef 1393 break;
927d4fc5 1394 case IDC_ALTSPACE:
c96a8fef 1395 if (HIWORD(wParam) == BN_CLICKED ||
1396 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1397 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC_ALTSPACE);
c96a8fef 1398 break;
a094ae43 1399 case IDC_ALTONLY:
1400 if (HIWORD(wParam) == BN_CLICKED ||
1401 HIWORD(wParam) == BN_DOUBLECLICKED)
1402 cfg.alt_only = IsDlgButtonChecked (hwnd, IDC_ALTONLY);
1403 break;
927d4fc5 1404 case IDC_LDISCTERM:
c96a8fef 1405 if (HIWORD(wParam) == BN_CLICKED ||
1406 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1407 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC_LDISCTERM);
c96a8fef 1408 break;
e95edc00 1409 case IDC_ALWAYSONTOP:
1410 if (HIWORD(wParam) == BN_CLICKED ||
1411 HIWORD(wParam) == BN_DOUBLECLICKED)
1412 cfg.alwaysontop = IsDlgButtonChecked (hwnd, IDC_ALWAYSONTOP);
1413 break;
927d4fc5 1414 case IDC_SCROLLKEY:
c96a8fef 1415 if (HIWORD(wParam) == BN_CLICKED ||
1416 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1417 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC_SCROLLKEY);
c96a8fef 1418 break;
a094ae43 1419 case IDC_SCROLLDISP:
1420 if (HIWORD(wParam) == BN_CLICKED ||
1421 HIWORD(wParam) == BN_DOUBLECLICKED)
1422 cfg.scroll_on_disp = IsDlgButtonChecked (hwnd, IDC_SCROLLDISP);
1423 break;
1424 case IDC_COMPOSEKEY:
1425 if (HIWORD(wParam) == BN_CLICKED ||
1426 HIWORD(wParam) == BN_DOUBLECLICKED)
1427 cfg.compose_key = IsDlgButtonChecked (hwnd, IDC_COMPOSEKEY);
1428 break;
927d4fc5 1429 case IDC_WRAPMODE:
374330e2 1430 if (HIWORD(wParam) == BN_CLICKED ||
1431 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1432 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC_WRAPMODE);
374330e2 1433 break;
927d4fc5 1434 case IDC_DECOM:
374330e2 1435 if (HIWORD(wParam) == BN_CLICKED ||
1436 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1437 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC_DECOM);
374330e2 1438 break;
927d4fc5 1439 case IDC_LFHASCR:
fef97f43 1440 if (HIWORD(wParam) == BN_CLICKED ||
1441 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1442 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC_LFHASCR);
fef97f43 1443 break;
927d4fc5 1444 case IDC_ROWSEDIT:
374330e2 1445 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1446 MyGetDlgItemInt (hwnd, IDC_ROWSEDIT, &cfg.height);
374330e2 1447 break;
927d4fc5 1448 case IDC_COLSEDIT:
374330e2 1449 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1450 MyGetDlgItemInt (hwnd, IDC_COLSEDIT, &cfg.width);
374330e2 1451 break;
927d4fc5 1452 case IDC_SAVEEDIT:
374330e2 1453 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1454 MyGetDlgItemInt (hwnd, IDC_SAVEEDIT, &cfg.savelines);
374330e2 1455 break;
927d4fc5 1456 case IDC_CHOOSEFONT:
374330e2 1457 lf.lfHeight = cfg.fontheight;
1458 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1459 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1460 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
14963b8f 1461 lf.lfCharSet = cfg.fontcharset;
374330e2 1462 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1463 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1464 lf.lfQuality = DEFAULT_QUALITY;
1465 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1466 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1467 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1468
1469 cf.lStructSize = sizeof(cf);
1470 cf.hwndOwner = hwnd;
1471 cf.lpLogFont = &lf;
1472 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1473 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1474
1475 if (ChooseFont (&cf)) {
1476 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1477 cfg.font[sizeof(cfg.font)-1] = '\0';
1478 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
14963b8f 1479 cfg.fontcharset = lf.lfCharSet;
374330e2 1480 cfg.fontheight = lf.lfHeight;
1481 fmtfont (fontstatic);
927d4fc5 1482 SetDlgItemText (hwnd, IDC_FONTSTATIC, fontstatic);
374330e2 1483 }
1484 break;
927d4fc5 1485 case IDC_BEEP:
c96a8fef 1486 if (HIWORD(wParam) == BN_CLICKED ||
1487 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1488 cfg.beep = IsDlgButtonChecked (hwnd, IDC_BEEP);
c96a8fef 1489 break;
927d4fc5 1490 case IDC_BLINKTEXT:
9ca5da42 1491 if (HIWORD(wParam) == BN_CLICKED ||
1492 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1493 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC_BLINKTEXT);
9ca5da42 1494 break;
927d4fc5 1495 case IDC_BCE:
c96a8fef 1496 if (HIWORD(wParam) == BN_CLICKED ||
1497 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1498 cfg.bce = IsDlgButtonChecked (hwnd, IDC_BCE);
c96a8fef 1499 break;
927d4fc5 1500 case IDC_WINNAME:
c96a8fef 1501 if (HIWORD(wParam) == BN_CLICKED ||
1502 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1503 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC_WINNAME);
c96a8fef 1504 break;
4e30ff69 1505 case IDC_CURBLOCK:
1506 if (HIWORD(wParam) == BN_CLICKED ||
1507 HIWORD(wParam) == BN_DOUBLECLICKED)
1508 cfg.cursor_type = 0;
1509 break;
1510 case IDC_CURUNDER:
1511 if (HIWORD(wParam) == BN_CLICKED ||
1512 HIWORD(wParam) == BN_DOUBLECLICKED)
1513 cfg.cursor_type = 1;
1514 break;
1515 case IDC_CURVERT:
1516 if (HIWORD(wParam) == BN_CLICKED ||
1517 HIWORD(wParam) == BN_DOUBLECLICKED)
1518 cfg.cursor_type = 2;
1519 break;
927d4fc5 1520 case IDC_BLINKCUR:
9ca5da42 1521 if (HIWORD(wParam) == BN_CLICKED ||
1522 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1523 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC_BLINKCUR);
9ca5da42 1524 break;
927d4fc5 1525 case IDC_SCROLLBAR:
9ca5da42 1526 if (HIWORD(wParam) == BN_CLICKED ||
1527 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1528 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC_SCROLLBAR);
9ca5da42 1529 break;
927d4fc5 1530 case IDC_LOCKSIZE:
9ca5da42 1531 if (HIWORD(wParam) == BN_CLICKED ||
1532 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1533 cfg.locksize = IsDlgButtonChecked (hwnd, IDC_LOCKSIZE);
9ca5da42 1534 break;
927d4fc5 1535 case IDC_WINEDIT:
9ca5da42 1536 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1537 GetDlgItemText (hwnd, IDC_WINEDIT, cfg.wintitle,
9ca5da42 1538 sizeof(cfg.wintitle)-1);
1539 break;
927d4fc5 1540 case IDC_CLOSEEXIT:
ec55b220 1541 if (HIWORD(wParam) == BN_CLICKED ||
1542 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1543 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC_CLOSEEXIT);
ec55b220 1544 break;
927d4fc5 1545 case IDC_CLOSEWARN:
ec55b220 1546 if (HIWORD(wParam) == BN_CLICKED ||
1547 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1548 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC_CLOSEWARN);
ec55b220 1549 break;
927d4fc5 1550 case IDC_TTEDIT:
374330e2 1551 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1552 GetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype,
374330e2 1553 sizeof(cfg.termtype)-1);
1554 break;
e1c8e0ed 1555 case IDC_LGFEDIT:
1556 if (HIWORD(wParam) == EN_CHANGE)
1557 GetDlgItemText (hwnd, IDC_LGFEDIT, cfg.logfilename,
1558 sizeof(cfg.logfilename)-1);
1559 break;
1560 case IDC_LGFBUTTON:
1561 memset(&of, 0, sizeof(of));
1562#ifdef OPENFILENAME_SIZE_VERSION_400
1563 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1564#else
1565 of.lStructSize = sizeof(of);
1566#endif
1567 of.hwndOwner = hwnd;
1568 of.lpstrFilter = "All Files\0*\0\0\0";
1569 of.lpstrCustomFilter = NULL;
1570 of.nFilterIndex = 1;
1571 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1572 of.nMaxFile = sizeof(filename);
1573 of.lpstrFileTitle = NULL;
1574 of.lpstrInitialDir = NULL;
1575 of.lpstrTitle = "Select session log file";
1576 of.Flags = 0;
1577 if (GetSaveFileName(&of)) {
1578 strcpy(cfg.keyfile, filename);
1579 SetDlgItemText (hwnd, IDC_LGFEDIT, cfg.keyfile);
1580 }
1581 break;
1582 case IDC_LSTATOFF:
1583 case IDC_LSTATASCII:
1584 case IDC_LSTATRAW:
1585 if (HIWORD(wParam) == BN_CLICKED ||
1586 HIWORD(wParam) == BN_DOUBLECLICKED) {
1587 if (IsDlgButtonChecked (hwnd, IDC_LSTATOFF)) cfg.logtype = 0;
1588 if (IsDlgButtonChecked (hwnd, IDC_LSTATASCII)) cfg.logtype = 1;
1589 if (IsDlgButtonChecked (hwnd, IDC_LSTATRAW)) cfg.logtype = 2;
1590 }
1591 break;
927d4fc5 1592 case IDC_TSEDIT:
c91409da 1593 case IDC_R_TSEDIT:
374330e2 1594 if (HIWORD(wParam) == EN_CHANGE)
c91409da 1595 GetDlgItemText (hwnd, LOWORD(wParam), cfg.termspeed,
374330e2 1596 sizeof(cfg.termspeed)-1);
1597 break;
927d4fc5 1598 case IDC_LOGEDIT:
1599 if (HIWORD(wParam) == EN_CHANGE)
1600 GetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username,
374330e2 1601 sizeof(cfg.username)-1);
1602 break;
c91409da 1603 case IDC_RLLUSEREDIT:
1604 if (HIWORD(wParam) == EN_CHANGE)
1605 GetDlgItemText (hwnd, IDC_RLLUSEREDIT, cfg.localusername,
1606 sizeof(cfg.localusername)-1);
1607 break;
927d4fc5 1608 case IDC_EMBSD:
1609 case IDC_EMRFC:
1610 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC_EMRFC);
374330e2 1611 break;
927d4fc5 1612 case IDC_ENVADD:
374330e2 1613 if (HIWORD(wParam) == BN_CLICKED ||
1614 HIWORD(wParam) == BN_DOUBLECLICKED) {
37508af4 1615 char str[sizeof(cfg.environmt)];
374330e2 1616 char *p;
927d4fc5 1617 GetDlgItemText (hwnd, IDC_VAREDIT, str, sizeof(str)-1);
374330e2 1618 if (!*str) {
1619 MessageBeep(0);
1620 break;
1621 }
1622 p = str + strlen(str);
1623 *p++ = '\t';
927d4fc5 1624 GetDlgItemText (hwnd, IDC_VALEDIT, p, sizeof(str)-1-(p-str));
374330e2 1625 if (!*p) {
1626 MessageBeep(0);
1627 break;
1628 }
37508af4 1629 p = cfg.environmt;
374330e2 1630 while (*p) {
1631 while (*p) p++;
1632 p++;
1633 }
37508af4 1634 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
374330e2 1635 strcpy (p, str);
1636 p[strlen(str)+1] = '\0';
927d4fc5 1637 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_ADDSTRING,
374330e2 1638 0, (LPARAM)str);
927d4fc5 1639 SetDlgItemText (hwnd, IDC_VAREDIT, "");
1640 SetDlgItemText (hwnd, IDC_VALEDIT, "");
374330e2 1641 } else {
1642 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1643 MB_OK | MB_ICONERROR);
1644 }
1645 }
1646 break;
927d4fc5 1647 case IDC_ENVREMOVE:
374330e2 1648 if (HIWORD(wParam) != BN_CLICKED &&
1649 HIWORD(wParam) != BN_DOUBLECLICKED)
1650 break;
927d4fc5 1651 i = SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_GETCURSEL, 0, 0);
374330e2 1652 if (i == LB_ERR)
1653 MessageBeep (0);
1654 else {
1655 char *p, *q;
1656
927d4fc5 1657 SendDlgItemMessage (hwnd, IDC_ENVLIST, LB_DELETESTRING,
374330e2 1658 i, 0);
37508af4 1659 p = cfg.environmt;
374330e2 1660 while (i > 0) {
1661 if (!*p)
1662 goto disaster;
1663 while (*p) p++;
1664 p++;
1665 i--;
1666 }
1667 q = p;
1668 if (!*p)
1669 goto disaster;
1670 while (*p) p++;
1671 p++;
1672 while (*p) {
1673 while (*p)
1674 *q++ = *p++;
1675 *q++ = *p++;
1676 }
1677 *q = '\0';
1678 disaster:;
1679 }
1680 break;
927d4fc5 1681 case IDC_NOPTY:
fef97f43 1682 if (HIWORD(wParam) == BN_CLICKED ||
1683 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1684 cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
fef97f43 1685 break;
4ba9b64b 1686 case IDC_COMPRESS:
1687 if (HIWORD(wParam) == BN_CLICKED ||
1688 HIWORD(wParam) == BN_DOUBLECLICKED)
1689 cfg.compression = IsDlgButtonChecked (hwnd, IDC_COMPRESS);
1690 break;
7591b9ff 1691 case IDC_BUGGYMAC:
1692 if (HIWORD(wParam) == BN_CLICKED ||
1693 HIWORD(wParam) == BN_DOUBLECLICKED)
1694 cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
1695 break;
927d4fc5 1696 case IDC_AGENTFWD:
979310f1 1697 if (HIWORD(wParam) == BN_CLICKED ||
1698 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1699 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC_AGENTFWD);
979310f1 1700 break;
927d4fc5 1701 case IDC_CIPHER3DES:
1702 case IDC_CIPHERBLOWF:
1703 case IDC_CIPHERDES:
bea1ef5f 1704 if (HIWORD(wParam) == BN_CLICKED ||
1705 HIWORD(wParam) == BN_DOUBLECLICKED) {
927d4fc5 1706 if (IsDlgButtonChecked (hwnd, IDC_CIPHER3DES))
bea1ef5f 1707 cfg.cipher = CIPHER_3DES;
927d4fc5 1708 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERBLOWF))
bea1ef5f 1709 cfg.cipher = CIPHER_BLOWFISH;
927d4fc5 1710 else if (IsDlgButtonChecked (hwnd, IDC_CIPHERDES))
9697bfd2 1711 cfg.cipher = CIPHER_DES;
bea1ef5f 1712 }
1713 break;
927d4fc5 1714 case IDC_SSHPROT1:
1715 case IDC_SSHPROT2:
adf799dd 1716 if (HIWORD(wParam) == BN_CLICKED ||
1717 HIWORD(wParam) == BN_DOUBLECLICKED) {
927d4fc5 1718 if (IsDlgButtonChecked (hwnd, IDC_SSHPROT1))
adf799dd 1719 cfg.sshprot = 1;
927d4fc5 1720 else if (IsDlgButtonChecked (hwnd, IDC_SSHPROT2))
adf799dd 1721 cfg.sshprot = 2;
1722 }
1723 break;
927d4fc5 1724 case IDC_AUTHTIS:
ccbfb941 1725 if (HIWORD(wParam) == BN_CLICKED ||
1726 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1727 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC_AUTHTIS);
ccbfb941 1728 break;
927d4fc5 1729 case IDC_PKEDIT:
7cca0d81 1730 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1731 GetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile,
7cca0d81 1732 sizeof(cfg.keyfile)-1);
1733 break;
927d4fc5 1734 case IDC_CMDEDIT:
4c73ca1f 1735 if (HIWORD(wParam) == EN_CHANGE)
927d4fc5 1736 GetDlgItemText (hwnd, IDC_CMDEDIT, cfg.remote_cmd,
4c73ca1f 1737 sizeof(cfg.remote_cmd)-1);
1738 break;
927d4fc5 1739 case IDC_PKBUTTON:
7cca0d81 1740 memset(&of, 0, sizeof(of));
1741#ifdef OPENFILENAME_SIZE_VERSION_400
1742 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1743#else
1744 of.lStructSize = sizeof(of);
1745#endif
1746 of.hwndOwner = hwnd;
1747 of.lpstrFilter = "All Files\0*\0\0\0";
1748 of.lpstrCustomFilter = NULL;
1749 of.nFilterIndex = 1;
1750 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1751 of.nMaxFile = sizeof(filename);
1752 of.lpstrFileTitle = NULL;
1753 of.lpstrInitialDir = NULL;
1754 of.lpstrTitle = "Select Public Key File";
1755 of.Flags = 0;
1756 if (GetOpenFileName(&of)) {
1757 strcpy(cfg.keyfile, filename);
927d4fc5 1758 SetDlgItemText (hwnd, IDC_PKEDIT, cfg.keyfile);
7cca0d81 1759 }
1760 break;
927d4fc5 1761 case IDC_MBWINDOWS:
1762 case IDC_MBXTERM:
1763 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC_MBXTERM);
374330e2 1764 break;
927d4fc5 1765 case IDC_CCSET:
374330e2 1766 {
1767 BOOL ok;
1768 int i;
927d4fc5 1769 int n = GetDlgItemInt (hwnd, IDC_CCEDIT, &ok, FALSE);
374330e2 1770
1771 if (!ok)
1772 MessageBeep (0);
1773 else {
1774 for (i=0; i<256; i++)
927d4fc5 1775 if (SendDlgItemMessage (hwnd, IDC_CCLIST, LB_GETSEL,
374330e2 1776 i, 0)) {
1777 char str[100];
1778 cfg.wordness[i] = n;
927d4fc5 1779 SendDlgItemMessage (hwnd, IDC_CCLIST,
374330e2 1780 LB_DELETESTRING, i, 0);
1781 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1782 (i>=0x21 && i != 0x7F) ? i : ' ',
1783 cfg.wordness[i]);
927d4fc5 1784 SendDlgItemMessage (hwnd, IDC_CCLIST,
374330e2 1785 LB_INSERTSTRING, i,
1786 (LPARAM)str);
1787 }
1788 }
1789 }
1790 break;
927d4fc5 1791 case IDC_BOLDCOLOUR:
374330e2 1792 if (HIWORD(wParam) == BN_CLICKED ||
1793 HIWORD(wParam) == BN_DOUBLECLICKED) {
1794 int n, i;
927d4fc5 1795 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC_BOLDCOLOUR);
5055f918 1796 n = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCOUNT, 0, 0);
2ceb950f 1797 if (n != 12+10*cfg.bold_colour) {
1798 for (i=n; i-- >0 ;)
1799 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
374330e2 1800 LB_DELETESTRING, i, 0);
2ceb950f 1801 for (i=0; i<22; i++)
1802 if (cfg.bold_colour || permcolour[i])
1803 SendDlgItemMessage (hwnd, IDC_COLOURLIST,
1804 LB_ADDSTRING, 0,
1805 (LPARAM) colours[i]);
374330e2 1806 }
1807 }
1808 break;
927d4fc5 1809 case IDC_PALETTE:
374330e2 1810 if (HIWORD(wParam) == BN_CLICKED ||
1811 HIWORD(wParam) == BN_DOUBLECLICKED)
927d4fc5 1812 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC_PALETTE);
374330e2 1813 break;
5055f918 1814 case IDC_COLOURLIST:
374330e2 1815 if (HIWORD(wParam) == LBN_DBLCLK ||
1816 HIWORD(wParam) == LBN_SELCHANGE) {
5055f918 1817 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
374330e2 1818 0, 0);
1819 if (!cfg.bold_colour)
1820 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
927d4fc5 1821 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0], FALSE);
1822 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1], FALSE);
1823 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2], FALSE);
374330e2 1824 }
1825 break;
927d4fc5 1826 case IDC_CHANGE:
374330e2 1827 if (HIWORD(wParam) == BN_CLICKED ||
1828 HIWORD(wParam) == BN_DOUBLECLICKED) {
1829 static CHOOSECOLOR cc;
1830 static DWORD custom[16] = {0}; /* zero initialisers */
5055f918 1831 int i = SendDlgItemMessage (hwnd, IDC_COLOURLIST, LB_GETCURSEL,
374330e2 1832 0, 0);
1833 if (!cfg.bold_colour)
1834 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1835 cc.lStructSize = sizeof(cc);
1836 cc.hwndOwner = hwnd;
1d470ad2 1837 cc.hInstance = (HWND)hinst;
374330e2 1838 cc.lpCustColors = custom;
1839 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1840 cfg.colours[i][2]);
1841 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1842 if (ChooseColor(&cc)) {
1843 cfg.colours[i][0] =
1844 (unsigned char) (cc.rgbResult & 0xFF);
1845 cfg.colours[i][1] =
1846 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1847 cfg.colours[i][2] =
1848 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
927d4fc5 1849 SetDlgItemInt (hwnd, IDC_RVALUE, cfg.colours[i][0],
374330e2 1850 FALSE);
927d4fc5 1851 SetDlgItemInt (hwnd, IDC_GVALUE, cfg.colours[i][1],
374330e2 1852 FALSE);
927d4fc5 1853 SetDlgItemInt (hwnd, IDC_BVALUE, cfg.colours[i][2],
374330e2 1854 FALSE);
1855 }
1856 }
1857 break;
927d4fc5 1858 case IDC_NOXLAT:
1859 case IDC_KOI8WIN1251:
1860 case IDC_88592WIN1250:
b0faa571 1861 case IDC_88592CP852:
d3d16feb 1862 cfg.xlat_enablekoiwin =
927d4fc5 1863 IsDlgButtonChecked (hwnd, IDC_KOI8WIN1251);
d3d16feb 1864 cfg.xlat_88592w1250 =
927d4fc5 1865 IsDlgButtonChecked (hwnd, IDC_88592WIN1250);
b0faa571 1866 cfg.xlat_88592cp852 =
1867 IsDlgButtonChecked (hwnd, IDC_88592CP852);
14963b8f 1868 break;
927d4fc5 1869 case IDC_CAPSLOCKCYR:
14963b8f 1870 if (HIWORD(wParam) == BN_CLICKED ||
1871 HIWORD(wParam) == BN_DOUBLECLICKED) {
1872 cfg.xlat_capslockcyr =
927d4fc5 1873 IsDlgButtonChecked (hwnd, IDC_CAPSLOCKCYR);
14963b8f 1874 }
1875 break;
927d4fc5 1876 case IDC_VTXWINDOWS:
1877 case IDC_VTOEMANSI:
1878 case IDC_VTOEMONLY:
1879 case IDC_VTPOORMAN:
c9def1b8 1880 cfg.vtmode =
927d4fc5 1881 (IsDlgButtonChecked (hwnd, IDC_VTXWINDOWS) ? VT_XWINDOWS :
1882 IsDlgButtonChecked (hwnd, IDC_VTOEMANSI) ? VT_OEMANSI :
1883 IsDlgButtonChecked (hwnd, IDC_VTOEMONLY) ? VT_OEMONLY :
c9def1b8 1884 VT_POORMAN);
1885 break;
9c964e85 1886 case IDC_X11_FORWARD:
1887 if (HIWORD(wParam) == BN_CLICKED ||
1888 HIWORD(wParam) == BN_DOUBLECLICKED)
1889 cfg.x11_forward = IsDlgButtonChecked (hwnd, IDC_X11_FORWARD);
1890 break;
1891 case IDC_X11_DISPLAY:
1892 if (HIWORD(wParam) == EN_CHANGE)
1893 GetDlgItemText (hwnd, IDC_X11_DISPLAY, cfg.x11_display,
1894 sizeof(cfg.x11_display)-1);
1895 break;
14963b8f 1896 }
374330e2 1897 return 0;
1898 case WM_CLOSE:
1899 EndDialog (hwnd, 0);
1900 return 0;
c9def1b8 1901
1902 /* Grrr Explorer will maximize Dialogs! */
1903 case WM_SIZE:
1904 if (wParam == SIZE_MAXIMIZED)
1905 force_normal(hwnd);
1906 return 0;
374330e2 1907 }
1908 return 0;
1909}
1910
1911static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
1912 WPARAM wParam, LPARAM lParam) {
374330e2 1913 static HWND page = NULL;
1914
1915 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
374330e2 1916 }
c96a8fef 1917 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
374330e2 1918 EnableWindow(hwnd, 0);
1919 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1920 GetParent(hwnd), AboutProc);
1921 EnableWindow(hwnd, 1);
9a70ac47 1922 SetActiveWindow(hwnd);
374330e2 1923 }
c96a8fef 1924 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
374330e2 1925}
1926
1927static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
1928 WPARAM wParam, LPARAM lParam) {
1929 static HWND page;
c96a8fef 1930 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
374330e2 1931}
1932
8c3cd914 1933void defuse_showwindow(void) {
301b66db 1934 /*
1935 * Work around the fact that the app's first call to ShowWindow
1936 * will ignore the default in favour of the shell-provided
1937 * setting.
1938 */
1939 {
1940 HWND hwnd;
1941 hwnd = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1942 NULL, NullDlgProc);
1943 ShowWindow(hwnd, SW_HIDE);
1944 DestroyWindow(hwnd);
1945 }
1946}
1947
374330e2 1948int do_config (void) {
1949 int ret;
1950
1951 get_sesslist(TRUE);
6584031a 1952 savedsession[0] = '\0';
374330e2 1953 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
1954 get_sesslist(FALSE);
1955
1956 return ret;
1957}
1958
1959int do_reconfig (HWND hwnd) {
1960 Config backup_cfg;
1961 int ret;
1962
1963 backup_cfg = cfg; /* structure copy */
1964 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
1965 if (!ret)
1966 cfg = backup_cfg; /* structure copy */
c9def1b8 1967
374330e2 1968 return ret;
1969}
1970
c5e9c988 1971void logevent (char *string) {
1972 if (nevents >= negsize) {
374330e2 1973 negsize += 64;
c5e9c988 1974 events = srealloc (events, negsize * sizeof(*events));
374330e2 1975 }
c5e9c988 1976 events[nevents] = smalloc(1+strlen(string));
1977 strcpy (events[nevents], string);
1978 nevents++;
9ad90448 1979 if (logbox) {
1980 int count;
374330e2 1981 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
1982 0, (LPARAM)string);
9ad90448 1983 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
989b10e9 1984 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
9ad90448 1985 }
374330e2 1986}
1987
c5e9c988 1988void showeventlog (HWND hwnd) {
374330e2 1989 if (!logbox) {
1990 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
1991 hwnd, LogProc);
1992 ShowWindow (logbox, SW_SHOWNORMAL);
1993 }
1994}
1995
1996void showabout (HWND hwnd) {
1997 if (!abtbox) {
1998 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
1999 hwnd, AboutProc);
2000 ShowWindow (abtbox, SW_SHOWNORMAL);
2001 }
2002}
2003
d4857987 2004void verify_ssh_host_key(char *host, int port, char *keytype,
d5859615 2005 char *keystr, char *fingerprint) {
2006 int ret;
374330e2 2007
d5859615 2008 static const char absentmsg[] =
2009 "The server's host key is not cached in the registry. You\n"
2010 "have no guarantee that the server is the computer you\n"
2011 "think it is.\n"
2012 "The server's key fingerprint is:\n"
2013 "%s\n"
2014 "If you trust this host, hit Yes to add the key to\n"
2015 "PuTTY's cache and carry on connecting.\n"
2016 "If you do not trust this host, hit No to abandon the\n"
2017 "connection.\n";
2018
2019 static const char wrongmsg[] =
2020 "WARNING - POTENTIAL SECURITY BREACH!\n"
2021 "\n"
2022 "The server's host key does not match the one PuTTY has\n"
2023 "cached in the registry. This means that either the\n"
2024 "server administrator has changed the host key, or you\n"
2025 "have actually connected to another computer pretending\n"
2026 "to be the server.\n"
2027 "The new key fingerprint is:\n"
2028 "%s\n"
2029 "If you were expecting this change and trust the new key,\n"
2030 "hit Yes to update PuTTY's cache and continue connecting.\n"
2031 "If you want to carry on connecting but without updating\n"
2032 "the cache, hit No.\n"
2033 "If you want to abandon the connection completely, hit\n"
2034 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2035 "choice.\n";
2036
2037 static const char mbtitle[] = "PuTTY Security Alert";
de3df031 2038
d5859615 2039
2040 char message[160+ /* sensible fingerprint max size */
2041 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2042 sizeof(absentmsg) : sizeof(wrongmsg))];
de3df031 2043
2044 /*
d5859615 2045 * Verify the key against the registry.
de3df031 2046 */
d4857987 2047 ret = verify_host_key(host, port, keytype, keystr);
d5859615 2048
2049 if (ret == 0) /* success - key matched OK */
2050 return;
2051 if (ret == 2) { /* key was different */
2052 int mbret;
2053 sprintf(message, wrongmsg, fingerprint);
2054 mbret = MessageBox(NULL, message, mbtitle,
2055 MB_ICONWARNING | MB_YESNOCANCEL);
2056 if (mbret == IDYES)
d4857987 2057 store_host_key(host, port, keytype, keystr);
d5859615 2058 if (mbret == IDCANCEL)
2059 exit(0);
de3df031 2060 }
d5859615 2061 if (ret == 1) { /* key was absent */
2062 int mbret;
2063 sprintf(message, absentmsg, fingerprint);
2064 mbret = MessageBox(NULL, message, mbtitle,
2065 MB_ICONWARNING | MB_YESNO);
2066 if (mbret == IDNO)
2067 exit(0);
d4857987 2068 store_host_key(host, port, keytype, keystr);
de3df031 2069 }
de3df031 2070}
e1c8e0ed 2071
2072/*
2073 * Ask whether to wipe a session log file before writing to it.
2074 * Returns 2 for wipe, 1 for append, 0 for cancel (don't log).
2075 */
2076int askappend(char *filename) {
2077 static const char mbtitle[] = "PuTTY Log to File";
2078 static const char msgtemplate[] =
2079 "The session log file \"%.*s\" already exists.\n"
2080 "You can overwrite it with a new session log,\n"
2081 "append your session log to the end of it,\n"
2082 "or disable session logging for this session.\n"
2083 "Hit Yes to wipe the file, No to append to it,\n"
2084 "or Cancel to disable logging.";
2085 char message[sizeof(msgtemplate) + FILENAME_MAX];
2086 int mbret;
2087 sprintf(message, msgtemplate, FILENAME_MAX, filename);
2088
2089 mbret = MessageBox(NULL, message, mbtitle,
2090 MB_ICONQUESTION | MB_YESNOCANCEL);
2091 if (mbret == IDYES)
2092 return 2;
2093 else if (mbret == IDNO)
2094 return 1;
2095 else
2096 return 0;
2097}