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