Import sources from 2011-03-30 iso image

This commit is contained in:
Taru Karttunen 2011-03-30 15:46:40 +03:00
commit e5888a1ffd
7810 changed files with 2489717 additions and 0 deletions

193
sys/src/libmemlayer/draw.c Executable file
View file

@ -0,0 +1,193 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
#include <pool.h>
struct Draw
{
Point deltas;
Point deltam;
Memlayer *dstlayer;
Memimage *src;
Memimage *mask;
int op;
};
static
void
ldrawop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
{
struct Draw *d;
Point p0, p1;
Rectangle oclipr, srcr, r, mr;
int ok;
d = etc;
if(insave && d->dstlayer->save==nil)
return;
p0 = addpt(screenr.min, d->deltas);
p1 = addpt(screenr.min, d->deltam);
if(insave){
r = rectsubpt(screenr, d->dstlayer->delta);
clipr = rectsubpt(clipr, d->dstlayer->delta);
}else
r = screenr;
/* now in logical coordinates */
/* clipr may have narrowed what we should draw on, so clip if necessary */
if(!rectinrect(r, clipr)){
oclipr = dst->clipr;
dst->clipr = clipr;
ok = drawclip(dst, &r, d->src, &p0, d->mask, &p1, &srcr, &mr);
dst->clipr = oclipr;
if(!ok)
return;
}
memdraw(dst, r, d->src, p0, d->mask, p1, d->op);
}
void
memdraw(Memimage *dst, Rectangle r, Memimage *src, Point p0, Memimage *mask, Point p1, int op)
{
struct Draw d;
Rectangle srcr, tr, mr;
Memlayer *dl, *sl;
if(drawdebug)
iprint("memdraw %p %R %p %P %p %P\n", dst, r, src, p0, mask, p1);
if(mask == nil)
mask = memopaque;
if(mask->layer){
if(drawdebug) iprint("mask->layer != nil\n");
return; /* too hard, at least for now */
}
Top:
if(dst->layer==nil && src->layer==nil){
memimagedraw(dst, r, src, p0, mask, p1, op);
return;
}
if(drawclip(dst, &r, src, &p0, mask, &p1, &srcr, &mr) == 0){
if(drawdebug) iprint("drawclip dstcr %R srccr %R maskcr %R\n", dst->clipr, src->clipr, mask->clipr);
return;
}
/*
* Convert to screen coordinates.
*/
dl = dst->layer;
if(dl != nil){
r.min.x += dl->delta.x;
r.min.y += dl->delta.y;
r.max.x += dl->delta.x;
r.max.y += dl->delta.y;
}
Clearlayer:
if(dl!=nil && dl->clear){
if(src == dst){
p0.x += dl->delta.x;
p0.y += dl->delta.y;
src = dl->screen->image;
}
dst = dl->screen->image;
goto Top;
}
sl = src->layer;
if(sl != nil){
p0.x += sl->delta.x;
p0.y += sl->delta.y;
srcr.min.x += sl->delta.x;
srcr.min.y += sl->delta.y;
srcr.max.x += sl->delta.x;
srcr.max.y += sl->delta.y;
}
/*
* Now everything is in screen coordinates.
* mask is an image. dst and src are images or obscured layers.
*/
/*
* if dst and src are the same layer, just draw in save area and expose.
*/
if(dl!=nil && dst==src){
if(dl->save == nil)
return; /* refresh function makes this case unworkable */
if(rectXrect(r, srcr)){
tr = r;
if(srcr.min.x < tr.min.x){
p1.x += tr.min.x - srcr.min.x;
tr.min.x = srcr.min.x;
}
if(srcr.min.y < tr.min.y){
p1.y += tr.min.x - srcr.min.x;
tr.min.y = srcr.min.y;
}
if(srcr.max.x > tr.max.x)
tr.max.x = srcr.max.x;
if(srcr.max.y > tr.max.y)
tr.max.y = srcr.max.y;
memlhide(dst, tr);
}else{
memlhide(dst, r);
memlhide(dst, srcr);
}
memdraw(dl->save, rectsubpt(r, dl->delta), dl->save,
subpt(srcr.min, src->layer->delta), mask, p1, op);
memlexpose(dst, r);
return;
}
if(sl){
if(sl->clear){
src = sl->screen->image;
if(dl != nil){
r.min.x -= dl->delta.x;
r.min.y -= dl->delta.y;
r.max.x -= dl->delta.x;
r.max.y -= dl->delta.y;
}
goto Top;
}
/* relatively rare case; use save area */
if(sl->save == nil)
return; /* refresh function makes this case unworkable */
memlhide(src, srcr);
/* convert back to logical coordinates */
p0.x -= sl->delta.x;
p0.y -= sl->delta.y;
srcr.min.x -= sl->delta.x;
srcr.min.y -= sl->delta.y;
srcr.max.x -= sl->delta.x;
srcr.max.y -= sl->delta.y;
src = src->layer->save;
}
/*
* src is now an image. dst may be an image or a clear layer
*/
if(dst->layer==nil)
goto Top;
if(dst->layer->clear)
goto Clearlayer;
/*
* dst is an obscured layer
*/
d.deltas = subpt(p0, r.min);
d.deltam = subpt(p1, r.min);
d.dstlayer = dl;
d.src = src;
d.op = op;
d.mask = mask;
_memlayerop(ldrawop, dst, r, r, &d);
}

