]>
Dogcows Code - chaz/openbox/blob - otk/gccache.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
4 # include "../config.h"
5 #endif // HAVE_CONFIG_H
15 #include "assassin.hh"
16 #include "screeninfo.hh"
20 GCCacheContext::~GCCacheContext(void) {
22 XFreeGC(Display::display
, gc
);
26 void GCCacheContext::set(const Color
&_color
,
27 const XFontStruct
* const _font
,
28 const int _function
, const int _subwindow
,
31 pixel
= gcv
.foreground
= _color
.pixel();
32 function
= gcv
.function
= _function
;
33 subwindow
= gcv
.subwindow_mode
= _subwindow
;
34 linewidth
= gcv
.line_width
= _linewidth
;
35 gcv
.cap_style
= CapProjecting
;
37 unsigned long mask
= GCForeground
| GCFunction
| GCSubwindowMode
|
38 GCLineWidth
| GCCapStyle
;
41 fontid
= gcv
.font
= _font
->fid
;
47 XChangeGC(Display::display
, gc
, mask
, &gcv
);
51 void GCCacheContext::set(const XFontStruct
* const _font
) {
58 fontid
= gcv
.font
= _font
->fid
;
59 XChangeGC(Display::display
, gc
, GCFont
, &gcv
);
63 GCCache::GCCache(unsigned int screen_count
)
64 : context_count(128u), cache_size(16u), cache_buckets(8u * screen_count
),
65 cache_total_size(cache_size
* cache_buckets
) {
67 contexts
= new GCCacheContext
*[context_count
];
69 for (i
= 0; i
< context_count
; i
++) {
70 contexts
[i
] = new GCCacheContext();
73 cache
= new GCCacheItem
*[cache_total_size
];
74 for (i
= 0; i
< cache_total_size
; ++i
) {
75 cache
[i
] = new GCCacheItem
;
80 GCCache::~GCCache(void) {
81 std::for_each(contexts
, contexts
+ context_count
, PointerAssassin());
82 std::for_each(cache
, cache
+ cache_total_size
, PointerAssassin());
88 GCCacheContext
*GCCache::nextContext(unsigned int scr
) {
89 Window hd
= Display::screenInfo(scr
)->rootWindow();
93 for (unsigned int i
= 0; i
< context_count
; ++i
) {
97 c
->gc
= XCreateGC(Display::display
, hd
, 0, 0);
101 if (! c
->used
&& c
->screen
== scr
)
105 fprintf(stderr
, "GCCache: context fault!\n");
107 return (GCCacheContext
*) 0; // not reached
111 void GCCache::release(GCCacheContext
*ctx
) {
116 GCCacheItem
*GCCache::find(const Color
&_color
,
117 const XFontStruct
* const _font
,
118 int _function
, int _subwindow
, int _linewidth
) {
119 const unsigned long pixel
= _color
.pixel();
120 const unsigned int screen
= _color
.screen();
121 const int key
= _color
.red() ^ _color
.green() ^ _color
.blue();
122 int k
= (key
% cache_size
) * cache_buckets
;
123 unsigned int i
= 0; // loop variable
124 GCCacheItem
*c
= cache
[ k
], *prev
= 0;
127 this will either loop cache_buckets times then return/abort or
128 it will stop matching
131 (c
->ctx
->pixel
!= pixel
|| c
->ctx
->function
!= _function
||
132 c
->ctx
->subwindow
!= _subwindow
|| c
->ctx
->screen
!= screen
||
133 c
->ctx
->linewidth
!= _linewidth
)) {
134 if (i
< (cache_buckets
- 1)) {
140 if (c
->count
== 0 && c
->ctx
->screen
== screen
) {
141 // use this cache item
142 c
->ctx
->set(_color
, _font
, _function
, _subwindow
, _linewidth
);
149 fprintf(stderr
, "GCCache: cache fault, count: %d, screen: %d, item screen: %d\n", c
->count
, screen
, c
->ctx
->screen
);
154 // reuse existing context
155 if (_font
&& _font
->fid
&& _font
->fid
!= c
->ctx
->fontid
)
159 if (prev
&& c
->hits
> prev
->hits
) {
164 c
->ctx
= nextContext(screen
);
165 c
->ctx
->set(_color
, _font
, _function
, _subwindow
, _linewidth
);
175 void GCCache::release(GCCacheItem
*_item
) {
180 void GCCache::purge(void) {
181 for (unsigned int i
= 0; i
< cache_total_size
; ++i
) {
182 GCCacheItem
*d
= cache
[ i
];
184 if (d
->ctx
&& d
->count
== 0) {
This page took 0.040477 seconds and 4 git commands to generate.