123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- #include <thread.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <control.h>
- typedef struct Cache Cache;
- struct Cache
- {
- char *name;
- CCache **cache;
- int ncache;
- };
- static struct Cache imagecache = {"image"};
- static struct Cache fontcache = {"font"};
- static CCache*
- getcacheitem(Cache *c, char *name)
- {
- int i;
- for(i=0; i<c->ncache; i++)
- if(c->cache[i]!=nil && strcmp(c->cache[i]->name, name)==0){
- c->cache[i]->ref++;
- return c->cache[i];
- }
- return nil;
- }
- static int
- namecacheitem(Cache *c, void *image, char *name)
- {
- int i, free;
- CCache *cc;
- free = -1;
- for(i=0; i<c->ncache; i++){
- if(c->cache[i] == nil){
- free = i;
- continue;
- }
- if(strcmp(c->cache[i]->name, name) == 0){
- werrstr("%s name %q already in use", c->name, name);
- return -1;
- }
- }
- cc = ctlmalloc(sizeof(CCache));
- cc->image = image;
- cc->name = ctlstrdup(name);
- if(free >= 0){
- cc->index = free;
- c->cache[free] = cc;
- }else{
- cc->index = c->ncache;
- c->cache = ctlrealloc(c->cache, (c->ncache+1)*sizeof(CCache*));
- c->cache[c->ncache++] = cc;
- }
- cc->ref = 1;
- return 1;
- }
- static int
- freecacheitem(Cache *c, char *name)
- {
- CCache *cc;
- cc = getcacheitem(c, name);
- if(cc == nil){
- werrstr("%s name %q not in use", c->name, name);
- return -1;
- }
- cc->ref--; /* getcacheitem increments ref */
- if(cc->ref-- == 1){
- /* client must free object itself */
- free(cc->name);
- c->cache[cc->index] = nil;
- free(cc);
- }
- return 0;
- }
- static void
- putcacheitem(CCache *cc)
- {
- if(cc == nil)
- return;
- cc->ref--;
- }
- static void
- setcacheitemptr(Cache *c, Control *ctl, CCache **cp, char *s)
- {
- CCache *ci;
- ci = getcacheitem(c, s);
- if(ci == nil)
- ctlerror("%q: %s name %q not defined", ctl->name, c->name, s);
- putcacheitem(*cp);
- *cp = ci;
- }
- /* Images */
- CImage*
- _getctlimage(char *name)
- {
- return getcacheitem(&imagecache, name);
- }
- void
- _putctlimage(CImage *c)
- {
- putcacheitem(c);
- }
- int
- namectlimage(Image *image, char *name)
- {
- return namecacheitem(&imagecache, image, name);
- }
- int
- freectlimage(char *name)
- {
- return freecacheitem(&imagecache, name);
- }
- void
- _setctlimage(Control *c, CImage **cp, char *s)
- {
- setcacheitemptr(&imagecache, c, cp, s);
- }
- /* Fonts */
- CFont*
- _getctlfont(char *name)
- {
- return getcacheitem(&fontcache, name);
- }
- void
- _putctlfont(CFont *c)
- {
- putcacheitem(c);
- }
- int
- namectlfont(Font *font, char *name)
- {
- return namecacheitem(&fontcache, font, name);
- }
- int
- freectlfont(char *name)
- {
- return freecacheitem(&fontcache, name);
- }
- void
- _setctlfont(Control *c, CFont **cp, char *s)
- {
- setcacheitemptr(&fontcache, c, cp, s);
- }
|