1 /*
2  * Copyright © 2001-2012 Matthieu Herrb
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  *    - Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *    - Redistributions in binary form must reproduce the above
12  *      copyright notice, this list of conditions and the following
13  *      disclaimer in the documentation and/or other materials provided
14  *      with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 /*
32  * Based on fbdev.c written by:
33  *
34  * Authors:  Alan Hourihane, <alanh@fairlite.demon.co.uk>
35  *	     Michel Dänzer, <michdaen@iiic.ethz.ch>
36  */
37 
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41 
42 #include <errno.h>
43 #include <fcntl.h>
44 #include <unistd.h>
45 #include <sys/ioctl.h>
46 #include <sys/types.h>
47 #include <sys/mman.h>
48 #include <sys/time.h>
49 #include <sys/consio.h>
50 #include <sys/fbio.h>
51 
52 /* All drivers need this. */
53 #include "xf86.h"
54 #include "xf86_OSproc.h"
55 #include "xf86Priv.h"
56 
57 #include "mipointer.h"
58 #include "micmap.h"
59 #include "colormapst.h"
60 #include "xf86cmap.h"
61 #include "shadow.h"
62 #include "dgaproc.h"
63 
64 /* For visuals */
65 #ifdef HAVE_XF1BPP
66 # include "xf1bpp.h"
67 #endif
68 #ifdef HAVE_XF4BPP
69 # include "xf4bpp.h"
70 #endif
71 #include "fb.h"
72 
73 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
74 #include "xf86Resources.h"
75 #include "xf86RAC.h"
76 #endif
77 
78 #ifdef XvExtension
79 #include "xf86xv.h"
80 #endif
81 
82 #include "compat-api.h"
83 
84 #undef	DEBUG
85 #define	DEBUG	1
86 
87 #if DEBUG
88 # define TRACE_ENTER(str)	ErrorF("scfb: " str " %d\n",pScrn->scrnIndex)
89 # define TRACE_EXIT(str)	ErrorF("scfb: " str " done\n")
90 # define TRACE(str)		ErrorF("scfb trace: " str "\n")
91 #else
92 # define TRACE_ENTER(str)
93 # define TRACE_EXIT(str)
94 # define TRACE(str)
95 #endif
96 
97 /* Prototypes */
98 static pointer ScfbSetup(pointer, pointer, int *, int *);
99 static Bool ScfbGetRec(ScrnInfoPtr);
100 static void ScfbFreeRec(ScrnInfoPtr);
101 static const OptionInfoRec * ScfbAvailableOptions(int, int);
102 static void ScfbIdentify(int);
103 static Bool ScfbProbe(DriverPtr, int);
104 static Bool ScfbPreInit(ScrnInfoPtr, int);
105 static Bool ScfbScreenInit(SCREEN_INIT_ARGS_DECL);
106 static Bool ScfbCloseScreen(CLOSE_SCREEN_ARGS_DECL);
107 static void *ScfbWindowLinear(ScreenPtr, CARD32, CARD32, int, CARD32 *,
108 			      void *);
109 static void ScfbPointerMoved(SCRN_ARG_TYPE, int, int);
110 static Bool ScfbEnterVT(VT_FUNC_ARGS_DECL);
111 static void ScfbLeaveVT(VT_FUNC_ARGS_DECL);
112 static Bool ScfbSwitchMode(SWITCH_MODE_ARGS_DECL);
113 static int ScfbValidMode(SCRN_ARG_TYPE, DisplayModePtr, Bool, int);
114 static void ScfbLoadPalette(ScrnInfoPtr, int, int *, LOCO *, VisualPtr);
115 static Bool ScfbSaveScreen(ScreenPtr, int);
116 static void ScfbSave(ScrnInfoPtr);
117 static void ScfbRestore(ScrnInfoPtr);
118 
119 /* DGA stuff */
120 #ifdef XFreeXDGA
121 static Bool ScfbDGAOpenFramebuffer(ScrnInfoPtr, char **, unsigned char **,
122 				   int *, int *, int *);
123 static Bool ScfbDGASetMode(ScrnInfoPtr, DGAModePtr);
124 static void ScfbDGASetViewport(ScrnInfoPtr, int, int, int);
125 static Bool ScfbDGAInit(ScrnInfoPtr, ScreenPtr);
126 #endif
127 static Bool ScfbDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op,
128 				pointer ptr);
129 
130 /* Helper functions */
131 static pointer scfb_mmap(size_t, off_t, int);
132 
133 enum { SCFB_ROTATE_NONE = 0,
134        SCFB_ROTATE_CCW = 90,
135        SCFB_ROTATE_UD = 180,
136        SCFB_ROTATE_CW = 270
137 };
138 
139 /*
140  * This is intentionally screen-independent.
141  * It indicates the binding choice made in the first PreInit.
142  */
143 static int pix24bpp = 0;
144 
145 #define SCFB_VERSION 		0002
146 #define SCFB_NAME		"scfb"
147 #define SCFB_DRIVER_NAME	"scfb"
148 
149 _X_EXPORT DriverRec SCFB = {
150 	SCFB_VERSION,
151 	SCFB_DRIVER_NAME,
152 	ScfbIdentify,
153 	ScfbProbe,
154 	ScfbAvailableOptions,
155 	NULL,
156 	0,
157 	ScfbDriverFunc
158 };
159 
160 /* Supported "chipsets" */
161 static SymTabRec ScfbChipsets[] = {
162 	{ 0, "scfb" },
163 	{ -1, NULL }
164 };
165 
166 /* Supported options */
167 typedef enum {
168 	OPTION_SHADOW_FB,
169 	OPTION_ROTATE
170 } ScfbOpts;
171 
172 static const OptionInfoRec ScfbOptions[] = {
173 	{ OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE},
174 	{ OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE},
175 	{ -1, NULL, OPTV_NONE, {0}, FALSE}
176 };
177 
178 static XF86ModuleVersionInfo ScfbVersRec = {
179 	"scfb",
180 	MODULEVENDORSTRING,
181 	MODINFOSTRING1,
182 	MODINFOSTRING2,
183 	XORG_VERSION_CURRENT,
184 	PACKAGE_VERSION_MAJOR,
185 	PACKAGE_VERSION_MINOR,
186 	PACKAGE_VERSION_PATCHLEVEL,
187 	ABI_CLASS_VIDEODRV,
188 	ABI_VIDEODRV_VERSION,
189 	NULL,
190 	{0, 0, 0, 0}
191 };
192 
193 _X_EXPORT XF86ModuleData scfbModuleData = { &ScfbVersRec, ScfbSetup, NULL };
194 
195 static pointer
ScfbSetup(pointer module,pointer opts,int * errmaj,int * errmin)196 ScfbSetup(pointer module, pointer opts, int *errmaj, int *errmin)
197 {
198 	static Bool setupDone = FALSE;
199 
200 	if (!setupDone) {
201 		setupDone = TRUE;
202 		xf86AddDriver(&SCFB, module, HaveDriverFuncs);
203 		return (pointer)1;
204 	} else {
205 		if (errmaj != NULL)
206 			*errmaj = LDR_ONCEONLY;
207 		return NULL;
208 	}
209 }
210 
211 /* Private data */
212 typedef struct {
213 	int			fd; /* File descriptor of open device. */
214 	struct video_info	info;
215 	int			linebytes; /* Number of bytes per row. */
216 	unsigned char*		fbstart;
217 	unsigned char*		fbmem;
218 	size_t			fbmem_len;
219 	int			rotate;
220 	Bool			shadowFB;
221 	void *			shadow;
222 	CloseScreenProcPtr	CloseScreen;
223 	CreateScreenResourcesProcPtr CreateScreenResources;
224 	void			(*PointerMoved)(SCRN_ARG_TYPE, int, int);
225 	EntityInfoPtr		pEnt;
226 
227 #ifdef XFreeXDGA
228 	/* DGA info */
229 	DGAModePtr		pDGAMode;
230 	int			nDGAMode;
231 #endif
232 	OptionInfoPtr		Options;
233 } ScfbRec, *ScfbPtr;
234 
235 #define SCFBPTR(p) ((ScfbPtr)((p)->driverPrivate))
236 
237 static Bool
ScfbGetRec(ScrnInfoPtr pScrn)238 ScfbGetRec(ScrnInfoPtr pScrn)
239 {
240 
241 	if (pScrn->driverPrivate != NULL)
242 		return TRUE;
243 
244 	pScrn->driverPrivate = xnfcalloc(sizeof(ScfbRec), 1);
245 	return TRUE;
246 }
247 
248 static void
ScfbFreeRec(ScrnInfoPtr pScrn)249 ScfbFreeRec(ScrnInfoPtr pScrn)
250 {
251 
252 	if (pScrn->driverPrivate == NULL)
253 		return;
254 	free(pScrn->driverPrivate);
255 	pScrn->driverPrivate = NULL;
256 }
257 
258 static const OptionInfoRec *
ScfbAvailableOptions(int chipid,int busid)259 ScfbAvailableOptions(int chipid, int busid)
260 {
261 	return ScfbOptions;
262 }
263 
264 static void
ScfbIdentify(int flags)265 ScfbIdentify(int flags)
266 {
267 	xf86PrintChipsets(SCFB_NAME, "driver for wsdisplay framebuffer",
268 			  ScfbChipsets);
269 }
270 
271 /* Map the framebuffer's memory. */
272 static pointer
scfb_mmap(size_t len,off_t off,int fd)273 scfb_mmap(size_t len, off_t off, int fd)
274 {
275 	int pagemask, mapsize;
276 	caddr_t addr;
277 	pointer mapaddr;
278 
279 	pagemask = getpagesize() - 1;
280 	mapsize = ((int) len + pagemask) & ~pagemask;
281 	addr = 0;
282 
283 	/*
284 	 * Try and make it private first, that way once we get it, an
285 	 * interloper, e.g. another server, can't get this frame buffer,
286 	 * and if another server already has it, this one won't.
287 	 */
288 	mapaddr = (pointer) mmap(addr, mapsize,
289 				 PROT_READ | PROT_WRITE, MAP_SHARED,
290 				 fd, off);
291 	if (mapaddr == (pointer) -1) {
292 		mapaddr = NULL;
293 	}
294 #if DEBUG
295 	ErrorF("mmap returns: addr %p len 0x%x, fd %d, off %lx\n", mapaddr, mapsize, fd, off);
296 #endif
297 	return mapaddr;
298 }
299 
300 static Bool
ScfbProbe(DriverPtr drv,int flags)301 ScfbProbe(DriverPtr drv, int flags)
302 {
303 	int i, fd, entity;
304        	GDevPtr *devSections;
305 	int numDevSections;
306 	const char *dev;
307 	struct fbtype fb;
308 	Bool foundScreen = FALSE;
309 
310 	TRACE("probe start");
311 
312 	/* For now, just bail out for PROBE_DETECT. */
313 	if (flags & PROBE_DETECT)
314 		return FALSE;
315 
316 	if ((numDevSections = xf86MatchDevice(SCFB_DRIVER_NAME,
317 					      &devSections)) <= 0)
318 		return FALSE;
319 
320 
321 	for (i = 0; i < numDevSections; i++) {
322 		ScrnInfoPtr pScrn = NULL;
323 		dev = xf86FindOptionValue(devSections[i]->options, "device");
324 		if ((fd = xf86Info.consoleFd) >= 0 &&
325 		    ioctl(fd, FBIOGTYPE, &fb) != -1 &&
326 		    fb.fb_type == FBTYPE_DUMBFB) {
327 			entity = xf86ClaimFbSlot(drv, 0, devSections[i], TRUE);
328 			pScrn = xf86ConfigFbEntity(NULL,0,entity,
329 						   NULL,NULL,NULL,NULL);
330 			if (pScrn != NULL) {
331 				foundScreen = TRUE;
332 				pScrn->driverVersion = SCFB_VERSION;
333 				pScrn->driverName = SCFB_DRIVER_NAME;
334 				pScrn->name = SCFB_NAME;
335 				pScrn->Probe = ScfbProbe;
336 				pScrn->PreInit = ScfbPreInit;
337 				pScrn->ScreenInit = ScfbScreenInit;
338 				pScrn->SwitchMode = ScfbSwitchMode;
339 				pScrn->AdjustFrame = NULL;
340 				pScrn->EnterVT = ScfbEnterVT;
341 				pScrn->LeaveVT = ScfbLeaveVT;
342 				pScrn->ValidMode = ScfbValidMode;
343 
344 				xf86DrvMsg(pScrn->scrnIndex, X_INFO,
345 				    "using %s\n", dev != NULL ? dev :
346 				    "default device");
347 			}
348 		}
349 	}
350 	free(devSections);
351 	TRACE("probe done");
352 	return foundScreen;
353 }
354 
355 static Bool
ScfbPreInit(ScrnInfoPtr pScrn,int flags)356 ScfbPreInit(ScrnInfoPtr pScrn, int flags)
357 {
358 	ScfbPtr fPtr;
359 	struct fbtype fb;
360 	int default_depth, wstype;
361 	const char *dev;
362 	char *mod = NULL;
363 	const char *reqSym = NULL, *s;
364 	Gamma zeros = {0.0, 0.0, 0.0};
365 	DisplayModePtr mode;
366 
367 	if (flags & PROBE_DETECT) return FALSE;
368 
369 	TRACE_ENTER("PreInit");
370 
371 	if (pScrn->numEntities != 1) return FALSE;
372 
373 	pScrn->monitor = pScrn->confScreen->monitor;
374 
375 	ScfbGetRec(pScrn);
376 	fPtr = SCFBPTR(pScrn);
377 
378 	fPtr->pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
379 
380 #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
381 	pScrn->racMemFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT;
382 	pScrn->racIoFlags = pScrn->racMemFlags;
383 #endif
384 
385 	dev = xf86FindOptionValue(fPtr->pEnt->device->options, "device");
386 	fPtr->fd = xf86Info.consoleFd;
387 	if (fPtr->fd == -1) {
388 		return FALSE;
389 	}
390 
391 	if (ioctl(fPtr->fd, FBIOGTYPE, &fb) == -1) {
392 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
393 			   "ioctl FBIOGTYPE: %s\n",
394 			   strerror(errno));
395 		return FALSE;
396 	}
397 
398 	fPtr->info.vi_depth = fb.fb_depth;
399 	fPtr->info.vi_width = fb.fb_width;
400 	fPtr->info.vi_height = fb.fb_height;
401 	fPtr->info.vi_pixel_size = fb.fb_depth/8;
402 
403 	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
404 	    "Using: depth (%d),\twidth (%d),\t height (%d)\n",
405 	    fPtr->info.vi_depth,fPtr->info.vi_width, fPtr->info.vi_height);
406 
407 	if (ioctl(fPtr->fd, FBIO_GETLINEWIDTH, &fPtr->linebytes) == -1) {
408 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
409 			   "ioctl FBIO_GETLINEWIDTH fail: %s. "
410 			   "Falling back to width * bytes per pixel.\n",
411 			   strerror(errno));
412 		fPtr->linebytes = fPtr->info.vi_width *
413 		    fPtr->info.vi_pixel_size;
414 	}
415 
416 	/* Handle depth */
417 	default_depth = fPtr->info.vi_depth <= 24 ? fPtr->info.vi_depth : 24;
418 	if (!xf86SetDepthBpp(pScrn, default_depth, default_depth,
419 		fPtr->info.vi_depth,
420 		fPtr->info.vi_depth >= 24 ? Support24bppFb|Support32bppFb : 0))
421 		return FALSE;
422 
423 	/* Check consistency. */
424 	if (pScrn->bitsPerPixel != fPtr->info.vi_depth) {
425 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
426 		    "specified depth (%d) or bpp (%d) doesn't match "
427 		    "framebuffer depth (%d)\n", pScrn->depth,
428 		    pScrn->bitsPerPixel, fPtr->info.vi_depth);
429 		return FALSE;
430 	}
431 	xf86PrintDepthBpp(pScrn);
432 
433 	/* Get the depth24 pixmap format. */
434 	if (pScrn->depth == 24 && pix24bpp == 0)
435 		pix24bpp = xf86GetBppFromDepth(pScrn, 24);
436 
437 	/* Color weight */
438 	if (pScrn->depth > 8) {
439 		rgb zeros = { 0, 0, 0 }, masks = { 0, 0, 0 };
440 #ifdef FBIO_GETRGBOFFS
441 		struct fb_rgboffs offs;
442 
443 		if (ioctl(fPtr->fd, FBIO_GETRGBOFFS, &offs) == -1) {
444 			xf86DrvMsg(pScrn->scrnIndex, X_INFO,
445 				   "ioctl FBIO_GETRGBOFFS fail: %s. "
446 				   "Falling back to default color format.\n",
447 				   strerror(errno));
448 			memset(&offs, 0, sizeof(offs));
449 		}
450 
451 		/*
452 		 * If FBIO_GETRGBOFFS returned any non-zero offset, set the
453 		 * RGB masks appropriately.
454 		 *
455 		 * As there was an issue in Xorg server's RGB masks handling
456 		 * (https://gitlab.freedesktop.org/xorg/xserver/-/issues/1112),
457 		 * that is only fixed in master and 21.1.x releases for now,
458 		 * avoid modifying the masks if they correspond to the default
459 		 * values used by X.
460 		 */
461 		if ((offs.red != 0 || offs.green != 0 || offs.blue != 0) &&
462 		    !(offs.red == 16 && offs.green == 8 && offs.blue == 0)) {
463 			masks.red = 0xff << offs.red;
464 			masks.green = 0xff << offs.green;
465 			masks.blue = 0xff << offs.blue;
466 		}
467 #endif
468 
469 		if (!xf86SetWeight(pScrn, zeros, masks))
470 			return FALSE;
471 	}
472 
473 	/* Visual init */
474 	if (!xf86SetDefaultVisual(pScrn, -1))
475 		return FALSE;
476 
477 	/* We don't currently support DirectColor at > 8bpp . */
478 	if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
479 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual"
480 			   " (%s) is not supported at depth %d\n",
481 			   xf86GetVisualName(pScrn->defaultVisual),
482 			   pScrn->depth);
483 		return FALSE;
484 	}
485 
486 	xf86SetGamma(pScrn,zeros);
487 
488 	pScrn->progClock = TRUE;
489 	pScrn->rgbBits   = 8;
490 	pScrn->chipset   = "scfb";
491 	pScrn->videoRam  = fPtr->linebytes * fPtr->info.vi_height;
492 
493 	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Vidmem: %dk\n",
494 		   pScrn->videoRam/1024);
495 
496 	/* Handle options. */
497 	xf86CollectOptions(pScrn, NULL);
498 	fPtr->Options = (OptionInfoRec *)malloc(sizeof(ScfbOptions));
499 	if (fPtr->Options == NULL)
500 		return FALSE;
501 	memcpy(fPtr->Options, ScfbOptions, sizeof(ScfbOptions));
502 	xf86ProcessOptions(pScrn->scrnIndex, fPtr->pEnt->device->options,
503 			   fPtr->Options);
504 
505 	/* Use shadow framebuffer by default, on depth >= 8 */
506 	if (pScrn->depth >= 8)
507 		fPtr->shadowFB = xf86ReturnOptValBool(fPtr->Options,
508 						      OPTION_SHADOW_FB, TRUE);
509 	else
510 		if (xf86ReturnOptValBool(fPtr->Options,
511 					 OPTION_SHADOW_FB, FALSE)) {
512 			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
513 				   "Shadow FB option ignored on depth < 8");
514 		}
515 
516 	/* Rotation */
517 	fPtr->rotate = SCFB_ROTATE_NONE;
518 	if ((s = xf86GetOptValString(fPtr->Options, OPTION_ROTATE))) {
519 		if (pScrn->depth >= 8) {
520 			if (!xf86NameCmp(s, "CW")) {
521 				fPtr->shadowFB = TRUE;
522 				fPtr->rotate = SCFB_ROTATE_CW;
523 				xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
524 				    "Rotating screen clockwise\n");
525 			} else if (!xf86NameCmp(s, "CCW")) {
526 				fPtr->shadowFB = TRUE;
527 				fPtr->rotate = SCFB_ROTATE_CCW;
528 				xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
529 				    "Rotating screen counter clockwise\n");
530 			} else if (!xf86NameCmp(s, "UD")) {
531 				fPtr->shadowFB = TRUE;
532 				fPtr->rotate = SCFB_ROTATE_UD;
533 				xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
534 				    "Rotating screen upside down\n");
535 			} else {
536 				xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
537 				    "\"%s\" is not a valid value for Option "
538 				    "\"Rotate\"\n", s);
539 				xf86DrvMsg(pScrn->scrnIndex, X_INFO,
540 				    "Valid options are \"CW\", \"CCW\","
541 				    " or \"UD\"\n");
542 			}
543 		} else {
544 			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
545 			    "Option \"Rotate\" ignored on depth < 8");
546 		}
547 	}
548 
549 	/* Fake video mode struct. */
550 	mode = (DisplayModePtr)malloc(sizeof(DisplayModeRec));
551 	mode->prev = mode;
552 	mode->next = mode;
553 	mode->name = "scfb current mode";
554 	mode->status = MODE_OK;
555 	mode->type = M_T_BUILTIN;
556 	mode->Clock = 0;
557 	mode->HDisplay = fPtr->info.vi_width;
558 	mode->HSyncStart = 0;
559 	mode->HSyncEnd = 0;
560 	mode->HTotal = 0;
561 	mode->HSkew = 0;
562 	mode->VDisplay = fPtr->info.vi_height;
563 	mode->VSyncStart = 0;
564 	mode->VSyncEnd = 0;
565 	mode->VTotal = 0;
566 	mode->VScan = 0;
567 	mode->Flags = 0;
568 	if (pScrn->modes != NULL) {
569 		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
570 		   "Ignoring mode specification from screen section\n");
571 	}
572 	pScrn->currentMode = pScrn->modes = mode;
573 	pScrn->virtualX = fPtr->info.vi_width;
574 	pScrn->virtualY = fPtr->info.vi_height;
575 	pScrn->displayWidth = pScrn->virtualX;
576 
577 	/* Set the display resolution. */
578 	xf86SetDpi(pScrn, 0, 0);
579 
580 	/* Load bpp-specific modules. */
581 	switch(pScrn->bitsPerPixel) {
582 #ifdef HAVE_XF1BPP
583 	case 1:
584 		mod = "xf1bpp";
585 		reqSym = "xf1bppScreenInit";
586 		break;
587 #endif
588 #ifdef HAVE_XF4BPP
589 	case 4:
590 		mod = "xf4bpp";
591 		reqSym = "xf4bppScreenInit";
592 		break;
593 #endif
594 	default:
595 		mod = "fb";
596 		break;
597 	}
598 
599 	/* Load shadow if needed. */
600 	if (fPtr->shadowFB) {
601 		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
602 			   "Using \"Shadow Framebuffer\"\n");
603 		if (xf86LoadSubModule(pScrn, "shadow") == NULL) {
604 			ScfbFreeRec(pScrn);
605 			return FALSE;
606 		}
607 	}
608 	if (mod && xf86LoadSubModule(pScrn, mod) == NULL) {
609 		ScfbFreeRec(pScrn);
610 		return FALSE;
611 	}
612 	TRACE_EXIT("PreInit");
613 	return TRUE;
614 }
615 
616 static void
scfbUpdateRotatePacked(ScreenPtr pScreen,shadowBufPtr pBuf)617 scfbUpdateRotatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
618 {
619     shadowUpdateRotatePacked(pScreen, pBuf);
620 }
621 
622 static void
scfbUpdatePacked(ScreenPtr pScreen,shadowBufPtr pBuf)623 scfbUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
624 {
625     shadowUpdatePacked(pScreen, pBuf);
626 }
627 
628 static Bool
ScfbCreateScreenResources(ScreenPtr pScreen)629 ScfbCreateScreenResources(ScreenPtr pScreen)
630 {
631 	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
632 	ScfbPtr fPtr = SCFBPTR(pScrn);
633 	PixmapPtr pPixmap;
634 	Bool ret;
635 
636 	pScreen->CreateScreenResources = fPtr->CreateScreenResources;
637 	ret = pScreen->CreateScreenResources(pScreen);
638 	pScreen->CreateScreenResources = ScfbCreateScreenResources;
639 
640 	if (!ret)
641 		return FALSE;
642 
643 	pPixmap = pScreen->GetScreenPixmap(pScreen);
644 
645 	if (!shadowAdd(pScreen, pPixmap, fPtr->rotate ?
646 		scfbUpdateRotatePacked : scfbUpdatePacked,
647 		ScfbWindowLinear, fPtr->rotate, NULL)) {
648 		return FALSE;
649 	}
650 	return TRUE;
651 }
652 
653 
654 static Bool
ScfbShadowInit(ScreenPtr pScreen)655 ScfbShadowInit(ScreenPtr pScreen)
656 {
657 	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
658 	ScfbPtr fPtr = SCFBPTR(pScrn);
659 
660 	if (!shadowSetup(pScreen))
661 		return FALSE;
662 	fPtr->CreateScreenResources = pScreen->CreateScreenResources;
663 	pScreen->CreateScreenResources = ScfbCreateScreenResources;
664 
665 	return TRUE;
666 }
667 
668 static Bool
ScfbScreenInit(SCREEN_INIT_ARGS_DECL)669 ScfbScreenInit(SCREEN_INIT_ARGS_DECL)
670 {
671 	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
672 	ScfbPtr fPtr = SCFBPTR(pScrn);
673 	VisualPtr visual;
674 	int ret, flags, ncolors;
675 	size_t len;
676 
677 	TRACE_ENTER("ScfbScreenInit");
678 #if DEBUG
679 	ErrorF("\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
680 	       "\tmask: %x,%x,%x, offset: %u,%u,%u\n",
681 	       pScrn->bitsPerPixel,
682 	       pScrn->depth,
683 	       xf86GetVisualName(pScrn->defaultVisual),
684 	       pScrn->mask.red,pScrn->mask.green,pScrn->mask.blue,
685 	       pScrn->offset.red,pScrn->offset.green,pScrn->offset.blue);
686 #endif
687 	switch (fPtr->info.vi_depth) {
688 	case 1:
689 	case 4:
690 	case 8:
691 		len = fPtr->linebytes*fPtr->info.vi_height;
692 		break;
693 	case 16:
694 		if (fPtr->linebytes == fPtr->info.vi_width) {
695 			len = fPtr->info.vi_width*fPtr->info.vi_height*sizeof(short);
696 		} else {
697 			len = fPtr->linebytes*fPtr->info.vi_height;
698 		}
699 		break;
700 	case 24:
701 		if (fPtr->linebytes == fPtr->info.vi_width) {
702 			len = fPtr->info.vi_width*fPtr->info.vi_height*3;
703 		} else {
704 			len = fPtr->linebytes*fPtr->info.vi_height;
705 		}
706 		break;
707 	case 32:
708 		if (fPtr->linebytes == fPtr->info.vi_width) {
709 			len = fPtr->info.vi_width*fPtr->info.vi_height*sizeof(int);
710 		} else {
711 			len = fPtr->linebytes*fPtr->info.vi_height;
712 		}
713 		break;
714 	default:
715 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
716 			   "unsupported depth %d\n", fPtr->info.vi_depth);
717 		return FALSE;
718 	}
719 	/* TODO: Switch to graphics mode - required before mmap. */
720 	fPtr->fbmem = scfb_mmap(len, 0, fPtr->fd);
721 
722 	if (fPtr->fbmem == NULL) {
723 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
724 			   "scfb_mmap: %s\n", strerror(errno));
725 		return FALSE;
726 	}
727 	fPtr->fbmem_len = len;
728 
729 	ScfbSave(pScrn);
730 	pScrn->vtSema = TRUE;
731 
732 	/* MI layer */
733 	miClearVisualTypes();
734 	if (pScrn->bitsPerPixel > 8) {
735 		if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
736 				      pScrn->rgbBits, TrueColor))
737 			return FALSE;
738 	} else {
739 		if (!miSetVisualTypes(pScrn->depth,
740 				      miGetDefaultVisualMask(pScrn->depth),
741 				      pScrn->rgbBits, pScrn->defaultVisual))
742 			return FALSE;
743 	}
744 	if (!miSetPixmapDepths())
745 		return FALSE;
746 
747 	if (fPtr->rotate == SCFB_ROTATE_CW
748 	    || fPtr->rotate == SCFB_ROTATE_CCW) {
749 		int tmp = pScrn->virtualX;
750 		pScrn->virtualX = pScrn->displayWidth = pScrn->virtualY;
751 		pScrn->virtualY = tmp;
752 	}
753 	if (fPtr->rotate && !fPtr->PointerMoved) {
754 		fPtr->PointerMoved = pScrn->PointerMoved;
755 		pScrn->PointerMoved = ScfbPointerMoved;
756 	}
757 
758 	fPtr->fbstart = fPtr->fbmem;
759 
760 	if (fPtr->shadowFB) {
761 		fPtr->shadow = calloc(1, pScrn->virtualX * pScrn->virtualY *
762 		    pScrn->bitsPerPixel/8);
763 
764 		if (!fPtr->shadow) {
765 			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
766 			    "Failed to allocate shadow framebuffer\n");
767 			return FALSE;
768 		}
769 	}
770 
771 	switch (pScrn->bitsPerPixel) {
772 	case 1:
773 #ifdef HAVE_XF1BPP
774 		ret = xf1bppScreenInit(pScreen, fPtr->fbstart,
775 				       pScrn->virtualX, pScrn->virtualY,
776 				       pScrn->xDpi, pScrn->yDpi,
777 				       fPtr->linebytes * 8);
778 		break;
779 #endif
780 	case 4:
781 #ifdef HAVE_XF4BPP
782 		ret = xf4bppScreenInit(pScreen, fPtr->fbstart,
783 				       pScrn->virtualX, pScrn->virtualY,
784 				       pScrn->xDpi, pScrn->yDpi,
785 				       fPtr->linebytes * 2);
786 		break;
787 #endif
788 	case 8:
789 	case 16:
790 	case 24:
791 	case 32:
792 		ret = fbScreenInit(pScreen,
793 		    fPtr->shadowFB ? fPtr->shadow : fPtr->fbstart,
794 		    pScrn->virtualX, pScrn->virtualY,
795 		    pScrn->xDpi, pScrn->yDpi,
796 		    pScrn->displayWidth, pScrn->bitsPerPixel);
797 		break;
798 	default:
799 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
800 			   "Unsupported bpp: %d", pScrn->bitsPerPixel);
801 		return FALSE;
802 	} /* case */
803 
804 	if (!ret)
805 		return FALSE;
806 
807 	if (pScrn->bitsPerPixel > 8) {
808 		/* Fixup RGB ordering. */
809 		visual = pScreen->visuals + pScreen->numVisuals;
810 		while (--visual >= pScreen->visuals) {
811 			if ((visual->class | DynamicClass) == DirectColor) {
812 				visual->offsetRed   = pScrn->offset.red;
813 				visual->offsetGreen = pScrn->offset.green;
814 				visual->offsetBlue  = pScrn->offset.blue;
815 				visual->redMask     = pScrn->mask.red;
816 				visual->greenMask   = pScrn->mask.green;
817 				visual->blueMask    = pScrn->mask.blue;
818 			}
819 		}
820 	}
821 
822 	if (pScrn->bitsPerPixel >= 8) {
823 		if (!fbPictureInit(pScreen, NULL, 0))
824 			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
825 				   "RENDER extension initialisation failed.");
826 	}
827 	if (fPtr->shadowFB && !ScfbShadowInit(pScreen)) {
828 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
829 		    "shadow framebuffer initialization failed\n");
830 		return FALSE;
831 	}
832 
833 #ifdef XFreeXDGA
834 	if (!fPtr->rotate)
835 		ScfbDGAInit(pScrn, pScreen);
836 	else
837 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Rotated display, "
838 		    "disabling DGA\n");
839 #endif
840 	if (fPtr->rotate) {
841 		xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Driver Rotation, "
842 		    "disabling RandR\n");
843 		xf86DisableRandR();
844 		if (pScrn->bitsPerPixel == 24)
845 			xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
846 			    "Rotation might be broken in 24 bpp\n");
847 	}
848 
849 	xf86SetBlackWhitePixels(pScreen);
850 	xf86SetBackingStore(pScreen);
851 
852 	/* Software cursor. */
853 	miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
854 
855 	/*
856 	 * Colormap
857 	 *
858 	 * Note that, even on less than 8 bit depth frame buffers, we
859 	 * expect the colormap to be programmable with 8 bit values.
860 	 * As of now, this is indeed the case on all OpenBSD supported
861 	 * graphics hardware.
862 	 */
863 	if (!miCreateDefColormap(pScreen))
864 		return FALSE;
865 	flags = CMAP_RELOAD_ON_MODE_SWITCH;
866 	ncolors = 256;
867 	if(!xf86HandleColormaps(pScreen, ncolors, 8, ScfbLoadPalette,
868 				NULL, flags))
869 		return FALSE;
870 
871 	pScreen->SaveScreen = ScfbSaveScreen;
872 
873 #ifdef XvExtension
874 	{
875 		XF86VideoAdaptorPtr *ptr;
876 
877 		int n = xf86XVListGenericAdaptors(pScrn,&ptr);
878 		if (n) {
879 			xf86XVScreenInit(pScreen,ptr,n);
880 		}
881 	}
882 #endif
883 
884 	/* Wrap the current CloseScreen function. */
885 	fPtr->CloseScreen = pScreen->CloseScreen;
886 	pScreen->CloseScreen = ScfbCloseScreen;
887 
888 	TRACE_EXIT("ScfbScreenInit");
889 	return TRUE;
890 }
891 
892 static Bool
ScfbCloseScreen(CLOSE_SCREEN_ARGS_DECL)893 ScfbCloseScreen(CLOSE_SCREEN_ARGS_DECL)
894 {
895 	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
896 	PixmapPtr pPixmap;
897 	ScfbPtr fPtr = SCFBPTR(pScrn);
898 
899 
900 	TRACE_ENTER("ScfbCloseScreen");
901 
902 	pPixmap = pScreen->GetScreenPixmap(pScreen);
903 	if (fPtr->shadowFB)
904 		shadowRemove(pScreen, pPixmap);
905 
906 	if (pScrn->vtSema) {
907 		ScfbRestore(pScrn);
908 		if (munmap(fPtr->fbmem, fPtr->fbmem_len) == -1) {
909 			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
910 				   "munmap: %s\n", strerror(errno));
911 		}
912 
913 		fPtr->fbmem = NULL;
914 	}
915 #ifdef XFreeXDGA
916 	if (fPtr->pDGAMode) {
917 		free(fPtr->pDGAMode);
918 		fPtr->pDGAMode = NULL;
919 		fPtr->nDGAMode = 0;
920 	}
921 #endif
922 	pScrn->vtSema = FALSE;
923 
924 	/* Unwrap CloseScreen. */
925 	pScreen->CloseScreen = fPtr->CloseScreen;
926 	TRACE_EXIT("ScfbCloseScreen");
927 	return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
928 }
929 
930 static void *
ScfbWindowLinear(ScreenPtr pScreen,CARD32 row,CARD32 offset,int mode,CARD32 * size,void * closure)931 ScfbWindowLinear(ScreenPtr pScreen, CARD32 row, CARD32 offset, int mode,
932 		CARD32 *size, void *closure)
933 {
934 	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
935 	ScfbPtr fPtr = SCFBPTR(pScrn);
936 
937 	*size = fPtr->linebytes;
938 	return ((CARD8 *)fPtr->fbmem + row *fPtr->linebytes + offset);
939 }
940 
941 static void
ScfbPointerMoved(SCRN_ARG_TYPE arg,int x,int y)942 ScfbPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
943 {
944     SCRN_INFO_PTR(arg);
945     ScfbPtr fPtr = SCFBPTR(pScrn);
946     int newX, newY;
947 
948     switch (fPtr->rotate)
949     {
950     case SCFB_ROTATE_CW:
951 	/* 90 degrees CW rotation. */
952 	newX = pScrn->pScreen->height - y - 1;
953 	newY = x;
954 	break;
955 
956     case SCFB_ROTATE_CCW:
957 	/* 90 degrees CCW rotation. */
958 	newX = y;
959 	newY = pScrn->pScreen->width - x - 1;
960 	break;
961 
962     case SCFB_ROTATE_UD:
963 	/* 180 degrees UD rotation. */
964 	newX = pScrn->pScreen->width - x - 1;
965 	newY = pScrn->pScreen->height - y - 1;
966 	break;
967 
968     default:
969 	/* No rotation. */
970 	newX = x;
971 	newY = y;
972 	break;
973     }
974 
975     /* Pass adjusted pointer coordinates to wrapped PointerMoved function. */
976     (*fPtr->PointerMoved)(arg, newX, newY);
977 }
978 
979 static Bool
ScfbEnterVT(VT_FUNC_ARGS_DECL)980 ScfbEnterVT(VT_FUNC_ARGS_DECL)
981 {
982 	SCRN_INFO_PTR(arg);
983 
984 	TRACE_ENTER("EnterVT");
985 	pScrn->vtSema = TRUE;
986 	TRACE_EXIT("EnterVT");
987 	return TRUE;
988 }
989 
990 static void
ScfbLeaveVT(VT_FUNC_ARGS_DECL)991 ScfbLeaveVT(VT_FUNC_ARGS_DECL)
992 {
993 #if DEBUG
994 	SCRN_INFO_PTR(arg);
995 #endif
996 
997 	TRACE_ENTER("LeaveVT");
998 }
999 
1000 static Bool
ScfbSwitchMode(SWITCH_MODE_ARGS_DECL)1001 ScfbSwitchMode(SWITCH_MODE_ARGS_DECL)
1002 {
1003 #if DEBUG
1004 	SCRN_INFO_PTR(arg);
1005 #endif
1006 
1007 	TRACE_ENTER("SwitchMode");
1008 	/* Nothing else to do. */
1009 	return TRUE;
1010 }
1011 
1012 static int
ScfbValidMode(SCRN_ARG_TYPE arg,DisplayModePtr mode,Bool verbose,int flags)1013 ScfbValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags)
1014 {
1015 #if DEBUG
1016 	SCRN_INFO_PTR(arg);
1017 #endif
1018 
1019 	TRACE_ENTER("ValidMode");
1020 	return MODE_OK;
1021 }
1022 
1023 static void
ScfbLoadPalette(ScrnInfoPtr pScrn,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)1024 ScfbLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
1025 	       LOCO *colors, VisualPtr pVisual)
1026 {
1027 
1028 	TRACE_ENTER("LoadPalette");
1029 	/* TODO */
1030 }
1031 
1032 static Bool
ScfbSaveScreen(ScreenPtr pScreen,int mode)1033 ScfbSaveScreen(ScreenPtr pScreen, int mode)
1034 {
1035 	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1036 	ScfbPtr fPtr = SCFBPTR(pScrn);
1037 	int state;
1038 
1039 	TRACE_ENTER("SaveScreen");
1040 
1041 	if (!pScrn->vtSema)
1042 		return TRUE;
1043 
1044 	if (mode != SCREEN_SAVER_FORCER) {
1045 		/* TODO, if (mode) enable_screen(); else disable_screen(); */
1046 	}
1047 	TRACE_EXIT("SaveScreen");
1048 	return TRUE;
1049 }
1050 
1051 
1052 static void
ScfbSave(ScrnInfoPtr pScrn)1053 ScfbSave(ScrnInfoPtr pScrn)
1054 {
1055 	ScfbPtr fPtr = SCFBPTR(pScrn);
1056 
1057 	TRACE_ENTER("ScfbSave");
1058 
1059 	TRACE_EXIT("ScfbSave");
1060 
1061 }
1062 
1063 static void
ScfbRestore(ScrnInfoPtr pScrn)1064 ScfbRestore(ScrnInfoPtr pScrn)
1065 {
1066 	ScfbPtr fPtr = SCFBPTR(pScrn);
1067 	int mode;
1068 
1069 	TRACE_ENTER("ScfbRestore");
1070 
1071 	/* Clear the screen. */
1072 	memset(fPtr->fbmem, 0, fPtr->fbmem_len);
1073 
1074 	/* Restore the text mode. */
1075 	/* TODO: We need to get first, if we need mode switching */
1076 	TRACE_EXIT("ScfbRestore");
1077 }
1078 
1079 #ifdef XFreeXDGA
1080 /***********************************************************************
1081  * DGA stuff
1082  ***********************************************************************/
1083 
1084 static Bool
ScfbDGAOpenFramebuffer(ScrnInfoPtr pScrn,char ** DeviceName,unsigned char ** ApertureBase,int * ApertureSize,int * ApertureOffset,int * flags)1085 ScfbDGAOpenFramebuffer(ScrnInfoPtr pScrn, char **DeviceName,
1086 		       unsigned char **ApertureBase, int *ApertureSize,
1087 		       int *ApertureOffset, int *flags)
1088 {
1089 	*DeviceName = NULL;		/* No special device */
1090 	*ApertureBase = (unsigned char *)(pScrn->memPhysBase);
1091 	*ApertureSize = pScrn->videoRam;
1092 	*ApertureOffset = pScrn->fbOffset;
1093 	*flags = 0;
1094 
1095 	return TRUE;
1096 }
1097 
1098 static Bool
ScfbDGASetMode(ScrnInfoPtr pScrn,DGAModePtr pDGAMode)1099 ScfbDGASetMode(ScrnInfoPtr pScrn, DGAModePtr pDGAMode)
1100 {
1101 	DisplayModePtr pMode;
1102 	int frameX0, frameY0;
1103 
1104 	if (pDGAMode) {
1105 		pMode = pDGAMode->mode;
1106 		frameX0 = frameY0 = 0;
1107 	} else {
1108 		if (!(pMode = pScrn->currentMode))
1109 			return TRUE;
1110 
1111 		frameX0 = pScrn->frameX0;
1112 		frameY0 = pScrn->frameY0;
1113 	}
1114 
1115 	if (!(*pScrn->SwitchMode)(SWITCH_MODE_ARGS(pScrn, pMode)))
1116 		return FALSE;
1117 	(*pScrn->AdjustFrame)(ADJUST_FRAME_ARGS(pScrn, frameX0, frameY0));
1118 
1119 	return TRUE;
1120 }
1121 
1122 static void
ScfbDGASetViewport(ScrnInfoPtr pScrn,int x,int y,int flags)1123 ScfbDGASetViewport(ScrnInfoPtr pScrn, int x, int y, int flags)
1124 {
1125 	(*pScrn->AdjustFrame)(ADJUST_FRAME_ARGS(pScrn, x, y));
1126 }
1127 
1128 static int
ScfbDGAGetViewport(ScrnInfoPtr pScrn)1129 ScfbDGAGetViewport(ScrnInfoPtr pScrn)
1130 {
1131 	return (0);
1132 }
1133 
1134 static DGAFunctionRec ScfbDGAFunctions =
1135 {
1136 	ScfbDGAOpenFramebuffer,
1137 	NULL,       /* CloseFramebuffer */
1138 	ScfbDGASetMode,
1139 	ScfbDGASetViewport,
1140 	ScfbDGAGetViewport,
1141 	NULL,       /* Sync */
1142 	NULL,       /* FillRect */
1143 	NULL,       /* BlitRect */
1144 	NULL,       /* BlitTransRect */
1145 };
1146 
1147 static void
ScfbDGAAddModes(ScrnInfoPtr pScrn)1148 ScfbDGAAddModes(ScrnInfoPtr pScrn)
1149 {
1150 	ScfbPtr fPtr = SCFBPTR(pScrn);
1151 	DisplayModePtr pMode = pScrn->modes;
1152 	DGAModePtr pDGAMode;
1153 
1154 	do {
1155 		pDGAMode = realloc(fPtr->pDGAMode,
1156 				    (fPtr->nDGAMode + 1) * sizeof(DGAModeRec));
1157 		if (!pDGAMode)
1158 			break;
1159 
1160 		fPtr->pDGAMode = pDGAMode;
1161 		pDGAMode += fPtr->nDGAMode;
1162 		(void)memset(pDGAMode, 0, sizeof(DGAModeRec));
1163 
1164 		++fPtr->nDGAMode;
1165 		pDGAMode->mode = pMode;
1166 		pDGAMode->flags = DGA_CONCURRENT_ACCESS | DGA_PIXMAP_AVAILABLE;
1167 		pDGAMode->byteOrder = pScrn->imageByteOrder;
1168 		pDGAMode->depth = pScrn->depth;
1169 		pDGAMode->bitsPerPixel = pScrn->bitsPerPixel;
1170 		pDGAMode->red_mask = pScrn->mask.red;
1171 		pDGAMode->green_mask = pScrn->mask.green;
1172 		pDGAMode->blue_mask = pScrn->mask.blue;
1173 		pDGAMode->visualClass = pScrn->bitsPerPixel > 8 ?
1174 			TrueColor : PseudoColor;
1175 		pDGAMode->xViewportStep = 1;
1176 		pDGAMode->yViewportStep = 1;
1177 		pDGAMode->viewportWidth = pMode->HDisplay;
1178 		pDGAMode->viewportHeight = pMode->VDisplay;
1179 
1180 		pDGAMode->bytesPerScanline = fPtr->linebytes;
1181 
1182 		pDGAMode->imageWidth = pMode->HDisplay;
1183 		pDGAMode->imageHeight =  pMode->VDisplay;
1184 		pDGAMode->pixmapWidth = pDGAMode->imageWidth;
1185 		pDGAMode->pixmapHeight = pDGAMode->imageHeight;
1186 		pDGAMode->maxViewportX = pScrn->virtualX -
1187 			pDGAMode->viewportWidth;
1188 		pDGAMode->maxViewportY = pScrn->virtualY -
1189 			pDGAMode->viewportHeight;
1190 
1191 		pDGAMode->address = fPtr->fbstart;
1192 
1193 		pMode = pMode->next;
1194 	} while (pMode != pScrn->modes);
1195 }
1196 
1197 static Bool
ScfbDGAInit(ScrnInfoPtr pScrn,ScreenPtr pScreen)1198 ScfbDGAInit(ScrnInfoPtr pScrn, ScreenPtr pScreen)
1199 {
1200 	ScfbPtr fPtr = SCFBPTR(pScrn);
1201 
1202 	if (pScrn->depth < 8)
1203 		return FALSE;
1204 
1205 	if (!fPtr->nDGAMode)
1206 		ScfbDGAAddModes(pScrn);
1207 
1208 	return (DGAInit(pScreen, &ScfbDGAFunctions,
1209 			fPtr->pDGAMode, fPtr->nDGAMode));
1210 }
1211 #endif
1212 
1213 static Bool
ScfbDriverFunc(ScrnInfoPtr pScrn,xorgDriverFuncOp op,pointer ptr)1214 ScfbDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op,
1215     pointer ptr)
1216 {
1217 	xorgHWFlags *flag;
1218 
1219 	switch (op) {
1220 	case GET_REQUIRED_HW_INTERFACES:
1221 		flag = (CARD32*)ptr;
1222 		(*flag) = 0;
1223 		return TRUE;
1224 	default:
1225 		return FALSE;
1226 	}
1227 }
1228 
1229