| 1 | /*********************************************************** |
| 2 | |
| 3 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 4 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 5 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 6 | AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
| 7 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
| 8 | CONNECTION 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 | |
| 24 | typedef struct _Private PrivateRec, *PrivatePtr; |
| 25 | |
| 26 | typedef 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 | |
| 59 | typedef 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 | |
| 68 | typedef struct _DevPrivateSetRec { |
| 69 | DevPrivateKey key; |
| 70 | unsigned offset; |
| 71 | int created; |
| 72 | int allocated; |
| 73 | } DevPrivateSetRec, *DevPrivateSetPtr; |
| 74 | |
| 75 | typedef 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 | */ |
| 101 | extern _X_EXPORT Bool |
| 102 | dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size); |
| 103 | |
| 104 | /* |
| 105 | * Check whether a private key has been registered |
| 106 | */ |
| 107 | static inline Bool |
| 108 | dixPrivateKeyRegistered(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 | */ |
| 119 | static inline void * |
| 120 | dixGetPrivateAddr(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 | */ |
| 133 | static inline void * |
| 134 | dixGetPrivate(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 | */ |
| 144 | static inline void |
| 145 | dixSetPrivate(PrivatePtr *privates, const DevPrivateKey key, pointer val) |
| 146 | { |
| 147 | assert(key->size == 0); |
| 148 | *(pointer *) 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 | */ |
| 161 | static inline pointer |
| 162 | dixLookupPrivate(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 | */ |
| 176 | static inline pointer * |
| 177 | dixLookupPrivateAddr(PrivatePtr *privates, const DevPrivateKey key) |
| 178 | { |
| 179 | assert(key->size == 0); |
| 180 | return (pointer *) dixGetPrivateAddr(privates, key); |
| 181 | } |
| 182 | |
| 183 | extern _X_EXPORT Bool |
| 184 | |
| 185 | dixRegisterScreenPrivateKey(DevScreenPrivateKey key, ScreenPtr pScreen, |
| 186 | DevPrivateType type, unsigned size); |
| 187 | |
| 188 | extern _X_EXPORT DevPrivateKey |
| 189 | _dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen); |
| 190 | |
| 191 | static inline void * |
| 192 | dixGetScreenPrivateAddr(PrivatePtr *privates, const DevScreenPrivateKey key, |
| 193 | ScreenPtr pScreen) |
| 194 | { |
| 195 | return dixGetPrivateAddr(privates, _dixGetScreenPrivateKey(key, pScreen)); |
| 196 | } |
| 197 | |
| 198 | static inline void * |
| 199 | dixGetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, |
| 200 | ScreenPtr pScreen) |
| 201 | { |
| 202 | return dixGetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen)); |
| 203 | } |
| 204 | |
| 205 | static inline void |
| 206 | dixSetScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, |
| 207 | ScreenPtr pScreen, pointer val) |
| 208 | { |
| 209 | dixSetPrivate(privates, _dixGetScreenPrivateKey(key, pScreen), val); |
| 210 | } |
| 211 | |
| 212 | static inline pointer |
| 213 | dixLookupScreenPrivate(PrivatePtr *privates, const DevScreenPrivateKey key, |
| 214 | ScreenPtr pScreen) |
| 215 | { |
| 216 | return dixLookupPrivate(privates, _dixGetScreenPrivateKey(key, pScreen)); |
| 217 | } |
| 218 | |
| 219 | static inline pointer * |
| 220 | dixLookupScreenPrivateAddr(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 | |
| 243 | extern _X_EXPORT Bool |
| 244 | dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, |
| 245 | DevPrivateType type, unsigned size); |
| 246 | |
| 247 | /* Clean up screen-specific privates before CloseScreen */ |
| 248 | extern void |
| 249 | dixFreeScreenSpecificPrivates(ScreenPtr pScreen); |
| 250 | |
| 251 | /* Initialize screen-specific privates in AddScreen */ |
| 252 | extern void |
| 253 | dixInitScreenSpecificPrivates(ScreenPtr pScreen); |
| 254 | |
| 255 | extern _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 | |
| 264 | extern _X_EXPORT int |
| 265 | dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type); |
| 266 | |
| 267 | extern _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 | */ |
| 281 | extern _X_EXPORT Bool |
| 282 | dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type); |
| 283 | |
| 284 | /* |
| 285 | * Frees separately allocated private data |
| 286 | */ |
| 287 | extern _X_EXPORT void |
| 288 | dixFreePrivates(PrivatePtr privates, DevPrivateType type); |
| 289 | |
| 290 | /* |
| 291 | * Initialize privates by zeroing them |
| 292 | */ |
| 293 | extern _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 | */ |
| 301 | extern _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 | */ |
| 311 | extern _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 | |
| 318 | extern _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 | */ |
| 328 | extern _X_EXPORT int |
| 329 | dixPrivatesSize(DevPrivateType type); |
| 330 | |
| 331 | /* |
| 332 | * Dump out private stats to ErrorF |
| 333 | */ |
| 334 | extern 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 | */ |
| 341 | extern _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 | */ |
| 352 | extern _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 */ |