1 /* Copyright (c) 2008, 2009
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Micah Cowan (micah@cowan.name)
5 * Sadrul Habib Chowdhury (sadrul@users.sourceforge.net)
6 * Copyright (c) 1993-2002, 2003, 2005, 2006, 2007
7 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
8 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
9 * Copyright (c) 1987 Oliver Laumann
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3, or (at your option)
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program (see the file COPYING); if not, see
23 * http://www.gnu.org/licenses/, or contact Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
26 ****************************************************************
29 #include <sys/types.h>
37 extern struct display
*display
, *displays
;
39 extern struct mline mline_blank
, mline_null
;
40 extern struct mchar mchar_blank
, mchar_null
;
42 extern struct layer
*flayer
; /* sigh */
43 extern struct LayFuncs WinLf
;
44 extern struct LayFuncs BlankLf
;
47 static struct mline
*mloff
__P((struct mline
*, int));
52 * ...here is all the clipping code... beware!
54 * XXX: add some speedup code!
63 static struct mline mml
;
67 mml
.image
= ml
->image
+ off
;
68 mml
.attr
= ml
->attr
+ off
;
70 mml
.font
= ml
->font
+ off
;
73 mml
.color
= ml
->color
+ off
;
75 mml
.colorx
= ml
->colorx
+ off
;
82 # define RECODE_MCHAR(mc) ((l->l_encoding == UTF8) != (D_encoding == UTF8) ? recode_mchar(mc, l->l_encoding, D_encoding) : (mc))
83 # define RECODE_MLINE(ml) ((l->l_encoding == UTF8) != (D_encoding == UTF8) ? recode_mline(ml, l->l_width, l->l_encoding, D_encoding) : (ml))
85 # define RECODE_MCHAR(mc) (mc)
86 # define RECODE_MLINE(ml) (ml)
101 LayPauseUpdateRegion(l
, x
, x
, y
, y
);
106 if (bd
.bd_refreshing
)
109 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
111 display
= cv
->c_display
;
118 debug2("---LGotoPos %d %d\n", x2
, y2
);
127 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
129 if (x2
< vp
->v_xs
|| x2
> vp
->v_xe
)
131 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
140 LScrollH(l
, n
, y
, xs
, xe
, bce
, ol
)
154 LayPauseUpdateRegion(l
, xs
, xe
, y
, y
);
157 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
158 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
161 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
163 xs2
= xs
+ vp
->v_xoff
;
164 xe2
= xe
+ vp
->v_xoff
;
171 display
= cv
->c_display
;
174 ScrollH(y2
, xs2
, xe2
, n
, bce
, ol
? mloff(ol
, -vp
->v_xoff
) : 0);
175 if (xe2
- xs2
== xe
- xs
)
180 xe2
= xe
+ vp
->v_xoff
- n
;
185 xs2
= xs
+ vp
->v_xoff
- n
;
192 RefreshArea(xs2
, y2
, xe2
, y2
, 1);
197 LScrollV(l
, n
, ys
, ye
, bce
)
205 int ys2
, ye2
, xs2
, xe2
;
210 LayPauseUpdateRegion(l
, 0, l
->l_width
- 1, ys
, ye
);
213 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
214 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
217 xe2
= l
->l_width
- 1 + vp
->v_xoff
;
218 ys2
= ys
+ vp
->v_yoff
;
219 ye2
= ye
+ vp
->v_yoff
;
228 if (ys2
> ye2
|| xs2
> xe2
)
230 display
= cv
->c_display
;
234 ScrollV(xs2
, ys2
, xe2
, ye2
, n
, bce
);
236 ScrollV(vp
->v_xs
, ys2
, vp
->v_xe
, ye2
, n
, bce
);
238 debug2("LScrollV: %d %d", ys
, ye
);
239 debug2(" -> %d %d\n", ys2
, ye2
);
240 if (ye2
- ys2
== ye
- ys
)
245 ye2
= ye
+ vp
->v_yoff
- n
;
250 ys2
= ys
+ vp
->v_yoff
- n
;
252 debug2("LScrollV: - %d %d\n", ys2
, ye2
);
257 debug2("LScrollV: - %d %d\n", ys2
, ye2
);
259 RefreshArea(xs2
, ys2
, xe2
, ye2
, 1);
264 LInsChar(l
, c
, x
, y
, ol
)
273 struct mchar
*c2
, cc
;
278 LayPauseUpdateRegion(l
, x
, l
->l_width
- 1, y
, y
);
281 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
282 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
285 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
287 xs2
= x
+ vp
->v_xoff
;
288 xe2
= l
->l_width
- 1 + vp
->v_xoff
;
298 i
= xs2
- vp
->v_xoff
- 1;
299 if (i
>= 0 && i
< l
->l_width
)
301 copy_mline2mchar(&cc
, ol
, i
);
312 display
= cv
->c_display
;
315 rol
= RECODE_MLINE(ol
);
316 InsChar(RECODE_MCHAR(c2
), xs2
, xe2
, y2
, mloff(rol
, -vp
->v_xoff
));
318 RefreshArea(xs2
, y2
, xs2
, y2
, 1);
332 if (bd
.bd_refreshing
)
334 BPutChar(l
, c
, x
, y
);
341 LayPauseUpdateRegion(l
, x
, x
, y
, y
);
345 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
347 display
= cv
->c_display
;
350 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
353 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
356 if (x2
< vp
->v_xs
|| x2
> vp
->v_xe
)
358 PutChar(RECODE_MCHAR(c
), x2
, y2
);
365 LPutStr(l
, s
, n
, r
, x
, y
)
377 if (x
+ n
> l
->l_width
)
380 if (bd
.bd_refreshing
)
382 BPutStr(l
, s
, n
, r
, x
, y
);
388 LayPauseUpdateRegion(l
, x
, x
+ n
- 1, y
, y
);
392 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
393 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
396 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
398 xs2
= x
+ vp
->v_xoff
;
406 display
= cv
->c_display
;
411 s2
= s
+ xs2
- x
- vp
->v_xoff
;
413 if (D_encoding
== UTF8
&& l
->l_encoding
!= UTF8
&& (r
->font
|| l
->l_encoding
))
420 PutChar(RECODE_MCHAR(&mc
), xs2
++, y2
);
431 LPutWinMsg(l
, s
, n
, r
, x
, y
)
440 int xs2
, xe2
, y2
, len
, len2
;
443 if (x
+ n
> l
->l_width
)
446 if (bd
.bd_refreshing
)
448 BPutStr(l
, s
, n
, r
, x
, y
);
454 LayPauseUpdateRegion(l
, x
, x
+ n
- 1, y
, y
);
460 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
461 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
464 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
466 xs2
= x
+ vp
->v_xoff
;
474 display
= cv
->c_display
;
479 len2
= xe2
- (x
+ vp
->v_xoff
) + 1;
482 PutWinMsg(s
, xs2
- x
- vp
->v_xoff
, len2
);
483 xs2
= x
+ vp
->v_xoff
+ len2
;
495 LClearLine(l
, y
, xs
, xe
, bce
, ol
)
504 /* check for magic margin condition */
505 if (xs
>= l
->l_width
)
507 if (xe
>= l
->l_width
)
511 LayPauseUpdateRegion(l
, xs
, xe
, y
, y
);
514 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
515 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
517 xs2
= xs
+ vp
->v_xoff
;
518 xe2
= xe
+ vp
->v_xoff
;
520 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
528 display
= cv
->c_display
;
531 ClearLine(ol
? mloff(RECODE_MLINE(ol
), -vp
->v_xoff
) : (struct mline
*)0, y2
, xs2
, xe2
, bce
);
536 LClearArea(l
, xs
, ys
, xe
, ye
, bce
, uself
)
544 int xs2
, ys2
, xe2
, ye2
;
546 if (bd
.bd_refreshing
)
549 /* Check for zero-height window */
550 if (ys
< 0 || ye
< ys
)
553 /* check for magic margin condition */
554 if (xs
>= l
->l_width
)
556 if (xe
>= l
->l_width
)
560 LayPauseUpdateRegion(l
, xs
, xe
, ys
, ye
);
563 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
565 display
= cv
->c_display
;
568 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
570 xs2
= xs
+ vp
->v_xoff
;
571 xe2
= xe
+ vp
->v_xoff
;
572 ys2
= ys
+ vp
->v_yoff
;
573 ye2
= ye
+ vp
->v_yoff
;
590 xce
= l
->l_width
- 1 + vp
->v_xoff
;
597 if (ys2
!= ys
+ vp
->v_yoff
)
599 if (ye2
!= ye
+ vp
->v_yoff
)
601 display
= cv
->c_display
;
602 ClearArea(xs2
, ys2
, xcs
, xce
, xe2
, ye2
, bce
, uself
);
604 if (xs
== 0 || ys2
!= ys
+ vp
->v_yoff
)
606 if (xe
== l
->l_width
- 1 || ye2
!= ye
+ vp
->v_yoff
)
608 display
= cv
->c_display
;
609 ClearArea(xs2
, ys2
, vp
->v_xs
, vp
->v_xe
, xe2
, ye2
, bce
, uself
);
616 LCDisplayLine(l
, ml
, y
, xs
, xe
, isblank
)
626 if (bd
.bd_refreshing
)
628 BCDisplayLine(l
, ml
, y
, xs
, xe
, isblank
);
634 LayPauseUpdateRegion(l
, xs
, xe
, y
, y
);
637 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
639 display
= cv
->c_display
;
642 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
644 xs2
= xs
+ vp
->v_xoff
;
645 xe2
= xe
+ vp
->v_xoff
;
647 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
655 display
= cv
->c_display
;
656 debug3("LCDisplayLine: DisplayLine %d, %d-%d", y2
, xs2
, xe2
);
657 debug1(" mloff = %d\n", -vp
->v_xoff
);
658 DisplayLine(isblank
? &mline_blank
: &mline_null
, mloff(RECODE_MLINE(ml
), -vp
->v_xoff
), y2
, xs2
, xe2
);
664 LCDisplayLineWrap(l
, ml
, y
, from
, to
, isblank
)
671 copy_mline2mchar(&nc
, ml
, 0);
673 if (dw_left(ml
, 0, l
->l_encoding
))
675 nc
.mbcs
= ml
->image
[1];
679 LWrapChar(l
, &nc
, y
- 1, -1, -1, 0);
682 LCDisplayLine(l
, ml
, y
, from
, to
, isblank
);
692 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
694 display
= cv
->c_display
;
702 LWrapChar(l
, c
, y
, top
, bot
, ins
)
708 struct canvas
*cv
, *cvlist
, *cvlnext
;
709 struct viewport
*vp
, *evp
, **vpp
;
710 int yy
, y2
, yy2
, top2
, bot2
;
716 LayPauseUpdateRegion(l
, 0, l
->l_width
- 1, top
, bot
);
727 /* simple case: no scrolling */
729 /* cursor after wrapping */
730 yy
= y
== l
->l_height
- 1 ? y
: y
+ 1;
732 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
734 y2
= 0; /* gcc -Wall */
735 display
= cv
->c_display
;
738 /* find the viewport of the wrapped character */
739 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
742 yy2
= yy
+ vp
->v_yoff
;
743 if (yy2
>= vp
->v_ys
&& yy2
<= vp
->v_ye
&& vp
->v_xoff
>= vp
->v_xs
&& vp
->v_xoff
<= vp
->v_xe
)
747 continue; /* nothing to do, character not visible */
748 /* find the viewport of the character at the end of the line*/
749 for (evp
= cv
->c_vplist
; evp
; evp
= evp
->v_next
)
750 if (y2
>= evp
->v_ys
&& y2
<= evp
->v_ye
&& evp
->v_xoff
+ l
->l_width
- 1 >= evp
->v_xs
&& evp
->v_xoff
+ l
->l_width
- 1 <= evp
->v_xe
)
752 if (evp
== 0 || (ins
&& vp
->v_xoff
+ l
->l_width
- 1 > vp
->v_ye
))
754 /* no wrapping possible */
755 debug("LWrap: can't wrap!\n");
756 cvlist
= l
->l_cvlist
;
757 cvlnext
= cv
->c_lnext
;
761 LInsChar(l
, c
, 0, yy
, 0);
763 LPutChar(l
, c
, 0, yy
);
764 l
->l_cvlist
= cvlist
;
765 cv
->c_lnext
= cvlnext
;
769 WrapChar(RECODE_MCHAR(c
), vp
->v_xoff
+ l
->l_width
, y2
, vp
->v_xoff
, -1, vp
->v_xoff
+ l
->l_width
- 1, -1, ins
);
775 /* hard case: scroll up*/
777 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
779 display
= cv
->c_display
;
782 /* search for wrap viewport */
783 for (vpp
= &cv
->c_vplist
; (vp
= *vpp
); vpp
= &vp
->v_next
)
785 yy2
= bot
+ vp
->v_yoff
;
786 if (yy2
>= vp
->v_ys
&& yy2
<= vp
->v_ye
&& vp
->v_xoff
>= vp
->v_xs
&& vp
->v_xoff
+ l
->l_width
- 1 <= vp
->v_xe
)
792 /* great, can use Wrap on the vp */
793 /* temporarily remove vp from cvlist */
798 /* scroll all viewports != vp */
799 cvlist
= l
->l_cvlist
;
800 cvlnext
= cv
->c_lnext
;
803 LScrollV(l
, 1, top
, bot
, bce
);
807 LInsChar(l
, c
, 0, bot
, 0);
809 LPutChar(l
, c
, 0, bot
);
811 l
->l_cvlist
= cvlist
;
812 cv
->c_lnext
= cvlnext
;
816 /* add vp back to cvlist */
818 top2
= top
+ vp
->v_yoff
;
819 bot2
= bot
+ vp
->v_yoff
;
822 WrapChar(RECODE_MCHAR(c
), vp
->v_xoff
+ l
->l_width
, bot2
, vp
->v_xoff
, top2
, vp
->v_xoff
+ l
->l_width
- 1, bot2
, ins
);
830 LCursorVisibility(l
, vis
)
835 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
837 display
= cv
->c_display
;
842 CursorVisibility(vis
);
852 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
854 display
= cv
->c_display
;
867 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
869 display
= cv
->c_display
;
879 LCursorkeysMode(l
, on
)
884 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
886 display
= cv
->c_display
;
901 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
903 display
= cv
->c_display
;
917 LClearArea(l
, 0, 0, l
->l_width
- 1, l
->l_height
- 1, 0, uself
);
921 LRefreshAll(l
, isblank
)
925 struct layer
*oldflayer
;
928 debug1("LRefreshAll isblank=%d\n", isblank
);
932 LClearArea(l
, 0, 0, l
->l_width
- 1, l
->l_height
- 1, 0, 0);
933 /* signal full refresh */
934 LayRedisplayLine(-1, -1, -1, 1);
935 for (y
= 0; y
< l
->l_height
; y
++)
936 LayRedisplayLine(y
, 0, l
->l_width
- 1, 1);
942 #if defined(USEVARARGS) && defined(__STDC__)
943 LMsg(int err
, const char *fmt
, VA_DOTS
)
945 LMsg(err
, fmt
, VA_DOTS
)
952 char buf
[MAXPATHLEN
*2];
958 (void)vsnprintf(p
, sizeof(buf
) - 100, fmt
, VA_ARGS(ap
));
965 strncpy(p
, strerror(err
), buf
+ sizeof(buf
) - p
- 1);
966 buf
[sizeof(buf
) - 1] = 0;
968 debug2("LMsg('%s') (%#x);\n", buf
, (unsigned int)flayer
);
969 for (display
= displays
; display
; display
= display
->d_next
)
971 for (cv
= D_cvlist
; cv
; cv
= cv
->c_next
)
972 if (cv
->c_layer
== flayer
)
981 /*******************************************************************/
982 /*******************************************************************/
985 * Layer creation / removal
992 struct canvas
*cv
, *ncv
;
993 struct layer
*l
, *oldflayer
;
996 debug1("KillLayerChain %#x\n", lay
);
997 for (l
= lay
; l
; l
= l
->l_next
)
999 if (l
->l_layfn
== &WinLf
|| l
->l_layfn
== &BlankLf
)
1001 debug1("- killing %#x\n", l
);
1004 for (cv
= l
->l_cvlist
; cv
; cv
= ncv
)
1020 InitOverlayPage(datasize
, lf
, block
)
1022 struct LayFuncs
*lf
;
1026 struct layer
*newlay
;
1027 struct canvas
*cv
, *cvp
, **cvpp
;
1033 if (display
&& D_forecv
->c_layer
== flayer
)
1034 cv
= D_forecv
; /* work only on this cv! */
1036 if ((newlay
= (struct layer
*)calloc(1, sizeof(struct layer
))) == 0)
1038 Msg(0, "No memory for layer struct");
1041 debug2("Entering new layer on top of %#x: %#x\n", (unsigned int)flayer
, newlay
);
1045 if ((data
= calloc(1, datasize
)) == 0)
1047 free((char *)newlay
);
1048 Msg(0, "No memory for layer data");
1053 p
= Layer2Window(flayer
);
1055 if (p
&& (p
->w_savelayer
== flayer
|| (block
&& flayer
->l_next
== 0)))
1057 if (p
->w_savelayer
&& p
->w_savelayer
!= flayer
&& p
->w_savelayer
->l_cvlist
== 0)
1058 KillLayerChain(p
->w_savelayer
);
1059 p
->w_savelayer
= newlay
;
1062 if (cv
&& flayer
->l_next
== 0 && !block
)
1064 struct display
*olddisplay
= display
;
1065 display
= cv
->c_display
;
1067 display
= olddisplay
;
1069 /* new branch -> just get canvas vps */
1070 for (cvpp
= &flayer
->l_cvlist
; (cvp
= *cvpp
); cvpp
= &cvp
->c_lnext
)
1074 *cvpp
= cv
->c_lnext
;
1075 newlay
->l_cvlist
= cv
;
1077 cv
->c_layer
= newlay
;
1081 LAY_DISPLAYS(flayer
, RemoveStatus());
1083 debug("layer is blocking\n");
1084 if (block
&& flayer
->l_layfn
== &WinLf
)
1086 debug("...and is first, so window gets blocked\n");
1087 ASSERT(p
->w_blocked
== 0);
1089 newlay
->l_blocking
= 1;
1091 /* change all canvases */
1092 newlay
->l_cvlist
= flayer
->l_cvlist
;
1093 for (cvp
= newlay
->l_cvlist
; cvp
; cvp
= cvp
->c_lnext
)
1094 cvp
->c_layer
= newlay
;
1095 flayer
->l_cvlist
= 0;
1097 newlay
->l_width
= flayer
->l_width
;
1098 newlay
->l_height
= flayer
->l_height
;
1099 newlay
->l_encoding
= 0;
1100 newlay
->l_layfn
= lf
;
1101 newlay
->l_data
= data
;
1102 newlay
->l_next
= flayer
;
1103 newlay
->l_bottom
= flayer
->l_bottom
;
1109 extern struct layout
*layouts
;
1114 struct layer
*oldlay
;
1116 int doredisplay
= 0;
1117 struct canvas
*cv
, *ocv
;
1121 debug1("Exiting layer %#x\n", (unsigned int)flayer
);
1124 free(oldlay
->l_data
);
1126 p
= Layer2Window(flayer
);
1128 flayer
= oldlay
->l_next
;
1129 if (flayer
->l_layfn
== &WinLf
)
1131 if (oldlay
->l_blocking
)
1133 ASSERT(p
->w_blocked
> 0);
1135 debug1("layer was blocking, -> w_blocked now %d\n", p
->w_blocked
);
1137 /* don't warp dead layers: check cvlist */
1138 if (p
->w_blocked
&& p
->w_savelayer
&& p
->w_savelayer
!= flayer
&& oldlay
->l_cvlist
)
1140 debug("warping to top of blocking chain!\n");
1141 /* warp ourself into savelayer */
1142 flayer
= p
->w_savelayer
;
1146 if (p
&& p
->w_savelayer
== oldlay
)
1147 p
->w_savelayer
= flayer
;
1149 if (p
&& oldlay
== p
->w_paster
.pa_pastelayer
)
1150 p
->w_paster
.pa_pastelayer
= 0;
1153 for (lay
= layouts
; lay
; lay
= lay
->lay_next
)
1154 for (cv
= lay
->lay_cvlist
; cv
; cv
= cv
->c_next
)
1155 if (cv
->c_layer
== oldlay
)
1156 cv
->c_layer
= flayer
;
1158 /* add all canvases back into next layer's canvas list */
1159 for (ocv
= 0, cv
= oldlay
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
1161 cv
->c_layer
= flayer
;
1166 cv
= flayer
->l_cvlist
;
1168 flayer
->l_cvlist
= oldlay
->l_cvlist
;
1169 /* redisplay only the warped cvs */
1171 LRefreshAll(flayer
, 0);
1174 oldlay
->l_cvlist
= 0;
1175 LayerCleanupMemory(oldlay
);
1176 free((char *)oldlay
);
1182 LayProcessMouse(struct layer
*l
, unsigned char ch
)
1184 /* XXX: Make sure the layer accepts mouse events */
1187 if (l
->l_mouseevent
.len
>= sizeof(l
->l_mouseevent
.buffer
))
1190 len
= l
->l_mouseevent
.len
++;
1191 l
->l_mouseevent
.buffer
[len
] = (len
> 0 ? ch
- 33 : ch
);
1192 return (l
->l_mouseevent
.len
== sizeof(l
->l_mouseevent
.buffer
));
1196 LayProcessMouseSwitch(struct layer
*l
, int s
)
1198 if ((l
->l_mouseevent
.start
= s
))
1200 l
->l_mouseevent
.len
= 0;
1204 void LayPause(layer
, pause
)
1205 struct layer
*layer
;
1209 struct display
*olddisplay
= display
;
1214 if (layer
->l_pause
.d
== pause
)
1217 if ((layer
->l_pause
.d
= pause
))
1220 layer
->l_pause
.top
= layer
->l_pause
.bottom
= -1;
1224 /* Unpause. So refresh the regions in the displays! */
1225 if (layer
->l_pause
.top
== -1 &&
1226 layer
->l_pause
.bottom
== -1)
1229 for (cv
= layer
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
1231 struct viewport
*vp
;
1233 display
= cv
->c_display
;
1235 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
1237 for (line
= layer
->l_pause
.top
; line
<= layer
->l_pause
.bottom
; line
++)
1241 if (line
+ vp
->v_yoff
>= vp
->v_ys
&& line
+ vp
->v_yoff
<= vp
->v_ye
&&
1242 ((xs
= layer
->l_pause
.left
[line
]) >= 0) &&
1243 ((xe
= layer
->l_pause
.right
[line
]) >= 0))
1248 if (xs
< vp
->v_xs
) xs
= vp
->v_xs
;
1249 if (xe
> vp
->v_xe
) xe
= vp
->v_xe
;
1252 RefreshLine(line
+ vp
->v_yoff
, xs
, xe
, 0);
1259 int cx
= layer
->l_x
+ cv
->c_xoff
;
1260 int cy
= layer
->l_y
+ cv
->c_yoff
;
1262 if (cx
< cv
->c_xs
) cx
= cv
->c_xs
;
1263 if (cy
< cv
->c_ys
) cy
= cv
->c_ys
;
1264 if (cx
> cv
->c_xe
) cx
= cv
->c_xe
;
1265 if (cy
> cv
->c_ye
) cy
= cv
->c_ye
;
1271 for (line
= layer
->l_pause
.top
; line
<= layer
->l_pause
.bottom
; line
++)
1272 layer
->l_pause
.left
[line
] = layer
->l_pause
.right
[line
] = -1;
1273 olddisplay
= display
;
1277 LayPauseUpdateRegion(layer
, xs
, xe
, ys
, ye
)
1278 struct layer
*layer
;
1282 if (!layer
->l_pause
.d
)
1284 if (ye
>= layer
->l_height
)
1285 ye
= layer
->l_height
- 1;
1286 if (xe
>= layer
->l_width
)
1287 xe
= layer
->l_width
- 1;
1289 if (layer
->l_pause
.top
== -1 || layer
->l_pause
.top
> ys
)
1290 layer
->l_pause
.top
= ys
;
1291 if (layer
->l_pause
.bottom
< ye
)
1293 layer
->l_pause
.bottom
= ye
;
1294 if (layer
->l_pause
.lines
<= ye
)
1296 int o
= layer
->l_pause
.lines
;
1297 layer
->l_pause
.lines
= ye
+ 32;
1298 layer
->l_pause
.left
= realloc(layer
->l_pause
.left
, sizeof(int) * layer
->l_pause
.lines
);
1299 layer
->l_pause
.right
= realloc(layer
->l_pause
.right
, sizeof(int) * layer
->l_pause
.lines
);
1300 while (o
< layer
->l_pause
.lines
)
1302 layer
->l_pause
.left
[o
] = layer
->l_pause
.right
[o
] = -1;
1310 if (layer
->l_pause
.left
[ys
] == -1 || layer
->l_pause
.left
[ys
] > xs
)
1311 layer
->l_pause
.left
[ys
] = xs
;
1312 if (layer
->l_pause
.right
[ys
] < xe
)
1313 layer
->l_pause
.right
[ys
] = xe
;
1319 LayerCleanupMemory(layer
)
1320 struct layer
*layer
;
1322 if (layer
->l_pause
.left
)
1323 free(layer
->l_pause
.left
);
1324 if (layer
->l_pause
.right
)
1325 free(layer
->l_pause
.right
);