annotate src/gccache-gtk.c @ 5724:ede80ef92a74

Make soft links in src for module source files, if built in to the executable. This ensures that those files are built with the same compiler flags as all other source files. See these xemacs-beta messages: <CAHCOHQn+q=Xuwq+y68dvqi7afAP9f-TdB7=8YiZ8VYO816sjHg@mail.gmail.com> <f5by5ejqiyk.fsf@calexico.inf.ed.ac.uk>
author Jerry James <james@xemacs.org>
date Sat, 02 Mar 2013 14:32:37 -0700
parents 308d34e9f07d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
1 /* Efficient caching of Gtk GCs (graphics contexts).
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
2 Copyright (C) 1993 Free Software Foundation, Inc.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
3 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
4
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
5 This file is part of XEmacs.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
6
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5050
diff changeset
7 XEmacs is free software: you can redistribute it and/or modify it
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
8 under the terms of the GNU General Public License as published by the
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5050
diff changeset
9 Free Software Foundation, either version 3 of the License, or (at your
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5050
diff changeset
10 option) any later version.
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
11
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
15 for more details.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
16
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 5050
diff changeset
18 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
19
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
20 /* Synched up with: Not in FSF. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
21
4908
b3ce27ca7647 various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents: 2515
diff changeset
22 /* XEmacs uses a lot of different display attributes; for example, assume
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
23 that only four fonts are in use (normal, bold, italic, and bold-italic).
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
24 Then assume that one stipple or background is used for text selections,
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
25 and another is used for highlighting mousable regions. That makes 16
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
26 GCs already. Add in the fact that another GC may be needed to display
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
27 the text cursor in any of those regions, and you've got 32. Add in
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
28 more fonts, and it keeps increasing exponentially.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
29
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
30 We used to keep these GCs in a cache of merged (fully qualified) faces.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
31 However, a lot of other code in xterm.c used XChangeGC of existing GCs,
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
32 which is kind of slow and kind of random. Also, managing the face cache
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
33 was tricky because it was hard to know when a face was no longer visible
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
34 on the frame -- we had to mark all frames as garbaged whenever a face
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
35 was changed, which caused an unpleasant amount of flicker (since faces are
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
36 created/destroyed (= changed) whenever a frame is created/destroyed.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
37
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
38 So this code maintains a cache at the GC level instead of at the face
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
39 level. There is an upper limit on the size of the cache, after which we
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
40 will stop creating GCs and start reusing them (reusing the least-recently-
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
41 used ones first). So if faces get changed, their GCs will eventually be
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
42 recycled. Also more sharing of GCs is possible.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
43
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
44 This code uses hashtables. It could be that, if the cache size is small
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
45 enough, a linear search might be faster; but I doubt it, since we need
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
46 `equal' comparisons, not `eq', and I expect that the optimal cache size
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
47 will be ~100.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
48
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
49 Written by jwz, 14 jun 93
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
50 Hacked by William Perry, apr 2000
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
51 */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
52
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
53 #include <config.h>
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
54 #include "lisp.h"
4908
b3ce27ca7647 various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents: 2515
diff changeset
55 #include "hash.h"
b3ce27ca7647 various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents: 2515
diff changeset
56
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
57 #include "gccache-gtk.h"
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
58
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
59 #define GC_CACHE_SIZE 100
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
60
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
61 #define GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
62
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
63 struct gcv_and_mask {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
64 GdkGCValues gcv;
2054
91d4c8c65a0f [xemacs-hg @ 2004-05-02 04:06:51 by malcolmp]
malcolmp
parents: 1726
diff changeset
65 unsigned long mask; /* contains a GdkGCValuesMask bitmask. */
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
66 };
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
67
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
68 struct gc_cache_cell {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
69 GdkGC *gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
70 struct gcv_and_mask gcvm;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
71 struct gc_cache_cell *prev, *next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
72 };
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
73
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
74 struct gc_cache {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
75 GdkWindow *window; /* used only as arg to XCreateGC */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
76 int size;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
77 struct gc_cache_cell *head;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
78 struct gc_cache_cell *tail;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
79 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
80 struct hash_table * table;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
81 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
82
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
83 int create_count;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
84 int delete_count;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
85 };
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
86
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
87 #ifdef GCCACHE_HASH
2515
de9952d2ed18 [xemacs-hg @ 2005-01-26 10:22:19 by ben]
ben
parents: 2500
diff changeset
88 static Hashcode
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
89 gc_cache_hash (const void *arg)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
90 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
91 const struct gcv_and_mask *gcvm = (const struct gcv_and_mask *) arg;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
92 unsigned long *longs = (unsigned long *) &gcvm->gcv;
2515
de9952d2ed18 [xemacs-hg @ 2005-01-26 10:22:19 by ben]
ben
parents: 2500
diff changeset
93 Hashcode hash = gcvm->mask;
778
2923009caf47 [xemacs-hg @ 2002-03-16 10:38:59 by ben]
ben
parents: 462
diff changeset
94 unsigned int i;
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
95 /* This could look at the mask and only use the used slots in the
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
96 hash code. That would win in that we wouldn't have to initialize
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
97 every slot of the gcv when calling gc_cache_lookup. But we need
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
98 the hash function to be as fast as possible; some timings should
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
99 be done. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
100 for (i = 0; i < (sizeof (GdkGCValues) / sizeof (unsigned long)); i++)
2515
de9952d2ed18 [xemacs-hg @ 2005-01-26 10:22:19 by ben]
ben
parents: 2500
diff changeset
101 hash = (hash << 1) ^ *longs++;
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
102 return hash;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
103 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
104
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
105 #endif /* GCCACHE_HASH */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
106
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
107 static int
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
108 gc_cache_eql (const void *arg1, const void *arg2)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
109 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
110 /* See comment in gc_cache_hash */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
111 const struct gcv_and_mask *gcvm1 = (const struct gcv_and_mask *) arg1;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
112 const struct gcv_and_mask *gcvm2 = (const struct gcv_and_mask *) arg2;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
113
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
114 return !memcmp(&gcvm1->gcv, &gcvm2->gcv, sizeof(gcvm1->gcv))
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
115 && gcvm1->mask == gcvm2->mask;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
116 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
117
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
118 struct gc_cache *
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
119 make_gc_cache (GtkWidget *widget)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
120 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
121 struct gc_cache *cache = xnew (struct gc_cache);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
122 cache->window = widget->window;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
123 cache->size = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
124 cache->head = cache->tail = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
125 cache->create_count = cache->delete_count = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
126 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
127 cache->table =
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
128 make_general_hash_table (GC_CACHE_SIZE, gc_cache_hash, gc_cache_eql);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
129 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
130 return cache;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
131 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
132
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
133 void
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
134 free_gc_cache (struct gc_cache *cache)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
135 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
136 struct gc_cache_cell *rest, *next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
137 rest = cache->head;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
138 while (rest)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
139 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
140 gdk_gc_destroy(rest->gc);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
141 next = rest->next;
4976
16112448d484 Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents: 4908
diff changeset
142 xfree (rest);
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
143 rest = next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
144 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
145 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
146 free_hash_table (cache->table);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
147 #endif
4976
16112448d484 Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents: 4908
diff changeset
148 xfree (cache);
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
149 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
150
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
151 GdkGC *
2054
91d4c8c65a0f [xemacs-hg @ 2004-05-02 04:06:51 by malcolmp]
malcolmp
parents: 1726
diff changeset
152 gc_cache_lookup (struct gc_cache *cache, GdkGCValues *gcv, unsigned long mask)
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
153 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
154 struct gc_cache_cell *cell, *next, *prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
155 struct gcv_and_mask gcvm;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
156
5050
6f2158fa75ed Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents: 4976
diff changeset
157 assert ((!!cache->head) == (!!cache->tail));
6f2158fa75ed Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents: 4976
diff changeset
158 assert (!(cache->head && (cache->head->prev || cache->tail->next)));
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
159
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
160 /* Gdk does not have the equivalent of 'None' for the clip_mask, so
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
161 we need to check it carefully, or gdk_gc_new_with_values will
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
162 coredump */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
163 if ((mask & GDK_GC_CLIP_MASK) && !gcv->clip_mask)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
164 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
165 mask &= ~GDK_GC_CLIP_MASK;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
166 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
167
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
168 gcvm.mask = mask;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
169 gcvm.gcv = *gcv; /* this copies... */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
170
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
171 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
172
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
173 if (gethash (&gcvm, cache->table, (const void **) &cell))
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
174
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
175 #else /* !GCCACHE_HASH */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
176
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
177 cell = cache->tail; /* start at the end (most recently used) */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
178 while (cell)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
179 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
180 if (gc_cache_eql (&gcvm, &cell->gcvm))
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
181 break;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
182 else
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
183 cell = cell->prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
184 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
185
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
186 /* #### This whole file needs some serious overhauling. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
187 if (!(mask | GDK_GC_TILE) && cell->gcvm.gcv.tile)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
188 cell = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
189 else if (!(mask | GDK_GC_STIPPLE) && cell->gcvm.gcv.stipple)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
190 cell = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
191
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
192 if (cell)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
193
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
194 #endif /* !GCCACHE_HASH */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
195
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
196 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
197 /* Found a cell. Move this cell to the end of the list, so that it
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
198 will be less likely to be collected than a cell that was accessed
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
199 less recently.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
200 */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
201 if (cell == cache->tail)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
202 return cell->gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
203
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
204 next = cell->next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
205 prev = cell->prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
206 if (prev) prev->next = next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
207 if (next) next->prev = prev;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
208 if (cache->head == cell) cache->head = next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
209 cell->next = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
210 cell->prev = cache->tail;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
211 cache->tail->next = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
212 cache->tail = cell;
5050
6f2158fa75ed Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents: 4976
diff changeset
213 assert (cache->head != cell);
6f2158fa75ed Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents: 4976
diff changeset
214 assert (!cell->next);
6f2158fa75ed Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents: 4976
diff changeset
215 assert (!cache->head->prev);
6f2158fa75ed Fix quick-build, use asserts() in place of ABORT()
Ben Wing <ben@xemacs.org>
parents: 4976
diff changeset
216 assert (!cache->tail->next);
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
217 return cell->gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
218 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
219
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
220 /* else, cache miss. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
221
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
222 if (cache->size == GC_CACHE_SIZE)
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
223 /* Reuse the first cell on the list (least-recently-used).
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
224 Remove it from the list, and unhash it from the table.
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
225 */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
226 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
227 cell = cache->head;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
228 cache->head = cell->next;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
229 cache->head->prev = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
230 if (cache->tail == cell) cache->tail = 0; /* only one */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
231 gdk_gc_destroy (cell->gc);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
232 cache->delete_count++;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
233 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
234 remhash (&cell->gcvm, cache->table);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
235 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
236 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
237 else if (cache->size > GC_CACHE_SIZE)
2500
3d8143fc88e1 [xemacs-hg @ 2005-01-24 23:33:30 by ben]
ben
parents: 2054
diff changeset
238 ABORT ();
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
239 else
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
240 {
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
241 /* Allocate a new cell (don't put it in the list or table yet). */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
242 cell = xnew (struct gc_cache_cell);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
243 cache->size++;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
244 }
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
245
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
246 /* Now we've got a cell (new or reused). Fill it in. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
247 memcpy (&cell->gcvm.gcv, gcv, sizeof (GdkGCValues));
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
248 cell->gcvm.mask = mask;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
249
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
250 /* Put the cell on the end of the list. */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
251 cell->next = 0;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
252 cell->prev = cache->tail;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
253 if (cache->tail) cache->tail->next = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
254 cache->tail = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
255 if (! cache->head) cache->head = cell;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
256
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
257 cache->create_count++;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
258 #ifdef GCCACHE_HASH
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
259 /* Hash it in the table */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
260 puthash (&cell->gcvm, cell, cache->table);
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
261 #endif
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
262
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
263 /* Now make and return the GC. */
2054
91d4c8c65a0f [xemacs-hg @ 2004-05-02 04:06:51 by malcolmp]
malcolmp
parents: 1726
diff changeset
264 cell->gc = gdk_gc_new_with_values (cache->window, gcv, (GdkGCValuesMask) mask);
462
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
265
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
266 /* debug */
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
267 assert (cell->gc == gc_cache_lookup (cache, gcv, mask));
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
268
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
269 return cell->gc;
0784d089fdc9 Import from CVS: tag r21-2-46
cvs
parents:
diff changeset
270 }