19 static char **events = NULL;
20 static int nevents = 0, negsize = 0;
22 static HWND logbox = NULL, abtbox = NULL;
24 static HINSTANCE hinst;
28 static void force_normal(HWND hwnd)
30 static int recurse = 0;
37 wp.length = sizeof(wp);
38 if (GetWindowPlacement(hwnd, &wp))
40 wp.showCmd = SW_SHOWNORMAL;
41 SetWindowPlacement(hwnd, &wp);
46 static void MyGetDlgItemInt (HWND hwnd, int id, int *result) {
49 n = GetDlgItemInt (hwnd, id, &ok, FALSE);
54 static int CALLBACK LogProc (HWND hwnd, UINT msg,
55 WPARAM wParam, LPARAM lParam) {
60 for (i=0; i<nevents; i++)
61 SendDlgItemMessage (hwnd, IDN_LIST, LB_ADDSTRING,
62 0, (LPARAM)events[i]);
65 switch (LOWORD(wParam)) {
71 if (HIWORD(wParam) == BN_CLICKED ||
72 HIWORD(wParam) == BN_DOUBLECLICKED) {
75 selcount = SendDlgItemMessage(hwnd, IDN_LIST,
76 LB_GETSELCOUNT, 0, 0);
77 selitems = malloc(selcount * sizeof(int));
79 int count = SendDlgItemMessage(hwnd, IDN_LIST,
81 selcount, (LPARAM)selitems);
85 static unsigned char sel_nl[] = SEL_NL;
87 if (count == 0) { /* can't copy zero stuff */
93 for (i = 0; i < count; i++)
94 size += strlen(events[selitems[i]]) + sizeof(sel_nl);
96 clipdata = malloc(size);
99 for (i = 0; i < count; i++) {
100 char *q = events[selitems[i]];
101 int qlen = strlen(q);
104 memcpy(p, sel_nl, sizeof(sel_nl));
107 write_clip(clipdata, size, TRUE);
112 for (i = 0; i < nevents; i++)
113 SendDlgItemMessage(hwnd, IDN_LIST, LB_SETSEL,
122 DestroyWindow (hwnd);
128 static int CALLBACK LicenceProc (HWND hwnd, UINT msg,
129 WPARAM wParam, LPARAM lParam) {
134 switch (LOWORD(wParam)) {
147 static int CALLBACK AboutProc (HWND hwnd, UINT msg,
148 WPARAM wParam, LPARAM lParam) {
151 SetDlgItemText (hwnd, IDA_VERSION, ver);
154 switch (LOWORD(wParam)) {
157 DestroyWindow (hwnd);
160 EnableWindow(hwnd, 0);
161 DialogBox (hinst, MAKEINTRESOURCE(IDD_LICENCEBOX),
163 EnableWindow(hwnd, 1);
164 SetActiveWindow(hwnd);
170 DestroyWindow (hwnd);
176 /* ----------------------------------------------------------------------
177 * Routines to self-manage the controls in a dialog box.
183 #define STATICHEIGHT 8
184 #define CHECKBOXHEIGHT 8
185 #define RADIOHEIGHT 8
186 #define EDITHEIGHT 12
187 #define COMBOHEIGHT 12
188 #define PUSHBTNHEIGHT 14
197 static void ctlposinit(struct ctlpos *cp, HWND hwnd,
198 int sideborder, int topborder) {
201 cp->font = SendMessage(hwnd, WM_GETFONT, 0, 0);
202 cp->ypos = GAPBETWEEN;
203 GetClientRect(hwnd, &r);
204 r2.left = r2.top = 0;
207 MapDialogRect(hwnd, &r2);
208 cp->width = (r.right * 4) / (r2.right) - 2*GAPBETWEEN;
209 cp->xoff = sideborder;
210 cp->width -= 2*sideborder;
211 cp->yoff = topborder;
214 static void doctl(struct ctlpos *cp, RECT r,
215 char *wclass, int wstyle, int exstyle,
216 char *wtext, int wid) {
219 * Note nonstandard use of RECT. This is deliberate: by
220 * transforming the width and height directly we arrange to
221 * have all supposedly same-sized controls really same-sized.
226 MapDialogRect(cp->hwnd, &r);
228 ctl = CreateWindowEx(exstyle, wclass, wtext, wstyle,
229 r.left, r.top, r.right, r.bottom,
230 cp->hwnd, (HMENU)wid, hinst, NULL);
231 SendMessage(ctl, WM_SETFONT, cp->font, MAKELPARAM(TRUE, 0));
235 * Some edit boxes. Each one has a static above it. The percentages
236 * of the horizontal space are provided.
238 static void multiedit(struct ctlpos *cp, ...) {
247 int staticid, editid, pcwidth;
248 text = va_arg(ap, char *);
251 staticid = va_arg(ap, int);
252 editid = va_arg(ap, int);
253 pcwidth = va_arg(ap, int);
255 r.left = xpos + GAPBETWEEN;
257 xpos = (cp->width + GAPBETWEEN) * percent / 100;
258 r.right = xpos - r.left;
260 r.top = cp->ypos; r.bottom = STATICHEIGHT;
261 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0,
263 r.top = cp->ypos + 8 + GAPWITHIN; r.bottom = EDITHEIGHT;
265 WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
270 cp->ypos += 8+GAPWITHIN+12+GAPBETWEEN;
274 * A set of radio buttons on the same line, with a static above
275 * them. `nacross' dictates how many parts the line is divided into
276 * (you might want this not to equal the number of buttons if you
277 * needed to line up some 2s and some 3s to look good in the same
280 static void radioline(struct ctlpos *cp,
281 char *text, int id, int nacross, ...) {
287 r.left = GAPBETWEEN; r.top = cp->ypos;
288 r.right = cp->width; r.bottom = STATICHEIGHT;
289 cp->ypos += r.bottom + GAPWITHIN;
290 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id);
291 va_start(ap, nacross);
297 btext = va_arg(ap, char *);
300 bid = va_arg(ap, int);
301 r.left = GAPBETWEEN + i * (cp->width+GAPBETWEEN)/nacross;
302 r.right = (i+1) * (cp->width+GAPBETWEEN)/nacross - r.left;
303 r.top = cp->ypos; r.bottom = RADIOHEIGHT;
304 doctl(cp, r, "BUTTON",
305 BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | group,
312 cp->ypos += r.bottom + GAPBETWEEN;
316 * A set of radio buttons on multiple lines, with a static above
319 static void radiobig(struct ctlpos *cp, char *text, int id, ...) {
324 r.left = GAPBETWEEN; r.top = cp->ypos;
325 r.right = cp->width; r.bottom = STATICHEIGHT;
326 cp->ypos += r.bottom + GAPWITHIN;
327 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, id);
333 btext = va_arg(ap, char *);
336 bid = va_arg(ap, int);
337 r.left = GAPBETWEEN; r.top = cp->ypos;
338 r.right = cp->width; r.bottom = STATICHEIGHT;
339 cp->ypos += r.bottom + GAPWITHIN;
340 doctl(cp, r, "BUTTON",
341 BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP | group,
347 cp->ypos += GAPBETWEEN - GAPWITHIN;
351 * A single standalone checkbox.
353 static void checkbox(struct ctlpos *cp, char *text, int id) {
356 r.left = GAPBETWEEN; r.top = cp->ypos;
357 r.right = cp->width; r.bottom = CHECKBOXHEIGHT;
358 cp->ypos += r.bottom + GAPBETWEEN;
359 doctl(cp, r, "BUTTON",
360 BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 0,
365 * A button on the right hand side, with a static to its left.
367 static void staticbtn(struct ctlpos *cp, char *stext, int sid,
368 char *btext, int bid) {
369 const int height = (PUSHBTNHEIGHT > STATICHEIGHT ?
370 PUSHBTNHEIGHT : STATICHEIGHT);
372 int lwid, rwid, rpos;
374 rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4;
375 lwid = rpos - 2*GAPBETWEEN;
376 rwid = cp->width + GAPBETWEEN - rpos;
378 r.left = GAPBETWEEN; r.top = cp->ypos + (height-STATICHEIGHT)/2;
379 r.right = lwid; r.bottom = STATICHEIGHT;
380 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
382 r.left = rpos; r.top = cp->ypos + (height-PUSHBTNHEIGHT)/2;
383 r.right = rwid; r.bottom = PUSHBTNHEIGHT;
384 doctl(cp, r, "BUTTON",
385 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
389 cp->ypos += height + GAPBETWEEN;
393 * An edit control on the right hand side, with a static to its left.
395 static void staticedit(struct ctlpos *cp, char *stext,
396 int sid, int eid, int percentedit) {
397 const int height = (EDITHEIGHT > STATICHEIGHT ?
398 EDITHEIGHT : STATICHEIGHT);
400 int lwid, rwid, rpos;
402 rpos = GAPBETWEEN + (100-percentedit) * (cp->width + GAPBETWEEN) / 100;
403 lwid = rpos - 2*GAPBETWEEN;
404 rwid = cp->width + GAPBETWEEN - rpos;
406 r.left = GAPBETWEEN; r.top = cp->ypos + (height-STATICHEIGHT)/2;
407 r.right = lwid; r.bottom = STATICHEIGHT;
408 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
410 r.left = rpos; r.top = cp->ypos + (height-EDITHEIGHT)/2;
411 r.right = rwid; r.bottom = EDITHEIGHT;
413 WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
417 cp->ypos += height + GAPBETWEEN;
421 * A tab-control substitute when a real tab control is unavailable.
423 static void ersatztab(struct ctlpos *cp, char *stext, int sid,
425 const int height = (COMBOHEIGHT > STATICHEIGHT ?
426 COMBOHEIGHT : STATICHEIGHT);
428 int bigwid, lwid, rwid, rpos;
429 static const int BIGGAP = 15;
430 static const int MEDGAP = 3;
432 bigwid = cp->width + 2*GAPBETWEEN - 2*BIGGAP;
434 rpos = BIGGAP + (bigwid + BIGGAP) / 2;
435 lwid = rpos - 2*BIGGAP;
436 rwid = bigwid + BIGGAP - rpos;
438 r.left = BIGGAP; r.top = cp->ypos + (height-STATICHEIGHT)/2;
439 r.right = lwid; r.bottom = STATICHEIGHT;
440 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
442 r.left = rpos; r.top = cp->ypos + (height-COMBOHEIGHT)/2;
443 r.right = rwid; r.bottom = COMBOHEIGHT*10;
444 doctl(cp, r, "COMBOBOX",
445 WS_CHILD | WS_VISIBLE | WS_TABSTOP |
446 CBS_DROPDOWNLIST | CBS_HASSTRINGS,
450 cp->ypos += height + MEDGAP + GAPBETWEEN;
452 r.left = GAPBETWEEN; r.top = cp->ypos;
453 r.right = cp->width; r.bottom = 2;
454 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_ETCHEDHORZ,
459 * A static line, followed by an edit control on the left hand side
460 * and a button on the right.
462 static void editbutton(struct ctlpos *cp, char *stext, int sid,
463 int eid, char *btext, int bid) {
464 const int height = (EDITHEIGHT > PUSHBTNHEIGHT ?
465 EDITHEIGHT : PUSHBTNHEIGHT);
467 int lwid, rwid, rpos;
469 r.left = GAPBETWEEN; r.top = cp->ypos;
470 r.right = cp->width; r.bottom = STATICHEIGHT;
471 cp->ypos += r.bottom + GAPWITHIN;
472 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
474 rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4;
475 lwid = rpos - 2*GAPBETWEEN;
476 rwid = cp->width + GAPBETWEEN - rpos;
478 r.left = GAPBETWEEN; r.top = cp->ypos + (height-EDITHEIGHT)/2;
479 r.right = lwid; r.bottom = EDITHEIGHT;
481 WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
485 r.left = rpos; r.top = cp->ypos + (height-PUSHBTNHEIGHT)/2;
486 r.right = rwid; r.bottom = PUSHBTNHEIGHT;
487 doctl(cp, r, "BUTTON",
488 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
492 cp->ypos += height + GAPBETWEEN;
496 * Special control which was hard to describe generically: the
497 * session-saver assembly. A static; below that an edit box; below
498 * that a list box. To the right of the list box, a column of
501 static void sesssaver(struct ctlpos *cp, char *text,
502 int staticid, int editid, int listid, ...) {
505 int lwid, rwid, rpos;
507 const int LISTDEFHEIGHT = 66;
509 rpos = GAPBETWEEN + 3 * (cp->width + GAPBETWEEN) / 4;
510 lwid = rpos - 2*GAPBETWEEN;
511 rwid = cp->width + GAPBETWEEN - rpos;
513 /* The static control. */
514 r.left = GAPBETWEEN; r.top = cp->ypos;
515 r.right = lwid; r.bottom = STATICHEIGHT;
516 cp->ypos += r.bottom + GAPWITHIN;
517 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, text, staticid);
519 /* The edit control. */
520 r.left = GAPBETWEEN; r.top = cp->ypos;
521 r.right = lwid; r.bottom = EDITHEIGHT;
522 cp->ypos += r.bottom + GAPWITHIN;
524 WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
529 * The buttons (we should hold off on the list box until we
530 * know how big the buttons are).
532 va_start(ap, listid);
535 char *btext = va_arg(ap, char *);
538 bid = va_arg(ap, int);
539 r.left = rpos; r.top = y;
540 r.right = rwid; r.bottom = PUSHBTNHEIGHT;
541 y += r.bottom + GAPWITHIN;
542 doctl(cp, r, "BUTTON",
543 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
548 /* Compute list box height. LISTDEFHEIGHT, or height of buttons. */
551 if (y < LISTDEFHEIGHT) y = LISTDEFHEIGHT;
552 r.left = GAPBETWEEN; r.top = cp->ypos;
553 r.right = lwid; r.bottom = y;
554 cp->ypos += y + GAPBETWEEN;
555 doctl(cp, r, "LISTBOX",
556 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL |
557 LBS_NOTIFY | LBS_HASSTRINGS,
563 * Another special control: the environment-variable setter. A
564 * static line first; then a pair of edit boxes with associated
565 * statics, and two buttons; then a list box.
567 static void envsetter(struct ctlpos *cp, char *stext, int sid,
568 char *e1stext, int e1sid, int e1id,
569 char *e2stext, int e2sid, int e2id,
571 char *b1text, int b1id, char *b2text, int b2id) {
573 const int height = (STATICHEIGHT > EDITHEIGHT && STATICHEIGHT > PUSHBTNHEIGHT ?
575 EDITHEIGHT > PUSHBTNHEIGHT ?
576 EDITHEIGHT : PUSHBTNHEIGHT);
577 const static int percents[] = { 20, 35, 10, 25 };
578 int i, j, xpos, percent;
579 const int LISTHEIGHT = 42;
581 /* The static control. */
582 r.left = GAPBETWEEN; r.top = cp->ypos;
583 r.right = cp->width; r.bottom = STATICHEIGHT;
584 cp->ypos += r.bottom + GAPWITHIN;
585 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
587 /* The statics+edits+buttons. */
588 for (j = 0; j < 2; j++) {
590 for (i = 0; i < 4; i++) {
591 xpos = (cp->width + GAPBETWEEN) * percent / 100;
592 r.left = xpos + GAPBETWEEN;
593 percent += percents[i];
594 xpos = (cp->width + GAPBETWEEN) * percent / 100;
595 r.right = xpos - r.left;
597 r.bottom = (i==0 ? STATICHEIGHT :
600 r.top += (height-r.bottom)/2;
602 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0,
603 j==0 ? e1stext : e2stext, j==0 ? e1sid : e2sid);
606 WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
608 "", j==0 ? e1id : e2id);
610 doctl(cp, r, "BUTTON",
611 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
613 j==0 ? b1text : b2text, j==0 ? b1id : b2id);
616 cp->ypos += height + GAPWITHIN;
620 r.left = GAPBETWEEN; r.top = cp->ypos;
621 r.right = cp->width; r.bottom = LISTHEIGHT;
622 cp->ypos += r.bottom + GAPBETWEEN;
623 doctl(cp, r, "LISTBOX",
624 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS |
631 * Yet another special control: the character-class setter. A
632 * static, then a list, then a line containing a
633 * button-and-static-and-edit.
635 static void charclass(struct ctlpos *cp, char *stext, int sid, int listid,
636 char *btext, int bid, int eid, char *s2text, int s2id) {
638 const int height = (STATICHEIGHT > EDITHEIGHT && STATICHEIGHT > PUSHBTNHEIGHT ?
640 EDITHEIGHT > PUSHBTNHEIGHT ?
641 EDITHEIGHT : PUSHBTNHEIGHT);
642 const static int percents[] = { 30, 40, 30 };
643 int i, xpos, percent;
644 const int LISTHEIGHT = 66;
646 /* The static control. */
647 r.left = GAPBETWEEN; r.top = cp->ypos;
648 r.right = cp->width; r.bottom = STATICHEIGHT;
649 cp->ypos += r.bottom + GAPWITHIN;
650 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
653 r.left = GAPBETWEEN; r.top = cp->ypos;
654 r.right = cp->width; r.bottom = LISTHEIGHT;
655 cp->ypos += r.bottom + GAPWITHIN;
656 doctl(cp, r, "LISTBOX",
657 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS |
662 /* The button+static+edit. */
664 for (i = 0; i < 3; i++) {
665 r.left = xpos + GAPBETWEEN;
666 percent += percents[i];
667 xpos = (cp->width + GAPBETWEEN) * percent / 100;
668 r.right = xpos - r.left;
670 r.bottom = (i==0 ? PUSHBTNHEIGHT :
671 i==1 ? STATICHEIGHT :
673 r.top += (height-r.bottom)/2;
675 doctl(cp, r, "BUTTON",
676 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
679 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_CENTER,
683 WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL,
684 WS_EX_CLIENTEDGE, "", eid);
687 cp->ypos += height + GAPBETWEEN;
691 * A special control (horrors!). The colour editor. A static line;
692 * then on the left, a list box, and on the right, a sequence of
693 * two-part statics followed by a button.
695 static void colouredit(struct ctlpos *cp, char *stext, int sid, int listid,
696 char *btext, int bid, ...) {
700 int lwid, rwid, rpos;
701 const int LISTHEIGHT = 66;
703 /* The static control. */
704 r.left = GAPBETWEEN; r.top = cp->ypos;
705 r.right = cp->width; r.bottom = STATICHEIGHT;
706 cp->ypos += r.bottom + GAPWITHIN;
707 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, stext, sid);
709 rpos = GAPBETWEEN + 2 * (cp->width + GAPBETWEEN) / 3;
710 lwid = rpos - 2*GAPBETWEEN;
711 rwid = cp->width + GAPBETWEEN - rpos;
714 r.left = GAPBETWEEN; r.top = cp->ypos;
715 r.right = lwid; r.bottom = LISTHEIGHT;
716 doctl(cp, r, "LISTBOX",
717 WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | LBS_HASSTRINGS |
728 ltext = va_arg(ap, char *);
730 lid = va_arg(ap, int);
731 rid = va_arg(ap, int);
732 r.top = y; r.bottom = STATICHEIGHT;
733 y += r.bottom + GAPWITHIN;
734 r.left = rpos; r.right = rwid/2;
735 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE, 0, ltext, lid);
736 r.left = rpos + r.right; r.right = rwid - r.right;
737 doctl(cp, r, "STATIC", WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, "", rid);
742 r.top = y + 2*GAPWITHIN; r.bottom = PUSHBTNHEIGHT;
743 r.left = rpos; r.right = rwid;
744 doctl(cp, r, "BUTTON",
745 WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON,
748 cp->ypos += LISTHEIGHT + GAPBETWEEN;
751 static char savedsession[2048];
753 enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TAB, controlstartvalue,
755 connectionpanelstart,
895 translationpanelstart,
911 static const char *const colours[] = {
912 "Default Foreground", "Default Bold Foreground",
913 "Default Background", "Default Bold Background",
914 "Cursor Text", "Cursor Colour",
915 "ANSI Black", "ANSI Black Bold",
916 "ANSI Red", "ANSI Red Bold",
917 "ANSI Green", "ANSI Green Bold",
918 "ANSI Yellow", "ANSI Yellow Bold",
919 "ANSI Blue", "ANSI Blue Bold",
920 "ANSI Magenta", "ANSI Magenta Bold",
921 "ANSI Cyan", "ANSI Cyan Bold",
922 "ANSI White", "ANSI White Bold"
924 static const int permcolour[] = {
925 TRUE, FALSE, TRUE, FALSE, TRUE, TRUE,
926 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE,
927 TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE
930 static void fmtfont (char *buf) {
931 sprintf (buf, "Font: %s, ", cfg.font);
933 strcat(buf, "bold, ");
934 if (cfg.fontheight == 0)
935 strcat (buf, "default height");
937 sprintf (buf+strlen(buf), "%d-%s",
938 (cfg.fontheight < 0 ? -cfg.fontheight : cfg.fontheight),
939 (cfg.fontheight < 0 ? "pixel" : "point"));
942 static void init_dlg_ctrls(HWND hwnd) {
944 char fontstatic[256];
946 SetDlgItemText (hwnd, IDC0_HOST, cfg.host);
947 SetDlgItemText (hwnd, IDC0_SESSEDIT, savedsession);
948 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
949 for (i = 0; i < nsessions; i++)
950 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
951 0, (LPARAM) (sessions[i]));
952 CheckRadioButton (hwnd, IDC0_PROTRAW, IDC0_PROTSSH,
953 cfg.protocol==PROT_SSH ? IDC0_PROTSSH :
954 cfg.protocol==PROT_TELNET ? IDC0_PROTTELNET : IDC0_PROTRAW );
955 SetDlgItemInt (hwnd, IDC0_PINGEDIT, cfg.ping_interval, FALSE);
957 CheckRadioButton (hwnd, IDC1_DEL008, IDC1_DEL127,
958 cfg.bksp_is_delete ? IDC1_DEL127 : IDC1_DEL008);
959 CheckRadioButton (hwnd, IDC1_HOMETILDE, IDC1_HOMERXVT,
960 cfg.rxvt_homeend ? IDC1_HOMERXVT : IDC1_HOMETILDE);
961 CheckRadioButton (hwnd, IDC1_FUNCTILDE, IDC1_FUNCXTERM,
962 cfg.funky_type == 0 ? IDC1_FUNCTILDE :
963 cfg.funky_type == 1 ? IDC1_FUNCLINUX :
964 cfg.funky_type == 2 ? IDC1_FUNCXTERM :
965 cfg.funky_type == 3 ? IDC1_FUNCVT400 :
967 CheckRadioButton (hwnd, IDC1_CURNORMAL, IDC1_CURAPPLIC,
968 cfg.app_cursor ? IDC1_CURAPPLIC : IDC1_CURNORMAL);
969 CheckRadioButton (hwnd, IDC1_KPNORMAL, IDC1_KPNH,
970 cfg.nethack_keypad ? IDC1_KPNH :
971 cfg.app_keypad ? IDC1_KPAPPLIC : IDC1_KPNORMAL);
972 CheckDlgButton (hwnd, IDC1_ALTF4, cfg.alt_f4);
973 CheckDlgButton (hwnd, IDC1_ALTSPACE, cfg.alt_space);
974 CheckDlgButton (hwnd, IDC1_LDISCTERM, cfg.ldisc_term);
975 CheckDlgButton (hwnd, IDC1_SCROLLKEY, cfg.scroll_on_key);
977 CheckDlgButton (hwnd, IDC2_WRAPMODE, cfg.wrap_mode);
978 CheckDlgButton (hwnd, IDC2_DECOM, cfg.dec_om);
979 CheckDlgButton (hwnd, IDC2_LFHASCR, cfg.lfhascr);
980 SetDlgItemInt (hwnd, IDC2_ROWSEDIT, cfg.height, FALSE);
981 SetDlgItemInt (hwnd, IDC2_COLSEDIT, cfg.width, FALSE);
982 SetDlgItemInt (hwnd, IDC2_SAVEEDIT, cfg.savelines, FALSE);
983 fmtfont (fontstatic);
984 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
985 CheckDlgButton (hwnd, IDC2_BEEP, cfg.beep);
986 CheckDlgButton (hwnd, IDC2_BCE, cfg.bce);
987 CheckDlgButton (hwnd, IDC2_BLINKTEXT, cfg.blinktext);
989 SetDlgItemText (hwnd, IDC3_WINEDIT, cfg.wintitle);
990 CheckDlgButton (hwnd, IDC3_WINNAME, cfg.win_name_always);
991 CheckDlgButton (hwnd, IDC3_BLINKCUR, cfg.blink_cur);
992 CheckDlgButton (hwnd, IDC3_SCROLLBAR, cfg.scrollbar);
993 CheckDlgButton (hwnd, IDC3_LOCKSIZE, cfg.locksize);
994 CheckDlgButton (hwnd, IDC3_CLOSEEXIT, cfg.close_on_exit);
995 CheckDlgButton (hwnd, IDC3_CLOSEWARN, cfg.warn_on_close);
997 SetDlgItemText (hwnd, IDC4_TTEDIT, cfg.termtype);
998 SetDlgItemText (hwnd, IDC4_TSEDIT, cfg.termspeed);
999 SetDlgItemText (hwnd, IDC4_LOGEDIT, cfg.username);
1001 char *p = cfg.environmt;
1003 SendDlgItemMessage (hwnd, IDC4_ENVLIST, LB_ADDSTRING, 0,
1008 CheckRadioButton (hwnd, IDC4_EMBSD, IDC4_EMRFC,
1009 cfg.rfc_environ ? IDC4_EMRFC : IDC4_EMBSD);
1011 SetDlgItemText (hwnd, IDC5_TTEDIT, cfg.termtype);
1012 SetDlgItemText (hwnd, IDC5_LOGEDIT, cfg.username);
1013 CheckDlgButton (hwnd, IDC5_NOPTY, cfg.nopty);
1014 CheckDlgButton (hwnd, IDC5_AGENTFWD, cfg.agentfwd);
1015 CheckRadioButton (hwnd, IDC5_CIPHER3DES, IDC5_CIPHERDES,
1016 cfg.cipher == CIPHER_BLOWFISH ? IDC5_CIPHERBLOWF :
1017 cfg.cipher == CIPHER_DES ? IDC5_CIPHERDES :
1019 CheckRadioButton (hwnd, IDC5_SSHPROT1, IDC5_SSHPROT2,
1020 cfg.sshprot == 1 ? IDC5_SSHPROT1 : IDC5_SSHPROT2);
1021 CheckDlgButton (hwnd, IDC5_AUTHTIS, cfg.try_tis_auth);
1022 SetDlgItemText (hwnd, IDC5_PKEDIT, cfg.keyfile);
1023 SetDlgItemText (hwnd, IDC5_CMDEDIT, cfg.remote_cmd);
1025 CheckRadioButton (hwnd, IDC6_MBWINDOWS, IDC6_MBXTERM,
1026 cfg.mouse_is_xterm ? IDC6_MBXTERM : IDC6_MBWINDOWS);
1028 static int tabs[4] = {25, 61, 96, 128};
1029 SendDlgItemMessage (hwnd, IDC6_CCLIST, LB_SETTABSTOPS, 4,
1032 for (i=0; i<256; i++) {
1034 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1035 (i>=0x21 && i != 0x7F) ? i : ' ',
1037 SendDlgItemMessage (hwnd, IDC6_CCLIST, LB_ADDSTRING, 0,
1041 CheckDlgButton (hwnd, IDC7_BOLDCOLOUR, cfg.bold_colour);
1042 CheckDlgButton (hwnd, IDC7_PALETTE, cfg.try_palette);
1045 for (i=0; i<22; i++)
1046 if (cfg.bold_colour || permcolour[i])
1047 SendDlgItemMessage (hwnd, IDC7_LIST, LB_ADDSTRING, 0,
1048 (LPARAM) colours[i]);
1050 SendDlgItemMessage (hwnd, IDC7_LIST, LB_SETCURSEL, 0, 0);
1051 SetDlgItemInt (hwnd, IDC7_RVALUE, cfg.colours[0][0], FALSE);
1052 SetDlgItemInt (hwnd, IDC7_GVALUE, cfg.colours[0][1], FALSE);
1053 SetDlgItemInt (hwnd, IDC7_BVALUE, cfg.colours[0][2], FALSE);
1055 CheckRadioButton (hwnd, IDC8_NOXLAT, IDC8_88592WIN1250,
1056 cfg.xlat_88592w1250 ? IDC8_88592WIN1250 :
1057 cfg.xlat_enablekoiwin ? IDC8_KOI8WIN1251 :
1059 CheckDlgButton (hwnd, IDC8_CAPSLOCKCYR, cfg.xlat_capslockcyr);
1060 CheckRadioButton (hwnd, IDC8_VTXWINDOWS, IDC8_VTPOORMAN,
1061 cfg.vtmode == VT_XWINDOWS ? IDC8_VTXWINDOWS :
1062 cfg.vtmode == VT_OEMANSI ? IDC8_VTOEMANSI :
1063 cfg.vtmode == VT_OEMONLY ? IDC8_VTOEMONLY :
1067 static void hide(HWND hwnd, int hide, int minid, int maxid) {
1069 for (i = minid; i < maxid; i++) {
1070 HWND ctl = GetDlgItem(hwnd, i);
1072 ShowWindow(ctl, hide ? SW_HIDE : SW_SHOW);
1078 * This _huge_ function is the configuration box.
1080 static int GenericMainDlgProc (HWND hwnd, UINT msg,
1081 WPARAM wParam, LPARAM lParam,
1086 char filename[sizeof(cfg.keyfile)];
1089 char fontstatic[256];
1094 SetWindowLong(hwnd, GWL_USERDATA, 0);
1096 * Centre the window.
1098 { /* centre the window */
1101 hw = GetDesktopWindow();
1102 if (GetWindowRect (hw, &rs) && GetWindowRect (hwnd, &rd))
1103 MoveWindow (hwnd, (rs.right + rs.left + rd.left - rd.right)/2,
1104 (rs.bottom + rs.top + rd.top - rd.bottom)/2,
1105 rd.right-rd.left, rd.bottom-rd.top, TRUE);
1109 * Create the tab control.
1115 r.left = 3; r.right = r.left + 174;
1116 r.top = 3; r.bottom = r.top + 193;
1117 MapDialogRect(hwnd, &r);
1118 tabctl = CreateWindowEx(0, WC_TABCONTROL, "",
1119 WS_CHILD | WS_VISIBLE |
1120 WS_TABSTOP | TCS_MULTILINE,
1122 r.right-r.left, r.bottom-r.top,
1123 hwnd, (HMENU)IDCX_TAB, hinst, NULL);
1124 font = SendMessage(hwnd, WM_GETFONT, 0, 0);
1125 SendMessage(tabctl, WM_SETFONT, font, MAKELPARAM(TRUE, 0));
1129 * Create the various panelfuls of controls.
1134 /* The Connection panel. Accelerators used: [aco] dehlnprstwx */
1137 ctlposinit(&cp, hwnd, 6, 30);
1140 "Host &Name", IDC0_HOSTSTATIC, IDC0_HOST, 75,
1141 "&Port", IDC0_PORTSTATIC, IDC0_PORT, 25, NULL);
1142 if (backends[2].backend == NULL) {
1143 /* this is PuTTYtel, so only two protocols available */
1144 radioline(&cp, "Protocol:", IDC0_PROTSTATIC, 3,
1145 "&Raw", IDC0_PROTRAW,
1146 "&Telnet", IDC0_PROTTELNET, NULL);
1148 radioline(&cp, "Protocol:", IDC0_PROTSTATIC, 3,
1149 "&Raw", IDC0_PROTRAW,
1150 "&Telnet", IDC0_PROTTELNET,
1156 IDC0_PROTSSH, NULL);
1158 sesssaver(&cp, "Stor&ed Sessions",
1159 IDC0_SESSSTATIC, IDC0_SESSEDIT, IDC0_SESSLIST,
1160 "&Load", IDC0_SESSLOAD,
1161 "&Save", IDC0_SESSSAVE,
1162 "&Delete", IDC0_SESSDEL, NULL);
1164 staticedit(&cp, "Keepalive inter&val (minutes)",
1165 IDC0_PINGSTATIC, IDC0_PINGEDIT, 25);
1167 tab.mask = TCIF_TEXT; tab.pszText = "Connection";
1168 TabCtrl_InsertItem (tabctl, i++, &tab);
1171 /* The Keyboard panel. Accelerators used: [aco] 4?ehiklmnprsuvxy */
1174 ctlposinit(&cp, hwnd, 6, 30);
1175 radioline(&cp, "Action of Backspace:", IDC1_DELSTATIC, 2,
1176 "Control-&H", IDC1_DEL008,
1177 "Control-&? (127)", IDC1_DEL127, NULL);
1178 radioline(&cp, "Action of Home and End:", IDC1_HOMESTATIC, 2,
1179 "&Standard", IDC1_HOMETILDE,
1180 "&rxvt", IDC1_HOMERXVT, NULL);
1181 radioline(&cp, "Function key and keypad layout:", IDC1_FUNCSTATIC, 4,
1182 "&VT400", IDC1_FUNCTILDE,
1183 "&Linux", IDC1_FUNCLINUX,
1184 "&Xterm R6", IDC1_FUNCXTERM,
1185 "&VT400", IDC1_FUNCVT400, NULL);
1186 radioline(&cp, "Initial state of cursor keys:", IDC1_CURSTATIC, 2,
1187 "&Normal", IDC1_CURNORMAL,
1188 "A&pplication", IDC1_CURAPPLIC, NULL);
1189 radioline(&cp, "Initial state of numeric keypad:", IDC1_KPSTATIC, 3,
1190 "Nor&mal", IDC1_KPNORMAL,
1191 "Appl&ication", IDC1_KPAPPLIC,
1192 "N&etHack", IDC1_KPNH, NULL);
1193 checkbox(&cp, "ALT-F&4 is special (closes window)", IDC1_ALTF4);
1194 checkbox(&cp, "ALT-Space is special (S&ystem menu)", IDC1_ALTSPACE);
1195 checkbox(&cp, "&Use local terminal line discipline", IDC1_LDISCTERM);
1196 checkbox(&cp, "Reset scrollback on &keypress", IDC1_SCROLLKEY);
1198 tab.mask = TCIF_TEXT; tab.pszText = "Keyboard";
1199 TabCtrl_InsertItem (tabctl, i++, &tab);
1202 /* The Terminal panel. Accelerators used: [aco] dghlmnprsvw */
1205 ctlposinit(&cp, hwnd, 6, 30);
1207 "&Rows", IDC2_ROWSSTATIC, IDC2_ROWSEDIT, 33,
1208 "Colu&mns", IDC2_COLSSTATIC, IDC2_COLSEDIT, 33,
1209 "&Scrollback", IDC2_SAVESTATIC, IDC2_SAVEEDIT, 33,
1211 staticbtn(&cp, "", IDC2_FONTSTATIC, "C&hange...", IDC2_CHOOSEFONT);
1212 checkbox(&cp, "Auto &wrap mode initially on", IDC2_WRAPMODE);
1213 checkbox(&cp, "&DEC Origin Mode initially on", IDC2_DECOM);
1214 checkbox(&cp, "Implicit CR in every &LF", IDC2_LFHASCR);
1215 checkbox(&cp, "Bee&p enabled", IDC2_BEEP);
1216 checkbox(&cp, "Use Back&ground colour erase", IDC2_BCE);
1217 checkbox(&cp, "Enable bli&nking text", IDC2_BLINKTEXT);
1218 tab.mask = TCIF_TEXT; tab.pszText = "Terminal";
1219 TabCtrl_InsertItem (tabctl, i++, &tab);
1222 /* The Window panel. Accelerators used: [aco] bikty */
1225 ctlposinit(&cp, hwnd, 6, 30);
1228 "Initial window &title:", IDC3_WINTITLE,
1229 IDC3_WINEDIT, 100, NULL);
1230 checkbox(&cp, "Avoid ever using &icon title", IDC3_WINNAME);
1231 checkbox(&cp, "&Blinking cursor", IDC3_BLINKCUR);
1232 checkbox(&cp, "Displa&y scrollbar", IDC3_SCROLLBAR);
1233 checkbox(&cp, "Loc&k Window size", IDC3_LOCKSIZE);
1234 checkbox(&cp, "Close Window on E&xit", IDC3_CLOSEEXIT);
1235 checkbox(&cp, "&Warn on Close", IDC3_CLOSEWARN);
1236 tab.mask = TCIF_TEXT; tab.pszText = "Window";
1237 TabCtrl_InsertItem (tabctl, i++, &tab);
1240 /* The Telnet panel. Accelerators used: [aco] bdflrstuv */
1243 ctlposinit(&cp, hwnd, 6, 30);
1245 staticedit(&cp, "Terminal-&type string", IDC4_TTSTATIC, IDC4_TTEDIT, 50);
1246 staticedit(&cp, "Terminal-&speed string", IDC4_TSSTATIC, IDC4_TSEDIT, 50);
1247 staticedit(&cp, "Auto-login &username", IDC4_LOGSTATIC, IDC4_LOGEDIT, 50);
1248 envsetter(&cp, "Environment variables:", IDC4_ENVSTATIC,
1249 "&Variable", IDC4_VARSTATIC, IDC4_VAREDIT,
1250 "Va&lue", IDC4_VALSTATIC, IDC4_VALEDIT,
1252 "A&dd", IDC4_ENVADD, "&Remove", IDC4_ENVREMOVE);
1253 radioline(&cp, "Handling of OLD_ENVIRON ambiguity:", IDC4_EMSTATIC, 2,
1254 "&BSD (commonplace)", IDC4_EMBSD,
1255 "R&FC 1408 (unusual)", IDC4_EMRFC, NULL);
1256 tab.mask = TCIF_TEXT; tab.pszText = "Telnet";
1257 TabCtrl_InsertItem (tabctl, i++, &tab);
1261 /* The SSH panel. Accelerators used: [aco] 123abdkmprtuw */
1264 ctlposinit(&cp, hwnd, 6, 30);
1266 staticedit(&cp, "Terminal-&type string", IDC5_TTSTATIC, IDC5_TTEDIT, 50);
1267 staticedit(&cp, "Auto-login &username", IDC5_LOGSTATIC, IDC5_LOGEDIT, 50);
1269 "&Remote command:", IDC5_CMDSTATIC, IDC5_CMDEDIT, 100,
1271 checkbox(&cp, "Don't allocate a &pseudo-terminal", IDC5_NOPTY);
1272 checkbox(&cp, "Atte&mpt TIS or CryptoCard authentication",
1274 checkbox(&cp, "Allow &agent forwarding", IDC5_AGENTFWD);
1275 editbutton(&cp, "Private &key file for authentication:",
1276 IDC5_PKSTATIC, IDC5_PKEDIT, "Bro&wse...", IDC5_PKBUTTON);
1277 radioline(&cp, "Preferred SSH protocol version:",
1278 IDC5_SSHPROTSTATIC, 2,
1279 "&1", IDC5_SSHPROT1, "&2", IDC5_SSHPROT2, NULL);
1280 radioline(&cp, "Preferred encryption algorithm:", IDC5_CIPHERSTATIC, 3,
1281 "&3DES", IDC5_CIPHER3DES,
1282 "&Blowfish", IDC5_CIPHERBLOWF,
1283 "&DES", IDC5_CIPHERDES, NULL);
1284 tab.mask = TCIF_TEXT; tab.pszText = "SSH";
1285 TabCtrl_InsertItem (tabctl, i++, &tab);
1289 /* The Selection panel. Accelerators used: [aco] stwx */
1292 ctlposinit(&cp, hwnd, 6, 30);
1293 radiobig(&cp, "Action of mouse buttons:", IDC6_MBSTATIC,
1294 "&Windows (Right pastes, Middle extends)", IDC6_MBWINDOWS,
1295 "&xterm (Right extends, Middle pastes)", IDC6_MBXTERM,
1297 charclass(&cp, "Character classes:", IDC6_CCSTATIC, IDC6_CCLIST,
1298 "&Set", IDC6_CCSET, IDC6_CCEDIT,
1299 "&to class", IDC6_CCSTATIC2);
1300 tab.mask = TCIF_TEXT; tab.pszText = "Selection";
1301 TabCtrl_InsertItem (tabctl, i++, &tab);
1304 /* The Colours panel. Accelerators used: [aco] bmlu */
1307 ctlposinit(&cp, hwnd, 6, 30);
1308 checkbox(&cp, "&Bolded text is a different colour", IDC7_BOLDCOLOUR);
1309 checkbox(&cp, "Attempt to use &logical palettes", IDC7_PALETTE);
1310 colouredit(&cp, "Select a colo&ur and click to modify it:",
1311 IDC7_STATIC, IDC7_LIST,
1312 "&Modify...", IDC7_CHANGE,
1313 "Red:", IDC7_RSTATIC, IDC7_RVALUE,
1314 "Green:", IDC7_GSTATIC, IDC7_GVALUE,
1315 "Blue:", IDC7_BSTATIC, IDC7_BVALUE, NULL);
1316 tab.mask = TCIF_TEXT; tab.pszText = "Colours";
1317 TabCtrl_InsertItem (tabctl, i++, &tab);
1320 /* The Translation panel. Accelerators used: [aco] beiknpsx */
1323 ctlposinit(&cp, hwnd, 6, 30);
1325 "Handling of VT100 line drawing characters:", IDC8_VTSTATIC,
1326 "Font has &XWindows encoding", IDC8_VTXWINDOWS,
1327 "Use font in &both ANSI and OEM modes", IDC8_VTOEMANSI,
1328 "Use font in O&EM mode only", IDC8_VTOEMONLY,
1329 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
1330 IDC8_VTPOORMAN, NULL);
1332 "Character set translation:", IDC8_XLATSTATIC,
1333 "&None", IDC8_NOXLAT,
1334 "&KOI8 / Win-1251", IDC8_KOI8WIN1251,
1335 "&ISO-8859-2 / Win-1250", IDC8_88592WIN1250, NULL);
1336 checkbox(&cp, "CAP&S LOCK acts as cyrillic switch", IDC8_CAPSLOCKCYR);
1337 tab.mask = TCIF_TEXT; tab.pszText = "Translation";
1338 TabCtrl_InsertItem (tabctl, i++, &tab);
1341 init_dlg_ctrls(hwnd);
1343 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1344 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1347 * Set focus into the first available control.
1351 ctl = GetDlgItem(hwnd, IDC0_HOST);
1352 if (!ctl) ctl = GetDlgItem(hwnd, IDC0_PINGEDIT);
1356 SetWindowLong(hwnd, GWL_USERDATA, 1);
1360 * Button release should trigger WM_OK if there was a
1361 * previous double click on the session list.
1365 SendMessage (hwnd, WM_COMMAND, IDOK, 0);
1368 if (LOWORD(wParam) == IDCX_TAB &&
1369 ((LPNMHDR)lParam)->code == TCN_SELCHANGE) {
1370 int i = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
1373 item.pszText = buffer;
1374 item.cchTextMax = sizeof(buffer);
1375 item.mask = TCIF_TEXT;
1376 TabCtrl_GetItem(((LPNMHDR)lParam)->hwndFrom, i, &item);
1377 hide(hwnd, TRUE, controlstartvalue, controlendvalue);
1378 if (!strcmp(buffer, "Connection"))
1379 hide(hwnd, FALSE, connectionpanelstart, connectionpanelend);
1380 if (!strcmp(buffer, "Keyboard"))
1381 hide(hwnd, FALSE, keyboardpanelstart, keyboardpanelend);
1382 if (!strcmp(buffer, "Terminal"))
1383 hide(hwnd, FALSE, terminalpanelstart, terminalpanelend);
1384 if (!strcmp(buffer, "Window"))
1385 hide(hwnd, FALSE, windowpanelstart, windowpanelend);
1386 if (!strcmp(buffer, "Telnet"))
1387 hide(hwnd, FALSE, telnetpanelstart, telnetpanelend);
1388 if (!strcmp(buffer, "SSH"))
1389 hide(hwnd, FALSE, sshpanelstart, sshpanelend);
1390 if (!strcmp(buffer, "Selection"))
1391 hide(hwnd, FALSE, selectionpanelstart, selectionpanelend);
1392 if (!strcmp(buffer, "Colours"))
1393 hide(hwnd, FALSE, colourspanelstart, colourspanelend);
1394 if (!strcmp(buffer, "Translation"))
1395 hide(hwnd, FALSE, translationpanelstart, translationpanelend);
1397 SetFocus (((LPNMHDR)lParam)->hwndFrom); /* ensure focus stays */
1403 * Only process WM_COMMAND once the dialog is fully formed.
1405 if (GetWindowLong(hwnd, GWL_USERDATA) == 1) switch (LOWORD(wParam)) {
1408 EndDialog (hwnd, 1);
1413 EndDialog (hwnd, 0);
1415 case IDC0_PROTTELNET:
1418 if (HIWORD(wParam) == BN_CLICKED ||
1419 HIWORD(wParam) == BN_DOUBLECLICKED) {
1420 int i = IsDlgButtonChecked (hwnd, IDC0_PROTSSH);
1421 int j = IsDlgButtonChecked (hwnd, IDC0_PROTTELNET);
1422 cfg.protocol = i ? PROT_SSH : j ? PROT_TELNET : PROT_RAW ;
1423 if ((cfg.protocol == PROT_SSH && cfg.port == 23) ||
1424 (cfg.protocol == PROT_TELNET && cfg.port == 22)) {
1425 cfg.port = i ? 22 : 23;
1426 SetDlgItemInt (hwnd, IDC0_PORT, cfg.port, FALSE);
1431 if (HIWORD(wParam) == EN_CHANGE)
1432 GetDlgItemText (hwnd, IDC0_HOST, cfg.host,
1433 sizeof(cfg.host)-1);
1436 if (HIWORD(wParam) == EN_CHANGE)
1437 MyGetDlgItemInt (hwnd, IDC0_PORT, &cfg.port);
1440 if (HIWORD(wParam) == EN_CHANGE) {
1441 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
1443 GetDlgItemText (hwnd, IDC0_SESSEDIT,
1444 savedsession, sizeof(savedsession)-1);
1445 savedsession[sizeof(savedsession)-1] = '\0';
1449 if (HIWORD(wParam) == BN_CLICKED ||
1450 HIWORD(wParam) == BN_DOUBLECLICKED) {
1455 GetDlgItemText (hwnd, IDC0_SESSEDIT, str, sizeof(str)-1);
1457 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
1458 LB_GETCURSEL, 0, 0);
1463 strcpy (str, sessions[n]);
1465 save_settings (str, !!strcmp(str, "Default Settings"), &cfg);
1466 get_sesslist (FALSE);
1467 get_sesslist (TRUE);
1468 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
1470 for (i = 0; i < nsessions; i++)
1471 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
1472 0, (LPARAM) (sessions[i]));
1473 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
1479 if (LOWORD(wParam) == IDC0_SESSLOAD &&
1480 HIWORD(wParam) != BN_CLICKED &&
1481 HIWORD(wParam) != BN_DOUBLECLICKED)
1483 if (LOWORD(wParam) == IDC0_SESSLIST &&
1484 HIWORD(wParam) != LBN_DBLCLK)
1487 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
1488 LB_GETCURSEL, 0, 0);
1493 load_settings (sessions[n],
1494 !!strcmp(sessions[n], "Default Settings"),
1496 init_dlg_ctrls(hwnd);
1498 if (LOWORD(wParam) == IDC0_SESSLIST) {
1500 * A double-click on a saved session should
1501 * actually start the session, not just load it.
1502 * Unless it's Default Settings or some other
1503 * host-less set of saved settings.
1512 if (HIWORD(wParam) == BN_CLICKED ||
1513 HIWORD(wParam) == BN_DOUBLECLICKED) {
1514 int n = SendDlgItemMessage (hwnd, IDC0_SESSLIST,
1515 LB_GETCURSEL, 0, 0);
1516 if (n == LB_ERR || n == 0) {
1520 del_settings(sessions[n]);
1521 get_sesslist (FALSE);
1522 get_sesslist (TRUE);
1523 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_RESETCONTENT,
1525 for (i = 0; i < nsessions; i++)
1526 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_ADDSTRING,
1527 0, (LPARAM) (sessions[i]));
1528 SendDlgItemMessage (hwnd, IDC0_SESSLIST, LB_SETCURSEL,
1532 if (HIWORD(wParam) == EN_CHANGE)
1533 MyGetDlgItemInt (hwnd, IDC0_PINGEDIT, &cfg.ping_interval);
1537 if (HIWORD(wParam) == BN_CLICKED ||
1538 HIWORD(wParam) == BN_DOUBLECLICKED)
1539 cfg.bksp_is_delete = IsDlgButtonChecked (hwnd, IDC1_DEL127);
1541 case IDC1_HOMETILDE:
1543 if (HIWORD(wParam) == BN_CLICKED ||
1544 HIWORD(wParam) == BN_DOUBLECLICKED)
1545 cfg.rxvt_homeend = IsDlgButtonChecked (hwnd, IDC1_HOMERXVT);
1547 case IDC1_FUNCXTERM:
1548 if (HIWORD(wParam) == BN_CLICKED ||
1549 HIWORD(wParam) == BN_DOUBLECLICKED)
1552 case IDC1_FUNCVT400:
1553 if (HIWORD(wParam) == BN_CLICKED ||
1554 HIWORD(wParam) == BN_DOUBLECLICKED)
1557 case IDC1_FUNCTILDE:
1558 case IDC1_FUNCLINUX:
1559 if (HIWORD(wParam) == BN_CLICKED ||
1560 HIWORD(wParam) == BN_DOUBLECLICKED)
1561 cfg.funky_type = IsDlgButtonChecked (hwnd, IDC1_FUNCLINUX);
1565 if (HIWORD(wParam) == BN_CLICKED ||
1566 HIWORD(wParam) == BN_DOUBLECLICKED) {
1567 cfg.app_keypad = IsDlgButtonChecked (hwnd, IDC1_KPAPPLIC);
1568 cfg.nethack_keypad = FALSE;
1572 if (HIWORD(wParam) == BN_CLICKED ||
1573 HIWORD(wParam) == BN_DOUBLECLICKED) {
1574 cfg.app_keypad = FALSE;
1575 cfg.nethack_keypad = TRUE;
1578 case IDC1_CURNORMAL:
1579 case IDC1_CURAPPLIC:
1580 if (HIWORD(wParam) == BN_CLICKED ||
1581 HIWORD(wParam) == BN_DOUBLECLICKED)
1582 cfg.app_cursor = IsDlgButtonChecked (hwnd, IDC1_CURAPPLIC);
1585 if (HIWORD(wParam) == BN_CLICKED ||
1586 HIWORD(wParam) == BN_DOUBLECLICKED)
1587 cfg.alt_f4 = IsDlgButtonChecked (hwnd, IDC1_ALTF4);
1590 if (HIWORD(wParam) == BN_CLICKED ||
1591 HIWORD(wParam) == BN_DOUBLECLICKED)
1592 cfg.alt_space = IsDlgButtonChecked (hwnd, IDC1_ALTSPACE);
1594 case IDC1_LDISCTERM:
1595 if (HIWORD(wParam) == BN_CLICKED ||
1596 HIWORD(wParam) == BN_DOUBLECLICKED)
1597 cfg.ldisc_term = IsDlgButtonChecked (hwnd, IDC1_LDISCTERM);
1599 case IDC1_SCROLLKEY:
1600 if (HIWORD(wParam) == BN_CLICKED ||
1601 HIWORD(wParam) == BN_DOUBLECLICKED)
1602 cfg.scroll_on_key = IsDlgButtonChecked (hwnd, IDC1_SCROLLKEY);
1605 if (HIWORD(wParam) == BN_CLICKED ||
1606 HIWORD(wParam) == BN_DOUBLECLICKED)
1607 cfg.wrap_mode = IsDlgButtonChecked (hwnd, IDC2_WRAPMODE);
1610 if (HIWORD(wParam) == BN_CLICKED ||
1611 HIWORD(wParam) == BN_DOUBLECLICKED)
1612 cfg.dec_om = IsDlgButtonChecked (hwnd, IDC2_DECOM);
1615 if (HIWORD(wParam) == BN_CLICKED ||
1616 HIWORD(wParam) == BN_DOUBLECLICKED)
1617 cfg.lfhascr = IsDlgButtonChecked (hwnd, IDC2_LFHASCR);
1620 if (HIWORD(wParam) == EN_CHANGE)
1621 MyGetDlgItemInt (hwnd, IDC2_ROWSEDIT, &cfg.height);
1624 if (HIWORD(wParam) == EN_CHANGE)
1625 MyGetDlgItemInt (hwnd, IDC2_COLSEDIT, &cfg.width);
1628 if (HIWORD(wParam) == EN_CHANGE)
1629 MyGetDlgItemInt (hwnd, IDC2_SAVEEDIT, &cfg.savelines);
1631 case IDC2_CHOOSEFONT:
1632 lf.lfHeight = cfg.fontheight;
1633 lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0;
1634 lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0;
1635 lf.lfWeight = (cfg.fontisbold ? FW_BOLD : 0);
1636 lf.lfCharSet = cfg.fontcharset;
1637 lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
1638 lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
1639 lf.lfQuality = DEFAULT_QUALITY;
1640 lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
1641 strncpy (lf.lfFaceName, cfg.font, sizeof(lf.lfFaceName)-1);
1642 lf.lfFaceName[sizeof(lf.lfFaceName)-1] = '\0';
1644 cf.lStructSize = sizeof(cf);
1645 cf.hwndOwner = hwnd;
1647 cf.Flags = CF_FIXEDPITCHONLY | CF_FORCEFONTEXIST |
1648 CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS;
1650 if (ChooseFont (&cf)) {
1651 strncpy (cfg.font, lf.lfFaceName, sizeof(cfg.font)-1);
1652 cfg.font[sizeof(cfg.font)-1] = '\0';
1653 cfg.fontisbold = (lf.lfWeight == FW_BOLD);
1654 cfg.fontcharset = lf.lfCharSet;
1655 cfg.fontheight = lf.lfHeight;
1656 fmtfont (fontstatic);
1657 SetDlgItemText (hwnd, IDC2_FONTSTATIC, fontstatic);
1661 if (HIWORD(wParam) == BN_CLICKED ||
1662 HIWORD(wParam) == BN_DOUBLECLICKED)
1663 cfg.beep = IsDlgButtonChecked (hwnd, IDC2_BEEP);
1665 case IDC2_BLINKTEXT:
1666 if (HIWORD(wParam) == BN_CLICKED ||
1667 HIWORD(wParam) == BN_DOUBLECLICKED)
1668 cfg.blinktext = IsDlgButtonChecked (hwnd, IDC2_BLINKTEXT);
1671 if (HIWORD(wParam) == BN_CLICKED ||
1672 HIWORD(wParam) == BN_DOUBLECLICKED)
1673 cfg.bce = IsDlgButtonChecked (hwnd, IDC2_BCE);
1676 if (HIWORD(wParam) == BN_CLICKED ||
1677 HIWORD(wParam) == BN_DOUBLECLICKED)
1678 cfg.win_name_always = IsDlgButtonChecked (hwnd, IDC3_WINNAME);
1681 if (HIWORD(wParam) == BN_CLICKED ||
1682 HIWORD(wParam) == BN_DOUBLECLICKED)
1683 cfg.blink_cur = IsDlgButtonChecked (hwnd, IDC3_BLINKCUR);
1685 case IDC3_SCROLLBAR:
1686 if (HIWORD(wParam) == BN_CLICKED ||
1687 HIWORD(wParam) == BN_DOUBLECLICKED)
1688 cfg.scrollbar = IsDlgButtonChecked (hwnd, IDC3_SCROLLBAR);
1691 if (HIWORD(wParam) == BN_CLICKED ||
1692 HIWORD(wParam) == BN_DOUBLECLICKED)
1693 cfg.locksize = IsDlgButtonChecked (hwnd, IDC3_LOCKSIZE);
1696 if (HIWORD(wParam) == EN_CHANGE)
1697 GetDlgItemText (hwnd, IDC3_WINEDIT, cfg.wintitle,
1698 sizeof(cfg.wintitle)-1);
1700 case IDC3_CLOSEEXIT:
1701 if (HIWORD(wParam) == BN_CLICKED ||
1702 HIWORD(wParam) == BN_DOUBLECLICKED)
1703 cfg.close_on_exit = IsDlgButtonChecked (hwnd, IDC3_CLOSEEXIT);
1705 case IDC3_CLOSEWARN:
1706 if (HIWORD(wParam) == BN_CLICKED ||
1707 HIWORD(wParam) == BN_DOUBLECLICKED)
1708 cfg.warn_on_close = IsDlgButtonChecked (hwnd, IDC3_CLOSEWARN);
1711 if (HIWORD(wParam) == EN_CHANGE)
1712 GetDlgItemText (hwnd, IDC4_TTEDIT, cfg.termtype,
1713 sizeof(cfg.termtype)-1);
1716 if (HIWORD(wParam) == EN_CHANGE)
1717 GetDlgItemText (hwnd, IDC4_TSEDIT, cfg.termspeed,
1718 sizeof(cfg.termspeed)-1);
1721 if (HIWORD(wParam) == EN_CHANGE) {
1722 GetDlgItemText (hwnd, IDC4_LOGEDIT, cfg.username,
1723 sizeof(cfg.username)-1);
1724 cfg.username[sizeof(cfg.username)-1] = '\0';
1725 SetWindowLong(hwnd, GWL_USERDATA, 0);
1726 SetDlgItemText (hwnd, IDC5_LOGEDIT, cfg.username);
1727 SetWindowLong(hwnd, GWL_USERDATA, 1);
1732 cfg.rfc_environ = IsDlgButtonChecked (hwnd, IDC4_EMRFC);
1735 if (HIWORD(wParam) == BN_CLICKED ||
1736 HIWORD(wParam) == BN_DOUBLECLICKED) {
1737 char str[sizeof(cfg.environmt)];
1739 GetDlgItemText (hwnd, IDC4_VAREDIT, str, sizeof(str)-1);
1744 p = str + strlen(str);
1746 GetDlgItemText (hwnd, IDC4_VALEDIT, p, sizeof(str)-1-(p-str));
1756 if ((p-cfg.environmt) + strlen(str) + 2 < sizeof(cfg.environmt)) {
1758 p[strlen(str)+1] = '\0';
1759 SendDlgItemMessage (hwnd, IDC4_ENVLIST, LB_ADDSTRING,
1761 SetDlgItemText (hwnd, IDC4_VAREDIT, "");
1762 SetDlgItemText (hwnd, IDC4_VALEDIT, "");
1764 MessageBox(hwnd, "Environment too big", "PuTTY Error",
1765 MB_OK | MB_ICONERROR);
1769 case IDC4_ENVREMOVE:
1770 if (HIWORD(wParam) != BN_CLICKED &&
1771 HIWORD(wParam) != BN_DOUBLECLICKED)
1773 i = SendDlgItemMessage (hwnd, IDC4_ENVLIST, LB_GETCURSEL, 0, 0);
1779 SendDlgItemMessage (hwnd, IDC4_ENVLIST, LB_DELETESTRING,
1804 if (HIWORD(wParam) == EN_CHANGE)
1805 GetDlgItemText (hwnd, IDC5_TTEDIT, cfg.termtype,
1806 sizeof(cfg.termtype)-1);
1809 if (HIWORD(wParam) == EN_CHANGE) {
1810 GetDlgItemText (hwnd, IDC5_LOGEDIT, cfg.username,
1811 sizeof(cfg.username)-1);
1812 cfg.username[sizeof(cfg.username)-1] = '\0';
1813 SetWindowLong(hwnd, GWL_USERDATA, 0);
1814 SetDlgItemText (hwnd, IDC4_LOGEDIT, cfg.username);
1815 SetWindowLong(hwnd, GWL_USERDATA, 1);
1819 if (HIWORD(wParam) == BN_CLICKED ||
1820 HIWORD(wParam) == BN_DOUBLECLICKED)
1821 cfg.nopty = IsDlgButtonChecked (hwnd, IDC5_NOPTY);
1824 if (HIWORD(wParam) == BN_CLICKED ||
1825 HIWORD(wParam) == BN_DOUBLECLICKED)
1826 cfg.agentfwd = IsDlgButtonChecked (hwnd, IDC5_AGENTFWD);
1828 case IDC5_CIPHER3DES:
1829 case IDC5_CIPHERBLOWF:
1830 case IDC5_CIPHERDES:
1831 if (HIWORD(wParam) == BN_CLICKED ||
1832 HIWORD(wParam) == BN_DOUBLECLICKED) {
1833 if (IsDlgButtonChecked (hwnd, IDC5_CIPHER3DES))
1834 cfg.cipher = CIPHER_3DES;
1835 else if (IsDlgButtonChecked (hwnd, IDC5_CIPHERBLOWF))
1836 cfg.cipher = CIPHER_BLOWFISH;
1837 else if (IsDlgButtonChecked (hwnd, IDC5_CIPHERDES))
1838 cfg.cipher = CIPHER_DES;
1843 if (HIWORD(wParam) == BN_CLICKED ||
1844 HIWORD(wParam) == BN_DOUBLECLICKED) {
1845 if (IsDlgButtonChecked (hwnd, IDC5_SSHPROT1))
1847 else if (IsDlgButtonChecked (hwnd, IDC5_SSHPROT2))
1852 if (HIWORD(wParam) == BN_CLICKED ||
1853 HIWORD(wParam) == BN_DOUBLECLICKED)
1854 cfg.try_tis_auth = IsDlgButtonChecked (hwnd, IDC5_AUTHTIS);
1857 if (HIWORD(wParam) == EN_CHANGE)
1858 GetDlgItemText (hwnd, IDC5_PKEDIT, cfg.keyfile,
1859 sizeof(cfg.keyfile)-1);
1862 if (HIWORD(wParam) == EN_CHANGE)
1863 GetDlgItemText (hwnd, IDC5_CMDEDIT, cfg.remote_cmd,
1864 sizeof(cfg.remote_cmd)-1);
1867 memset(&of, 0, sizeof(of));
1868 #ifdef OPENFILENAME_SIZE_VERSION_400
1869 of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
1871 of.lStructSize = sizeof(of);
1873 of.hwndOwner = hwnd;
1874 of.lpstrFilter = "All Files\0*\0\0\0";
1875 of.lpstrCustomFilter = NULL;
1876 of.nFilterIndex = 1;
1877 of.lpstrFile = filename; strcpy(filename, cfg.keyfile);
1878 of.nMaxFile = sizeof(filename);
1879 of.lpstrFileTitle = NULL;
1880 of.lpstrInitialDir = NULL;
1881 of.lpstrTitle = "Select Public Key File";
1883 if (GetOpenFileName(&of)) {
1884 strcpy(cfg.keyfile, filename);
1885 SetDlgItemText (hwnd, IDC5_PKEDIT, cfg.keyfile);
1888 case IDC6_MBWINDOWS:
1890 cfg.mouse_is_xterm = IsDlgButtonChecked (hwnd, IDC6_MBXTERM);
1896 int n = GetDlgItemInt (hwnd, IDC6_CCEDIT, &ok, FALSE);
1901 for (i=0; i<256; i++)
1902 if (SendDlgItemMessage (hwnd, IDC6_CCLIST, LB_GETSEL,
1905 cfg.wordness[i] = n;
1906 SendDlgItemMessage (hwnd, IDC6_CCLIST,
1907 LB_DELETESTRING, i, 0);
1908 sprintf(str, "%d\t(0x%02X)\t%c\t%d", i, i,
1909 (i>=0x21 && i != 0x7F) ? i : ' ',
1911 SendDlgItemMessage (hwnd, IDC6_CCLIST,
1918 case IDC7_BOLDCOLOUR:
1919 if (HIWORD(wParam) == BN_CLICKED ||
1920 HIWORD(wParam) == BN_DOUBLECLICKED) {
1922 cfg.bold_colour = IsDlgButtonChecked (hwnd, IDC7_BOLDCOLOUR);
1923 n = SendDlgItemMessage (hwnd, IDC7_LIST, LB_GETCOUNT, 0, 0);
1924 if (cfg.bold_colour && n!=22) {
1925 for (i=0; i<22; i++)
1927 SendDlgItemMessage (hwnd, IDC7_LIST,
1929 (LPARAM) colours[i]);
1930 } else if (!cfg.bold_colour && n!=12) {
1933 SendDlgItemMessage (hwnd, IDC7_LIST,
1934 LB_DELETESTRING, i, 0);
1939 if (HIWORD(wParam) == BN_CLICKED ||
1940 HIWORD(wParam) == BN_DOUBLECLICKED)
1941 cfg.try_palette = IsDlgButtonChecked (hwnd, IDC7_PALETTE);
1944 if (HIWORD(wParam) == LBN_DBLCLK ||
1945 HIWORD(wParam) == LBN_SELCHANGE) {
1946 int i = SendDlgItemMessage (hwnd, IDC7_LIST, LB_GETCURSEL,
1948 if (!cfg.bold_colour)
1949 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1950 SetDlgItemInt (hwnd, IDC7_RVALUE, cfg.colours[i][0], FALSE);
1951 SetDlgItemInt (hwnd, IDC7_GVALUE, cfg.colours[i][1], FALSE);
1952 SetDlgItemInt (hwnd, IDC7_BVALUE, cfg.colours[i][2], FALSE);
1956 if (HIWORD(wParam) == BN_CLICKED ||
1957 HIWORD(wParam) == BN_DOUBLECLICKED) {
1958 static CHOOSECOLOR cc;
1959 static DWORD custom[16] = {0}; /* zero initialisers */
1960 int i = SendDlgItemMessage (hwnd, IDC7_LIST, LB_GETCURSEL,
1962 if (!cfg.bold_colour)
1963 i = (i < 3 ? i*2 : i == 3 ? 5 : i*2-2);
1964 cc.lStructSize = sizeof(cc);
1965 cc.hwndOwner = hwnd;
1966 cc.hInstance = (HWND)hinst;
1967 cc.lpCustColors = custom;
1968 cc.rgbResult = RGB (cfg.colours[i][0], cfg.colours[i][1],
1970 cc.Flags = CC_FULLOPEN | CC_RGBINIT;
1971 if (ChooseColor(&cc)) {
1973 (unsigned char) (cc.rgbResult & 0xFF);
1975 (unsigned char) (cc.rgbResult >> 8) & 0xFF;
1977 (unsigned char) (cc.rgbResult >> 16) & 0xFF;
1978 SetDlgItemInt (hwnd, IDC7_RVALUE, cfg.colours[i][0],
1980 SetDlgItemInt (hwnd, IDC7_GVALUE, cfg.colours[i][1],
1982 SetDlgItemInt (hwnd, IDC7_BVALUE, cfg.colours[i][2],
1988 case IDC8_KOI8WIN1251:
1989 case IDC8_88592WIN1250:
1990 cfg.xlat_enablekoiwin =
1991 IsDlgButtonChecked (hwnd, IDC8_KOI8WIN1251);
1992 cfg.xlat_88592w1250 =
1993 IsDlgButtonChecked (hwnd, IDC8_88592WIN1250);
1995 case IDC8_CAPSLOCKCYR:
1996 if (HIWORD(wParam) == BN_CLICKED ||
1997 HIWORD(wParam) == BN_DOUBLECLICKED) {
1998 cfg.xlat_capslockcyr =
1999 IsDlgButtonChecked (hwnd, IDC8_CAPSLOCKCYR);
2002 case IDC8_VTXWINDOWS:
2003 case IDC8_VTOEMANSI:
2004 case IDC8_VTOEMONLY:
2005 case IDC8_VTPOORMAN:
2007 (IsDlgButtonChecked (hwnd, IDC8_VTXWINDOWS) ? VT_XWINDOWS :
2008 IsDlgButtonChecked (hwnd, IDC8_VTOEMANSI) ? VT_OEMANSI :
2009 IsDlgButtonChecked (hwnd, IDC8_VTOEMONLY) ? VT_OEMONLY :
2015 EndDialog (hwnd, 0);
2018 /* Grrr Explorer will maximize Dialogs! */
2020 if (wParam == SIZE_MAXIMIZED)
2027 static int CALLBACK MainDlgProc (HWND hwnd, UINT msg,
2028 WPARAM wParam, LPARAM lParam) {
2029 static HWND page = NULL;
2031 if (msg == WM_COMMAND && LOWORD(wParam) == IDOK) {
2033 if (msg == WM_COMMAND && LOWORD(wParam) == IDCX_ABOUT) {
2034 EnableWindow(hwnd, 0);
2035 DialogBox(hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2036 GetParent(hwnd), AboutProc);
2037 EnableWindow(hwnd, 1);
2038 SetActiveWindow(hwnd);
2040 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 0);
2043 static int CALLBACK ReconfDlgProc (HWND hwnd, UINT msg,
2044 WPARAM wParam, LPARAM lParam) {
2046 return GenericMainDlgProc (hwnd, msg, wParam, lParam, 1);
2049 int do_config (void) {
2053 savedsession[0] = '\0';
2054 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_MAINBOX), NULL, MainDlgProc);
2055 get_sesslist(FALSE);
2060 int do_reconfig (HWND hwnd) {
2064 backup_cfg = cfg; /* structure copy */
2065 ret = DialogBox (hinst, MAKEINTRESOURCE(IDD_RECONF), hwnd, ReconfDlgProc);
2067 cfg = backup_cfg; /* structure copy */
2074 void logevent (char *string) {
2075 if (nevents >= negsize) {
2077 events = srealloc (events, negsize * sizeof(*events));
2079 events[nevents] = smalloc(1+strlen(string));
2080 strcpy (events[nevents], string);
2084 SendDlgItemMessage (logbox, IDN_LIST, LB_ADDSTRING,
2086 count = SendDlgItemMessage (logbox, IDN_LIST, LB_GETCOUNT, 0, 0);
2087 SendDlgItemMessage (logbox, IDN_LIST, LB_SETTOPINDEX, count-1, 0);
2091 void showeventlog (HWND hwnd) {
2093 logbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_LOGBOX),
2095 ShowWindow (logbox, SW_SHOWNORMAL);
2099 void showabout (HWND hwnd) {
2101 abtbox = CreateDialog (hinst, MAKEINTRESOURCE(IDD_ABOUTBOX),
2103 ShowWindow (abtbox, SW_SHOWNORMAL);
2107 void verify_ssh_host_key(char *host, int port, char *keytype,
2108 char *keystr, char *fingerprint) {
2111 static const char absentmsg[] =
2112 "The server's host key is not cached in the registry. You\n"
2113 "have no guarantee that the server is the computer you\n"
2115 "The server's key fingerprint is:\n"
2117 "If you trust this host, hit Yes to add the key to\n"
2118 "PuTTY's cache and carry on connecting.\n"
2119 "If you do not trust this host, hit No to abandon the\n"
2122 static const char wrongmsg[] =
2123 "WARNING - POTENTIAL SECURITY BREACH!\n"
2125 "The server's host key does not match the one PuTTY has\n"
2126 "cached in the registry. This means that either the\n"
2127 "server administrator has changed the host key, or you\n"
2128 "have actually connected to another computer pretending\n"
2129 "to be the server.\n"
2130 "The new key fingerprint is:\n"
2132 "If you were expecting this change and trust the new key,\n"
2133 "hit Yes to update PuTTY's cache and continue connecting.\n"
2134 "If you want to carry on connecting but without updating\n"
2135 "the cache, hit No.\n"
2136 "If you want to abandon the connection completely, hit\n"
2137 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2140 static const char mbtitle[] = "PuTTY Security Alert";
2143 char message[160+ /* sensible fingerprint max size */
2144 (sizeof(absentmsg) > sizeof(wrongmsg) ?
2145 sizeof(absentmsg) : sizeof(wrongmsg))];
2148 * Verify the key against the registry.
2150 ret = verify_host_key(host, port, keytype, keystr);
2152 if (ret == 0) /* success - key matched OK */
2154 if (ret == 2) { /* key was different */
2156 sprintf(message, wrongmsg, fingerprint);
2157 mbret = MessageBox(NULL, message, mbtitle,
2158 MB_ICONWARNING | MB_YESNOCANCEL);
2160 store_host_key(host, port, keytype, keystr);
2161 if (mbret == IDCANCEL)
2164 if (ret == 1) { /* key was absent */
2166 sprintf(message, absentmsg, fingerprint);
2167 mbret = MessageBox(NULL, message, mbtitle,
2168 MB_ICONWARNING | MB_YESNO);
2171 store_host_key(host, port, keytype, keystr);