1*37da2899SCharles.Forsyth #include <lib9.h>
2*37da2899SCharles.Forsyth #include <kernel.h>
3*37da2899SCharles.Forsyth #include "draw.h"
4*37da2899SCharles.Forsyth #include "tk.h"
5*37da2899SCharles.Forsyth #include "frame.h"
6*37da2899SCharles.Forsyth
7*37da2899SCharles.Forsyth char*
tkframe(TkTop * t,char * arg,char ** ret)8*37da2899SCharles.Forsyth tkframe(TkTop *t, char *arg, char **ret)
9*37da2899SCharles.Forsyth {
10*37da2899SCharles.Forsyth Tk *tk;
11*37da2899SCharles.Forsyth char *e;
12*37da2899SCharles.Forsyth TkOptab tko[2];
13*37da2899SCharles.Forsyth TkName *names;
14*37da2899SCharles.Forsyth
15*37da2899SCharles.Forsyth tk = tknewobj(t, TKframe, sizeof(Tk));
16*37da2899SCharles.Forsyth if(tk == nil)
17*37da2899SCharles.Forsyth return TkNomem;
18*37da2899SCharles.Forsyth
19*37da2899SCharles.Forsyth tko[0].ptr = tk;
20*37da2899SCharles.Forsyth tko[0].optab = tkgeneric;
21*37da2899SCharles.Forsyth tko[1].ptr = nil;
22*37da2899SCharles.Forsyth names = nil;
23*37da2899SCharles.Forsyth
24*37da2899SCharles.Forsyth e = tkparse(t, arg, tko, &names);
25*37da2899SCharles.Forsyth if(e != nil) {
26*37da2899SCharles.Forsyth tkfreeobj(tk);
27*37da2899SCharles.Forsyth return e;
28*37da2899SCharles.Forsyth }
29*37da2899SCharles.Forsyth tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd));
30*37da2899SCharles.Forsyth
31*37da2899SCharles.Forsyth e = tkaddchild(t, tk, &names);
32*37da2899SCharles.Forsyth
33*37da2899SCharles.Forsyth tkfreename(names);
34*37da2899SCharles.Forsyth if(e != nil) {
35*37da2899SCharles.Forsyth tkfreeobj(tk);
36*37da2899SCharles.Forsyth return e;
37*37da2899SCharles.Forsyth }
38*37da2899SCharles.Forsyth tk->name->link = nil;
39*37da2899SCharles.Forsyth
40*37da2899SCharles.Forsyth return tkvalue(ret, "%s", tk->name->name);
41*37da2899SCharles.Forsyth }
42*37da2899SCharles.Forsyth
43*37da2899SCharles.Forsyth /*
44*37da2899SCharles.Forsyth * Also used for windows, menus, separators
45*37da2899SCharles.Forsyth */
46*37da2899SCharles.Forsyth void
tkfreeframe(Tk * tk)47*37da2899SCharles.Forsyth tkfreeframe(Tk *tk)
48*37da2899SCharles.Forsyth {
49*37da2899SCharles.Forsyth TkWin *tkw;
50*37da2899SCharles.Forsyth
51*37da2899SCharles.Forsyth if((tk->flag & Tkwindow) == 0)
52*37da2899SCharles.Forsyth return;
53*37da2899SCharles.Forsyth
54*37da2899SCharles.Forsyth if(tk->type == TKmenu) {
55*37da2899SCharles.Forsyth tkw = TKobj(TkWin, tk);
56*37da2899SCharles.Forsyth free(tkw->postcmd);
57*37da2899SCharles.Forsyth free(tkw->cascade);
58*37da2899SCharles.Forsyth free(tkw->cbname);
59*37da2899SCharles.Forsyth }
60*37da2899SCharles.Forsyth
61*37da2899SCharles.Forsyth tkunmap(tk); /* XXX do this only if (tk->flag&Tkswept)==0 ?? */
62*37da2899SCharles.Forsyth }
63*37da2899SCharles.Forsyth
64*37da2899SCharles.Forsyth char*
tkdrawframe(Tk * tk,Point orig)65*37da2899SCharles.Forsyth tkdrawframe(Tk *tk, Point orig)
66*37da2899SCharles.Forsyth {
67*37da2899SCharles.Forsyth int bw;
68*37da2899SCharles.Forsyth Point p;
69*37da2899SCharles.Forsyth Image *i;
70*37da2899SCharles.Forsyth Tk *f;
71*37da2899SCharles.Forsyth Rectangle r, slaver; /* dribbling, whipping or just square? */
72*37da2899SCharles.Forsyth
73*37da2899SCharles.Forsyth i = tkimageof(tk);
74*37da2899SCharles.Forsyth if(i == nil)
75*37da2899SCharles.Forsyth return nil;
76*37da2899SCharles.Forsyth
77*37da2899SCharles.Forsyth p.x = orig.x + tk->act.x + tk->borderwidth;
78*37da2899SCharles.Forsyth p.y = orig.y + tk->act.y + tk->borderwidth;
79*37da2899SCharles.Forsyth
80*37da2899SCharles.Forsyth draw(i, rectaddpt(tk->dirty, p), tkgc(tk->env, TkCbackgnd), nil, ZP);
81*37da2899SCharles.Forsyth
82*37da2899SCharles.Forsyth /*
83*37da2899SCharles.Forsyth * doesn't matter about drawing TKseparator
84*37da2899SCharles.Forsyth * oblivious of dirty rect, as it never has any children to sully anyway
85*37da2899SCharles.Forsyth */
86*37da2899SCharles.Forsyth if(tk->type == TKseparator) {
87*37da2899SCharles.Forsyth r = rectaddpt(tkrect(tk, 1), p);
88*37da2899SCharles.Forsyth r.min.x += 4;
89*37da2899SCharles.Forsyth r.max.x -= 4;
90*37da2899SCharles.Forsyth r.min.y += (Dy(r) - 2)/2;
91*37da2899SCharles.Forsyth r.max.y = r.min.y+1;
92*37da2899SCharles.Forsyth draw(i, r, tkgc(tk->env, TkCbackgnddark), nil, ZP);
93*37da2899SCharles.Forsyth r.min.y += 1;
94*37da2899SCharles.Forsyth r.max.y += 1;
95*37da2899SCharles.Forsyth draw(i, r, tkgc(tk->env, TkCbackgndlght), nil, ZP);
96*37da2899SCharles.Forsyth return nil;
97*37da2899SCharles.Forsyth }
98*37da2899SCharles.Forsyth
99*37da2899SCharles.Forsyth /*
100*37da2899SCharles.Forsyth * make sure all the slaves inside the area we've just drawn
101*37da2899SCharles.Forsyth * refresh themselves properly.
102*37da2899SCharles.Forsyth */
103*37da2899SCharles.Forsyth for(f = tk->slave; f; f = f->next) {
104*37da2899SCharles.Forsyth bw = f->borderwidth;
105*37da2899SCharles.Forsyth slaver.min.x = f->act.x;
106*37da2899SCharles.Forsyth slaver.min.y = f->act.y;
107*37da2899SCharles.Forsyth slaver.max.x = slaver.min.x + f->act.width + 2*bw;
108*37da2899SCharles.Forsyth slaver.max.y = slaver.min.y + f->act.height + 2*bw;
109*37da2899SCharles.Forsyth if (rectclip(&slaver, tk->dirty)) {
110*37da2899SCharles.Forsyth f->flag |= Tkrefresh;
111*37da2899SCharles.Forsyth slaver = rectsubpt(slaver, Pt(f->act.x + bw, f->act.y + bw));
112*37da2899SCharles.Forsyth combinerect(&f->dirty, slaver);
113*37da2899SCharles.Forsyth }
114*37da2899SCharles.Forsyth }
115*37da2899SCharles.Forsyth p.x -= tk->borderwidth;
116*37da2899SCharles.Forsyth p.y -= tk->borderwidth;
117*37da2899SCharles.Forsyth
118*37da2899SCharles.Forsyth if (!rectinrect(tk->dirty, tkrect(tk, 0)))
119*37da2899SCharles.Forsyth tkdrawrelief(i, tk, p, TkCbackgnd, tk->relief);
120*37da2899SCharles.Forsyth return nil;
121*37da2899SCharles.Forsyth }
122*37da2899SCharles.Forsyth
123*37da2899SCharles.Forsyth /* Frame commands */
124*37da2899SCharles.Forsyth
125*37da2899SCharles.Forsyth static char*
tkframecget(Tk * tk,char * arg,char ** val)126*37da2899SCharles.Forsyth tkframecget(Tk *tk, char *arg, char **val)
127*37da2899SCharles.Forsyth {
128*37da2899SCharles.Forsyth TkOptab tko[3];
129*37da2899SCharles.Forsyth
130*37da2899SCharles.Forsyth tko[0].ptr = tk;
131*37da2899SCharles.Forsyth tko[0].optab = tkgeneric;
132*37da2899SCharles.Forsyth tko[1].ptr = nil;
133*37da2899SCharles.Forsyth if(tk->flag & Tkwindow){
134*37da2899SCharles.Forsyth tko[1].ptr = TKobj(TkWin, tk);
135*37da2899SCharles.Forsyth tko[1].optab = tktop;
136*37da2899SCharles.Forsyth tko[2].ptr = nil;
137*37da2899SCharles.Forsyth }
138*37da2899SCharles.Forsyth
139*37da2899SCharles.Forsyth return tkgencget(tko, arg, val, tk->env->top);
140*37da2899SCharles.Forsyth }
141*37da2899SCharles.Forsyth
142*37da2899SCharles.Forsyth static char*
tkframeconf(Tk * tk,char * arg,char ** val)143*37da2899SCharles.Forsyth tkframeconf(Tk *tk, char *arg, char **val)
144*37da2899SCharles.Forsyth {
145*37da2899SCharles.Forsyth char *e;
146*37da2899SCharles.Forsyth TkGeom g;
147*37da2899SCharles.Forsyth int bd;
148*37da2899SCharles.Forsyth Point oldp;
149*37da2899SCharles.Forsyth TkOptab tko[3];
150*37da2899SCharles.Forsyth TkWin *tkw;
151*37da2899SCharles.Forsyth
152*37da2899SCharles.Forsyth tko[0].ptr = tk;
153*37da2899SCharles.Forsyth tko[0].optab = tkgeneric;
154*37da2899SCharles.Forsyth tko[1].ptr = nil;
155*37da2899SCharles.Forsyth tkw = nil;
156*37da2899SCharles.Forsyth if(tk->flag & Tkwindow) {
157*37da2899SCharles.Forsyth tkw = TKobj(TkWin, tk);
158*37da2899SCharles.Forsyth tko[1].ptr = tkw;
159*37da2899SCharles.Forsyth tko[1].optab = tktop;
160*37da2899SCharles.Forsyth tko[2].ptr = nil;
161*37da2899SCharles.Forsyth oldp = tkw->act;
162*37da2899SCharles.Forsyth }
163*37da2899SCharles.Forsyth
164*37da2899SCharles.Forsyth if(*arg == '\0')
165*37da2899SCharles.Forsyth return tkconflist(tko, val);
166*37da2899SCharles.Forsyth
167*37da2899SCharles.Forsyth if(tkw != nil){
168*37da2899SCharles.Forsyth /*
169*37da2899SCharles.Forsyth * see whether only -x or -y is being configured,
170*37da2899SCharles.Forsyth * in which case just move the window; don't redraw
171*37da2899SCharles.Forsyth * everything
172*37da2899SCharles.Forsyth */
173*37da2899SCharles.Forsyth e = tkparse(tk->env->top, arg, &tko[1], nil);
174*37da2899SCharles.Forsyth if(e == nil){
175*37da2899SCharles.Forsyth if(!eqpt(oldp, tkw->req))
176*37da2899SCharles.Forsyth tkmovewin(tk, tkw->req);
177*37da2899SCharles.Forsyth return nil;
178*37da2899SCharles.Forsyth }
179*37da2899SCharles.Forsyth }
180*37da2899SCharles.Forsyth
181*37da2899SCharles.Forsyth g = tk->req;
182*37da2899SCharles.Forsyth bd = tk->borderwidth;
183*37da2899SCharles.Forsyth e = tkparse(tk->env->top, arg, tko, nil);
184*37da2899SCharles.Forsyth tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd));
185*37da2899SCharles.Forsyth tk->req.x = tk->act.x;
186*37da2899SCharles.Forsyth tk->req.y = tk->act.y;
187*37da2899SCharles.Forsyth tkgeomchg(tk, &g, bd);
188*37da2899SCharles.Forsyth if(tkw != nil && !eqpt(oldp, tkw->act))
189*37da2899SCharles.Forsyth tkmovewin(tk, tkw->req);
190*37da2899SCharles.Forsyth
191*37da2899SCharles.Forsyth tk->dirty = tkrect(tk, 1);
192*37da2899SCharles.Forsyth
193*37da2899SCharles.Forsyth return e;
194*37da2899SCharles.Forsyth }
195*37da2899SCharles.Forsyth
196*37da2899SCharles.Forsyth static char*
tkframesuspend(Tk * tk,char * arg,char ** val)197*37da2899SCharles.Forsyth tkframesuspend(Tk *tk, char *arg, char **val)
198*37da2899SCharles.Forsyth {
199*37da2899SCharles.Forsyth USED(arg);
200*37da2899SCharles.Forsyth USED(val);
201*37da2899SCharles.Forsyth if((tk->flag & Tkwindow) == 0)
202*37da2899SCharles.Forsyth return TkNotwm;
203*37da2899SCharles.Forsyth tk->flag |= Tksuspended;
204*37da2899SCharles.Forsyth return nil;
205*37da2899SCharles.Forsyth }
206*37da2899SCharles.Forsyth
207*37da2899SCharles.Forsyth static char*
tkframemap(Tk * tk,char * arg,char ** val)208*37da2899SCharles.Forsyth tkframemap(Tk *tk, char *arg, char **val)
209*37da2899SCharles.Forsyth {
210*37da2899SCharles.Forsyth USED(arg);
211*37da2899SCharles.Forsyth USED(val);
212*37da2899SCharles.Forsyth if(tk->flag & Tkwindow)
213*37da2899SCharles.Forsyth return tkmap(tk);
214*37da2899SCharles.Forsyth return TkNotwm;
215*37da2899SCharles.Forsyth }
216*37da2899SCharles.Forsyth
217*37da2899SCharles.Forsyth static char*
tkframeunmap(Tk * tk,char * arg,char ** val)218*37da2899SCharles.Forsyth tkframeunmap(Tk *tk, char *arg, char **val)
219*37da2899SCharles.Forsyth {
220*37da2899SCharles.Forsyth USED(arg);
221*37da2899SCharles.Forsyth USED(val);
222*37da2899SCharles.Forsyth if(tk->flag & Tkwindow) {
223*37da2899SCharles.Forsyth tkunmap(tk);
224*37da2899SCharles.Forsyth return nil;
225*37da2899SCharles.Forsyth }
226*37da2899SCharles.Forsyth return TkNotwm;
227*37da2899SCharles.Forsyth }
228*37da2899SCharles.Forsyth
229*37da2899SCharles.Forsyth static void
tkframefocusorder(Tk * tk)230*37da2899SCharles.Forsyth tkframefocusorder(Tk *tk)
231*37da2899SCharles.Forsyth {
232*37da2899SCharles.Forsyth int i, n;
233*37da2899SCharles.Forsyth Tk *sub;
234*37da2899SCharles.Forsyth TkWinfo *inf;
235*37da2899SCharles.Forsyth
236*37da2899SCharles.Forsyth n = 0;
237*37da2899SCharles.Forsyth for (sub = tk->slave; sub != nil; sub = sub->next)
238*37da2899SCharles.Forsyth n++;
239*37da2899SCharles.Forsyth
240*37da2899SCharles.Forsyth if (n == 0)
241*37da2899SCharles.Forsyth return;
242*37da2899SCharles.Forsyth
243*37da2899SCharles.Forsyth inf = malloc(sizeof(*inf) * n);
244*37da2899SCharles.Forsyth if (inf == nil)
245*37da2899SCharles.Forsyth return;
246*37da2899SCharles.Forsyth i = 0;
247*37da2899SCharles.Forsyth for (sub = tk->slave; sub != nil; sub = sub->next) {
248*37da2899SCharles.Forsyth inf[i].w = sub;
249*37da2899SCharles.Forsyth inf[i].r = rectaddpt(tkrect(sub, 1), Pt(sub->act.x, sub->act.y));
250*37da2899SCharles.Forsyth i++;
251*37da2899SCharles.Forsyth }
252*37da2899SCharles.Forsyth tksortfocusorder(inf, n);
253*37da2899SCharles.Forsyth for (i = 0; i < n; i++)
254*37da2899SCharles.Forsyth tkappendfocusorder(inf[i].w);
255*37da2899SCharles.Forsyth free(inf);
256*37da2899SCharles.Forsyth }
257*37da2899SCharles.Forsyth
258*37da2899SCharles.Forsyth static
259*37da2899SCharles.Forsyth TkCmdtab tkframecmd[] =
260*37da2899SCharles.Forsyth {
261*37da2899SCharles.Forsyth "cget", tkframecget,
262*37da2899SCharles.Forsyth "configure", tkframeconf,
263*37da2899SCharles.Forsyth "map", tkframemap,
264*37da2899SCharles.Forsyth "unmap", tkframeunmap,
265*37da2899SCharles.Forsyth "suspend", tkframesuspend,
266*37da2899SCharles.Forsyth nil
267*37da2899SCharles.Forsyth };
268*37da2899SCharles.Forsyth
269*37da2899SCharles.Forsyth TkMethod framemethod = {
270*37da2899SCharles.Forsyth "frame",
271*37da2899SCharles.Forsyth tkframecmd,
272*37da2899SCharles.Forsyth tkfreeframe,
273*37da2899SCharles.Forsyth tkdrawframe,
274*37da2899SCharles.Forsyth nil,
275*37da2899SCharles.Forsyth nil,
276*37da2899SCharles.Forsyth tkframefocusorder
277*37da2899SCharles.Forsyth };
278