privates.h revision 1b5d61b8
1/***********************************************************
2
3THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
6AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
7AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
8CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9
10******************************************************************/
11
12#ifndef PRIVATES_H
13#define PRIVATES_H 1
14
15#include <X11/Xdefs.h>
16#include <X11/Xosdefs.h>
17#include <X11/Xfuncproto.h>
18#include "misc.h"
19
20/*****************************************************************
21 * STUFF FOR PRIVATES
22 *****************************************************************/
23
24typedef struct _Private PrivateRec, *PrivatePtr;
25
26typedef enum {
27    /* XSELinux uses the same private keys for numerous objects */
28    PRIVATE_XSELINUX,
29
30    /* Otherwise, you get a private in just the requested structure
31     */
32    /* These can have objects created before all of the keys are registered */
33    PRIVATE_SCREEN,
34    PRIVATE_EXTENSION,
35    PRIVATE_COLORMAP,
36    PRIVATE_DEVICE,
37
38    /* These cannot have any objects before all relevant keys are registered */
39    PRIVATE_CLIENT,
40    PRIVATE_PROPERTY,
41    PRIVATE_SELECTION,
42    PRIVATE_WINDOW,
43    PRIVATE_PIXMAP,
44    PRIVATE_GC,
45    PRIVATE_CURSOR,
46    PRIVATE_CURSOR_BITS,
47
48    /* extension privates */
49    PRIVATE_GLYPH,
50    PRIVATE_GLYPHSET,
51    PRIVATE_PICTURE,
52    PRIVATE_SYNC_FENCE,
53
54    /* last private type */
55    PRIVATE_LAST,
56} DevPrivateType;
57
58typedef struct _DevPrivateKeyRec {
59    int offset;
60    int size;
61    Bool initialized;
62    Bool allocated;
63    DevPrivateType type;
64    struct _DevPrivateKeyRec *next;
65} DevPrivateKeyRec, *DevPrivateKey;
66
67typedef struct _DevPrivateSetRec {
68    DevPrivateKey key;
69    unsigned offset;
70    int created;
71    int allocated;
72} DevPrivateSetRec, *DevPrivateSetPtr;
73
74typedef struct _DevScreenPrivateKeyRec {
75    DevPrivateKeyRec screenKey;
76} DevScreenPrivateKeyRec, *DevScreenPrivateKey;
77
78/*
79 * Let drivers know how to initialize private keys
80 */
81
82#define HAS_DEVPRIVATEKEYREC		1
83#define HAS_DIXREGISTERPRIVATEKEY	1
84
85/*
86 * Register a new private index for the private type.
87 *
88 * This initializes the specified key and optionally requests pre-allocated
89 * private space for your driver/module. If you request no extra space, you
90 * may set and get a single pointer value using this private key. Otherwise,
91 * you can get the address of the extra space and store whatever data you like
92 * there.
93 *
94 * You may call dixRegisterPrivateKey more than once on the same key, but the
95 * size and type must match or the server will abort.
96 *
97 * dixRegisterPrivateKey returns FALSE if it fails to allocate memory
98 * during its operation.
99 */
100extern _X_EXPORT Bool
101 dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size);
102
103/*
104 * Check whether a private key has been registered
105 */
106static inline Bool
107dixPrivateKeyRegistered(DevPrivateKey key)
108{
109    return key->initialized;
110}
111
112/*
113 * Get the address of the private storage.
114 *
115 * For keys with pre-defined storage, this gets the base of that storage
116 * Otherwise, it returns the place where the private pointer is stored.
117 */
118static inline void *
119dixGetPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
120{
121    assert(key->initialized);
122    return (char *) (*privates) + key->offset;
123}
124
125/*
126 * Fetch a private pointer stored in the object
127 *
128 * Returns the pointer stored with dixSetPrivate.
129 * This must only be used with keys that have
130 * no pre-defined storage
131 */
132static inline void *
133dixGetPrivate(PrivatePtr *privates, const DevPrivateKey key)
134{
135    assert(key->size == 0);
136    return *(void **) dixGetPrivateAddr(privates, key);
137}
138
139/*
140 * Associate 'val' with 'key' in 'privates' so that later calls to
141 * dixLookupPrivate(privates, key) will return 'val'.
142 */
143static inline void
144dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, void *val)
145{
146    assert(key->size == 0);
147    *(void **) dixGetPrivateAddr(privates, key) = val;
148}
149
150#include "dix.h"
151#include "resource.h"
152
153/*
154 * Lookup a pointer to the private record.
155 *
156 * For privates with defined storage, return the address of the
157 * storage. For privates without defined storage, return the pointer
158 * contents
159 */
160static inline void *
161dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key)
162{
163    if (key->size)
164        return dixGetPrivateAddr(privates, key);
165    else
166        return dixGetPrivate(privates, key);
167}
168
169/*
170 * Look up the address of the pointer to the storage
171 *
172 * This returns the place where the private pointer is stored,
173 * which is only valid for privates without predefined storage.
174 */
175static inline void **
176dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
177{
178    assert(key->size == 0);
179    return (void **) dixGetPrivateAddr(privates, key);
180}
181
182extern _X_EXPORT Bool
183
184dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen,
185                            DevPrivateType type, unsigned size);
186
187extern _X_EXPORT DevPrivateKey
188 _dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen);
189
190static inline void *
191dixGetScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key,
192                        ScreenPtr pScreen)
193{
194    return dixGetPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen));
195}
196
197static inline void *
198dixGetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key,
199                    ScreenPtr pScreen)
200{
201    return dixGetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen));
202}
203
204static inline void
205dixSetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key,
206                    ScreenPtr pScreen, void *val)
207{
208    dixSetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen), val);
209}
210
211static inline void *
212dixLookupScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key,
213                       ScreenPtr pScreen)
214{
215    return dixLookupPrivate(privates, _dixGetScreenPrivateKey(key, pScreen));
216}
217
218static inline void **
219dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key,
220                           ScreenPtr pScreen)
221{
222    return dixLookupPrivateAddr(privates,
223                                _dixGetScreenPrivateKey(key, pScreen));
224}
225
226/*
227 * These functions relate to allocations related to a specific screen;
228 * space will only be available for objects allocated for use on that
229 * screen. As such, only objects which are related directly to a specific
230 * screen are candidates for allocation this way, this includes
231 * windows, pixmaps, gcs, pictures and colormaps. This key is
232 * used just like any other key using dixGetPrivate and friends.
233 *
234 * This is distinctly different from the ScreenPrivateKeys above which
235 * allocate space in global objects like cursor bits for a specific
236 * screen, allowing multiple screen-related chunks of storage in a
237 * single global object.
238 */
239
240#define HAVE_SCREEN_SPECIFIC_PRIVATE_KEYS       1
241
242extern _X_EXPORT Bool
243dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
244                                    DevPrivateType type, unsigned size);
245
246/* Clean up screen-specific privates before CloseScreen */
247extern void
248dixFreeScreenSpecificPrivates(ScreenPtr pScreen);
249
250/* Initialize screen-specific privates in AddScreen */
251extern void
252dixInitScreenSpecificPrivates(ScreenPtr pScreen);
253
254/* is this private created - so hotplug can avoid crashing */
255Bool dixPrivatesCreated(DevPrivateType type);
256
257extern _X_EXPORT void *
258_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen,
259                                     unsigned size,
260                                     unsigned clear,
261                                     unsigned offset,
262                                     DevPrivateType type);
263
264#define dixAllocateScreenObjectWithPrivates(s, t, type) _dixAllocateScreenObjectWithPrivates(s, sizeof(t), sizeof(t), offsetof(t, devPrivates), type)
265
266extern _X_EXPORT int
267dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type);
268
269extern _X_EXPORT void
270_dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type);
271
272#define dixInitScreenPrivates(s, o, v, type) _dixInitScreenPrivates(s, &(o)->devPrivates, (v), type);
273
274/*
275 * Allocates private data separately from main object.
276 *
277 * For objects created during server initialization, this allows those
278 * privates to be re-allocated as new private keys are registered.
279 *
280 * This includes screens, the serverClient, default colormaps and
281 * extensions entries.
282 */
283extern _X_EXPORT Bool
284 dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type);
285
286/*
287 * Frees separately allocated private data
288 */
289extern _X_EXPORT void
290 dixFreePrivates(PrivatePtr privates, DevPrivateType type);
291
292/*
293 * Initialize privates by zeroing them
294 */
295extern _X_EXPORT void
296_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type);
297
298#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type);
299
300/*
301 * Clean up privates
302 */
303extern _X_EXPORT void
304 _dixFiniPrivates(PrivatePtr privates, DevPrivateType type);
305
306#define dixFiniPrivates(o,t)	_dixFiniPrivates((o)->devPrivates,t)
307
308/*
309 * Allocates private data at object creation time. Required
310 * for almost all objects, except for the list described
311 * above for dixAllocatePrivates.
312 */
313extern _X_EXPORT void *_dixAllocateObjectWithPrivates(unsigned size,
314                                                      unsigned clear,
315                                                      unsigned offset,
316                                                      DevPrivateType type);
317
318#define dixAllocateObjectWithPrivates(t, type) (t *) _dixAllocateObjectWithPrivates(sizeof(t), sizeof(t), offsetof(t, devPrivates), type)
319
320extern _X_EXPORT void
321
322_dixFreeObjectWithPrivates(void *object, PrivatePtr privates,
323                           DevPrivateType type);
324
325#define dixFreeObjectWithPrivates(o,t) _dixFreeObjectWithPrivates(o, (o)->devPrivates, t)
326
327/*
328 * Return size of privates for the specified type
329 */
330extern _X_EXPORT int
331 dixPrivatesSize(DevPrivateType type);
332
333/*
334 * Dump out private stats to ErrorF
335 */
336extern void
337 dixPrivateUsage(void);
338
339/*
340 * Resets the privates subsystem.  dixResetPrivates is called from the main loop
341 * before each server generation.  This function must only be called by main().
342 */
343extern _X_EXPORT void
344 dixResetPrivates(void);
345
346/*
347 * Looks up the offset where the devPrivates field is located.
348 *
349 * Returns -1 if the specified resource has no dev privates.
350 * The position of the devPrivates field varies by structure
351 * and calling code might only know the resource type, not the
352 * structure definition.
353 */
354extern _X_EXPORT int
355 dixLookupPrivateOffset(RESTYPE type);
356
357/*
358 * Convenience macro for adding an offset to an object pointer
359 * when making a call to one of the devPrivates functions
360 */
361#define DEVPRIV_AT(ptr, offset) ((PrivatePtr *)((char *)(ptr) + offset))
362
363#endif                          /* PRIVATES_H */
364