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