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