1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1993, 1998 The Open Group
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included
12*4882a593Smuzhiyun in all copies or substantial portions of the Software.
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*4882a593Smuzhiyun OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16*4882a593Smuzhiyun MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17*4882a593Smuzhiyun IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*4882a593Smuzhiyun OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*4882a593Smuzhiyun ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*4882a593Smuzhiyun OTHER DEALINGS IN THE SOFTWARE.
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall
23*4882a593Smuzhiyun not be used in advertising or otherwise to promote the sale, use or
24*4882a593Smuzhiyun other dealings in this Software without prior written authorization
25*4882a593Smuzhiyun from The Open Group.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * Copyright © 2010, Keith Packard
30*4882a593Smuzhiyun * Copyright © 2010, Jamey Sharp
31*4882a593Smuzhiyun *
32*4882a593Smuzhiyun * Permission to use, copy, modify, distribute, and sell this software and its
33*4882a593Smuzhiyun * documentation for any purpose is hereby granted without fee, provided that
34*4882a593Smuzhiyun * the above copyright notice appear in all copies and that both that copyright
35*4882a593Smuzhiyun * notice and this permission notice appear in supporting documentation, and
36*4882a593Smuzhiyun * that the name of the copyright holders not be used in advertising or
37*4882a593Smuzhiyun * publicity pertaining to distribution of the software without specific,
38*4882a593Smuzhiyun * written prior permission. The copyright holders make no representations
39*4882a593Smuzhiyun * about the suitability of this software for any purpose. It is provided "as
40*4882a593Smuzhiyun * is" without express or implied warranty.
41*4882a593Smuzhiyun *
42*4882a593Smuzhiyun * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
43*4882a593Smuzhiyun * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
44*4882a593Smuzhiyun * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
45*4882a593Smuzhiyun * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
46*4882a593Smuzhiyun * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
47*4882a593Smuzhiyun * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
48*4882a593Smuzhiyun * OF THIS SOFTWARE.
49*4882a593Smuzhiyun */
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
52*4882a593Smuzhiyun #include <dix-config.h>
53*4882a593Smuzhiyun #endif
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun #include <stddef.h>
56*4882a593Smuzhiyun #include "windowstr.h"
57*4882a593Smuzhiyun #include "resource.h"
58*4882a593Smuzhiyun #include "privates.h"
59*4882a593Smuzhiyun #include "gcstruct.h"
60*4882a593Smuzhiyun #include "cursorstr.h"
61*4882a593Smuzhiyun #include "colormapst.h"
62*4882a593Smuzhiyun #include "inputstr.h"
63*4882a593Smuzhiyun #include "scrnintstr.h"
64*4882a593Smuzhiyun #include "extnsionst.h"
65*4882a593Smuzhiyun #include "inputstr.h"
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun static DevPrivateSetRec global_keys[PRIVATE_LAST];
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun static const Bool xselinux_private[PRIVATE_LAST] = {
70*4882a593Smuzhiyun [PRIVATE_SCREEN] = TRUE,
71*4882a593Smuzhiyun [PRIVATE_CLIENT] = TRUE,
72*4882a593Smuzhiyun [PRIVATE_WINDOW] = TRUE,
73*4882a593Smuzhiyun [PRIVATE_PIXMAP] = TRUE,
74*4882a593Smuzhiyun [PRIVATE_GC] = TRUE,
75*4882a593Smuzhiyun [PRIVATE_CURSOR] = TRUE,
76*4882a593Smuzhiyun [PRIVATE_COLORMAP] = TRUE,
77*4882a593Smuzhiyun [PRIVATE_DEVICE] = TRUE,
78*4882a593Smuzhiyun [PRIVATE_EXTENSION] = TRUE,
79*4882a593Smuzhiyun [PRIVATE_SELECTION] = TRUE,
80*4882a593Smuzhiyun [PRIVATE_PROPERTY] = TRUE,
81*4882a593Smuzhiyun [PRIVATE_PICTURE] = TRUE,
82*4882a593Smuzhiyun [PRIVATE_GLYPHSET] = TRUE,
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun static const char *key_names[PRIVATE_LAST] = {
86*4882a593Smuzhiyun /* XSELinux uses the same private keys for numerous objects */
87*4882a593Smuzhiyun [PRIVATE_XSELINUX] = "XSELINUX",
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /* Otherwise, you get a private in just the requested structure
90*4882a593Smuzhiyun */
91*4882a593Smuzhiyun /* These can have objects created before all of the keys are registered */
92*4882a593Smuzhiyun [PRIVATE_SCREEN] = "SCREEN",
93*4882a593Smuzhiyun [PRIVATE_EXTENSION] = "EXTENSION",
94*4882a593Smuzhiyun [PRIVATE_COLORMAP] = "COLORMAP",
95*4882a593Smuzhiyun [PRIVATE_DEVICE] = "DEVICE",
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun /* These cannot have any objects before all relevant keys are registered */
98*4882a593Smuzhiyun [PRIVATE_CLIENT] = "CLIENT",
99*4882a593Smuzhiyun [PRIVATE_PROPERTY] = "PROPERTY",
100*4882a593Smuzhiyun [PRIVATE_SELECTION] = "SELECTION",
101*4882a593Smuzhiyun [PRIVATE_WINDOW] = "WINDOW",
102*4882a593Smuzhiyun [PRIVATE_PIXMAP] = "PIXMAP",
103*4882a593Smuzhiyun [PRIVATE_GC] = "GC",
104*4882a593Smuzhiyun [PRIVATE_CURSOR] = "CURSOR",
105*4882a593Smuzhiyun [PRIVATE_CURSOR_BITS] = "CURSOR_BITS",
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun /* extension privates */
108*4882a593Smuzhiyun [PRIVATE_GLYPH] = "GLYPH",
109*4882a593Smuzhiyun [PRIVATE_GLYPHSET] = "GLYPHSET",
110*4882a593Smuzhiyun [PRIVATE_PICTURE] = "PICTURE",
111*4882a593Smuzhiyun [PRIVATE_SYNC_FENCE] = "SYNC_FENCE",
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun static const Bool screen_specific_private[PRIVATE_LAST] = {
115*4882a593Smuzhiyun [PRIVATE_SCREEN] = FALSE,
116*4882a593Smuzhiyun [PRIVATE_CLIENT] = FALSE,
117*4882a593Smuzhiyun [PRIVATE_WINDOW] = TRUE,
118*4882a593Smuzhiyun [PRIVATE_PIXMAP] = TRUE,
119*4882a593Smuzhiyun [PRIVATE_GC] = TRUE,
120*4882a593Smuzhiyun [PRIVATE_CURSOR] = FALSE,
121*4882a593Smuzhiyun [PRIVATE_COLORMAP] = FALSE,
122*4882a593Smuzhiyun [PRIVATE_DEVICE] = FALSE,
123*4882a593Smuzhiyun [PRIVATE_EXTENSION] = FALSE,
124*4882a593Smuzhiyun [PRIVATE_SELECTION] = FALSE,
125*4882a593Smuzhiyun [PRIVATE_PROPERTY] = FALSE,
126*4882a593Smuzhiyun [PRIVATE_PICTURE] = TRUE,
127*4882a593Smuzhiyun [PRIVATE_GLYPHSET] = FALSE,
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun typedef Bool (*FixupFunc) (PrivatePtr *privates, int offset, unsigned bytes);
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun typedef enum { FixupMove, FixupRealloc } FixupType;
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun static Bool
dixReallocPrivates(PrivatePtr * privates,int old_offset,unsigned bytes)135*4882a593Smuzhiyun dixReallocPrivates(PrivatePtr *privates, int old_offset, unsigned bytes)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun void *new_privates;
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun new_privates = realloc(*privates, old_offset + bytes);
140*4882a593Smuzhiyun if (!new_privates)
141*4882a593Smuzhiyun return FALSE;
142*4882a593Smuzhiyun memset((char *) new_privates + old_offset, '\0', bytes);
143*4882a593Smuzhiyun *privates = new_privates;
144*4882a593Smuzhiyun return TRUE;
145*4882a593Smuzhiyun }
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun static Bool
dixMovePrivates(PrivatePtr * privates,int new_offset,unsigned bytes)148*4882a593Smuzhiyun dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun memmove((char *) *privates + bytes, *privates, new_offset - bytes);
151*4882a593Smuzhiyun memset(*privates, '\0', bytes);
152*4882a593Smuzhiyun return TRUE;
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun static Bool
fixupOneScreen(ScreenPtr pScreen,FixupFunc fixup,unsigned bytes)156*4882a593Smuzhiyun fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun intptr_t dist;
159*4882a593Smuzhiyun char *old;
160*4882a593Smuzhiyun char *new;
161*4882a593Smuzhiyun DevPrivateKey *keyp, key;
162*4882a593Smuzhiyun DevPrivateType type;
163*4882a593Smuzhiyun int size;
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun old = (char *) pScreen->devPrivates;
166*4882a593Smuzhiyun size = global_keys[PRIVATE_SCREEN].offset;
167*4882a593Smuzhiyun if (!fixup (&pScreen->devPrivates, size, bytes))
168*4882a593Smuzhiyun return FALSE;
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun /* Screen privates can contain screen-specific private keys
171*4882a593Smuzhiyun * for other types. When they move, the linked list we use to
172*4882a593Smuzhiyun * track them gets scrambled. Fix that by computing the change
173*4882a593Smuzhiyun * in the location of each private adjusting our linked list
174*4882a593Smuzhiyun * pointers to match
175*4882a593Smuzhiyun */
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun new = (char *) pScreen->devPrivates;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun /* Moving means everyone shifts up in the privates by 'bytes' amount,
180*4882a593Smuzhiyun * realloc means the base pointer moves
181*4882a593Smuzhiyun */
182*4882a593Smuzhiyun if (fixup == dixMovePrivates)
183*4882a593Smuzhiyun new += bytes;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun dist = new - old;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun if (dist) {
188*4882a593Smuzhiyun for (type = PRIVATE_XSELINUX; type < PRIVATE_LAST; type++)
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun /* Walk the privates list, being careful as the
191*4882a593Smuzhiyun * pointers are scrambled before we patch them.
192*4882a593Smuzhiyun */
193*4882a593Smuzhiyun for (keyp = &pScreen->screenSpecificPrivates[type].key;
194*4882a593Smuzhiyun (key = *keyp) != NULL;
195*4882a593Smuzhiyun keyp = &key->next)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun /* Only mangle things if the private structure
199*4882a593Smuzhiyun * is contained within the allocation. Privates
200*4882a593Smuzhiyun * stored elsewhere will be left alone
201*4882a593Smuzhiyun */
202*4882a593Smuzhiyun if (old <= (char *) key && (char *) key < old + size)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun /* Compute new location of key */
205*4882a593Smuzhiyun key = (DevPrivateKey) ((char *) key + dist);
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun /* Patch the list */
208*4882a593Smuzhiyun *keyp = key;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun return TRUE;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun static Bool
fixupScreens(FixupFunc fixup,unsigned bytes)216*4882a593Smuzhiyun fixupScreens(FixupFunc fixup, unsigned bytes)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun int s;
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun for (s = 0; s < screenInfo.numScreens; s++)
221*4882a593Smuzhiyun if (!fixupOneScreen (screenInfo.screens[s], fixup, bytes))
222*4882a593Smuzhiyun return FALSE;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun for (s = 0; s < screenInfo.numGPUScreens; s++)
225*4882a593Smuzhiyun if (!fixupOneScreen (screenInfo.gpuscreens[s], fixup, bytes))
226*4882a593Smuzhiyun return FALSE;
227*4882a593Smuzhiyun return TRUE;
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun static Bool
fixupServerClient(FixupFunc fixup,unsigned bytes)231*4882a593Smuzhiyun fixupServerClient(FixupFunc fixup, unsigned bytes)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun if (serverClient)
234*4882a593Smuzhiyun return fixup(&serverClient->devPrivates, global_keys[PRIVATE_CLIENT].offset,
235*4882a593Smuzhiyun bytes);
236*4882a593Smuzhiyun return TRUE;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun static Bool
fixupExtensions(FixupFunc fixup,unsigned bytes)240*4882a593Smuzhiyun fixupExtensions(FixupFunc fixup, unsigned bytes)
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun unsigned char major;
243*4882a593Smuzhiyun ExtensionEntry *extension;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun for (major = EXTENSION_BASE; (extension = GetExtensionEntry(major));
246*4882a593Smuzhiyun major++)
247*4882a593Smuzhiyun if (!fixup
248*4882a593Smuzhiyun (&extension->devPrivates, global_keys[PRIVATE_EXTENSION].offset, bytes))
249*4882a593Smuzhiyun return FALSE;
250*4882a593Smuzhiyun return TRUE;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun static Bool
fixupDefaultColormaps(FixupFunc fixup,unsigned bytes)254*4882a593Smuzhiyun fixupDefaultColormaps(FixupFunc fixup, unsigned bytes)
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun int s;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun for (s = 0; s < screenInfo.numScreens; s++) {
259*4882a593Smuzhiyun ColormapPtr cmap;
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun dixLookupResourceByType((void **) &cmap,
262*4882a593Smuzhiyun screenInfo.screens[s]->defColormap, RT_COLORMAP,
263*4882a593Smuzhiyun serverClient, DixCreateAccess);
264*4882a593Smuzhiyun if (cmap &&
265*4882a593Smuzhiyun !fixup(&cmap->devPrivates, screenInfo.screens[s]->screenSpecificPrivates[PRIVATE_COLORMAP].offset, bytes))
266*4882a593Smuzhiyun return FALSE;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun return TRUE;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun static Bool
fixupDeviceList(DeviceIntPtr device,FixupFunc fixup,unsigned bytes)272*4882a593Smuzhiyun fixupDeviceList(DeviceIntPtr device, FixupFunc fixup, unsigned bytes)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun while (device) {
275*4882a593Smuzhiyun if (!fixup(&device->devPrivates, global_keys[PRIVATE_DEVICE].offset, bytes))
276*4882a593Smuzhiyun return FALSE;
277*4882a593Smuzhiyun device = device->next;
278*4882a593Smuzhiyun }
279*4882a593Smuzhiyun return TRUE;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun static Bool
fixupDevices(FixupFunc fixup,unsigned bytes)283*4882a593Smuzhiyun fixupDevices(FixupFunc fixup, unsigned bytes)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun return (fixupDeviceList(inputInfo.devices, fixup, bytes) &&
286*4882a593Smuzhiyun fixupDeviceList(inputInfo.off_devices, fixup, bytes));
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun static Bool (*const allocated_early[PRIVATE_LAST]) (FixupFunc, unsigned) = {
290*4882a593Smuzhiyun [PRIVATE_SCREEN] = fixupScreens,
291*4882a593Smuzhiyun [PRIVATE_CLIENT] = fixupServerClient,
292*4882a593Smuzhiyun [PRIVATE_EXTENSION] = fixupExtensions,
293*4882a593Smuzhiyun [PRIVATE_COLORMAP] = fixupDefaultColormaps,
294*4882a593Smuzhiyun [PRIVATE_DEVICE] = fixupDevices,
295*4882a593Smuzhiyun };
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun static void
grow_private_set(DevPrivateSetPtr set,unsigned bytes)298*4882a593Smuzhiyun grow_private_set(DevPrivateSetPtr set, unsigned bytes)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun DevPrivateKey k;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun for (k = set->key; k; k = k->next)
303*4882a593Smuzhiyun k->offset += bytes;
304*4882a593Smuzhiyun set->offset += bytes;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun static void
grow_screen_specific_set(DevPrivateType type,unsigned bytes)308*4882a593Smuzhiyun grow_screen_specific_set(DevPrivateType type, unsigned bytes)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun int s;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /* Update offsets for all screen-specific keys */
313*4882a593Smuzhiyun for (s = 0; s < screenInfo.numScreens; s++) {
314*4882a593Smuzhiyun ScreenPtr pScreen = screenInfo.screens[s];
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun grow_private_set(&pScreen->screenSpecificPrivates[type], bytes);
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun for (s = 0; s < screenInfo.numGPUScreens; s++) {
319*4882a593Smuzhiyun ScreenPtr pScreen = screenInfo.gpuscreens[s];
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun grow_private_set(&pScreen->screenSpecificPrivates[type], bytes);
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /*
326*4882a593Smuzhiyun * Register a private key. This takes the type of object the key will
327*4882a593Smuzhiyun * be used with, which may be PRIVATE_ALL indicating that this key
328*4882a593Smuzhiyun * will be used with all of the private objects. If 'size' is
329*4882a593Smuzhiyun * non-zero, then the specified amount of space will be allocated in
330*4882a593Smuzhiyun * the private storage. Otherwise, space for a single pointer will
331*4882a593Smuzhiyun * be allocated which can be set with dixSetPrivate
332*4882a593Smuzhiyun */
333*4882a593Smuzhiyun Bool
dixRegisterPrivateKey(DevPrivateKey key,DevPrivateType type,unsigned size)334*4882a593Smuzhiyun dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun DevPrivateType t;
337*4882a593Smuzhiyun int offset;
338*4882a593Smuzhiyun unsigned bytes;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun if (key->initialized) {
341*4882a593Smuzhiyun assert(size == key->size);
342*4882a593Smuzhiyun return TRUE;
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun /* Compute required space */
346*4882a593Smuzhiyun bytes = size;
347*4882a593Smuzhiyun if (size == 0)
348*4882a593Smuzhiyun bytes = sizeof(void *);
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun /* align to pointer size */
351*4882a593Smuzhiyun bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun /* Update offsets for all affected keys */
354*4882a593Smuzhiyun if (type == PRIVATE_XSELINUX) {
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun /* Resize if we can, or make sure nothing's allocated if we can't
357*4882a593Smuzhiyun */
358*4882a593Smuzhiyun for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++)
359*4882a593Smuzhiyun if (xselinux_private[t]) {
360*4882a593Smuzhiyun if (!allocated_early[t])
361*4882a593Smuzhiyun assert(!global_keys[t].created);
362*4882a593Smuzhiyun else if (!allocated_early[t] (dixReallocPrivates, bytes))
363*4882a593Smuzhiyun return FALSE;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun /* Move all existing keys up in the privates space to make
367*4882a593Smuzhiyun * room for this new global key
368*4882a593Smuzhiyun */
369*4882a593Smuzhiyun for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
370*4882a593Smuzhiyun if (xselinux_private[t]) {
371*4882a593Smuzhiyun grow_private_set(&global_keys[t], bytes);
372*4882a593Smuzhiyun grow_screen_specific_set(t, bytes);
373*4882a593Smuzhiyun if (allocated_early[t])
374*4882a593Smuzhiyun allocated_early[t] (dixMovePrivates, bytes);
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun offset = 0;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun else {
382*4882a593Smuzhiyun /* Resize if we can, or make sure nothing's allocated if we can't */
383*4882a593Smuzhiyun if (!allocated_early[type])
384*4882a593Smuzhiyun assert(!global_keys[type].created);
385*4882a593Smuzhiyun else if (!allocated_early[type] (dixReallocPrivates, bytes))
386*4882a593Smuzhiyun return FALSE;
387*4882a593Smuzhiyun offset = global_keys[type].offset;
388*4882a593Smuzhiyun global_keys[type].offset += bytes;
389*4882a593Smuzhiyun grow_screen_specific_set(type, bytes);
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun /* Setup this key */
393*4882a593Smuzhiyun key->offset = offset;
394*4882a593Smuzhiyun key->size = size;
395*4882a593Smuzhiyun key->initialized = TRUE;
396*4882a593Smuzhiyun key->type = type;
397*4882a593Smuzhiyun key->allocated = FALSE;
398*4882a593Smuzhiyun key->next = global_keys[type].key;
399*4882a593Smuzhiyun global_keys[type].key = key;
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun return TRUE;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun Bool
dixRegisterScreenPrivateKey(DevScreenPrivateKey screenKey,ScreenPtr pScreen,DevPrivateType type,unsigned size)405*4882a593Smuzhiyun dixRegisterScreenPrivateKey(DevScreenPrivateKey screenKey, ScreenPtr pScreen,
406*4882a593Smuzhiyun DevPrivateType type, unsigned size)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun DevPrivateKey key;
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun if (!dixRegisterPrivateKey(&screenKey->screenKey, PRIVATE_SCREEN, 0))
411*4882a593Smuzhiyun return FALSE;
412*4882a593Smuzhiyun key = dixGetPrivate(&pScreen->devPrivates, &screenKey->screenKey);
413*4882a593Smuzhiyun if (key != NULL) {
414*4882a593Smuzhiyun assert(key->size == size);
415*4882a593Smuzhiyun assert(key->type == type);
416*4882a593Smuzhiyun return TRUE;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun key = calloc(sizeof(DevPrivateKeyRec), 1);
419*4882a593Smuzhiyun if (!key)
420*4882a593Smuzhiyun return FALSE;
421*4882a593Smuzhiyun if (!dixRegisterPrivateKey(key, type, size)) {
422*4882a593Smuzhiyun free(key);
423*4882a593Smuzhiyun return FALSE;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun key->allocated = TRUE;
426*4882a593Smuzhiyun dixSetPrivate(&pScreen->devPrivates, &screenKey->screenKey, key);
427*4882a593Smuzhiyun return TRUE;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun DevPrivateKey
_dixGetScreenPrivateKey(const DevScreenPrivateKey key,ScreenPtr pScreen)431*4882a593Smuzhiyun _dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen)
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun return dixGetPrivate(&pScreen->devPrivates, &key->screenKey);
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun /*
437*4882a593Smuzhiyun * Initialize privates by zeroing them
438*4882a593Smuzhiyun */
439*4882a593Smuzhiyun void
_dixInitPrivates(PrivatePtr * privates,void * addr,DevPrivateType type)440*4882a593Smuzhiyun _dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type)
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun assert (!screen_specific_private[type]);
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun global_keys[type].created++;
445*4882a593Smuzhiyun if (xselinux_private[type])
446*4882a593Smuzhiyun global_keys[PRIVATE_XSELINUX].created++;
447*4882a593Smuzhiyun if (global_keys[type].offset == 0)
448*4882a593Smuzhiyun addr = 0;
449*4882a593Smuzhiyun *privates = addr;
450*4882a593Smuzhiyun memset(addr, '\0', global_keys[type].offset);
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun /*
454*4882a593Smuzhiyun * Clean up privates
455*4882a593Smuzhiyun */
456*4882a593Smuzhiyun void
_dixFiniPrivates(PrivatePtr privates,DevPrivateType type)457*4882a593Smuzhiyun _dixFiniPrivates(PrivatePtr privates, DevPrivateType type)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun global_keys[type].created--;
460*4882a593Smuzhiyun if (xselinux_private[type])
461*4882a593Smuzhiyun global_keys[PRIVATE_XSELINUX].created--;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun /*
465*4882a593Smuzhiyun * Allocate new object with privates.
466*4882a593Smuzhiyun *
467*4882a593Smuzhiyun * This is expected to be invoked from the
468*4882a593Smuzhiyun * dixAllocateObjectWithPrivates macro
469*4882a593Smuzhiyun */
470*4882a593Smuzhiyun void *
_dixAllocateObjectWithPrivates(unsigned baseSize,unsigned clear,unsigned offset,DevPrivateType type)471*4882a593Smuzhiyun _dixAllocateObjectWithPrivates(unsigned baseSize, unsigned clear,
472*4882a593Smuzhiyun unsigned offset, DevPrivateType type)
473*4882a593Smuzhiyun {
474*4882a593Smuzhiyun unsigned totalSize;
475*4882a593Smuzhiyun void *object;
476*4882a593Smuzhiyun PrivatePtr privates;
477*4882a593Smuzhiyun PrivatePtr *devPrivates;
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST);
480*4882a593Smuzhiyun assert(!screen_specific_private[type]);
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun /* round up so that void * is aligned */
483*4882a593Smuzhiyun baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
484*4882a593Smuzhiyun totalSize = baseSize + global_keys[type].offset;
485*4882a593Smuzhiyun object = malloc(totalSize);
486*4882a593Smuzhiyun if (!object)
487*4882a593Smuzhiyun return NULL;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun memset(object, '\0', clear);
490*4882a593Smuzhiyun privates = (PrivatePtr) (((char *) object) + baseSize);
491*4882a593Smuzhiyun devPrivates = (PrivatePtr *) ((char *) object + offset);
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun _dixInitPrivates(devPrivates, privates, type);
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun return object;
496*4882a593Smuzhiyun }
497*4882a593Smuzhiyun
498*4882a593Smuzhiyun /*
499*4882a593Smuzhiyun * Allocate privates separately from containing object.
500*4882a593Smuzhiyun * Used for clients and screens.
501*4882a593Smuzhiyun */
502*4882a593Smuzhiyun Bool
dixAllocatePrivates(PrivatePtr * privates,DevPrivateType type)503*4882a593Smuzhiyun dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun unsigned size;
506*4882a593Smuzhiyun PrivatePtr p;
507*4882a593Smuzhiyun
508*4882a593Smuzhiyun assert(type > PRIVATE_XSELINUX && type < PRIVATE_LAST);
509*4882a593Smuzhiyun assert(!screen_specific_private[type]);
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun size = global_keys[type].offset;
512*4882a593Smuzhiyun if (!size) {
513*4882a593Smuzhiyun p = NULL;
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun else {
516*4882a593Smuzhiyun if (!(p = malloc(size)))
517*4882a593Smuzhiyun return FALSE;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun _dixInitPrivates(privates, p, type);
521*4882a593Smuzhiyun ++global_keys[type].allocated;
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun return TRUE;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun /*
527*4882a593Smuzhiyun * Free an object that has privates
528*4882a593Smuzhiyun *
529*4882a593Smuzhiyun * This is expected to be invoked from the
530*4882a593Smuzhiyun * dixFreeObjectWithPrivates macro
531*4882a593Smuzhiyun */
532*4882a593Smuzhiyun void
_dixFreeObjectWithPrivates(void * object,PrivatePtr privates,DevPrivateType type)533*4882a593Smuzhiyun _dixFreeObjectWithPrivates(void *object, PrivatePtr privates,
534*4882a593Smuzhiyun DevPrivateType type)
535*4882a593Smuzhiyun {
536*4882a593Smuzhiyun _dixFiniPrivates(privates, type);
537*4882a593Smuzhiyun free(object);
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun /*
541*4882a593Smuzhiyun * Called to free screen or client privates
542*4882a593Smuzhiyun */
543*4882a593Smuzhiyun void
dixFreePrivates(PrivatePtr privates,DevPrivateType type)544*4882a593Smuzhiyun dixFreePrivates(PrivatePtr privates, DevPrivateType type)
545*4882a593Smuzhiyun {
546*4882a593Smuzhiyun _dixFiniPrivates(privates, type);
547*4882a593Smuzhiyun --global_keys[type].allocated;
548*4882a593Smuzhiyun free(privates);
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun /*
552*4882a593Smuzhiyun * Return size of privates for the specified type
553*4882a593Smuzhiyun */
554*4882a593Smuzhiyun extern _X_EXPORT int
dixPrivatesSize(DevPrivateType type)555*4882a593Smuzhiyun dixPrivatesSize(DevPrivateType type)
556*4882a593Smuzhiyun {
557*4882a593Smuzhiyun assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST);
558*4882a593Smuzhiyun assert (!screen_specific_private[type]);
559*4882a593Smuzhiyun
560*4882a593Smuzhiyun return global_keys[type].offset;
561*4882a593Smuzhiyun }
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun /* Table of devPrivates offsets */
564*4882a593Smuzhiyun static const int offsets[] = {
565*4882a593Smuzhiyun -1, /* RT_NONE */
566*4882a593Smuzhiyun offsetof(WindowRec, devPrivates), /* RT_WINDOW */
567*4882a593Smuzhiyun offsetof(PixmapRec, devPrivates), /* RT_PIXMAP */
568*4882a593Smuzhiyun offsetof(GC, devPrivates), /* RT_GC */
569*4882a593Smuzhiyun -1, /* RT_FONT */
570*4882a593Smuzhiyun offsetof(CursorRec, devPrivates), /* RT_CURSOR */
571*4882a593Smuzhiyun offsetof(ColormapRec, devPrivates), /* RT_COLORMAP */
572*4882a593Smuzhiyun };
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun int
dixLookupPrivateOffset(RESTYPE type)575*4882a593Smuzhiyun dixLookupPrivateOffset(RESTYPE type)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun /*
578*4882a593Smuzhiyun * Special kludge for DBE which registers a new resource type that
579*4882a593Smuzhiyun * points at pixmaps (thanks, DBE)
580*4882a593Smuzhiyun */
581*4882a593Smuzhiyun if (type & RC_DRAWABLE) {
582*4882a593Smuzhiyun if (type == RT_WINDOW)
583*4882a593Smuzhiyun return offsets[RT_WINDOW & TypeMask];
584*4882a593Smuzhiyun else
585*4882a593Smuzhiyun return offsets[RT_PIXMAP & TypeMask];
586*4882a593Smuzhiyun }
587*4882a593Smuzhiyun type = type & TypeMask;
588*4882a593Smuzhiyun if (type < ARRAY_SIZE(offsets))
589*4882a593Smuzhiyun return offsets[type];
590*4882a593Smuzhiyun return -1;
591*4882a593Smuzhiyun }
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun /*
594*4882a593Smuzhiyun * Screen-specific privates
595*4882a593Smuzhiyun */
596*4882a593Smuzhiyun
597*4882a593Smuzhiyun extern _X_EXPORT Bool
dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen,DevPrivateKey key,DevPrivateType type,unsigned size)598*4882a593Smuzhiyun dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
599*4882a593Smuzhiyun DevPrivateType type, unsigned size)
600*4882a593Smuzhiyun {
601*4882a593Smuzhiyun int offset;
602*4882a593Smuzhiyun unsigned bytes;
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun if (!screen_specific_private[type])
605*4882a593Smuzhiyun FatalError("Attempt to allocate screen-specific private storage for type %s\n",
606*4882a593Smuzhiyun key_names[type]);
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun if (key->initialized) {
609*4882a593Smuzhiyun assert(size == key->size);
610*4882a593Smuzhiyun return TRUE;
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun /* Compute required space */
614*4882a593Smuzhiyun bytes = size;
615*4882a593Smuzhiyun if (size == 0)
616*4882a593Smuzhiyun bytes = sizeof(void *);
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun /* align to void * size */
619*4882a593Smuzhiyun bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun assert (!allocated_early[type]);
622*4882a593Smuzhiyun assert (!pScreen->screenSpecificPrivates[type].created);
623*4882a593Smuzhiyun offset = pScreen->screenSpecificPrivates[type].offset;
624*4882a593Smuzhiyun pScreen->screenSpecificPrivates[type].offset += bytes;
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun /* Setup this key */
627*4882a593Smuzhiyun key->offset = offset;
628*4882a593Smuzhiyun key->size = size;
629*4882a593Smuzhiyun key->initialized = TRUE;
630*4882a593Smuzhiyun key->type = type;
631*4882a593Smuzhiyun key->allocated = FALSE;
632*4882a593Smuzhiyun key->next = pScreen->screenSpecificPrivates[type].key;
633*4882a593Smuzhiyun pScreen->screenSpecificPrivates[type].key = key;
634*4882a593Smuzhiyun
635*4882a593Smuzhiyun return TRUE;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun /* Clean up screen-specific privates before CloseScreen */
639*4882a593Smuzhiyun void
dixFreeScreenSpecificPrivates(ScreenPtr pScreen)640*4882a593Smuzhiyun dixFreeScreenSpecificPrivates(ScreenPtr pScreen)
641*4882a593Smuzhiyun {
642*4882a593Smuzhiyun DevPrivateType t;
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
645*4882a593Smuzhiyun DevPrivateKey key;
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun for (key = pScreen->screenSpecificPrivates[t].key; key; key = key->next) {
648*4882a593Smuzhiyun key->initialized = FALSE;
649*4882a593Smuzhiyun }
650*4882a593Smuzhiyun }
651*4882a593Smuzhiyun }
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun /* Initialize screen-specific privates in AddScreen */
654*4882a593Smuzhiyun void
dixInitScreenSpecificPrivates(ScreenPtr pScreen)655*4882a593Smuzhiyun dixInitScreenSpecificPrivates(ScreenPtr pScreen)
656*4882a593Smuzhiyun {
657*4882a593Smuzhiyun DevPrivateType t;
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++)
660*4882a593Smuzhiyun pScreen->screenSpecificPrivates[t].offset = global_keys[t].offset;
661*4882a593Smuzhiyun }
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun /* Initialize screen-specific privates in AddScreen */
664*4882a593Smuzhiyun void
_dixInitScreenPrivates(ScreenPtr pScreen,PrivatePtr * privates,void * addr,DevPrivateType type)665*4882a593Smuzhiyun _dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun int privates_size;
668*4882a593Smuzhiyun assert (screen_specific_private[type]);
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun if (pScreen) {
671*4882a593Smuzhiyun privates_size = pScreen->screenSpecificPrivates[type].offset;
672*4882a593Smuzhiyun pScreen->screenSpecificPrivates[type].created++;
673*4882a593Smuzhiyun }
674*4882a593Smuzhiyun else
675*4882a593Smuzhiyun privates_size = global_keys[type].offset;
676*4882a593Smuzhiyun
677*4882a593Smuzhiyun global_keys[type].created++;
678*4882a593Smuzhiyun if (xselinux_private[type])
679*4882a593Smuzhiyun global_keys[PRIVATE_XSELINUX].created++;
680*4882a593Smuzhiyun if (privates_size == 0)
681*4882a593Smuzhiyun addr = 0;
682*4882a593Smuzhiyun *privates = addr;
683*4882a593Smuzhiyun memset(addr, '\0', privates_size);
684*4882a593Smuzhiyun }
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun void *
_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,unsigned baseSize,unsigned clear,unsigned offset,DevPrivateType type)687*4882a593Smuzhiyun _dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
688*4882a593Smuzhiyun unsigned baseSize,
689*4882a593Smuzhiyun unsigned clear,
690*4882a593Smuzhiyun unsigned offset,
691*4882a593Smuzhiyun DevPrivateType type)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun unsigned totalSize;
694*4882a593Smuzhiyun void *object;
695*4882a593Smuzhiyun PrivatePtr privates;
696*4882a593Smuzhiyun PrivatePtr *devPrivates;
697*4882a593Smuzhiyun int privates_size;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST);
700*4882a593Smuzhiyun assert (screen_specific_private[type]);
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun if (pScreen)
703*4882a593Smuzhiyun privates_size = pScreen->screenSpecificPrivates[type].offset;
704*4882a593Smuzhiyun else
705*4882a593Smuzhiyun privates_size = global_keys[type].offset;
706*4882a593Smuzhiyun /* round up so that pointer is aligned */
707*4882a593Smuzhiyun baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
708*4882a593Smuzhiyun totalSize = baseSize + privates_size;
709*4882a593Smuzhiyun object = malloc(totalSize);
710*4882a593Smuzhiyun if (!object)
711*4882a593Smuzhiyun return NULL;
712*4882a593Smuzhiyun
713*4882a593Smuzhiyun memset(object, '\0', clear);
714*4882a593Smuzhiyun privates = (PrivatePtr) (((char *) object) + baseSize);
715*4882a593Smuzhiyun devPrivates = (PrivatePtr *) ((char *) object + offset);
716*4882a593Smuzhiyun
717*4882a593Smuzhiyun _dixInitScreenPrivates(pScreen, devPrivates, privates, type);
718*4882a593Smuzhiyun
719*4882a593Smuzhiyun return object;
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun
722*4882a593Smuzhiyun int
dixScreenSpecificPrivatesSize(ScreenPtr pScreen,DevPrivateType type)723*4882a593Smuzhiyun dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type)
724*4882a593Smuzhiyun {
725*4882a593Smuzhiyun assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST);
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun if (screen_specific_private[type])
728*4882a593Smuzhiyun return pScreen->screenSpecificPrivates[type].offset;
729*4882a593Smuzhiyun else
730*4882a593Smuzhiyun return global_keys[type].offset;
731*4882a593Smuzhiyun }
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun void
dixPrivateUsage(void)734*4882a593Smuzhiyun dixPrivateUsage(void)
735*4882a593Smuzhiyun {
736*4882a593Smuzhiyun int objects = 0;
737*4882a593Smuzhiyun int bytes = 0;
738*4882a593Smuzhiyun int alloc = 0;
739*4882a593Smuzhiyun DevPrivateType t;
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun for (t = PRIVATE_XSELINUX + 1; t < PRIVATE_LAST; t++) {
742*4882a593Smuzhiyun if (global_keys[t].offset) {
743*4882a593Smuzhiyun ErrorF
744*4882a593Smuzhiyun ("%s: %d objects of %d bytes = %d total bytes %d private allocs\n",
745*4882a593Smuzhiyun key_names[t], global_keys[t].created, global_keys[t].offset,
746*4882a593Smuzhiyun global_keys[t].created * global_keys[t].offset, global_keys[t].allocated);
747*4882a593Smuzhiyun bytes += global_keys[t].created * global_keys[t].offset;
748*4882a593Smuzhiyun objects += global_keys[t].created;
749*4882a593Smuzhiyun alloc += global_keys[t].allocated;
750*4882a593Smuzhiyun }
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun ErrorF("TOTAL: %d objects, %d bytes, %d allocs\n", objects, bytes, alloc);
753*4882a593Smuzhiyun }
754*4882a593Smuzhiyun
755*4882a593Smuzhiyun void
dixResetPrivates(void)756*4882a593Smuzhiyun dixResetPrivates(void)
757*4882a593Smuzhiyun {
758*4882a593Smuzhiyun DevPrivateType t;
759*4882a593Smuzhiyun
760*4882a593Smuzhiyun for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
761*4882a593Smuzhiyun DevPrivateKey key, next;
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun for (key = global_keys[t].key; key; key = next) {
764*4882a593Smuzhiyun next = key->next;
765*4882a593Smuzhiyun key->offset = 0;
766*4882a593Smuzhiyun key->initialized = FALSE;
767*4882a593Smuzhiyun key->size = 0;
768*4882a593Smuzhiyun key->type = 0;
769*4882a593Smuzhiyun if (key->allocated)
770*4882a593Smuzhiyun free(key);
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun if (global_keys[t].created) {
773*4882a593Smuzhiyun ErrorF("%d %ss still allocated at reset\n",
774*4882a593Smuzhiyun global_keys[t].created, key_names[t]);
775*4882a593Smuzhiyun dixPrivateUsage();
776*4882a593Smuzhiyun }
777*4882a593Smuzhiyun global_keys[t].key = NULL;
778*4882a593Smuzhiyun global_keys[t].offset = 0;
779*4882a593Smuzhiyun global_keys[t].created = 0;
780*4882a593Smuzhiyun global_keys[t].allocated = 0;
781*4882a593Smuzhiyun }
782*4882a593Smuzhiyun }
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun Bool
dixPrivatesCreated(DevPrivateType type)785*4882a593Smuzhiyun dixPrivatesCreated(DevPrivateType type)
786*4882a593Smuzhiyun {
787*4882a593Smuzhiyun if (global_keys[type].created)
788*4882a593Smuzhiyun return TRUE;
789*4882a593Smuzhiyun else
790*4882a593Smuzhiyun return FALSE;
791*4882a593Smuzhiyun }
792