Merge branch 'softpipe-opt'
[mesa.git] / src / gallium / state_trackers / xorg / xorg_driver.c
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
59 static void AdjustFrame(int scrnIndex, int x, int y, int flags);
60 static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen);
61 static Bool EnterVT(int scrnIndex, int flags);
62 static Bool SaveHWState(ScrnInfoPtr pScrn);
63 static Bool RestoreHWState(ScrnInfoPtr pScrn);
64
65
66 static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose,
67 int flags);
68 static void FreeScreen(int scrnIndex, int flags);
69 static void LeaveVT(int scrnIndex, int flags);
70 static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
71 static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
72 char **argv);
73 static Bool PreInit(ScrnInfoPtr pScrn, int flags);
74
75 typedef enum
76 {
77 OPTION_SW_CURSOR,
78 } modesettingOpts;
79
80 static 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
89 const OptionInfoRec *
90 xorg_tracker_available_options(int chipid, int busid)
91 {
92 return Options;
93 }
94
95 void
96 xorg_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
112 static Bool
113 GetRec(ScrnInfoPtr pScrn)
114 {
115 if (pScrn->driverPrivate)
116 return TRUE;
117
118 pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
119
120 return TRUE;
121 }
122
123 static void
124 FreeRec(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
137 static void
138 ProbeDDC(ScrnInfoPtr pScrn, int index)
139 {
140 ConfiguredMonitor = NULL;
141 }
142
143 static Bool
144 CreateFrontBuffer(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
178 static Bool
179 crtc_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
204 static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
205 crtc_resize
206 };
207
208 static Bool
209 PreInit(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
371 static Bool
372 SaveHWState(ScrnInfoPtr pScrn)
373 {
374 /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
375
376 return TRUE;
377 }
378
379 static Bool
380 RestoreHWState(ScrnInfoPtr pScrn)
381 {
382 /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
383
384 return TRUE;
385 }
386
387 static 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
425 static Bool
426 CreateScreenResources(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
480 static Bool
481 ScreenInit(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
601 static void
602 AdjustFrame(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
617 static void
618 FreeScreen(int scrnIndex, int flags)
619 {
620 FreeRec(xf86Screens[scrnIndex]);
621 }
622
623 static void
624 LeaveVT(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 */
658 static Bool
659 EnterVT(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
693 static Bool
694 SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
695 {
696 ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
697
698 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
699 }
700
701 static Bool
702 CloseScreen(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
738 static ModeStatus
739 ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
740 {
741 return MODE_OK;
742 }
743
744 /* vim: set sw=4 ts=8 sts=4: */