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
9*37da2899SCharles.Forsyth extern void queuerefresh(Image *i, Rectangle r, Reffn reffn, void *refptr);
10*37da2899SCharles.Forsyth
11*37da2899SCharles.Forsyth Draw_Rect
edgerect(Prefab_Environ * e,Draw_Point p,Draw_Rect * rin)12*37da2899SCharles.Forsyth edgerect(Prefab_Environ *e, Draw_Point p, Draw_Rect *rin)
13*37da2899SCharles.Forsyth {
14*37da2899SCharles.Forsyth Draw_Rect r;
15*37da2899SCharles.Forsyth Screen *s;
16*37da2899SCharles.Forsyth
17*37da2899SCharles.Forsyth r.min.x = p.x;
18*37da2899SCharles.Forsyth r.min.y = p.y;
19*37da2899SCharles.Forsyth r.max.x = p.x + 1 + Dx(*rin) + 1;
20*37da2899SCharles.Forsyth r.max.y = p.y + 1 + Dy(*rin) + 1;
21*37da2899SCharles.Forsyth /* outer box computed; now make sure it's all visible */
22*37da2899SCharles.Forsyth s = lookupscreen(e->screen);
23*37da2899SCharles.Forsyth if(s != nil)
24*37da2899SCharles.Forsyth fitrect((Rectangle*)&r, s->display->image->r);
25*37da2899SCharles.Forsyth
26*37da2899SCharles.Forsyth rin->min.x = r.min.x+1;
27*37da2899SCharles.Forsyth rin->min.y = r.min.y+1;
28*37da2899SCharles.Forsyth rin->max.x = r.max.x-1;
29*37da2899SCharles.Forsyth rin->max.y = r.max.y-1;
30*37da2899SCharles.Forsyth
31*37da2899SCharles.Forsyth return r;
32*37da2899SCharles.Forsyth }
33*37da2899SCharles.Forsyth
34*37da2899SCharles.Forsyth /*
35*37da2899SCharles.Forsyth * Draw edge around r.
36*37da2899SCharles.Forsyth * Assume geometry has already been clipped and adjusted.
37*37da2899SCharles.Forsyth */
38*37da2899SCharles.Forsyth void
edge(Prefab_Environ * e,Image * box,Draw_Rect dr,Draw_Rect dclipr)39*37da2899SCharles.Forsyth edge(Prefab_Environ *e, Image *box, Draw_Rect dr, Draw_Rect dclipr)
40*37da2899SCharles.Forsyth {
41*37da2899SCharles.Forsyth Rectangle r, r1, clipr;
42*37da2899SCharles.Forsyth Image *ec;
43*37da2899SCharles.Forsyth Screen *s;
44*37da2899SCharles.Forsyth
45*37da2899SCharles.Forsyth R2R(r, dr);
46*37da2899SCharles.Forsyth R2R(clipr, dclipr);
47*37da2899SCharles.Forsyth r.min.x -= 1;
48*37da2899SCharles.Forsyth r.min.y -= 1;
49*37da2899SCharles.Forsyth r.max.x += 1;
50*37da2899SCharles.Forsyth r.max.y += 1;
51*37da2899SCharles.Forsyth s = lookupscreen(e->screen);
52*37da2899SCharles.Forsyth if(s == nil)
53*37da2899SCharles.Forsyth return;
54*37da2899SCharles.Forsyth ec = lookupimage(e->style->edgecolor);
55*37da2899SCharles.Forsyth if(ec == nil)
56*37da2899SCharles.Forsyth return;
57*37da2899SCharles.Forsyth
58*37da2899SCharles.Forsyth r1 = r;
59*37da2899SCharles.Forsyth r1.min.y++;
60*37da2899SCharles.Forsyth r1.max.y = r1.min.y+2;
61*37da2899SCharles.Forsyth r1.max.x = r1.min.x+2*(r1.max.x-r1.min.x)/3;
62*37da2899SCharles.Forsyth if(rectclip(&r1, clipr))
63*37da2899SCharles.Forsyth draw(box, r1, ec, nil, r1.min);
64*37da2899SCharles.Forsyth r1 = r;
65*37da2899SCharles.Forsyth r1.min.x++;
66*37da2899SCharles.Forsyth r1.max.x = r1.min.x+2;
67*37da2899SCharles.Forsyth r1.max.y = r1.min.y+2*(r1.max.y-r1.min.y)/3;
68*37da2899SCharles.Forsyth if(rectclip(&r1, clipr))
69*37da2899SCharles.Forsyth draw(box, r1, ec, nil, r1.min);
70*37da2899SCharles.Forsyth r1=r;
71*37da2899SCharles.Forsyth r1.min.x = r1.max.x-1;
72*37da2899SCharles.Forsyth if(rectclip(&r1, clipr))
73*37da2899SCharles.Forsyth draw(box, r1, ec, nil, r1.min);
74*37da2899SCharles.Forsyth r1=r;
75*37da2899SCharles.Forsyth r1.min.y = r1.max.y-1;
76*37da2899SCharles.Forsyth if(rectclip(&r1, clipr))
77*37da2899SCharles.Forsyth draw(box, r1, ec, nil, r1.min);
78*37da2899SCharles.Forsyth r1 = r;
79*37da2899SCharles.Forsyth r1.max.y = r1.min.y+1;
80*37da2899SCharles.Forsyth if(rectclip(&r1, clipr))
81*37da2899SCharles.Forsyth draw(box, r1, ec, nil, r1.min);
82*37da2899SCharles.Forsyth r1=r;
83*37da2899SCharles.Forsyth r1.max.x = r1.min.x+1;
84*37da2899SCharles.Forsyth if(rectclip(&r1, clipr))
85*37da2899SCharles.Forsyth draw(box, r1, ec, nil, r1.min);
86*37da2899SCharles.Forsyth }
87*37da2899SCharles.Forsyth
88*37da2899SCharles.Forsyth void
redrawcompound(Image * i,Rectangle clipr,Prefab_Compound * c)89*37da2899SCharles.Forsyth redrawcompound(Image *i, Rectangle clipr, Prefab_Compound *c)
90*37da2899SCharles.Forsyth {
91*37da2899SCharles.Forsyth Rectangle r1, rt, r;
92*37da2899SCharles.Forsyth int l, len;
93*37da2899SCharles.Forsyth Prefab_Style *s;
94*37da2899SCharles.Forsyth Image *elemcolor, *edgecolor;
95*37da2899SCharles.Forsyth List *list;
96*37da2899SCharles.Forsyth Font *font;
97*37da2899SCharles.Forsyth Prefab_Element *e;
98*37da2899SCharles.Forsyth
99*37da2899SCharles.Forsyth if(c==H || badenviron(c->environ, 0))
100*37da2899SCharles.Forsyth return;
101*37da2899SCharles.Forsyth
102*37da2899SCharles.Forsyth r = clipr;
103*37da2899SCharles.Forsyth s = c->environ->style;
104*37da2899SCharles.Forsyth elemcolor = lookupimage(s->elemcolor);
105*37da2899SCharles.Forsyth edgecolor = lookupimage(s->edgecolor);
106*37da2899SCharles.Forsyth if(elemcolor==nil || edgecolor==nil)
107*37da2899SCharles.Forsyth return;
108*37da2899SCharles.Forsyth draw(i, r, elemcolor, nil, r.min);
109*37da2899SCharles.Forsyth if(lookupelement(c->title) != H){
110*37da2899SCharles.Forsyth R2R(rt, c->title->r);
111*37da2899SCharles.Forsyth if(c->title->environ!=H && c->title->environ->style!=H && rectXrect(r, rt)){
112*37da2899SCharles.Forsyth drawelement(c->title, i, r, c->environ==c->title->environ, 0);
113*37da2899SCharles.Forsyth r1.min.x = c->r.min.x;
114*37da2899SCharles.Forsyth r1.min.y = c->title->r.max.y;
115*37da2899SCharles.Forsyth s = c->title->environ->style;
116*37da2899SCharles.Forsyth len = 0;
117*37da2899SCharles.Forsyth switch(c->title->kind){
118*37da2899SCharles.Forsyth case ETitle:
119*37da2899SCharles.Forsyth font = lookupfont(s->titlefont);
120*37da2899SCharles.Forsyth if(font != nil)
121*37da2899SCharles.Forsyth len = 2+1+stringwidth(font, string2c(c->title->str));
122*37da2899SCharles.Forsyth break;
123*37da2899SCharles.Forsyth case EVertical:
124*37da2899SCharles.Forsyth font = lookupfont(s->titlefont);
125*37da2899SCharles.Forsyth if(font != nil)
126*37da2899SCharles.Forsyth for(list=c->title->kids; list!=H; list=list->tail){
127*37da2899SCharles.Forsyth e = *(Prefab_Element**)list->data;
128*37da2899SCharles.Forsyth l = stringwidth(font, string2c(e->str));
129*37da2899SCharles.Forsyth if(l > len)
130*37da2899SCharles.Forsyth len = l;
131*37da2899SCharles.Forsyth }
132*37da2899SCharles.Forsyth len += 2+1;
133*37da2899SCharles.Forsyth break;
134*37da2899SCharles.Forsyth default:
135*37da2899SCharles.Forsyth len = r1.min.x+2*Dx(c->r)/3;
136*37da2899SCharles.Forsyth }
137*37da2899SCharles.Forsyth r1.max.x = r1.min.x + len;
138*37da2899SCharles.Forsyth r1.max.y = r1.min.y+1;
139*37da2899SCharles.Forsyth draw(i, r1, edgecolor, nil, r.min);
140*37da2899SCharles.Forsyth r.min.y = r1.max.y;
141*37da2899SCharles.Forsyth }
142*37da2899SCharles.Forsyth }
143*37da2899SCharles.Forsyth if(c->contents!=H)
144*37da2899SCharles.Forsyth drawelement(c->contents, i, r, c->environ==c->contents->environ, 0);
145*37da2899SCharles.Forsyth edge(c->environ, i, c->r, DRECT(clipr));
146*37da2899SCharles.Forsyth }
147*37da2899SCharles.Forsyth
148*37da2899SCharles.Forsyth void
refreshcompound(Image * i,Rectangle r,void * ptr)149*37da2899SCharles.Forsyth refreshcompound(Image *i, Rectangle r, void *ptr)
150*37da2899SCharles.Forsyth {
151*37da2899SCharles.Forsyth Prefab_Compound *c;
152*37da2899SCharles.Forsyth
153*37da2899SCharles.Forsyth c = ptr;
154*37da2899SCharles.Forsyth if(c == nil)
155*37da2899SCharles.Forsyth return;
156*37da2899SCharles.Forsyth if(i == nil){ /* called from flushimage */
157*37da2899SCharles.Forsyth i = lookupimage(c->image);
158*37da2899SCharles.Forsyth if(i == nil)
159*37da2899SCharles.Forsyth return;
160*37da2899SCharles.Forsyth }
161*37da2899SCharles.Forsyth redrawcompound(i, r, c);
162*37da2899SCharles.Forsyth }
163*37da2899SCharles.Forsyth
164*37da2899SCharles.Forsyth void
localrefreshcompound(Memimage * mi,Rectangle r,void * ptr)165*37da2899SCharles.Forsyth localrefreshcompound(Memimage *mi, Rectangle r, void *ptr)
166*37da2899SCharles.Forsyth {
167*37da2899SCharles.Forsyth Prefab_Compound *c;
168*37da2899SCharles.Forsyth Image *i;
169*37da2899SCharles.Forsyth
170*37da2899SCharles.Forsyth USED(mi); /* can't do anything with this, but it's part of the memlayer interface */
171*37da2899SCharles.Forsyth c = ptr;
172*37da2899SCharles.Forsyth if(c == nil)
173*37da2899SCharles.Forsyth return;
174*37da2899SCharles.Forsyth i = lookupimage(c->image);
175*37da2899SCharles.Forsyth if(i == nil)
176*37da2899SCharles.Forsyth return;
177*37da2899SCharles.Forsyth queuerefresh(i, r, refreshcompound, ptr);
178*37da2899SCharles.Forsyth }
179*37da2899SCharles.Forsyth
180*37da2899SCharles.Forsyth void
drawcompound(Prefab_Compound * c)181*37da2899SCharles.Forsyth drawcompound(Prefab_Compound *c)
182*37da2899SCharles.Forsyth {
183*37da2899SCharles.Forsyth Image *i;
184*37da2899SCharles.Forsyth
185*37da2899SCharles.Forsyth if(c==H || c->image==H)
186*37da2899SCharles.Forsyth return;
187*37da2899SCharles.Forsyth i = lookupimage(c->image);
188*37da2899SCharles.Forsyth redrawcompound(i, insetrect(IRECT(c->r), -1), c);
189*37da2899SCharles.Forsyth if(i->display->local && i->refptr==nil)
190*37da2899SCharles.Forsyth if(drawlsetrefresh(i->display->dataqid, i->id, localrefreshcompound, c) <= 0)
191*37da2899SCharles.Forsyth fprint(2, "drawcompound: can't set refresh\n");
192*37da2899SCharles.Forsyth i->refptr = c; /* can now be refreshed */
193*37da2899SCharles.Forsyth }
194