Import sources from 2011-03-30 iso image
This commit is contained in:
commit
e5888a1ffd
7810 changed files with 2489717 additions and 0 deletions
193
sys/src/libmemlayer/draw.c
Executable file
193
sys/src/libmemlayer/draw.c
Executable 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
79
sys/src/libmemlayer/lalloc.c
Executable 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
112
sys/src/libmemlayer/layerop.c
Executable 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
67
sys/src/libmemlayer/ldelete.c
Executable 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
68
sys/src/libmemlayer/lhide.c
Executable 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
122
sys/src/libmemlayer/line.c
Executable 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
55
sys/src/libmemlayer/load.c
Executable 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
107
sys/src/libmemlayer/lorigin.c
Executable 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);
|
||||
}
|
35
sys/src/libmemlayer/lsetrefresh.c
Executable file
35
sys/src/libmemlayer/lsetrefresh.c
Executable 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
81
sys/src/libmemlayer/ltofront.c
Executable 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
69
sys/src/libmemlayer/ltorear.c
Executable 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
38
sys/src/libmemlayer/makefile
Executable 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
29
sys/src/libmemlayer/mkfile
Executable 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
|
4
sys/src/libmemlayer/mkfile-Inferno
Executable file
4
sys/src/libmemlayer/mkfile-Inferno
Executable file
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# System dependent objects for Inferno model systems
|
||||
#
|
||||
SYSFILES=lalloc.$O
|
4
sys/src/libmemlayer/mkfile-Nt
Executable file
4
sys/src/libmemlayer/mkfile-Nt
Executable file
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# System dependent objects for Nt model systems
|
||||
#
|
||||
SYSFILES=lalloc.$O
|
4
sys/src/libmemlayer/mkfile-Posix
Executable file
4
sys/src/libmemlayer/mkfile-Posix
Executable file
|
@ -0,0 +1,4 @@
|
|||
#
|
||||
# System dependent objects for Posix model systems
|
||||
#
|
||||
SYSFILES=lalloc-x11.$O
|
52
sys/src/libmemlayer/unload.c
Executable file
52
sys/src/libmemlayer/unload.c
Executable 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;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue