1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier #include <draw.h>
4*8ccd4a63SDavid du Colombier #include <memdraw.h>
5*8ccd4a63SDavid du Colombier #include <memlayer.h>
67dd7cddfSDavid du Colombier
77dd7cddfSDavid du Colombier #define RECUR(a,b,c,d) _layerop(fn, i, Rect(a.x, b.y, c.x, d.y), clipr, etc, front->layer->rear);
87dd7cddfSDavid du Colombier
97dd7cddfSDavid du Colombier static void
_layerop(void (* fn)(Memimage *,Rectangle,Rectangle,void *,int),Memimage * i,Rectangle r,Rectangle clipr,void * etc,Memimage * front)107dd7cddfSDavid du Colombier _layerop(
117dd7cddfSDavid du Colombier void (*fn)(Memimage*, Rectangle, Rectangle, void*, int),
127dd7cddfSDavid du Colombier Memimage *i,
137dd7cddfSDavid du Colombier Rectangle r,
147dd7cddfSDavid du Colombier Rectangle clipr,
157dd7cddfSDavid du Colombier void *etc,
167dd7cddfSDavid du Colombier Memimage *front)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier Rectangle fr;
197dd7cddfSDavid du Colombier
207dd7cddfSDavid du Colombier Top:
217dd7cddfSDavid du Colombier if(front == i){
227dd7cddfSDavid du Colombier /* no one is in front of this part of window; use the screen */
237dd7cddfSDavid du Colombier fn(i->layer->screen->image, r, clipr, etc, 0);
247dd7cddfSDavid du Colombier return;
257dd7cddfSDavid du Colombier }
267dd7cddfSDavid du Colombier fr = front->layer->screenr;
277dd7cddfSDavid du Colombier if(rectXrect(r, fr) == 0){
287dd7cddfSDavid du Colombier /* r doesn't touch this window; continue on next rearmost */
29*8ccd4a63SDavid du Colombier // assert(front && front->layer && front->layer->screen && front->layer->rear);
307dd7cddfSDavid du Colombier front = front->layer->rear;
317dd7cddfSDavid du Colombier goto Top;
327dd7cddfSDavid du Colombier }
337dd7cddfSDavid du Colombier if(fr.max.y < r.max.y){
347dd7cddfSDavid du Colombier RECUR(r.min, fr.max, r.max, r.max);
357dd7cddfSDavid du Colombier r.max.y = fr.max.y;
367dd7cddfSDavid du Colombier }
377dd7cddfSDavid du Colombier if(r.min.y < fr.min.y){
387dd7cddfSDavid du Colombier RECUR(r.min, r.min, r.max, fr.min);
397dd7cddfSDavid du Colombier r.min.y = fr.min.y;
407dd7cddfSDavid du Colombier }
417dd7cddfSDavid du Colombier if(fr.max.x < r.max.x){
427dd7cddfSDavid du Colombier RECUR(fr.max, r.min, r.max, r.max);
437dd7cddfSDavid du Colombier r.max.x = fr.max.x;
447dd7cddfSDavid du Colombier }
457dd7cddfSDavid du Colombier if(r.min.x < fr.min.x){
467dd7cddfSDavid du Colombier RECUR(r.min, r.min, fr.min, r.max);
477dd7cddfSDavid du Colombier r.min.x = fr.min.x;
487dd7cddfSDavid du Colombier }
497dd7cddfSDavid du Colombier /* r is covered by front, so put in save area */
507dd7cddfSDavid du Colombier (*fn)(i->layer->save, r, clipr, etc, 1);
517dd7cddfSDavid du Colombier }
527dd7cddfSDavid du Colombier
537dd7cddfSDavid du Colombier /*
547dd7cddfSDavid du Colombier * Assumes incoming rectangle has already been clipped to i's logical r and clipr
557dd7cddfSDavid du Colombier */
567dd7cddfSDavid du Colombier void
_memlayerop(void (* fn)(Memimage *,Rectangle,Rectangle,void *,int),Memimage * i,Rectangle screenr,Rectangle clipr,void * etc)57*8ccd4a63SDavid du Colombier _memlayerop(
587dd7cddfSDavid du Colombier void (*fn)(Memimage*, Rectangle, Rectangle, void*, int),
597dd7cddfSDavid du Colombier Memimage *i,
607dd7cddfSDavid du Colombier Rectangle screenr, /* clipped to window boundaries */
617dd7cddfSDavid du Colombier Rectangle clipr, /* clipped also to clipping rectangles of hierarchy */
627dd7cddfSDavid du Colombier void *etc)
637dd7cddfSDavid du Colombier {
647dd7cddfSDavid du Colombier Memlayer *l;
657dd7cddfSDavid du Colombier Rectangle r, scr;
667dd7cddfSDavid du Colombier
677dd7cddfSDavid du Colombier l = i->layer;
687dd7cddfSDavid du Colombier if(!rectclip(&screenr, l->screenr))
697dd7cddfSDavid du Colombier return;
707dd7cddfSDavid du Colombier if(l->clear){
717dd7cddfSDavid du Colombier fn(l->screen->image, screenr, clipr, etc, 0);
727dd7cddfSDavid du Colombier return;
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier r = screenr;
757dd7cddfSDavid du Colombier scr = l->screen->image->clipr;
767dd7cddfSDavid du Colombier
777dd7cddfSDavid du Colombier /*
787dd7cddfSDavid du Colombier * Do the piece on the screen
797dd7cddfSDavid du Colombier */
807dd7cddfSDavid du Colombier if(rectclip(&screenr, scr))
817dd7cddfSDavid du Colombier _layerop(fn, i, screenr, clipr, etc, l->screen->frontmost);
827dd7cddfSDavid du Colombier if(rectinrect(r, scr))
837dd7cddfSDavid du Colombier return;
847dd7cddfSDavid du Colombier
857dd7cddfSDavid du Colombier /*
867dd7cddfSDavid du Colombier * Do the piece off the screen
877dd7cddfSDavid du Colombier */
887dd7cddfSDavid du Colombier if(!rectXrect(r, scr)){
897dd7cddfSDavid du Colombier /* completely offscreen; easy */
907dd7cddfSDavid du Colombier fn(l->save, r, clipr, etc, 1);
917dd7cddfSDavid du Colombier return;
927dd7cddfSDavid du Colombier }
937dd7cddfSDavid du Colombier if(r.min.y < scr.min.y){
947dd7cddfSDavid du Colombier /* above screen */
957dd7cddfSDavid du Colombier fn(l->save, Rect(r.min.x, r.min.y, r.max.x, scr.min.y), clipr, etc, 1);
967dd7cddfSDavid du Colombier r.min.y = scr.min.y;
977dd7cddfSDavid du Colombier }
987dd7cddfSDavid du Colombier if(r.max.y > scr.max.y){
997dd7cddfSDavid du Colombier /* below screen */
1007dd7cddfSDavid du Colombier fn(l->save, Rect(r.min.x, scr.max.y, r.max.x, r.max.y), clipr, etc, 1);
1017dd7cddfSDavid du Colombier r.max.y = scr.max.y;
1027dd7cddfSDavid du Colombier }
1037dd7cddfSDavid du Colombier if(r.min.x < scr.min.x){
1047dd7cddfSDavid du Colombier /* left of screen */
1057dd7cddfSDavid du Colombier fn(l->save, Rect(r.min.x, r.min.y, scr.min.x, r.max.y), clipr, etc, 1);
1067dd7cddfSDavid du Colombier r.min.x = scr.min.x;
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier if(r.max.x > scr.max.x){
1097dd7cddfSDavid du Colombier /* right of screen */
1107dd7cddfSDavid du Colombier fn(l->save, Rect(scr.max.x, r.min.y, r.max.x, r.max.y), clipr, etc, 1);
1117dd7cddfSDavid du Colombier }
1127dd7cddfSDavid du Colombier }
113