xref: /OK3568_Linux_fs/external/xserver/dix/privates.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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