xf86DGA.c (59980B)
1 /* 2 * Copyright (c) 1995 Jon Tombs 3 * Copyright (c) 1995, 1996, 1999 XFree86 Inc 4 * Copyright (c) 1998-2002 by The XFree86 Project, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Except as contained in this notice, the name of the copyright holder(s) 25 * and author(s) shall not be used in advertising or otherwise to promote 26 * the sale, use or other dealings in this Software without prior written 27 * authorization from the copyright holder(s) and author(s). 28 * 29 * Written by Mark Vojkovich 30 */ 31 32 /* 33 * This is quite literally just two files glued together: 34 * hw/xfree86/common/xf86DGA.c is the first part, and 35 * hw/xfree86/dixmods/extmod/xf86dga2.c is the second part. One day, if 36 * someone actually cares about DGA, it'd be nice to clean this up. But trust 37 * me, I am not that person. 38 */ 39 40 #ifdef HAVE_XORG_CONFIG_H 41 #include <xorg-config.h> 42 #endif 43 44 #include <X11/X.h> 45 #include <X11/Xproto.h> 46 #include "xf86.h" 47 #include "xf86str.h" 48 #include "xf86Priv.h" 49 #include "dgaproc.h" 50 #include <X11/extensions/xf86dgaproto.h> 51 #include "colormapst.h" 52 #include "pixmapstr.h" 53 #include "inputstr.h" 54 #include "globals.h" 55 #include "servermd.h" 56 #include "micmap.h" 57 #include "xkbsrv.h" 58 #include "xf86Xinput.h" 59 #include "exglobals.h" 60 #include "exevents.h" 61 #include "eventstr.h" 62 #include "eventconvert.h" 63 #include "xf86Extensions.h" 64 65 #include "mi.h" 66 67 #include "misc.h" 68 #include "dixstruct.h" 69 #include "dixevents.h" 70 #include "extnsionst.h" 71 #include "cursorstr.h" 72 #include "scrnintstr.h" 73 #include "swaprep.h" 74 #include "dgaproc.h" 75 #include "protocol-versions.h" 76 77 #include <string.h> 78 79 #define DGA_PROTOCOL_OLD_SUPPORT 1 80 81 static DevPrivateKeyRec DGAScreenKeyRec; 82 83 #define DGAScreenKeyRegistered dixPrivateKeyRegistered(&DGAScreenKeyRec) 84 85 static Bool DGACloseScreen(ScreenPtr pScreen); 86 static void DGADestroyColormap(ColormapPtr pmap); 87 static void DGAInstallColormap(ColormapPtr pmap); 88 static void DGAUninstallColormap(ColormapPtr pmap); 89 static void DGAHandleEvent(int screen_num, InternalEvent *event, 90 DeviceIntPtr device); 91 92 static void 93 DGACopyModeInfo(DGAModePtr mode, XDGAModePtr xmode); 94 95 static unsigned char DGAReqCode = 0; 96 static int DGAErrorBase; 97 static int DGAEventBase; 98 99 #define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \ 100 dixLookupPrivate(&(pScreen)->devPrivates, &DGAScreenKeyRec)) 101 102 typedef struct _FakedVisualList { 103 Bool free; 104 VisualPtr pVisual; 105 struct _FakedVisualList *next; 106 } FakedVisualList; 107 108 typedef struct { 109 ScrnInfoPtr pScrn; 110 int numModes; 111 DGAModePtr modes; 112 CloseScreenProcPtr CloseScreen; 113 DestroyColormapProcPtr DestroyColormap; 114 InstallColormapProcPtr InstallColormap; 115 UninstallColormapProcPtr UninstallColormap; 116 DGADevicePtr current; 117 DGAFunctionPtr funcs; 118 int input; 119 ClientPtr client; 120 int pixmapMode; 121 FakedVisualList *fakedVisuals; 122 ColormapPtr dgaColormap; 123 ColormapPtr savedColormap; 124 Bool grabMouse; 125 Bool grabKeyboard; 126 } DGAScreenRec, *DGAScreenPtr; 127 128 Bool 129 DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, DGAModePtr modes, int num) 130 { 131 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 132 DGAScreenPtr pScreenPriv; 133 int i; 134 135 if (!funcs || !funcs->SetMode || !funcs->OpenFramebuffer) 136 return FALSE; 137 138 if (!modes || num <= 0) 139 return FALSE; 140 141 if (!dixRegisterPrivateKey(&DGAScreenKeyRec, PRIVATE_SCREEN, 0)) 142 return FALSE; 143 144 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 145 146 if (!pScreenPriv) { 147 if (!(pScreenPriv = (DGAScreenPtr) malloc(sizeof(DGAScreenRec)))) 148 return FALSE; 149 dixSetPrivate(&pScreen->devPrivates, &DGAScreenKeyRec, pScreenPriv); 150 pScreenPriv->CloseScreen = pScreen->CloseScreen; 151 pScreen->CloseScreen = DGACloseScreen; 152 pScreenPriv->DestroyColormap = pScreen->DestroyColormap; 153 pScreen->DestroyColormap = DGADestroyColormap; 154 pScreenPriv->InstallColormap = pScreen->InstallColormap; 155 pScreen->InstallColormap = DGAInstallColormap; 156 pScreenPriv->UninstallColormap = pScreen->UninstallColormap; 157 pScreen->UninstallColormap = DGAUninstallColormap; 158 } 159 160 pScreenPriv->pScrn = pScrn; 161 pScreenPriv->numModes = num; 162 pScreenPriv->modes = modes; 163 pScreenPriv->current = NULL; 164 165 pScreenPriv->funcs = funcs; 166 pScreenPriv->input = 0; 167 pScreenPriv->client = NULL; 168 pScreenPriv->fakedVisuals = NULL; 169 pScreenPriv->dgaColormap = NULL; 170 pScreenPriv->savedColormap = NULL; 171 pScreenPriv->grabMouse = FALSE; 172 pScreenPriv->grabKeyboard = FALSE; 173 174 for (i = 0; i < num; i++) 175 modes[i].num = i + 1; 176 177 #ifdef PANORAMIX 178 if (!noPanoramiXExtension) 179 for (i = 0; i < num; i++) 180 modes[i].flags &= ~DGA_PIXMAP_AVAILABLE; 181 #endif 182 183 return TRUE; 184 } 185 186 /* DGAReInitModes allows the driver to re-initialize 187 * the DGA mode list. 188 */ 189 190 Bool 191 DGAReInitModes(ScreenPtr pScreen, DGAModePtr modes, int num) 192 { 193 DGAScreenPtr pScreenPriv; 194 int i; 195 196 /* No DGA? Ignore call (but don't make it look like it failed) */ 197 if (!DGAScreenKeyRegistered) 198 return TRUE; 199 200 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 201 202 /* Same as above */ 203 if (!pScreenPriv) 204 return TRUE; 205 206 /* Can't do this while DGA is active */ 207 if (pScreenPriv->current) 208 return FALSE; 209 210 /* Quick sanity check */ 211 if (!num) 212 modes = NULL; 213 else if (!modes) 214 num = 0; 215 216 pScreenPriv->numModes = num; 217 pScreenPriv->modes = modes; 218 219 /* This practically disables DGA. So be it. */ 220 if (!num) 221 return TRUE; 222 223 for (i = 0; i < num; i++) 224 modes[i].num = i + 1; 225 226 #ifdef PANORAMIX 227 if (!noPanoramiXExtension) 228 for (i = 0; i < num; i++) 229 modes[i].flags &= ~DGA_PIXMAP_AVAILABLE; 230 #endif 231 232 return TRUE; 233 } 234 235 static void 236 FreeMarkedVisuals(ScreenPtr pScreen) 237 { 238 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 239 FakedVisualList *prev, *curr, *tmp; 240 241 if (!pScreenPriv->fakedVisuals) 242 return; 243 244 prev = NULL; 245 curr = pScreenPriv->fakedVisuals; 246 247 while (curr) { 248 if (curr->free) { 249 tmp = curr; 250 curr = curr->next; 251 if (prev) 252 prev->next = curr; 253 else 254 pScreenPriv->fakedVisuals = curr; 255 free(tmp->pVisual); 256 free(tmp); 257 } 258 else { 259 prev = curr; 260 curr = curr->next; 261 } 262 } 263 } 264 265 static Bool 266 DGACloseScreen(ScreenPtr pScreen) 267 { 268 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 269 270 mieqSetHandler(ET_DGAEvent, NULL); 271 pScreenPriv->pScrn->SetDGAMode(pScreenPriv->pScrn, 0, NULL); 272 FreeMarkedVisuals(pScreen); 273 274 pScreen->CloseScreen = pScreenPriv->CloseScreen; 275 pScreen->DestroyColormap = pScreenPriv->DestroyColormap; 276 pScreen->InstallColormap = pScreenPriv->InstallColormap; 277 pScreen->UninstallColormap = pScreenPriv->UninstallColormap; 278 279 free(pScreenPriv); 280 281 return ((*pScreen->CloseScreen) (pScreen)); 282 } 283 284 static void 285 DGADestroyColormap(ColormapPtr pmap) 286 { 287 ScreenPtr pScreen = pmap->pScreen; 288 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 289 VisualPtr pVisual = pmap->pVisual; 290 291 if (pScreenPriv->fakedVisuals) { 292 FakedVisualList *curr = pScreenPriv->fakedVisuals; 293 294 while (curr) { 295 if (curr->pVisual == pVisual) { 296 /* We can't get rid of them yet since FreeColormap 297 still needs the pVisual during the cleanup */ 298 curr->free = TRUE; 299 break; 300 } 301 curr = curr->next; 302 } 303 } 304 305 if (pScreenPriv->DestroyColormap) { 306 pScreen->DestroyColormap = pScreenPriv->DestroyColormap; 307 (*pScreen->DestroyColormap) (pmap); 308 pScreen->DestroyColormap = DGADestroyColormap; 309 } 310 } 311 312 static void 313 DGAInstallColormap(ColormapPtr pmap) 314 { 315 ScreenPtr pScreen = pmap->pScreen; 316 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 317 318 if (pScreenPriv->current && pScreenPriv->dgaColormap) { 319 if (pmap != pScreenPriv->dgaColormap) { 320 pScreenPriv->savedColormap = pmap; 321 pmap = pScreenPriv->dgaColormap; 322 } 323 } 324 325 pScreen->InstallColormap = pScreenPriv->InstallColormap; 326 (*pScreen->InstallColormap) (pmap); 327 pScreen->InstallColormap = DGAInstallColormap; 328 } 329 330 static void 331 DGAUninstallColormap(ColormapPtr pmap) 332 { 333 ScreenPtr pScreen = pmap->pScreen; 334 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 335 336 if (pScreenPriv->current && pScreenPriv->dgaColormap) { 337 if (pmap == pScreenPriv->dgaColormap) { 338 pScreenPriv->dgaColormap = NULL; 339 } 340 } 341 342 pScreen->UninstallColormap = pScreenPriv->UninstallColormap; 343 (*pScreen->UninstallColormap) (pmap); 344 pScreen->UninstallColormap = DGAUninstallColormap; 345 } 346 347 int 348 xf86SetDGAMode(ScrnInfoPtr pScrn, int num, DGADevicePtr devRet) 349 { 350 ScreenPtr pScreen = xf86ScrnToScreen(pScrn); 351 DGAScreenPtr pScreenPriv; 352 DGADevicePtr device; 353 PixmapPtr pPix = NULL; 354 DGAModePtr pMode = NULL; 355 356 /* First check if DGAInit was successful on this screen */ 357 if (!DGAScreenKeyRegistered) 358 return BadValue; 359 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 360 if (!pScreenPriv) 361 return BadValue; 362 363 if (!num) { 364 if (pScreenPriv->current) { 365 PixmapPtr oldPix = pScreenPriv->current->pPix; 366 367 if (oldPix) { 368 if (oldPix->drawable.id) 369 FreeResource(oldPix->drawable.id, RT_NONE); 370 else 371 (*pScreen->DestroyPixmap) (oldPix); 372 } 373 free(pScreenPriv->current); 374 pScreenPriv->current = NULL; 375 pScrn->vtSema = TRUE; 376 (*pScreenPriv->funcs->SetMode) (pScrn, NULL); 377 if (pScreenPriv->savedColormap) { 378 (*pScreen->InstallColormap) (pScreenPriv->savedColormap); 379 pScreenPriv->savedColormap = NULL; 380 } 381 pScreenPriv->dgaColormap = NULL; 382 (*pScrn->EnableDisableFBAccess) (pScrn, TRUE); 383 384 FreeMarkedVisuals(pScreen); 385 } 386 387 pScreenPriv->grabMouse = FALSE; 388 pScreenPriv->grabKeyboard = FALSE; 389 390 return Success; 391 } 392 393 if (!pScrn->vtSema && !pScreenPriv->current) /* Really switched away */ 394 return BadAlloc; 395 396 if ((num > 0) && (num <= pScreenPriv->numModes)) 397 pMode = &(pScreenPriv->modes[num - 1]); 398 else 399 return BadValue; 400 401 if (!(device = (DGADevicePtr) malloc(sizeof(DGADeviceRec)))) 402 return BadAlloc; 403 404 if (!pScreenPriv->current) { 405 Bool oldVTSema = pScrn->vtSema; 406 407 pScrn->vtSema = FALSE; /* kludge until we rewrite VT switching */ 408 (*pScrn->EnableDisableFBAccess) (pScrn, FALSE); 409 pScrn->vtSema = oldVTSema; 410 } 411 412 if (!(*pScreenPriv->funcs->SetMode) (pScrn, pMode)) { 413 free(device); 414 return BadAlloc; 415 } 416 417 pScrn->currentMode = pMode->mode; 418 419 if (!pScreenPriv->current && !pScreenPriv->input) { 420 /* if it's multihead we need to warp the cursor off of 421 our screen so it doesn't get trapped */ 422 } 423 424 pScrn->vtSema = FALSE; 425 426 if (pScreenPriv->current) { 427 PixmapPtr oldPix = pScreenPriv->current->pPix; 428 429 if (oldPix) { 430 if (oldPix->drawable.id) 431 FreeResource(oldPix->drawable.id, RT_NONE); 432 else 433 (*pScreen->DestroyPixmap) (oldPix); 434 } 435 free(pScreenPriv->current); 436 pScreenPriv->current = NULL; 437 } 438 439 if (pMode->flags & DGA_PIXMAP_AVAILABLE) { 440 if ((pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, pMode->depth, 0))) { 441 (*pScreen->ModifyPixmapHeader) (pPix, 442 pMode->pixmapWidth, 443 pMode->pixmapHeight, pMode->depth, 444 pMode->bitsPerPixel, 445 pMode->bytesPerScanline, 446 (void *) (pMode->address)); 447 } 448 } 449 450 devRet->mode = device->mode = pMode; 451 devRet->pPix = device->pPix = pPix; 452 pScreenPriv->current = device; 453 pScreenPriv->pixmapMode = FALSE; 454 pScreenPriv->grabMouse = TRUE; 455 pScreenPriv->grabKeyboard = TRUE; 456 457 mieqSetHandler(ET_DGAEvent, DGAHandleEvent); 458 459 return Success; 460 } 461 462 /*********** exported ones ***************/ 463 464 static void 465 DGASetInputMode(int index, Bool keyboard, Bool mouse) 466 { 467 ScreenPtr pScreen = screenInfo.screens[index]; 468 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 469 470 if (pScreenPriv) { 471 pScreenPriv->grabMouse = mouse; 472 pScreenPriv->grabKeyboard = keyboard; 473 474 mieqSetHandler(ET_DGAEvent, DGAHandleEvent); 475 } 476 } 477 478 static Bool 479 DGAChangePixmapMode(int index, int *x, int *y, int mode) 480 { 481 DGAScreenPtr pScreenPriv; 482 DGADevicePtr pDev; 483 DGAModePtr pMode; 484 PixmapPtr pPix; 485 486 if (!DGAScreenKeyRegistered) 487 return FALSE; 488 489 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 490 491 if (!pScreenPriv || !pScreenPriv->current || !pScreenPriv->current->pPix) 492 return FALSE; 493 494 pDev = pScreenPriv->current; 495 pPix = pDev->pPix; 496 pMode = pDev->mode; 497 498 if (mode) { 499 int shift = 2; 500 501 if (*x > (pMode->pixmapWidth - pMode->viewportWidth)) 502 *x = pMode->pixmapWidth - pMode->viewportWidth; 503 if (*y > (pMode->pixmapHeight - pMode->viewportHeight)) 504 *y = pMode->pixmapHeight - pMode->viewportHeight; 505 506 switch (xf86Screens[index]->bitsPerPixel) { 507 case 16: 508 shift = 1; 509 break; 510 case 32: 511 shift = 0; 512 break; 513 default: 514 break; 515 } 516 517 if (BITMAP_SCANLINE_PAD == 64) 518 shift++; 519 520 *x = (*x >> shift) << shift; 521 522 pPix->drawable.x = *x; 523 pPix->drawable.y = *y; 524 pPix->drawable.width = pMode->viewportWidth; 525 pPix->drawable.height = pMode->viewportHeight; 526 } 527 else { 528 pPix->drawable.x = 0; 529 pPix->drawable.y = 0; 530 pPix->drawable.width = pMode->pixmapWidth; 531 pPix->drawable.height = pMode->pixmapHeight; 532 } 533 pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER; 534 pScreenPriv->pixmapMode = mode; 535 536 return TRUE; 537 } 538 539 Bool 540 DGAScreenAvailable(ScreenPtr pScreen) 541 { 542 if (!DGAScreenKeyRegistered) 543 return FALSE; 544 545 if (DGA_GET_SCREEN_PRIV(pScreen)) 546 return TRUE; 547 return FALSE; 548 } 549 550 static Bool 551 DGAAvailable(int index) 552 { 553 ScreenPtr pScreen; 554 555 assert(index < MAXSCREENS); 556 pScreen = screenInfo.screens[index]; 557 return DGAScreenAvailable(pScreen); 558 } 559 560 Bool 561 DGAActive(int index) 562 { 563 DGAScreenPtr pScreenPriv; 564 565 if (!DGAScreenKeyRegistered) 566 return FALSE; 567 568 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 569 570 if (pScreenPriv && pScreenPriv->current) 571 return TRUE; 572 573 return FALSE; 574 } 575 576 /* Called by the extension to initialize a mode */ 577 578 static int 579 DGASetMode(int index, int num, XDGAModePtr mode, PixmapPtr *pPix) 580 { 581 ScrnInfoPtr pScrn = xf86Screens[index]; 582 DGADeviceRec device; 583 int ret; 584 585 /* We rely on the extension to check that DGA is available */ 586 587 ret = (*pScrn->SetDGAMode) (pScrn, num, &device); 588 if ((ret == Success) && num) { 589 DGACopyModeInfo(device.mode, mode); 590 *pPix = device.pPix; 591 } 592 593 return ret; 594 } 595 596 /* Called from the extension to let the DDX know which events are requested */ 597 598 static void 599 DGASelectInput(int index, ClientPtr client, long mask) 600 { 601 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 602 603 /* We rely on the extension to check that DGA is available */ 604 pScreenPriv->client = client; 605 pScreenPriv->input = mask; 606 } 607 608 static int 609 DGAGetViewportStatus(int index) 610 { 611 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 612 613 /* We rely on the extension to check that DGA is active */ 614 615 if (!pScreenPriv->funcs->GetViewport) 616 return 0; 617 618 return (*pScreenPriv->funcs->GetViewport) (pScreenPriv->pScrn); 619 } 620 621 static int 622 DGASetViewport(int index, int x, int y, int mode) 623 { 624 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 625 626 if (pScreenPriv->funcs->SetViewport) 627 (*pScreenPriv->funcs->SetViewport) (pScreenPriv->pScrn, x, y, mode); 628 return Success; 629 } 630 631 static int 632 BitsClear(CARD32 data) 633 { 634 int bits = 0; 635 CARD32 mask; 636 637 for (mask = 1; mask; mask <<= 1) { 638 if (!(data & mask)) 639 bits++; 640 else 641 break; 642 } 643 644 return bits; 645 } 646 647 static int 648 DGACreateColormap(int index, ClientPtr client, int id, int mode, int alloc) 649 { 650 ScreenPtr pScreen = screenInfo.screens[index]; 651 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 652 FakedVisualList *fvlp; 653 VisualPtr pVisual; 654 DGAModePtr pMode; 655 ColormapPtr pmap; 656 657 if (!mode || (mode > pScreenPriv->numModes)) 658 return BadValue; 659 660 if ((alloc != AllocNone) && (alloc != AllocAll)) 661 return BadValue; 662 663 pMode = &(pScreenPriv->modes[mode - 1]); 664 665 if (!(pVisual = malloc(sizeof(VisualRec)))) 666 return BadAlloc; 667 668 pVisual->vid = FakeClientID(0); 669 pVisual->class = pMode->visualClass; 670 pVisual->nplanes = pMode->depth; 671 pVisual->ColormapEntries = 1 << pMode->depth; 672 pVisual->bitsPerRGBValue = (pMode->depth + 2) / 3; 673 674 switch (pVisual->class) { 675 case PseudoColor: 676 case GrayScale: 677 case StaticGray: 678 pVisual->bitsPerRGBValue = 8; /* not quite */ 679 pVisual->redMask = 0; 680 pVisual->greenMask = 0; 681 pVisual->blueMask = 0; 682 pVisual->offsetRed = 0; 683 pVisual->offsetGreen = 0; 684 pVisual->offsetBlue = 0; 685 break; 686 case DirectColor: 687 case TrueColor: 688 pVisual->ColormapEntries = 1 << pVisual->bitsPerRGBValue; 689 /* fall through */ 690 case StaticColor: 691 pVisual->redMask = pMode->red_mask; 692 pVisual->greenMask = pMode->green_mask; 693 pVisual->blueMask = pMode->blue_mask; 694 pVisual->offsetRed = BitsClear(pVisual->redMask); 695 pVisual->offsetGreen = BitsClear(pVisual->greenMask); 696 pVisual->offsetBlue = BitsClear(pVisual->blueMask); 697 } 698 699 if (!(fvlp = malloc(sizeof(FakedVisualList)))) { 700 free(pVisual); 701 return BadAlloc; 702 } 703 704 fvlp->free = FALSE; 705 fvlp->pVisual = pVisual; 706 fvlp->next = pScreenPriv->fakedVisuals; 707 pScreenPriv->fakedVisuals = fvlp; 708 709 LEGAL_NEW_RESOURCE(id, client); 710 711 return CreateColormap(id, pScreen, pVisual, &pmap, alloc, client->index); 712 } 713 714 /* Called by the extension to install a colormap on DGA active screens */ 715 716 static void 717 DGAInstallCmap(ColormapPtr cmap) 718 { 719 ScreenPtr pScreen = cmap->pScreen; 720 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 721 722 /* We rely on the extension to check that DGA is active */ 723 724 if (!pScreenPriv->dgaColormap) 725 pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen); 726 727 pScreenPriv->dgaColormap = cmap; 728 729 (*pScreen->InstallColormap) (cmap); 730 } 731 732 static int 733 DGASync(int index) 734 { 735 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 736 737 /* We rely on the extension to check that DGA is active */ 738 739 if (pScreenPriv->funcs->Sync) 740 (*pScreenPriv->funcs->Sync) (pScreenPriv->pScrn); 741 742 return Success; 743 } 744 745 static int 746 DGAFillRect(int index, int x, int y, int w, int h, unsigned long color) 747 { 748 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 749 750 /* We rely on the extension to check that DGA is active */ 751 752 if (pScreenPriv->funcs->FillRect && 753 (pScreenPriv->current->mode->flags & DGA_FILL_RECT)) { 754 755 (*pScreenPriv->funcs->FillRect) (pScreenPriv->pScrn, x, y, w, h, color); 756 return Success; 757 } 758 return BadMatch; 759 } 760 761 static int 762 DGABlitRect(int index, int srcx, int srcy, int w, int h, int dstx, int dsty) 763 { 764 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 765 766 /* We rely on the extension to check that DGA is active */ 767 768 if (pScreenPriv->funcs->BlitRect && 769 (pScreenPriv->current->mode->flags & DGA_BLIT_RECT)) { 770 771 (*pScreenPriv->funcs->BlitRect) (pScreenPriv->pScrn, 772 srcx, srcy, w, h, dstx, dsty); 773 return Success; 774 } 775 return BadMatch; 776 } 777 778 static int 779 DGABlitTransRect(int index, 780 int srcx, int srcy, 781 int w, int h, int dstx, int dsty, unsigned long color) 782 { 783 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 784 785 /* We rely on the extension to check that DGA is active */ 786 787 if (pScreenPriv->funcs->BlitTransRect && 788 (pScreenPriv->current->mode->flags & DGA_BLIT_RECT_TRANS)) { 789 790 (*pScreenPriv->funcs->BlitTransRect) (pScreenPriv->pScrn, 791 srcx, srcy, w, h, dstx, dsty, 792 color); 793 return Success; 794 } 795 return BadMatch; 796 } 797 798 static int 799 DGAGetModes(int index) 800 { 801 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 802 803 /* We rely on the extension to check that DGA is available */ 804 805 return pScreenPriv->numModes; 806 } 807 808 static int 809 DGAGetModeInfo(int index, XDGAModePtr mode, int num) 810 { 811 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 812 813 /* We rely on the extension to check that DGA is available */ 814 815 if ((num <= 0) || (num > pScreenPriv->numModes)) 816 return BadValue; 817 818 DGACopyModeInfo(&(pScreenPriv->modes[num - 1]), mode); 819 820 return Success; 821 } 822 823 static void 824 DGACopyModeInfo(DGAModePtr mode, XDGAModePtr xmode) 825 { 826 DisplayModePtr dmode = mode->mode; 827 828 xmode->num = mode->num; 829 xmode->name = dmode->name; 830 xmode->VSync_num = (int) (dmode->VRefresh * 1000.0); 831 xmode->VSync_den = 1000; 832 xmode->flags = mode->flags; 833 xmode->imageWidth = mode->imageWidth; 834 xmode->imageHeight = mode->imageHeight; 835 xmode->pixmapWidth = mode->pixmapWidth; 836 xmode->pixmapHeight = mode->pixmapHeight; 837 xmode->bytesPerScanline = mode->bytesPerScanline; 838 xmode->byteOrder = mode->byteOrder; 839 xmode->depth = mode->depth; 840 xmode->bitsPerPixel = mode->bitsPerPixel; 841 xmode->red_mask = mode->red_mask; 842 xmode->green_mask = mode->green_mask; 843 xmode->blue_mask = mode->blue_mask; 844 xmode->visualClass = mode->visualClass; 845 xmode->viewportWidth = mode->viewportWidth; 846 xmode->viewportHeight = mode->viewportHeight; 847 xmode->xViewportStep = mode->xViewportStep; 848 xmode->yViewportStep = mode->yViewportStep; 849 xmode->maxViewportX = mode->maxViewportX; 850 xmode->maxViewportY = mode->maxViewportY; 851 xmode->viewportFlags = mode->viewportFlags; 852 xmode->reserved1 = mode->reserved1; 853 xmode->reserved2 = mode->reserved2; 854 xmode->offset = mode->offset; 855 856 if (dmode->Flags & V_INTERLACE) 857 xmode->flags |= DGA_INTERLACED; 858 if (dmode->Flags & V_DBLSCAN) 859 xmode->flags |= DGA_DOUBLESCAN; 860 } 861 862 Bool 863 DGAVTSwitch(void) 864 { 865 ScreenPtr pScreen; 866 int i; 867 868 for (i = 0; i < screenInfo.numScreens; i++) { 869 pScreen = screenInfo.screens[i]; 870 871 /* Alternatively, this could send events to DGA clients */ 872 873 if (DGAScreenKeyRegistered) { 874 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 875 876 if (pScreenPriv && pScreenPriv->current) 877 return FALSE; 878 } 879 } 880 881 return TRUE; 882 } 883 884 Bool 885 DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down) 886 { 887 DGAScreenPtr pScreenPriv; 888 DGAEvent event; 889 890 if (!DGAScreenKeyRegistered) /* no DGA */ 891 return FALSE; 892 893 if (key_code < 8 || key_code > 255) 894 return FALSE; 895 896 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 897 898 if (!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */ 899 return FALSE; 900 901 event = (DGAEvent) { 902 .header = ET_Internal, 903 .type = ET_DGAEvent, 904 .length = sizeof(event), 905 .time = GetTimeInMillis(), 906 .subtype = (is_down ? ET_KeyPress : ET_KeyRelease), 907 .detail = key_code, 908 .dx = 0, 909 .dy = 0 910 }; 911 mieqEnqueue(dev, (InternalEvent *) &event); 912 913 return TRUE; 914 } 915 916 Bool 917 DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy) 918 { 919 DGAScreenPtr pScreenPriv; 920 DGAEvent event; 921 922 if (!DGAScreenKeyRegistered) /* no DGA */ 923 return FALSE; 924 925 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 926 927 if (!pScreenPriv || !pScreenPriv->grabMouse) /* no direct mode */ 928 return FALSE; 929 930 event = (DGAEvent) { 931 .header = ET_Internal, 932 .type = ET_DGAEvent, 933 .length = sizeof(event), 934 .time = GetTimeInMillis(), 935 .subtype = ET_Motion, 936 .detail = 0, 937 .dx = dx, 938 .dy = dy 939 }; 940 mieqEnqueue(dev, (InternalEvent *) &event); 941 return TRUE; 942 } 943 944 Bool 945 DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down) 946 { 947 DGAScreenPtr pScreenPriv; 948 DGAEvent event; 949 950 if (!DGAScreenKeyRegistered) /* no DGA */ 951 return FALSE; 952 953 pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 954 955 if (!pScreenPriv || !pScreenPriv->grabMouse) 956 return FALSE; 957 958 event = (DGAEvent) { 959 .header = ET_Internal, 960 .type = ET_DGAEvent, 961 .length = sizeof(event), 962 .time = GetTimeInMillis(), 963 .subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease), 964 .detail = button, 965 .dx = 0, 966 .dy = 0 967 }; 968 mieqEnqueue(dev, (InternalEvent *) &event); 969 970 return TRUE; 971 } 972 973 /* We have the power to steal or modify events that are about to get queued */ 974 975 #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ 976 static Mask filters[] = { 977 NoSuchEvent, /* 0 */ 978 NoSuchEvent, /* 1 */ 979 KeyPressMask, /* KeyPress */ 980 KeyReleaseMask, /* KeyRelease */ 981 ButtonPressMask, /* ButtonPress */ 982 ButtonReleaseMask, /* ButtonRelease */ 983 PointerMotionMask, /* MotionNotify (initial state) */ 984 }; 985 986 static void 987 DGAProcessKeyboardEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr keybd) 988 { 989 KeyClassPtr keyc = keybd->key; 990 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 991 DeviceIntPtr pointer = GetMaster(keybd, POINTER_OR_FLOAT); 992 DeviceEvent ev = { 993 .header = ET_Internal, 994 .length = sizeof(ev), 995 .detail.key = event->detail, 996 .type = event->subtype, 997 .root_x = 0, 998 .root_y = 0, 999 .corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state) 1000 }; 1001 ev.corestate |= pointer->button->state; 1002 1003 UpdateDeviceState(keybd, &ev); 1004 1005 if (!IsMaster(keybd)) 1006 return; 1007 1008 /* 1009 * Deliver the DGA event 1010 */ 1011 if (pScreenPriv->client) { 1012 dgaEvent de = { 1013 .u.event.time = event->time, 1014 .u.event.dx = event->dx, 1015 .u.event.dy = event->dy, 1016 .u.event.screen = pScreen->myNum, 1017 .u.event.state = ev.corestate 1018 }; 1019 de.u.u.type = DGAEventBase + GetCoreType(ev.type); 1020 de.u.u.detail = event->detail; 1021 1022 /* If the DGA client has selected input, then deliver based on the usual filter */ 1023 TryClientEvents(pScreenPriv->client, keybd, (xEvent *) &de, 1, 1024 filters[ev.type], pScreenPriv->input, 0); 1025 } 1026 else { 1027 /* If the keyboard is actively grabbed, deliver a grabbed core event */ 1028 if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab) { 1029 ev.detail.key = event->detail; 1030 ev.time = event->time; 1031 ev.root_x = event->dx; 1032 ev.root_y = event->dy; 1033 ev.corestate = event->state; 1034 ev.deviceid = keybd->id; 1035 DeliverGrabbedEvent((InternalEvent *) &ev, keybd, FALSE); 1036 } 1037 } 1038 } 1039 1040 static void 1041 DGAProcessPointerEvent(ScreenPtr pScreen, DGAEvent * event, DeviceIntPtr mouse) 1042 { 1043 ButtonClassPtr butc = mouse->button; 1044 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 1045 DeviceIntPtr master = GetMaster(mouse, MASTER_KEYBOARD); 1046 DeviceEvent ev = { 1047 .header = ET_Internal, 1048 .length = sizeof(ev), 1049 .detail.key = event->detail, 1050 .type = event->subtype, 1051 .corestate = butc ? butc->state : 0 1052 }; 1053 1054 if (master && master->key) 1055 ev.corestate |= XkbStateFieldFromRec(&master->key->xkbInfo->state); 1056 1057 UpdateDeviceState(mouse, &ev); 1058 1059 if (!IsMaster(mouse)) 1060 return; 1061 1062 /* 1063 * Deliver the DGA event 1064 */ 1065 if (pScreenPriv->client) { 1066 int coreEquiv = GetCoreType(ev.type); 1067 dgaEvent de = { 1068 .u.event.time = event->time, 1069 .u.event.dx = event->dx, 1070 .u.event.dy = event->dy, 1071 .u.event.screen = pScreen->myNum, 1072 .u.event.state = ev.corestate 1073 }; 1074 de.u.u.type = DGAEventBase + coreEquiv; 1075 de.u.u.detail = event->detail; 1076 1077 /* If the DGA client has selected input, then deliver based on the usual filter */ 1078 TryClientEvents(pScreenPriv->client, mouse, (xEvent *) &de, 1, 1079 filters[coreEquiv], pScreenPriv->input, 0); 1080 } 1081 else { 1082 /* If the pointer is actively grabbed, deliver a grabbed core event */ 1083 if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab) { 1084 ev.detail.button = event->detail; 1085 ev.time = event->time; 1086 ev.root_x = event->dx; 1087 ev.root_y = event->dy; 1088 ev.corestate = event->state; 1089 /* DGA is core only, so valuators.data doesn't actually matter. 1090 * Mask must be set for EventToCore to create motion events. */ 1091 SetBit(ev.valuators.mask, 0); 1092 SetBit(ev.valuators.mask, 1); 1093 DeliverGrabbedEvent((InternalEvent *) &ev, mouse, FALSE); 1094 } 1095 } 1096 } 1097 1098 static Bool 1099 DGAOpenFramebuffer(int index, 1100 char **name, 1101 unsigned char **mem, int *size, int *offset, int *flags) 1102 { 1103 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 1104 1105 /* We rely on the extension to check that DGA is available */ 1106 1107 return (*pScreenPriv->funcs->OpenFramebuffer) (pScreenPriv->pScrn, 1108 name, mem, size, offset, 1109 flags); 1110 } 1111 1112 static void 1113 DGACloseFramebuffer(int index) 1114 { 1115 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 1116 1117 /* We rely on the extension to check that DGA is available */ 1118 if (pScreenPriv->funcs->CloseFramebuffer) 1119 (*pScreenPriv->funcs->CloseFramebuffer) (pScreenPriv->pScrn); 1120 } 1121 1122 /* For DGA 1.0 backwards compatibility only */ 1123 1124 static int 1125 DGAGetOldDGAMode(int index) 1126 { 1127 DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]); 1128 ScrnInfoPtr pScrn = pScreenPriv->pScrn; 1129 DGAModePtr mode; 1130 int i, w, h, p; 1131 1132 /* We rely on the extension to check that DGA is available */ 1133 1134 w = pScrn->currentMode->HDisplay; 1135 h = pScrn->currentMode->VDisplay; 1136 p = pad_to_int32(pScrn->displayWidth * bits_to_bytes(pScrn->bitsPerPixel)); 1137 1138 for (i = 0; i < pScreenPriv->numModes; i++) { 1139 mode = &(pScreenPriv->modes[i]); 1140 1141 if ((mode->viewportWidth == w) && (mode->viewportHeight == h) && 1142 (mode->bytesPerScanline == p) && 1143 (mode->bitsPerPixel == pScrn->bitsPerPixel) && 1144 (mode->depth == pScrn->depth)) { 1145 1146 return mode->num; 1147 } 1148 } 1149 1150 return 0; 1151 } 1152 1153 static void 1154 DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device) 1155 { 1156 DGAEvent *event = &ev->dga_event; 1157 ScreenPtr pScreen = screenInfo.screens[screen_num]; 1158 DGAScreenPtr pScreenPriv; 1159 1160 /* no DGA */ 1161 if (!DGAScreenKeyRegistered || noXFree86DGAExtension) 1162 return; 1163 pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen); 1164 1165 /* DGA not initialized on this screen */ 1166 if (!pScreenPriv) 1167 return; 1168 1169 switch (event->subtype) { 1170 case KeyPress: 1171 case KeyRelease: 1172 DGAProcessKeyboardEvent(pScreen, event, device); 1173 break; 1174 case MotionNotify: 1175 case ButtonPress: 1176 case ButtonRelease: 1177 DGAProcessPointerEvent(pScreen, event, device); 1178 break; 1179 default: 1180 break; 1181 } 1182 } 1183 1184 static void XDGAResetProc(ExtensionEntry * extEntry); 1185 1186 static void DGAClientStateChange(CallbackListPtr *, void *, void *); 1187 1188 static DevPrivateKeyRec DGAScreenPrivateKeyRec; 1189 1190 #define DGAScreenPrivateKey (&DGAScreenPrivateKeyRec) 1191 #define DGAScreenPrivateKeyRegistered (DGAScreenPrivateKeyRec.initialized) 1192 static DevPrivateKeyRec DGAClientPrivateKeyRec; 1193 1194 #define DGAClientPrivateKey (&DGAClientPrivateKeyRec) 1195 static int DGACallbackRefCount = 0; 1196 1197 /* This holds the client's version information */ 1198 typedef struct { 1199 int major; 1200 int minor; 1201 } DGAPrivRec, *DGAPrivPtr; 1202 1203 #define DGA_GETCLIENT(idx) ((ClientPtr) \ 1204 dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey)) 1205 #define DGA_SETCLIENT(idx,p) \ 1206 dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p) 1207 1208 #define DGA_GETPRIV(c) ((DGAPrivPtr) \ 1209 dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey)) 1210 #define DGA_SETPRIV(c,p) \ 1211 dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p) 1212 1213 static void 1214 XDGAResetProc(ExtensionEntry * extEntry) 1215 { 1216 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); 1217 DGACallbackRefCount = 0; 1218 } 1219 1220 static int 1221 ProcXDGAQueryVersion(ClientPtr client) 1222 { 1223 xXDGAQueryVersionReply rep; 1224 1225 REQUEST_SIZE_MATCH(xXDGAQueryVersionReq); 1226 rep.type = X_Reply; 1227 rep.length = 0; 1228 rep.sequenceNumber = client->sequence; 1229 rep.majorVersion = SERVER_XDGA_MAJOR_VERSION; 1230 rep.minorVersion = SERVER_XDGA_MINOR_VERSION; 1231 1232 WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *) &rep); 1233 return Success; 1234 } 1235 1236 static int 1237 ProcXDGAOpenFramebuffer(ClientPtr client) 1238 { 1239 REQUEST(xXDGAOpenFramebufferReq); 1240 xXDGAOpenFramebufferReply rep; 1241 char *deviceName; 1242 int nameSize; 1243 1244 REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq); 1245 1246 if (stuff->screen >= screenInfo.numScreens) 1247 return BadValue; 1248 1249 if (!DGAAvailable(stuff->screen)) 1250 return DGAErrorBase + XF86DGANoDirectVideoMode; 1251 1252 rep.type = X_Reply; 1253 rep.length = 0; 1254 rep.sequenceNumber = client->sequence; 1255 1256 if (!DGAOpenFramebuffer(stuff->screen, &deviceName, 1257 (unsigned char **) (&rep.mem1), 1258 (int *) &rep.size, (int *) &rep.offset, 1259 (int *) &rep.extra)) { 1260 return BadAlloc; 1261 } 1262 1263 nameSize = deviceName ? (strlen(deviceName) + 1) : 0; 1264 rep.length = bytes_to_int32(nameSize); 1265 1266 WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *) &rep); 1267 if (rep.length) 1268 WriteToClient(client, nameSize, deviceName); 1269 1270 return Success; 1271 } 1272 1273 static int 1274 ProcXDGACloseFramebuffer(ClientPtr client) 1275 { 1276 REQUEST(xXDGACloseFramebufferReq); 1277 1278 REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq); 1279 1280 if (stuff->screen >= screenInfo.numScreens) 1281 return BadValue; 1282 1283 if (!DGAAvailable(stuff->screen)) 1284 return DGAErrorBase + XF86DGANoDirectVideoMode; 1285 1286 DGACloseFramebuffer(stuff->screen); 1287 1288 return Success; 1289 } 1290 1291 static int 1292 ProcXDGAQueryModes(ClientPtr client) 1293 { 1294 int i, num, size; 1295 1296 REQUEST(xXDGAQueryModesReq); 1297 xXDGAQueryModesReply rep; 1298 xXDGAModeInfo info; 1299 XDGAModePtr mode; 1300 1301 REQUEST_SIZE_MATCH(xXDGAQueryModesReq); 1302 1303 if (stuff->screen >= screenInfo.numScreens) 1304 return BadValue; 1305 1306 rep.type = X_Reply; 1307 rep.length = 0; 1308 rep.number = 0; 1309 rep.sequenceNumber = client->sequence; 1310 1311 if (!DGAAvailable(stuff->screen)) { 1312 rep.number = 0; 1313 rep.length = 0; 1314 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep); 1315 return Success; 1316 } 1317 1318 if (!(num = DGAGetModes(stuff->screen))) { 1319 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep); 1320 return Success; 1321 } 1322 1323 if (!(mode = xallocarray(num, sizeof(XDGAModeRec)))) 1324 return BadAlloc; 1325 1326 for (i = 0; i < num; i++) 1327 DGAGetModeInfo(stuff->screen, mode + i, i + 1); 1328 1329 size = num * sz_xXDGAModeInfo; 1330 for (i = 0; i < num; i++) 1331 size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */ 1332 1333 rep.number = num; 1334 rep.length = bytes_to_int32(size); 1335 1336 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep); 1337 1338 for (i = 0; i < num; i++) { 1339 size = strlen(mode[i].name) + 1; 1340 1341 info.byte_order = mode[i].byteOrder; 1342 info.depth = mode[i].depth; 1343 info.num = mode[i].num; 1344 info.bpp = mode[i].bitsPerPixel; 1345 info.name_size = (size + 3) & ~3L; 1346 info.vsync_num = mode[i].VSync_num; 1347 info.vsync_den = mode[i].VSync_den; 1348 info.flags = mode[i].flags; 1349 info.image_width = mode[i].imageWidth; 1350 info.image_height = mode[i].imageHeight; 1351 info.pixmap_width = mode[i].pixmapWidth; 1352 info.pixmap_height = mode[i].pixmapHeight; 1353 info.bytes_per_scanline = mode[i].bytesPerScanline; 1354 info.red_mask = mode[i].red_mask; 1355 info.green_mask = mode[i].green_mask; 1356 info.blue_mask = mode[i].blue_mask; 1357 info.visual_class = mode[i].visualClass; 1358 info.viewport_width = mode[i].viewportWidth; 1359 info.viewport_height = mode[i].viewportHeight; 1360 info.viewport_xstep = mode[i].xViewportStep; 1361 info.viewport_ystep = mode[i].yViewportStep; 1362 info.viewport_xmax = mode[i].maxViewportX; 1363 info.viewport_ymax = mode[i].maxViewportY; 1364 info.viewport_flags = mode[i].viewportFlags; 1365 info.reserved1 = mode[i].reserved1; 1366 info.reserved2 = mode[i].reserved2; 1367 1368 WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info)); 1369 WriteToClient(client, size, mode[i].name); 1370 } 1371 1372 free(mode); 1373 1374 return Success; 1375 } 1376 1377 static void 1378 DGAClientStateChange(CallbackListPtr *pcbl, void *nulldata, void *calldata) 1379 { 1380 NewClientInfoRec *pci = (NewClientInfoRec *) calldata; 1381 ClientPtr client = NULL; 1382 int i; 1383 1384 for (i = 0; i < screenInfo.numScreens; i++) { 1385 if (DGA_GETCLIENT(i) == pci->client) { 1386 client = pci->client; 1387 break; 1388 } 1389 } 1390 1391 if (client && 1392 ((client->clientState == ClientStateGone) || 1393 (client->clientState == ClientStateRetained))) { 1394 XDGAModeRec mode; 1395 PixmapPtr pPix; 1396 1397 DGA_SETCLIENT(i, NULL); 1398 DGASelectInput(i, NULL, 0); 1399 DGASetMode(i, 0, &mode, &pPix); 1400 1401 if (--DGACallbackRefCount == 0) 1402 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); 1403 } 1404 } 1405 1406 static int 1407 ProcXDGASetMode(ClientPtr client) 1408 { 1409 REQUEST(xXDGASetModeReq); 1410 xXDGASetModeReply rep; 1411 XDGAModeRec mode; 1412 xXDGAModeInfo info; 1413 PixmapPtr pPix; 1414 ClientPtr owner; 1415 int size; 1416 1417 REQUEST_SIZE_MATCH(xXDGASetModeReq); 1418 1419 if (stuff->screen >= screenInfo.numScreens) 1420 return BadValue; 1421 owner = DGA_GETCLIENT(stuff->screen); 1422 1423 rep.type = X_Reply; 1424 rep.length = 0; 1425 rep.offset = 0; 1426 rep.flags = 0; 1427 rep.sequenceNumber = client->sequence; 1428 1429 if (!DGAAvailable(stuff->screen)) 1430 return DGAErrorBase + XF86DGANoDirectVideoMode; 1431 1432 if (owner && owner != client) 1433 return DGAErrorBase + XF86DGANoDirectVideoMode; 1434 1435 if (!stuff->mode) { 1436 if (owner) { 1437 if (--DGACallbackRefCount == 0) 1438 DeleteCallback(&ClientStateCallback, DGAClientStateChange, 1439 NULL); 1440 } 1441 DGA_SETCLIENT(stuff->screen, NULL); 1442 DGASelectInput(stuff->screen, NULL, 0); 1443 DGASetMode(stuff->screen, 0, &mode, &pPix); 1444 WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep); 1445 return Success; 1446 } 1447 1448 if (Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix)) 1449 return BadValue; 1450 1451 if (!owner) { 1452 if (DGACallbackRefCount++ == 0) 1453 AddCallback(&ClientStateCallback, DGAClientStateChange, NULL); 1454 } 1455 1456 DGA_SETCLIENT(stuff->screen, client); 1457 1458 if (pPix) { 1459 if (AddResource(stuff->pid, RT_PIXMAP, (void *) (pPix))) { 1460 pPix->drawable.id = (int) stuff->pid; 1461 rep.flags = DGA_PIXMAP_AVAILABLE; 1462 } 1463 } 1464 1465 size = strlen(mode.name) + 1; 1466 1467 info.byte_order = mode.byteOrder; 1468 info.depth = mode.depth; 1469 info.num = mode.num; 1470 info.bpp = mode.bitsPerPixel; 1471 info.name_size = (size + 3) & ~3L; 1472 info.vsync_num = mode.VSync_num; 1473 info.vsync_den = mode.VSync_den; 1474 info.flags = mode.flags; 1475 info.image_width = mode.imageWidth; 1476 info.image_height = mode.imageHeight; 1477 info.pixmap_width = mode.pixmapWidth; 1478 info.pixmap_height = mode.pixmapHeight; 1479 info.bytes_per_scanline = mode.bytesPerScanline; 1480 info.red_mask = mode.red_mask; 1481 info.green_mask = mode.green_mask; 1482 info.blue_mask = mode.blue_mask; 1483 info.visual_class = mode.visualClass; 1484 info.viewport_width = mode.viewportWidth; 1485 info.viewport_height = mode.viewportHeight; 1486 info.viewport_xstep = mode.xViewportStep; 1487 info.viewport_ystep = mode.yViewportStep; 1488 info.viewport_xmax = mode.maxViewportX; 1489 info.viewport_ymax = mode.maxViewportY; 1490 info.viewport_flags = mode.viewportFlags; 1491 info.reserved1 = mode.reserved1; 1492 info.reserved2 = mode.reserved2; 1493 1494 rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size); 1495 1496 WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep); 1497 WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info)); 1498 WriteToClient(client, size, mode.name); 1499 1500 return Success; 1501 } 1502 1503 static int 1504 ProcXDGASetViewport(ClientPtr client) 1505 { 1506 REQUEST(xXDGASetViewportReq); 1507 1508 REQUEST_SIZE_MATCH(xXDGASetViewportReq); 1509 1510 if (stuff->screen >= screenInfo.numScreens) 1511 return BadValue; 1512 1513 if (DGA_GETCLIENT(stuff->screen) != client) 1514 return DGAErrorBase + XF86DGADirectNotActivated; 1515 1516 DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags); 1517 1518 return Success; 1519 } 1520 1521 static int 1522 ProcXDGAInstallColormap(ClientPtr client) 1523 { 1524 ColormapPtr cmap; 1525 int rc; 1526 1527 REQUEST(xXDGAInstallColormapReq); 1528 1529 REQUEST_SIZE_MATCH(xXDGAInstallColormapReq); 1530 1531 if (stuff->screen >= screenInfo.numScreens) 1532 return BadValue; 1533 1534 if (DGA_GETCLIENT(stuff->screen) != client) 1535 return DGAErrorBase + XF86DGADirectNotActivated; 1536 1537 rc = dixLookupResourceByType((void **) &cmap, stuff->cmap, RT_COLORMAP, 1538 client, DixInstallAccess); 1539 if (rc != Success) 1540 return rc; 1541 DGAInstallCmap(cmap); 1542 return Success; 1543 } 1544 1545 static int 1546 ProcXDGASelectInput(ClientPtr client) 1547 { 1548 REQUEST(xXDGASelectInputReq); 1549 1550 REQUEST_SIZE_MATCH(xXDGASelectInputReq); 1551 1552 if (stuff->screen >= screenInfo.numScreens) 1553 return BadValue; 1554 1555 if (DGA_GETCLIENT(stuff->screen) != client) 1556 return DGAErrorBase + XF86DGADirectNotActivated; 1557 1558 if (DGA_GETCLIENT(stuff->screen) == client) 1559 DGASelectInput(stuff->screen, client, stuff->mask); 1560 1561 return Success; 1562 } 1563 1564 static int 1565 ProcXDGAFillRectangle(ClientPtr client) 1566 { 1567 REQUEST(xXDGAFillRectangleReq); 1568 1569 REQUEST_SIZE_MATCH(xXDGAFillRectangleReq); 1570 1571 if (stuff->screen >= screenInfo.numScreens) 1572 return BadValue; 1573 1574 if (DGA_GETCLIENT(stuff->screen) != client) 1575 return DGAErrorBase + XF86DGADirectNotActivated; 1576 1577 if (Success != DGAFillRect(stuff->screen, stuff->x, stuff->y, 1578 stuff->width, stuff->height, stuff->color)) 1579 return BadMatch; 1580 1581 return Success; 1582 } 1583 1584 static int 1585 ProcXDGACopyArea(ClientPtr client) 1586 { 1587 REQUEST(xXDGACopyAreaReq); 1588 1589 REQUEST_SIZE_MATCH(xXDGACopyAreaReq); 1590 1591 if (stuff->screen >= screenInfo.numScreens) 1592 return BadValue; 1593 1594 if (DGA_GETCLIENT(stuff->screen) != client) 1595 return DGAErrorBase + XF86DGADirectNotActivated; 1596 1597 if (Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy, 1598 stuff->width, stuff->height, stuff->dstx, 1599 stuff->dsty)) 1600 return BadMatch; 1601 1602 return Success; 1603 } 1604 1605 static int 1606 ProcXDGACopyTransparentArea(ClientPtr client) 1607 { 1608 REQUEST(xXDGACopyTransparentAreaReq); 1609 1610 REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq); 1611 1612 if (stuff->screen >= screenInfo.numScreens) 1613 return BadValue; 1614 1615 if (DGA_GETCLIENT(stuff->screen) != client) 1616 return DGAErrorBase + XF86DGADirectNotActivated; 1617 1618 if (Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy, 1619 stuff->width, stuff->height, stuff->dstx, 1620 stuff->dsty, stuff->key)) 1621 return BadMatch; 1622 1623 return Success; 1624 } 1625 1626 static int 1627 ProcXDGAGetViewportStatus(ClientPtr client) 1628 { 1629 REQUEST(xXDGAGetViewportStatusReq); 1630 xXDGAGetViewportStatusReply rep; 1631 1632 REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq); 1633 1634 if (stuff->screen >= screenInfo.numScreens) 1635 return BadValue; 1636 1637 if (DGA_GETCLIENT(stuff->screen) != client) 1638 return DGAErrorBase + XF86DGADirectNotActivated; 1639 1640 rep.type = X_Reply; 1641 rep.length = 0; 1642 rep.sequenceNumber = client->sequence; 1643 1644 rep.status = DGAGetViewportStatus(stuff->screen); 1645 1646 WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *) &rep); 1647 return Success; 1648 } 1649 1650 static int 1651 ProcXDGASync(ClientPtr client) 1652 { 1653 REQUEST(xXDGASyncReq); 1654 xXDGASyncReply rep; 1655 1656 REQUEST_SIZE_MATCH(xXDGASyncReq); 1657 1658 if (stuff->screen >= screenInfo.numScreens) 1659 return BadValue; 1660 1661 if (DGA_GETCLIENT(stuff->screen) != client) 1662 return DGAErrorBase + XF86DGADirectNotActivated; 1663 1664 rep.type = X_Reply; 1665 rep.length = 0; 1666 rep.sequenceNumber = client->sequence; 1667 1668 DGASync(stuff->screen); 1669 1670 WriteToClient(client, sizeof(xXDGASyncReply), (char *) &rep); 1671 return Success; 1672 } 1673 1674 static int 1675 ProcXDGASetClientVersion(ClientPtr client) 1676 { 1677 REQUEST(xXDGASetClientVersionReq); 1678 1679 DGAPrivPtr pPriv; 1680 1681 REQUEST_SIZE_MATCH(xXDGASetClientVersionReq); 1682 if ((pPriv = DGA_GETPRIV(client)) == NULL) { 1683 pPriv = malloc(sizeof(DGAPrivRec)); 1684 /* XXX Need to look into freeing this */ 1685 if (!pPriv) 1686 return BadAlloc; 1687 DGA_SETPRIV(client, pPriv); 1688 } 1689 pPriv->major = stuff->major; 1690 pPriv->minor = stuff->minor; 1691 1692 return Success; 1693 } 1694 1695 static int 1696 ProcXDGAChangePixmapMode(ClientPtr client) 1697 { 1698 REQUEST(xXDGAChangePixmapModeReq); 1699 xXDGAChangePixmapModeReply rep; 1700 int x, y; 1701 1702 REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq); 1703 1704 if (stuff->screen >= screenInfo.numScreens) 1705 return BadValue; 1706 1707 if (DGA_GETCLIENT(stuff->screen) != client) 1708 return DGAErrorBase + XF86DGADirectNotActivated; 1709 1710 rep.type = X_Reply; 1711 rep.length = 0; 1712 rep.sequenceNumber = client->sequence; 1713 1714 x = stuff->x; 1715 y = stuff->y; 1716 1717 if (!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags)) 1718 return BadMatch; 1719 1720 rep.x = x; 1721 rep.y = y; 1722 WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *) &rep); 1723 1724 return Success; 1725 } 1726 1727 static int 1728 ProcXDGACreateColormap(ClientPtr client) 1729 { 1730 REQUEST(xXDGACreateColormapReq); 1731 int result; 1732 1733 REQUEST_SIZE_MATCH(xXDGACreateColormapReq); 1734 1735 if (stuff->screen >= screenInfo.numScreens) 1736 return BadValue; 1737 1738 if (DGA_GETCLIENT(stuff->screen) != client) 1739 return DGAErrorBase + XF86DGADirectNotActivated; 1740 1741 if (!stuff->mode) 1742 return BadValue; 1743 1744 result = DGACreateColormap(stuff->screen, client, stuff->id, 1745 stuff->mode, stuff->alloc); 1746 if (result != Success) 1747 return result; 1748 1749 return Success; 1750 } 1751 1752 /* 1753 * 1754 * Support for the old DGA protocol, used to live in xf86dga.c 1755 * 1756 */ 1757 1758 #ifdef DGA_PROTOCOL_OLD_SUPPORT 1759 1760 static int 1761 ProcXF86DGAGetVideoLL(ClientPtr client) 1762 { 1763 REQUEST(xXF86DGAGetVideoLLReq); 1764 xXF86DGAGetVideoLLReply rep; 1765 XDGAModeRec mode; 1766 int num, offset, flags; 1767 char *name; 1768 1769 REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq); 1770 1771 if (stuff->screen >= screenInfo.numScreens) 1772 return BadValue; 1773 1774 rep.type = X_Reply; 1775 rep.length = 0; 1776 rep.sequenceNumber = client->sequence; 1777 1778 if (!DGAAvailable(stuff->screen)) 1779 return DGAErrorBase + XF86DGANoDirectVideoMode; 1780 1781 if (!(num = DGAGetOldDGAMode(stuff->screen))) 1782 return DGAErrorBase + XF86DGANoDirectVideoMode; 1783 1784 /* get the parameters for the mode that best matches */ 1785 DGAGetModeInfo(stuff->screen, &mode, num); 1786 1787 if (!DGAOpenFramebuffer(stuff->screen, &name, 1788 (unsigned char **) (&rep.offset), 1789 (int *) (&rep.bank_size), &offset, &flags)) 1790 return BadAlloc; 1791 1792 rep.offset += mode.offset; 1793 rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3); 1794 rep.ram_size = rep.bank_size >> 10; 1795 1796 WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *) &rep); 1797 return Success; 1798 } 1799 1800 static int 1801 ProcXF86DGADirectVideo(ClientPtr client) 1802 { 1803 int num; 1804 PixmapPtr pix; 1805 XDGAModeRec mode; 1806 ClientPtr owner; 1807 1808 REQUEST(xXF86DGADirectVideoReq); 1809 1810 REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq); 1811 1812 if (stuff->screen >= screenInfo.numScreens) 1813 return BadValue; 1814 1815 if (!DGAAvailable(stuff->screen)) 1816 return DGAErrorBase + XF86DGANoDirectVideoMode; 1817 1818 owner = DGA_GETCLIENT(stuff->screen); 1819 1820 if (owner && owner != client) 1821 return DGAErrorBase + XF86DGANoDirectVideoMode; 1822 1823 if (stuff->enable & XF86DGADirectGraphics) { 1824 if (!(num = DGAGetOldDGAMode(stuff->screen))) 1825 return DGAErrorBase + XF86DGANoDirectVideoMode; 1826 } 1827 else 1828 num = 0; 1829 1830 if (Success != DGASetMode(stuff->screen, num, &mode, &pix)) 1831 return DGAErrorBase + XF86DGAScreenNotActive; 1832 1833 DGASetInputMode(stuff->screen, 1834 (stuff->enable & XF86DGADirectKeyb) != 0, 1835 (stuff->enable & XF86DGADirectMouse) != 0); 1836 1837 /* We need to track the client and attach the teardown callback */ 1838 if (stuff->enable & 1839 (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) { 1840 if (!owner) { 1841 if (DGACallbackRefCount++ == 0) 1842 AddCallback(&ClientStateCallback, DGAClientStateChange, NULL); 1843 } 1844 1845 DGA_SETCLIENT(stuff->screen, client); 1846 } 1847 else { 1848 if (owner) { 1849 if (--DGACallbackRefCount == 0) 1850 DeleteCallback(&ClientStateCallback, DGAClientStateChange, 1851 NULL); 1852 } 1853 1854 DGA_SETCLIENT(stuff->screen, NULL); 1855 } 1856 1857 return Success; 1858 } 1859 1860 static int 1861 ProcXF86DGAGetViewPortSize(ClientPtr client) 1862 { 1863 int num; 1864 XDGAModeRec mode; 1865 1866 REQUEST(xXF86DGAGetViewPortSizeReq); 1867 xXF86DGAGetViewPortSizeReply rep; 1868 1869 REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq); 1870 1871 if (stuff->screen >= screenInfo.numScreens) 1872 return BadValue; 1873 1874 rep.type = X_Reply; 1875 rep.length = 0; 1876 rep.sequenceNumber = client->sequence; 1877 1878 if (!DGAAvailable(stuff->screen)) 1879 return DGAErrorBase + XF86DGANoDirectVideoMode; 1880 1881 if (!(num = DGAGetOldDGAMode(stuff->screen))) 1882 return DGAErrorBase + XF86DGANoDirectVideoMode; 1883 1884 DGAGetModeInfo(stuff->screen, &mode, num); 1885 1886 rep.width = mode.viewportWidth; 1887 rep.height = mode.viewportHeight; 1888 1889 WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *) &rep); 1890 return Success; 1891 } 1892 1893 static int 1894 ProcXF86DGASetViewPort(ClientPtr client) 1895 { 1896 REQUEST(xXF86DGASetViewPortReq); 1897 1898 REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq); 1899 1900 if (stuff->screen >= screenInfo.numScreens) 1901 return BadValue; 1902 1903 if (DGA_GETCLIENT(stuff->screen) != client) 1904 return DGAErrorBase + XF86DGADirectNotActivated; 1905 1906 if (!DGAAvailable(stuff->screen)) 1907 return DGAErrorBase + XF86DGANoDirectVideoMode; 1908 1909 if (!DGAActive(stuff->screen)) 1910 return DGAErrorBase + XF86DGADirectNotActivated; 1911 1912 if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE) 1913 != Success) 1914 return DGAErrorBase + XF86DGADirectNotActivated; 1915 1916 return Success; 1917 } 1918 1919 static int 1920 ProcXF86DGAGetVidPage(ClientPtr client) 1921 { 1922 REQUEST(xXF86DGAGetVidPageReq); 1923 xXF86DGAGetVidPageReply rep; 1924 1925 REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq); 1926 1927 if (stuff->screen >= screenInfo.numScreens) 1928 return BadValue; 1929 1930 rep.type = X_Reply; 1931 rep.length = 0; 1932 rep.sequenceNumber = client->sequence; 1933 rep.vpage = 0; /* silently fail */ 1934 1935 WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *) &rep); 1936 return Success; 1937 } 1938 1939 static int 1940 ProcXF86DGASetVidPage(ClientPtr client) 1941 { 1942 REQUEST(xXF86DGASetVidPageReq); 1943 1944 REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq); 1945 1946 if (stuff->screen >= screenInfo.numScreens) 1947 return BadValue; 1948 1949 /* silently fail */ 1950 1951 return Success; 1952 } 1953 1954 static int 1955 ProcXF86DGAInstallColormap(ClientPtr client) 1956 { 1957 ColormapPtr pcmp; 1958 int rc; 1959 1960 REQUEST(xXF86DGAInstallColormapReq); 1961 1962 REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq); 1963 1964 if (stuff->screen >= screenInfo.numScreens) 1965 return BadValue; 1966 1967 if (DGA_GETCLIENT(stuff->screen) != client) 1968 return DGAErrorBase + XF86DGADirectNotActivated; 1969 1970 if (!DGAActive(stuff->screen)) 1971 return DGAErrorBase + XF86DGADirectNotActivated; 1972 1973 rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, 1974 client, DixInstallAccess); 1975 if (rc == Success) { 1976 DGAInstallCmap(pcmp); 1977 return Success; 1978 } 1979 else { 1980 return rc; 1981 } 1982 } 1983 1984 static int 1985 ProcXF86DGAQueryDirectVideo(ClientPtr client) 1986 { 1987 REQUEST(xXF86DGAQueryDirectVideoReq); 1988 xXF86DGAQueryDirectVideoReply rep; 1989 1990 REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq); 1991 1992 if (stuff->screen >= screenInfo.numScreens) 1993 return BadValue; 1994 1995 rep.type = X_Reply; 1996 rep.length = 0; 1997 rep.sequenceNumber = client->sequence; 1998 rep.flags = 0; 1999 2000 if (DGAAvailable(stuff->screen)) 2001 rep.flags = XF86DGADirectPresent; 2002 2003 WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *) &rep); 2004 return Success; 2005 } 2006 2007 static int 2008 ProcXF86DGAViewPortChanged(ClientPtr client) 2009 { 2010 REQUEST(xXF86DGAViewPortChangedReq); 2011 xXF86DGAViewPortChangedReply rep; 2012 2013 REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq); 2014 2015 if (stuff->screen >= screenInfo.numScreens) 2016 return BadValue; 2017 2018 if (DGA_GETCLIENT(stuff->screen) != client) 2019 return DGAErrorBase + XF86DGADirectNotActivated; 2020 2021 if (!DGAActive(stuff->screen)) 2022 return DGAErrorBase + XF86DGADirectNotActivated; 2023 2024 rep.type = X_Reply; 2025 rep.length = 0; 2026 rep.sequenceNumber = client->sequence; 2027 rep.result = 1; 2028 2029 WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *) &rep); 2030 return Success; 2031 } 2032 2033 #endif /* DGA_PROTOCOL_OLD_SUPPORT */ 2034 2035 static int _X_COLD 2036 SProcXDGADispatch(ClientPtr client) 2037 { 2038 return DGAErrorBase + XF86DGAClientNotLocal; 2039 } 2040 2041 #if 0 2042 #define DGA_REQ_DEBUG 2043 #endif 2044 2045 #ifdef DGA_REQ_DEBUG 2046 static char *dgaMinor[] = { 2047 "QueryVersion", 2048 "GetVideoLL", 2049 "DirectVideo", 2050 "GetViewPortSize", 2051 "SetViewPort", 2052 "GetVidPage", 2053 "SetVidPage", 2054 "InstallColormap", 2055 "QueryDirectVideo", 2056 "ViewPortChanged", 2057 "10", 2058 "11", 2059 "QueryModes", 2060 "SetMode", 2061 "SetViewport", 2062 "InstallColormap", 2063 "SelectInput", 2064 "FillRectangle", 2065 "CopyArea", 2066 "CopyTransparentArea", 2067 "GetViewportStatus", 2068 "Sync", 2069 "OpenFramebuffer", 2070 "CloseFramebuffer", 2071 "SetClientVersion", 2072 "ChangePixmapMode", 2073 "CreateColormap", 2074 }; 2075 #endif 2076 2077 static int 2078 ProcXDGADispatch(ClientPtr client) 2079 { 2080 REQUEST(xReq); 2081 2082 if (!client->local) 2083 return DGAErrorBase + XF86DGAClientNotLocal; 2084 2085 #ifdef DGA_REQ_DEBUG 2086 if (stuff->data <= X_XDGACreateColormap) 2087 fprintf(stderr, " DGA %s\n", dgaMinor[stuff->data]); 2088 #endif 2089 2090 switch (stuff->data) { 2091 /* 2092 * DGA2 Protocol 2093 */ 2094 case X_XDGAQueryVersion: 2095 return ProcXDGAQueryVersion(client); 2096 case X_XDGAQueryModes: 2097 return ProcXDGAQueryModes(client); 2098 case X_XDGASetMode: 2099 return ProcXDGASetMode(client); 2100 case X_XDGAOpenFramebuffer: 2101 return ProcXDGAOpenFramebuffer(client); 2102 case X_XDGACloseFramebuffer: 2103 return ProcXDGACloseFramebuffer(client); 2104 case X_XDGASetViewport: 2105 return ProcXDGASetViewport(client); 2106 case X_XDGAInstallColormap: 2107 return ProcXDGAInstallColormap(client); 2108 case X_XDGASelectInput: 2109 return ProcXDGASelectInput(client); 2110 case X_XDGAFillRectangle: 2111 return ProcXDGAFillRectangle(client); 2112 case X_XDGACopyArea: 2113 return ProcXDGACopyArea(client); 2114 case X_XDGACopyTransparentArea: 2115 return ProcXDGACopyTransparentArea(client); 2116 case X_XDGAGetViewportStatus: 2117 return ProcXDGAGetViewportStatus(client); 2118 case X_XDGASync: 2119 return ProcXDGASync(client); 2120 case X_XDGASetClientVersion: 2121 return ProcXDGASetClientVersion(client); 2122 case X_XDGAChangePixmapMode: 2123 return ProcXDGAChangePixmapMode(client); 2124 case X_XDGACreateColormap: 2125 return ProcXDGACreateColormap(client); 2126 /* 2127 * Old DGA Protocol 2128 */ 2129 #ifdef DGA_PROTOCOL_OLD_SUPPORT 2130 case X_XF86DGAGetVideoLL: 2131 return ProcXF86DGAGetVideoLL(client); 2132 case X_XF86DGADirectVideo: 2133 return ProcXF86DGADirectVideo(client); 2134 case X_XF86DGAGetViewPortSize: 2135 return ProcXF86DGAGetViewPortSize(client); 2136 case X_XF86DGASetViewPort: 2137 return ProcXF86DGASetViewPort(client); 2138 case X_XF86DGAGetVidPage: 2139 return ProcXF86DGAGetVidPage(client); 2140 case X_XF86DGASetVidPage: 2141 return ProcXF86DGASetVidPage(client); 2142 case X_XF86DGAInstallColormap: 2143 return ProcXF86DGAInstallColormap(client); 2144 case X_XF86DGAQueryDirectVideo: 2145 return ProcXF86DGAQueryDirectVideo(client); 2146 case X_XF86DGAViewPortChanged: 2147 return ProcXF86DGAViewPortChanged(client); 2148 #endif /* DGA_PROTOCOL_OLD_SUPPORT */ 2149 default: 2150 return BadRequest; 2151 } 2152 } 2153 2154 void 2155 XFree86DGAExtensionInit(void) 2156 { 2157 ExtensionEntry *extEntry; 2158 2159 if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0)) 2160 return; 2161 2162 if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 2163 return; 2164 2165 if ((extEntry = AddExtension(XF86DGANAME, 2166 XF86DGANumberEvents, 2167 XF86DGANumberErrors, 2168 ProcXDGADispatch, 2169 SProcXDGADispatch, 2170 XDGAResetProc, StandardMinorOpcode))) { 2171 int i; 2172 2173 DGAReqCode = (unsigned char) extEntry->base; 2174 DGAErrorBase = extEntry->errorBase; 2175 DGAEventBase = extEntry->eventBase; 2176 for (i = KeyPress; i <= MotionNotify; i++) 2177 SetCriticalEvent(DGAEventBase + i); 2178 } 2179 }