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