79
sys/src/libmemlayer/lalloc.c Executable file
View file

@ -0,0 +1,79 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
Memimage*
memlalloc(Memscreen *s, Rectangle screenr, Refreshfn refreshfn, void *refreshptr, ulong val)
{
Memlayer *l;
Memimage *n;
static Memimage *paint;
if(paint == nil){
paint = allocmemimage(Rect(0,0,1,1), RGBA32);
if(paint == nil)
return nil;
paint->flags |= Frepl;
paint->clipr = Rect(-0x3FFFFFF, -0x3FFFFFF, 0x3FFFFFF, 0x3FFFFFF);
}
n = allocmemimaged(screenr, s->image->chan, s->image->data);
if(n == nil)
return nil;
l = malloc(sizeof(Memlayer));
if(l == nil){
free(n);
return nil;
}
l->screen = s;
if(refreshfn)
l->save = nil;
else{
l->save = allocmemimage(screenr, s->image->chan);
if(l->save == nil){
free(l);
free(n);
return nil;
}
/* allocmemimage doesn't initialize memory; this paints save area */
if(val != DNofill)
memfillcolor(l->save, val);
}
l->refreshfn = refreshfn;
l->refreshptr = nil; /* don't set it until we're done */
l->screenr = screenr;
l->delta = Pt(0,0);
n->data->ref++;
n->zero = s->image->zero;
n->width = s->image->width;
n->layer = l;
/* start with new window behind all existing ones */
l->front = s->rearmost;
l->rear = nil;
if(s->rearmost)
s->rearmost->layer->rear = n;
s->rearmost = n;
if(s->frontmost == nil)
s->frontmost = n;
l->clear = 0;
/* now pull new window to front */
_memltofrontfill(n, val != DNofill);
l->refreshptr = refreshptr;
/*
* paint with requested color; previously exposed areas are already right
* if this window has backing store, but just painting the whole thing is simplest.
*/
if(val != DNofill){
memsetchan(paint, n->chan);
memfillcolor(paint, val);
memdraw(n, n->r, paint, n->r.min, nil, n->r.min, S);
}
return n;
}

112
sys/src/libmemlayer/layerop.c Executable file
View file

