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