]>
Dogcows Code - chaz/openbox/blob - otk_c/gccache.c
1 // -*- mode: C; indent-tabs-mode: nil; -*-
5 #include "screeninfo.h"
11 static OtkGCCache
*gccache
;
13 OtkGCCacheContext
*OtkGCCacheContext_New()
15 OtkGCCacheContext
*self
= malloc(sizeof(OtkGCCacheContext
));
29 void OtkGCCacheContext_Destroy(OtkGCCacheContext
*self
)
32 XFreeGC(OBDisplay
->display
, self
->gc
);
36 void OtkGCCacheContext_Set(OtkGCCacheContext
*self
,
37 OtkColor
*color
, XFontStruct
*font
,
38 int function
, int subwindow
, int linewidth
)
43 self
->pixel
= gcv
.foreground
= OtkColor_Pixel(color
);
44 self
->function
= gcv
.function
= function
;
45 self
->subwindow
= gcv
.subwindow_mode
= subwindow
;
46 self
->linewidth
= gcv
.line_width
= linewidth
;
47 gcv
.cap_style
= CapProjecting
;
49 mask
= GCForeground
| GCFunction
| GCSubwindowMode
| GCLineWidth
|
53 self
->fontid
= gcv
.font
= font
->fid
;
59 XChangeGC(OBDisplay
->display
, self
->gc
, mask
, &gcv
);
62 void OtkGCCacheContext_SetFont(OtkGCCacheContext
*self
,
71 self
->fontid
= gcv
.font
= font
->fid
;
72 XChangeGC(OBDisplay
->display
, self
->gc
, GCFont
, &gcv
);
76 OtkGCCacheItem
*OtkGCCacheItem_New()
78 OtkGCCacheItem
*self
= malloc(sizeof(OtkGCCacheItem
));
87 void OtkGCCache_Initialize(int screen_count
)
91 gccache
= malloc(sizeof(OtkGCCache
));
93 gccache
->context_count
= 128;
94 gccache
->cache_size
= 16;
95 gccache
->cache_buckets
= 8 * screen_count
;
96 gccache
->cache_total_size
= gccache
->cache_size
* gccache
->cache_buckets
;
98 gccache
->contexts
= malloc(sizeof(OtkGCCacheContext
*) *
99 gccache
->context_count
);
100 for (i
= 0; i
< gccache
->context_count
; ++i
)
101 gccache
->contexts
[i
] = OtkGCCacheContext_New();
103 gccache
->cache
= malloc(sizeof(OtkGCCacheItem
*) * gccache
->cache_total_size
);
104 for (i
= 0; i
< gccache
->cache_total_size
; ++i
)
105 gccache
->cache
[i
] = OtkGCCacheItem_New();
109 void OtkGCCache_Destroy()
113 for (i
= 0; i
< gccache
->context_count
; ++i
)
114 OtkGCCacheContext_Destroy(gccache
->contexts
[i
]);
116 for (i
= 0; i
< gccache
->cache_total_size
; ++i
)
117 free(gccache
->cache
[i
]);
119 free(gccache
->contexts
);
120 free(gccache
->cache
);
125 OtkGCCacheContext
*OtkGCCache_NextContext(int screen
)
127 Window hd
= OtkDisplay_ScreenInfo(OBDisplay
, screen
)->root_window
;
128 OtkGCCacheContext
*c
;
131 for (i
= 0; i
< gccache
->context_count
; ++i
) {
132 c
= gccache
->contexts
[i
];
135 c
->gc
= XCreateGC(OBDisplay
->display
, hd
, 0, 0);
139 if (! c
->used
&& c
->screen
== screen
)
143 fprintf(stderr
, "OtkGCCache: context fault!\n");
145 return NULL
; // shut gcc up
149 static void OtkGCCache_InternalRelease(OtkGCCacheContext
*ctx
)
154 OtkGCCacheItem
*OtkGCCache_Find(OtkColor
*color
, XFontStruct
*font
,
155 int function
, int subwindow
, int linewidth
)
157 const unsigned long pixel
= OtkColor_Pixel(color
);
158 const unsigned int screen
= color
->screen
;
159 const int key
= color
->red
^ color
->green
^ color
->blue
;
160 int k
= (key
% gccache
->cache_size
) * gccache
->cache_buckets
;
161 int i
= 0; // loop variable
162 OtkGCCacheItem
*c
= gccache
->cache
[k
], *prev
= 0;
165 this will either loop cache_buckets times then return/abort or
166 it will stop matching
169 (c
->ctx
->pixel
!= pixel
|| c
->ctx
->function
!= function
||
170 c
->ctx
->subwindow
!= subwindow
|| c
->ctx
->screen
!= screen
||
171 c
->ctx
->linewidth
!= linewidth
)) {
172 if (i
< (gccache
->cache_buckets
- 1)) {
174 c
= gccache
->cache
[++k
];
178 if (c
->count
== 0 && c
->ctx
->screen
== screen
) {
179 // use this cache item
180 OtkGCCacheContext_Set(c
->ctx
, color
, font
, function
, subwindow
,
188 fprintf(stderr
, "OtkGCCache: cache fault, count: %d, screen: %d, item screen: %d\n", c
->count
, screen
, c
->ctx
->screen
);
193 // reuse existing context
194 if (font
&& font
->fid
&& font
->fid
!= c
->ctx
->fontid
)
195 OtkGCCacheContext_SetFont(c
->ctx
, font
);
198 if (prev
&& c
->hits
> prev
->hits
) {
199 gccache
->cache
[k
] = prev
;
200 gccache
->cache
[k
-1] = c
;
203 c
->ctx
= OtkGCCache_NextContext(screen
);
204 OtkGCCacheContext_Set(c
->ctx
, color
, font
, function
, subwindow
, linewidth
);
214 void OtkGCCache_Release(OtkGCCacheItem
*item
)
220 void OtkGCCache_Purge()
224 for (i
= 0; i
< gccache
->cache_total_size
; ++i
) {
225 OtkGCCacheItem
*d
= gccache
->cache
[i
];
227 if (d
->ctx
&& d
->count
== 0) {
This page took 0.048648 seconds and 5 git commands to generate.