1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free
16 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 typedef struct _GtkGCKey GtkGCKey;
22 typedef struct _GtkGCDrawable GtkGCDrawable;
27 GdkColormap *colormap;
39 static void gtk_gc_init (void);
40 static GtkGCKey* gtk_gc_key_dup (GtkGCKey *key);
41 static void gtk_gc_key_destroy (GtkGCKey *key);
42 static gpointer gtk_gc_new (gpointer key);
43 static void gtk_gc_destroy (gpointer value);
44 static guint gtk_gc_key_hash (gpointer key);
45 static guint gtk_gc_value_hash (gpointer value);
46 static gint gtk_gc_key_compare (gpointer a,
48 static guint gtk_gc_drawable_hash (GtkGCDrawable *d);
49 static gint gtk_gc_drawable_compare (GtkGCDrawable *a,
53 static gint initialize = TRUE;
54 static GCache *gc_cache = NULL;
55 static GHashTable *gc_drawable_ht = NULL;
57 static GMemChunk *key_mem_chunk = NULL;
61 gtk_gc_get (gint depth,
62 GdkColormap *colormap,
64 GdkGCValuesMask values_mask)
73 key.colormap = colormap;
75 key.mask = values_mask;
77 gc = g_cache_insert (gc_cache, &key);
83 gtk_gc_release (GdkGC *gc)
88 g_cache_remove (gc_cache, gc);
97 gc_cache = g_cache_new ((GCacheNewFunc) gtk_gc_new,
98 (GCacheDestroyFunc) gtk_gc_destroy,
99 (GCacheDupFunc) gtk_gc_key_dup,
100 (GCacheDestroyFunc) gtk_gc_key_destroy,
101 (GHashFunc) gtk_gc_key_hash,
102 (GHashFunc) gtk_gc_value_hash,
103 (GCompareFunc) gtk_gc_key_compare);
105 gc_drawable_ht = g_hash_table_new ((GHashFunc) gtk_gc_drawable_hash,
106 (GCompareFunc) gtk_gc_drawable_compare);
110 gtk_gc_key_dup (GtkGCKey *key)
115 key_mem_chunk = g_mem_chunk_new ("key mem chunk", sizeof (GtkGCKey),
116 1024, G_ALLOC_AND_FREE);
118 new_key = g_chunk_new (GtkGCKey, key_mem_chunk);
126 gtk_gc_key_destroy (GtkGCKey *key)
128 g_mem_chunk_free (key_mem_chunk, key);
132 gtk_gc_new (gpointer key)
135 GtkGCDrawable *drawable;
140 drawable = g_hash_table_lookup (gc_drawable_ht, &keyval->depth);
143 drawable = g_new (GtkGCDrawable, 1);
144 drawable->depth = keyval->depth;
145 drawable->drawable = gdk_pixmap_new (NULL, 1, 1, drawable->depth);
147 g_hash_table_insert (gc_drawable_ht, &drawable->depth, drawable);
150 gc = gdk_gc_new_with_values (drawable->drawable, &keyval->values, keyval->mask);
152 return (gpointer) gc;
156 gtk_gc_destroy (gpointer value)
158 gdk_gc_destroy ((GdkGC*) value);
162 gtk_gc_key_hash (gpointer key)
170 if (keyval->mask & GDK_GC_FOREGROUND)
172 hash_val += keyval->values.foreground.pixel;
174 if (keyval->mask & GDK_GC_BACKGROUND)
176 hash_val += keyval->values.background.pixel;
178 if (keyval->mask & GDK_GC_FONT)
180 hash_val += gdk_font_id (keyval->values.font);
182 if (keyval->mask & GDK_GC_FUNCTION)
184 hash_val += (gint) keyval->values.function;
186 if (keyval->mask & GDK_GC_FILL)
188 hash_val += (gint) keyval->values.fill;
190 if (keyval->mask & GDK_GC_TILE)
192 hash_val += (glong) keyval->values.tile;
194 if (keyval->mask & GDK_GC_STIPPLE)
196 hash_val += (glong) keyval->values.stipple;
198 if (keyval->mask & GDK_GC_CLIP_MASK)
200 hash_val += (glong) keyval->values.clip_mask;
202 if (keyval->mask & GDK_GC_SUBWINDOW)
204 hash_val += (gint) keyval->values.subwindow_mode;
206 if (keyval->mask & GDK_GC_TS_X_ORIGIN)
208 hash_val += (gint) keyval->values.ts_x_origin;
210 if (keyval->mask & GDK_GC_TS_Y_ORIGIN)
212 hash_val += (gint) keyval->values.ts_y_origin;
214 if (keyval->mask & GDK_GC_CLIP_X_ORIGIN)
216 hash_val += (gint) keyval->values.clip_x_origin;
218 if (keyval->mask & GDK_GC_CLIP_Y_ORIGIN)
220 hash_val += (gint) keyval->values.clip_y_origin;
222 if (keyval->mask & GDK_GC_EXPOSURES)
224 hash_val += (gint) keyval->values.graphics_exposures;
226 if (keyval->mask & GDK_GC_LINE_WIDTH)
228 hash_val += (gint) keyval->values.line_width;
230 if (keyval->mask & GDK_GC_LINE_STYLE)
232 hash_val += (gint) keyval->values.line_style;
234 if (keyval->mask & GDK_GC_CAP_STYLE)
236 hash_val += (gint) keyval->values.cap_style;
238 if (keyval->mask & GDK_GC_JOIN_STYLE)
240 hash_val += (gint) keyval->values.join_style;
247 gtk_gc_value_hash (gpointer value)
249 return (gulong) value;
253 gtk_gc_key_compare (gpointer a,
258 GdkGCValues *avalues;
259 GdkGCValues *bvalues;
264 avalues = &akey->values;
265 bvalues = &bkey->values;
267 if (akey->mask != bkey->mask)
270 if (akey->depth != bkey->depth)
273 if (akey->colormap != bkey->colormap)
276 if (akey->mask & GDK_GC_FOREGROUND)
278 if (avalues->foreground.pixel != bvalues->foreground.pixel)
281 if (akey->mask & GDK_GC_BACKGROUND)
283 if (avalues->background.pixel != bvalues->background.pixel)
286 if (akey->mask & GDK_GC_FONT)
288 if (!gdk_font_equal (avalues->font, bvalues->font))
291 if (akey->mask & GDK_GC_FUNCTION)
293 if (avalues->function != bvalues->function)
296 if (akey->mask & GDK_GC_FILL)
298 if (avalues->fill != bvalues->fill)
301 if (akey->mask & GDK_GC_TILE)
303 if (avalues->tile != bvalues->tile)
306 if (akey->mask & GDK_GC_STIPPLE)
308 if (avalues->stipple != bvalues->stipple)
311 if (akey->mask & GDK_GC_CLIP_MASK)
313 if (avalues->clip_mask != bvalues->clip_mask)
316 if (akey->mask & GDK_GC_SUBWINDOW)
318 if (avalues->subwindow_mode != bvalues->subwindow_mode)
321 if (akey->mask & GDK_GC_TS_X_ORIGIN)
323 if (avalues->ts_x_origin != bvalues->ts_x_origin)
326 if (akey->mask & GDK_GC_TS_Y_ORIGIN)
328 if (avalues->ts_y_origin != bvalues->ts_y_origin)
331 if (akey->mask & GDK_GC_CLIP_X_ORIGIN)
333 if (avalues->clip_x_origin != bvalues->clip_x_origin)
336 if (akey->mask & GDK_GC_CLIP_Y_ORIGIN)
338 if (avalues->clip_y_origin != bvalues->clip_y_origin)
341 if (akey->mask & GDK_GC_EXPOSURES)
343 if (avalues->graphics_exposures != bvalues->graphics_exposures)
346 if (akey->mask & GDK_GC_LINE_WIDTH)
348 if (avalues->line_width != bvalues->line_width)
351 if (akey->mask & GDK_GC_LINE_STYLE)
353 if (avalues->line_style != bvalues->line_style)
356 if (akey->mask & GDK_GC_CAP_STYLE)
358 if (avalues->cap_style != bvalues->cap_style)
361 if (akey->mask & GDK_GC_JOIN_STYLE)
363 if (avalues->join_style != bvalues->join_style)
372 gtk_gc_drawable_hash (GtkGCDrawable *d)
378 gtk_gc_drawable_compare (GtkGCDrawable *a,
381 return (a->depth == b->depth);