]>
Dogcows Code - chaz/openbox/blob - otk_c/gccache.c
1 // -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "screeninfo.h"
11 static OtkGCCache
*gccache
= NULL
;
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
= color
->pixel
;
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
));
89 void OtkGCCache_Initialize()
93 gccache
= malloc(sizeof(OtkGCCache
));
95 gccache
->context_count
= 128;
96 gccache
->cache_size
= 16;
97 gccache
->cache_buckets
= 8 * ScreenCount(OBDisplay
->display
);
98 gccache
->cache_total_size
= gccache
->cache_size
* gccache
->cache_buckets
;
100 gccache
->contexts
= malloc(sizeof(OtkGCCacheContext
*) *
101 gccache
->context_count
);
102 for (i
= 0; i
< gccache
->context_count
; ++i
)
103 gccache
->contexts
[i
] = OtkGCCacheContext_New();
105 gccache
->cache
= malloc(sizeof(OtkGCCacheItem
*) * gccache
->cache_total_size
);
106 for (i
= 0; i
< gccache
->cache_total_size
; ++i
)
107 gccache
->cache
[i
] = OtkGCCacheItem_New();
111 /*void OtkGCCache_Destroy()
115 for (i = 0; i < gccache->context_count; ++i)
116 OtkGCCacheContext_Destroy(gccache->contexts[i]);
118 for (i = 0; i < gccache->cache_total_size; ++i)
119 free(gccache->cache[i]);
121 free(gccache->contexts);
122 free(gccache->cache);
127 static OtkGCCacheContext
*nextContext(int screen
)
129 Window hd
= OtkDisplay_ScreenInfo(OBDisplay
, screen
)->root_window
;
130 OtkGCCacheContext
*c
;
133 for (i
= 0; i
< gccache
->context_count
; ++i
) {
134 c
= gccache
->contexts
[i
];
137 c
->gc
= XCreateGC(OBDisplay
->display
, hd
, 0, 0);
141 if (! c
->used
&& c
->screen
== screen
)
145 fprintf(stderr
, "OtkGCCache: context fault!\n");
147 return NULL
; // shut gcc up
151 static void OtkGCCache_InternalRelease(OtkGCCacheContext
*ctx
)
156 OtkGCCacheItem
*OtkGCCache_Find(OtkColor
*color
, XFontStruct
*font
,
157 int function
, int subwindow
, int linewidth
)
159 const unsigned long pixel
= color
->pixel
;
160 const int screen
= color
->screen
;
161 const int key
= color
->red
^ color
->green
^ color
->blue
;
162 int k
= (key
% gccache
->cache_size
) * gccache
->cache_buckets
;
163 unsigned int i
= 0; // loop variable
164 OtkGCCacheItem
*c
= gccache
->cache
[k
], *prev
= 0;
167 this will either loop cache_buckets times then return/abort or
168 it will stop matching
171 (c
->ctx
->pixel
!= pixel
|| c
->ctx
->function
!= function
||
172 c
->ctx
->subwindow
!= subwindow
|| c
->ctx
->screen
!= screen
||
173 c
->ctx
->linewidth
!= linewidth
)) {
174 if (i
< (gccache
->cache_buckets
- 1)) {
176 c
= gccache
->cache
[++k
];
180 if (c
->count
== 0 && c
->ctx
->screen
== screen
) {
181 // use this cache item
182 OtkGCCacheContext_Set(c
->ctx
, color
, font
, function
, subwindow
,
190 fprintf(stderr
, "OtkGCCache: cache fault, count: %d, screen: %d, item screen: %d\n", c
->count
, screen
, c
->ctx
->screen
);
195 // reuse existing context
196 if (font
&& font
->fid
&& font
->fid
!= c
->ctx
->fontid
)
197 OtkGCCacheContext_SetFont(c
->ctx
, font
);
200 if (prev
&& c
->hits
> prev
->hits
) {
201 gccache
->cache
[k
] = prev
;
202 gccache
->cache
[k
-1] = c
;
205 c
->ctx
= nextContext(screen
);
206 OtkGCCacheContext_Set(c
->ctx
, color
, font
, function
, subwindow
, linewidth
);
216 void OtkGCCache_Release(OtkGCCacheItem
*item
)
222 void OtkGCCache_Purge()
226 for (i
= 0; i
< gccache
->cache_total_size
; ++i
) {
227 OtkGCCacheItem
*d
= gccache
->cache
[i
];
229 if (d
->ctx
&& d
->count
== 0) {
230 OtkGCCache_InternalRelease(d
->ctx
);
This page took 0.048483 seconds and 4 git commands to generate.