diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libcontrol/cache.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libcontrol/cache.c')
-rwxr-xr-x | sys/src/libcontrol/cache.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/sys/src/libcontrol/cache.c b/sys/src/libcontrol/cache.c new file mode 100755 index 000000000..ab38d3084 --- /dev/null +++ b/sys/src/libcontrol/cache.c @@ -0,0 +1,168 @@ +#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); +} |