cache.c 3.0 KB

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