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)
89 #define FOR_EACH_UNPAUSED_CANVAS(l, fn) for (cv = (l)->l_cvlist; cv; cv = cv->c_lnext) \
91 if ((l)->l_pause.d && cv->c_slorient) \
106 LayPauseUpdateRegion(l
, x
, x
, y
, y
);
109 if (bd
.bd_refreshing
)
112 FOR_EACH_UNPAUSED_CANVAS(l
,
114 display
= cv
->c_display
;
121 debug2("---LGotoPos %d %d\n", x2
, y2
);
130 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
132 if (x2
< vp
->v_xs
|| x2
> vp
->v_xe
)
134 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
144 LScrollH(l
, n
, y
, xs
, xe
, bce
, ol
)
157 LayPauseUpdateRegion(l
, xs
, xe
, y
, y
);
158 FOR_EACH_UNPAUSED_CANVAS(l
,
159 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
162 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
164 xs2
= xs
+ vp
->v_xoff
;
165 xe2
= xe
+ vp
->v_xoff
;
172 display
= cv
->c_display
;
175 ScrollH(y2
, xs2
, xe2
, n
, bce
, ol
? mloff(ol
, -vp
->v_xoff
) : 0);
176 if (xe2
- xs2
== xe
- xs
)
181 xe2
= xe
+ vp
->v_xoff
- n
;
186 xs2
= xs
+ vp
->v_xoff
- n
;
193 RefreshArea(xs2
, y2
, xe2
, y2
, 1);
199 LScrollV(l
, n
, ys
, ye
, bce
)
207 int ys2
, ye2
, xs2
, xe2
;
211 LayPauseUpdateRegion(l
, 0, l
->l_width
- 1, ys
, ye
);
212 FOR_EACH_UNPAUSED_CANVAS(l
,
213 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
216 xe2
= l
->l_width
- 1 + vp
->v_xoff
;
217 ys2
= ys
+ vp
->v_yoff
;
218 ye2
= ye
+ vp
->v_yoff
;
227 if (ys2
> ye2
|| xs2
> xe2
)
229 display
= cv
->c_display
;
233 ScrollV(xs2
, ys2
, xe2
, ye2
, n
, bce
);
235 ScrollV(vp
->v_xs
, ys2
, vp
->v_xe
, ye2
, n
, bce
);
237 debug2("LScrollV: %d %d", ys
, ye
);
238 debug2(" -> %d %d\n", ys2
, ye2
);
239 if (ye2
- ys2
== ye
- ys
)
244 ye2
= ye
+ vp
->v_yoff
- n
;
249 ys2
= ys
+ vp
->v_yoff
- n
;
251 debug2("LScrollV: - %d %d\n", ys2
, ye2
);
256 debug2("LScrollV: - %d %d\n", ys2
, ye2
);
258 RefreshArea(xs2
, ys2
, xe2
, ye2
, 1);
264 LInsChar(l
, c
, x
, y
, ol
)
273 struct mchar
*c2
, cc
;
277 LayPauseUpdateRegion(l
, x
, l
->l_width
- 1, y
, y
);
278 FOR_EACH_UNPAUSED_CANVAS(l
,
279 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
282 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
284 xs2
= x
+ vp
->v_xoff
;
285 xe2
= l
->l_width
- 1 + vp
->v_xoff
;
295 i
= xs2
- vp
->v_xoff
- 1;
296 if (i
>= 0 && i
< l
->l_width
)
298 copy_mline2mchar(&cc
, ol
, i
);
309 display
= cv
->c_display
;
312 rol
= RECODE_MLINE(ol
);
313 InsChar(RECODE_MCHAR(c2
), xs2
, xe2
, y2
, mloff(rol
, -vp
->v_xoff
));
315 RefreshArea(xs2
, y2
, xs2
, y2
, 1);
330 if (bd
.bd_refreshing
)
332 BPutChar(l
, c
, x
, y
);
338 LayPauseUpdateRegion(l
, x
,
340 x
+ (c
->mbcs
? 1 : 0)
346 FOR_EACH_UNPAUSED_CANVAS(l
,
348 display
= cv
->c_display
;
351 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
354 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
357 if (x2
< vp
->v_xs
|| x2
> vp
->v_xe
)
359 PutChar(RECODE_MCHAR(c
), x2
, y2
);
367 LPutStr(l
, s
, n
, r
, x
, y
)
379 if (x
+ n
> l
->l_width
)
382 if (bd
.bd_refreshing
)
384 BPutStr(l
, s
, n
, r
, x
, y
);
389 LayPauseUpdateRegion(l
, x
, x
+ n
- 1, y
, y
);
391 FOR_EACH_UNPAUSED_CANVAS(l
,
392 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
395 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
397 xs2
= x
+ vp
->v_xoff
;
405 display
= cv
->c_display
;
410 s2
= s
+ xs2
- x
- vp
->v_xoff
;
412 if (D_encoding
== UTF8
&& l
->l_encoding
!= UTF8
&& (r
->font
|| l
->l_encoding
))
419 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
);
453 LayPauseUpdateRegion(l
, x
, x
+ n
- 1, y
, y
);
457 FOR_EACH_UNPAUSED_CANVAS(l
,
458 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
461 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
463 xs2
= x
+ vp
->v_xoff
;
471 display
= cv
->c_display
;
476 len2
= xe2
- (x
+ vp
->v_xoff
) + 1;
479 PutWinMsg(s
, xs2
- x
- vp
->v_xoff
, len2
);
480 xs2
= x
+ vp
->v_xoff
+ len2
;
493 LClearLine(l
, y
, xs
, xe
, bce
, ol
)
502 /* check for magic margin condition */
503 if (xs
>= l
->l_width
)
505 if (xe
>= l
->l_width
)
508 LayPauseUpdateRegion(l
, xs
, xe
, y
, y
);
509 FOR_EACH_UNPAUSED_CANVAS(l
,
510 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
512 xs2
= xs
+ vp
->v_xoff
;
513 xe2
= xe
+ vp
->v_xoff
;
515 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
523 display
= cv
->c_display
;
526 ClearLine(ol
? mloff(RECODE_MLINE(ol
), -vp
->v_xoff
) : (struct mline
*)0, y2
, xs2
, xe2
, bce
);
532 LClearArea(l
, xs
, ys
, xe
, ye
, bce
, uself
)
540 int xs2
, ys2
, xe2
, ye2
;
542 if (bd
.bd_refreshing
)
545 /* Check for zero-height window */
546 if (ys
< 0 || ye
< ys
)
549 /* check for magic margin condition */
550 if (xs
>= l
->l_width
)
552 if (xe
>= l
->l_width
)
555 LayPauseUpdateRegion(l
, xs
, xe
, ys
, ye
);
556 FOR_EACH_UNPAUSED_CANVAS(l
,
558 display
= cv
->c_display
;
561 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
563 xs2
= xs
+ vp
->v_xoff
;
564 xe2
= xe
+ vp
->v_xoff
;
565 ys2
= ys
+ vp
->v_yoff
;
566 ye2
= ye
+ vp
->v_yoff
;
583 xce
= l
->l_width
- 1 + vp
->v_xoff
;
590 if (ys2
!= ys
+ vp
->v_yoff
)
592 if (ye2
!= ye
+ vp
->v_yoff
)
594 display
= cv
->c_display
;
595 ClearArea(xs2
, ys2
, xcs
, xce
, xe2
, ye2
, bce
, uself
);
597 if (xs
== 0 || ys2
!= ys
+ vp
->v_yoff
)
599 if (xe
== l
->l_width
- 1 || ye2
!= ye
+ vp
->v_yoff
)
601 display
= cv
->c_display
;
602 ClearArea(xs2
, ys2
, vp
->v_xs
, vp
->v_xe
, xe2
, ye2
, bce
, uself
);
603 if (xe
== l
->l_width
- 1 && xe2
> vp
->v_xoff
+ xe
)
606 SetRendition(&mchar_blank
);
607 for (y
= ys2
; y
<= ye2
; y
++)
609 GotoPos(xe
+ vp
->v_xoff
+ 1, y
);
620 LCDisplayLine(l
, ml
, y
, xs
, xe
, isblank
)
630 if (bd
.bd_refreshing
)
632 BCDisplayLine(l
, ml
, y
, xs
, xe
, isblank
);
637 LayPauseUpdateRegion(l
, xs
, xe
, y
, y
);
638 FOR_EACH_UNPAUSED_CANVAS(l
,
640 display
= cv
->c_display
;
643 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
645 xs2
= xs
+ vp
->v_xoff
;
646 xe2
= xe
+ vp
->v_xoff
;
648 if (y2
< vp
->v_ys
|| y2
> vp
->v_ye
)
656 display
= cv
->c_display
;
657 debug3("LCDisplayLine: DisplayLine %d, %d-%d", y2
, xs2
, xe2
);
658 debug1(" mloff = %d\n", -vp
->v_xoff
);
659 DisplayLine(isblank
? &mline_blank
: &mline_null
, mloff(RECODE_MLINE(ml
), -vp
->v_xoff
), y2
, xs2
, xe2
);
666 LCDisplayLineWrap(l
, ml
, y
, from
, to
, isblank
)
673 copy_mline2mchar(&nc
, ml
, 0);
675 if (dw_left(ml
, 0, l
->l_encoding
))
677 nc
.mbcs
= ml
->image
[1];
681 LWrapChar(l
, &nc
, y
- 1, -1, -1, 0);
684 LCDisplayLine(l
, ml
, y
, from
, to
, isblank
);
694 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
696 display
= cv
->c_display
;
704 LWrapChar(l
, c
, y
, top
, bot
, ins
)
710 struct canvas
*cv
, *cvlist
, *cvlnext
;
711 struct viewport
*vp
, *evp
, **vpp
;
712 int yy
, y2
, yy2
, top2
, bot2
;
717 LayPauseUpdateRegion(l
, 0, l
->l_width
- 1, top
, bot
);
726 /* simple case: no scrolling */
728 /* cursor after wrapping */
729 yy
= y
== l
->l_height
- 1 ? y
: y
+ 1;
731 FOR_EACH_UNPAUSED_CANVAS(l
,
733 y2
= 0; /* gcc -Wall */
734 display
= cv
->c_display
;
737 /* find the viewport of the wrapped character */
738 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
741 yy2
= yy
+ vp
->v_yoff
;
742 if (yy2
>= vp
->v_ys
&& yy2
<= vp
->v_ye
&& vp
->v_xoff
>= vp
->v_xs
&& vp
->v_xoff
<= vp
->v_xe
)
746 continue; /* nothing to do, character not visible */
747 /* find the viewport of the character at the end of the line*/
748 for (evp
= cv
->c_vplist
; evp
; evp
= evp
->v_next
)
749 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
)
751 if (evp
== 0 || (ins
&& vp
->v_xoff
+ l
->l_width
- 1 > vp
->v_ye
))
753 /* no wrapping possible */
754 debug("LWrap: can't wrap!\n");
755 cvlist
= l
->l_cvlist
;
756 cvlnext
= cv
->c_lnext
;
760 LInsChar(l
, c
, 0, yy
, 0);
762 LPutChar(l
, c
, 0, yy
);
763 l
->l_cvlist
= cvlist
;
764 cv
->c_lnext
= cvlnext
;
768 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_EACH_UNPAUSED_CANVAS(l
,
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
);
831 LCursorVisibility(l
, vis
)
836 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
838 display
= cv
->c_display
;
843 CursorVisibility(vis
);
853 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
855 display
= cv
->c_display
;
868 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
870 display
= cv
->c_display
;
880 LCursorkeysMode(l
, on
)
885 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
887 display
= cv
->c_display
;
902 for (cv
= l
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
904 display
= cv
->c_display
;
918 LClearArea(l
, 0, 0, l
->l_width
- 1, l
->l_height
- 1, 0, uself
);
922 LRefreshAll(l
, isblank
)
926 struct layer
*oldflayer
;
929 debug1("LRefreshAll isblank=%d\n", isblank
);
933 LClearArea(l
, 0, 0, l
->l_width
- 1, l
->l_height
- 1, 0, 0);
934 /* signal full refresh */
935 LayRedisplayLine(-1, -1, -1, 1);
936 for (y
= 0; y
< l
->l_height
; y
++)
937 LayRedisplayLine(y
, 0, l
->l_width
- 1, 1);
943 #if defined(USEVARARGS) && defined(__STDC__)
944 LMsg(int err
, const char *fmt
, VA_DOTS
)
946 LMsg(err
, fmt
, VA_DOTS
)
953 char buf
[MAXPATHLEN
*2];
959 (void)vsnprintf(p
, sizeof(buf
) - 100, fmt
, VA_ARGS(ap
));
966 strncpy(p
, strerror(err
), buf
+ sizeof(buf
) - p
- 1);
967 buf
[sizeof(buf
) - 1] = 0;
969 debug2("LMsg('%s') (%#x);\n", buf
, (unsigned int)flayer
);
970 for (display
= displays
; display
; display
= display
->d_next
)
972 for (cv
= D_cvlist
; cv
; cv
= cv
->c_next
)
973 if (cv
->c_layer
== flayer
)
982 /*******************************************************************/
983 /*******************************************************************/
986 * Layer creation / removal
993 struct canvas
*cv
, *ncv
;
994 struct layer
*l
, *oldflayer
;
997 debug1("KillLayerChain %#x\n", lay
);
998 for (l
= lay
; l
; l
= l
->l_next
)
1000 if (l
->l_layfn
== &WinLf
|| l
->l_layfn
== &BlankLf
)
1002 debug1("- killing %#x\n", l
);
1005 for (cv
= l
->l_cvlist
; cv
; cv
= ncv
)
1021 InitOverlayPage(datasize
, lf
, block
)
1023 struct LayFuncs
*lf
;
1027 struct layer
*newlay
;
1028 struct canvas
*cv
, *cvp
, **cvpp
;
1034 if (display
&& D_forecv
->c_layer
== flayer
)
1035 cv
= D_forecv
; /* work only on this cv! */
1037 if ((newlay
= (struct layer
*)calloc(1, sizeof(struct layer
))) == 0)
1039 Msg(0, "No memory for layer struct");
1042 debug2("Entering new layer on top of %#x: %#x\n", (unsigned int)flayer
, newlay
);
1046 if ((data
= calloc(1, datasize
)) == 0)
1048 free((char *)newlay
);
1049 Msg(0, "No memory for layer data");
1054 p
= Layer2Window(flayer
);
1056 if (p
&& (p
->w_savelayer
== flayer
|| (block
&& flayer
->l_next
== 0)))
1058 if (p
->w_savelayer
&& p
->w_savelayer
!= flayer
&& p
->w_savelayer
->l_cvlist
== 0)
1059 KillLayerChain(p
->w_savelayer
);
1060 p
->w_savelayer
= newlay
;
1063 if (cv
&& flayer
->l_next
== 0 && !block
)
1065 struct display
*olddisplay
= display
;
1066 display
= cv
->c_display
;
1068 display
= olddisplay
;
1070 /* new branch -> just get canvas vps */
1071 for (cvpp
= &flayer
->l_cvlist
; (cvp
= *cvpp
); cvpp
= &cvp
->c_lnext
)
1075 *cvpp
= cv
->c_lnext
;
1076 newlay
->l_cvlist
= cv
;
1078 cv
->c_layer
= newlay
;
1082 LAY_DISPLAYS(flayer
, RemoveStatus());
1084 debug("layer is blocking\n");
1085 if (block
&& flayer
->l_layfn
== &WinLf
)
1087 debug("...and is first, so window gets blocked\n");
1088 ASSERT(p
->w_blocked
== 0);
1090 newlay
->l_blocking
= 1;
1092 /* change all canvases */
1093 newlay
->l_cvlist
= flayer
->l_cvlist
;
1094 for (cvp
= newlay
->l_cvlist
; cvp
; cvp
= cvp
->c_lnext
)
1095 cvp
->c_layer
= newlay
;
1096 flayer
->l_cvlist
= 0;
1098 newlay
->l_width
= flayer
->l_width
;
1099 newlay
->l_height
= flayer
->l_height
;
1100 newlay
->l_encoding
= 0;
1101 newlay
->l_layfn
= lf
;
1102 newlay
->l_data
= data
;
1103 newlay
->l_next
= flayer
;
1104 newlay
->l_bottom
= flayer
->l_bottom
;
1110 extern struct layout
*layouts
;
1115 struct layer
*oldlay
;
1117 int doredisplay
= 0;
1118 struct canvas
*cv
, *ocv
;
1122 debug1("Exiting layer %#x\n", (unsigned int)flayer
);
1126 if (oldlay
->l_layfn
->lf_LayFree
)
1127 LayFree(oldlay
->l_data
);
1128 free(oldlay
->l_data
);
1131 p
= Layer2Window(flayer
);
1133 flayer
= oldlay
->l_next
;
1134 if (flayer
->l_layfn
== &WinLf
)
1136 if (oldlay
->l_blocking
)
1138 ASSERT(p
->w_blocked
> 0);
1140 debug1("layer was blocking, -> w_blocked now %d\n", p
->w_blocked
);
1142 /* don't warp dead layers: check cvlist */
1143 if (p
->w_blocked
&& p
->w_savelayer
&& p
->w_savelayer
!= flayer
&& oldlay
->l_cvlist
)
1145 debug("warping to top of blocking chain!\n");
1146 /* warp ourself into savelayer */
1147 flayer
= p
->w_savelayer
;
1151 if (p
&& p
->w_savelayer
== oldlay
)
1152 p
->w_savelayer
= flayer
;
1154 if (p
&& oldlay
== p
->w_paster
.pa_pastelayer
)
1155 p
->w_paster
.pa_pastelayer
= 0;
1158 for (lay
= layouts
; lay
; lay
= lay
->lay_next
)
1159 for (cv
= lay
->lay_cvlist
; cv
; cv
= cv
->c_next
)
1160 if (cv
->c_layer
== oldlay
)
1161 cv
->c_layer
= flayer
;
1163 /* add all canvases back into next layer's canvas list */
1164 for (ocv
= 0, cv
= oldlay
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
1166 cv
->c_layer
= flayer
;
1171 cv
= flayer
->l_cvlist
;
1173 flayer
->l_cvlist
= oldlay
->l_cvlist
;
1174 /* redisplay only the warped cvs */
1176 LRefreshAll(flayer
, 0);
1179 oldlay
->l_cvlist
= 0;
1180 LayerCleanupMemory(oldlay
);
1181 free((char *)oldlay
);
1187 LayProcessMouse(struct layer
*l
, unsigned char ch
)
1189 /* XXX: Make sure the layer accepts mouse events */
1192 if (l
->l_mouseevent
.len
>= sizeof(l
->l_mouseevent
.buffer
))
1195 len
= l
->l_mouseevent
.len
++;
1196 l
->l_mouseevent
.buffer
[len
] = (len
> 0 ? ch
- 33 : ch
);
1197 return (l
->l_mouseevent
.len
== sizeof(l
->l_mouseevent
.buffer
));
1201 LayProcessMouseSwitch(struct layer
*l
, int s
)
1203 if ((l
->l_mouseevent
.start
= s
))
1205 l
->l_mouseevent
.len
= 0;
1209 void LayPause(layer
, pause
)
1210 struct layer
*layer
;
1214 struct display
*olddisplay
= display
;
1220 if (layer
->l_pause
.d
== pause
)
1223 if ((layer
->l_pause
.d
= pause
))
1226 layer
->l_pause
.top
= layer
->l_pause
.bottom
= -1;
1230 /* Unpause. So refresh the regions in the displays! */
1231 if (layer
->l_pause
.top
== -1 &&
1232 layer
->l_pause
.bottom
== -1)
1235 if (layer
->l_layfn
== &WinLf
) /* Currently, this will always be the case! */
1236 win
= layer
->l_data
;
1240 for (cv
= layer
->l_cvlist
; cv
; cv
= cv
->c_lnext
)
1242 struct viewport
*vp
;
1244 if (!cv
->c_slorient
)
1245 continue; /* Wasn't split, so already updated. */
1247 display
= cv
->c_display
;
1249 for (vp
= cv
->c_vplist
; vp
; vp
= vp
->v_next
)
1251 for (line
= layer
->l_pause
.top
; line
<= layer
->l_pause
.bottom
; line
++)
1255 if (line
+ vp
->v_yoff
>= vp
->v_ys
&& line
+ vp
->v_yoff
<= vp
->v_ye
&&
1256 ((xs
= layer
->l_pause
.left
[line
]) >= 0) &&
1257 ((xe
= layer
->l_pause
.right
[line
]) >= 0))
1262 if (xs
< vp
->v_xs
) xs
= vp
->v_xs
;
1263 if (xe
> vp
->v_xe
) xe
= vp
->v_xe
;
1265 #if defined(DW_CHARS) && defined(UTF8)
1266 if (layer
->l_encoding
== UTF8
&& xe
< vp
->v_xe
&& win
)
1268 struct mline
*ml
= win
->w_mlines
+ line
;
1269 if (dw_left(ml
, xe
, UTF8
))
1275 RefreshLine(line
+ vp
->v_yoff
, xs
, xe
, 0);
1282 int cx
= layer
->l_x
+ cv
->c_xoff
;
1283 int cy
= layer
->l_y
+ cv
->c_yoff
;
1285 if (cx
< cv
->c_xs
) cx
= cv
->c_xs
;
1286 if (cy
< cv
->c_ys
) cy
= cv
->c_ys
;
1287 if (cx
> cv
->c_xe
) cx
= cv
->c_xe
;
1288 if (cy
> cv
->c_ye
) cy
= cv
->c_ye
;
1294 for (line
= layer
->l_pause
.top
; line
<= layer
->l_pause
.bottom
; line
++)
1295 layer
->l_pause
.left
[line
] = layer
->l_pause
.right
[line
] = -1;
1296 olddisplay
= display
;
1300 LayPauseUpdateRegion(layer
, xs
, xe
, ys
, ye
)
1301 struct layer
*layer
;
1305 if (!layer
->l_pause
.d
)
1309 if (ye
>= layer
->l_height
)
1310 ye
= layer
->l_height
- 1;
1311 if (xe
>= layer
->l_width
)
1312 xe
= layer
->l_width
- 1;
1314 if (layer
->l_pause
.top
== -1 || layer
->l_pause
.top
> ys
)
1315 layer
->l_pause
.top
= ys
;
1316 if (layer
->l_pause
.bottom
< ye
)
1318 layer
->l_pause
.bottom
= ye
;
1319 if (layer
->l_pause
.lines
<= ye
)
1321 int o
= layer
->l_pause
.lines
;
1322 layer
->l_pause
.lines
= ye
+ 32;
1323 layer
->l_pause
.left
= realloc(layer
->l_pause
.left
, sizeof(int) * layer
->l_pause
.lines
);
1324 layer
->l_pause
.right
= realloc(layer
->l_pause
.right
, sizeof(int) * layer
->l_pause
.lines
);
1325 while (o
< layer
->l_pause
.lines
)
1327 layer
->l_pause
.left
[o
] = layer
->l_pause
.right
[o
] = -1;
1335 if (layer
->l_pause
.left
[ys
] == -1 || layer
->l_pause
.left
[ys
] > xs
)
1336 layer
->l_pause
.left
[ys
] = xs
;
1337 if (layer
->l_pause
.right
[ys
] < xe
)
1338 layer
->l_pause
.right
[ys
] = xe
;
1344 LayerCleanupMemory(layer
)
1345 struct layer
*layer
;
1347 if (layer
->l_pause
.left
)
1348 free(layer
->l_pause
.left
);
1349 if (layer
->l_pause
.right
)
1350 free(layer
->l_pause
.right
);