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