@ -0,0 +1,112 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
#define RECUR(a,b,c,d) _layerop(fn, i, Rect(a.x, b.y, c.x, d.y), clipr, etc, front->layer->rear);
static void
_layerop(
void (*fn)(Memimage*, Rectangle, Rectangle, void*, int),
Memimage *i,
Rectangle r,
Rectangle clipr,
void *etc,
Memimage *front)
{
Rectangle fr;
Top:
if(front == i){
/* no one is in front of this part of window; use the screen */
fn(i->layer->screen->image, r, clipr, etc, 0);
return;
}
fr = front->layer->screenr;
if(rectXrect(r, fr) == 0){
/* r doesn't touch this window; continue on next rearmost */
// assert(front && front->layer && front->layer->screen && front->layer->rear);
front = front->layer->rear;
goto Top;
}
if(fr.max.y < r.max.y){
RECUR(r.min, fr.max, r.max, r.max);
r.max.y = fr.max.y;
}
if(r.min.y < fr.min.y){
RECUR(r.min, r.min, r.max, fr.min);
r.min.y = fr.min.y;
}
if(fr.max.x < r.max.x){
RECUR(fr.max, r.min, r.max, r.max);
r.max.x = fr.max.x;
}
if(r.min.x < fr.min.x){
RECUR(r.min, r.min, fr.min, r.max);
r.min.x = fr.min.x;
}
/* r is covered by front, so put in save area */
(*fn)(i->layer->save, r, clipr, etc, 1);
}
/*
* Assumes incoming rectangle has already been clipped to i's logical r and clipr
*/
void
_memlayerop(
void (*fn)(Memimage*, Rectangle, Rectangle, void*, int),
Memimage *i,
Rectangle screenr, /* clipped to window boundaries */
Rectangle clipr, /* clipped also to clipping rectangles of hierarchy */
void *etc)
{
Memlayer *l;
Rectangle r, scr;
l = i->layer;
if(!rectclip(&screenr, l->screenr))
return;
if(l->clear){
fn(l->screen->image, screenr, clipr, etc, 0);
return;
}
r = screenr;
scr = l->screen->image->clipr;
/*
* Do the piece on the screen
*/
if(rectclip(&screenr, scr))
_layerop(fn, i, screenr, clipr, etc, l->screen->frontmost);
if(rectinrect(r, scr))
return;
/*
* Do the piece off the screen
*/
if(!rectXrect(r, scr)){
/* completely offscreen; easy */
fn(l->save, r, clipr, etc, 1);
return;
}
if(r.min.y < scr.min.y){
/* above screen */
fn(l->save, Rect(r.min.x, r.min.y, r.max.x, scr.min.y), clipr, etc, 1);
r.min.y = scr.min.y;
}
if(r.max.y > scr.max.y){
/* below screen */
fn(l->save, Rect(r.min.x, scr.max.y, r.max.x, r.max.y), clipr, etc, 1);
r.max.y = scr.max.y;
}
if(r.min.x < scr.min.x){
/* left of screen */
fn(l->save, Rect(r.min.x, r.min.y, scr.min.x, r.max.y), clipr, etc, 1);
r.min.x = scr.min.x;
}
if(r.max.x > scr.max.x){
/* right of screen */
fn(l->save, Rect(scr.max.x, r.min.y, r.max.x, r.max.y), clipr, etc, 1);
}
}

67
sys/src/libmemlayer/ldelete.c Executable file
View file

@ -0,0 +1,67 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
void
memldelete(Memimage *i)
{
Memscreen *s;
Memlayer *l;
l = i->layer;
/* free backing store and disconnect refresh, to make pushback fast */
freememimage(l->save);
l->save = nil;
l->refreshptr = nil;
memltorear(i);
/* window is now the rearmost; clean up screen structures and deallocate */
s = i->layer->screen;
if(s->fill){
i->clipr = i->r;
memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min, S);
}
if(l->front){
l->front->layer->rear = nil;
s->rearmost = l->front;
}else{
s->frontmost = nil;
s->rearmost = nil;
}
free(l);
freememimage(i);
}
/*
* Just free the data structures, don't do graphics
*/
void
memlfree(Memimage *i)
{
Memlayer *l;
l = i->layer;
freememimage(l->save);
free(l);
freememimage(i);
}
void
_memlsetclear(Memscreen *s)
{
Memimage *i, *j;
Memlayer *l;
for(i=s->rearmost; i; i=i->layer->front){
l = i->layer;
l->clear = rectinrect(l->screenr, l->screen->image->clipr);
if(l->clear)
for(j=l->front; j; j=j->layer->front)
if(rectXrect(l->screenr, j->layer->screenr)){
l->clear = 0;
break;
}
}
}

68
sys/src/libmemlayer/lhide.c Executable file
View file

