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