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