]> cvs.zerfleddert.de Git - micropolis/blob - src/tk/tkgc.c
Fixes for compilation with gcc 15
[micropolis] / src / tk / tkgc.c
1 /*
2 * tkGC.c --
3 *
4 * This file maintains a database of read-only graphics contexts
5 * for the Tk toolkit, in order to allow GC's to be shared.
6 *
7 * Copyright 1990 Regents of the University of California
8 * Permission to use, copy, modify, and distribute this
9 * software and its documentation for any purpose and without
10 * fee is hereby granted, provided that the above copyright
11 * notice appear in all copies. The University of California
12 * makes no representations about the suitability of this
13 * software for any purpose. It is provided "as is" without
14 * express or implied warranty.
15 */
16
17 #ifndef lint
18 static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkGC.c,v 1.9 92/05/13 08:48:45 ouster Exp $ SPRITE (Berkeley)";
19 #endif /* not lint */
20
21 #include "tkconfig.h"
22 #include "tk.h"
23
24 /*
25 * One of the following data structures exists for each GC that is
26 * currently active. The structure is indexed with two hash tables,
27 * one based on font name and one based on XFontStruct address.
28 */
29
30 typedef struct {
31 GC gc; /* Graphics context. */
32 Display *display; /* Display to which gc belongs. */
33 int refCount; /* Number of active uses of gc. */
34 Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting
35 * this structure). */
36 } TkGC;
37
38 /*
39 * Hash table to map from a GC's values to a TkGC structure describing
40 * a GC with those values (used by Tk_GetGC).
41 */
42
43 static Tcl_HashTable valueTable;
44 typedef struct {
45 XGCValues values; /* Desired values for GC. */
46 Screen *screen; /* Screen for which GC is valid. */
47 } ValueKey;
48
49 /*
50 * Hash table for GC -> TkGC mapping. This table is indexed by the
51 * GC identifier, and is used by Tk_FreeGC.
52 */
53
54 static Tcl_HashTable idTable;
55
56 static int initialized = 0; /* 0 means static structures haven't been
57 * initialized yet. */
58
59 /*
60 * Forward declarations for procedures defined in this file:
61 */
62
63 static void GCInit _ANSI_ARGS_((void));
64 \f
65 /*
66 *----------------------------------------------------------------------
67 *
68 * Tk_GetGC --
69 *
70 * Given a desired set of values for a graphics context, find
71 * a read-only graphics context with the desired values.
72 *
73 * Results:
74 * The return value is the X identifer for the desired graphics
75 * context. The caller should never modify this GC, and should
76 * call Tk_FreeGC when the GC is no longer needed.
77 *
78 * Side effects:
79 * The GC is added to an internal database with a reference count.
80 * For each call to this procedure, there should eventually be a call
81 * to Tk_FreeGC, so that the database can be cleaned up when GC's
82 * aren't needed anymore.
83 *
84 *----------------------------------------------------------------------
85 */
86
87 GC
88 Tk_GetGC (
89 Tk_Window tkwin, /* Window in which GC will be used. */
90 register unsigned long valueMask,
91 register XGCValues *valuePtr
92 )
93 /* Values are specified here for bits set
94 * in valueMask. */
95 {
96 ValueKey key;
97 Tcl_HashEntry *valueHashPtr, *idHashPtr;
98 register TkGC *gcPtr;
99 int new;
100
101 if (!initialized) {
102 GCInit();
103 }
104
105 /*
106 * Must zero key at start to clear out pad bytes that may be
107 * part of structure on some systems.
108 */
109
110 memset((VOID *) &key, 0, sizeof(key));
111
112 /*
113 * First, check to see if there's already a GC that will work
114 * for this request (exact matches only, sorry).
115 */
116
117 if (valueMask & GCFunction) {
118 key.values.function = valuePtr->function;
119 } else {
120 key.values.function = GXcopy;
121 }
122 if (valueMask & GCPlaneMask) {
123 key.values.plane_mask = valuePtr->plane_mask;
124 } else {
125 key.values.plane_mask = ~0;
126 }
127 if (valueMask & GCForeground) {
128 key.values.foreground = valuePtr->foreground;
129 } else {
130 key.values.foreground = 0;
131 }
132 if (valueMask & GCBackground) {
133 key.values.background = valuePtr->background;
134 } else {
135 key.values.background = 1;
136 }
137 if (valueMask & GCLineWidth) {
138 key.values.line_width = valuePtr->line_width;
139 } else {
140 key.values.line_width = 0;
141 }
142 if (valueMask & GCLineStyle) {
143 key.values.line_style = valuePtr->line_style;
144 } else {
145 key.values.line_style = LineSolid;
146 }
147 if (valueMask & GCCapStyle) {
148 key.values.cap_style = valuePtr->cap_style;
149 } else {
150 key.values.cap_style = CapButt;
151 }
152 if (valueMask & GCJoinStyle) {
153 key.values.join_style = valuePtr->join_style;
154 } else {
155 key.values.join_style = JoinMiter;
156 }
157 if (valueMask & GCFillStyle) {
158 key.values.fill_style = valuePtr->fill_style;
159 } else {
160 key.values.fill_style = FillSolid;
161 }
162 if (valueMask & GCFillRule) {
163 key.values.fill_rule = valuePtr->fill_rule;
164 } else {
165 key.values.fill_rule = EvenOddRule;
166 }
167 if (valueMask & GCArcMode) {
168 key.values.arc_mode = valuePtr->arc_mode;
169 } else {
170 key.values.arc_mode = ArcPieSlice;
171 }
172 if (valueMask & GCTile) {
173 key.values.tile = valuePtr->tile;
174 } else {
175 key.values.tile = None;
176 }
177 if (valueMask & GCStipple) {
178 key.values.stipple = valuePtr->stipple;
179 } else {
180 key.values.stipple = None;
181 }
182 if (valueMask & GCTileStipXOrigin) {
183 key.values.ts_x_origin = valuePtr->ts_x_origin;
184 } else {
185 key.values.ts_x_origin = 0;
186 }
187 if (valueMask & GCTileStipYOrigin) {
188 key.values.ts_y_origin = valuePtr->ts_y_origin;
189 } else {
190 key.values.ts_y_origin = 0;
191 }
192 if (valueMask & GCFont) {
193 key.values.font = valuePtr->font;
194 } else {
195 key.values.font = None;
196 }
197 if (valueMask & GCSubwindowMode) {
198 key.values.subwindow_mode = valuePtr->subwindow_mode;
199 } else {
200 key.values.subwindow_mode = ClipByChildren;
201 }
202 if (valueMask & GCGraphicsExposures) {
203 key.values.graphics_exposures = valuePtr->graphics_exposures;
204 } else {
205 key.values.graphics_exposures = True;
206 }
207 if (valueMask & GCClipXOrigin) {
208 key.values.clip_x_origin = valuePtr->clip_x_origin;
209 } else {
210 key.values.clip_x_origin = 0;
211 }
212 if (valueMask & GCClipYOrigin) {
213 key.values.clip_y_origin = valuePtr->clip_y_origin;
214 } else {
215 key.values.clip_y_origin = 0;
216 }
217 if (valueMask & GCClipMask) {
218 key.values.clip_mask = valuePtr->clip_mask;
219 } else {
220 key.values.clip_mask = None;
221 }
222 if (valueMask & GCDashOffset) {
223 key.values.dash_offset = valuePtr->dash_offset;
224 } else {
225 key.values.dash_offset = 0;
226 }
227 if (valueMask & GCDashList) {
228 key.values.dashes = valuePtr->dashes;
229 } else {
230 key.values.dashes = 4;
231 }
232 key.screen = Tk_Screen(tkwin);
233 valueHashPtr = Tcl_CreateHashEntry(&valueTable, (char *) &key, &new);
234 if (!new) {
235 gcPtr = (TkGC *) Tcl_GetHashValue(valueHashPtr);
236 gcPtr->refCount++;
237 return gcPtr->gc;
238 }
239
240 /*
241 * No GC is currently available for this set of values. Allocate a
242 * new GC and add a new structure to the database.
243 */
244
245 gcPtr = (TkGC *) ckalloc(sizeof(TkGC));
246 #if 0
247 gcPtr->gc = XCreateGC(Tk_Display(tkwin),
248 RootWindowOfScreen(Tk_Screen(tkwin)),
249 valueMask, &key.values);
250 #else
251 gcPtr->gc = XCreateGC(Tk_Display(tkwin),
252 Tk_DefaultPixmap(Tk_Screen(tkwin)),
253 valueMask, &key.values);
254 #endif
255 gcPtr->display = Tk_Display(tkwin);
256 gcPtr->refCount = 1;
257 gcPtr->valueHashPtr = valueHashPtr;
258 idHashPtr = Tcl_CreateHashEntry(&idTable, (char *) gcPtr->gc, &new);
259 if (!new) {
260 panic("GC already registered in Tk_GetGC");
261 }
262 Tcl_SetHashValue(valueHashPtr, gcPtr);
263 Tcl_SetHashValue(idHashPtr, gcPtr);
264 return gcPtr->gc;
265 }
266 \f
267 /*
268 *----------------------------------------------------------------------
269 *
270 * Tk_FreeGC --
271 *
272 * This procedure is called to release a font allocated by
273 * Tk_GetGC.
274 *
275 * Results:
276 * None.
277 *
278 * Side effects:
279 * The reference count associated with gc is decremented, and
280 * gc is officially deallocated if no-one is using it anymore.
281 *
282 *----------------------------------------------------------------------
283 */
284
285 void
286 Tk_FreeGC (
287 GC gc /* Graphics context to be released. */
288 )
289 {
290 Tcl_HashEntry *idHashPtr;
291 register TkGC *gcPtr;
292
293 if (!initialized) {
294 panic("Tk_FreeGC called before Tk_GetGC");
295 }
296
297 idHashPtr = Tcl_FindHashEntry(&idTable, (char *) gc);
298 if (idHashPtr == NULL) {
299 panic("Tk_FreeGC received unknown gc argument");
300 }
301 gcPtr = (TkGC *) Tcl_GetHashValue(idHashPtr);
302 gcPtr->refCount--;
303 if (gcPtr->refCount == 0) {
304 XFreeGC(gcPtr->display, gcPtr->gc);
305 Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
306 Tcl_DeleteHashEntry(idHashPtr);
307 ckfree((char *) gcPtr);
308 }
309 }
310 \f
311 /*
312 *----------------------------------------------------------------------
313 *
314 * GCInit --
315 *
316 * Initialize the structures used for GC management.
317 *
318 * Results:
319 * None.
320 *
321 * Side effects:
322 * Read the code.
323 *
324 *----------------------------------------------------------------------
325 */
326
327 static void
328 GCInit (void)
329 {
330 initialized = 1;
331 Tcl_InitHashTable(&valueTable, sizeof(ValueKey)/sizeof(int));
332 Tcl_InitHashTable(&idTable, TCL_ONE_WORD_KEYS);
333 }
Impressum, Datenschutz