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
, int sid
, int eid
) {
396 const int height
= (EDITHEIGHT
> STATICHEIGHT ?
397 EDITHEIGHT
: STATICHEIGHT
);
399 int lwid
, rwid
, rpos
;
401 rpos
= GAPBETWEEN
+ (cp
->width
+ GAPBETWEEN
) / 2;
402 lwid
= rpos
- 2*GAPBETWEEN
;
403 rwid
= cp
->width
+ GAPBETWEEN
- rpos
;
405 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
+ (height
-STATICHEIGHT
)/2;
406 r
.right
= lwid
; r
.bottom
= STATICHEIGHT
;
407 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, stext
, sid
);
409 r
.left
= rpos
; r
.top
= cp
->ypos
+ (height
-EDITHEIGHT
)/2;
410 r
.right
= rwid
; r
.bottom
= EDITHEIGHT
;
412 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| ES_AUTOHSCROLL
,
416 cp
->ypos
+= height
+ GAPBETWEEN
;
420 * A tab-control substitute when a real tab control is unavailable.
422 static void ersatztab(struct ctlpos
*cp
, char *stext
, int sid
,
424 const int height
= (COMBOHEIGHT
> STATICHEIGHT ?
425 COMBOHEIGHT
: STATICHEIGHT
);
427 int bigwid
, lwid
, rwid
, rpos
;
428 static const int BIGGAP
= 15;
429 static const int MEDGAP
= 3;
431 bigwid
= cp
->width
+ 2*GAPBETWEEN
- 2*BIGGAP
;
433 rpos
= BIGGAP
+ (bigwid
+ BIGGAP
) / 2;
434 lwid
= rpos
- 2*BIGGAP
;
435 rwid
= bigwid
+ BIGGAP
- rpos
;
437 r
.left
= BIGGAP
; r
.top
= cp
->ypos
+ (height
-STATICHEIGHT
)/2;
438 r
.right
= lwid
; r
.bottom
= STATICHEIGHT
;
439 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, stext
, sid
);
441 r
.left
= rpos
; r
.top
= cp
->ypos
+ (height
-COMBOHEIGHT
)/2;
442 r
.right
= rwid
; r
.bottom
= COMBOHEIGHT
*10;
443 doctl(cp
, r
, "COMBOBOX",
444 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
|
445 CBS_DROPDOWNLIST
| CBS_HASSTRINGS
,
449 cp
->ypos
+= height
+ MEDGAP
+ GAPBETWEEN
;
451 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
452 r
.right
= cp
->width
; r
.bottom
= 2;
453 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
| SS_ETCHEDHORZ
,
458 * A static line, followed by an edit control on the left hand side
459 * and a button on the right.
461 static void editbutton(struct ctlpos
*cp
, char *stext
, int sid
,
462 int eid
, char *btext
, int bid
) {
463 const int height
= (EDITHEIGHT
> PUSHBTNHEIGHT ?
464 EDITHEIGHT
: PUSHBTNHEIGHT
);
466 int lwid
, rwid
, rpos
;
468 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
469 r
.right
= cp
->width
; r
.bottom
= STATICHEIGHT
;
470 cp
->ypos
+= r
.bottom
+ GAPWITHIN
;
471 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, stext
, sid
);
473 rpos
= GAPBETWEEN
+ 3 * (cp
->width
+ GAPBETWEEN
) / 4;
474 lwid
= rpos
- 2*GAPBETWEEN
;
475 rwid
= cp
->width
+ GAPBETWEEN
- rpos
;
477 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
+ (height
-EDITHEIGHT
)/2;
478 r
.right
= lwid
; r
.bottom
= EDITHEIGHT
;
480 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| ES_AUTOHSCROLL
,
484 r
.left
= rpos
; r
.top
= cp
->ypos
+ (height
-PUSHBTNHEIGHT
)/2;
485 r
.right
= rwid
; r
.bottom
= PUSHBTNHEIGHT
;
486 doctl(cp
, r
, "BUTTON",
487 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| BS_PUSHBUTTON
,
491 cp
->ypos
+= height
+ GAPBETWEEN
;
495 * Special control which was hard to describe generically: the
496 * session-saver assembly. A static; below that an edit box; below
497 * that a list box. To the right of the list box, a column of
500 static void sesssaver(struct ctlpos
*cp
, char *text
,
501 int staticid
, int editid
, int listid
, ...) {
504 int lwid
, rwid
, rpos
;
506 const int LISTDEFHEIGHT
= 66;
508 rpos
= GAPBETWEEN
+ 3 * (cp
->width
+ GAPBETWEEN
) / 4;
509 lwid
= rpos
- 2*GAPBETWEEN
;
510 rwid
= cp
->width
+ GAPBETWEEN
- rpos
;
512 /* The static control. */
513 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
514 r
.right
= lwid
; r
.bottom
= STATICHEIGHT
;
515 cp
->ypos
+= r
.bottom
+ GAPWITHIN
;
516 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, text
, staticid
);
518 /* The edit control. */
519 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
520 r
.right
= lwid
; r
.bottom
= EDITHEIGHT
;
521 cp
->ypos
+= r
.bottom
+ GAPWITHIN
;
523 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| ES_AUTOHSCROLL
,
528 * The buttons (we should hold off on the list box until we
529 * know how big the buttons are).
531 va_start(ap
, listid
);
534 char *btext
= va_arg(ap
, char *);
537 bid
= va_arg(ap
, int);
538 r
.left
= rpos
; r
.top
= y
;
539 r
.right
= rwid
; r
.bottom
= PUSHBTNHEIGHT
;
540 y
+= r
.bottom
+ GAPWITHIN
;
541 doctl(cp
, r
, "BUTTON",
542 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| BS_PUSHBUTTON
,
547 /* Compute list box height. LISTDEFHEIGHT, or height of buttons. */
550 if (y
< LISTDEFHEIGHT
) y
= LISTDEFHEIGHT
;
551 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
552 r
.right
= lwid
; r
.bottom
= y
;
553 cp
->ypos
+= y
+ GAPBETWEEN
;
554 doctl(cp
, r
, "LISTBOX",
555 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_VSCROLL
|
556 LBS_NOTIFY
| LBS_HASSTRINGS
,
562 * Another special control: the environment-variable setter. A
563 * static line first; then a pair of edit boxes with associated
564 * statics, and two buttons; then a list box.
566 static void envsetter(struct ctlpos
*cp
, char *stext
, int sid
,
567 char *e1stext
, int e1sid
, int e1id
,
568 char *e2stext
, int e2sid
, int e2id
,
570 char *b1text
, int b1id
, char *b2text
, int b2id
) {
572 const int height
= (STATICHEIGHT
> EDITHEIGHT
&& STATICHEIGHT
> PUSHBTNHEIGHT ?
574 EDITHEIGHT
> PUSHBTNHEIGHT ?
575 EDITHEIGHT
: PUSHBTNHEIGHT
);
576 const static int percents
[] = { 20, 35, 10, 25 };
577 int i
, j
, xpos
, percent
;
578 const int LISTHEIGHT
= 42;
580 /* The static control. */
581 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
582 r
.right
= cp
->width
; r
.bottom
= STATICHEIGHT
;
583 cp
->ypos
+= r
.bottom
+ GAPWITHIN
;
584 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, stext
, sid
);
586 /* The statics+edits+buttons. */
587 for (j
= 0; j
< 2; j
++) {
589 for (i
= 0; i
< 4; i
++) {
590 xpos
= (cp
->width
+ GAPBETWEEN
) * percent
/ 100;
591 r
.left
= xpos
+ GAPBETWEEN
;
592 percent
+= percents
[i
];
593 xpos
= (cp
->width
+ GAPBETWEEN
) * percent
/ 100;
594 r
.right
= xpos
- r
.left
;
596 r
.bottom
= (i
==0 ? STATICHEIGHT
:
599 r
.top
+= (height
-r
.bottom
)/2;
601 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0,
602 j
==0 ? e1stext
: e2stext
, j
==0 ? e1sid
: e2sid
);
605 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| ES_AUTOHSCROLL
,
607 "", j
==0 ? e1id
: e2id
);
609 doctl(cp
, r
, "BUTTON",
610 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| BS_PUSHBUTTON
,
612 j
==0 ? b1text
: b2text
, j
==0 ? b1id
: b2id
);
615 cp
->ypos
+= height
+ GAPWITHIN
;
619 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
620 r
.right
= cp
->width
; r
.bottom
= LISTHEIGHT
;
621 cp
->ypos
+= r
.bottom
+ GAPBETWEEN
;
622 doctl(cp
, r
, "LISTBOX",
623 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_VSCROLL
| LBS_HASSTRINGS
|
630 * Yet another special control: the character-class setter. A
631 * static, then a list, then a line containing a
632 * button-and-static-and-edit.
634 static void charclass(struct ctlpos
*cp
, char *stext
, int sid
, int listid
,
635 char *btext
, int bid
, int eid
, char *s2text
, int s2id
) {
637 const int height
= (STATICHEIGHT
> EDITHEIGHT
&& STATICHEIGHT
> PUSHBTNHEIGHT ?
639 EDITHEIGHT
> PUSHBTNHEIGHT ?
640 EDITHEIGHT
: PUSHBTNHEIGHT
);
641 const static int percents
[] = { 30, 40, 30 };
642 int i
, xpos
, percent
;
643 const int LISTHEIGHT
= 66;
645 /* The static control. */
646 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
647 r
.right
= cp
->width
; r
.bottom
= STATICHEIGHT
;
648 cp
->ypos
+= r
.bottom
+ GAPWITHIN
;
649 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, stext
, sid
);
652 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
653 r
.right
= cp
->width
; r
.bottom
= LISTHEIGHT
;
654 cp
->ypos
+= r
.bottom
+ GAPWITHIN
;
655 doctl(cp
, r
, "LISTBOX",
656 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_VSCROLL
| LBS_HASSTRINGS
|
661 /* The button+static+edit. */
663 for (i
= 0; i
< 3; i
++) {
664 r
.left
= xpos
+ GAPBETWEEN
;
665 percent
+= percents
[i
];
666 xpos
= (cp
->width
+ GAPBETWEEN
) * percent
/ 100;
667 r
.right
= xpos
- r
.left
;
669 r
.bottom
= (i
==0 ? PUSHBTNHEIGHT
:
670 i
==1 ? STATICHEIGHT
:
672 r
.top
+= (height
-r
.bottom
)/2;
674 doctl(cp
, r
, "BUTTON",
675 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| BS_PUSHBUTTON
,
678 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
| SS_CENTER
,
682 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| ES_AUTOHSCROLL
,
683 WS_EX_CLIENTEDGE
, "", eid
);
686 cp
->ypos
+= height
+ GAPBETWEEN
;
690 * A special control (horrors!). The colour editor. A static line;
691 * then on the left, a list box, and on the right, a sequence of
692 * two-part statics followed by a button.
694 static void colouredit(struct ctlpos
*cp
, char *stext
, int sid
, int listid
,
695 char *btext
, int bid
, ...) {
699 int lwid
, rwid
, rpos
;
700 const int LISTHEIGHT
= 66;
702 /* The static control. */
703 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
704 r
.right
= cp
->width
; r
.bottom
= STATICHEIGHT
;
705 cp
->ypos
+= r
.bottom
+ GAPWITHIN
;
706 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, stext
, sid
);
708 rpos
= GAPBETWEEN
+ 2 * (cp
->width
+ GAPBETWEEN
) / 3;
709 lwid
= rpos
- 2*GAPBETWEEN
;
710 rwid
= cp
->width
+ GAPBETWEEN
- rpos
;
713 r
.left
= GAPBETWEEN
; r
.top
= cp
->ypos
;
714 r
.right
= lwid
; r
.bottom
= LISTHEIGHT
;
715 doctl(cp
, r
, "LISTBOX",
716 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| WS_VSCROLL
| LBS_HASSTRINGS
|
727 ltext
= va_arg(ap
, char *);
729 lid
= va_arg(ap
, int);
730 rid
= va_arg(ap
, int);
731 r
.top
= y
; r
.bottom
= STATICHEIGHT
;
732 y
+= r
.bottom
+ GAPWITHIN
;
733 r
.left
= rpos
; r
.right
= rwid
/2;
734 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
, 0, ltext
, lid
);
735 r
.left
= rpos
+ r
.right
; r
.right
= rwid
- r
.right
;
736 doctl(cp
, r
, "STATIC", WS_CHILD
| WS_VISIBLE
| SS_RIGHT
, 0, "", rid
);
741 r
.top
= y
+ 2*GAPWITHIN
; r
.bottom
= PUSHBTNHEIGHT
;
742 r
.left
= rpos
; r
.right
= rwid
;
743 doctl(cp
, r
, "BUTTON",
744 WS_CHILD
| WS_VISIBLE
| WS_TABSTOP
| BS_PUSHBUTTON
,
747 cp
->ypos
+= LISTHEIGHT
+ GAPBETWEEN
;
750 static char savedsession
[2048];
752 enum { IDCX_ABOUT
= IDC_ABOUT
, IDCX_TAB
, controlstartvalue
,
754 connectionpanelstart
,
891 translationpanelstart
,
907 static const char *const colours
[] = {
908 "Default Foreground", "Default Bold Foreground",
909 "Default Background", "Default Bold Background",
910 "Cursor Text", "Cursor Colour",
911 "ANSI Black", "ANSI Black Bold",
912 "ANSI Red", "ANSI Red Bold",
913 "ANSI Green", "ANSI Green Bold",
914 "ANSI Yellow", "ANSI Yellow Bold",
915 "ANSI Blue", "ANSI Blue Bold",
916 "ANSI Magenta", "ANSI Magenta Bold",
917 "ANSI Cyan", "ANSI Cyan Bold",
918 "ANSI White", "ANSI White Bold"
920 static const int permcolour
[] = {
921 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, TRUE
,
922 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
,
923 TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
, TRUE
, FALSE
926 static void fmtfont (char *buf
) {
927 sprintf (buf
, "Font: %s, ", cfg
.font
);
929 strcat(buf
, "bold, ");
930 if (cfg
.fontheight
== 0)
931 strcat (buf
, "default height");
933 sprintf (buf
+strlen(buf
), "%d-%s",
934 (cfg
.fontheight
< 0 ?
-cfg
.fontheight
: cfg
.fontheight
),
935 (cfg
.fontheight
< 0 ?
"pixel" : "point"));
938 static void init_dlg_ctrls(HWND hwnd
) {
940 char fontstatic
[256];
942 SetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
);
943 SetDlgItemText (hwnd
, IDC0_SESSEDIT
, savedsession
);
944 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
945 for (i
= 0; i
< nsessions
; i
++)
946 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
947 0, (LPARAM
) (sessions
[i
]));
948 CheckRadioButton (hwnd
, IDC0_PROTRAW
, IDC0_PROTSSH
,
949 cfg
.protocol
==PROT_SSH ? IDC0_PROTSSH
:
950 cfg
.protocol
==PROT_TELNET ? IDC0_PROTTELNET
: IDC0_PROTRAW
);
951 CheckDlgButton (hwnd
, IDC0_CLOSEEXIT
, cfg
.close_on_exit
);
952 CheckDlgButton (hwnd
, IDC0_CLOSEWARN
, cfg
.warn_on_close
);
954 CheckRadioButton (hwnd
, IDC1_DEL008
, IDC1_DEL127
,
955 cfg
.bksp_is_delete ? IDC1_DEL127
: IDC1_DEL008
);
956 CheckRadioButton (hwnd
, IDC1_HOMETILDE
, IDC1_HOMERXVT
,
957 cfg
.rxvt_homeend ? IDC1_HOMERXVT
: IDC1_HOMETILDE
);
958 CheckRadioButton (hwnd
, IDC1_FUNCTILDE
, IDC1_FUNCXTERM
,
960 (cfg
.funky_type
==2 ? IDC1_FUNCXTERM
963 CheckRadioButton (hwnd
, IDC1_CURNORMAL
, IDC1_CURAPPLIC
,
964 cfg
.app_cursor ? IDC1_CURAPPLIC
: IDC1_CURNORMAL
);
965 CheckRadioButton (hwnd
, IDC1_KPNORMAL
, IDC1_KPNH
,
966 cfg
.nethack_keypad ? IDC1_KPNH
:
967 cfg
.app_keypad ? IDC1_KPAPPLIC
: IDC1_KPNORMAL
);
968 CheckDlgButton (hwnd
, IDC1_ALTF4
, cfg
.alt_f4
);
969 CheckDlgButton (hwnd
, IDC1_ALTSPACE
, cfg
.alt_space
);
970 CheckDlgButton (hwnd
, IDC1_LDISCTERM
, cfg
.ldisc_term
);
971 CheckDlgButton (hwnd
, IDC1_SCROLLKEY
, cfg
.scroll_on_key
);
973 CheckDlgButton (hwnd
, IDC2_WRAPMODE
, cfg
.wrap_mode
);
974 CheckDlgButton (hwnd
, IDC2_DECOM
, cfg
.dec_om
);
975 CheckDlgButton (hwnd
, IDC2_LFHASCR
, cfg
.lfhascr
);
976 SetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, cfg
.height
, FALSE
);
977 SetDlgItemInt (hwnd
, IDC2_COLSEDIT
, cfg
.width
, FALSE
);
978 SetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, cfg
.savelines
, FALSE
);
979 fmtfont (fontstatic
);
980 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
981 CheckDlgButton (hwnd
, IDC2_BEEP
, cfg
.beep
);
982 CheckDlgButton (hwnd
, IDC2_BCE
, cfg
.bce
);
983 CheckDlgButton (hwnd
, IDC2_BLINKTEXT
, cfg
.blinktext
);
985 SetDlgItemText (hwnd
, IDC3_WINEDIT
, cfg
.wintitle
);
986 CheckDlgButton (hwnd
, IDC3_WINNAME
, cfg
.win_name_always
);
987 CheckDlgButton (hwnd
, IDC3_BLINKCUR
, cfg
.blink_cur
);
988 CheckDlgButton (hwnd
, IDC3_SCROLLBAR
, cfg
.scrollbar
);
989 CheckDlgButton (hwnd
, IDC3_LOCKSIZE
, cfg
.locksize
);
991 SetDlgItemText (hwnd
, IDC4_TTEDIT
, cfg
.termtype
);
992 SetDlgItemText (hwnd
, IDC4_TSEDIT
, cfg
.termspeed
);
993 SetDlgItemText (hwnd
, IDC4_LOGEDIT
, cfg
.username
);
995 char *p
= cfg
.environmt
;
997 SendDlgItemMessage (hwnd
, IDC4_ENVLIST
, LB_ADDSTRING
, 0,
1002 CheckRadioButton (hwnd
, IDC4_EMBSD
, IDC4_EMRFC
,
1003 cfg
.rfc_environ ? IDC4_EMRFC
: IDC4_EMBSD
);
1005 SetDlgItemText (hwnd
, IDC5_TTEDIT
, cfg
.termtype
);
1006 SetDlgItemText (hwnd
, IDC5_LOGEDIT
, cfg
.username
);
1007 CheckDlgButton (hwnd
, IDC5_NOPTY
, cfg
.nopty
);
1008 CheckDlgButton (hwnd
, IDC5_AGENTFWD
, cfg
.agentfwd
);
1009 CheckRadioButton (hwnd
, IDC5_CIPHER3DES
, IDC5_CIPHERDES
,
1010 cfg
.cipher
== CIPHER_BLOWFISH ? IDC5_CIPHERBLOWF
:
1011 cfg
.cipher
== CIPHER_DES ? IDC5_CIPHERDES
:
1013 CheckRadioButton (hwnd
, IDC5_SSHPROT1
, IDC5_SSHPROT2
,
1014 cfg
.sshprot
== 1 ? IDC5_SSHPROT1
: IDC5_SSHPROT2
);
1015 CheckDlgButton (hwnd
, IDC5_AUTHTIS
, cfg
.try_tis_auth
);
1016 SetDlgItemText (hwnd
, IDC5_PKEDIT
, cfg
.keyfile
);
1017 SetDlgItemText (hwnd
, IDC5_CMDEDIT
, cfg
.remote_cmd
);
1019 CheckRadioButton (hwnd
, IDC6_MBWINDOWS
, IDC6_MBXTERM
,
1020 cfg
.mouse_is_xterm ? IDC6_MBXTERM
: IDC6_MBWINDOWS
);
1022 static int tabs
[4] = {25, 61, 96, 128};
1023 SendDlgItemMessage (hwnd
, IDC6_CCLIST
, LB_SETTABSTOPS
, 4,
1026 for (i
=0; i
<256; i
++) {
1028 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1029 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1031 SendDlgItemMessage (hwnd
, IDC6_CCLIST
, LB_ADDSTRING
, 0,
1035 CheckDlgButton (hwnd
, IDC7_BOLDCOLOUR
, cfg
.bold_colour
);
1036 CheckDlgButton (hwnd
, IDC7_PALETTE
, cfg
.try_palette
);
1039 for (i
=0; i
<22; i
++)
1040 if (cfg
.bold_colour
|| permcolour
[i
])
1041 SendDlgItemMessage (hwnd
, IDC7_LIST
, LB_ADDSTRING
, 0,
1042 (LPARAM
) colours
[i
]);
1044 SendDlgItemMessage (hwnd
, IDC7_LIST
, LB_SETCURSEL
, 0, 0);
1045 SetDlgItemInt (hwnd
, IDC7_RVALUE
, cfg
.colours
[0][0], FALSE
);
1046 SetDlgItemInt (hwnd
, IDC7_GVALUE
, cfg
.colours
[0][1], FALSE
);
1047 SetDlgItemInt (hwnd
, IDC7_BVALUE
, cfg
.colours
[0][2], FALSE
);
1049 CheckRadioButton (hwnd
, IDC8_NOXLAT
, IDC8_88592WIN1250
,
1050 cfg
.xlat_88592w1250 ? IDC8_88592WIN1250
:
1051 cfg
.xlat_enablekoiwin ? IDC8_KOI8WIN1251
:
1053 CheckDlgButton (hwnd
, IDC8_CAPSLOCKCYR
, cfg
.xlat_capslockcyr
);
1054 CheckRadioButton (hwnd
, IDC8_VTXWINDOWS
, IDC8_VTPOORMAN
,
1055 cfg
.vtmode
== VT_XWINDOWS ? IDC8_VTXWINDOWS
:
1056 cfg
.vtmode
== VT_OEMANSI ? IDC8_VTOEMANSI
:
1057 cfg
.vtmode
== VT_OEMONLY ? IDC8_VTOEMONLY
:
1061 static void hide(HWND hwnd
, int hide
, int minid
, int maxid
) {
1063 for (i
= minid
; i
< maxid
; i
++) {
1064 HWND ctl
= GetDlgItem(hwnd
, i
);
1066 ShowWindow(ctl
, hide ? SW_HIDE
: SW_SHOW
);
1072 * This _huge_ function is the configuration box.
1074 static int GenericMainDlgProc (HWND hwnd
, UINT msg
,
1075 WPARAM wParam
, LPARAM lParam
,
1080 char filename
[sizeof(cfg
.keyfile
)];
1083 char fontstatic
[256];
1088 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1090 * Centre the window.
1092 { /* centre the window */
1095 hw
= GetDesktopWindow();
1096 if (GetWindowRect (hw
, &rs
) && GetWindowRect (hwnd
, &rd
))
1097 MoveWindow (hwnd
, (rs
.right
+ rs
.left
+ rd
.left
- rd
.right
)/2,
1098 (rs
.bottom
+ rs
.top
+ rd
.top
- rd
.bottom
)/2,
1099 rd
.right
-rd
.left
, rd
.bottom
-rd
.top
, TRUE
);
1103 * Create the tab control.
1109 r
.left
= 3; r
.right
= r
.left
+ 174;
1110 r
.top
= 3; r
.bottom
= r
.top
+ 193;
1111 MapDialogRect(hwnd
, &r
);
1112 tabctl
= CreateWindowEx(0, WC_TABCONTROL
, "",
1113 WS_CHILD
| WS_VISIBLE
|
1114 WS_TABSTOP
| TCS_MULTILINE
,
1116 r
.right
-r
.left
, r
.bottom
-r
.top
,
1117 hwnd
, (HMENU
)IDCX_TAB
, hinst
, NULL
);
1118 font
= SendMessage(hwnd
, WM_GETFONT
, 0, 0);
1119 SendMessage(tabctl
, WM_SETFONT
, font
, MAKELPARAM(TRUE
, 0));
1123 * Create the various panelfuls of controls.
1128 /* The Connection panel. Accelerators used: [aco] dehlnprstwx */
1131 ctlposinit(&cp
, hwnd
, 6, 30);
1134 "Host &Name", IDC0_HOSTSTATIC
, IDC0_HOST
, 75,
1135 "&Port", IDC0_PORTSTATIC
, IDC0_PORT
, 25, NULL
);
1136 if (backends
[2].backend
== NULL
) {
1137 /* this is PuTTYtel, so only two protocols available */
1138 radioline(&cp
, "Protocol:", IDC0_PROTSTATIC
, 3,
1139 "&Raw", IDC0_PROTRAW
,
1140 "&Telnet", IDC0_PROTTELNET
, NULL
);
1142 radioline(&cp
, "Protocol:", IDC0_PROTSTATIC
, 3,
1143 "&Raw", IDC0_PROTRAW
,
1144 "&Telnet", IDC0_PROTTELNET
,
1150 IDC0_PROTSSH
, NULL
);
1152 sesssaver(&cp
, "Stor&ed Sessions",
1153 IDC0_SESSSTATIC
, IDC0_SESSEDIT
, IDC0_SESSLIST
,
1154 "&Load", IDC0_SESSLOAD
,
1155 "&Save", IDC0_SESSSAVE
,
1156 "&Delete", IDC0_SESSDEL
, NULL
);
1158 checkbox(&cp
, "Close Window on E&xit", IDC0_CLOSEEXIT
);
1159 checkbox(&cp
, "&Warn on Close", IDC0_CLOSEWARN
);
1161 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Connection";
1162 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1165 /* The Keyboard panel. Accelerators used: [aco] 4?ehiklmnprsuvxy */
1168 ctlposinit(&cp
, hwnd
, 6, 30);
1169 radioline(&cp
, "Action of Backspace:", IDC1_DELSTATIC
, 2,
1170 "Control-&H", IDC1_DEL008
,
1171 "Control-&? (127)", IDC1_DEL127
, NULL
);
1172 radioline(&cp
, "Action of Home and End:", IDC1_HOMESTATIC
, 2,
1173 "&Standard", IDC1_HOMETILDE
,
1174 "&rxvt", IDC1_HOMERXVT
, NULL
);
1175 radioline(&cp
, "Function key and keypad layout:", IDC1_FUNCSTATIC
, 3,
1176 "&VT400", IDC1_FUNCTILDE
,
1177 "&Linux", IDC1_FUNCLINUX
,
1178 "&Xterm R6", IDC1_FUNCXTERM
, NULL
);
1179 radioline(&cp
, "Initial state of cursor keys:", IDC1_CURSTATIC
, 2,
1180 "&Normal", IDC1_CURNORMAL
,
1181 "A&pplication", IDC1_CURAPPLIC
, NULL
);
1182 radioline(&cp
, "Initial state of numeric keypad:", IDC1_KPSTATIC
, 3,
1183 "Nor&mal", IDC1_KPNORMAL
,
1184 "Appl&ication", IDC1_KPAPPLIC
,
1185 "N&etHack", IDC1_KPNH
, NULL
);
1186 checkbox(&cp
, "ALT-F&4 is special (closes window)", IDC1_ALTF4
);
1187 checkbox(&cp
, "ALT-Space is special (S&ystem menu)", IDC1_ALTSPACE
);
1188 checkbox(&cp
, "&Use local terminal line discipline", IDC1_LDISCTERM
);
1189 checkbox(&cp
, "Reset scrollback on &keypress", IDC1_SCROLLKEY
);
1191 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Keyboard";
1192 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1195 /* The Terminal panel. Accelerators used: [aco] dghlmnprsw */
1198 ctlposinit(&cp
, hwnd
, 6, 30);
1200 "&Rows", IDC2_ROWSSTATIC
, IDC2_ROWSEDIT
, 33,
1201 "Colu&mns", IDC2_COLSSTATIC
, IDC2_COLSEDIT
, 33,
1202 "&Scrollback", IDC2_SAVESTATIC
, IDC2_SAVEEDIT
, 33,
1204 staticbtn(&cp
, "", IDC2_FONTSTATIC
, "C&hange...", IDC2_CHOOSEFONT
);
1205 checkbox(&cp
, "Auto &wrap mode initially on", IDC2_WRAPMODE
);
1206 checkbox(&cp
, "&DEC Origin Mode initially on", IDC2_DECOM
);
1207 checkbox(&cp
, "Implicit CR in every &LF", IDC2_LFHASCR
);
1208 checkbox(&cp
, "Bee&p enabled", IDC2_BEEP
);
1209 checkbox(&cp
, "Use Back&ground colour erase", IDC2_BCE
);
1210 checkbox(&cp
, "Enable bli&nking text", IDC2_BLINKTEXT
);
1211 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Terminal";
1212 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1215 /* The Window panel. Accelerators used: [aco] bikty */
1218 ctlposinit(&cp
, hwnd
, 6, 30);
1221 "Initial window &title:", IDC3_WINTITLE
,
1222 IDC3_WINEDIT
, 100, NULL
);
1223 checkbox(&cp
, "Avoid ever using &icon title", IDC3_WINNAME
);
1224 checkbox(&cp
, "&Blinking cursor", IDC3_BLINKCUR
);
1225 checkbox(&cp
, "Displa&y scrollbar", IDC3_SCROLLBAR
);
1226 checkbox(&cp
, "Loc&k Window size", IDC3_LOCKSIZE
);
1227 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Window";
1228 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1231 /* The Telnet panel. Accelerators used: [aco] bdflrstuv */
1234 ctlposinit(&cp
, hwnd
, 6, 30);
1236 staticedit(&cp
, "Terminal-&type string", IDC4_TTSTATIC
, IDC4_TTEDIT
);
1237 staticedit(&cp
, "Terminal-&speed string", IDC4_TSSTATIC
, IDC4_TSEDIT
);
1238 staticedit(&cp
, "Auto-login &username", IDC4_LOGSTATIC
, IDC4_LOGEDIT
);
1239 envsetter(&cp
, "Environment variables:", IDC4_ENVSTATIC
,
1240 "&Variable", IDC4_VARSTATIC
, IDC4_VAREDIT
,
1241 "Va&lue", IDC4_VALSTATIC
, IDC4_VALEDIT
,
1243 "A&dd", IDC4_ENVADD
, "&Remove", IDC4_ENVREMOVE
);
1244 radioline(&cp
, "Handling of OLD_ENVIRON ambiguity:", IDC4_EMSTATIC
, 2,
1245 "&BSD (commonplace)", IDC4_EMBSD
,
1246 "R&FC 1408 (unusual)", IDC4_EMRFC
, NULL
);
1247 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Telnet";
1248 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1252 /* The SSH panel. Accelerators used: [aco] 123abdkmprtuw */
1255 ctlposinit(&cp
, hwnd
, 6, 30);
1257 staticedit(&cp
, "Terminal-&type string", IDC5_TTSTATIC
, IDC5_TTEDIT
);
1258 staticedit(&cp
, "Auto-login &username", IDC5_LOGSTATIC
, IDC5_LOGEDIT
);
1260 "&Remote command:", IDC5_CMDSTATIC
, IDC5_CMDEDIT
, 100,
1262 checkbox(&cp
, "Don't allocate a &pseudo-terminal", IDC5_NOPTY
);
1263 checkbox(&cp
, "Atte&mpt TIS or CryptoCard authentication",
1265 checkbox(&cp
, "Allow &agent forwarding", IDC5_AGENTFWD
);
1266 editbutton(&cp
, "Private &key file for authentication:",
1267 IDC5_PKSTATIC
, IDC5_PKEDIT
, "Bro&wse...", IDC5_PKBUTTON
);
1268 radioline(&cp
, "Preferred SSH protocol version:",
1269 IDC5_SSHPROTSTATIC
, 2,
1270 "&1", IDC5_SSHPROT1
, "&2", IDC5_SSHPROT2
, NULL
);
1271 radioline(&cp
, "Preferred encryption algorithm:", IDC5_CIPHERSTATIC
, 3,
1272 "&3DES", IDC5_CIPHER3DES
,
1273 "&Blowfish", IDC5_CIPHERBLOWF
,
1274 "&DES", IDC5_CIPHERDES
, NULL
);
1275 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "SSH";
1276 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1280 /* The Selection panel. Accelerators used: [aco] stwx */
1283 ctlposinit(&cp
, hwnd
, 6, 30);
1284 radiobig(&cp
, "Action of mouse buttons:", IDC6_MBSTATIC
,
1285 "&Windows (Right pastes, Middle extends)", IDC6_MBWINDOWS
,
1286 "&xterm (Right extends, Middle pastes)", IDC6_MBXTERM
,
1288 charclass(&cp
, "Character classes:", IDC6_CCSTATIC
, IDC6_CCLIST
,
1289 "&Set", IDC6_CCSET
, IDC6_CCEDIT
,
1290 "&to class", IDC6_CCSTATIC2
);
1291 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Selection";
1292 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1295 /* The Colours panel. Accelerators used: [aco] bmlu */
1298 ctlposinit(&cp
, hwnd
, 6, 30);
1299 checkbox(&cp
, "&Bolded text is a different colour", IDC7_BOLDCOLOUR
);
1300 checkbox(&cp
, "Attempt to use &logical palettes", IDC7_PALETTE
);
1301 colouredit(&cp
, "Select a colo&ur and click to modify it:",
1302 IDC7_STATIC
, IDC7_LIST
,
1303 "&Modify...", IDC7_CHANGE
,
1304 "Red:", IDC7_RSTATIC
, IDC7_RVALUE
,
1305 "Green:", IDC7_GSTATIC
, IDC7_GVALUE
,
1306 "Blue:", IDC7_BSTATIC
, IDC7_BVALUE
, NULL
);
1307 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Colours";
1308 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1311 /* The Translation panel. Accelerators used: [aco] beiknpsx */
1314 ctlposinit(&cp
, hwnd
, 6, 30);
1316 "Handling of VT100 line drawing characters:", IDC8_VTSTATIC
,
1317 "Font has &XWindows encoding", IDC8_VTXWINDOWS
,
1318 "Use font in &both ANSI and OEM modes", IDC8_VTOEMANSI
,
1319 "Use font in O&EM mode only", IDC8_VTOEMONLY
,
1320 "&Poor man's line drawing (""+"", ""-"" and ""|"")",
1321 IDC8_VTPOORMAN
, NULL
);
1323 "Character set translation:", IDC8_XLATSTATIC
,
1324 "&None", IDC8_NOXLAT
,
1325 "&KOI8 / Win-1251", IDC8_KOI8WIN1251
,
1326 "&ISO-8859-2 / Win-1250", IDC8_88592WIN1250
, NULL
);
1327 checkbox(&cp
, "CAP&S LOCK acts as cyrillic switch", IDC8_CAPSLOCKCYR
);
1328 tab
.mask
= TCIF_TEXT
; tab
.pszText
= "Translation";
1329 TabCtrl_InsertItem (tabctl
, i
++, &tab
);
1332 init_dlg_ctrls(hwnd
);
1334 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
1335 hide(hwnd
, FALSE
, connectionpanelstart
, connectionpanelend
);
1338 * Set focus into the first available control.
1342 ctl
= GetDlgItem(hwnd
, IDC0_HOST
);
1343 if (!ctl
) ctl
= GetDlgItem(hwnd
, IDC0_CLOSEEXIT
);
1347 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1351 * Button release should trigger WM_OK if there was a
1352 * previous double click on the session list.
1356 SendMessage (hwnd
, WM_COMMAND
, IDOK
, 0);
1359 if (LOWORD(wParam
) == IDCX_TAB
&&
1360 ((LPNMHDR
)lParam
)->code
== TCN_SELCHANGE
) {
1361 int i
= TabCtrl_GetCurSel(((LPNMHDR
)lParam
)->hwndFrom
);
1364 item
.pszText
= buffer
;
1365 item
.cchTextMax
= sizeof(buffer
);
1366 item
.mask
= TCIF_TEXT
;
1367 TabCtrl_GetItem(((LPNMHDR
)lParam
)->hwndFrom
, i
, &item
);
1368 hide(hwnd
, TRUE
, controlstartvalue
, controlendvalue
);
1369 if (!strcmp(buffer
, "Connection"))
1370 hide(hwnd
, FALSE
, connectionpanelstart
, connectionpanelend
);
1371 if (!strcmp(buffer
, "Keyboard"))
1372 hide(hwnd
, FALSE
, keyboardpanelstart
, keyboardpanelend
);
1373 if (!strcmp(buffer
, "Terminal"))
1374 hide(hwnd
, FALSE
, terminalpanelstart
, terminalpanelend
);
1375 if (!strcmp(buffer
, "Window"))
1376 hide(hwnd
, FALSE
, windowpanelstart
, windowpanelend
);
1377 if (!strcmp(buffer
, "Telnet"))
1378 hide(hwnd
, FALSE
, telnetpanelstart
, telnetpanelend
);
1379 if (!strcmp(buffer
, "SSH"))
1380 hide(hwnd
, FALSE
, sshpanelstart
, sshpanelend
);
1381 if (!strcmp(buffer
, "Selection"))
1382 hide(hwnd
, FALSE
, selectionpanelstart
, selectionpanelend
);
1383 if (!strcmp(buffer
, "Colours"))
1384 hide(hwnd
, FALSE
, colourspanelstart
, colourspanelend
);
1385 if (!strcmp(buffer
, "Translation"))
1386 hide(hwnd
, FALSE
, translationpanelstart
, translationpanelend
);
1388 SetFocus (((LPNMHDR
)lParam
)->hwndFrom
); /* ensure focus stays */
1394 * Only process WM_COMMAND once the dialog is fully formed.
1396 if (GetWindowLong(hwnd
, GWL_USERDATA
) == 1) switch (LOWORD(wParam
)) {
1399 EndDialog (hwnd
, 1);
1404 EndDialog (hwnd
, 0);
1406 case IDC0_PROTTELNET
:
1409 if (HIWORD(wParam
) == BN_CLICKED
||
1410 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1411 int i
= IsDlgButtonChecked (hwnd
, IDC0_PROTSSH
);
1412 int j
= IsDlgButtonChecked (hwnd
, IDC0_PROTTELNET
);
1413 cfg
.protocol
= i ? PROT_SSH
: j ? PROT_TELNET
: PROT_RAW
;
1414 if ((cfg
.protocol
== PROT_SSH
&& cfg
.port
== 23) ||
1415 (cfg
.protocol
== PROT_TELNET
&& cfg
.port
== 22)) {
1416 cfg
.port
= i ?
22 : 23;
1417 SetDlgItemInt (hwnd
, IDC0_PORT
, cfg
.port
, FALSE
);
1422 if (HIWORD(wParam
) == EN_CHANGE
)
1423 GetDlgItemText (hwnd
, IDC0_HOST
, cfg
.host
,
1424 sizeof(cfg
.host
)-1);
1427 if (HIWORD(wParam
) == EN_CHANGE
)
1428 MyGetDlgItemInt (hwnd
, IDC0_PORT
, &cfg
.port
);
1430 case IDC0_CLOSEEXIT
:
1431 if (HIWORD(wParam
) == BN_CLICKED
||
1432 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1433 cfg
.close_on_exit
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEEXIT
);
1435 case IDC0_CLOSEWARN
:
1436 if (HIWORD(wParam
) == BN_CLICKED
||
1437 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1438 cfg
.warn_on_close
= IsDlgButtonChecked (hwnd
, IDC0_CLOSEWARN
);
1441 if (HIWORD(wParam
) == EN_CHANGE
) {
1442 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
1444 GetDlgItemText (hwnd
, IDC0_SESSEDIT
,
1445 savedsession
, sizeof(savedsession
)-1);
1446 savedsession
[sizeof(savedsession
)-1] = '\0';
1450 if (HIWORD(wParam
) == BN_CLICKED
||
1451 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1456 GetDlgItemText (hwnd
, IDC0_SESSEDIT
, str
, sizeof(str
)-1);
1458 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
1459 LB_GETCURSEL
, 0, 0);
1464 strcpy (str
, sessions
[n
]);
1466 save_settings (str
, !!strcmp(str
, "Default Settings"), &cfg
);
1467 get_sesslist (FALSE
);
1468 get_sesslist (TRUE
);
1469 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
1471 for (i
= 0; i
< nsessions
; i
++)
1472 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
1473 0, (LPARAM
) (sessions
[i
]));
1474 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
1480 if (LOWORD(wParam
) == IDC0_SESSLOAD
&&
1481 HIWORD(wParam
) != BN_CLICKED
&&
1482 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1484 if (LOWORD(wParam
) == IDC0_SESSLIST
&&
1485 HIWORD(wParam
) != LBN_DBLCLK
)
1488 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
1489 LB_GETCURSEL
, 0, 0);
1494 load_settings (sessions
[n
],
1495 !!strcmp(sessions
[n
], "Default Settings"),
1497 init_dlg_ctrls(hwnd
);
1499 if (LOWORD(wParam
) == IDC0_SESSLIST
) {
1501 * A double-click on a saved session should
1502 * actually start the session, not just load it.
1503 * Unless it's Default Settings or some other
1504 * host-less set of saved settings.
1513 if (HIWORD(wParam
) == BN_CLICKED
||
1514 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1515 int n
= SendDlgItemMessage (hwnd
, IDC0_SESSLIST
,
1516 LB_GETCURSEL
, 0, 0);
1517 if (n
== LB_ERR
|| n
== 0) {
1521 del_settings(sessions
[n
]);
1522 get_sesslist (FALSE
);
1523 get_sesslist (TRUE
);
1524 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_RESETCONTENT
,
1526 for (i
= 0; i
< nsessions
; i
++)
1527 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_ADDSTRING
,
1528 0, (LPARAM
) (sessions
[i
]));
1529 SendDlgItemMessage (hwnd
, IDC0_SESSLIST
, LB_SETCURSEL
,
1534 if (HIWORD(wParam
) == BN_CLICKED
||
1535 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1536 cfg
.bksp_is_delete
= IsDlgButtonChecked (hwnd
, IDC1_DEL127
);
1538 case IDC1_HOMETILDE
:
1540 if (HIWORD(wParam
) == BN_CLICKED
||
1541 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1542 cfg
.rxvt_homeend
= IsDlgButtonChecked (hwnd
, IDC1_HOMERXVT
);
1544 case IDC1_FUNCXTERM
:
1545 if (HIWORD(wParam
) == BN_CLICKED
||
1546 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1549 case IDC1_FUNCTILDE
:
1550 case IDC1_FUNCLINUX
:
1551 if (HIWORD(wParam
) == BN_CLICKED
||
1552 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1553 cfg
.funky_type
= IsDlgButtonChecked (hwnd
, IDC1_FUNCLINUX
);
1557 if (HIWORD(wParam
) == BN_CLICKED
||
1558 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1559 cfg
.app_keypad
= IsDlgButtonChecked (hwnd
, IDC1_KPAPPLIC
);
1560 cfg
.nethack_keypad
= FALSE
;
1564 if (HIWORD(wParam
) == BN_CLICKED
||
1565 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1566 cfg
.app_keypad
= FALSE
;
1567 cfg
.nethack_keypad
= TRUE
;
1570 case IDC1_CURNORMAL
:
1571 case IDC1_CURAPPLIC
:
1572 if (HIWORD(wParam
) == BN_CLICKED
||
1573 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1574 cfg
.app_cursor
= IsDlgButtonChecked (hwnd
, IDC1_CURAPPLIC
);
1577 if (HIWORD(wParam
) == BN_CLICKED
||
1578 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1579 cfg
.alt_f4
= IsDlgButtonChecked (hwnd
, IDC1_ALTF4
);
1582 if (HIWORD(wParam
) == BN_CLICKED
||
1583 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1584 cfg
.alt_space
= IsDlgButtonChecked (hwnd
, IDC1_ALTSPACE
);
1586 case IDC1_LDISCTERM
:
1587 if (HIWORD(wParam
) == BN_CLICKED
||
1588 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1589 cfg
.ldisc_term
= IsDlgButtonChecked (hwnd
, IDC1_LDISCTERM
);
1591 case IDC1_SCROLLKEY
:
1592 if (HIWORD(wParam
) == BN_CLICKED
||
1593 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1594 cfg
.scroll_on_key
= IsDlgButtonChecked (hwnd
, IDC1_SCROLLKEY
);
1597 if (HIWORD(wParam
) == BN_CLICKED
||
1598 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1599 cfg
.wrap_mode
= IsDlgButtonChecked (hwnd
, IDC2_WRAPMODE
);
1602 if (HIWORD(wParam
) == BN_CLICKED
||
1603 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1604 cfg
.dec_om
= IsDlgButtonChecked (hwnd
, IDC2_DECOM
);
1607 if (HIWORD(wParam
) == BN_CLICKED
||
1608 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1609 cfg
.lfhascr
= IsDlgButtonChecked (hwnd
, IDC2_LFHASCR
);
1612 if (HIWORD(wParam
) == EN_CHANGE
)
1613 MyGetDlgItemInt (hwnd
, IDC2_ROWSEDIT
, &cfg
.height
);
1616 if (HIWORD(wParam
) == EN_CHANGE
)
1617 MyGetDlgItemInt (hwnd
, IDC2_COLSEDIT
, &cfg
.width
);
1620 if (HIWORD(wParam
) == EN_CHANGE
)
1621 MyGetDlgItemInt (hwnd
, IDC2_SAVEEDIT
, &cfg
.savelines
);
1623 case IDC2_CHOOSEFONT
:
1624 lf
.lfHeight
= cfg
.fontheight
;
1625 lf
.lfWidth
= lf
.lfEscapement
= lf
.lfOrientation
= 0;
1626 lf
.lfItalic
= lf
.lfUnderline
= lf
.lfStrikeOut
= 0;
1627 lf
.lfWeight
= (cfg
.fontisbold ? FW_BOLD
: 0);
1628 lf
.lfCharSet
= cfg
.fontcharset
;
1629 lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1630 lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1631 lf
.lfQuality
= DEFAULT_QUALITY
;
1632 lf
.lfPitchAndFamily
= FIXED_PITCH
| FF_DONTCARE
;
1633 strncpy (lf
.lfFaceName
, cfg
.font
, sizeof(lf
.lfFaceName
)-1);
1634 lf
.lfFaceName
[sizeof(lf
.lfFaceName
)-1] = '\0';
1636 cf
.lStructSize
= sizeof(cf
);
1637 cf
.hwndOwner
= hwnd
;
1639 cf
.Flags
= CF_FIXEDPITCHONLY
| CF_FORCEFONTEXIST
|
1640 CF_INITTOLOGFONTSTRUCT
| CF_SCREENFONTS
;
1642 if (ChooseFont (&cf
)) {
1643 strncpy (cfg
.font
, lf
.lfFaceName
, sizeof(cfg
.font
)-1);
1644 cfg
.font
[sizeof(cfg
.font
)-1] = '\0';
1645 cfg
.fontisbold
= (lf
.lfWeight
== FW_BOLD
);
1646 cfg
.fontcharset
= lf
.lfCharSet
;
1647 cfg
.fontheight
= lf
.lfHeight
;
1648 fmtfont (fontstatic
);
1649 SetDlgItemText (hwnd
, IDC2_FONTSTATIC
, fontstatic
);
1653 if (HIWORD(wParam
) == BN_CLICKED
||
1654 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1655 cfg
.beep
= IsDlgButtonChecked (hwnd
, IDC2_BEEP
);
1657 case IDC2_BLINKTEXT
:
1658 if (HIWORD(wParam
) == BN_CLICKED
||
1659 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1660 cfg
.blinktext
= IsDlgButtonChecked (hwnd
, IDC2_BLINKTEXT
);
1663 if (HIWORD(wParam
) == BN_CLICKED
||
1664 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1665 cfg
.bce
= IsDlgButtonChecked (hwnd
, IDC2_BCE
);
1668 if (HIWORD(wParam
) == BN_CLICKED
||
1669 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1670 cfg
.win_name_always
= IsDlgButtonChecked (hwnd
, IDC3_WINNAME
);
1673 if (HIWORD(wParam
) == BN_CLICKED
||
1674 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1675 cfg
.blink_cur
= IsDlgButtonChecked (hwnd
, IDC3_BLINKCUR
);
1677 case IDC3_SCROLLBAR
:
1678 if (HIWORD(wParam
) == BN_CLICKED
||
1679 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1680 cfg
.scrollbar
= IsDlgButtonChecked (hwnd
, IDC3_SCROLLBAR
);
1683 if (HIWORD(wParam
) == BN_CLICKED
||
1684 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1685 cfg
.locksize
= IsDlgButtonChecked (hwnd
, IDC3_LOCKSIZE
);
1688 if (HIWORD(wParam
) == EN_CHANGE
)
1689 GetDlgItemText (hwnd
, IDC3_WINEDIT
, cfg
.wintitle
,
1690 sizeof(cfg
.wintitle
)-1);
1693 if (HIWORD(wParam
) == EN_CHANGE
)
1694 GetDlgItemText (hwnd
, IDC4_TTEDIT
, cfg
.termtype
,
1695 sizeof(cfg
.termtype
)-1);
1698 if (HIWORD(wParam
) == EN_CHANGE
)
1699 GetDlgItemText (hwnd
, IDC4_TSEDIT
, cfg
.termspeed
,
1700 sizeof(cfg
.termspeed
)-1);
1703 if (HIWORD(wParam
) == EN_CHANGE
) {
1704 GetDlgItemText (hwnd
, IDC4_LOGEDIT
, cfg
.username
,
1705 sizeof(cfg
.username
)-1);
1706 cfg
.username
[sizeof(cfg
.username
)-1] = '\0';
1707 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1708 SetDlgItemText (hwnd
, IDC5_LOGEDIT
, cfg
.username
);
1709 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1714 cfg
.rfc_environ
= IsDlgButtonChecked (hwnd
, IDC4_EMRFC
);
1717 if (HIWORD(wParam
) == BN_CLICKED
||
1718 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1719 char str
[sizeof(cfg
.environmt
)];
1721 GetDlgItemText (hwnd
, IDC4_VAREDIT
, str
, sizeof(str
)-1);
1726 p
= str
+ strlen(str
);
1728 GetDlgItemText (hwnd
, IDC4_VALEDIT
, p
, sizeof(str
)-1-(p
-str
));
1738 if ((p
-cfg
.environmt
) + strlen(str
) + 2 < sizeof(cfg
.environmt
)) {
1740 p
[strlen(str
)+1] = '\0';
1741 SendDlgItemMessage (hwnd
, IDC4_ENVLIST
, LB_ADDSTRING
,
1743 SetDlgItemText (hwnd
, IDC4_VAREDIT
, "");
1744 SetDlgItemText (hwnd
, IDC4_VALEDIT
, "");
1746 MessageBox(hwnd
, "Environment too big", "PuTTY Error",
1747 MB_OK
| MB_ICONERROR
);
1751 case IDC4_ENVREMOVE
:
1752 if (HIWORD(wParam
) != BN_CLICKED
&&
1753 HIWORD(wParam
) != BN_DOUBLECLICKED
)
1755 i
= SendDlgItemMessage (hwnd
, IDC4_ENVLIST
, LB_GETCURSEL
, 0, 0);
1761 SendDlgItemMessage (hwnd
, IDC4_ENVLIST
, LB_DELETESTRING
,
1786 if (HIWORD(wParam
) == EN_CHANGE
)
1787 GetDlgItemText (hwnd
, IDC5_TTEDIT
, cfg
.termtype
,
1788 sizeof(cfg
.termtype
)-1);
1791 if (HIWORD(wParam
) == EN_CHANGE
) {
1792 GetDlgItemText (hwnd
, IDC5_LOGEDIT
, cfg
.username
,
1793 sizeof(cfg
.username
)-1);
1794 cfg
.username
[sizeof(cfg
.username
)-1] = '\0';
1795 SetWindowLong(hwnd
, GWL_USERDATA
, 0);
1796 SetDlgItemText (hwnd
, IDC4_LOGEDIT
, cfg
.username
);
1797 SetWindowLong(hwnd
, GWL_USERDATA
, 1);
1801 if (HIWORD(wParam
) == BN_CLICKED
||
1802 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1803 cfg
.nopty
= IsDlgButtonChecked (hwnd
, IDC5_NOPTY
);
1806 if (HIWORD(wParam
) == BN_CLICKED
||
1807 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1808 cfg
.agentfwd
= IsDlgButtonChecked (hwnd
, IDC5_AGENTFWD
);
1810 case IDC5_CIPHER3DES
:
1811 case IDC5_CIPHERBLOWF
:
1812 case IDC5_CIPHERDES
:
1813 if (HIWORD(wParam
) == BN_CLICKED
||
1814 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1815 if (IsDlgButtonChecked (hwnd
, IDC5_CIPHER3DES
))
1816 cfg
.cipher
= CIPHER_3DES
;
1817 else if (IsDlgButtonChecked (hwnd
, IDC5_CIPHERBLOWF
))
1818 cfg
.cipher
= CIPHER_BLOWFISH
;
1819 else if (IsDlgButtonChecked (hwnd
, IDC5_CIPHERDES
))
1820 cfg
.cipher
= CIPHER_DES
;
1825 if (HIWORD(wParam
) == BN_CLICKED
||
1826 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1827 if (IsDlgButtonChecked (hwnd
, IDC5_SSHPROT1
))
1829 else if (IsDlgButtonChecked (hwnd
, IDC5_SSHPROT2
))
1834 if (HIWORD(wParam
) == BN_CLICKED
||
1835 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1836 cfg
.try_tis_auth
= IsDlgButtonChecked (hwnd
, IDC5_AUTHTIS
);
1839 if (HIWORD(wParam
) == EN_CHANGE
)
1840 GetDlgItemText (hwnd
, IDC5_PKEDIT
, cfg
.keyfile
,
1841 sizeof(cfg
.keyfile
)-1);
1844 if (HIWORD(wParam
) == EN_CHANGE
)
1845 GetDlgItemText (hwnd
, IDC5_CMDEDIT
, cfg
.remote_cmd
,
1846 sizeof(cfg
.remote_cmd
)-1);
1849 memset(&of
, 0, sizeof(of
));
1850 #ifdef OPENFILENAME_SIZE_VERSION_400
1851 of
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
1853 of
.lStructSize
= sizeof(of
);
1855 of
.hwndOwner
= hwnd
;
1856 of
.lpstrFilter
= "All Files\0*\0\0\0";
1857 of
.lpstrCustomFilter
= NULL
;
1858 of
.nFilterIndex
= 1;
1859 of
.lpstrFile
= filename
; strcpy(filename
, cfg
.keyfile
);
1860 of
.nMaxFile
= sizeof(filename
);
1861 of
.lpstrFileTitle
= NULL
;
1862 of
.lpstrInitialDir
= NULL
;
1863 of
.lpstrTitle
= "Select Public Key File";
1865 if (GetOpenFileName(&of
)) {
1866 strcpy(cfg
.keyfile
, filename
);
1867 SetDlgItemText (hwnd
, IDC5_PKEDIT
, cfg
.keyfile
);
1870 case IDC6_MBWINDOWS
:
1872 cfg
.mouse_is_xterm
= IsDlgButtonChecked (hwnd
, IDC6_MBXTERM
);
1878 int n
= GetDlgItemInt (hwnd
, IDC6_CCEDIT
, &ok
, FALSE
);
1883 for (i
=0; i
<256; i
++)
1884 if (SendDlgItemMessage (hwnd
, IDC6_CCLIST
, LB_GETSEL
,
1887 cfg
.wordness
[i
] = n
;
1888 SendDlgItemMessage (hwnd
, IDC6_CCLIST
,
1889 LB_DELETESTRING
, i
, 0);
1890 sprintf(str
, "%d\t(0x%02X)\t%c\t%d", i
, i
,
1891 (i
>=0x21 && i
!= 0x7F) ? i
: ' ',
1893 SendDlgItemMessage (hwnd
, IDC6_CCLIST
,
1900 case IDC7_BOLDCOLOUR
:
1901 if (HIWORD(wParam
) == BN_CLICKED
||
1902 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1904 cfg
.bold_colour
= IsDlgButtonChecked (hwnd
, IDC7_BOLDCOLOUR
);
1905 n
= SendDlgItemMessage (hwnd
, IDC7_LIST
, LB_GETCOUNT
, 0, 0);
1906 if (cfg
.bold_colour
&& n
!=22) {
1907 for (i
=0; i
<22; i
++)
1909 SendDlgItemMessage (hwnd
, IDC7_LIST
,
1911 (LPARAM
) colours
[i
]);
1912 } else if (!cfg
.bold_colour
&& n
!=12) {
1915 SendDlgItemMessage (hwnd
, IDC7_LIST
,
1916 LB_DELETESTRING
, i
, 0);
1921 if (HIWORD(wParam
) == BN_CLICKED
||
1922 HIWORD(wParam
) == BN_DOUBLECLICKED
)
1923 cfg
.try_palette
= IsDlgButtonChecked (hwnd
, IDC7_PALETTE
);
1926 if (HIWORD(wParam
) == LBN_DBLCLK
||
1927 HIWORD(wParam
) == LBN_SELCHANGE
) {
1928 int i
= SendDlgItemMessage (hwnd
, IDC7_LIST
, LB_GETCURSEL
,
1930 if (!cfg
.bold_colour
)
1931 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1932 SetDlgItemInt (hwnd
, IDC7_RVALUE
, cfg
.colours
[i
][0], FALSE
);
1933 SetDlgItemInt (hwnd
, IDC7_GVALUE
, cfg
.colours
[i
][1], FALSE
);
1934 SetDlgItemInt (hwnd
, IDC7_BVALUE
, cfg
.colours
[i
][2], FALSE
);
1938 if (HIWORD(wParam
) == BN_CLICKED
||
1939 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1940 static CHOOSECOLOR cc
;
1941 static DWORD custom
[16] = {0}; /* zero initialisers */
1942 int i
= SendDlgItemMessage (hwnd
, IDC7_LIST
, LB_GETCURSEL
,
1944 if (!cfg
.bold_colour
)
1945 i
= (i
< 3 ? i
*2 : i
== 3 ?
5 : i
*2-2);
1946 cc
.lStructSize
= sizeof(cc
);
1947 cc
.hwndOwner
= hwnd
;
1948 cc
.hInstance
= (HWND
)hinst
;
1949 cc
.lpCustColors
= custom
;
1950 cc
.rgbResult
= RGB (cfg
.colours
[i
][0], cfg
.colours
[i
][1],
1952 cc
.Flags
= CC_FULLOPEN
| CC_RGBINIT
;
1953 if (ChooseColor(&cc
)) {
1955 (unsigned char) (cc
.rgbResult
& 0xFF);
1957 (unsigned char) (cc
.rgbResult
>> 8) & 0xFF;
1959 (unsigned char) (cc
.rgbResult
>> 16) & 0xFF;
1960 SetDlgItemInt (hwnd
, IDC7_RVALUE
, cfg
.colours
[i
][0],
1962 SetDlgItemInt (hwnd
, IDC7_GVALUE
, cfg
.colours
[i
][1],
1964 SetDlgItemInt (hwnd
, IDC7_BVALUE
, cfg
.colours
[i
][2],
1970 case IDC8_KOI8WIN1251
:
1971 case IDC8_88592WIN1250
:
1972 cfg
.xlat_enablekoiwin
=
1973 IsDlgButtonChecked (hwnd
, IDC8_KOI8WIN1251
);
1974 cfg
.xlat_88592w1250
=
1975 IsDlgButtonChecked (hwnd
, IDC8_88592WIN1250
);
1977 case IDC8_CAPSLOCKCYR
:
1978 if (HIWORD(wParam
) == BN_CLICKED
||
1979 HIWORD(wParam
) == BN_DOUBLECLICKED
) {
1980 cfg
.xlat_capslockcyr
=
1981 IsDlgButtonChecked (hwnd
, IDC8_CAPSLOCKCYR
);
1984 case IDC8_VTXWINDOWS
:
1985 case IDC8_VTOEMANSI
:
1986 case IDC8_VTOEMONLY
:
1987 case IDC8_VTPOORMAN
:
1989 (IsDlgButtonChecked (hwnd
, IDC8_VTXWINDOWS
) ? VT_XWINDOWS
:
1990 IsDlgButtonChecked (hwnd
, IDC8_VTOEMANSI
) ? VT_OEMANSI
:
1991 IsDlgButtonChecked (hwnd
, IDC8_VTOEMONLY
) ? VT_OEMONLY
:
1997 EndDialog (hwnd
, 0);
2000 /* Grrr Explorer will maximize Dialogs! */
2002 if (wParam
== SIZE_MAXIMIZED
)
2009 static int CALLBACK
MainDlgProc (HWND hwnd
, UINT msg
,
2010 WPARAM wParam
, LPARAM lParam
) {
2011 static HWND page
= NULL
;
2013 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDOK
) {
2015 if (msg
== WM_COMMAND
&& LOWORD(wParam
) == IDCX_ABOUT
) {
2016 EnableWindow(hwnd
, 0);
2017 DialogBox(hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2018 GetParent(hwnd
), AboutProc
);
2019 EnableWindow(hwnd
, 1);
2020 SetActiveWindow(hwnd
);
2022 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 0);
2025 static int CALLBACK
ReconfDlgProc (HWND hwnd
, UINT msg
,
2026 WPARAM wParam
, LPARAM lParam
) {
2028 return GenericMainDlgProc (hwnd
, msg
, wParam
, lParam
, 1);
2031 int do_config (void) {
2035 savedsession
[0] = '\0';
2036 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_MAINBOX
), NULL
, MainDlgProc
);
2037 get_sesslist(FALSE
);
2042 int do_reconfig (HWND hwnd
) {
2046 backup_cfg
= cfg
; /* structure copy */
2047 ret
= DialogBox (hinst
, MAKEINTRESOURCE(IDD_RECONF
), hwnd
, ReconfDlgProc
);
2049 cfg
= backup_cfg
; /* structure copy */
2056 void logevent (char *string
) {
2057 if (nevents
>= negsize
) {
2059 events
= srealloc (events
, negsize
* sizeof(*events
));
2061 events
[nevents
] = smalloc(1+strlen(string
));
2062 strcpy (events
[nevents
], string
);
2066 SendDlgItemMessage (logbox
, IDN_LIST
, LB_ADDSTRING
,
2068 count
= SendDlgItemMessage (logbox
, IDN_LIST
, LB_GETCOUNT
, 0, 0);
2069 SendDlgItemMessage (logbox
, IDN_LIST
, LB_SETTOPINDEX
, count
-1, 0);
2073 void showeventlog (HWND hwnd
) {
2075 logbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_LOGBOX
),
2077 ShowWindow (logbox
, SW_SHOWNORMAL
);
2081 void showabout (HWND hwnd
) {
2083 abtbox
= CreateDialog (hinst
, MAKEINTRESOURCE(IDD_ABOUTBOX
),
2085 ShowWindow (abtbox
, SW_SHOWNORMAL
);
2089 void verify_ssh_host_key(char *host
, int port
, char *keytype
,
2090 char *keystr
, char *fingerprint
) {
2093 static const char absentmsg
[] =
2094 "The server's host key is not cached in the registry. You\n"
2095 "have no guarantee that the server is the computer you\n"
2097 "The server's key fingerprint is:\n"
2099 "If you trust this host, hit Yes to add the key to\n"
2100 "PuTTY's cache and carry on connecting.\n"
2101 "If you do not trust this host, hit No to abandon the\n"
2104 static const char wrongmsg
[] =
2105 "WARNING - POTENTIAL SECURITY BREACH!\n"
2107 "The server's host key does not match the one PuTTY has\n"
2108 "cached in the registry. This means that either the\n"
2109 "server administrator has changed the host key, or you\n"
2110 "have actually connected to another computer pretending\n"
2111 "to be the server.\n"
2112 "The new key fingerprint is:\n"
2114 "If you were expecting this change and trust the new key,\n"
2115 "hit Yes to update PuTTY's cache and continue connecting.\n"
2116 "If you want to carry on connecting but without updating\n"
2117 "the cache, hit No.\n"
2118 "If you want to abandon the connection completely, hit\n"
2119 "Cancel. Hitting Cancel is the ONLY guaranteed safe\n"
2122 static const char mbtitle
[] = "PuTTY Security Alert";
2125 char message
[160+ /* sensible fingerprint max size */
2126 (sizeof(absentmsg
) > sizeof(wrongmsg
) ?
2127 sizeof(absentmsg
) : sizeof(wrongmsg
))];
2130 * Verify the key against the registry.
2132 ret
= verify_host_key(host
, port
, keytype
, keystr
);
2134 if (ret
== 0) /* success - key matched OK */
2136 if (ret
== 2) { /* key was different */
2138 sprintf(message
, wrongmsg
, fingerprint
);
2139 mbret
= MessageBox(NULL
, message
, mbtitle
,
2140 MB_ICONWARNING
| MB_YESNOCANCEL
);
2142 store_host_key(host
, port
, keytype
, keystr
);
2143 if (mbret
== IDCANCEL
)
2146 if (ret
== 1) { /* key was absent */
2148 sprintf(message
, absentmsg
, fingerprint
);
2149 mbret
= MessageBox(NULL
, message
, mbtitle
,
2150 MB_ICONWARNING
| MB_YESNO
);
2153 store_host_key(host
, port
, keytype
, keystr
);