123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- #include <lib9.h>
- #include <kernel.h>
- #include "draw.h"
- #include "tk.h"
- #include "frame.h"
- char*
- tkframe(TkTop *t, char *arg, char **ret)
- {
- Tk *tk;
- char *e;
- TkOptab tko[2];
- TkName *names;
- tk = tknewobj(t, TKframe, sizeof(Tk));
- if(tk == nil)
- return TkNomem;
- tko[0].ptr = tk;
- tko[0].optab = tkgeneric;
- tko[1].ptr = nil;
- names = nil;
- e = tkparse(t, arg, tko, &names);
- if(e != nil) {
- tkfreeobj(tk);
- return e;
- }
- tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd));
- e = tkaddchild(t, tk, &names);
- tkfreename(names);
- if(e != nil) {
- tkfreeobj(tk);
- return e;
- }
- tk->name->link = nil;
- return tkvalue(ret, "%s", tk->name->name);
- }
- /*
- * Also used for windows, menus, separators
- */
- void
- tkfreeframe(Tk *tk)
- {
- TkWin *tkw;
- if((tk->flag & Tkwindow) == 0)
- return;
- if(tk->type == TKmenu) {
- tkw = TKobj(TkWin, tk);
- free(tkw->postcmd);
- free(tkw->cascade);
- free(tkw->cbname);
- }
- tkunmap(tk); /* XXX do this only if (tk->flag&Tkswept)==0 ?? */
- }
- char*
- tkdrawframe(Tk *tk, Point orig)
- {
- int bw;
- Point p;
- Image *i;
- Tk *f;
- Rectangle r, slaver; /* dribbling, whipping or just square? */
- i = tkimageof(tk);
- if(i == nil)
- return nil;
-
- p.x = orig.x + tk->act.x + tk->borderwidth;
- p.y = orig.y + tk->act.y + tk->borderwidth;
- draw(i, rectaddpt(tk->dirty, p), tkgc(tk->env, TkCbackgnd), nil, ZP);
- /*
- * doesn't matter about drawing TKseparator
- * oblivious of dirty rect, as it never has any children to sully anyway
- */
- if(tk->type == TKseparator) {
- r = rectaddpt(tkrect(tk, 1), p);
- r.min.x += 4;
- r.max.x -= 4;
- r.min.y += (Dy(r) - 2)/2;
- r.max.y = r.min.y+1;
- draw(i, r, tkgc(tk->env, TkCbackgnddark), nil, ZP);
- r.min.y += 1;
- r.max.y += 1;
- draw(i, r, tkgc(tk->env, TkCbackgndlght), nil, ZP);
- return nil;
- }
- /*
- * make sure all the slaves inside the area we've just drawn
- * refresh themselves properly.
- */
- for(f = tk->slave; f; f = f->next) {
- bw = f->borderwidth;
- slaver.min.x = f->act.x;
- slaver.min.y = f->act.y;
- slaver.max.x = slaver.min.x + f->act.width + 2*bw;
- slaver.max.y = slaver.min.y + f->act.height + 2*bw;
- if (rectclip(&slaver, tk->dirty)) {
- f->flag |= Tkrefresh;
- slaver = rectsubpt(slaver, Pt(f->act.x + bw, f->act.y + bw));
- combinerect(&f->dirty, slaver);
- }
- }
- p.x -= tk->borderwidth;
- p.y -= tk->borderwidth;
- if (!rectinrect(tk->dirty, tkrect(tk, 0)))
- tkdrawrelief(i, tk, p, TkCbackgnd, tk->relief);
- return nil;
- }
- /* Frame commands */
- static char*
- tkframecget(Tk *tk, char *arg, char **val)
- {
- TkOptab tko[3];
- tko[0].ptr = tk;
- tko[0].optab = tkgeneric;
- tko[1].ptr = nil;
- if(tk->flag & Tkwindow){
- tko[1].ptr = TKobj(TkWin, tk);
- tko[1].optab = tktop;
- tko[2].ptr = nil;
- }
- return tkgencget(tko, arg, val, tk->env->top);
- }
- static char*
- tkframeconf(Tk *tk, char *arg, char **val)
- {
- char *e;
- TkGeom g;
- int bd;
- Point oldp;
- TkOptab tko[3];
- TkWin *tkw;
- tko[0].ptr = tk;
- tko[0].optab = tkgeneric;
- tko[1].ptr = nil;
- tkw = nil;
- if(tk->flag & Tkwindow) {
- tkw = TKobj(TkWin, tk);
- tko[1].ptr = tkw;
- tko[1].optab = tktop;
- tko[2].ptr = nil;
- oldp = tkw->act;
- }
- if(*arg == '\0')
- return tkconflist(tko, val);
- if(tkw != nil){
- /*
- * see whether only -x or -y is being configured,
- * in which case just move the window; don't redraw
- * everything
- */
- e = tkparse(tk->env->top, arg, &tko[1], nil);
- if(e == nil){
- if(!eqpt(oldp, tkw->req))
- tkmovewin(tk, tkw->req);
- return nil;
- }
- }
- g = tk->req;
- bd = tk->borderwidth;
- e = tkparse(tk->env->top, arg, tko, nil);
- tksettransparent(tk, tkhasalpha(tk->env, TkCbackgnd));
- tk->req.x = tk->act.x;
- tk->req.y = tk->act.y;
- tkgeomchg(tk, &g, bd);
- if(tkw != nil && !eqpt(oldp, tkw->act))
- tkmovewin(tk, tkw->req);
- tk->dirty = tkrect(tk, 1);
- return e;
- }
- static char*
- tkframesuspend(Tk *tk, char *arg, char **val)
- {
- USED(arg);
- USED(val);
- if((tk->flag & Tkwindow) == 0)
- return TkNotwm;
- tk->flag |= Tksuspended;
- return nil;
- }
- static char*
- tkframemap(Tk *tk, char *arg, char **val)
- {
- USED(arg);
- USED(val);
- if(tk->flag & Tkwindow)
- return tkmap(tk);
- return TkNotwm;
- }
- static char*
- tkframeunmap(Tk *tk, char *arg, char **val)
- {
- USED(arg);
- USED(val);
- if(tk->flag & Tkwindow) {
- tkunmap(tk);
- return nil;
- }
- return TkNotwm;
- }
- static void
- tkframefocusorder(Tk *tk)
- {
- int i, n;
- Tk *sub;
- TkWinfo *inf;
- n = 0;
- for (sub = tk->slave; sub != nil; sub = sub->next)
- n++;
- if (n == 0)
- return;
- inf = malloc(sizeof(*inf) * n);
- if (inf == nil)
- return;
- i = 0;
- for (sub = tk->slave; sub != nil; sub = sub->next) {
- inf[i].w = sub;
- inf[i].r = rectaddpt(tkrect(sub, 1), Pt(sub->act.x, sub->act.y));
- i++;
- }
- tksortfocusorder(inf, n);
- for (i = 0; i < n; i++)
- tkappendfocusorder(inf[i].w);
- free(inf);
- }
- static
- TkCmdtab tkframecmd[] =
- {
- "cget", tkframecget,
- "configure", tkframeconf,
- "map", tkframemap,
- "unmap", tkframeunmap,
- "suspend", tkframesuspend,
- nil
- };
- TkMethod framemethod = {
- "frame",
- tkframecmd,
- tkfreeframe,
- tkdrawframe,
- nil,
- nil,
- tkframefocusorder
- };
|