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