annotate src/gccache-xlike-inc.c @ 2586:196ee3cd1ac5

[xemacs-hg @ 2005-02-15 01:19:48 by ben] first check-in of ben-fixup branch
author ben
date Tue, 15 Feb 2005 01:21:24 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2586
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
1 /* Efficient caching of GCs (graphics contexts) -- shared code, X and GTK.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
2 Copyright (C) 1993 Free Software Foundation, Inc.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
3 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
4 Copyright (C) 2003, 2005 Ben Wing.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
5
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
6 This file is part of XEmacs.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
7
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
8 XEmacs is free software; you can redistribute it and/or modify it
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
9 under the terms of the GNU General Public License as published by the
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
10 Free Software Foundation; either version 2, or (at your option) any
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
11 later version.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
12
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
16 for more details.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
17
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
19 along with XEmacs; see the file COPYING. If not, write to
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
21 Boston, MA 02111-1307, USA. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
22
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
23 /* Synched up with: Not in FSF. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
24
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
25 /* Emacs uses a lot of different display attributes; for example, assume
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
26 that only four fonts are in use (normal, bold, italic, and bold-italic).
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
27 Then assume that one stipple or background is used for text selections,
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
28 and another is used for highlighting mousable regions. That makes 16
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
29 GCs already. Add in the fact that another GC may be needed to display
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
30 the text cursor in any of those regions, and you've got 32. Add in
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
31 more fonts, and it keeps increasing exponentially.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
32
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
33 We used to keep these GCs in a cache of merged (fully qualified) faces.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
34 However, a lot of other code in xterm.c used XChangeGC of existing GCs,
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
35 which is kind of slow and kind of random. Also, managing the face cache
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
36 was tricky because it was hard to know when a face was no longer visible
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
37 on the frame -- we had to mark all frames as garbaged whenever a face
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
38 was changed, which caused an unpleasant amount of flicker (since faces are
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
39 created/destroyed (= changed) whenever a frame is created/destroyed.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
40
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
41 So this code maintains a cache at the GC level instead of at the face
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
42 level. There is an upper limit on the size of the cache, after which we
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
43 will stop creating GCs and start reusing them (reusing the least-recently-
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
44 used ones first). So if faces get changed, their GCs will eventually be
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
45 recycled. Also more sharing of GCs is possible.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
46
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
47 This code uses hash tables. It could be that, if the cache size is small
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
48 enough, a linear search might be faster; but I doubt it, since we need
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
49 `equal' comparisons, not `eq', and I expect that the optimal cache size
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
50 will be ~100.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
51
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
52 Written by jwz, 14 jun 93
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
53 Hacked by William Perry, apr 2000 for GTK and introduced code
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
54 duplication (a no-no)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
55 Undid code duplication, Ben Wing, Jan 28, 2003.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
56 */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
57
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
58 #include <config.h>
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
59 #include "lisp.h"
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
60 #include "hash.h"
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
61
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
62 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
63 #include <X11/Xlib.h>
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
64 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
65 #include <gtk/gtk.h>
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
66 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
67
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
68 #define GC_CACHE_SIZE 100
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
69
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
70 #define GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
71
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
72 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
73 #define ZZGCVALUES XGCValues
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
74 #define ZZGC GC
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
75 #define ZZ(z) x_##z
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
76 #else
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
77 #define ZZGCVALUES GdkGCValues
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
78 #define ZZGC GdkGC *
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
79 #define ZZ(z) gtk_##z
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
80 #endif
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
81
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
82 struct gcv_and_mask {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
83 ZZGCVALUES gcv;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
84 unsigned long mask;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
85 };
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
86
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
87 struct gc_cache_cell {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
88 ZZGC gc;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
89 struct gcv_and_mask gcvm;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
90 struct gc_cache_cell *prev, *next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
91 };
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
92
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
93 struct gc_cache {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
94 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
95 Display *dpy; /* used only as arg to XCreateGC/XFreeGC */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
96 Window window; /* used only as arg to XCreateGC */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
97 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
98 GdkWindow *window; /* used only as arg to XCreateGC */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
99 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
100 int size;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
101 struct gc_cache_cell *head;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
102 struct gc_cache_cell *tail;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
103 #ifdef GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
104 struct hash_table *table;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
105 #endif
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
106
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
107 int create_count;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
108 int delete_count;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
109 };
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
110
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
111 #ifdef GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
112 static Hashcode
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
113 gc_cache_hash (const void *arg)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
114 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
115 const struct gcv_and_mask *gcvm = (const struct gcv_and_mask *) arg;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
116 unsigned long *longs = (unsigned long *) &gcvm->gcv;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
117 Hashcode hash = gcvm->mask;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
118 int i;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
119 /* This could look at the mask and only use the used slots in the
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
120 hash code. That would win in that we wouldn't have to initialize
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
121 every slot of the gcv when calling gc_cache_lookup. But we need
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
122 the hash function to be as fast as possible; some timings should
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
123 be done. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
124 for (i = 0; i < (int) (sizeof (ZZGCVALUES) /
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
125 sizeof (unsigned long)); i++)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
126 hash = (hash << 1) ^ *longs++;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
127 return hash;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
128 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
129
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
130 #endif /* GCCACHE_HASH */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
131
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
132 static int
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
133 gc_cache_eql (const void *arg1, const void *arg2)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
134 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
135 /* See comment in gc_cache_hash */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
136 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
137 return !memcmp (arg1, arg2, sizeof (struct gcv_and_mask));
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
138 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
139 const struct gcv_and_mask *gcvm1 = (const struct gcv_and_mask *) arg1;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
140 const struct gcv_and_mask *gcvm2 = (const struct gcv_and_mask *) arg2;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
141
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
142 return !memcmp (&gcvm1->gcv, &gcvm2->gcv, sizeof (gcvm1->gcv))
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
143 && gcvm1->mask == gcvm2->mask;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
144 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
145 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
146
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
147 struct gc_cache *
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
148 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
149 ZZ (make_gc_cache) (Display *dpy, Window window)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
150 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
151 ZZ (make_gc_cache) (GtkWidget *widget)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
152 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
153 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
154 struct gc_cache *cache = xnew (struct gc_cache);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
155 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
156 cache->dpy = dpy;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
157 cache->window = window;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
158 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
159 cache->window = widget->window;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
160 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
161 cache->size = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
162 cache->head = cache->tail = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
163 cache->create_count = cache->delete_count = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
164 #ifdef GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
165 cache->table =
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
166 make_general_hash_table (GC_CACHE_SIZE, gc_cache_hash, gc_cache_eql);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
167 #endif
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
168 return cache;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
169 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
170
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
171 void
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
172 ZZ (free_gc_cache) (struct gc_cache *cache)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
173 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
174 struct gc_cache_cell *rest, *next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
175 rest = cache->head;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
176 while (rest)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
177 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
178 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
179 XFreeGC (cache->dpy, rest->gc);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
180 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
181 gdk_gc_destroy (rest->gc);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
182 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
183 next = rest->next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
184 xfree (rest, struct gc_cache_cell *);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
185 rest = next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
186 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
187 #ifdef GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
188 free_hash_table (cache->table);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
189 #endif
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
190 xfree (cache, struct gc_cache *);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
191 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
192
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
193 ZZGC
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
194 ZZ (gc_cache_lookup) (struct gc_cache *cache, ZZGCVALUES *gcv, unsigned long mask)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
195 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
196 struct gc_cache_cell *cell, *next, *prev;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
197 struct gcv_and_mask gcvm;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
198
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
199 if ((!!cache->head) != (!!cache->tail)) ABORT ();
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
200 if (cache->head && (cache->head->prev || cache->tail->next)) ABORT ();
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
201
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
202 #ifdef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
203 /* Gdk does not have the equivalent of 'None' for the clip_mask, so
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
204 we need to check it carefully, or gdk_gc_new_with_values will
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
205 coredump */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
206 if ((mask & GDK_GC_CLIP_MASK) && !gcv->clip_mask)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
207 mask = (GdkGCValuesMask) (mask & ~GDK_GC_CLIP_MASK);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
208 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
209
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
210 gcvm.mask = mask;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
211 gcvm.gcv = *gcv; /* this copies... */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
212
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
213 #ifdef GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
214
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
215 if (gethash (&gcvm, cache->table, (const void **) &cell))
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
216
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
217 #else /* !GCCACHE_HASH */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
218
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
219 cell = cache->tail; /* start at the end (most recently used) */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
220 while (cell)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
221 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
222 if (gc_cache_eql (&gcvm, &cell->gcvm))
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
223 break;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
224 else
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
225 cell = cell->prev;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
226 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
227
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
228 /* #### This whole file needs some serious overhauling. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
229 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
230 if (!(mask | GCTile) && cell->gc->values.tile)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
231 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
232 if (!(mask | GDK_GC_TILE) && cell->gcvm.gcv.tile)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
233 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
234 cell = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
235 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
236 else if (!(mask | GCStipple) && cell->gc->values.stipple)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
237 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
238 else if (!(mask | GDK_GC_STIPPLE) && cell->gcvm.gcv.stipple)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
239 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
240 cell = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
241
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
242 if (cell)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
243
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
244 #endif /* !GCCACHE_HASH */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
245
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
246 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
247 /* Found a cell. Move this cell to the end of the list, so that it
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
248 will be less likely to be collected than a cell that was accessed
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
249 less recently.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
250 */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
251 if (cell == cache->tail)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
252 return cell->gc;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
253
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
254 next = cell->next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
255 prev = cell->prev;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
256 if (prev) prev->next = next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
257 if (next) next->prev = prev;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
258 if (cache->head == cell) cache->head = next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
259 cell->next = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
260 cell->prev = cache->tail;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
261 cache->tail->next = cell;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
262 cache->tail = cell;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
263 if (cache->head == cell) ABORT ();
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
264 if (cell->next) ABORT ();
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
265 if (cache->head->prev) ABORT ();
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
266 if (cache->tail->next) ABORT ();
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
267 return cell->gc;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
268 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
269
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
270 /* else, cache miss. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
271
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
272 if (cache->size == GC_CACHE_SIZE)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
273 /* Reuse the first cell on the list (least-recently-used).
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
274 Remove it from the list, and unhash it from the table.
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
275 */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
276 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
277 cell = cache->head;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
278 cache->head = cell->next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
279 cache->head->prev = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
280 if (cache->tail == cell) cache->tail = 0; /* only one */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
281 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
282 XFreeGC (cache->dpy, cell->gc);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
283 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
284 gdk_gc_destroy (cell->gc);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
285 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
286 cache->delete_count++;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
287 #ifdef GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
288 remhash (&cell->gcvm, cache->table);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
289 #endif
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
290 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
291 else if (cache->size > GC_CACHE_SIZE)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
292 ABORT ();
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
293 else
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
294 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
295 /* Allocate a new cell (don't put it in the list or table yet). */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
296 cell = xnew (struct gc_cache_cell);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
297 cache->size++;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
298 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
299
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
300 /* Now we've got a cell (new or reused). Fill it in. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
301 memcpy (&cell->gcvm.gcv, gcv, sizeof (ZZGCVALUES));
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
302 cell->gcvm.mask = mask;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
303
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
304 /* Put the cell on the end of the list. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
305 cell->next = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
306 cell->prev = cache->tail;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
307 if (cache->tail) cache->tail->next = cell;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
308 cache->tail = cell;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
309 if (! cache->head) cache->head = cell;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
310
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
311 cache->create_count++;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
312 #ifdef GCCACHE_HASH
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
313 /* Hash it in the table */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
314 puthash (&cell->gcvm, cell, cache->table);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
315 #endif
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
316
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
317 /* Now make and return the GC. */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
318 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
319 cell->gc = XCreateGC (cache->dpy, cache->window, mask, gcv);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
320 #else /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
321 cell->gc = gdk_gc_new_with_values (cache->window, gcv, (GdkGCValuesMask) mask);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
322 #endif /* THIS_IS_GTK */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
323
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
324 /* debug */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
325 assert (cell->gc == ZZ (gc_cache_lookup) (cache, gcv, mask));
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
326
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
327 return cell->gc;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
328 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
329 #ifndef THIS_IS_GTK
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
330
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
331
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
332 #ifdef DEBUG_XEMACS
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
333
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
334 void x_describe_gc_cache (struct gc_cache *cache);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
335 void
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
336 x_describe_gc_cache (struct gc_cache *cache)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
337 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
338 int count = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
339 struct gc_cache_cell *cell = cache->head;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
340 stderr_out ("\nsize: %d", cache->size);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
341 stderr_out ("\ncreated: %d", cache->create_count);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
342 stderr_out ("\ndeleted: %d", cache->delete_count);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
343 while (cell)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
344 {
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
345 struct gc_cache_cell *cell2;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
346 int i = 0;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
347 stderr_out ("\n%d:\t0x%lx GC: 0x%08lx hash: 0x%08lx\n",
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
348 count, (long) cell, (long) cell->gc, gc_cache_hash (&cell->gcvm));
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
349 for (cell2 = cache->head; cell2; cell2 = cell2->next, i++)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
350 if (count != i &&
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
351 gc_cache_hash (&cell->gcvm) == gc_cache_hash (&cell2->gcvm))
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
352 stderr_out ("\tHASH COLLISION with cell %d\n", i);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
353 stderr_out ("\tmask: %8lx\n", cell->gcvm.mask);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
354
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
355 #define FROB(field) do { \
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
356 if ((int)cell->gcvm.gcv.field != (~0)) \
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
357 stderr_out ("\t%-12s%8x\n", #field ":", (int)cell->gcvm.gcv.field); \
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
358 } while (0)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
359 FROB (function);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
360 FROB (plane_mask);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
361 FROB (foreground);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
362 FROB (background);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
363 FROB (line_width);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
364 FROB (line_style);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
365 FROB (cap_style);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
366 FROB (join_style);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
367 FROB (fill_style);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
368 FROB (fill_rule);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
369 FROB (arc_mode);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
370 FROB (tile);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
371 FROB (stipple);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
372 FROB (ts_x_origin);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
373 FROB (ts_y_origin);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
374 FROB (font);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
375 FROB (subwindow_mode);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
376 FROB (graphics_exposures);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
377 FROB (clip_x_origin);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
378 FROB (clip_y_origin);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
379 FROB (clip_mask);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
380 FROB (dash_offset);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
381 #undef FROB
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
382
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
383 count++;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
384 if (cell->next && cell == cache->tail)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
385 stderr_out ("\nERROR! tail is here!\n\n");
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
386 else if (!cell->next && cell != cache->tail)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
387 stderr_out ("\nERROR! tail is not at the end\n\n");
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
388 cell = cell->next;
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
389 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
390 if (count != cache->size)
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
391 stderr_out ("\nERROR! count should be %d\n\n", cache->size);
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
392 }
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
393
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
394 #endif /* DEBUG_XEMACS */
196ee3cd1ac5 [xemacs-hg @ 2005-02-15 01:19:48 by ben]
ben
parents:
diff changeset
395 #endif /* ! THIS_IS_GTK */