xorg_driver.c revision c0cf0fd163397d68acfb2e226a6b9a569ded54cd
1/* 2 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * 26 * Author: Alan Hourihane <alanh@tungstengraphics.com> 27 * Author: Jakob Bornecrantz <wallbraker@gmail.com> 28 * 29 */ 30 31 32#include "xorg-server.h" 33#include "xf86.h" 34#include "xf86_OSproc.h" 35#include "compiler.h" 36#include "xf86PciInfo.h" 37#include "xf86Pci.h" 38#include "mipointer.h" 39#include "micmap.h" 40#include <X11/extensions/randr.h> 41#include "fb.h" 42#include "edid.h" 43#include "xf86i2c.h" 44#include "xf86Crtc.h" 45#include "miscstruct.h" 46#include "dixstruct.h" 47#include "xf86xv.h" 48#include <X11/extensions/Xv.h> 49#ifndef XSERVER_LIBPCIACCESS 50#error "libpciaccess needed" 51#endif 52 53#include <pciaccess.h> 54 55#include "pipe/p_context.h" 56#include "xorg_tracker.h" 57#include "xorg_winsys.h" 58 59static void AdjustFrame(int scrnIndex, int x, int y, int flags); 60static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen); 61static Bool EnterVT(int scrnIndex, int flags); 62static Bool SaveHWState(ScrnInfoPtr pScrn); 63static Bool RestoreHWState(ScrnInfoPtr pScrn); 64 65 66static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, 67 int flags); 68static void FreeScreen(int scrnIndex, int flags); 69static void LeaveVT(int scrnIndex, int flags); 70static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); 71static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 72 char **argv); 73static Bool PreInit(ScrnInfoPtr pScrn, int flags); 74 75typedef enum 76{ 77 OPTION_SW_CURSOR, 78} modesettingOpts; 79 80static const OptionInfoRec Options[] = { 81 {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, 82 {-1, NULL, OPTV_NONE, {0}, FALSE} 83}; 84 85/* 86 * Exported Xorg driver functions to winsys 87 */ 88 89const OptionInfoRec * 90xorg_tracker_available_options(int chipid, int busid) 91{ 92 return Options; 93} 94 95void 96xorg_tracker_set_functions(ScrnInfoPtr scrn) 97{ 98 scrn->PreInit = PreInit; 99 scrn->ScreenInit = ScreenInit; 100 scrn->SwitchMode = SwitchMode; 101 scrn->AdjustFrame = AdjustFrame; 102 scrn->EnterVT = EnterVT; 103 scrn->LeaveVT = LeaveVT; 104 scrn->FreeScreen = FreeScreen; 105 scrn->ValidMode = ValidMode; 106} 107 108/* 109 * Static Xorg funtctions 110 */ 111 112static Bool 113GetRec(ScrnInfoPtr pScrn) 114{ 115 if (pScrn->driverPrivate) 116 return TRUE; 117 118 pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); 119 120 return TRUE; 121} 122 123static void 124FreeRec(ScrnInfoPtr pScrn) 125{ 126 if (!pScrn) 127 return; 128 129 if (!pScrn->driverPrivate) 130 return; 131 132 xfree(pScrn->driverPrivate); 133 134 pScrn->driverPrivate = NULL; 135} 136 137static void 138ProbeDDC(ScrnInfoPtr pScrn, int index) 139{ 140 ConfiguredMonitor = NULL; 141} 142 143static Bool 144CreateFrontBuffer(ScrnInfoPtr pScrn) 145{ 146 modesettingPtr ms = modesettingPTR(pScrn); 147 ScreenPtr pScreen = pScrn->pScreen; 148 PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); 149 unsigned handle, stride; 150 151 ms->noEvict = TRUE; 152 xorg_exa_set_displayed_usage(rootPixmap); 153 pScreen->ModifyPixmapHeader(rootPixmap, 154 pScrn->virtualX, pScrn->virtualY, 155 pScrn->depth, pScrn->bitsPerPixel, 156 pScrn->displayWidth * pScrn->bitsPerPixel / 8, 157 NULL); 158 ms->noEvict = FALSE; 159 160 handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride); 161 162 drmModeAddFB(ms->fd, 163 pScrn->virtualX, 164 pScrn->virtualY, 165 pScrn->depth, 166 pScrn->bitsPerPixel, 167 stride, 168 handle, 169 &ms->fb_id); 170 171 pScrn->frameX0 = 0; 172 pScrn->frameY0 = 0; 173 AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 174 175 return TRUE; 176} 177 178static Bool 179crtc_resize(ScrnInfoPtr pScrn, int width, int height) 180{ 181 modesettingPtr ms = modesettingPTR(pScrn); 182 //ScreenPtr pScreen = pScrn->pScreen; 183 //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); 184 //Bool fbAccessDisabled; 185 //CARD8 *fbstart; 186 187 if (width == pScrn->virtualX && height == pScrn->virtualY) 188 return TRUE; 189 190 ErrorF("RESIZING TO %dx%d\n", width, height); 191 192 pScrn->virtualX = width; 193 pScrn->virtualY = height; 194 195 /* HW dependent - FIXME */ 196 pScrn->displayWidth = pScrn->virtualX; 197 198 drmModeRmFB(ms->fd, ms->fb_id); 199 200 /* now create new frontbuffer */ 201 return CreateFrontBuffer(pScrn); 202} 203 204static const xf86CrtcConfigFuncsRec crtc_config_funcs = { 205 crtc_resize 206}; 207 208static Bool 209PreInit(ScrnInfoPtr pScrn, int flags) 210{ 211 xf86CrtcConfigPtr xf86_config; 212 modesettingPtr ms; 213 rgb defaultWeight = { 0, 0, 0 }; 214 EntityInfoPtr pEnt; 215 EntPtr msEnt = NULL; 216 char *BusID; 217 int max_width, max_height; 218 219 if (pScrn->numEntities != 1) 220 return FALSE; 221 222 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 223 224 if (flags & PROBE_DETECT) { 225 ProbeDDC(pScrn, pEnt->index); 226 return TRUE; 227 } 228 229 /* Allocate driverPrivate */ 230 if (!GetRec(pScrn)) 231 return FALSE; 232 233 ms = modesettingPTR(pScrn); 234 ms->SaveGeneration = -1; 235 ms->pEnt = pEnt; 236 237 pScrn->displayWidth = 640; /* default it */ 238 239 if (ms->pEnt->location.type != BUS_PCI) 240 return FALSE; 241 242 ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); 243 244 /* Allocate an entity private if necessary */ 245 if (xf86IsEntityShared(pScrn->entityList[0])) { 246 FatalError("Entity"); 247#if 0 248 msEnt = xf86GetEntityPrivate(pScrn->entityList[0], 249 modesettingEntityIndex)->ptr; 250 ms->entityPrivate = msEnt; 251#else 252 (void)msEnt; 253#endif 254 } else 255 ms->entityPrivate = NULL; 256 257 if (xf86IsEntityShared(pScrn->entityList[0])) { 258 if (xf86IsPrimInitDone(pScrn->entityList[0])) { 259 /* do something */ 260 } else { 261 xf86SetPrimInitDone(pScrn->entityList[0]); 262 } 263 } 264 265 BusID = xalloc(64); 266 sprintf(BusID, "PCI:%d:%d:%d", 267 ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), 268 ms->PciInfo->dev, ms->PciInfo->func 269 ); 270 271 ms->api = drm_api_create(); 272 ms->fd = drmOpen(NULL, BusID); 273 274 if (ms->fd < 0) 275 return FALSE; 276 277 pScrn->monitor = pScrn->confScreen->monitor; 278 pScrn->progClock = TRUE; 279 pScrn->rgbBits = 8; 280 281 if (!xf86SetDepthBpp 282 (pScrn, 0, 0, 0, 283 PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) 284 return FALSE; 285 286 switch (pScrn->depth) { 287 case 15: 288 case 16: 289 case 24: 290 break; 291 default: 292 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 293 "Given depth (%d) is not supported by the driver\n", 294 pScrn->depth); 295 return FALSE; 296 } 297 xf86PrintDepthBpp(pScrn); 298 299 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) 300 return FALSE; 301 if (!xf86SetDefaultVisual(pScrn, -1)) 302 return FALSE; 303 304 /* Process the options */ 305 xf86CollectOptions(pScrn, NULL); 306 if (!(ms->Options = xalloc(sizeof(Options)))) 307 return FALSE; 308 memcpy(ms->Options, Options, sizeof(Options)); 309 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); 310 311 /* Allocate an xf86CrtcConfig */ 312 xf86CrtcConfigInit(pScrn, &crtc_config_funcs); 313 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 314 315 max_width = 8192; 316 max_height = 8192; 317 xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); 318 319 if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { 320 ms->SWCursor = TRUE; 321 } 322 323 SaveHWState(pScrn); 324 325 crtc_init(pScrn); 326 output_init(pScrn); 327 328 if (!xf86InitialConfiguration(pScrn, TRUE)) { 329 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); 330 RestoreHWState(pScrn); 331 return FALSE; 332 } 333 334 RestoreHWState(pScrn); 335 336 /* 337 * If the driver can do gamma correction, it should call xf86SetGamma() here. 338 */ 339 { 340 Gamma zeros = { 0.0, 0.0, 0.0 }; 341 342 if (!xf86SetGamma(pScrn, zeros)) { 343 return FALSE; 344 } 345 } 346 347 if (pScrn->modes == NULL) { 348 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); 349 return FALSE; 350 } 351 352 pScrn->currentMode = pScrn->modes; 353 354 /* Set display resolution */ 355 xf86SetDpi(pScrn, 0, 0); 356 357 /* Load the required sub modules */ 358 if (!xf86LoadSubModule(pScrn, "fb")) { 359 return FALSE; 360 } 361 362 xf86LoadSubModule(pScrn, "exa"); 363 364#ifdef DRI2 365 xf86LoadSubModule(pScrn, "dri2"); 366#endif 367 368 return TRUE; 369} 370 371static Bool 372SaveHWState(ScrnInfoPtr pScrn) 373{ 374 /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/ 375 376 return TRUE; 377} 378 379static Bool 380RestoreHWState(ScrnInfoPtr pScrn) 381{ 382 /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/ 383 384 return TRUE; 385} 386 387static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout, 388 pointer pReadmask) 389{ 390 ScreenPtr pScreen = screenInfo.screens[i]; 391 modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]); 392 393 pScreen->BlockHandler = ms->blockHandler; 394 pScreen->BlockHandler(i, blockData, pTimeout, pReadmask); 395 pScreen->BlockHandler = xorgBlockHandler; 396 397 ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL); 398 399#ifdef DRM_MODE_FEATURE_DIRTYFB 400 { 401 RegionPtr dirty = DamageRegion(ms->damage); 402 unsigned num_cliprects = REGION_NUM_RECTS(dirty); 403 404 if (num_cliprects) { 405 drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip)); 406 BoxPtr rect = REGION_RECTS(dirty); 407 int i; 408 409 for (i = 0; i < num_cliprects; i++, rect++) { 410 clip[i].x = rect->x1; 411 clip[i].y = rect->y1; 412 clip[i].width = rect->x2 - rect->x1; 413 clip[i].height = rect->y2 - rect->y1; 414 } 415 416 /* TODO query connector property to see if this is needed */ 417 drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects); 418 419 DamageEmpty(ms->damage); 420 } 421 } 422#endif 423} 424 425static Bool 426CreateScreenResources(ScreenPtr pScreen) 427{ 428 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 429 modesettingPtr ms = modesettingPTR(pScrn); 430 PixmapPtr rootPixmap; 431 Bool ret; 432 unsigned handle, stride; 433 434 ms->noEvict = TRUE; 435 436 pScreen->CreateScreenResources = ms->createScreenResources; 437 ret = pScreen->CreateScreenResources(pScreen); 438 pScreen->CreateScreenResources = CreateScreenResources; 439 440 rootPixmap = pScreen->GetScreenPixmap(pScreen); 441 442 xorg_exa_set_displayed_usage(rootPixmap); 443 xorg_exa_set_shared_usage(rootPixmap); 444 if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) 445 FatalError("Couldn't adjust screen pixmap\n"); 446 447 ms->noEvict = FALSE; 448 449 handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride); 450 451 drmModeAddFB(ms->fd, 452 pScrn->virtualX, 453 pScrn->virtualY, 454 pScrn->depth, 455 pScrn->bitsPerPixel, 456 stride, 457 handle, 458 &ms->fb_id); 459 460 AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 461 462#ifdef DRM_MODE_FEATURE_DIRTYFB 463 ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, 464 pScreen, rootPixmap); 465 466 if (ms->damage) { 467 DamageRegister(&rootPixmap->drawable, ms->damage); 468 469 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); 470 } else { 471 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 472 "Failed to create screen damage record\n"); 473 return FALSE; 474 } 475#endif 476 477 return ret; 478} 479 480static Bool 481ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 482{ 483 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 484 modesettingPtr ms = modesettingPTR(pScrn); 485 VisualPtr visual; 486 487 /* deal with server regeneration */ 488 if (ms->fd < 0) { 489 char *BusID; 490 491 BusID = xalloc(64); 492 sprintf(BusID, "PCI:%d:%d:%d", 493 ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), 494 ms->PciInfo->dev, ms->PciInfo->func 495 ); 496 497 ms->fd = drmOpen(NULL, BusID); 498 499 if (ms->fd < 0) 500 return FALSE; 501 } 502 503 if (!ms->screen) { 504 ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL); 505 506 if (!ms->screen) { 507 FatalError("Could not init pipe_screen\n"); 508 return FALSE; 509 } 510 } 511 512 pScrn->pScreen = pScreen; 513 514 /* HW dependent - FIXME */ 515 pScrn->displayWidth = pScrn->virtualX; 516 517 miClearVisualTypes(); 518 519 if (!miSetVisualTypes(pScrn->depth, 520 miGetDefaultVisualMask(pScrn->depth), 521 pScrn->rgbBits, pScrn->defaultVisual)) 522 return FALSE; 523 524 if (!miSetPixmapDepths()) 525 return FALSE; 526 527 pScrn->memPhysBase = 0; 528 pScrn->fbOffset = 0; 529 530 if (!fbScreenInit(pScreen, NULL, 531 pScrn->virtualX, pScrn->virtualY, 532 pScrn->xDpi, pScrn->yDpi, 533 pScrn->displayWidth, pScrn->bitsPerPixel)) 534 return FALSE; 535 536 if (pScrn->bitsPerPixel > 8) { 537 /* Fixup RGB ordering */ 538 visual = pScreen->visuals + pScreen->numVisuals; 539 while (--visual >= pScreen->visuals) { 540 if ((visual->class | DynamicClass) == DirectColor) { 541 visual->offsetRed = pScrn->offset.red; 542 visual->offsetGreen = pScrn->offset.green; 543 visual->offsetBlue = pScrn->offset.blue; 544 visual->redMask = pScrn->mask.red; 545 visual->greenMask = pScrn->mask.green; 546 visual->blueMask = pScrn->mask.blue; 547 } 548 } 549 } 550 551 fbPictureInit(pScreen, NULL, 0); 552 553 ms->blockHandler = pScreen->BlockHandler; 554 pScreen->BlockHandler = xorgBlockHandler; 555 ms->createScreenResources = pScreen->CreateScreenResources; 556 pScreen->CreateScreenResources = CreateScreenResources; 557 558 xf86SetBlackWhitePixels(pScreen); 559 560 ms->exa = xorg_exa_init(pScrn); 561 562 miInitializeBackingStore(pScreen); 563 xf86SetBackingStore(pScreen); 564 xf86SetSilkenMouse(pScreen); 565 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 566 567 /* Need to extend HWcursor support to handle mask interleave */ 568 if (!ms->SWCursor) 569 xf86_cursors_init(pScreen, 64, 64, 570 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 571 HARDWARE_CURSOR_ARGB); 572 573 /* Must force it before EnterVT, so we are in control of VT and 574 * later memory should be bound when allocating, e.g rotate_mem */ 575 pScrn->vtSema = TRUE; 576 577 pScreen->SaveScreen = xf86SaveScreen; 578 ms->CloseScreen = pScreen->CloseScreen; 579 pScreen->CloseScreen = CloseScreen; 580 581 if (!xf86CrtcScreenInit(pScreen)) 582 return FALSE; 583 584 if (!miCreateDefColormap(pScreen)) 585 return FALSE; 586 587 xf86DPMSInit(pScreen, xf86DPMSSet, 0); 588 589 if (serverGeneration == 1) 590 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 591 592#if 1 593#ifdef DRI2 594 driScreenInit(pScreen); 595#endif 596#endif 597 598 return EnterVT(scrnIndex, 1); 599} 600 601static void 602AdjustFrame(int scrnIndex, int x, int y, int flags) 603{ 604 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 605 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 606 xf86OutputPtr output = config->output[config->compat_output]; 607 xf86CrtcPtr crtc = output->crtc; 608 609 if (crtc && crtc->enabled) { 610 crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, 611 y); 612 crtc->x = output->initial_x + x; 613 crtc->y = output->initial_y + y; 614 } 615} 616 617static void 618FreeScreen(int scrnIndex, int flags) 619{ 620 FreeRec(xf86Screens[scrnIndex]); 621} 622 623static void 624LeaveVT(int scrnIndex, int flags) 625{ 626 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 627 modesettingPtr ms = modesettingPTR(pScrn); 628 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 629 int o; 630 631 for (o = 0; o < config->num_crtc; o++) { 632 xf86CrtcPtr crtc = config->crtc[o]; 633 634 crtc_cursor_destroy(crtc); 635 636 if (crtc->rotatedPixmap || crtc->rotatedData) { 637 crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, 638 crtc->rotatedData); 639 crtc->rotatedPixmap = NULL; 640 crtc->rotatedData = NULL; 641 } 642 } 643 644 drmModeRmFB(ms->fd, ms->fb_id); 645 646 RestoreHWState(pScrn); 647 648 if (drmDropMaster(ms->fd)) 649 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 650 "drmDropMaster failed: %s\n", strerror(errno)); 651 652 pScrn->vtSema = FALSE; 653} 654 655/* 656 * This gets called when gaining control of the VT, and from ScreenInit(). 657 */ 658static Bool 659EnterVT(int scrnIndex, int flags) 660{ 661 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 662 modesettingPtr ms = modesettingPTR(pScrn); 663 664 if (drmSetMaster(ms->fd)) { 665 if (errno == EINVAL) { 666 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 667 "drmSetMaster failed: 2.6.29 or newer kernel required for " 668 "multi-server DRI\n"); 669 } else { 670 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 671 "drmSetMaster failed: %s\n", strerror(errno)); 672 } 673 } 674 675 /* 676 * Only save state once per server generation since that's what most 677 * drivers do. Could change this to save state at each VT enter. 678 */ 679 if (ms->SaveGeneration != serverGeneration) { 680 ms->SaveGeneration = serverGeneration; 681 SaveHWState(pScrn); 682 } 683 684 if (!flags) /* signals startup as we'll do this in CreateScreenResources */ 685 CreateFrontBuffer(pScrn); 686 687 if (!xf86SetDesiredModes(pScrn)) 688 return FALSE; 689 690 return TRUE; 691} 692 693static Bool 694SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 695{ 696 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 697 698 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 699} 700 701static Bool 702CloseScreen(int scrnIndex, ScreenPtr pScreen) 703{ 704 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 705 modesettingPtr ms = modesettingPTR(pScrn); 706 707 if (pScrn->vtSema) { 708 LeaveVT(scrnIndex, 0); 709 } 710#ifdef DRI2 711 driCloseScreen(pScreen); 712#endif 713 714 pScreen->BlockHandler = ms->blockHandler; 715 pScreen->CreateScreenResources = ms->createScreenResources; 716 717#ifdef DRM_MODE_FEATURE_DIRTYFB 718 if (ms->damage) { 719 DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage); 720 DamageDestroy(ms->damage); 721 ms->damage = NULL; 722 } 723#endif 724 725 if (ms->exa) 726 xorg_exa_close(pScrn); 727 728 ms->api->destroy(ms->api); 729 ms->api = NULL; 730 drmClose(ms->fd); 731 ms->fd = -1; 732 733 pScrn->vtSema = FALSE; 734 pScreen->CloseScreen = ms->CloseScreen; 735 return (*pScreen->CloseScreen) (scrnIndex, pScreen); 736} 737 738static ModeStatus 739ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 740{ 741 return MODE_OK; 742} 743 744/* vim: set sw=4 ts=8 sts=4: */ 745