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