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