1
/* $Xorg: GCManager.c,v 1.5 2001/02/09 02:03:54 xorgcvs Exp $ */
3
/***********************************************************
4
Copyright 1987, 1988, 1990 by Digital Equipment Corporation, Maynard, Massachusetts
5
Copyright 1993 by Sun Microsystems, Inc. Mountain View, CA.
9
Permission to use, copy, modify, and distribute this software and its
10
documentation for any purpose and without fee is hereby granted,
11
provided that the above copyright notice appear in all copies and that
12
both that copyright notice and this permission notice appear in
13
supporting documentation, and that the names of Digital or Sun not be
14
used in advertising or publicity pertaining to distribution of the
15
software without specific, written prior permission.
17
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
18
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
19
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
20
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
22
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25
SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
27
NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE LI-
28
ABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
29
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
30
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
31
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH
32
THE USE OR PERFORMANCE OF THIS SOFTWARE.
34
******************************************************************/
38
Copyright 1987, 1988, 1990, 1994, 1998 The Open Group
40
Permission to use, copy, modify, distribute, and sell this software and its
41
documentation for any purpose is hereby granted without fee, provided that
42
the above copyright notice appear in all copies and that both that
43
copyright notice and this permission notice appear in supporting
46
The above copyright notice and this permission notice shall be included in
47
all copies or substantial portions of the Software.
49
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
53
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
54
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56
Except as contained in this notice, the name of The Open Group shall not be
57
used in advertising or otherwise to promote the sale, use or other dealings
58
in this Software without prior written authorization from The Open Group.
61
/* $XFree86: xc/lib/Xt/GCManager.c,v 1.5 2001/08/22 22:52:18 dawes Exp $ */
66
#include "IntrinsicI.h"
69
typedef struct _GCrec {
70
unsigned char screen; /* Screen for GC */
71
unsigned char depth; /* Depth for GC */
72
char dashes; /* Dashes value */
73
Pixmap clip_mask; /* Clip_mask value */
74
Cardinal ref_count; /* # of shareholders */
75
GC gc; /* The GC itself. */
76
XtGCMask dynamic_mask; /* Writable values */
77
XtGCMask unused_mask; /* Unused values */
78
struct _GCrec *next; /* Next GC for this widgetkind. */
81
#define GCVAL(bit,mask,val,default) ((bit&mask) ? val : default)
83
#define CHECK(bit,comp,default) \
84
if ((checkMask & bit) && \
85
(GCVAL(bit,valueMask,v->comp,default) != gcv.comp)) return False
87
#define ALLGCVALS (GCFunction | GCPlaneMask | GCForeground | \
88
GCBackground | GCLineWidth | GCLineStyle | \
89
GCCapStyle | GCJoinStyle | GCFillStyle | \
90
GCFillRule | GCTile | GCStipple | \
91
GCTileStipXOrigin | GCTileStipYOrigin | \
92
GCFont | GCSubwindowMode | GCGraphicsExposures | \
93
GCClipXOrigin | GCClipYOrigin | GCDashOffset | \
99
register XtGCMask valueMask,
100
register XGCValues *v,
101
XtGCMask readOnlyMask,
102
XtGCMask dynamicMask)
105
register XtGCMask checkMask;
107
if (readOnlyMask & ptr->dynamic_mask)
109
if (((ptr->dynamic_mask|ptr->unused_mask) & dynamicMask) != dynamicMask)
111
if (!XGetGCValues(dpy, ptr->gc, ALLGCVALS, &gcv))
113
checkMask = readOnlyMask & ~ptr->unused_mask;
114
CHECK(GCForeground, foreground, 0);
115
CHECK(GCBackground, background, 1);
116
CHECK(GCFont, font, ~0UL);
117
CHECK(GCFillStyle, fill_style, FillSolid);
118
CHECK(GCLineWidth, line_width, 0);
119
CHECK(GCFunction, function, GXcopy);
120
CHECK(GCGraphicsExposures, graphics_exposures, True);
121
CHECK(GCTile, tile, ~0UL);
122
CHECK(GCSubwindowMode, subwindow_mode, ClipByChildren);
123
CHECK(GCPlaneMask, plane_mask, AllPlanes);
124
CHECK(GCLineStyle, line_style, LineSolid);
125
CHECK(GCCapStyle, cap_style, CapButt);
126
CHECK(GCJoinStyle, join_style, JoinMiter);
127
CHECK(GCFillRule, fill_rule, EvenOddRule);
128
CHECK(GCArcMode, arc_mode, ArcPieSlice);
129
CHECK(GCStipple, stipple, ~0UL);
130
CHECK(GCTileStipXOrigin, ts_x_origin, 0);
131
CHECK(GCTileStipYOrigin, ts_y_origin, 0);
132
CHECK(GCClipXOrigin, clip_x_origin, 0);
133
CHECK(GCClipYOrigin, clip_y_origin, 0);
134
CHECK(GCDashOffset, dash_offset, 0);
135
gcv.clip_mask = ptr->clip_mask;
136
CHECK(GCClipMask, clip_mask, None);
137
gcv.dashes = ptr->dashes;
138
CHECK(GCDashList, dashes, 4);
139
valueMask &= ptr->unused_mask | dynamicMask;
141
XChangeGC(dpy, ptr->gc, valueMask, v);
142
if (valueMask & GCDashList)
143
ptr->dashes = v->dashes;
144
if (valueMask & GCClipMask)
145
ptr->clip_mask = v->clip_mask;
147
ptr->unused_mask &= ~(dynamicMask | readOnlyMask);
148
ptr->dynamic_mask |= dynamicMask;
152
/* Called by CloseDisplay to free the per-display GC list */
155
register XtPerDisplay pd)
157
register GCptr GClist, next;
163
XtFree((char*)GClist);
166
if (pd->pixmap_tab) {
167
for (i = ScreenCount(dpy); --i >= 0; ) {
168
if (pd->pixmap_tab[i])
169
XtFree((char *)pd->pixmap_tab[i]);
171
XtFree((char *)pd->pixmap_tab);
177
* Return a GC with the given values and characteristics.
181
register Widget widget,
185
XtGCMask dynamicMask,
188
register GCptr *prev;
191
register Display *dpy;
192
register XtPerDisplay pd;
195
XtGCMask readOnlyMask;
197
WIDGET_TO_APPCON(widget);
201
if (!XtIsWidget(widget))
202
widget = _XtWindowedAncestor(widget);
204
depth = widget->core.depth;
205
screen = XtScreen(widget);
206
dpy = DisplayOfScreen(screen);
207
pd = _XtGetPerDisplay(dpy);
208
unusedMask &= ~valueMask;
209
readOnlyMask = ~(dynamicMask | unusedMask);
211
/* Search for existing GC that matches exactly */
212
for (prev = &pd->GClist; (cur = *prev); prev = &cur->next) {
213
if (cur->depth == depth &&
214
ScreenOfDisplay(dpy, cur->screen) == screen &&
215
Matches(dpy, cur, valueMask, values, readOnlyMask, dynamicMask)) {
217
/* Move this GC to front of list */
219
cur->next = pd->GClist;
228
/* No matches, have to create a new one */
230
cur->screen = XScreenNumberOfScreen(screen);
233
cur->dynamic_mask = dynamicMask;
234
cur->unused_mask = (unusedMask & ~dynamicMask);
235
cur->dashes = GCVAL(GCDashList, valueMask, values->dashes, 4);
236
cur->clip_mask = GCVAL(GCClipMask, valueMask, values->clip_mask, None);
238
if (depth == widget->core.depth)
239
drawable = XtWindow(widget);
240
if (!drawable && depth == (Cardinal) DefaultDepthOfScreen(screen))
241
drawable = RootWindowOfScreen(screen);
243
if (!pd->pixmap_tab) {
245
pd->pixmap_tab = (Drawable **)__XtMalloc((unsigned)ScreenCount(dpy) *
247
for (n = 0; n < ScreenCount(dpy); n++)
248
pd->pixmap_tab[n] = NULL;
250
pixmaps = pd->pixmap_tab[cur->screen];
253
depths = XListDepths(dpy, cur->screen, &n);
260
XFree((char *)depths);
261
pixmaps = (Drawable *)__XtCalloc((unsigned)max, sizeof(Drawable));
262
pd->pixmap_tab[cur->screen] = pixmaps;
264
drawable = pixmaps[cur->depth - 1];
266
drawable = XCreatePixmap(dpy, RootWindowOfScreen(screen), 1, 1,
268
pixmaps[cur->depth - 1] = drawable;
271
cur->gc = XCreateGC(dpy, drawable, valueMask, values);
272
cur->next = pd->GClist;
281
* Return a read-only GC with the given values.
285
register Widget widget,
289
return XtAllocateGC(widget, 0, valueMask, values, 0, 0);
296
register GCptr cur, *prev;
299
WIDGET_TO_APPCON(widget);
303
dpy = XtDisplayOfObject(widget);
304
pd = _XtGetPerDisplay(dpy);
306
for (prev = &pd->GClist; (cur = *prev); prev = &cur->next) {
308
if (--(cur->ref_count) == 0) {
311
XtFree((char *) cur);
320
/* The following interface is broken and supplied only for backwards
321
* compatibility. It will work properly in all cases only if there
322
* is exactly 1 Display created by the application.
325
void XtDestroyGC(register GC gc)
331
app = _XtGetProcessContext()->appContextList;
332
/* This is awful; we have to search through all the lists
334
for (; app; app = app->next) {
336
for (i = app->count; i ;) {
337
Display *dpy = app->list[--i];
338
XtPerDisplay pd = _XtGetPerDisplay(dpy);
339
for (prev = &pd->GClist; (cur = *prev); prev = &cur->next) {
341
if (--(cur->ref_count) == 0) {
344
XtFree((char *) cur);