summaryrefslogtreecommitdiff
path: root/sys/src/libcontrol/cache.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/libcontrol/cache.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libcontrol/cache.c')
-rwxr-xr-xsys/src/libcontrol/cache.c168
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);
+}