1*37da2899SCharles.Forsyth #include <lib9.h>
2*37da2899SCharles.Forsyth #include <draw.h>
3*37da2899SCharles.Forsyth #include <interp.h>
4*37da2899SCharles.Forsyth #include <isa.h>
5*37da2899SCharles.Forsyth #include "../libinterp/runt.h"
6*37da2899SCharles.Forsyth #include <drawif.h>
7*37da2899SCharles.Forsyth #include <prefab.h>
8*37da2899SCharles.Forsyth #include <kernel.h>
9*37da2899SCharles.Forsyth
10*37da2899SCharles.Forsyth List*
prefabwrap(void * elem)11*37da2899SCharles.Forsyth prefabwrap(void *elem)
12*37da2899SCharles.Forsyth {
13*37da2899SCharles.Forsyth List *l;
14*37da2899SCharles.Forsyth Heap *h, *e;
15*37da2899SCharles.Forsyth
16*37da2899SCharles.Forsyth e = D2H(elem);
17*37da2899SCharles.Forsyth h = nheap(sizeof(List) + sizeof(WORD*));
18*37da2899SCharles.Forsyth h->t = &Tlist;
19*37da2899SCharles.Forsyth Tlist.ref++;
20*37da2899SCharles.Forsyth l = H2D(List*, h);
21*37da2899SCharles.Forsyth l->tail = H;
22*37da2899SCharles.Forsyth l->t = &Tptr;
23*37da2899SCharles.Forsyth Tptr.ref++;
24*37da2899SCharles.Forsyth e->ref++;
25*37da2899SCharles.Forsyth *(WORD**)l->data = elem;
26*37da2899SCharles.Forsyth return l;
27*37da2899SCharles.Forsyth }
28*37da2899SCharles.Forsyth
29*37da2899SCharles.Forsyth static
30*37da2899SCharles.Forsyth PElement*
elistelement1(Prefab_Environ * e,Prefab_Element * elem,Prefab_Element * new,enum Elementtype kind)31*37da2899SCharles.Forsyth elistelement1(Prefab_Environ *e, Prefab_Element *elem, Prefab_Element *new, enum Elementtype kind)
32*37da2899SCharles.Forsyth {
33*37da2899SCharles.Forsyth int first;
34*37da2899SCharles.Forsyth PElement *pelem;
35*37da2899SCharles.Forsyth List *atom;
36*37da2899SCharles.Forsyth
37*37da2899SCharles.Forsyth if(badenviron(e, 0))
38*37da2899SCharles.Forsyth return H;
39*37da2899SCharles.Forsyth
40*37da2899SCharles.Forsyth gchalt++;
41*37da2899SCharles.Forsyth first = 0;
42*37da2899SCharles.Forsyth if(new == H)
43*37da2899SCharles.Forsyth atom = H;
44*37da2899SCharles.Forsyth else
45*37da2899SCharles.Forsyth atom = prefabwrap(new);
46*37da2899SCharles.Forsyth if(elem == H){
47*37da2899SCharles.Forsyth pelem = mkelement(e, kind);
48*37da2899SCharles.Forsyth elem = &pelem->e;
49*37da2899SCharles.Forsyth pelem->first = H;
50*37da2899SCharles.Forsyth pelem->nkids = 0;
51*37da2899SCharles.Forsyth }else
52*37da2899SCharles.Forsyth pelem = (PElement*)elem;
53*37da2899SCharles.Forsyth if(atom == H)
54*37da2899SCharles.Forsyth goto Return;
55*37da2899SCharles.Forsyth
56*37da2899SCharles.Forsyth if(elem->kids != pelem->first)
57*37da2899SCharles.Forsyth error("list Element has been modified externally");
58*37da2899SCharles.Forsyth if(elem->kids == H){
59*37da2899SCharles.Forsyth elem->kids = atom;
60*37da2899SCharles.Forsyth pelem->first = atom;
61*37da2899SCharles.Forsyth pelem->last = atom;
62*37da2899SCharles.Forsyth pelem->vfirst = atom;
63*37da2899SCharles.Forsyth pelem->vlast = atom;
64*37da2899SCharles.Forsyth first = 1;
65*37da2899SCharles.Forsyth }
66*37da2899SCharles.Forsyth if(new->kind!=ESeparator && Dx(elem->r)==0){
67*37da2899SCharles.Forsyth elem->r = new->r;
68*37da2899SCharles.Forsyth pelem->drawpt.x = elem->r.min.x;
69*37da2899SCharles.Forsyth pelem->drawpt.y = elem->r.min.y;
70*37da2899SCharles.Forsyth }
71*37da2899SCharles.Forsyth pelem->nkids++;
72*37da2899SCharles.Forsyth if(first)
73*37da2899SCharles.Forsyth goto Return;
74*37da2899SCharles.Forsyth pelem->last->tail = atom;
75*37da2899SCharles.Forsyth pelem->last = atom;
76*37da2899SCharles.Forsyth pelem->vlast = atom;
77*37da2899SCharles.Forsyth if(new->kind != ESeparator){
78*37da2899SCharles.Forsyth if(kind == EVertical){
79*37da2899SCharles.Forsyth elem->r.max.y += Dy(new->r);
80*37da2899SCharles.Forsyth if(elem->r.min.x > new->r.min.x)
81*37da2899SCharles.Forsyth elem->r.min.x = new->r.min.x;
82*37da2899SCharles.Forsyth if(elem->r.max.x < new->r.max.x)
83*37da2899SCharles.Forsyth elem->r.max.x = new->r.max.x;
84*37da2899SCharles.Forsyth }else{
85*37da2899SCharles.Forsyth elem->r.max.x += Dx(new->r);
86*37da2899SCharles.Forsyth if(elem->r.min.y > new->r.min.y)
87*37da2899SCharles.Forsyth elem->r.min.y = new->r.min.y;
88*37da2899SCharles.Forsyth if(elem->r.max.y < new->r.max.y)
89*37da2899SCharles.Forsyth elem->r.max.y = new->r.max.y;
90*37da2899SCharles.Forsyth }
91*37da2899SCharles.Forsyth }
92*37da2899SCharles.Forsyth pelem->pkind = kind;
93*37da2899SCharles.Forsyth
94*37da2899SCharles.Forsyth Return:
95*37da2899SCharles.Forsyth gchalt--;
96*37da2899SCharles.Forsyth return pelem;
97*37da2899SCharles.Forsyth }
98*37da2899SCharles.Forsyth
99*37da2899SCharles.Forsyth PElement*
elistelement(Prefab_Environ * e,Prefab_Element * new,enum Elementtype kind)100*37da2899SCharles.Forsyth elistelement(Prefab_Environ *e, Prefab_Element *new, enum Elementtype kind)
101*37da2899SCharles.Forsyth {
102*37da2899SCharles.Forsyth return elistelement1(e, H, new, kind);
103*37da2899SCharles.Forsyth }
104*37da2899SCharles.Forsyth
105*37da2899SCharles.Forsyth PElement*
appendelist(Prefab_Element * elem,Prefab_Element * new)106*37da2899SCharles.Forsyth appendelist(Prefab_Element *elem, Prefab_Element *new)
107*37da2899SCharles.Forsyth {
108*37da2899SCharles.Forsyth if(elem->kind!=EVertical && elem->kind!=EHorizontal){
109*37da2899SCharles.Forsyth kwerrstr("appendelist to non-list");
110*37da2899SCharles.Forsyth return H;
111*37da2899SCharles.Forsyth }
112*37da2899SCharles.Forsyth return elistelement1(elem->environ, elem, new, elem->kind);
113*37da2899SCharles.Forsyth }
114