/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #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 intnamecacheitem(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 intfreecacheitem(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 voidputcacheitem(CCache *cc){ if(cc == nil) return; cc->ref--;} static voidsetcacheitemptr(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);} intnamectlimage(Image *image, char *name){ return namecacheitem(&imagecache, image, name);} intfreectlimage(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);} intnamectlfont(Font *font, char *name){ return namecacheitem(&fontcache, font, name);} intfreectlfont(char *name){ return freecacheitem(&fontcache, name);} void_setctlfont(Control *c, CFont **cp, char *s){ setcacheitemptr(&fontcache, c, cp, s);}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
#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);
}