123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- #include <lib9.h>
- #include <draw.h>
- #include <interp.h>
- #include <isa.h>
- #include "../libinterp/runt.h"
- #include <drawif.h>
- #include <prefab.h>
- #include <kernel.h>
- List*
- prefabwrap(void *elem)
- {
- List *l;
- Heap *h, *e;
- e = D2H(elem);
- h = nheap(sizeof(List) + sizeof(WORD*));
- h->t = &Tlist;
- Tlist.ref++;
- l = H2D(List*, h);
- l->tail = H;
- l->t = &Tptr;
- Tptr.ref++;
- e->ref++;
- *(WORD**)l->data = elem;
- return l;
- }
- static
- PElement*
- elistelement1(Prefab_Environ *e, Prefab_Element *elem, Prefab_Element *new, enum Elementtype kind)
- {
- int first;
- PElement *pelem;
- List *atom;
- if(badenviron(e, 0))
- return H;
- gchalt++;
- first = 0;
- if(new == H)
- atom = H;
- else
- atom = prefabwrap(new);
- if(elem == H){
- pelem = mkelement(e, kind);
- elem = &pelem->e;
- pelem->first = H;
- pelem->nkids = 0;
- }else
- pelem = (PElement*)elem;
- if(atom == H)
- goto Return;
- if(elem->kids != pelem->first)
- error("list Element has been modified externally");
- if(elem->kids == H){
- elem->kids = atom;
- pelem->first = atom;
- pelem->last = atom;
- pelem->vfirst = atom;
- pelem->vlast = atom;
- first = 1;
- }
- if(new->kind!=ESeparator && Dx(elem->r)==0){
- elem->r = new->r;
- pelem->drawpt.x = elem->r.min.x;
- pelem->drawpt.y = elem->r.min.y;
- }
- pelem->nkids++;
- if(first)
- goto Return;
- pelem->last->tail = atom;
- pelem->last = atom;
- pelem->vlast = atom;
- if(new->kind != ESeparator){
- if(kind == EVertical){
- elem->r.max.y += Dy(new->r);
- if(elem->r.min.x > new->r.min.x)
- elem->r.min.x = new->r.min.x;
- if(elem->r.max.x < new->r.max.x)
- elem->r.max.x = new->r.max.x;
- }else{
- elem->r.max.x += Dx(new->r);
- if(elem->r.min.y > new->r.min.y)
- elem->r.min.y = new->r.min.y;
- if(elem->r.max.y < new->r.max.y)
- elem->r.max.y = new->r.max.y;
- }
- }
- pelem->pkind = kind;
- Return:
- gchalt--;
- return pelem;
- }
- PElement*
- elistelement(Prefab_Environ *e, Prefab_Element *new, enum Elementtype kind)
- {
- return elistelement1(e, H, new, kind);
- }
- PElement*
- appendelist(Prefab_Element *elem, Prefab_Element *new)
- {
- if(elem->kind!=EVertical && elem->kind!=EHorizontal){
- kwerrstr("appendelist to non-list");
- return H;
- }
- return elistelement1(elem->environ, elem, new, elem->kind);
- }
|