@ -0,0 +1,68 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
#include <pool.h>
/*
* Hide puts that portion of screenr now on the screen into the window's save area.
* Expose puts that portion of screenr now in the save area onto the screen.
*
* Hide and Expose both require that the layer structures in the screen
* match the geometry they are being asked to update, that is, they update the
* save area (hide) or screen (expose) based on what those structures tell them.
* This means they must be called at the correct time during window shuffles.
*/
static
void
lhideop(Memimage *src, Rectangle screenr, Rectangle clipr, void *etc, int insave)
{
Rectangle r;
Memlayer *l;
USED(clipr.min.x);
USED(insave);
l = etc;
if(src != l->save){ /* do nothing if src is already in save area */
r = rectsubpt(screenr, l->delta);
memdraw(l->save, r, src, screenr.min, nil, screenr.min, S);
}
}
void
memlhide(Memimage *i, Rectangle screenr)
{
if(i->layer->save == nil)
return;
if(rectclip(&screenr, i->layer->screen->image->r) == 0)
return;
_memlayerop(lhideop, i, screenr, screenr, i->layer);
}
static
void
lexposeop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
{
Memlayer *l;
Rectangle r;
USED(clipr.min.x);
if(insave) /* if dst is save area, don't bother */
return;
l = etc;
r = rectsubpt(screenr, l->delta);
if(l->save)
memdraw(dst, screenr, l->save, r.min, nil, r.min, S);
else
l->refreshfn(dst, r, l->refreshptr);
}
void
memlexpose(Memimage *i, Rectangle screenr)
{
if(rectclip(&screenr, i->layer->screen->image->r) == 0)
return;
_memlayerop(lexposeop, i, screenr, screenr, i->layer);
}

122
sys/src/libmemlayer/line.c Executable file
View file

@ -0,0 +1,122 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
struct Lline
{
Point p0;
Point p1;
Point delta;
int end0;
int end1;
int radius;
Point sp;
Memlayer *dstlayer;
Memimage *src;
int op;
};
static void llineop(Memimage*, Rectangle, Rectangle, void*, int);
static
void
_memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, Rectangle clipr, int op)
{
Rectangle r;
struct Lline ll;
Point d;
int srcclipped;
Memlayer *dl;
if(radius < 0)
return;
if(src->layer) /* can't draw line with layered source */
return;
srcclipped = 0;
Top:
dl = dst->layer;
if(dl == nil){
_memimageline(dst, p0, p1, end0, end1, radius, src, sp, clipr, op);
return;
}
if(!srcclipped){
d = subpt(sp, p0);
if(rectclip(&clipr, rectsubpt(src->clipr, d)) == 0)
return;
if((src->flags&Frepl)==0 && rectclip(&clipr, rectsubpt(src->r, d))==0)
return;
srcclipped = 1;
}
/* dst is known to be a layer */
p0.x += dl->delta.x;
p0.y += dl->delta.y;
p1.x += dl->delta.x;
p1.y += dl->delta.y;
clipr.min.x += dl->delta.x;
clipr.min.y += dl->delta.y;
clipr.max.x += dl->delta.x;
clipr.max.y += dl->delta.y;
if(dl->clear){
dst = dst->layer->screen->image;
goto Top;
}
/* XXX */
/* this is not the correct set of tests */
// if(log2[dst->depth] != log2[src->depth] || log2[dst->depth]!=3)
// return;
/* can't use sutherland-cohen clipping because lines are wide */
r = memlinebbox(p0, p1, end0, end1, radius);
/*
* r is now a bounding box for the line;
* use it as a clipping rectangle for subdivision
*/
if(rectclip(&r, clipr) == 0)
return;
ll.p0 = p0;
ll.p1 = p1;
ll.end0 = end0;
ll.end1 = end1;
ll.sp = sp;
ll.dstlayer = dst->layer;
ll.src = src;
ll.radius = radius;
ll.delta = dl->delta;
ll.op = op;
_memlayerop(llineop, dst, r, r, &ll);
}
static
void
llineop(Memimage *dst, Rectangle screenr, Rectangle clipr, void *etc, int insave)
{
struct Lline *ll;
Point p0, p1;
USED(screenr.min.x);
ll = etc;
if(insave && ll->dstlayer->save==nil)
return;
if(!rectclip(&clipr, screenr))
return;
if(insave){
p0 = subpt(ll->p0, ll->delta);
p1 = subpt(ll->p1, ll->delta);
clipr = rectsubpt(clipr, ll->delta);
}else{
p0 = ll->p0;
p1 = ll->p1;
}
_memline(dst, p0, p1, ll->end0, ll->end1, ll->radius, ll->src, ll->sp, clipr, ll->op);
}
void
memline(Memimage *dst, Point p0, Point p1, int end0, int end1, int radius, Memimage *src, Point sp, int op)
{
_memline(dst, p0, p1, end0, end1, radius, src, sp, dst->clipr, op);
}

55
sys/src/libmemlayer/load.c Executable file
View file

@ -0,0 +1,55 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
int
memload(Memimage *dst, Rectangle r, uchar *data, int n, int iscompressed)
{
int (*loadfn)(Memimage*, Rectangle, uchar*, int);
Memimage *tmp;
Memlayer *dl;
Rectangle lr;
int dx;
loadfn = loadmemimage;
if(iscompressed)
loadfn = cloadmemimage;
Top:
dl = dst->layer;
if(dl == nil)
return loadfn(dst, r, data, n);
/*
* Convert to screen coordinates.
*/
lr = r;
r.min.x += dl->delta.x;
r.min.y += dl->delta.y;
r.max.x += dl->delta.x;
r.max.y += dl->delta.y;
dx = dl->delta.x&(7/dst->depth);
if(dl->clear && dx==0){
dst = dl->screen->image;
goto Top;
}
/*
* dst is an obscured layer or data is unaligned
*/
if(dl->save && dx==0){
n = loadfn(dl->save, lr, data, n);
if(n > 0)
memlexpose(dst, r);
return n;
}
tmp = allocmemimage(lr, dst->chan);
if(tmp == nil)
return -1;
n = loadfn(tmp, lr, data, n);
memdraw(dst, lr, tmp, lr.min, nil, lr.min, S);
freememimage(tmp);
return n;
}

107
sys/src/libmemlayer/lorigin.c Executable file
View file

@ -0,0 +1,107 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
/*
* Place i so i->r.min = log, i->layer->screenr.min == scr.
*/
int
memlorigin(Memimage *i, Point log, Point scr)
{
Memlayer *l;
Memscreen *s;
Memimage *t, *shad, *nsave;
Rectangle x, newr, oldr;
Point delta;
int overlap, eqlog, eqscr, wasclear;
l = i->layer;
s = l->screen;
oldr = l->screenr;
newr = Rect(scr.x, scr.y, scr.x+Dx(oldr), scr.y+Dy(oldr));
eqscr = eqpt(scr, oldr.min);
eqlog = eqpt(log, i->r.min);
if(eqscr && eqlog)
return 0;
nsave = nil;
if(eqlog==0 && l->save!=nil){
nsave = allocmemimage(Rect(log.x, log.y, log.x+Dx(oldr), log.y+Dy(oldr)), i->chan);
if(nsave == nil)
return -1;
}
/*
* Bring it to front and move logical coordinate system.
*/
memltofront(i);
wasclear = l->clear;
if(nsave){
if(!wasclear)
memimagedraw(nsave, nsave->r, l->save, l->save->r.min, nil, Pt(0,0), S);
freememimage(l->save);
l->save = nsave;
}
delta = subpt(log, i->r.min);
i->r = rectaddpt(i->r, delta);
i->clipr = rectaddpt(i->clipr, delta);
l->delta = subpt(l->screenr.min, i->r.min);
if(eqscr)
return 0;
/*
* To clean up old position, make a shadow window there, don't paint it,
* push it behind this one, and (later) delete it. Because the refresh function
* for this fake window is a no-op, this will cause no graphics action except
* to restore the background and expose the windows previously hidden.
*/
shad = memlalloc(s, oldr, memlnorefresh, nil, DNofill);
if(shad == nil)
return -1;
s->frontmost = i;
if(s->rearmost == i)
s->rearmost = shad;
else
l->rear->layer->front = shad;
shad->layer->front = i;
shad->layer->rear = l->rear;
l->rear = shad;
l->front = nil;
shad->layer->clear = 0;
/*
* Shadow is now holding down the fort at the old position.
* Move the window and hide things obscured by new position.
*/
for(t=l->rear->layer->rear; t!=nil; t=t->layer->rear){
x = newr;
overlap = rectclip(&x, t->layer->screenr);
if(overlap){
memlhide(t, x);
t->layer->clear = 0;
}
}
l->screenr = newr;
l->delta = subpt(scr, i->r.min);
l->clear = rectinrect(newr, l->screen->image->clipr);
/*
* Everything's covered. Copy to new position and delete shadow window.
*/
if(wasclear)
memdraw(s->image, newr, s->image, oldr.min, nil, Pt(0,0), S);
else
memlexpose(i, newr);
memldelete(shad);
return 1;
}
void
memlnorefresh(Memimage *l, Rectangle r, void *v)
{
USED(l);
USED(r.min.x);
USED(v);
}

