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 37 /* These cannot have any objects before all relevant keys are registered */ 38 PRIVATE_DEVICE, 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_DBE_WINDOW, 50 PRIVATE_DAMAGE, 51 PRIVATE_GLYPH, 52 PRIVATE_GLYPHSET, 53 PRIVATE_PICTURE, 54 PRIVATE_SYNC_FENCE, 55 56 /* last private type */ 57 PRIVATE_LAST, 58} DevPrivateType; 59 60typedef struct _DevPrivateKeyRec { 61 int offset; 62 int size; 63 Bool initialized; 64 Bool allocated; 65 DevPrivateType type; 66 struct _DevPrivateKeyRec *next; 67} DevPrivateKeyRec, *DevPrivateKey; 68 69typedef struct _DevScreenPrivateKeyRec { 70 DevPrivateKeyRec screenKey; 71} DevScreenPrivateKeyRec, *DevScreenPrivateKey; 72 73/* 74 * Let drivers know how to initialize private keys 75 */ 76 77#define HAS_DEVPRIVATEKEYREC 1 78#define HAS_DIXREGISTERPRIVATEKEY 1 79 80/* 81 * Register a new private index for the private type. 82 * 83 * This initializes the specified key and optionally requests pre-allocated 84 * private space for your driver/module. If you request no extra space, you 85 * may set and get a single pointer value using this private key. Otherwise, 86 * you can get the address of the extra space and store whatever data you like 87 * there. 88 * 89 * You may call dixRegisterPrivateKey more than once on the same key, but the 90 * size and type must match or the server will abort. 91 * 92 * dixRegisterPrivateKey returns FALSE if it fails to allocate memory 93 * during its operation. 94 */ 95extern _X_EXPORT Bool 96dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size); 97 98/* 99 * Check whether a private key has been registered 100 */ 101static inline Bool 102dixPrivateKeyRegistered(DevPrivateKey key) 103{ 104 return key->initialized; 105} 106 107/* 108 * Get the address of the private storage. 109 * 110 * For keys with pre-defined storage, this gets the base of that storage 111 * Otherwise, it returns the place where the private pointer is stored. 112 */ 113static inline void * 114dixGetPrivateAddr(PrivatePtr *privates, const DevPrivateKey key) 115{ 116 assert(key->initialized); 117 return (char *) (*privates) + key->offset; 118} 119 120/* 121 * Fetch a private pointer stored in the object 122 * 123 * Returns the pointer stored with dixSetPrivate. 124 * This must only be used with keys that have 125 * no pre-defined storage 126 */ 127static inline void * 128dixGetPrivate(PrivatePtr *privates, const DevPrivateKey key) 129{ 130 assert (key->size == 0); 131 return *(void **) dixGetPrivateAddr(privates, key); 132} 133 134/* 135 * Associate 'val' with 'key' in 'privates' so that later calls to 136 * dixLookupPrivate(privates, key) will return 'val'. 137 */ 138static inline void 139dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val) 140{ 141 assert (key->size == 0); 142 *(pointer *) dixGetPrivateAddr(privates, key) = val; 143} 144 145#include "dix.h" 146#include "resource.h" 147 148/* 149 * Lookup a pointer to the private record. 150 * 151 * For privates with defined storage, return the address of the 152 * storage. For privates without defined storage, return the pointer 153 * contents 154 */ 155static inline pointer 156dixLookupPrivate(PrivatePtr *privates, const DevPrivateKey key) 157{ 158 if (key->size) 159 return dixGetPrivateAddr(privates, key); 160 else 161 return dixGetPrivate(privates, key); 162} 163 164/* 165 * Look up the address of the pointer to the storage 166 * 167 * This returns the place where the private pointer is stored, 168 * which is only valid for privates without predefined storage. 169 */ 170static inline pointer * 171dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key) 172{ 173 assert (key->size == 0); 174 return (pointer *)dixGetPrivateAddr(privates, key); 175} 176 177extern _X_EXPORT Bool 178dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, DevPrivateType type, unsigned size); 179 180extern _X_EXPORT DevPrivateKey 181_dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen); 182 183static inline void * 184dixGetScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) 185{ 186 return dixGetPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen)); 187} 188 189static inline void * 190dixGetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) 191{ 192 return dixGetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen)); 193} 194 195static inline void 196dixSetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen, pointer val) 197{ 198 dixSetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen), val); 199} 200 201static inline pointer 202dixLookupScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) 203{ 204 return dixLookupPrivate(privates, _dixGetScreenPrivateKey(key, pScreen)); 205} 206 207static inline pointer * 208dixLookupScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, ScreenPtr pScreen) 209{ 210 return dixLookupPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen)); 211} 212 213/* 214 * Allocates private data separately from main object. 215 * 216 * For objects created during server initialization, this allows those 217 * privates to be re-allocated as new private keys are registered. 218 * 219 * This includes screens, the serverClient, default colormaps and 220 * extensions entries. 221 */ 222extern _X_EXPORT Bool 223dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type); 224 225/* 226 * Frees separately allocated private data 227 */ 228extern _X_EXPORT void 229dixFreePrivates(PrivatePtr privates, DevPrivateType type); 230 231/* 232 * Initialize privates by zeroing them 233 */ 234extern _X_EXPORT void 235_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type); 236 237#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type); 238 239/* 240 * Clean up privates 241 */ 242extern _X_EXPORT void 243_dixFiniPrivates(PrivatePtr privates, DevPrivateType type); 244 245#define dixFiniPrivates(o,t) _dixFiniPrivates((o)->devPrivates,t) 246 247/* 248 * Allocates private data at object creation time. Required 249 * for almost all objects, except for the list described 250 * above for dixAllocatePrivates. 251 */ 252extern _X_EXPORT void * 253_dixAllocateObjectWithPrivates(unsigned size, unsigned clear, unsigned offset, DevPrivateType type); 254 255#define dixAllocateObjectWithPrivates(t, type) (t *) _dixAllocateObjectWithPrivates(sizeof(t), sizeof(t), offsetof(t, devPrivates), type) 256 257extern _X_EXPORT void 258_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, DevPrivateType type); 259 260#define dixFreeObjectWithPrivates(o,t) _dixFreeObjectWithPrivates(o, (o)->devPrivates, t) 261 262/* 263 * Return size of privates for the specified type 264 */ 265extern _X_EXPORT int 266dixPrivatesSize(DevPrivateType type); 267 268/* 269 * Dump out private stats to ErrorF 270 */ 271extern void 272dixPrivateUsage(void); 273 274/* 275 * Resets the privates subsystem. dixResetPrivates is called from the main loop 276 * before each server generation. This function must only be called by main(). 277 */ 278extern _X_EXPORT void 279dixResetPrivates(void); 280 281/* 282 * Looks up the offset where the devPrivates field is located. 283 * 284 * Returns -1 if the specified resource has no dev privates. 285 * The position of the devPrivates field varies by structure 286 * and calling code might only know the resource type, not the 287 * structure definition. 288 */ 289extern _X_EXPORT int 290dixLookupPrivateOffset(RESTYPE type); 291 292/* 293 * Convenience macro for adding an offset to an object pointer 294 * when making a call to one of the devPrivates functions 295 */ 296#define DEVPRIV_AT(ptr, offset) ((PrivatePtr *)((char *)(ptr) + offset)) 297 298#endif /* PRIVATES_H */ 299