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