1*80ee5cbfSDavid du Colombier #include <u.h>
2*80ee5cbfSDavid du Colombier #include <libc.h>
3*80ee5cbfSDavid du Colombier #include <draw.h>
4*80ee5cbfSDavid du Colombier #include <thread.h>
5*80ee5cbfSDavid du Colombier #include <mouse.h>
6*80ee5cbfSDavid du Colombier #include <keyboard.h>
7*80ee5cbfSDavid du Colombier #include <control.h>
8*80ee5cbfSDavid du Colombier
9*80ee5cbfSDavid du Colombier typedef struct Cache Cache;
10*80ee5cbfSDavid du Colombier
11*80ee5cbfSDavid du Colombier struct Cache
12*80ee5cbfSDavid du Colombier {
13*80ee5cbfSDavid du Colombier char *name;
14*80ee5cbfSDavid du Colombier CCache **cache;
15*80ee5cbfSDavid du Colombier int ncache;
16*80ee5cbfSDavid du Colombier };
17*80ee5cbfSDavid du Colombier
18*80ee5cbfSDavid du Colombier static struct Cache imagecache = {"image"};
19*80ee5cbfSDavid du Colombier static struct Cache fontcache = {"font"};
20*80ee5cbfSDavid du Colombier
21*80ee5cbfSDavid du Colombier static CCache*
getcacheitem(Cache * c,char * name)22*80ee5cbfSDavid du Colombier getcacheitem(Cache *c, char *name)
23*80ee5cbfSDavid du Colombier {
24*80ee5cbfSDavid du Colombier int i;
25*80ee5cbfSDavid du Colombier
26*80ee5cbfSDavid du Colombier for(i=0; i<c->ncache; i++)
27*80ee5cbfSDavid du Colombier if(c->cache[i]!=nil && strcmp(c->cache[i]->name, name)==0){
28*80ee5cbfSDavid du Colombier c->cache[i]->ref++;
29*80ee5cbfSDavid du Colombier return c->cache[i];
30*80ee5cbfSDavid du Colombier }
31*80ee5cbfSDavid du Colombier return nil;
32*80ee5cbfSDavid du Colombier }
33*80ee5cbfSDavid du Colombier
34*80ee5cbfSDavid du Colombier static int
namecacheitem(Cache * c,void * image,char * name)35*80ee5cbfSDavid du Colombier namecacheitem(Cache *c, void *image, char *name)
36*80ee5cbfSDavid du Colombier {
37*80ee5cbfSDavid du Colombier int i, free;
38*80ee5cbfSDavid du Colombier CCache *cc;
39*80ee5cbfSDavid du Colombier
40*80ee5cbfSDavid du Colombier free = -1;
41*80ee5cbfSDavid du Colombier for(i=0; i<c->ncache; i++){
42*80ee5cbfSDavid du Colombier if(c->cache[i] == nil){
43*80ee5cbfSDavid du Colombier free = i;
44*80ee5cbfSDavid du Colombier continue;
45*80ee5cbfSDavid du Colombier }
46*80ee5cbfSDavid du Colombier if(strcmp(c->cache[i]->name, name) == 0){
47*80ee5cbfSDavid du Colombier werrstr("%s name %q already in use", c->name, name);
48*80ee5cbfSDavid du Colombier return -1;
49*80ee5cbfSDavid du Colombier }
50*80ee5cbfSDavid du Colombier }
51*80ee5cbfSDavid du Colombier cc = ctlmalloc(sizeof(CCache));
52*80ee5cbfSDavid du Colombier cc->image = image;
53*80ee5cbfSDavid du Colombier cc->name = ctlstrdup(name);
54*80ee5cbfSDavid du Colombier if(free >= 0){
55*80ee5cbfSDavid du Colombier cc->index = free;
56*80ee5cbfSDavid du Colombier c->cache[free] = cc;
57*80ee5cbfSDavid du Colombier }else{
58*80ee5cbfSDavid du Colombier cc->index = c->ncache;
59*80ee5cbfSDavid du Colombier c->cache = ctlrealloc(c->cache, (c->ncache+1)*sizeof(CCache*));
60*80ee5cbfSDavid du Colombier c->cache[c->ncache++] = cc;
61*80ee5cbfSDavid du Colombier }
62*80ee5cbfSDavid du Colombier cc->ref = 1;
63*80ee5cbfSDavid du Colombier return 1;
64*80ee5cbfSDavid du Colombier }
65*80ee5cbfSDavid du Colombier
66*80ee5cbfSDavid du Colombier static int
freecacheitem(Cache * c,char * name)67*80ee5cbfSDavid du Colombier freecacheitem(Cache *c, char *name)
68*80ee5cbfSDavid du Colombier {
69*80ee5cbfSDavid du Colombier CCache *cc;
70*80ee5cbfSDavid du Colombier
71*80ee5cbfSDavid du Colombier cc = getcacheitem(c, name);
72*80ee5cbfSDavid du Colombier if(cc == nil){
73*80ee5cbfSDavid du Colombier werrstr("%s name %q not in use", c->name, name);
74*80ee5cbfSDavid du Colombier return -1;
75*80ee5cbfSDavid du Colombier }
76*80ee5cbfSDavid du Colombier cc->ref--; /* getcacheitem increments ref */
77*80ee5cbfSDavid du Colombier if(cc->ref-- == 1){
78*80ee5cbfSDavid du Colombier /* client must free object itself */
79*80ee5cbfSDavid du Colombier free(cc->name);
80*80ee5cbfSDavid du Colombier c->cache[cc->index] = nil;
81*80ee5cbfSDavid du Colombier free(cc);
82*80ee5cbfSDavid du Colombier }
83*80ee5cbfSDavid du Colombier return 0;
84*80ee5cbfSDavid du Colombier }
85*80ee5cbfSDavid du Colombier
86*80ee5cbfSDavid du Colombier static void
putcacheitem(CCache * cc)87*80ee5cbfSDavid du Colombier putcacheitem(CCache *cc)
88*80ee5cbfSDavid du Colombier {
89*80ee5cbfSDavid du Colombier if(cc == nil)
90*80ee5cbfSDavid du Colombier return;
91*80ee5cbfSDavid du Colombier cc->ref--;
92*80ee5cbfSDavid du Colombier }
93*80ee5cbfSDavid du Colombier
94*80ee5cbfSDavid du Colombier static void
setcacheitemptr(Cache * c,Control * ctl,CCache ** cp,char * s)95*80ee5cbfSDavid du Colombier setcacheitemptr(Cache *c, Control *ctl, CCache **cp, char *s)
96*80ee5cbfSDavid du Colombier {
97*80ee5cbfSDavid du Colombier CCache *ci;
98*80ee5cbfSDavid du Colombier
99*80ee5cbfSDavid du Colombier ci = getcacheitem(c, s);
100*80ee5cbfSDavid du Colombier if(ci == nil)
101*80ee5cbfSDavid du Colombier ctlerror("%q: %s name %q not defined", ctl->name, c->name, s);
102*80ee5cbfSDavid du Colombier putcacheitem(*cp);
103*80ee5cbfSDavid du Colombier *cp = ci;
104*80ee5cbfSDavid du Colombier }
105*80ee5cbfSDavid du Colombier
106*80ee5cbfSDavid du Colombier /* Images */
107*80ee5cbfSDavid du Colombier
108*80ee5cbfSDavid du Colombier CImage*
_getctlimage(char * name)109*80ee5cbfSDavid du Colombier _getctlimage(char *name)
110*80ee5cbfSDavid du Colombier {
111*80ee5cbfSDavid du Colombier return getcacheitem(&imagecache, name);
112*80ee5cbfSDavid du Colombier }
113*80ee5cbfSDavid du Colombier
114*80ee5cbfSDavid du Colombier void
_putctlimage(CImage * c)115*80ee5cbfSDavid du Colombier _putctlimage(CImage *c)
116*80ee5cbfSDavid du Colombier {
117*80ee5cbfSDavid du Colombier putcacheitem(c);
118*80ee5cbfSDavid du Colombier }
119*80ee5cbfSDavid du Colombier
120*80ee5cbfSDavid du Colombier int
namectlimage(Image * image,char * name)121*80ee5cbfSDavid du Colombier namectlimage(Image *image, char *name)
122*80ee5cbfSDavid du Colombier {
123*80ee5cbfSDavid du Colombier return namecacheitem(&imagecache, image, name);
124*80ee5cbfSDavid du Colombier }
125*80ee5cbfSDavid du Colombier
126*80ee5cbfSDavid du Colombier int
freectlimage(char * name)127*80ee5cbfSDavid du Colombier freectlimage(char *name)
128*80ee5cbfSDavid du Colombier {
129*80ee5cbfSDavid du Colombier return freecacheitem(&imagecache, name);
130*80ee5cbfSDavid du Colombier }
131*80ee5cbfSDavid du Colombier
132*80ee5cbfSDavid du Colombier void
_setctlimage(Control * c,CImage ** cp,char * s)133*80ee5cbfSDavid du Colombier _setctlimage(Control *c, CImage **cp, char *s)
134*80ee5cbfSDavid du Colombier {
135*80ee5cbfSDavid du Colombier setcacheitemptr(&imagecache, c, cp, s);
136*80ee5cbfSDavid du Colombier }
137*80ee5cbfSDavid du Colombier
138*80ee5cbfSDavid du Colombier /* Fonts */
139*80ee5cbfSDavid du Colombier
140*80ee5cbfSDavid du Colombier CFont*
_getctlfont(char * name)141*80ee5cbfSDavid du Colombier _getctlfont(char *name)
142*80ee5cbfSDavid du Colombier {
143*80ee5cbfSDavid du Colombier return getcacheitem(&fontcache, name);
144*80ee5cbfSDavid du Colombier }
145*80ee5cbfSDavid du Colombier
146*80ee5cbfSDavid du Colombier void
_putctlfont(CFont * c)147*80ee5cbfSDavid du Colombier _putctlfont(CFont *c)
148*80ee5cbfSDavid du Colombier {
149*80ee5cbfSDavid du Colombier putcacheitem(c);
150*80ee5cbfSDavid du Colombier }
151*80ee5cbfSDavid du Colombier
152*80ee5cbfSDavid du Colombier int
namectlfont(Font * font,char * name)153*80ee5cbfSDavid du Colombier namectlfont(Font *font, char *name)
154*80ee5cbfSDavid du Colombier {
155*80ee5cbfSDavid du Colombier return namecacheitem(&fontcache, font, name);
156*80ee5cbfSDavid du Colombier }
157*80ee5cbfSDavid du Colombier
158*80ee5cbfSDavid du Colombier int
freectlfont(char * name)159*80ee5cbfSDavid du Colombier freectlfont(char *name)
160*80ee5cbfSDavid du Colombier {
161*80ee5cbfSDavid du Colombier return freecacheitem(&fontcache, name);
162*80ee5cbfSDavid du Colombier }
163*80ee5cbfSDavid du Colombier
164*80ee5cbfSDavid du Colombier void
_setctlfont(Control * c,CFont ** cp,char * s)165*80ee5cbfSDavid du Colombier _setctlfont(Control *c, CFont **cp, char *s)
166*80ee5cbfSDavid du Colombier {
167*80ee5cbfSDavid du Colombier setcacheitemptr(&fontcache, c, cp, s);
168*80ee5cbfSDavid du Colombier }
169