privates.c revision 1b5d61b8
1/* 2 3Copyright 1993, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28/* 29 * Copyright © 2010, Keith Packard 30 * Copyright © 2010, Jamey Sharp 31 * 32 * Permission to use, copy, modify, distribute, and sell this software and its 33 * documentation for any purpose is hereby granted without fee, provided that 34 * the above copyright notice appear in all copies and that both that copyright 35 * notice and this permission notice appear in supporting documentation, and 36 * that the name of the copyright holders not be used in advertising or 37 * publicity pertaining to distribution of the software without specific, 38 * written prior permission. The copyright holders make no representations 39 * about the suitability of this software for any purpose. It is provided "as 40 * is" without express or implied warranty. 41 * 42 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 43 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 44 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 45 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 46 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 47 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 48 * OF THIS SOFTWARE. 49 */ 50 51#ifdef HAVE_DIX_CONFIG_H 52#include <dix-config.h> 53#endif 54 55#include <stddef.h> 56#include "windowstr.h" 57#include "resource.h" 58#include "privates.h" 59#include "gcstruct.h" 60#include "cursorstr.h" 61#include "colormapst.h" 62#include "inputstr.h" 63#include "scrnintstr.h" 64#include "extnsionst.h" 65#include "inputstr.h" 66 67static DevPrivateSetRec global_keys[PRIVATE_LAST]; 68 69static const Bool xselinux_private[PRIVATE_LAST] = { 70 [PRIVATE_SCREEN] = TRUE, 71 [PRIVATE_CLIENT] = TRUE, 72 [PRIVATE_WINDOW] = TRUE, 73 [PRIVATE_PIXMAP] = TRUE, 74 [PRIVATE_GC] = TRUE, 75 [PRIVATE_CURSOR] = TRUE, 76 [PRIVATE_COLORMAP] = TRUE, 77 [PRIVATE_DEVICE] = TRUE, 78 [PRIVATE_EXTENSION] = TRUE, 79 [PRIVATE_SELECTION] = TRUE, 80 [PRIVATE_PROPERTY] = TRUE, 81 [PRIVATE_PICTURE] = TRUE, 82 [PRIVATE_GLYPHSET] = TRUE, 83}; 84 85static const char *key_names[PRIVATE_LAST] = { 86 /* XSELinux uses the same private keys for numerous objects */ 87 [PRIVATE_XSELINUX] = "XSELINUX", 88 89 /* Otherwise, you get a private in just the requested structure 90 */ 91 /* These can have objects created before all of the keys are registered */ 92 [PRIVATE_SCREEN] = "SCREEN", 93 [PRIVATE_EXTENSION] = "EXTENSION", 94 [PRIVATE_COLORMAP] = "COLORMAP", 95 [PRIVATE_DEVICE] = "DEVICE", 96 97 /* These cannot have any objects before all relevant keys are registered */ 98 [PRIVATE_CLIENT] = "CLIENT", 99 [PRIVATE_PROPERTY] = "PROPERTY", 100 [PRIVATE_SELECTION] = "SELECTION", 101 [PRIVATE_WINDOW] = "WINDOW", 102 [PRIVATE_PIXMAP] = "PIXMAP", 103 [PRIVATE_GC] = "GC", 104 [PRIVATE_CURSOR] = "CURSOR", 105 [PRIVATE_CURSOR_BITS] = "CURSOR_BITS", 106 107 /* extension privates */ 108 [PRIVATE_GLYPH] = "GLYPH", 109 [PRIVATE_GLYPHSET] = "GLYPHSET", 110 [PRIVATE_PICTURE] = "PICTURE", 111 [PRIVATE_SYNC_FENCE] = "SYNC_FENCE", 112}; 113 114static const Bool screen_specific_private[PRIVATE_LAST] = { 115 [PRIVATE_SCREEN] = FALSE, 116 [PRIVATE_CLIENT] = FALSE, 117 [PRIVATE_WINDOW] = TRUE, 118 [PRIVATE_PIXMAP] = TRUE, 119 [PRIVATE_GC] = TRUE, 120 [PRIVATE_CURSOR] = FALSE, 121 [PRIVATE_COLORMAP] = FALSE, 122 [PRIVATE_DEVICE] = FALSE, 123 [PRIVATE_EXTENSION] = FALSE, 124 [PRIVATE_SELECTION] = FALSE, 125 [PRIVATE_PROPERTY] = FALSE, 126 [PRIVATE_PICTURE] = TRUE, 127 [PRIVATE_GLYPHSET] = FALSE, 128}; 129 130typedef Bool (*FixupFunc) (PrivatePtr *privates, int offset, unsigned bytes); 131 132typedef enum { FixupMove, FixupRealloc } FixupType; 133 134static Bool 135dixReallocPrivates(PrivatePtr *privates, int old_offset, unsigned bytes) 136{ 137 void *new_privates; 138 139 new_privates = realloc(*privates, old_offset + bytes); 140 if (!new_privates) 141 return FALSE; 142 memset((char *) new_privates + old_offset, '\0', bytes); 143 *privates = new_privates; 144 return TRUE; 145} 146 147static Bool 148dixMovePrivates(PrivatePtr *privates, int new_offset, unsigned bytes) 149{ 150 memmove((char *) *privates + bytes, *privates, new_offset - bytes); 151 memset(*privates, '\0', bytes); 152 return TRUE; 153} 154 155static Bool 156fixupOneScreen(ScreenPtr pScreen, FixupFunc fixup, unsigned bytes) 157{ 158 intptr_t dist; 159 char *old; 160 char *new; 161 DevPrivateKey *keyp, key; 162 DevPrivateType type; 163 int size; 164 165 old = (char *) pScreen->devPrivates; 166 size = global_keys[PRIVATE_SCREEN].offset; 167 if (!fixup (&pScreen->devPrivates, size, bytes)) 168 return FALSE; 169 170 /* Screen privates can contain screen-specific private keys 171 * for other types. When they move, the linked list we use to 172 * track them gets scrambled. Fix that by computing the change 173 * in the location of each private adjusting our linked list 174 * pointers to match 175 */ 176 177 new = (char *) pScreen->devPrivates; 178 179 /* Moving means everyone shifts up in the privates by 'bytes' amount, 180 * realloc means the base pointer moves 181 */ 182 if (fixup == dixMovePrivates) 183 new += bytes; 184 185 dist = new - old; 186 187 if (dist) { 188 for (type = PRIVATE_XSELINUX; type < PRIVATE_LAST; type++) 189 190 /* Walk the privates list, being careful as the 191 * pointers are scrambled before we patch them. 192 */ 193 for (keyp = &pScreen->screenSpecificPrivates[type].key; 194 (key = *keyp) != NULL; 195 keyp = &key->next) 196 { 197 198 /* Only mangle things if the private structure 199 * is contained within the allocation. Privates 200 * stored elsewhere will be left alone 201 */ 202 if (old <= (char *) key && (char *) key < old + size) 203 { 204 /* Compute new location of key */ 205 key = (DevPrivateKey) ((char *) key + dist); 206 207 /* Patch the list */ 208 *keyp = key; 209 } 210 } 211 } 212 return TRUE; 213} 214 215static Bool 216fixupScreens(FixupFunc fixup, unsigned bytes) 217{ 218 int s; 219 220 for (s = 0; s < screenInfo.numScreens; s++) 221 if (!fixupOneScreen (screenInfo.screens[s], fixup, bytes)) 222 return FALSE; 223 224 for (s = 0; s < screenInfo.numGPUScreens; s++) 225 if (!fixupOneScreen (screenInfo.gpuscreens[s], fixup, bytes)) 226 return FALSE; 227 return TRUE; 228} 229 230static Bool 231fixupServerClient(FixupFunc fixup, unsigned bytes) 232{ 233 if (serverClient) 234 return fixup(&serverClient->devPrivates, global_keys[PRIVATE_CLIENT].offset, 235 bytes); 236 return TRUE; 237} 238 239static Bool 240fixupExtensions(FixupFunc fixup, unsigned bytes) 241{ 242 unsigned char major; 243 ExtensionEntry *extension; 244 245 for (major = EXTENSION_BASE; (extension = GetExtensionEntry(major)); 246 major++) 247 if (!fixup 248 (&extension->devPrivates, global_keys[PRIVATE_EXTENSION].offset, bytes)) 249 return FALSE; 250 return TRUE; 251} 252 253static Bool 254fixupDefaultColormaps(FixupFunc fixup, unsigned bytes) 255{ 256 int s; 257 258 for (s = 0; s < screenInfo.numScreens; s++) { 259 ColormapPtr cmap; 260 261 dixLookupResourceByType((void **) &cmap, 262 screenInfo.screens[s]->defColormap, RT_COLORMAP, 263 serverClient, DixCreateAccess); 264 if (cmap && 265 !fixup(&cmap->devPrivates, screenInfo.screens[s]->screenSpecificPrivates[PRIVATE_COLORMAP].offset, bytes)) 266 return FALSE; 267 } 268 return TRUE; 269} 270 271static Bool 272fixupDeviceList(DeviceIntPtr device, FixupFunc fixup, unsigned bytes) 273{ 274 while (device) { 275 if (!fixup(&device->devPrivates, global_keys[PRIVATE_DEVICE].offset, bytes)) 276 return FALSE; 277 device = device->next; 278 } 279 return TRUE; 280} 281 282static Bool 283fixupDevices(FixupFunc fixup, unsigned bytes) 284{ 285 return (fixupDeviceList(inputInfo.devices, fixup, bytes) && 286 fixupDeviceList(inputInfo.off_devices, fixup, bytes)); 287} 288 289static Bool (*const allocated_early[PRIVATE_LAST]) (FixupFunc, unsigned) = { 290 [PRIVATE_SCREEN] = fixupScreens, 291 [PRIVATE_CLIENT] = fixupServerClient, 292 [PRIVATE_EXTENSION] = fixupExtensions, 293 [PRIVATE_COLORMAP] = fixupDefaultColormaps, 294 [PRIVATE_DEVICE] = fixupDevices, 295}; 296 297static void 298grow_private_set(DevPrivateSetPtr set, unsigned bytes) 299{ 300 DevPrivateKey k; 301 302 for (k = set->key; k; k = k->next) 303 k->offset += bytes; 304 set->offset += bytes; 305} 306 307static void 308grow_screen_specific_set(DevPrivateType type, unsigned bytes) 309{ 310 int s; 311 312 /* Update offsets for all screen-specific keys */ 313 for (s = 0; s < screenInfo.numScreens; s++) { 314 ScreenPtr pScreen = screenInfo.screens[s]; 315 316 grow_private_set(&pScreen->screenSpecificPrivates[type], bytes); 317 } 318 for (s = 0; s < screenInfo.numGPUScreens; s++) { 319 ScreenPtr pScreen = screenInfo.gpuscreens[s]; 320 321 grow_private_set(&pScreen->screenSpecificPrivates[type], bytes); 322 } 323} 324 325/* 326 * Register a private key. This takes the type of object the key will 327 * be used with, which may be PRIVATE_ALL indicating that this key 328 * will be used with all of the private objects. If 'size' is 329 * non-zero, then the specified amount of space will be allocated in 330 * the private storage. Otherwise, space for a single pointer will 331 * be allocated which can be set with dixSetPrivate 332 */ 333Bool 334dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size) 335{ 336 DevPrivateType t; 337 int offset; 338 unsigned bytes; 339 340 if (key->initialized) { 341 assert(size == key->size); 342 return TRUE; 343 } 344 345 /* Compute required space */ 346 bytes = size; 347 if (size == 0) 348 bytes = sizeof(void *); 349 350 /* align to pointer size */ 351 bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1); 352 353 /* Update offsets for all affected keys */ 354 if (type == PRIVATE_XSELINUX) { 355 356 /* Resize if we can, or make sure nothing's allocated if we can't 357 */ 358 for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) 359 if (xselinux_private[t]) { 360 if (!allocated_early[t]) 361 assert(!global_keys[t].created); 362 else if (!allocated_early[t] (dixReallocPrivates, bytes)) 363 return FALSE; 364 } 365 366 /* Move all existing keys up in the privates space to make 367 * room for this new global key 368 */ 369 for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { 370 if (xselinux_private[t]) { 371 grow_private_set(&global_keys[t], bytes); 372 grow_screen_specific_set(t, bytes); 373 if (allocated_early[t]) 374 allocated_early[t] (dixMovePrivates, bytes); 375 } 376 377 } 378 379 offset = 0; 380 } 381 else { 382 /* Resize if we can, or make sure nothing's allocated if we can't */ 383 if (!allocated_early[type]) 384 assert(!global_keys[type].created); 385 else if (!allocated_early[type] (dixReallocPrivates, bytes)) 386 return FALSE; 387 offset = global_keys[type].offset; 388 global_keys[type].offset += bytes; 389 grow_screen_specific_set(type, bytes); 390 } 391 392 /* Setup this key */ 393 key->offset = offset; 394 key->size = size; 395 key->initialized = TRUE; 396 key->type = type; 397 key->allocated = FALSE; 398 key->next = global_keys[type].key; 399 global_keys[type].key = key; 400 401 return TRUE; 402} 403 404Bool 405dixRegisterScreenPrivateKey(DevScreenPrivateKey screenKey, ScreenPtr pScreen, 406 DevPrivateType type, unsigned size) 407{ 408 DevPrivateKey key; 409 410 if (!dixRegisterPrivateKey(&screenKey->screenKey, PRIVATE_SCREEN, 0)) 411 return FALSE; 412 key = dixGetPrivate(&pScreen->devPrivates, &screenKey->screenKey); 413 if (key != NULL) { 414 assert(key->size == size); 415 assert(key->type == type); 416 return TRUE; 417 } 418 key = calloc(sizeof(DevPrivateKeyRec), 1); 419 if (!key) 420 return FALSE; 421 if (!dixRegisterPrivateKey(key, type, size)) { 422 free(key); 423 return FALSE; 424 } 425 key->allocated = TRUE; 426 dixSetPrivate(&pScreen->devPrivates, &screenKey->screenKey, key); 427 return TRUE; 428} 429 430DevPrivateKey 431_dixGetScreenPrivateKey(const DevScreenPrivateKey key, ScreenPtr pScreen) 432{ 433 return dixGetPrivate(&pScreen->devPrivates, &key->screenKey); 434} 435 436/* 437 * Initialize privates by zeroing them 438 */ 439void 440_dixInitPrivates(PrivatePtr *privates, void *addr, DevPrivateType type) 441{ 442 assert (!screen_specific_private[type]); 443 444 global_keys[type].created++; 445 if (xselinux_private[type]) 446 global_keys[PRIVATE_XSELINUX].created++; 447 if (global_keys[type].offset == 0) 448 addr = 0; 449 *privates = addr; 450 memset(addr, '\0', global_keys[type].offset); 451} 452 453/* 454 * Clean up privates 455 */ 456void 457_dixFiniPrivates(PrivatePtr privates, DevPrivateType type) 458{ 459 global_keys[type].created--; 460 if (xselinux_private[type]) 461 global_keys[PRIVATE_XSELINUX].created--; 462} 463 464/* 465 * Allocate new object with privates. 466 * 467 * This is expected to be invoked from the 468 * dixAllocateObjectWithPrivates macro 469 */ 470void * 471_dixAllocateObjectWithPrivates(unsigned baseSize, unsigned clear, 472 unsigned offset, DevPrivateType type) 473{ 474 unsigned totalSize; 475 void *object; 476 PrivatePtr privates; 477 PrivatePtr *devPrivates; 478 479 assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST); 480 assert(!screen_specific_private[type]); 481 482 /* round up so that void * is aligned */ 483 baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1); 484 totalSize = baseSize + global_keys[type].offset; 485 object = malloc(totalSize); 486 if (!object) 487 return NULL; 488 489 memset(object, '\0', clear); 490 privates = (PrivatePtr) (((char *) object) + baseSize); 491 devPrivates = (PrivatePtr *) ((char *) object + offset); 492 493 _dixInitPrivates(devPrivates, privates, type); 494 495 return object; 496} 497 498/* 499 * Allocate privates separately from containing object. 500 * Used for clients and screens. 501 */ 502Bool 503dixAllocatePrivates(PrivatePtr *privates, DevPrivateType type) 504{ 505 unsigned size; 506 PrivatePtr p; 507 508 assert(type > PRIVATE_XSELINUX && type < PRIVATE_LAST); 509 assert(!screen_specific_private[type]); 510 511 size = global_keys[type].offset; 512 if (!size) { 513 p = NULL; 514 } 515 else { 516 if (!(p = malloc(size))) 517 return FALSE; 518 } 519 520 _dixInitPrivates(privates, p, type); 521 ++global_keys[type].allocated; 522 523 return TRUE; 524} 525 526/* 527 * Free an object that has privates 528 * 529 * This is expected to be invoked from the 530 * dixFreeObjectWithPrivates macro 531 */ 532void 533_dixFreeObjectWithPrivates(void *object, PrivatePtr privates, 534 DevPrivateType type) 535{ 536 _dixFiniPrivates(privates, type); 537 free(object); 538} 539 540/* 541 * Called to free screen or client privates 542 */ 543void 544dixFreePrivates(PrivatePtr privates, DevPrivateType type) 545{ 546 _dixFiniPrivates(privates, type); 547 --global_keys[type].allocated; 548 free(privates); 549} 550 551/* 552 * Return size of privates for the specified type 553 */ 554extern _X_EXPORT int 555dixPrivatesSize(DevPrivateType type) 556{ 557 assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST); 558 assert (!screen_specific_private[type]); 559 560 return global_keys[type].offset; 561} 562 563/* Table of devPrivates offsets */ 564static const int offsets[] = { 565 -1, /* RT_NONE */ 566 offsetof(WindowRec, devPrivates), /* RT_WINDOW */ 567 offsetof(PixmapRec, devPrivates), /* RT_PIXMAP */ 568 offsetof(GC, devPrivates), /* RT_GC */ 569 -1, /* RT_FONT */ 570 offsetof(CursorRec, devPrivates), /* RT_CURSOR */ 571 offsetof(ColormapRec, devPrivates), /* RT_COLORMAP */ 572}; 573 574int 575dixLookupPrivateOffset(RESTYPE type) 576{ 577 /* 578 * Special kludge for DBE which registers a new resource type that 579 * points at pixmaps (thanks, DBE) 580 */ 581 if (type & RC_DRAWABLE) { 582 if (type == RT_WINDOW) 583 return offsets[RT_WINDOW & TypeMask]; 584 else 585 return offsets[RT_PIXMAP & TypeMask]; 586 } 587 type = type & TypeMask; 588 if (type < ARRAY_SIZE(offsets)) 589 return offsets[type]; 590 return -1; 591} 592 593/* 594 * Screen-specific privates 595 */ 596 597extern _X_EXPORT Bool 598dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key, 599 DevPrivateType type, unsigned size) 600{ 601 int offset; 602 unsigned bytes; 603 604 if (!screen_specific_private[type]) 605 FatalError("Attempt to allocate screen-specific private storage for type %s\n", 606 key_names[type]); 607 608 if (key->initialized) { 609 assert(size == key->size); 610 return TRUE; 611 } 612 613 /* Compute required space */ 614 bytes = size; 615 if (size == 0) 616 bytes = sizeof(void *); 617 618 /* align to void * size */ 619 bytes = (bytes + sizeof(void *) - 1) & ~(sizeof(void *) - 1); 620 621 assert (!allocated_early[type]); 622 assert (!pScreen->screenSpecificPrivates[type].created); 623 offset = pScreen->screenSpecificPrivates[type].offset; 624 pScreen->screenSpecificPrivates[type].offset += bytes; 625 626 /* Setup this key */ 627 key->offset = offset; 628 key->size = size; 629 key->initialized = TRUE; 630 key->type = type; 631 key->allocated = FALSE; 632 key->next = pScreen->screenSpecificPrivates[type].key; 633 pScreen->screenSpecificPrivates[type].key = key; 634 635 return TRUE; 636} 637 638/* Clean up screen-specific privates before CloseScreen */ 639void 640dixFreeScreenSpecificPrivates(ScreenPtr pScreen) 641{ 642 DevPrivateType t; 643 644 for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { 645 DevPrivateKey key; 646 647 for (key = pScreen->screenSpecificPrivates[t].key; key; key = key->next) { 648 key->initialized = FALSE; 649 } 650 } 651} 652 653/* Initialize screen-specific privates in AddScreen */ 654void 655dixInitScreenSpecificPrivates(ScreenPtr pScreen) 656{ 657 DevPrivateType t; 658 659 for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) 660 pScreen->screenSpecificPrivates[t].offset = global_keys[t].offset; 661} 662 663/* Initialize screen-specific privates in AddScreen */ 664void 665_dixInitScreenPrivates(ScreenPtr pScreen, PrivatePtr *privates, void *addr, DevPrivateType type) 666{ 667 int privates_size; 668 assert (screen_specific_private[type]); 669 670 if (pScreen) { 671 privates_size = pScreen->screenSpecificPrivates[type].offset; 672 pScreen->screenSpecificPrivates[type].created++; 673 } 674 else 675 privates_size = global_keys[type].offset; 676 677 global_keys[type].created++; 678 if (xselinux_private[type]) 679 global_keys[PRIVATE_XSELINUX].created++; 680 if (privates_size == 0) 681 addr = 0; 682 *privates = addr; 683 memset(addr, '\0', privates_size); 684} 685 686void * 687_dixAllocateScreenObjectWithPrivates(ScreenPtr pScreen, 688 unsigned baseSize, 689 unsigned clear, 690 unsigned offset, 691 DevPrivateType type) 692{ 693 unsigned totalSize; 694 void *object; 695 PrivatePtr privates; 696 PrivatePtr *devPrivates; 697 int privates_size; 698 699 assert(type > PRIVATE_SCREEN && type < PRIVATE_LAST); 700 assert (screen_specific_private[type]); 701 702 if (pScreen) 703 privates_size = pScreen->screenSpecificPrivates[type].offset; 704 else 705 privates_size = global_keys[type].offset; 706 /* round up so that pointer is aligned */ 707 baseSize = (baseSize + sizeof(void *) - 1) & ~(sizeof(void *) - 1); 708 totalSize = baseSize + privates_size; 709 object = malloc(totalSize); 710 if (!object) 711 return NULL; 712 713 memset(object, '\0', clear); 714 privates = (PrivatePtr) (((char *) object) + baseSize); 715 devPrivates = (PrivatePtr *) ((char *) object + offset); 716 717 _dixInitScreenPrivates(pScreen, devPrivates, privates, type); 718 719 return object; 720} 721 722int 723dixScreenSpecificPrivatesSize(ScreenPtr pScreen, DevPrivateType type) 724{ 725 assert(type >= PRIVATE_SCREEN && type < PRIVATE_LAST); 726 727 if (screen_specific_private[type]) 728 return pScreen->screenSpecificPrivates[type].offset; 729 else 730 return global_keys[type].offset; 731} 732 733void 734dixPrivateUsage(void) 735{ 736 int objects = 0; 737 int bytes = 0; 738 int alloc = 0; 739 DevPrivateType t; 740 741 for (t = PRIVATE_XSELINUX + 1; t < PRIVATE_LAST; t++) { 742 if (global_keys[t].offset) { 743 ErrorF 744 ("%s: %d objects of %d bytes = %d total bytes %d private allocs\n", 745 key_names[t], global_keys[t].created, global_keys[t].offset, 746 global_keys[t].created * global_keys[t].offset, global_keys[t].allocated); 747 bytes += global_keys[t].created * global_keys[t].offset; 748 objects += global_keys[t].created; 749 alloc += global_keys[t].allocated; 750 } 751 } 752 ErrorF("TOTAL: %d objects, %d bytes, %d allocs\n", objects, bytes, alloc); 753} 754 755void 756dixResetPrivates(void) 757{ 758 DevPrivateType t; 759 760 for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) { 761 DevPrivateKey key, next; 762 763 for (key = global_keys[t].key; key; key = next) { 764 next = key->next; 765 key->offset = 0; 766 key->initialized = FALSE; 767 key->size = 0; 768 key->type = 0; 769 if (key->allocated) 770 free(key); 771 } 772 if (global_keys[t].created) { 773 ErrorF("%d %ss still allocated at reset\n", 774 global_keys[t].created, key_names[t]); 775 dixPrivateUsage(); 776 } 777 global_keys[t].key = NULL; 778 global_keys[t].offset = 0; 779 global_keys[t].created = 0; 780 global_keys[t].allocated = 0; 781 } 782} 783 784Bool 785dixPrivatesCreated(DevPrivateType type) 786{ 787 if (global_keys[type].created) 788 return TRUE; 789 else 790 return FALSE; 791} 792