View file

@ -0,0 +1,35 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
int
memlsetrefresh(Memimage *i, Refreshfn fn, void *ptr)
{
Memlayer *l;
l = i->layer;
if(l->refreshfn!=nil && fn!=nil){ /* just change functions */
l->refreshfn = fn;
l->refreshptr = ptr;
return 1;
}
if(l->refreshfn == nil){ /* is using backup image; just free it */
freememimage(l->save);
l->save = nil;
l->refreshfn = fn;
l->refreshptr = ptr;
return 1;
}
l->save = allocmemimage(i->r, i->chan);
if(l->save == nil)
return 0;
/* easiest way is just to update the entire save area */
l->refreshfn(i, i->r, l->refreshptr);
l->refreshfn = nil;
l->refreshptr = nil;
return 1;
}

81
sys/src/libmemlayer/ltofront.c Executable file
View file

@ -0,0 +1,81 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
#include <pool.h>
/*
* Pull i towards top of screen, just behind front
*/
static
void
_memltofront(Memimage *i, Memimage *front, int fill)
{
Memlayer *l;
Memscreen *s;
Memimage *f, *ff, *rr;
Rectangle x;
int overlap;
l = i->layer;
s = l->screen;
while(l->front != front){
f = l->front;
x = l->screenr;
overlap = rectclip(&x, f->layer->screenr);
if(overlap){
memlhide(f, x);
f->layer->clear = 0;
}
/* swap l and f in screen's list */
ff = f->layer->front;
rr = l->rear;
if(ff == nil)
s->frontmost = i;
else
ff->layer->rear = i;
if(rr == nil)
s->rearmost = f;
else
rr->layer->front = f;
l->front = ff;
l->rear = f;
f->layer->front = i;
f->layer->rear = rr;
if(overlap && fill)
memlexpose(i, x);
}
}
void
_memltofrontfill(Memimage *i, int fill)
{
_memltofront(i, nil, fill);
_memlsetclear(i->layer->screen);
}
void
memltofront(Memimage *i)
{
_memltofront(i, nil, 1);
_memlsetclear(i->layer->screen);
}
void
memltofrontn(Memimage **ip, int n)
{
Memimage *i, *front;
Memscreen *s;
if(n == 0)
return;
front = nil;
while(--n >= 0){
i = *ip++;
_memltofront(i, front, 1);
front = i;
}
s = front->layer->screen;
_memlsetclear(s);
}

69
sys/src/libmemlayer/ltorear.c Executable file
View file

@ -0,0 +1,69 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
void
_memltorear(Memimage *i, Memimage *rear)
{
Memlayer *l;
Memscreen *s;
Memimage *f, *r, *rr;
Rectangle x;
int overlap;
l = i->layer;
s = l->screen;
while(l->rear != rear){
r = l->rear;
x = l->screenr;
overlap = rectclip(&x, r->layer->screenr);
if(overlap){
memlhide(i, x);
l->clear = 0;
}
/* swap l and r in screen's list */
rr = r->layer->rear;
f = l->front;
if(rr == nil)
s->rearmost = i;
else
rr->layer->front = i;
if(f == nil)
s->frontmost = r;
else
f->layer->rear = r;
l->rear = rr;
l->front = r;
r->layer->rear = i;
r->layer->front = f;
if(overlap)
memlexpose(r, x);
}
}
void
memltorear(Memimage *i)
{
_memltorear(i, nil);
_memlsetclear(i->layer->screen);
}
void
memltorearn(Memimage **ip, int n)
{
Memimage *i, *rear;
Memscreen *s;
if(n == 0)
return;
rear = nil;
while(--n >= 0){
i = *ip++;
_memltorear(i, rear);
rear = i;
}
s = rear->layer->screen;
_memlsetclear(s);
}

