xorg_driver.c revision 2ea061509ddab9054514ad87f28de950fb30dba1
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 /* 183 ScreenPtr pScreen = pScrn->pScreen; 184 PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); 185 Bool fbAccessDisabled; 186 CARD8 *fbstart; 187 */ 188 189 if (width == pScrn->virtualX && height == pScrn->virtualY) 190 return TRUE; 191 192 ErrorF("RESIZING TO %dx%d\n", width, height); 193 194 pScrn->virtualX = width; 195 pScrn->virtualY = height; 196 197 /* HW dependent - FIXME */ 198 pScrn->displayWidth = pScrn->virtualX; 199 200 drmModeRmFB(ms->fd, ms->fb_id); 201 202 /* now create new frontbuffer */ 203 return CreateFrontBuffer(pScrn); 204} 205 206static const xf86CrtcConfigFuncsRec crtc_config_funcs = { 207 crtc_resize 208}; 209 210static Bool 211PreInit(ScrnInfoPtr pScrn, int flags) 212{ 213 xf86CrtcConfigPtr xf86_config; 214 modesettingPtr ms; 215 rgb defaultWeight = { 0, 0, 0 }; 216 EntityInfoPtr pEnt; 217 EntPtr msEnt = NULL; 218 char *BusID; 219 int max_width, max_height; 220 221 if (pScrn->numEntities != 1) 222 return FALSE; 223 224 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 225 226 if (flags & PROBE_DETECT) { 227 ProbeDDC(pScrn, pEnt->index); 228 return TRUE; 229 } 230 231 /* Allocate driverPrivate */ 232 if (!GetRec(pScrn)) 233 return FALSE; 234 235 ms = modesettingPTR(pScrn); 236 ms->SaveGeneration = -1; 237 ms->pEnt = pEnt; 238 239 pScrn->displayWidth = 640; /* default it */ 240 241 if (ms->pEnt->location.type != BUS_PCI) 242 return FALSE; 243 244 ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); 245 246 /* Allocate an entity private if necessary */ 247 if (xf86IsEntityShared(pScrn->entityList[0])) { 248 FatalError("Entity"); 249#if 0 250 msEnt = xf86GetEntityPrivate(pScrn->entityList[0], 251 modesettingEntityIndex)->ptr; 252 ms->entityPrivate = msEnt; 253#else 254 (void)msEnt; 255#endif 256 } else 257 ms->entityPrivate = NULL; 258 259 if (xf86IsEntityShared(pScrn->entityList[0])) { 260 if (xf86IsPrimInitDone(pScrn->entityList[0])) { 261 /* do something */ 262 } else { 263 xf86SetPrimInitDone(pScrn->entityList[0]); 264 } 265 } 266 267 BusID = xalloc(64); 268 sprintf(BusID, "PCI:%d:%d:%d", 269 ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), 270 ms->PciInfo->dev, ms->PciInfo->func 271 ); 272 273 ms->api = drm_api_create(); 274 ms->fd = drmOpen(NULL, BusID); 275 276 if (ms->fd < 0) 277 return FALSE; 278 279 pScrn->monitor = pScrn->confScreen->monitor; 280 pScrn->progClock = TRUE; 281 pScrn->rgbBits = 8; 282 283 if (!xf86SetDepthBpp 284 (pScrn, 0, 0, 0, 285 PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) 286 return FALSE; 287 288 switch (pScrn->depth) { 289 case 15: 290 case 16: 291 case 24: 292 break; 293 default: 294 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 295 "Given depth (%d) is not supported by the driver\n", 296 pScrn->depth); 297 return FALSE; 298 } 299 xf86PrintDepthBpp(pScrn); 300 301 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) 302 return FALSE; 303 if (!xf86SetDefaultVisual(pScrn, -1)) 304 return FALSE; 305 306 /* Process the options */ 307 xf86CollectOptions(pScrn, NULL); 308 if (!(ms->Options = xalloc(sizeof(Options)))) 309 return FALSE; 310 memcpy(ms->Options, Options, sizeof(Options)); 311 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); 312 313 /* Allocate an xf86CrtcConfig */ 314 xf86CrtcConfigInit(pScrn, &crtc_config_funcs); 315 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); 316 317 max_width = 8192; 318 max_height = 8192; 319 xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); 320 321 if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { 322 ms->SWCursor = TRUE; 323 } 324 325 SaveHWState(pScrn); 326 327 crtc_init(pScrn); 328 output_init(pScrn); 329 330 if (!xf86InitialConfiguration(pScrn, TRUE)) { 331 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); 332 RestoreHWState(pScrn); 333 return FALSE; 334 } 335 336 RestoreHWState(pScrn); 337 338 /* 339 * If the driver can do gamma correction, it should call xf86SetGamma() here. 340 */ 341 { 342 Gamma zeros = { 0.0, 0.0, 0.0 }; 343 344 if (!xf86SetGamma(pScrn, zeros)) { 345 return FALSE; 346 } 347 } 348 349 if (pScrn->modes == NULL) { 350 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); 351 return FALSE; 352 } 353 354 pScrn->currentMode = pScrn->modes; 355 356 /* Set display resolution */ 357 xf86SetDpi(pScrn, 0, 0); 358 359 /* Load the required sub modules */ 360 if (!xf86LoadSubModule(pScrn, "fb")) { 361 return FALSE; 362 } 363 364 xf86LoadSubModule(pScrn, "exa"); 365 366#ifdef DRI2 367 xf86LoadSubModule(pScrn, "dri2"); 368#endif 369 370 return TRUE; 371} 372 373static Bool 374SaveHWState(ScrnInfoPtr pScrn) 375{ 376 /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/ 377 378 return TRUE; 379} 380 381static Bool 382RestoreHWState(ScrnInfoPtr pScrn) 383{ 384 /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/ 385 386 return TRUE; 387} 388 389static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout, 390 pointer pReadmask) 391{ 392 ScreenPtr pScreen = screenInfo.screens[i]; 393 modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]); 394 395 pScreen->BlockHandler = ms->blockHandler; 396 pScreen->BlockHandler(i, blockData, pTimeout, pReadmask); 397 pScreen->BlockHandler = xorgBlockHandler; 398 399 ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL); 400 401#ifdef DRM_MODE_FEATURE_DIRTYFB 402 { 403 RegionPtr dirty = DamageRegion(ms->damage); 404 unsigned num_cliprects = REGION_NUM_RECTS(dirty); 405 406 if (num_cliprects) { 407 drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip)); 408 BoxPtr rect = REGION_RECTS(dirty); 409 int i; 410 411 for (i = 0; i < num_cliprects; i++, rect++) { 412 clip[i].x = rect->x1; 413 clip[i].y = rect->y1; 414 clip[i].width = rect->x2 - rect->x1; 415 clip[i].height = rect->y2 - rect->y1; 416 } 417 418 /* TODO query connector property to see if this is needed */ 419 drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects); 420 421 DamageEmpty(ms->damage); 422 } 423 } 424#endif 425} 426 427static Bool 428CreateScreenResources(ScreenPtr pScreen) 429{ 430 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 431 modesettingPtr ms = modesettingPTR(pScrn); 432 PixmapPtr rootPixmap; 433 Bool ret; 434 unsigned handle, stride; 435 436 ms->noEvict = TRUE; 437 438 pScreen->CreateScreenResources = ms->createScreenResources; 439 ret = pScreen->CreateScreenResources(pScreen); 440 pScreen->CreateScreenResources = CreateScreenResources; 441 442 rootPixmap = pScreen->GetScreenPixmap(pScreen); 443 444 xorg_exa_set_displayed_usage(rootPixmap); 445 xorg_exa_set_shared_usage(rootPixmap); 446 if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) 447 FatalError("Couldn't adjust screen pixmap\n"); 448 449 ms->noEvict = FALSE; 450 451 handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride); 452 453 drmModeAddFB(ms->fd, 454 pScrn->virtualX, 455 pScrn->virtualY, 456 pScrn->depth, 457 pScrn->bitsPerPixel, 458 stride, 459 handle, 460 &ms->fb_id); 461 462 AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 463 464#ifdef DRM_MODE_FEATURE_DIRTYFB 465 ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, 466 pScreen, rootPixmap); 467 468 if (ms->damage) { 469 DamageRegister(&rootPixmap->drawable, ms->damage); 470 471 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n"); 472 } else { 473 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 474 "Failed to create screen damage record\n"); 475 return FALSE; 476 } 477#endif 478 479 return ret; 480} 481 482static Bool 483ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) 484{ 485 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 486 modesettingPtr ms = modesettingPTR(pScrn); 487 VisualPtr visual; 488 489 /* deal with server regeneration */ 490 if (ms->fd < 0) { 491 char *BusID; 492 493 BusID = xalloc(64); 494 sprintf(BusID, "PCI:%d:%d:%d", 495 ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), 496 ms->PciInfo->dev, ms->PciInfo->func 497 ); 498 499 ms->fd = drmOpen(NULL, BusID); 500 501 if (ms->fd < 0) 502 return FALSE; 503 } 504 505 if (!ms->screen) { 506 ms->screen = ms->api->create_screen(ms->api, ms->fd, NULL); 507 508 if (!ms->screen) { 509 FatalError("Could not init pipe_screen\n"); 510 return FALSE; 511 } 512 } 513 514 pScrn->pScreen = pScreen; 515 516 /* HW dependent - FIXME */ 517 pScrn->displayWidth = pScrn->virtualX; 518 519 miClearVisualTypes(); 520 521 if (!miSetVisualTypes(pScrn->depth, 522 miGetDefaultVisualMask(pScrn->depth), 523 pScrn->rgbBits, pScrn->defaultVisual)) 524 return FALSE; 525 526 if (!miSetPixmapDepths()) 527 return FALSE; 528 529 pScrn->memPhysBase = 0; 530 pScrn->fbOffset = 0; 531 532 if (!fbScreenInit(pScreen, NULL, 533 pScrn->virtualX, pScrn->virtualY, 534 pScrn->xDpi, pScrn->yDpi, 535 pScrn->displayWidth, pScrn->bitsPerPixel)) 536 return FALSE; 537 538 if (pScrn->bitsPerPixel > 8) { 539 /* Fixup RGB ordering */ 540 visual = pScreen->visuals + pScreen->numVisuals; 541 while (--visual >= pScreen->visuals) { 542 if ((visual->class | DynamicClass) == DirectColor) { 543 visual->offsetRed = pScrn->offset.red; 544 visual->offsetGreen = pScrn->offset.green; 545 visual->offsetBlue = pScrn->offset.blue; 546 visual->redMask = pScrn->mask.red; 547 visual->greenMask = pScrn->mask.green; 548 visual->blueMask = pScrn->mask.blue; 549 } 550 } 551 } 552 553 fbPictureInit(pScreen, NULL, 0); 554 555 ms->blockHandler = pScreen->BlockHandler; 556 pScreen->BlockHandler = xorgBlockHandler; 557 ms->createScreenResources = pScreen->CreateScreenResources; 558 pScreen->CreateScreenResources = CreateScreenResources; 559 560 xf86SetBlackWhitePixels(pScreen); 561 562 ms->exa = xorg_exa_init(pScrn); 563 564 miInitializeBackingStore(pScreen); 565 xf86SetBackingStore(pScreen); 566 xf86SetSilkenMouse(pScreen); 567 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 568 569 /* Need to extend HWcursor support to handle mask interleave */ 570 if (!ms->SWCursor) 571 xf86_cursors_init(pScreen, 64, 64, 572 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 573 HARDWARE_CURSOR_ARGB); 574 575 /* Must force it before EnterVT, so we are in control of VT and 576 * later memory should be bound when allocating, e.g rotate_mem */ 577 pScrn->vtSema = TRUE; 578 579 pScreen->SaveScreen = xf86SaveScreen; 580 ms->CloseScreen = pScreen->CloseScreen; 581 pScreen->CloseScreen = CloseScreen; 582 583 if (!xf86CrtcScreenInit(pScreen)) 584 return FALSE; 585 586 if (!miCreateDefColormap(pScreen)) 587 return FALSE; 588 589 xf86DPMSInit(pScreen, xf86DPMSSet, 0); 590 591 if (serverGeneration == 1) 592 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 593 594#if 1 595#ifdef DRI2 596 driScreenInit(pScreen); 597#endif 598#endif 599 600 return EnterVT(scrnIndex, 1); 601} 602 603static void 604AdjustFrame(int scrnIndex, int x, int y, int flags) 605{ 606 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 607 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 608 xf86OutputPtr output = config->output[config->compat_output]; 609 xf86CrtcPtr crtc = output->crtc; 610 611 if (crtc && crtc->enabled) { 612 crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, 613 y); 614 crtc->x = output->initial_x + x; 615 crtc->y = output->initial_y + y; 616 } 617} 618 619static void 620FreeScreen(int scrnIndex, int flags) 621{ 622 FreeRec(xf86Screens[scrnIndex]); 623} 624 625static void 626LeaveVT(int scrnIndex, int flags) 627{ 628 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 629 modesettingPtr ms = modesettingPTR(pScrn); 630 xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); 631 int o; 632 633 for (o = 0; o < config->num_crtc; o++) { 634 xf86CrtcPtr crtc = config->crtc[o]; 635 636 crtc_cursor_destroy(crtc); 637 638 if (crtc->rotatedPixmap || crtc->rotatedData) { 639 crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, 640 crtc->rotatedData); 641 crtc->rotatedPixmap = NULL; 642 crtc->rotatedData = NULL; 643 } 644 } 645 646 drmModeRmFB(ms->fd, ms->fb_id); 647 648 RestoreHWState(pScrn); 649 650 if (drmDropMaster(ms->fd)) 651 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 652 "drmDropMaster failed: %s\n", strerror(errno)); 653 654 pScrn->vtSema = FALSE; 655} 656 657/* 658 * This gets called when gaining control of the VT, and from ScreenInit(). 659 */ 660static Bool 661EnterVT(int scrnIndex, int flags) 662{ 663 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 664 modesettingPtr ms = modesettingPTR(pScrn); 665 666 if (drmSetMaster(ms->fd)) { 667 if (errno == EINVAL) { 668 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 669 "drmSetMaster failed: 2.6.29 or newer kernel required for " 670 "multi-server DRI\n"); 671 } else { 672 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 673 "drmSetMaster failed: %s\n", strerror(errno)); 674 } 675 } 676 677 /* 678 * Only save state once per server generation since that's what most 679 * drivers do. Could change this to save state at each VT enter. 680 */ 681 if (ms->SaveGeneration != serverGeneration) { 682 ms->SaveGeneration = serverGeneration; 683 SaveHWState(pScrn); 684 } 685 686 if (!flags) /* signals startup as we'll do this in CreateScreenResources */ 687 CreateFrontBuffer(pScrn); 688 689 if (!xf86SetDesiredModes(pScrn)) 690 return FALSE; 691 692 return TRUE; 693} 694 695static Bool 696SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 697{ 698 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 699 700 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); 701} 702 703static Bool 704CloseScreen(int scrnIndex, ScreenPtr pScreen) 705{ 706 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 707 modesettingPtr ms = modesettingPTR(pScrn); 708 709 if (pScrn->vtSema) { 710 LeaveVT(scrnIndex, 0); 711 } 712#ifdef DRI2 713 driCloseScreen(pScreen); 714#endif 715 716 pScreen->BlockHandler = ms->blockHandler; 717 pScreen->CreateScreenResources = ms->createScreenResources; 718 719#ifdef DRM_MODE_FEATURE_DIRTYFB 720 if (ms->damage) { 721 DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage); 722 DamageDestroy(ms->damage); 723 ms->damage = NULL; 724 } 725#endif 726 727 if (ms->exa) 728 xorg_exa_close(pScrn); 729 730 ms->api->destroy(ms->api); 731 ms->api = NULL; 732 drmClose(ms->fd); 733 ms->fd = -1; 734 735 pScrn->vtSema = FALSE; 736 pScreen->CloseScreen = ms->CloseScreen; 737 return (*pScreen->CloseScreen) (scrnIndex, pScreen); 738} 739 740static ModeStatus 741ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) 742{ 743 return MODE_OK; 744} 745 746/* vim: set sw=4 ts=8 sts=4: */ 747