]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libmemlayer/layerop.c
vncv: do NOT map Kaltgr to meta, introduce Mod4 (Super) as an extra key to use instead
[plan9front.git] / sys / src / libmemlayer / layerop.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <memdraw.h>
5 #include <memlayer.h>
6
7 #define RECUR(a,b,c,d)  _layerop(fn, i, Rect(a.x, b.y, c.x, d.y), clipr, etc, front->layer->rear);
8
9 static void
10 _layerop(
11         void (*fn)(Memimage*, Rectangle, Rectangle, void*, int),
12         Memimage *i,
13         Rectangle r,
14         Rectangle clipr,
15         void *etc,
16         Memimage *front)
17 {
18         Rectangle fr;
19
20     Top:
21         if(front == i){
22                 /* no one is in front of this part of window; use the screen */
23                 fn(i->layer->screen->image, r, clipr, etc, 0);
24                 return;
25         }
26         fr = front->layer->screenr;
27         if(rectXrect(r, fr) == 0){
28                 /* r doesn't touch this window; continue on next rearmost */
29                 // assert(front && front->layer && front->layer->screen && front->layer->rear);
30                 front = front->layer->rear;
31                 goto Top;
32         }
33         if(fr.max.y < r.max.y){
34                 RECUR(r.min, fr.max, r.max, r.max);
35                 r.max.y = fr.max.y;
36         }
37         if(r.min.y < fr.min.y){
38                 RECUR(r.min, r.min, r.max, fr.min);
39                 r.min.y = fr.min.y;
40         }
41         if(fr.max.x < r.max.x){
42                 RECUR(fr.max, r.min, r.max, r.max);
43                 r.max.x = fr.max.x;
44         }
45         if(r.min.x < fr.min.x){
46                 RECUR(r.min, r.min, fr.min, r.max);
47                 r.min.x = fr.min.x;
48         }
49         /* r is covered by front, so put in save area */
50         (*fn)(i->layer->save, r, clipr, etc, 1);
51 }
52
53 /*
54  * Assumes incoming rectangle has already been clipped to i's logical r and clipr
55  */
56 void
57 _memlayerop(
58         void (*fn)(Memimage*, Rectangle, Rectangle, void*, int),
59         Memimage *i,
60         Rectangle screenr,      /* clipped to window boundaries */
61         Rectangle clipr,                /* clipped also to clipping rectangles of hierarchy */
62         void *etc)
63 {
64         Memlayer *l;
65         Rectangle r, scr;
66
67         l = i->layer;
68         if(!rectclip(&screenr, l->screenr))
69                 return;
70         if(l->clear){
71                 fn(l->screen->image, screenr, clipr, etc, 0);
72                 return;
73         }
74         r = screenr;
75         scr = l->screen->image->clipr;
76
77         /*
78          * Do the piece on the screen
79          */
80         if(rectclip(&screenr, scr))
81                 _layerop(fn, i, screenr, clipr, etc, l->screen->frontmost);
82         if(rectinrect(r, scr))
83                 return;
84
85         /*
86          * Do the piece off the screen
87         */
88         if(!rectXrect(r, scr)){
89                 /* completely offscreen; easy */
90                 fn(l->save, r, clipr, etc, 1);
91                 return;
92         }
93         if(r.min.y < scr.min.y){
94                 /* above screen */
95                 fn(l->save, Rect(r.min.x, r.min.y, r.max.x, scr.min.y), clipr, etc, 1);
96                 r.min.y = scr.min.y;
97         }
98         if(r.max.y > scr.max.y){
99                 /* below screen */
100                 fn(l->save, Rect(r.min.x, scr.max.y, r.max.x, r.max.y), clipr, etc, 1);
101                 r.max.y = scr.max.y;
102         }
103         if(r.min.x < scr.min.x){
104                 /* left of screen */
105                 fn(l->save, Rect(r.min.x, r.min.y, scr.min.x, r.max.y), clipr, etc, 1);
106                 r.min.x = scr.min.x;
107         }
108         if(r.max.x > scr.max.x){
109                 /* right of screen */
110                 fn(l->save, Rect(scr.max.x, r.min.y, r.max.x, r.max.y), clipr, etc, 1);
111         }
112 }