38
sys/src/libmemlayer/makefile Executable file
View file

@ -0,0 +1,38 @@
!include ..\mkconfig.nmk
!include ..\$(SYSHOST)\mkhost
!include ..\$(OBJDIR)\makefile
CC_LOCAL=
dotodir=.
LIB=libmemlayer.$A
OFILES_C=\
$(dotodir)\draw.$O\
$(dotodir)\lalloc-$(SYSTARG).$O\
$(dotodir)\layerop.$O\
$(dotodir)\ldelete.$O\
$(dotodir)\lhide.$O\
$(dotodir)\line.$O\
$(dotodir)\load.$O\
$(dotodir)\lorigin.$O\
$(dotodir)\lsetrefresh.$O\
$(dotodir)\ltofront.$O\
$(dotodir)\ltorear.$O
HFILES=\
..\include\image.h\
..\include\memimage.h\
..\include\memlayer.h
!include ..\$(SYSTARG)\mksyslib.nmk
$(dotodir)\draw.$O: draw.c
$(dotodir)\lalloc.$O: lalloc.c
$(dotodir)\layerop.$O: layerop.c
$(dotodir)\ldelete.$O: ldelete.c
$(dotodir)\lhide.$O: lhide.c
$(dotodir)\line.$O: line.c
$(dotodir)\lsetrefresh.$O: lsetrefresh.c
$(dotodir)\ltofront.$O: ltofront.c
$(dotodir)\ltorear.$O: ltorear.c

29
sys/src/libmemlayer/mkfile Executable file
View file

@ -0,0 +1,29 @@
</$objtype/mkfile
LIB=/$objtype/lib/libmemlayer.a
OFILES=\
draw.$O\
lalloc.$O\
layerop.$O\
ldelete.$O\
lhide.$O\
line.$O\
load.$O\
lorigin.$O\
lsetrefresh.$O\
ltofront.$O\
ltorear.$O\
unload.$O\
HFILES=\
/sys/include/memlayer.h\
/sys/include/memdraw.h\
/sys/include/draw.h
UPDATE=\
mkfile\
$HFILES\
${OFILES:%.$O=%.c}\
</sys/src/cmd/mksyslib

View file

@ -0,0 +1,4 @@
#
# System dependent objects for Inferno model systems
#
SYSFILES=lalloc.$O

4
sys/src/libmemlayer/mkfile-Nt Executable file
View file

@ -0,0 +1,4 @@
#
# System dependent objects for Nt model systems
#
SYSFILES=lalloc.$O

View file

@ -0,0 +1,4 @@
#
# System dependent objects for Posix model systems
#
SYSFILES=lalloc-x11.$O

52
sys/src/libmemlayer/unload.c Executable file
View file

@ -0,0 +1,52 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <memlayer.h>
int
memunload(Memimage *src, Rectangle r, uchar *data, int n)
{
Memimage *tmp;
Memlayer *dl;
Rectangle lr;
int dx;
Top:
dl = src->layer;
if(dl == nil)
return unloadmemimage(src, r, data, n);
/*
* Convert to screen coordinates.
*/
lr = r;
r.min.x += dl->delta.x;
r.min.y += dl->delta.y;
r.max.x += dl->delta.x;
r.max.y += dl->delta.y;
dx = dl->delta.x&(7/src->depth);
if(dl->clear && dx==0){
src = dl->screen->image;
goto Top;
}
/*
* src is an obscured layer or data is unaligned
*/
if(dl->save && dx==0){
if(dl->refreshfn != nil)
return -1; /* can't unload window if it's not Refbackup */
if(n > 0)
memlhide(src, r);
n = unloadmemimage(dl->save, lr, data, n);
return n;
}
tmp = allocmemimage(lr, src->chan);
if(tmp == nil)
return -1;
memdraw(tmp, lr, src, lr.min, nil, lr.min, S);
n = unloadmemimage(tmp, lr, data, n);
freememimage(tmp);
return n;
}