privates.h revision 35c4bbdf
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_DAMAGE, 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 255extern _X_EXPORT void * 256_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen, 257 unsigned size, 258 unsigned clear, 259 unsigned offset, 260 DevPrivateType type); 261 262#define dixAllocateScreenObjectWithPrivates(s, t, type) _dixAllocateScreenObjectWithPrivates(s, sizeof(t), sizeof(t), offsetof(t, devPrivates), type) 263 264extern _X_EXPORT int 265dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type); 266 267extern _X_EXPORT void 268_dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type); 269 270#define dixInitScreenPrivates(s, o, v, type) _dixInitScreenPrivates(s, &(o)->devPrivates, (v), type); 271 272/* 273 * Allocates private data separately from main object. 274 * 275 * For objects created during server initialization, this allows those 276 * privates to be re-allocated as new private keys are registered. 277 * 278 * This includes screens, the serverClient, default colormaps and 279 * extensions entries. 280 */ 281extern _X_EXPORT Bool 282 dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type); 283 284/* 285 * Frees separately allocated private data 286 */ 287extern _X_EXPORT void 288 dixFreePrivates(PrivatePtr privates, DevPrivateType type); 289 290/* 291 * Initialize privates by zeroing them 292 */ 293extern _X_EXPORT void 294_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type); 295 296#define dixInitPrivates(o, v, type) _dixInitPrivates(&(o)->devPrivates, (v), type); 297 298/* 299 * Clean up privates 300 */ 301extern _X_EXPORT void 302 _dixFiniPrivates(PrivatePtr privates, DevPrivateType type); 303 304#define dixFiniPrivates(o,t) _dixFiniPrivates((o)->devPrivates,t) 305 306/* 307 * Allocates private data at object creation time. Required 308 * for almost all objects, except for the list described 309 * above for dixAllocatePrivates. 310 */ 311extern _X_EXPORT void *_dixAllocateObjectWithPrivates(unsigned size, 312 unsigned clear, 313 unsigned offset, 314 DevPrivateType type); 315 316#define dixAllocateObjectWithPrivates(t, type) (t *) _dixAllocateObjectWithPrivates(sizeof(t), sizeof(t), offsetof(t, devPrivates), type) 317 318extern _X_EXPORT void 319 320_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, 321 DevPrivateType type); 322 323#define dixFreeObjectWithPrivates(o,t) _dixFreeObjectWithPrivates(o, (o)->devPrivates, t) 324 325/* 326 * Return size of privates for the specified type 327 */ 328extern _X_EXPORT int 329 dixPrivatesSize(DevPrivateType type); 330 331/* 332 * Dump out private stats to ErrorF 333 */ 334extern void 335 dixPrivateUsage(void); 336 337/* 338 * Resets the privates subsystem. dixResetPrivates is called from the main loop 339 * before each server generation. This function must only be called by main(). 340 */ 341extern _X_EXPORT void 342 dixResetPrivates(void); 343 344/* 345 * Looks up the offset where the devPrivates field is located. 346 * 347 * Returns -1 if the specified resource has no dev privates. 348 * The position of the devPrivates field varies by structure 349 * and calling code might only know the resource type, not the 350 * structure definition. 351 */ 352extern _X_EXPORT int 353 dixLookupPrivateOffset(RESTYPE type); 354 355/* 356 * Convenience macro for adding an offset to an object pointer 357 * when making a call to one of the devPrivates functions 358 */ 359#define DEVPRIV_AT(ptr, offset) ((PrivatePtr *)((char *)(ptr) + offset)) 360 361#endif /* PRIVATES_H */ 362