xf86DGA.c revision 6e78d31f
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 REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq); 1276 1277 if (stuff->screen >= screenInfo.numScreens) 1278 return BadValue; 1279 1280 if (!DGAAvailable(stuff->screen)) 1281 return DGAErrorBase + XF86DGANoDirectVideoMode; 1282 1283 rep.type = X_Reply; 1284 rep.length = 0; 1285 rep.sequenceNumber = client->sequence; 1286 1287 if (!DGAOpenFramebuffer(stuff->screen, &deviceName, 1288 (unsigned char **) (&rep.mem1), 1289 (int *) &rep.size, (int *) &rep.offset, 1290 (int *) &rep.extra)) { 1291 return BadAlloc; 1292 } 1293 1294 nameSize = deviceName ? (strlen(deviceName) + 1) : 0; 1295 rep.length = bytes_to_int32(nameSize); 1296 1297 WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *) &rep); 1298 if (rep.length) 1299 WriteToClient(client, nameSize, deviceName); 1300 1301 return Success; 1302} 1303 1304static int 1305ProcXDGACloseFramebuffer(ClientPtr client) 1306{ 1307 REQUEST(xXDGACloseFramebufferReq); 1308 1309 REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq); 1310 1311 if (stuff->screen >= screenInfo.numScreens) 1312 return BadValue; 1313 1314 if (!DGAAvailable(stuff->screen)) 1315 return DGAErrorBase + XF86DGANoDirectVideoMode; 1316 1317 DGACloseFramebuffer(stuff->screen); 1318 1319 return Success; 1320} 1321 1322static int 1323ProcXDGAQueryModes(ClientPtr client) 1324{ 1325 int i, num, size; 1326 1327 REQUEST(xXDGAQueryModesReq); 1328 xXDGAQueryModesReply rep; 1329 xXDGAModeInfo info; 1330 XDGAModePtr mode; 1331 1332 REQUEST_SIZE_MATCH(xXDGAQueryModesReq); 1333 1334 if (stuff->screen >= screenInfo.numScreens) 1335 return BadValue; 1336 1337 rep.type = X_Reply; 1338 rep.length = 0; 1339 rep.number = 0; 1340 rep.sequenceNumber = client->sequence; 1341 1342 if (!DGAAvailable(stuff->screen)) { 1343 rep.number = 0; 1344 rep.length = 0; 1345 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep); 1346 return Success; 1347 } 1348 1349 if (!(num = DGAGetModes(stuff->screen))) { 1350 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep); 1351 return Success; 1352 } 1353 1354 if (!(mode = xallocarray(num, sizeof(XDGAModeRec)))) 1355 return BadAlloc; 1356 1357 for (i = 0; i < num; i++) 1358 DGAGetModeInfo(stuff->screen, mode + i, i + 1); 1359 1360 size = num * sz_xXDGAModeInfo; 1361 for (i = 0; i < num; i++) 1362 size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */ 1363 1364 rep.number = num; 1365 rep.length = bytes_to_int32(size); 1366 1367 WriteToClient(client, sz_xXDGAQueryModesReply, (char *) &rep); 1368 1369 for (i = 0; i < num; i++) { 1370 size = strlen(mode[i].name) + 1; 1371 1372 info.byte_order = mode[i].byteOrder; 1373 info.depth = mode[i].depth; 1374 info.num = mode[i].num; 1375 info.bpp = mode[i].bitsPerPixel; 1376 info.name_size = (size + 3) & ~3L; 1377 info.vsync_num = mode[i].VSync_num; 1378 info.vsync_den = mode[i].VSync_den; 1379 info.flags = mode[i].flags; 1380 info.image_width = mode[i].imageWidth; 1381 info.image_height = mode[i].imageHeight; 1382 info.pixmap_width = mode[i].pixmapWidth; 1383 info.pixmap_height = mode[i].pixmapHeight; 1384 info.bytes_per_scanline = mode[i].bytesPerScanline; 1385 info.red_mask = mode[i].red_mask; 1386 info.green_mask = mode[i].green_mask; 1387 info.blue_mask = mode[i].blue_mask; 1388 info.visual_class = mode[i].visualClass; 1389 info.viewport_width = mode[i].viewportWidth; 1390 info.viewport_height = mode[i].viewportHeight; 1391 info.viewport_xstep = mode[i].xViewportStep; 1392 info.viewport_ystep = mode[i].yViewportStep; 1393 info.viewport_xmax = mode[i].maxViewportX; 1394 info.viewport_ymax = mode[i].maxViewportY; 1395 info.viewport_flags = mode[i].viewportFlags; 1396 info.reserved1 = mode[i].reserved1; 1397 info.reserved2 = mode[i].reserved2; 1398 1399 WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info)); 1400 WriteToClient(client, size, mode[i].name); 1401 } 1402 1403 free(mode); 1404 1405 return Success; 1406} 1407 1408static void 1409DGAClientStateChange(CallbackListPtr *pcbl, void *nulldata, void *calldata) 1410{ 1411 NewClientInfoRec *pci = (NewClientInfoRec *) calldata; 1412 ClientPtr client = NULL; 1413 int i; 1414 1415 for (i = 0; i < screenInfo.numScreens; i++) { 1416 if (DGA_GETCLIENT(i) == pci->client) { 1417 client = pci->client; 1418 break; 1419 } 1420 } 1421 1422 if (client && 1423 ((client->clientState == ClientStateGone) || 1424 (client->clientState == ClientStateRetained))) { 1425 XDGAModeRec mode; 1426 PixmapPtr pPix; 1427 1428 DGA_SETCLIENT(i, NULL); 1429 DGASelectInput(i, NULL, 0); 1430 DGASetMode(i, 0, &mode, &pPix); 1431 1432 if (--DGACallbackRefCount == 0) 1433 DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL); 1434 } 1435} 1436 1437static int 1438ProcXDGASetMode(ClientPtr client) 1439{ 1440 REQUEST(xXDGASetModeReq); 1441 xXDGASetModeReply rep; 1442 XDGAModeRec mode; 1443 xXDGAModeInfo info; 1444 PixmapPtr pPix; 1445 ClientPtr owner; 1446 int size; 1447 1448 REQUEST_SIZE_MATCH(xXDGASetModeReq); 1449 1450 if (stuff->screen >= screenInfo.numScreens) 1451 return BadValue; 1452 owner = DGA_GETCLIENT(stuff->screen); 1453 1454 rep.type = X_Reply; 1455 rep.length = 0; 1456 rep.offset = 0; 1457 rep.flags = 0; 1458 rep.sequenceNumber = client->sequence; 1459 1460 if (!DGAAvailable(stuff->screen)) 1461 return DGAErrorBase + XF86DGANoDirectVideoMode; 1462 1463 if (owner && owner != client) 1464 return DGAErrorBase + XF86DGANoDirectVideoMode; 1465 1466 if (!stuff->mode) { 1467 if (owner) { 1468 if (--DGACallbackRefCount == 0) 1469 DeleteCallback(&ClientStateCallback, DGAClientStateChange, 1470 NULL); 1471 } 1472 DGA_SETCLIENT(stuff->screen, NULL); 1473 DGASelectInput(stuff->screen, NULL, 0); 1474 DGASetMode(stuff->screen, 0, &mode, &pPix); 1475 WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep); 1476 return Success; 1477 } 1478 1479 if (Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix)) 1480 return BadValue; 1481 1482 if (!owner) { 1483 if (DGACallbackRefCount++ == 0) 1484 AddCallback(&ClientStateCallback, DGAClientStateChange, NULL); 1485 } 1486 1487 DGA_SETCLIENT(stuff->screen, client); 1488 1489 if (pPix) { 1490 if (AddResource(stuff->pid, RT_PIXMAP, (void *) (pPix))) { 1491 pPix->drawable.id = (int) stuff->pid; 1492 rep.flags = DGA_PIXMAP_AVAILABLE; 1493 } 1494 } 1495 1496 size = strlen(mode.name) + 1; 1497 1498 info.byte_order = mode.byteOrder; 1499 info.depth = mode.depth; 1500 info.num = mode.num; 1501 info.bpp = mode.bitsPerPixel; 1502 info.name_size = (size + 3) & ~3L; 1503 info.vsync_num = mode.VSync_num; 1504 info.vsync_den = mode.VSync_den; 1505 info.flags = mode.flags; 1506 info.image_width = mode.imageWidth; 1507 info.image_height = mode.imageHeight; 1508 info.pixmap_width = mode.pixmapWidth; 1509 info.pixmap_height = mode.pixmapHeight; 1510 info.bytes_per_scanline = mode.bytesPerScanline; 1511 info.red_mask = mode.red_mask; 1512 info.green_mask = mode.green_mask; 1513 info.blue_mask = mode.blue_mask; 1514 info.visual_class = mode.visualClass; 1515 info.viewport_width = mode.viewportWidth; 1516 info.viewport_height = mode.viewportHeight; 1517 info.viewport_xstep = mode.xViewportStep; 1518 info.viewport_ystep = mode.yViewportStep; 1519 info.viewport_xmax = mode.maxViewportX; 1520 info.viewport_ymax = mode.maxViewportY; 1521 info.viewport_flags = mode.viewportFlags; 1522 info.reserved1 = mode.reserved1; 1523 info.reserved2 = mode.reserved2; 1524 1525 rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size); 1526 1527 WriteToClient(client, sz_xXDGASetModeReply, (char *) &rep); 1528 WriteToClient(client, sz_xXDGAModeInfo, (char *) (&info)); 1529 WriteToClient(client, size, mode.name); 1530 1531 return Success; 1532} 1533 1534static int 1535ProcXDGASetViewport(ClientPtr client) 1536{ 1537 REQUEST(xXDGASetViewportReq); 1538 1539 REQUEST_SIZE_MATCH(xXDGASetViewportReq); 1540 1541 if (stuff->screen >= screenInfo.numScreens) 1542 return BadValue; 1543 1544 if (DGA_GETCLIENT(stuff->screen) != client) 1545 return DGAErrorBase + XF86DGADirectNotActivated; 1546 1547 DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags); 1548 1549 return Success; 1550} 1551 1552static int 1553ProcXDGAInstallColormap(ClientPtr client) 1554{ 1555 ColormapPtr cmap; 1556 int rc; 1557 1558 REQUEST(xXDGAInstallColormapReq); 1559 1560 REQUEST_SIZE_MATCH(xXDGAInstallColormapReq); 1561 1562 if (stuff->screen >= screenInfo.numScreens) 1563 return BadValue; 1564 1565 if (DGA_GETCLIENT(stuff->screen) != client) 1566 return DGAErrorBase + XF86DGADirectNotActivated; 1567 1568 rc = dixLookupResourceByType((void **) &cmap, stuff->cmap, RT_COLORMAP, 1569 client, DixInstallAccess); 1570 if (rc != Success) 1571 return rc; 1572 DGAInstallCmap(cmap); 1573 return Success; 1574} 1575 1576static int 1577ProcXDGASelectInput(ClientPtr client) 1578{ 1579 REQUEST(xXDGASelectInputReq); 1580 1581 REQUEST_SIZE_MATCH(xXDGASelectInputReq); 1582 1583 if (stuff->screen >= screenInfo.numScreens) 1584 return BadValue; 1585 1586 if (DGA_GETCLIENT(stuff->screen) != client) 1587 return DGAErrorBase + XF86DGADirectNotActivated; 1588 1589 if (DGA_GETCLIENT(stuff->screen) == client) 1590 DGASelectInput(stuff->screen, client, stuff->mask); 1591 1592 return Success; 1593} 1594 1595static int 1596ProcXDGAFillRectangle(ClientPtr client) 1597{ 1598 REQUEST(xXDGAFillRectangleReq); 1599 1600 REQUEST_SIZE_MATCH(xXDGAFillRectangleReq); 1601 1602 if (stuff->screen >= screenInfo.numScreens) 1603 return BadValue; 1604 1605 if (DGA_GETCLIENT(stuff->screen) != client) 1606 return DGAErrorBase + XF86DGADirectNotActivated; 1607 1608 if (Success != DGAFillRect(stuff->screen, stuff->x, stuff->y, 1609 stuff->width, stuff->height, stuff->color)) 1610 return BadMatch; 1611 1612 return Success; 1613} 1614 1615static int 1616ProcXDGACopyArea(ClientPtr client) 1617{ 1618 REQUEST(xXDGACopyAreaReq); 1619 1620 REQUEST_SIZE_MATCH(xXDGACopyAreaReq); 1621 1622 if (stuff->screen >= screenInfo.numScreens) 1623 return BadValue; 1624 1625 if (DGA_GETCLIENT(stuff->screen) != client) 1626 return DGAErrorBase + XF86DGADirectNotActivated; 1627 1628 if (Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy, 1629 stuff->width, stuff->height, stuff->dstx, 1630 stuff->dsty)) 1631 return BadMatch; 1632 1633 return Success; 1634} 1635 1636static int 1637ProcXDGACopyTransparentArea(ClientPtr client) 1638{ 1639 REQUEST(xXDGACopyTransparentAreaReq); 1640 1641 REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq); 1642 1643 if (stuff->screen >= screenInfo.numScreens) 1644 return BadValue; 1645 1646 if (DGA_GETCLIENT(stuff->screen) != client) 1647 return DGAErrorBase + XF86DGADirectNotActivated; 1648 1649 if (Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy, 1650 stuff->width, stuff->height, stuff->dstx, 1651 stuff->dsty, stuff->key)) 1652 return BadMatch; 1653 1654 return Success; 1655} 1656 1657static int 1658ProcXDGAGetViewportStatus(ClientPtr client) 1659{ 1660 REQUEST(xXDGAGetViewportStatusReq); 1661 xXDGAGetViewportStatusReply rep; 1662 1663 REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq); 1664 1665 if (stuff->screen >= screenInfo.numScreens) 1666 return BadValue; 1667 1668 if (DGA_GETCLIENT(stuff->screen) != client) 1669 return DGAErrorBase + XF86DGADirectNotActivated; 1670 1671 rep.type = X_Reply; 1672 rep.length = 0; 1673 rep.sequenceNumber = client->sequence; 1674 1675 rep.status = DGAGetViewportStatus(stuff->screen); 1676 1677 WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *) &rep); 1678 return Success; 1679} 1680 1681static int 1682ProcXDGASync(ClientPtr client) 1683{ 1684 REQUEST(xXDGASyncReq); 1685 xXDGASyncReply rep; 1686 1687 REQUEST_SIZE_MATCH(xXDGASyncReq); 1688 1689 if (stuff->screen >= screenInfo.numScreens) 1690 return BadValue; 1691 1692 if (DGA_GETCLIENT(stuff->screen) != client) 1693 return DGAErrorBase + XF86DGADirectNotActivated; 1694 1695 rep.type = X_Reply; 1696 rep.length = 0; 1697 rep.sequenceNumber = client->sequence; 1698 1699 DGASync(stuff->screen); 1700 1701 WriteToClient(client, sizeof(xXDGASyncReply), (char *) &rep); 1702 return Success; 1703} 1704 1705static int 1706ProcXDGASetClientVersion(ClientPtr client) 1707{ 1708 REQUEST(xXDGASetClientVersionReq); 1709 1710 DGAPrivPtr pPriv; 1711 1712 REQUEST_SIZE_MATCH(xXDGASetClientVersionReq); 1713 if ((pPriv = DGA_GETPRIV(client)) == NULL) { 1714 pPriv = malloc(sizeof(DGAPrivRec)); 1715 /* XXX Need to look into freeing this */ 1716 if (!pPriv) 1717 return BadAlloc; 1718 DGA_SETPRIV(client, pPriv); 1719 } 1720 pPriv->major = stuff->major; 1721 pPriv->minor = stuff->minor; 1722 1723 return Success; 1724} 1725 1726static int 1727ProcXDGAChangePixmapMode(ClientPtr client) 1728{ 1729 REQUEST(xXDGAChangePixmapModeReq); 1730 xXDGAChangePixmapModeReply rep; 1731 int x, y; 1732 1733 REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq); 1734 1735 if (stuff->screen >= screenInfo.numScreens) 1736 return BadValue; 1737 1738 if (DGA_GETCLIENT(stuff->screen) != client) 1739 return DGAErrorBase + XF86DGADirectNotActivated; 1740 1741 rep.type = X_Reply; 1742 rep.length = 0; 1743 rep.sequenceNumber = client->sequence; 1744 1745 x = stuff->x; 1746 y = stuff->y; 1747 1748 if (!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags)) 1749 return BadMatch; 1750 1751 rep.x = x; 1752 rep.y = y; 1753 WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *) &rep); 1754 1755 return Success; 1756} 1757 1758static int 1759ProcXDGACreateColormap(ClientPtr client) 1760{ 1761 REQUEST(xXDGACreateColormapReq); 1762 int result; 1763 1764 REQUEST_SIZE_MATCH(xXDGACreateColormapReq); 1765 1766 if (stuff->screen >= screenInfo.numScreens) 1767 return BadValue; 1768 1769 if (DGA_GETCLIENT(stuff->screen) != client) 1770 return DGAErrorBase + XF86DGADirectNotActivated; 1771 1772 if (!stuff->mode) 1773 return BadValue; 1774 1775 result = DGACreateColormap(stuff->screen, client, stuff->id, 1776 stuff->mode, stuff->alloc); 1777 if (result != Success) 1778 return result; 1779 1780 return Success; 1781} 1782 1783/* 1784 * 1785 * Support for the old DGA protocol, used to live in xf86dga.c 1786 * 1787 */ 1788 1789#ifdef DGA_PROTOCOL_OLD_SUPPORT 1790 1791static int 1792ProcXF86DGAGetVideoLL(ClientPtr client) 1793{ 1794 REQUEST(xXF86DGAGetVideoLLReq); 1795 xXF86DGAGetVideoLLReply rep; 1796 XDGAModeRec mode; 1797 int num, offset, flags; 1798 char *name; 1799 1800 REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq); 1801 1802 if (stuff->screen >= screenInfo.numScreens) 1803 return BadValue; 1804 1805 rep.type = X_Reply; 1806 rep.length = 0; 1807 rep.sequenceNumber = client->sequence; 1808 1809 if (!DGAAvailable(stuff->screen)) 1810 return DGAErrorBase + XF86DGANoDirectVideoMode; 1811 1812 if (!(num = DGAGetOldDGAMode(stuff->screen))) 1813 return DGAErrorBase + XF86DGANoDirectVideoMode; 1814 1815 /* get the parameters for the mode that best matches */ 1816 DGAGetModeInfo(stuff->screen, &mode, num); 1817 1818 if (!DGAOpenFramebuffer(stuff->screen, &name, 1819 (unsigned char **) (&rep.offset), 1820 (int *) (&rep.bank_size), &offset, &flags)) 1821 return BadAlloc; 1822 1823 rep.offset += mode.offset; 1824 rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3); 1825 rep.ram_size = rep.bank_size >> 10; 1826 1827 WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *) &rep); 1828 return Success; 1829} 1830 1831static int 1832ProcXF86DGADirectVideo(ClientPtr client) 1833{ 1834 int num; 1835 PixmapPtr pix; 1836 XDGAModeRec mode; 1837 ClientPtr owner; 1838 1839 REQUEST(xXF86DGADirectVideoReq); 1840 1841 REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq); 1842 1843 if (stuff->screen >= screenInfo.numScreens) 1844 return BadValue; 1845 1846 if (!DGAAvailable(stuff->screen)) 1847 return DGAErrorBase + XF86DGANoDirectVideoMode; 1848 1849 owner = DGA_GETCLIENT(stuff->screen); 1850 1851 if (owner && owner != client) 1852 return DGAErrorBase + XF86DGANoDirectVideoMode; 1853 1854 if (stuff->enable & XF86DGADirectGraphics) { 1855 if (!(num = DGAGetOldDGAMode(stuff->screen))) 1856 return DGAErrorBase + XF86DGANoDirectVideoMode; 1857 } 1858 else 1859 num = 0; 1860 1861 if (Success != DGASetMode(stuff->screen, num, &mode, &pix)) 1862 return DGAErrorBase + XF86DGAScreenNotActive; 1863 1864 DGASetInputMode(stuff->screen, 1865 (stuff->enable & XF86DGADirectKeyb) != 0, 1866 (stuff->enable & XF86DGADirectMouse) != 0); 1867 1868 /* We need to track the client and attach the teardown callback */ 1869 if (stuff->enable & 1870 (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) { 1871 if (!owner) { 1872 if (DGACallbackRefCount++ == 0) 1873 AddCallback(&ClientStateCallback, DGAClientStateChange, NULL); 1874 } 1875 1876 DGA_SETCLIENT(stuff->screen, client); 1877 } 1878 else { 1879 if (owner) { 1880 if (--DGACallbackRefCount == 0) 1881 DeleteCallback(&ClientStateCallback, DGAClientStateChange, 1882 NULL); 1883 } 1884 1885 DGA_SETCLIENT(stuff->screen, NULL); 1886 } 1887 1888 return Success; 1889} 1890 1891static int 1892ProcXF86DGAGetViewPortSize(ClientPtr client) 1893{ 1894 int num; 1895 XDGAModeRec mode; 1896 1897 REQUEST(xXF86DGAGetViewPortSizeReq); 1898 xXF86DGAGetViewPortSizeReply rep; 1899 1900 REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq); 1901 1902 if (stuff->screen >= screenInfo.numScreens) 1903 return BadValue; 1904 1905 rep.type = X_Reply; 1906 rep.length = 0; 1907 rep.sequenceNumber = client->sequence; 1908 1909 if (!DGAAvailable(stuff->screen)) 1910 return DGAErrorBase + XF86DGANoDirectVideoMode; 1911 1912 if (!(num = DGAGetOldDGAMode(stuff->screen))) 1913 return DGAErrorBase + XF86DGANoDirectVideoMode; 1914 1915 DGAGetModeInfo(stuff->screen, &mode, num); 1916 1917 rep.width = mode.viewportWidth; 1918 rep.height = mode.viewportHeight; 1919 1920 WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *) &rep); 1921 return Success; 1922} 1923 1924static int 1925ProcXF86DGASetViewPort(ClientPtr client) 1926{ 1927 REQUEST(xXF86DGASetViewPortReq); 1928 1929 REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq); 1930 1931 if (stuff->screen >= screenInfo.numScreens) 1932 return BadValue; 1933 1934 if (DGA_GETCLIENT(stuff->screen) != client) 1935 return DGAErrorBase + XF86DGADirectNotActivated; 1936 1937 if (!DGAAvailable(stuff->screen)) 1938 return DGAErrorBase + XF86DGANoDirectVideoMode; 1939 1940 if (!DGAActive(stuff->screen)) 1941 return DGAErrorBase + XF86DGADirectNotActivated; 1942 1943 if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE) 1944 != Success) 1945 return DGAErrorBase + XF86DGADirectNotActivated; 1946 1947 return Success; 1948} 1949 1950static int 1951ProcXF86DGAGetVidPage(ClientPtr client) 1952{ 1953 REQUEST(xXF86DGAGetVidPageReq); 1954 xXF86DGAGetVidPageReply rep; 1955 1956 REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq); 1957 1958 if (stuff->screen >= screenInfo.numScreens) 1959 return BadValue; 1960 1961 rep.type = X_Reply; 1962 rep.length = 0; 1963 rep.sequenceNumber = client->sequence; 1964 rep.vpage = 0; /* silently fail */ 1965 1966 WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *) &rep); 1967 return Success; 1968} 1969 1970static int 1971ProcXF86DGASetVidPage(ClientPtr client) 1972{ 1973 REQUEST(xXF86DGASetVidPageReq); 1974 1975 REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq); 1976 1977 if (stuff->screen >= screenInfo.numScreens) 1978 return BadValue; 1979 1980 /* silently fail */ 1981 1982 return Success; 1983} 1984 1985static int 1986ProcXF86DGAInstallColormap(ClientPtr client) 1987{ 1988 ColormapPtr pcmp; 1989 int rc; 1990 1991 REQUEST(xXF86DGAInstallColormapReq); 1992 1993 REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq); 1994 1995 if (stuff->screen >= screenInfo.numScreens) 1996 return BadValue; 1997 1998 if (DGA_GETCLIENT(stuff->screen) != client) 1999 return DGAErrorBase + XF86DGADirectNotActivated; 2000 2001 if (!DGAActive(stuff->screen)) 2002 return DGAErrorBase + XF86DGADirectNotActivated; 2003 2004 rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP, 2005 client, DixInstallAccess); 2006 if (rc == Success) { 2007 DGAInstallCmap(pcmp); 2008 return Success; 2009 } 2010 else { 2011 return rc; 2012 } 2013} 2014 2015static int 2016ProcXF86DGAQueryDirectVideo(ClientPtr client) 2017{ 2018 REQUEST(xXF86DGAQueryDirectVideoReq); 2019 xXF86DGAQueryDirectVideoReply rep; 2020 2021 REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq); 2022 2023 if (stuff->screen >= screenInfo.numScreens) 2024 return BadValue; 2025 2026 rep.type = X_Reply; 2027 rep.length = 0; 2028 rep.sequenceNumber = client->sequence; 2029 rep.flags = 0; 2030 2031 if (DGAAvailable(stuff->screen)) 2032 rep.flags = XF86DGADirectPresent; 2033 2034 WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *) &rep); 2035 return Success; 2036} 2037 2038static int 2039ProcXF86DGAViewPortChanged(ClientPtr client) 2040{ 2041 REQUEST(xXF86DGAViewPortChangedReq); 2042 xXF86DGAViewPortChangedReply rep; 2043 2044 REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq); 2045 2046 if (stuff->screen >= screenInfo.numScreens) 2047 return BadValue; 2048 2049 if (DGA_GETCLIENT(stuff->screen) != client) 2050 return DGAErrorBase + XF86DGADirectNotActivated; 2051 2052 if (!DGAActive(stuff->screen)) 2053 return DGAErrorBase + XF86DGADirectNotActivated; 2054 2055 rep.type = X_Reply; 2056 rep.length = 0; 2057 rep.sequenceNumber = client->sequence; 2058 rep.result = 1; 2059 2060 WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *) &rep); 2061 return Success; 2062} 2063 2064#endif /* DGA_PROTOCOL_OLD_SUPPORT */ 2065 2066static int 2067SProcXDGADispatch(ClientPtr client) 2068{ 2069 return DGAErrorBase + XF86DGAClientNotLocal; 2070} 2071 2072#if 0 2073#define DGA_REQ_DEBUG 2074#endif 2075 2076#ifdef DGA_REQ_DEBUG 2077static char *dgaMinor[] = { 2078 "QueryVersion", 2079 "GetVideoLL", 2080 "DirectVideo", 2081 "GetViewPortSize", 2082 "SetViewPort", 2083 "GetVidPage", 2084 "SetVidPage", 2085 "InstallColormap", 2086 "QueryDirectVideo", 2087 "ViewPortChanged", 2088 "10", 2089 "11", 2090 "QueryModes", 2091 "SetMode", 2092 "SetViewport", 2093 "InstallColormap", 2094 "SelectInput", 2095 "FillRectangle", 2096 "CopyArea", 2097 "CopyTransparentArea", 2098 "GetViewportStatus", 2099 "Sync", 2100 "OpenFramebuffer", 2101 "CloseFramebuffer", 2102 "SetClientVersion", 2103 "ChangePixmapMode", 2104 "CreateColormap", 2105}; 2106#endif 2107 2108static int 2109ProcXDGADispatch(ClientPtr client) 2110{ 2111 REQUEST(xReq); 2112 2113 if (!client->local) 2114 return DGAErrorBase + XF86DGAClientNotLocal; 2115 2116#ifdef DGA_REQ_DEBUG 2117 if (stuff->data <= X_XDGACreateColormap) 2118 fprintf(stderr, " DGA %s\n", dgaMinor[stuff->data]); 2119#endif 2120 2121 switch (stuff->data) { 2122 /* 2123 * DGA2 Protocol 2124 */ 2125 case X_XDGAQueryVersion: 2126 return ProcXDGAQueryVersion(client); 2127 case X_XDGAQueryModes: 2128 return ProcXDGAQueryModes(client); 2129 case X_XDGASetMode: 2130 return ProcXDGASetMode(client); 2131 case X_XDGAOpenFramebuffer: 2132 return ProcXDGAOpenFramebuffer(client); 2133 case X_XDGACloseFramebuffer: 2134 return ProcXDGACloseFramebuffer(client); 2135 case X_XDGASetViewport: 2136 return ProcXDGASetViewport(client); 2137 case X_XDGAInstallColormap: 2138 return ProcXDGAInstallColormap(client); 2139 case X_XDGASelectInput: 2140 return ProcXDGASelectInput(client); 2141 case X_XDGAFillRectangle: 2142 return ProcXDGAFillRectangle(client); 2143 case X_XDGACopyArea: 2144 return ProcXDGACopyArea(client); 2145 case X_XDGACopyTransparentArea: 2146 return ProcXDGACopyTransparentArea(client); 2147 case X_XDGAGetViewportStatus: 2148 return ProcXDGAGetViewportStatus(client); 2149 case X_XDGASync: 2150 return ProcXDGASync(client); 2151 case X_XDGASetClientVersion: 2152 return ProcXDGASetClientVersion(client); 2153 case X_XDGAChangePixmapMode: 2154 return ProcXDGAChangePixmapMode(client); 2155 case X_XDGACreateColormap: 2156 return ProcXDGACreateColormap(client); 2157 /* 2158 * Old DGA Protocol 2159 */ 2160#ifdef DGA_PROTOCOL_OLD_SUPPORT 2161 case X_XF86DGAGetVideoLL: 2162 return ProcXF86DGAGetVideoLL(client); 2163 case X_XF86DGADirectVideo: 2164 return ProcXF86DGADirectVideo(client); 2165 case X_XF86DGAGetViewPortSize: 2166 return ProcXF86DGAGetViewPortSize(client); 2167 case X_XF86DGASetViewPort: 2168 return ProcXF86DGASetViewPort(client); 2169 case X_XF86DGAGetVidPage: 2170 return ProcXF86DGAGetVidPage(client); 2171 case X_XF86DGASetVidPage: 2172 return ProcXF86DGASetVidPage(client); 2173 case X_XF86DGAInstallColormap: 2174 return ProcXF86DGAInstallColormap(client); 2175 case X_XF86DGAQueryDirectVideo: 2176 return ProcXF86DGAQueryDirectVideo(client); 2177 case X_XF86DGAViewPortChanged: 2178 return ProcXF86DGAViewPortChanged(client); 2179#endif /* DGA_PROTOCOL_OLD_SUPPORT */ 2180 default: 2181 return BadRequest; 2182 } 2183} 2184 2185void 2186XFree86DGAExtensionInit(void) 2187{ 2188 ExtensionEntry *extEntry; 2189 2190 if (!dixRegisterPrivateKey(&DGAClientPrivateKeyRec, PRIVATE_CLIENT, 0)) 2191 return; 2192 2193 if (!dixRegisterPrivateKey(&DGAScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 2194 return; 2195 2196 if ((extEntry = AddExtension(XF86DGANAME, 2197 XF86DGANumberEvents, 2198 XF86DGANumberErrors, 2199 ProcXDGADispatch, 2200 SProcXDGADispatch, 2201 XDGAResetProc, StandardMinorOpcode))) { 2202 int i; 2203 2204 DGAReqCode = (unsigned char) extEntry->base; 2205 DGAErrorBase = extEntry->errorBase; 2206 DGAEventBase = extEntry->eventBase; 2207 for (i = KeyPress; i <= MotionNotify; i++) 2208 SetCriticalEvent(DGAEventBase + i); 2209 } 2210} 2211