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