damageext.c (21376B)
1 /* 2 * Copyright © 2002 Keith Packard 3 * Copyright 2013 Red Hat, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Keith Packard not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Keith Packard makes no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24 #ifdef HAVE_DIX_CONFIG_H 25 #include <dix-config.h> 26 #endif 27 28 #include "damageextint.h" 29 #include "damagestr.h" 30 #include "protocol-versions.h" 31 #include "extinit.h" 32 33 #ifdef PANORAMIX 34 #include "panoramiX.h" 35 #include "panoramiXsrv.h" 36 37 typedef struct { 38 DamageExtPtr ext; 39 DamagePtr damage[MAXSCREENS]; 40 } PanoramiXDamageRes; 41 42 static RESTYPE XRT_DAMAGE; 43 static int (*PanoramiXSaveDamageCreate) (ClientPtr); 44 45 #endif 46 47 static unsigned char DamageReqCode; 48 static int DamageEventBase; 49 static RESTYPE DamageExtType; 50 51 static DevPrivateKeyRec DamageClientPrivateKeyRec; 52 53 #define DamageClientPrivateKey (&DamageClientPrivateKeyRec) 54 55 static void 56 DamageNoteCritical(ClientPtr pClient) 57 { 58 DamageClientPtr pDamageClient = GetDamageClient(pClient); 59 60 /* Composite extension marks clients with manual Subwindows as critical */ 61 if (pDamageClient->critical > 0) { 62 SetCriticalOutputPending(); 63 pClient->smart_priority = SMART_MAX_PRIORITY; 64 } 65 } 66 67 static void 68 damageGetGeometry(DrawablePtr draw, int *x, int *y, int *w, int *h) 69 { 70 #ifdef PANORAMIX 71 if (!noPanoramiXExtension && draw->type == DRAWABLE_WINDOW) { 72 WindowPtr win = (WindowPtr)draw; 73 74 if (!win->parent) { 75 *x = screenInfo.x; 76 *y = screenInfo.y; 77 *w = screenInfo.width; 78 *h = screenInfo.height; 79 return; 80 } 81 } 82 #endif 83 84 *x = draw->x; 85 *y = draw->y; 86 *w = draw->width; 87 *h = draw->height; 88 } 89 90 static void 91 DamageExtNotify(DamageExtPtr pDamageExt, BoxPtr pBoxes, int nBoxes) 92 { 93 ClientPtr pClient = pDamageExt->pClient; 94 DrawablePtr pDrawable = pDamageExt->pDrawable; 95 xDamageNotifyEvent ev; 96 int i, x, y, w, h; 97 98 damageGetGeometry(pDrawable, &x, &y, &w, &h); 99 100 UpdateCurrentTimeIf(); 101 ev = (xDamageNotifyEvent) { 102 .type = DamageEventBase + XDamageNotify, 103 .level = pDamageExt->level, 104 .drawable = pDamageExt->drawable, 105 .damage = pDamageExt->id, 106 .timestamp = currentTime.milliseconds, 107 .geometry.x = x, 108 .geometry.y = y, 109 .geometry.width = w, 110 .geometry.height = h 111 }; 112 if (pBoxes) { 113 for (i = 0; i < nBoxes; i++) { 114 ev.level = pDamageExt->level; 115 if (i < nBoxes - 1) 116 ev.level |= DamageNotifyMore; 117 ev.area.x = pBoxes[i].x1; 118 ev.area.y = pBoxes[i].y1; 119 ev.area.width = pBoxes[i].x2 - pBoxes[i].x1; 120 ev.area.height = pBoxes[i].y2 - pBoxes[i].y1; 121 WriteEventsToClient(pClient, 1, (xEvent *) &ev); 122 } 123 } 124 else { 125 ev.area.x = 0; 126 ev.area.y = 0; 127 ev.area.width = w; 128 ev.area.height = h; 129 WriteEventsToClient(pClient, 1, (xEvent *) &ev); 130 } 131 132 DamageNoteCritical(pClient); 133 } 134 135 static void 136 DamageExtReport(DamagePtr pDamage, RegionPtr pRegion, void *closure) 137 { 138 DamageExtPtr pDamageExt = closure; 139 140 switch (pDamageExt->level) { 141 case DamageReportRawRegion: 142 case DamageReportDeltaRegion: 143 DamageExtNotify(pDamageExt, RegionRects(pRegion), 144 RegionNumRects(pRegion)); 145 break; 146 case DamageReportBoundingBox: 147 DamageExtNotify(pDamageExt, RegionExtents(pRegion), 1); 148 break; 149 case DamageReportNonEmpty: 150 DamageExtNotify(pDamageExt, NullBox, 0); 151 break; 152 case DamageReportNone: 153 break; 154 } 155 } 156 157 static void 158 DamageExtDestroy(DamagePtr pDamage, void *closure) 159 { 160 DamageExtPtr pDamageExt = closure; 161 162 pDamageExt->pDamage = 0; 163 if (pDamageExt->id) 164 FreeResource(pDamageExt->id, RT_NONE); 165 } 166 167 void 168 DamageExtSetCritical(ClientPtr pClient, Bool critical) 169 { 170 DamageClientPtr pDamageClient = GetDamageClient(pClient); 171 172 if (pDamageClient) 173 pDamageClient->critical += critical ? 1 : -1; 174 } 175 176 static int 177 ProcDamageQueryVersion(ClientPtr client) 178 { 179 DamageClientPtr pDamageClient = GetDamageClient(client); 180 xDamageQueryVersionReply rep = { 181 .type = X_Reply, 182 .sequenceNumber = client->sequence, 183 .length = 0 184 }; 185 186 REQUEST(xDamageQueryVersionReq); 187 188 REQUEST_SIZE_MATCH(xDamageQueryVersionReq); 189 190 if (stuff->majorVersion < SERVER_DAMAGE_MAJOR_VERSION) { 191 rep.majorVersion = stuff->majorVersion; 192 rep.minorVersion = stuff->minorVersion; 193 } 194 else { 195 rep.majorVersion = SERVER_DAMAGE_MAJOR_VERSION; 196 if (stuff->majorVersion == SERVER_DAMAGE_MAJOR_VERSION && 197 stuff->minorVersion < SERVER_DAMAGE_MINOR_VERSION) 198 rep.minorVersion = stuff->minorVersion; 199 else 200 rep.minorVersion = SERVER_DAMAGE_MINOR_VERSION; 201 } 202 pDamageClient->major_version = rep.majorVersion; 203 pDamageClient->minor_version = rep.minorVersion; 204 if (client->swapped) { 205 swaps(&rep.sequenceNumber); 206 swapl(&rep.length); 207 swapl(&rep.majorVersion); 208 swapl(&rep.minorVersion); 209 } 210 WriteToClient(client, sizeof(xDamageQueryVersionReply), &rep); 211 return Success; 212 } 213 214 static void 215 DamageExtRegister(DrawablePtr pDrawable, DamagePtr pDamage, Bool report) 216 { 217 DamageSetReportAfterOp(pDamage, TRUE); 218 DamageRegister(pDrawable, pDamage); 219 220 if (report) { 221 RegionPtr pRegion = &((WindowPtr) pDrawable)->borderClip; 222 RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); 223 DamageReportDamage(pDamage, pRegion); 224 RegionTranslate(pRegion, pDrawable->x, pDrawable->y); 225 } 226 } 227 228 static DamageExtPtr 229 DamageExtCreate(DrawablePtr pDrawable, DamageReportLevel level, 230 ClientPtr client, XID id, XID drawable) 231 { 232 DamageExtPtr pDamageExt = malloc(sizeof(DamageExtRec)); 233 if (!pDamageExt) 234 return NULL; 235 236 pDamageExt->id = id; 237 pDamageExt->drawable = drawable; 238 pDamageExt->pDrawable = pDrawable; 239 pDamageExt->level = level; 240 pDamageExt->pClient = client; 241 pDamageExt->pDamage = DamageCreate(DamageExtReport, DamageExtDestroy, level, 242 FALSE, pDrawable->pScreen, pDamageExt); 243 if (!pDamageExt->pDamage) { 244 free(pDamageExt); 245 return NULL; 246 } 247 248 if (!AddResource(id, DamageExtType, (void *) pDamageExt)) 249 return NULL; 250 251 DamageExtRegister(pDrawable, pDamageExt->pDamage, 252 pDrawable->type == DRAWABLE_WINDOW); 253 254 return pDamageExt; 255 } 256 257 static DamageExtPtr 258 doDamageCreate(ClientPtr client, int *rc) 259 { 260 DrawablePtr pDrawable; 261 DamageExtPtr pDamageExt; 262 DamageReportLevel level; 263 264 REQUEST(xDamageCreateReq); 265 266 *rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 267 DixGetAttrAccess | DixReadAccess); 268 if (*rc != Success) 269 return NULL; 270 271 switch (stuff->level) { 272 case XDamageReportRawRectangles: 273 level = DamageReportRawRegion; 274 break; 275 case XDamageReportDeltaRectangles: 276 level = DamageReportDeltaRegion; 277 break; 278 case XDamageReportBoundingBox: 279 level = DamageReportBoundingBox; 280 break; 281 case XDamageReportNonEmpty: 282 level = DamageReportNonEmpty; 283 break; 284 default: 285 client->errorValue = stuff->level; 286 *rc = BadValue; 287 return NULL; 288 } 289 290 pDamageExt = DamageExtCreate(pDrawable, level, client, stuff->damage, 291 stuff->drawable); 292 if (!pDamageExt) 293 *rc = BadAlloc; 294 295 return pDamageExt; 296 } 297 298 static int 299 ProcDamageCreate(ClientPtr client) 300 { 301 int rc; 302 REQUEST(xDamageCreateReq); 303 REQUEST_SIZE_MATCH(xDamageCreateReq); 304 LEGAL_NEW_RESOURCE(stuff->damage, client); 305 doDamageCreate(client, &rc); 306 return rc; 307 } 308 309 static int 310 ProcDamageDestroy(ClientPtr client) 311 { 312 REQUEST(xDamageDestroyReq); 313 DamageExtPtr pDamageExt; 314 315 REQUEST_SIZE_MATCH(xDamageDestroyReq); 316 VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); 317 FreeResource(stuff->damage, RT_NONE); 318 return Success; 319 } 320 321 #ifdef PANORAMIX 322 static RegionPtr 323 DamageExtSubtractWindowClip(DamageExtPtr pDamageExt) 324 { 325 WindowPtr win = (WindowPtr)pDamageExt->pDrawable; 326 PanoramiXRes *res = NULL; 327 RegionPtr ret; 328 int i; 329 330 if (!win->parent) 331 return &PanoramiXScreenRegion; 332 333 dixLookupResourceByType((void **)&res, win->drawable.id, XRT_WINDOW, 334 serverClient, DixReadAccess); 335 if (!res) 336 return NULL; 337 338 ret = RegionCreate(NULL, 0); 339 if (!ret) 340 return NULL; 341 342 FOR_NSCREENS_FORWARD(i) { 343 ScreenPtr screen; 344 if (Success != dixLookupWindow(&win, res->info[i].id, serverClient, 345 DixReadAccess)) 346 goto out; 347 348 screen = win->drawable.pScreen; 349 350 RegionTranslate(ret, -screen->x, -screen->y); 351 if (!RegionUnion(ret, ret, &win->borderClip)) 352 goto out; 353 RegionTranslate(ret, screen->x, screen->y); 354 } 355 356 return ret; 357 358 out: 359 RegionDestroy(ret); 360 return NULL; 361 } 362 363 static void 364 DamageExtFreeWindowClip(RegionPtr reg) 365 { 366 if (reg != &PanoramiXScreenRegion) 367 RegionDestroy(reg); 368 } 369 #endif 370 371 /* 372 * DamageSubtract intersects with borderClip, so we must reconstruct the 373 * protocol's perspective of same... 374 */ 375 static Bool 376 DamageExtSubtract(DamageExtPtr pDamageExt, const RegionPtr pRegion) 377 { 378 DamagePtr pDamage = pDamageExt->pDamage; 379 380 #ifdef PANORAMIX 381 if (!noPanoramiXExtension) { 382 RegionPtr damage = DamageRegion(pDamage); 383 RegionSubtract(damage, damage, pRegion); 384 385 if (pDamageExt->pDrawable->type == DRAWABLE_WINDOW) { 386 DrawablePtr pDraw = pDamageExt->pDrawable; 387 RegionPtr clip = DamageExtSubtractWindowClip(pDamageExt); 388 if (clip) { 389 RegionTranslate(clip, -pDraw->x, -pDraw->y); 390 RegionIntersect(damage, damage, clip); 391 RegionTranslate(clip, pDraw->x, pDraw->y); 392 DamageExtFreeWindowClip(clip); 393 } 394 } 395 396 return RegionNotEmpty(damage); 397 } 398 #endif 399 400 return DamageSubtract(pDamage, pRegion); 401 } 402 403 static int 404 ProcDamageSubtract(ClientPtr client) 405 { 406 REQUEST(xDamageSubtractReq); 407 DamageExtPtr pDamageExt; 408 RegionPtr pRepair; 409 RegionPtr pParts; 410 411 REQUEST_SIZE_MATCH(xDamageSubtractReq); 412 VERIFY_DAMAGEEXT(pDamageExt, stuff->damage, client, DixWriteAccess); 413 VERIFY_REGION_OR_NONE(pRepair, stuff->repair, client, DixWriteAccess); 414 VERIFY_REGION_OR_NONE(pParts, stuff->parts, client, DixWriteAccess); 415 416 if (pDamageExt->level != DamageReportRawRegion) { 417 DamagePtr pDamage = pDamageExt->pDamage; 418 419 if (pRepair) { 420 if (pParts) 421 RegionIntersect(pParts, DamageRegion(pDamage), pRepair); 422 if (DamageExtSubtract(pDamageExt, pRepair)) 423 DamageExtReport(pDamage, DamageRegion(pDamage), 424 (void *) pDamageExt); 425 } 426 else { 427 if (pParts) 428 RegionCopy(pParts, DamageRegion(pDamage)); 429 DamageEmpty(pDamage); 430 } 431 } 432 433 return Success; 434 } 435 436 static int 437 ProcDamageAdd(ClientPtr client) 438 { 439 REQUEST(xDamageAddReq); 440 DrawablePtr pDrawable; 441 RegionPtr pRegion; 442 int rc; 443 444 REQUEST_SIZE_MATCH(xDamageAddReq); 445 VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); 446 rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, 447 DixWriteAccess); 448 if (rc != Success) 449 return rc; 450 451 /* The region is relative to the drawable origin, so translate it out to 452 * screen coordinates like damage expects. 453 */ 454 RegionTranslate(pRegion, pDrawable->x, pDrawable->y); 455 DamageDamageRegion(pDrawable, pRegion); 456 RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y); 457 458 return Success; 459 } 460 461 /* Major version controls available requests */ 462 static const int version_requests[] = { 463 X_DamageQueryVersion, /* before client sends QueryVersion */ 464 X_DamageAdd, /* Version 1 */ 465 }; 466 467 static int (*ProcDamageVector[XDamageNumberRequests]) (ClientPtr) = { 468 /*************** Version 1 ******************/ 469 ProcDamageQueryVersion, 470 ProcDamageCreate, 471 ProcDamageDestroy, 472 ProcDamageSubtract, 473 /*************** Version 1.1 ****************/ 474 ProcDamageAdd, 475 }; 476 477 static int 478 ProcDamageDispatch(ClientPtr client) 479 { 480 REQUEST(xDamageReq); 481 DamageClientPtr pDamageClient = GetDamageClient(client); 482 483 if (pDamageClient->major_version >= ARRAY_SIZE(version_requests)) 484 return BadRequest; 485 if (stuff->damageReqType > version_requests[pDamageClient->major_version]) 486 return BadRequest; 487 return (*ProcDamageVector[stuff->damageReqType]) (client); 488 } 489 490 static int _X_COLD 491 SProcDamageQueryVersion(ClientPtr client) 492 { 493 REQUEST(xDamageQueryVersionReq); 494 495 swaps(&stuff->length); 496 REQUEST_SIZE_MATCH(xDamageQueryVersionReq); 497 swapl(&stuff->majorVersion); 498 swapl(&stuff->minorVersion); 499 return (*ProcDamageVector[stuff->damageReqType]) (client); 500 } 501 502 static int _X_COLD 503 SProcDamageCreate(ClientPtr client) 504 { 505 REQUEST(xDamageCreateReq); 506 507 swaps(&stuff->length); 508 REQUEST_SIZE_MATCH(xDamageCreateReq); 509 swapl(&stuff->damage); 510 swapl(&stuff->drawable); 511 return (*ProcDamageVector[stuff->damageReqType]) (client); 512 } 513 514 static int _X_COLD 515 SProcDamageDestroy(ClientPtr client) 516 { 517 REQUEST(xDamageDestroyReq); 518 519 swaps(&stuff->length); 520 REQUEST_SIZE_MATCH(xDamageDestroyReq); 521 swapl(&stuff->damage); 522 return (*ProcDamageVector[stuff->damageReqType]) (client); 523 } 524 525 static int _X_COLD 526 SProcDamageSubtract(ClientPtr client) 527 { 528 REQUEST(xDamageSubtractReq); 529 530 swaps(&stuff->length); 531 REQUEST_SIZE_MATCH(xDamageSubtractReq); 532 swapl(&stuff->damage); 533 swapl(&stuff->repair); 534 swapl(&stuff->parts); 535 return (*ProcDamageVector[stuff->damageReqType]) (client); 536 } 537 538 static int _X_COLD 539 SProcDamageAdd(ClientPtr client) 540 { 541 REQUEST(xDamageAddReq); 542 543 swaps(&stuff->length); 544 REQUEST_SIZE_MATCH(xDamageSubtractReq); 545 swapl(&stuff->drawable); 546 swapl(&stuff->region); 547 return (*ProcDamageVector[stuff->damageReqType]) (client); 548 } 549 550 static int (*SProcDamageVector[XDamageNumberRequests]) (ClientPtr) = { 551 /*************** Version 1 ******************/ 552 SProcDamageQueryVersion, 553 SProcDamageCreate, 554 SProcDamageDestroy, 555 SProcDamageSubtract, 556 /*************** Version 1.1 ****************/ 557 SProcDamageAdd, 558 }; 559 560 static int _X_COLD 561 SProcDamageDispatch(ClientPtr client) 562 { 563 REQUEST(xDamageReq); 564 DamageClientPtr pDamageClient = GetDamageClient(client); 565 566 if (pDamageClient->major_version >= ARRAY_SIZE(version_requests)) 567 return BadRequest; 568 if (stuff->damageReqType > version_requests[pDamageClient->major_version]) 569 return BadRequest; 570 return (*SProcDamageVector[stuff->damageReqType]) (client); 571 } 572 573 static int 574 FreeDamageExt(void *value, XID did) 575 { 576 DamageExtPtr pDamageExt = (DamageExtPtr) value; 577 578 /* 579 * Get rid of the resource table entry hanging from the window id 580 */ 581 pDamageExt->id = 0; 582 if (pDamageExt->pDamage) { 583 DamageDestroy(pDamageExt->pDamage); 584 } 585 free(pDamageExt); 586 return Success; 587 } 588 589 static void _X_COLD 590 SDamageNotifyEvent(xDamageNotifyEvent * from, xDamageNotifyEvent * to) 591 { 592 to->type = from->type; 593 cpswaps(from->sequenceNumber, to->sequenceNumber); 594 cpswapl(from->drawable, to->drawable); 595 cpswapl(from->damage, to->damage); 596 cpswaps(from->area.x, to->area.x); 597 cpswaps(from->area.y, to->area.y); 598 cpswaps(from->area.width, to->area.width); 599 cpswaps(from->area.height, to->area.height); 600 cpswaps(from->geometry.x, to->geometry.x); 601 cpswaps(from->geometry.y, to->geometry.y); 602 cpswaps(from->geometry.width, to->geometry.width); 603 cpswaps(from->geometry.height, to->geometry.height); 604 } 605 606 #ifdef PANORAMIX 607 608 static void 609 PanoramiXDamageReport(DamagePtr pDamage, RegionPtr pRegion, void *closure) 610 { 611 PanoramiXDamageRes *res = closure; 612 DamageExtPtr pDamageExt = res->ext; 613 WindowPtr pWin = (WindowPtr)pDamage->pDrawable; 614 ScreenPtr pScreen = pDamage->pScreen; 615 616 /* happens on unmap? sigh xinerama */ 617 if (RegionNil(pRegion)) 618 return; 619 620 /* translate root windows if necessary */ 621 if (!pWin->parent) 622 RegionTranslate(pRegion, pScreen->x, pScreen->y); 623 624 /* add our damage to the protocol view */ 625 DamageReportDamage(pDamageExt->pDamage, pRegion); 626 627 /* empty our view */ 628 DamageEmpty(pDamage); 629 } 630 631 static void 632 PanoramiXDamageExtDestroy(DamagePtr pDamage, void *closure) 633 { 634 PanoramiXDamageRes *damage = closure; 635 damage->damage[pDamage->pScreen->myNum] = NULL; 636 } 637 638 static int 639 PanoramiXDamageCreate(ClientPtr client) 640 { 641 PanoramiXDamageRes *damage; 642 PanoramiXRes *draw; 643 int i, rc; 644 645 REQUEST(xDamageCreateReq); 646 647 REQUEST_SIZE_MATCH(xDamageCreateReq); 648 LEGAL_NEW_RESOURCE(stuff->damage, client); 649 rc = dixLookupResourceByClass((void **)&draw, stuff->drawable, XRC_DRAWABLE, 650 client, DixGetAttrAccess | DixReadAccess); 651 if (rc != Success) 652 return rc; 653 654 if (!(damage = calloc(1, sizeof(PanoramiXDamageRes)))) 655 return BadAlloc; 656 657 if (!AddResource(stuff->damage, XRT_DAMAGE, damage)) 658 return BadAlloc; 659 660 damage->ext = doDamageCreate(client, &rc); 661 if (rc == Success && draw->type == XRT_WINDOW) { 662 FOR_NSCREENS_FORWARD(i) { 663 DrawablePtr pDrawable; 664 DamagePtr pDamage = DamageCreate(PanoramiXDamageReport, 665 PanoramiXDamageExtDestroy, 666 DamageReportRawRegion, 667 FALSE, 668 screenInfo.screens[i], 669 damage); 670 if (!pDamage) { 671 rc = BadAlloc; 672 } else { 673 damage->damage[i] = pDamage; 674 rc = dixLookupDrawable(&pDrawable, draw->info[i].id, client, 675 M_WINDOW, 676 DixGetAttrAccess | DixReadAccess); 677 } 678 if (rc != Success) 679 break; 680 681 DamageExtRegister(pDrawable, pDamage, i != 0); 682 } 683 } 684 685 if (rc != Success) 686 FreeResource(stuff->damage, RT_NONE); 687 688 return rc; 689 } 690 691 static int 692 PanoramiXDamageDelete(void *res, XID id) 693 { 694 int i; 695 PanoramiXDamageRes *damage = res; 696 697 FOR_NSCREENS_BACKWARD(i) { 698 if (damage->damage[i]) { 699 DamageDestroy(damage->damage[i]); 700 damage->damage[i] = NULL; 701 } 702 } 703 704 free(damage); 705 return 1; 706 } 707 708 void 709 PanoramiXDamageInit(void) 710 { 711 XRT_DAMAGE = CreateNewResourceType(PanoramiXDamageDelete, "XineramaDamage"); 712 if (!XRT_DAMAGE) 713 FatalError("Couldn't Xineramify Damage extension\n"); 714 715 PanoramiXSaveDamageCreate = ProcDamageVector[X_DamageCreate]; 716 ProcDamageVector[X_DamageCreate] = PanoramiXDamageCreate; 717 } 718 719 void 720 PanoramiXDamageReset(void) 721 { 722 ProcDamageVector[X_DamageCreate] = PanoramiXSaveDamageCreate; 723 } 724 725 #endif /* PANORAMIX */ 726 727 void 728 DamageExtensionInit(void) 729 { 730 ExtensionEntry *extEntry; 731 int s; 732 733 for (s = 0; s < screenInfo.numScreens; s++) 734 DamageSetup(screenInfo.screens[s]); 735 736 DamageExtType = CreateNewResourceType(FreeDamageExt, "DamageExt"); 737 if (!DamageExtType) 738 return; 739 740 if (!dixRegisterPrivateKey 741 (&DamageClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(DamageClientRec))) 742 return; 743 744 if ((extEntry = AddExtension(DAMAGE_NAME, XDamageNumberEvents, 745 XDamageNumberErrors, 746 ProcDamageDispatch, SProcDamageDispatch, 747 NULL, StandardMinorOpcode)) != 0) { 748 DamageReqCode = (unsigned char) extEntry->base; 749 DamageEventBase = extEntry->eventBase; 750 EventSwapVector[DamageEventBase + XDamageNotify] = 751 (EventSwapPtr) SDamageNotifyEvent; 752 SetResourceTypeErrorValue(DamageExtType, 753 extEntry->errorBase + BadDamage); 754 #ifdef PANORAMIX 755 if (XRT_DAMAGE) 756 SetResourceTypeErrorValue(XRT_DAMAGE, 757 extEntry->errorBase + BadDamage); 758 #endif 759 } 760 }