xf86Helper.c revision 6747b715
1/*
2 * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of the copyright holder(s)
23 * and author(s) shall not be used in advertising or otherwise to promote
24 * the sale, use or other dealings in this Software without prior written
25 * authorization from the copyright holder(s) and author(s).
26 */
27
28/*
29 * Authors: Dirk Hohndel <hohndel@XFree86.Org>
30 *          David Dawes <dawes@XFree86.Org>
31 *          ... and others
32 *
33 * This file includes the helper functions that the server provides for
34 * different drivers.
35 */
36
37#ifdef HAVE_XORG_CONFIG_H
38#include <xorg-config.h>
39#endif
40
41#include <X11/X.h>
42#include "os.h"
43#include "servermd.h"
44#include "pixmapstr.h"
45#include "windowstr.h"
46#include "propertyst.h"
47#include "gcstruct.h"
48#include "loaderProcs.h"
49#include "xf86.h"
50#include "xf86Priv.h"
51#include "xf86_OSlib.h"
52#include "micmap.h"
53#include "xf86DDC.h"
54#include "xf86Xinput.h"
55#include "xf86InPriv.h"
56#include "mivalidate.h"
57#include "xf86Crtc.h"
58
59/* For xf86GetClocks */
60#if defined(CSRG_BASED) || defined(__GNU__)
61#define HAS_SETPRIORITY
62#include <sys/resource.h>
63#endif
64
65static int xf86ScrnInfoPrivateCount = 0;
66
67
68/* Add a pointer to a new DriverRec to xf86DriverList */
69
70void
71xf86AddDriver(DriverPtr driver, pointer module, int flags)
72{
73    /* Don't add null entries */
74    if (!driver)
75	return;
76
77    if (xf86DriverList == NULL)
78	xf86NumDrivers = 0;
79
80    xf86NumDrivers++;
81    xf86DriverList = xnfrealloc(xf86DriverList,
82				xf86NumDrivers * sizeof(DriverPtr));
83    xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
84    if (flags & HaveDriverFuncs)
85	*xf86DriverList[xf86NumDrivers - 1] = *driver;
86    else {
87	(void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
88		       sizeof( DriverRec ) );
89	(void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
90		       sizeof(DriverRec1));
91
92    }
93    xf86DriverList[xf86NumDrivers - 1]->module = module;
94    xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
95}
96
97void
98xf86DeleteDriver(int drvIndex)
99{
100    if (xf86DriverList[drvIndex]
101	&& (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
102	if (xf86DriverList[drvIndex]->module)
103	    UnloadModule(xf86DriverList[drvIndex]->module);
104	free(xf86DriverList[drvIndex]);
105	xf86DriverList[drvIndex] = NULL;
106    }
107}
108
109/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
110
111void
112xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
113{
114    /* Don't add null entries */
115    if (!driver)
116	return;
117
118    if (xf86InputDriverList == NULL)
119	xf86NumInputDrivers = 0;
120
121    xf86NumInputDrivers++;
122    xf86InputDriverList = xnfrealloc(xf86InputDriverList,
123				xf86NumInputDrivers * sizeof(InputDriverPtr));
124    xf86InputDriverList[xf86NumInputDrivers - 1] =
125				xnfalloc(sizeof(InputDriverRec));
126    *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
127    xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
128    xf86InputDriverList[xf86NumInputDrivers - 1]->refCount = 0;
129}
130
131void
132xf86DeleteInputDriver(int drvIndex)
133{
134    if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
135	UnloadModule(xf86InputDriverList[drvIndex]->module);
136    free(xf86InputDriverList[drvIndex]);
137    xf86InputDriverList[drvIndex] = NULL;
138}
139
140InputDriverPtr
141xf86LookupInputDriver(const char *name)
142{
143    int i;
144
145    for (i = 0; i < xf86NumInputDrivers; i++) {
146       if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
147           xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
148           return xf86InputDriverList[i];
149    }
150    return NULL;
151}
152
153InputInfoPtr
154xf86LookupInput(const char *name)
155{
156    InputInfoPtr p;
157
158    for (p = xf86InputDevs; p != NULL; p = p->next) {
159        if (strcmp(name, p->name) == 0)
160            return p;
161    }
162
163    return NULL;
164}
165
166/* Allocate a new ScrnInfoRec in xf86Screens */
167
168ScrnInfoPtr
169xf86AllocateScreen(DriverPtr drv, int flags)
170{
171    int i;
172
173    if (xf86Screens == NULL)
174	xf86NumScreens = 0;
175
176    i = xf86NumScreens++;
177    xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
178    xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
179    xf86Screens[i]->scrnIndex = i;	/* Changes when a screen is removed */
180    xf86Screens[i]->origIndex = i;	/* This never changes */
181    xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
182					 xf86ScrnInfoPrivateCount);
183    /*
184     * EnableDisableFBAccess now gets initialized in InitOutput()
185     * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
186     */
187
188    xf86Screens[i]->drv = drv;
189    drv->refCount++;
190    xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
191
192    xf86Screens[i]->DriverFunc = drv->driverFunc;
193
194    return xf86Screens[i];
195}
196
197
198/*
199 * Remove an entry from xf86Screens.  Ideally it should free all allocated
200 * data.  To do this properly may require a driver hook.
201 */
202
203void
204xf86DeleteScreen(int scrnIndex, int flags)
205{
206    ScrnInfoPtr pScrn;
207    int i;
208
209    /* First check if the screen is valid */
210    if (xf86NumScreens == 0 || xf86Screens == NULL)
211	return;
212
213    if (scrnIndex > xf86NumScreens - 1)
214	return;
215
216    if (!(pScrn = xf86Screens[scrnIndex]))
217	return;
218
219    /* If a FreeScreen function is defined, call it here */
220    if (pScrn->FreeScreen != NULL)
221	pScrn->FreeScreen(scrnIndex, 0);
222
223    while (pScrn->modes)
224	xf86DeleteMode(&pScrn->modes, pScrn->modes);
225
226    while (pScrn->modePool)
227	xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
228
229    xf86OptionListFree(pScrn->options);
230
231    if (pScrn->module)
232	UnloadModule(pScrn->module);
233
234    if (pScrn->drv)
235	pScrn->drv->refCount--;
236
237    free(pScrn->privates);
238
239    xf86ClearEntityListForScreen(scrnIndex);
240
241    free(pScrn);
242
243    /* Move the other entries down, updating their scrnIndex fields */
244
245    xf86NumScreens--;
246
247    for (i = scrnIndex; i < xf86NumScreens; i++) {
248	xf86Screens[i] = xf86Screens[i + 1];
249	xf86Screens[i]->scrnIndex = i;
250	/* Also need to take care of the screen layout settings */
251    }
252}
253
254/*
255 * Allocate a private in ScrnInfoRec.
256 */
257
258int
259xf86AllocateScrnInfoPrivateIndex(void)
260{
261    int idx, i;
262    ScrnInfoPtr pScr;
263    DevUnion *nprivs;
264
265    idx = xf86ScrnInfoPrivateCount++;
266    for (i = 0; i < xf86NumScreens; i++) {
267	pScr = xf86Screens[i];
268	nprivs = xnfrealloc(pScr->privates,
269			    xf86ScrnInfoPrivateCount * sizeof(DevUnion));
270	/* Zero the new private */
271	memset(&nprivs[idx], 0, sizeof(DevUnion));
272	pScr->privates = nprivs;
273    }
274    return idx;
275}
276
277/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
278InputInfoPtr
279xf86AllocateInput(InputDriverPtr drv, int flags)
280{
281    InputInfoPtr new, *prev = NULL;
282
283    if (!(new = calloc(sizeof(InputInfoRec), 1)))
284	return NULL;
285
286    new->drv = drv;
287    drv->refCount++;
288    new->module = DuplicateModule(drv->module, NULL);
289
290    for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
291        ;
292
293    *prev = new;
294    new->next = NULL;
295
296    return new;
297}
298
299
300/*
301 * Remove an entry from xf86InputDevs.  Ideally it should free all allocated
302 * data.  To do this properly may require a driver hook.
303 */
304
305void
306xf86DeleteInput(InputInfoPtr pInp, int flags)
307{
308    InputInfoPtr p;
309
310    /* First check if the inputdev is valid. */
311    if (pInp == NULL)
312	return;
313
314#if 0
315    /* If a free function is defined, call it here. */
316    if (pInp->free)
317	pInp->free(pInp, 0);
318#endif
319
320    if (pInp->module)
321	UnloadModule(pInp->module);
322
323    if (pInp->drv)
324	pInp->drv->refCount--;
325
326    /* This should *really* be handled in drv->UnInit(dev) call instead, but
327     * if the driver forgets about it make sure we free it or at least crash
328     * with flying colors */
329    free(pInp->private);
330
331    FreeInputAttributes(pInp->attrs);
332
333    /* Remove the entry from the list. */
334    if (pInp == xf86InputDevs)
335	xf86InputDevs = pInp->next;
336    else {
337	p = xf86InputDevs;
338	while (p && p->next != pInp)
339	    p = p->next;
340	if (p)
341	    p->next = pInp->next;
342	/* Else the entry wasn't in the xf86InputDevs list (ignore this). */
343    }
344    free(pInp);
345}
346
347Bool
348xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
349{
350    int i;
351
352    if (pScrn->numFormats >= MAXFORMATS)
353	return FALSE;
354
355    if (bpp <= 0) {
356	if (depth == 1)
357	    bpp = 1;
358	else if (depth <= 8)
359	    bpp = 8;
360	else if (depth <= 16)
361	    bpp = 16;
362	else if (depth <= 32)
363	    bpp = 32;
364	else
365	    return FALSE;
366    }
367    if (pad <= 0)
368	pad = BITMAP_SCANLINE_PAD;
369
370    i = pScrn->numFormats++;
371    pScrn->formats[i].depth = depth;
372    pScrn->formats[i].bitsPerPixel = bpp;
373    pScrn->formats[i].scanlinePad = pad;
374    return TRUE;
375}
376
377/*
378 * Set the depth we are using based on (in the following order of preference):
379 *  - values given on the command line
380 *  - values given in the config file
381 *  - values provided by the driver
382 *  - an overall default when nothing else is given
383 *
384 * Also find a Display subsection matching the depth/bpp found.
385 *
386 * Sets the following ScrnInfoRec fields:
387 *     bitsPerPixel, pixmap24, depth, display, imageByteOrder,
388 *     bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
389 *     formats, fbFormat.
390 */
391
392/* Can the screen handle 24 bpp pixmaps */
393#define DO_PIX24(f) ((f & Support24bppFb) || \
394		     ((f & Support32bppFb) && (f & SupportConvert24to32)))
395
396/* Can the screen handle 32 bpp pixmaps */
397#define DO_PIX32(f) ((f & Support32bppFb) || \
398		     ((f & Support24bppFb) && (f & SupportConvert32to24)))
399
400/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
401#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
402			  && (f & PreferConvert24to32))
403
404/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
405#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
406			  && (f & PreferConvert32to24))
407
408/* Can the screen handle 32bpp pixmaps for 24bpp fb */
409#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
410
411/* Can the screen handle 24bpp pixmaps for 32bpp fb */
412#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
413
414#ifndef GLOBAL_DEFAULT_DEPTH
415#define GLOBAL_DEFAULT_DEPTH 24
416#endif
417
418Bool
419xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
420		int depth24flags)
421{
422    int i;
423    DispPtr disp;
424    Pix24Flags pix24 = xf86Info.pixmap24;
425    Bool nomatch = FALSE;
426
427    scrp->bitsPerPixel = -1;
428    scrp->depth = -1;
429    scrp->pixmap24 = Pix24DontCare;
430    scrp->bitsPerPixelFrom = X_DEFAULT;
431    scrp->depthFrom = X_DEFAULT;
432
433    if (xf86FbBpp > 0) {
434	scrp->bitsPerPixel = xf86FbBpp;
435	scrp->bitsPerPixelFrom = X_CMDLINE;
436    }
437
438    if (xf86Depth > 0) {
439	scrp->depth = xf86Depth;
440	scrp->depthFrom = X_CMDLINE;
441    }
442
443    if (xf86FbBpp < 0 && xf86Depth < 0) {
444	if (scrp->confScreen->defaultfbbpp > 0) {
445	    scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
446	    scrp->bitsPerPixelFrom = X_CONFIG;
447	}
448	if (scrp->confScreen->defaultdepth > 0) {
449	    scrp->depth = scrp->confScreen->defaultdepth;
450	    scrp->depthFrom = X_CONFIG;
451	}
452
453	if (scrp->confScreen->defaultfbbpp <= 0 &&
454	    scrp->confScreen->defaultdepth <= 0) {
455	    /*
456	     * Check for DefaultDepth and DefaultFbBpp options in the
457	     * Device sections.
458	     */
459	    int i;
460	    GDevPtr device;
461	    Bool found = FALSE;
462
463	    for (i = 0; i < scrp->numEntities; i++) {
464		device = xf86GetDevFromEntity(scrp->entityList[i],
465					      scrp->entityInstanceList[i]);
466		if (device && device->options) {
467		    if (xf86FindOption(device->options, "DefaultDepth")) {
468			scrp->depth = xf86SetIntOption(device->options,
469						       "DefaultDepth", -1);
470			scrp->depthFrom = X_CONFIG;
471			found = TRUE;
472		    }
473		    if (xf86FindOption(device->options, "DefaultFbBpp")) {
474			scrp->bitsPerPixel = xf86SetIntOption(device->options,
475							      "DefaultFbBpp",
476							      -1);
477			scrp->bitsPerPixelFrom = X_CONFIG;
478			found = TRUE;
479		    }
480		}
481		if (found)
482		    break;
483	    }
484	}
485    }
486
487    /* If none of these is set, pick a default */
488    if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
489        if (fbbpp > 0 || depth > 0) {
490	    if (fbbpp > 0)
491		scrp->bitsPerPixel = fbbpp;
492	    if (depth > 0)
493		scrp->depth = depth;
494	} else {
495	    scrp->depth = GLOBAL_DEFAULT_DEPTH;
496	}
497    }
498
499    /* If any are not given, determine a default for the others */
500
501    if (scrp->bitsPerPixel < 0) {
502	/* The depth must be set */
503	if (scrp->depth > -1) {
504	    if (scrp->depth == 1)
505		scrp->bitsPerPixel = 1;
506	    else if (scrp->depth <= 4)
507		scrp->bitsPerPixel = 4;
508	    else if (scrp->depth <= 8)
509		scrp->bitsPerPixel = 8;
510	    else if (scrp->depth <= 16)
511		scrp->bitsPerPixel = 16;
512	    else if (scrp->depth <= 24) {
513		/*
514		 * Figure out if a choice is possible based on the depth24
515		 * and pix24 flags.
516		 */
517		/* Check pix24 first */
518		if (pix24 != Pix24DontCare) {
519		    if (pix24 == Pix24Use32) {
520			if (DO_PIX32(depth24flags)) {
521			    if (CHOOSE24FOR32(depth24flags))
522				scrp->bitsPerPixel = 24;
523			    else
524				scrp->bitsPerPixel = 32;
525			} else {
526			    nomatch = TRUE;
527			}
528		    } else if (pix24 == Pix24Use24) {
529			if (DO_PIX24(depth24flags)) {
530			    if (CHOOSE32FOR24(depth24flags))
531				scrp->bitsPerPixel = 32;
532			    else
533				scrp->bitsPerPixel = 24;
534			} else {
535			    nomatch = TRUE;
536			}
537		    }
538		} else {
539		    if (DO_PIX32(depth24flags)) {
540			if (CHOOSE24FOR32(depth24flags))
541			    scrp->bitsPerPixel = 24;
542			else
543			    scrp->bitsPerPixel = 32;
544		    } else if (DO_PIX24(depth24flags)) {
545			if (CHOOSE32FOR24(depth24flags))
546			    scrp->bitsPerPixel = 32;
547			else
548			    scrp->bitsPerPixel = 24;
549		    }
550		}
551	    } else if (scrp->depth <= 32)
552		scrp->bitsPerPixel = 32;
553	    else {
554		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
555			   "Specified depth (%d) is greater than 32\n",
556			   scrp->depth);
557		return FALSE;
558	    }
559	} else {
560	    xf86DrvMsg(scrp->scrnIndex, X_ERROR,
561			"xf86SetDepthBpp: internal error: depth and fbbpp"
562			" are both not set\n");
563	    return FALSE;
564	}
565	if (scrp->bitsPerPixel < 0) {
566	    if (nomatch)
567		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
568			"Driver can't support depth 24 pixmap format (%d)\n",
569			PIX24TOBPP(pix24));
570	    else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
571		     NoDepth24Support)
572		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
573			"Driver can't support depth 24\n");
574	    else
575		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
576			"Can't find fbbpp for depth 24\n");
577	    return FALSE;
578	}
579	scrp->bitsPerPixelFrom = X_PROBED;
580    }
581
582    if (scrp->depth <= 0) {
583	/* bitsPerPixel is already set */
584	switch (scrp->bitsPerPixel) {
585	case 32:
586	    scrp->depth = 24;
587	    break;
588	default:
589	    /* 1, 4, 8, 16 and 24 */
590	    scrp->depth = scrp->bitsPerPixel;
591	    break;
592	}
593	scrp->depthFrom = X_PROBED;
594    }
595
596    /* Sanity checks */
597    if (scrp->depth < 1 || scrp->depth > 32) {
598	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
599		   "Specified depth (%d) is not in the range 1-32\n",
600		    scrp->depth);
601	return FALSE;
602    }
603    switch (scrp->bitsPerPixel) {
604    case 1:
605    case 4:
606    case 8:
607    case 16:
608    case 24:
609    case 32:
610	break;
611    default:
612	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
613		   "Specified fbbpp (%d) is not a permitted value\n",
614		   scrp->bitsPerPixel);
615	return FALSE;
616    }
617    if (scrp->depth > scrp->bitsPerPixel) {
618	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
619		   "Specified depth (%d) is greater than the fbbpp (%d)\n",
620		   scrp->depth, scrp->bitsPerPixel);
621	return FALSE;
622    }
623
624    /* set scrp->pixmap24 if the driver isn't flexible */
625    if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
626	scrp->pixmap24 = Pix24Use24;
627    }
628    if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
629	scrp->pixmap24 = Pix24Use32;
630    }
631
632    /*
633     * Find the Display subsection matching the depth/fbbpp and initialise
634     * scrp->display with it.
635     */
636    for (i = 0, disp = scrp->confScreen->displays;
637	 i < scrp->confScreen->numdisplays; i++, disp++) {
638	if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
639	    || (disp->depth == scrp->depth && disp->fbbpp <= 0)
640	    || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
641	    scrp->display = disp;
642	    break;
643	}
644    }
645
646    /*
647     * If an exact match can't be found, see if there is one with no
648     * depth or fbbpp specified.
649     */
650    if (i == scrp->confScreen->numdisplays) {
651	for (i = 0, disp = scrp->confScreen->displays;
652	     i < scrp->confScreen->numdisplays; i++, disp++) {
653	    if (disp->depth <= 0 && disp->fbbpp <= 0) {
654		scrp->display = disp;
655		break;
656	    }
657	}
658    }
659
660    /*
661     * If all else fails, create a default one.
662     */
663    if (i == scrp->confScreen->numdisplays) {
664	scrp->confScreen->numdisplays++;
665	scrp->confScreen->displays =
666		xnfrealloc(scrp->confScreen->displays,
667			   scrp->confScreen->numdisplays * sizeof(DispRec));
668	xf86DrvMsg(scrp->scrnIndex, X_INFO,
669		   "Creating default Display subsection in Screen section\n"
670		   "\t\"%s\" for depth/fbbpp %d/%d\n",
671		   scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
672	memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
673	scrp->confScreen->displays[i].blackColour.red = -1;
674	scrp->confScreen->displays[i].blackColour.green = -1;
675	scrp->confScreen->displays[i].blackColour.blue = -1;
676	scrp->confScreen->displays[i].whiteColour.red = -1;
677	scrp->confScreen->displays[i].whiteColour.green = -1;
678	scrp->confScreen->displays[i].whiteColour.blue = -1;
679	scrp->confScreen->displays[i].defaultVisual = -1;
680	scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
681	scrp->confScreen->displays[i].modes[0] = NULL;
682	scrp->confScreen->displays[i].depth = depth;
683	scrp->confScreen->displays[i].fbbpp = fbbpp;
684	scrp->display = &scrp->confScreen->displays[i];
685    }
686
687    /*
688     * Setup defaults for the display-wide attributes the framebuffer will
689     * need.  These defaults should eventually be set globally, and not
690     * dependent on the screens.
691     */
692    scrp->imageByteOrder = IMAGE_BYTE_ORDER;
693    scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
694    if (scrp->depth < 8) {
695	/* Planar modes need these settings */
696	scrp->bitmapScanlineUnit = 8;
697	scrp->bitmapBitOrder = MSBFirst;
698    } else {
699	scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
700	scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
701    }
702
703    /*
704     * If an unusual depth is required, add it to scrp->formats.  The formats
705     * for the common depths are handled globally in InitOutput
706     */
707    switch (scrp->depth) {
708    case 1:
709    case 4:
710    case 8:
711    case 15:
712    case 16:
713    case 24:
714	/* Common depths.  Nothing to do for them */
715	break;
716    default:
717	if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
718	    xf86DrvMsg(scrp->scrnIndex, X_ERROR,
719		       "Can't add pixmap format for depth %d\n", scrp->depth);
720	    return FALSE;
721	}
722    }
723
724    /* Initialise the framebuffer format for this screen */
725    scrp->fbFormat.depth = scrp->depth;
726    scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
727    scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
728
729    return TRUE;
730}
731
732/*
733 * Print out the selected depth and bpp.
734 */
735void
736xf86PrintDepthBpp(ScrnInfoPtr scrp)
737{
738    xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
739    xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
740}
741
742/*
743 * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
744 * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
745 */
746Bool
747xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
748{
749    MessageType weightFrom = X_DEFAULT;
750
751    scrp->weight.red = 0;
752    scrp->weight.green = 0;
753    scrp->weight.blue = 0;
754
755    if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
756	scrp->weight = xf86Weight;
757	weightFrom = X_CMDLINE;
758    } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
759	       && scrp->display->weight.blue > 0) {
760	scrp->weight = scrp->display->weight;
761	weightFrom = X_CONFIG;
762    } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
763	scrp->weight = weight;
764    } else {
765	switch (scrp->depth) {
766	case 1:
767	case 4:
768	case 8:
769	    scrp->weight.red = scrp->weight.green =
770		scrp->weight.blue = scrp->rgbBits;
771	    break;
772	case 15:
773	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
774	    break;
775	case 16:
776	    scrp->weight.red = scrp->weight.blue = 5;
777	    scrp->weight.green = 6;
778	    break;
779	case 18:
780	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6;
781	    break;
782	case 24:
783	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
784	    break;
785	case 30:
786	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
787	    break;
788	}
789    }
790
791    if (scrp->weight.red)
792	xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
793		   (int)scrp->weight.red, (int)scrp->weight.green,
794		   (int)scrp->weight.blue);
795
796    if (scrp->depth > MAX_PSEUDO_DEPTH &&
797	(scrp->depth != scrp->weight.red + scrp->weight.green +
798			scrp->weight.blue)) {
799	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
800		   "Weight given (%d%d%d) is inconsistent with the "
801		   "depth (%d)\n",
802		   (int)scrp->weight.red, (int)scrp->weight.green,
803		   (int)scrp->weight.blue, scrp->depth);
804	return FALSE;
805    }
806    if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
807	/*
808	 * XXX Does this even mean anything for TrueColor visuals?
809	 * If not, we shouldn't even be setting it here.  However, this
810	 * matches the behaviour of 3.x versions of XFree86.
811	 */
812	scrp->rgbBits = scrp->weight.red;
813	if (scrp->weight.green > scrp->rgbBits)
814	    scrp->rgbBits = scrp->weight.green;
815	if (scrp->weight.blue > scrp->rgbBits)
816	    scrp->rgbBits = scrp->weight.blue;
817    }
818
819    /* Set the mask and offsets */
820    if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
821	/* Default to a setting common to PC hardware */
822	scrp->offset.red = scrp->weight.green + scrp->weight.blue;
823	scrp->offset.green = scrp->weight.blue;
824	scrp->offset.blue = 0;
825	scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
826	scrp->mask.green = ((1 << scrp->weight.green) - 1)
827				<< scrp->offset.green;
828	scrp->mask.blue = (1 << scrp->weight.blue) - 1;
829    } else {
830	/* Initialise to the values passed */
831	scrp->mask.red = mask.red;
832	scrp->mask.green = mask.green;
833	scrp->mask.blue = mask.blue;
834	scrp->offset.red = ffs(mask.red);
835	scrp->offset.green = ffs(mask.green);
836	scrp->offset.blue = ffs(mask.blue);
837    }
838    return TRUE;
839}
840
841Bool
842xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
843{
844    MessageType visualFrom = X_DEFAULT;
845
846    if (defaultColorVisualClass >= 0) {
847	scrp->defaultVisual = defaultColorVisualClass;
848	visualFrom = X_CMDLINE;
849    } else if (scrp->display->defaultVisual >= 0) {
850	scrp->defaultVisual = scrp->display->defaultVisual;
851	visualFrom = X_CONFIG;
852    } else if (visual >= 0) {
853	scrp->defaultVisual = visual;
854    } else {
855	if (scrp->depth == 1)
856	    scrp->defaultVisual = StaticGray;
857	else if (scrp->depth == 4)
858	    scrp->defaultVisual = StaticColor;
859	else if (scrp->depth <= MAX_PSEUDO_DEPTH)
860	    scrp->defaultVisual = PseudoColor;
861	else
862	    scrp->defaultVisual = TrueColor;
863    }
864    switch (scrp->defaultVisual) {
865    case StaticGray:
866    case GrayScale:
867    case StaticColor:
868    case PseudoColor:
869    case TrueColor:
870    case DirectColor:
871	xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
872		   xf86VisualNames[scrp->defaultVisual]);
873	    return TRUE;
874    default:
875
876	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
877		   "Invalid default visual class (%d)\n", scrp->defaultVisual);
878	return FALSE;
879    }
880}
881
882#define TEST_GAMMA(g) \
883	(g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
884
885#define SET_GAMMA(g) \
886	(g) > GAMMA_ZERO ? (g) : 1.0
887
888Bool
889xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
890{
891    MessageType from = X_DEFAULT;
892#if 0
893    xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
894#endif
895    if (TEST_GAMMA(xf86Gamma)) {
896	from = X_CMDLINE;
897	scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
898	scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
899	scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
900    } else if (TEST_GAMMA(scrp->monitor->gamma)) {
901	from = X_CONFIG;
902	scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
903	scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
904	scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
905#if 0
906    } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
907        from = X_PROBED;
908	scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
909	scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
910	scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
911	/* EDID structure version 2 gives optional seperate red, green & blue gamma values
912	 * in bytes 0x57-0x59 */
913#endif
914    } else if (TEST_GAMMA(gamma)) {
915	scrp->gamma.red = SET_GAMMA(gamma.red);
916	scrp->gamma.green = SET_GAMMA(gamma.green);
917	scrp->gamma.blue = SET_GAMMA(gamma.blue);
918    } else {
919	scrp->gamma.red = 1.0;
920	scrp->gamma.green = 1.0;
921	scrp->gamma.blue = 1.0;
922    }
923    /* Pretend we succeeded if we support better a gamma system.
924     * This avoids a confusing message.
925     */
926    if (xf86_crtc_supports_gamma(scrp))
927	return TRUE;
928    xf86DrvMsg(scrp->scrnIndex, from,
929	       "Using gamma correction (%.1f, %.1f, %.1f)\n",
930	       scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
931
932    return TRUE;
933}
934
935#undef TEST_GAMMA
936#undef SET_GAMMA
937
938
939/*
940 * Set the DPI from the command line option.  XXX should allow it to be
941 * calculated from the widthmm/heightmm values.
942 */
943
944#undef MMPERINCH
945#define MMPERINCH 25.4
946
947void
948xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
949{
950    MessageType from = X_DEFAULT;
951    xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
952    int ddcWidthmm, ddcHeightmm;
953    int widthErr, heightErr;
954
955    /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
956    pScrn->widthmm = pScrn->monitor->widthmm;
957    pScrn->heightmm = pScrn->monitor->heightmm;
958
959    if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
960      /* DDC gives display size in mm for individual modes,
961       * but cm for monitor
962       */
963      ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
964      ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
965    } else {
966      ddcWidthmm = ddcHeightmm = 0;
967    }
968
969    if (monitorResolution > 0) {
970	pScrn->xDpi = monitorResolution;
971	pScrn->yDpi = monitorResolution;
972	from = X_CMDLINE;
973    } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
974	from = X_CONFIG;
975	if (pScrn->widthmm > 0) {
976	   pScrn->xDpi =
977		(int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
978	}
979	if (pScrn->heightmm > 0) {
980	   pScrn->yDpi =
981		(int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
982	}
983	if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
984	    pScrn->yDpi = pScrn->xDpi;
985	if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
986	    pScrn->xDpi = pScrn->yDpi;
987	xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
988		   pScrn->widthmm, pScrn->heightmm);
989
990	/* Warn if config and probe disagree about display size */
991	if ( ddcWidthmm && ddcHeightmm ) {
992	  if (pScrn->widthmm > 0) {
993	    widthErr  = abs(ddcWidthmm  - pScrn->widthmm);
994	  } else {
995	    widthErr  = 0;
996	  }
997	  if (pScrn->heightmm > 0) {
998	    heightErr = abs(ddcHeightmm - pScrn->heightmm);
999	  } else {
1000	    heightErr = 0;
1001	  }
1002	  if (widthErr>10 || heightErr>10) {
1003	    /* Should include config file name for monitor here */
1004	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1005		       "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
1006		       ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
1007	  }
1008	}
1009    } else if ( ddcWidthmm && ddcHeightmm ) {
1010	from = X_PROBED;
1011	xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
1012		   ddcWidthmm, ddcHeightmm );
1013	pScrn->widthmm = ddcWidthmm;
1014	pScrn->heightmm = ddcHeightmm;
1015	if (pScrn->widthmm > 0) {
1016	   pScrn->xDpi =
1017		(int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
1018	}
1019	if (pScrn->heightmm > 0) {
1020	   pScrn->yDpi =
1021		(int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
1022	}
1023	if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
1024	    pScrn->yDpi = pScrn->xDpi;
1025	if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
1026	    pScrn->xDpi = pScrn->yDpi;
1027    } else {
1028	if (x > 0)
1029	    pScrn->xDpi = x;
1030	else
1031	    pScrn->xDpi = DEFAULT_DPI;
1032	if (y > 0)
1033	    pScrn->yDpi = y;
1034	else
1035	    pScrn->yDpi = DEFAULT_DPI;
1036    }
1037    xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
1038	       pScrn->xDpi, pScrn->yDpi);
1039}
1040
1041#undef MMPERINCH
1042
1043
1044void
1045xf86SetBlackWhitePixels(ScreenPtr pScreen)
1046{
1047    if (xf86FlipPixels) {
1048	pScreen->whitePixel = 0;
1049	pScreen->blackPixel = 1;
1050    } else {
1051	pScreen->whitePixel = 1;
1052	pScreen->blackPixel = 0;
1053    }
1054}
1055
1056/*
1057 * xf86SetRootClip --
1058 *	Enable or disable rendering to the screen by
1059 *	setting the root clip list and revalidating
1060 *	all of the windows
1061 */
1062
1063static void
1064xf86SetRootClip (ScreenPtr pScreen, Bool enable)
1065{
1066    WindowPtr	pWin = pScreen->root;
1067    WindowPtr	pChild;
1068    Bool	WasViewable = (Bool)(pWin->viewable);
1069    Bool	anyMarked = FALSE;
1070    WindowPtr   pLayerWin;
1071    BoxRec	box;
1072
1073    if (WasViewable)
1074    {
1075	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
1076	{
1077	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
1078						     pChild,
1079						     &pLayerWin);
1080	}
1081	(*pScreen->MarkWindow) (pWin);
1082	anyMarked = TRUE;
1083	if (pWin->valdata)
1084	{
1085	    if (HasBorder (pWin))
1086	    {
1087		RegionPtr	borderVisible;
1088
1089		borderVisible = RegionCreate(NullBox, 1);
1090		RegionSubtract(borderVisible,
1091				&pWin->borderClip, &pWin->winSize);
1092		pWin->valdata->before.borderVisible = borderVisible;
1093	    }
1094	    pWin->valdata->before.resized = TRUE;
1095	}
1096    }
1097
1098    /*
1099     * Use REGION_BREAK to avoid optimizations in ValidateTree
1100     * that assume the root borderClip can't change well, normally
1101     * it doesn't...)
1102     */
1103    if (enable)
1104    {
1105	box.x1 = 0;
1106	box.y1 = 0;
1107	box.x2 = pScreen->width;
1108	box.y2 = pScreen->height;
1109	RegionInit(&pWin->winSize, &box, 1);
1110	RegionInit(&pWin->borderSize, &box, 1);
1111	if (WasViewable)
1112	    RegionReset(&pWin->borderClip, &box);
1113	pWin->drawable.width = pScreen->width;
1114	pWin->drawable.height = pScreen->height;
1115        RegionBreak(&pWin->clipList);
1116    }
1117    else
1118    {
1119	RegionEmpty(&pWin->borderClip);
1120	RegionBreak(&pWin->clipList);
1121    }
1122
1123    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
1124
1125    if (WasViewable)
1126    {
1127	if (pWin->firstChild)
1128	{
1129	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
1130							   pWin->firstChild,
1131							   (WindowPtr *)NULL);
1132	}
1133	else
1134	{
1135	    (*pScreen->MarkWindow) (pWin);
1136	    anyMarked = TRUE;
1137	}
1138
1139
1140	if (anyMarked)
1141	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
1142    }
1143
1144    if (WasViewable)
1145    {
1146	if (anyMarked)
1147	    (*pScreen->HandleExposures)(pWin);
1148	if (anyMarked && pScreen->PostValidateTree)
1149	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
1150    }
1151    if (pWin->realized)
1152	WindowsRestructured ();
1153    FlushAllOutput ();
1154}
1155
1156/*
1157 * Function to enable/disable access to the frame buffer
1158 *
1159 * This is used when VT switching and when entering/leaving DGA direct mode.
1160 *
1161 * This has been rewritten again to eliminate the saved pixmap.  The
1162 * devPrivate field in the screen pixmap is set to NULL to catch code
1163 * accidentally referencing the frame buffer while the X server is not
1164 * supposed to touch it.
1165 *
1166 * Here, we exchange the pixmap private data, rather than the pixmaps
1167 * themselves to avoid having to find and change any references to the screen
1168 * pixmap such as GC's, window privates etc.  This also means that this code
1169 * does not need to know exactly how the pixmap pixels are accessed.  Further,
1170 * this exchange is >not< done through the screen's ModifyPixmapHeader()
1171 * vector.  This means the called frame buffer code layers can determine
1172 * whether they are switched in or out by keeping track of the root pixmap's
1173 * private data, and therefore don't need to access pScrnInfo->vtSema.
1174 */
1175void
1176xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
1177{
1178    ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
1179    ScreenPtr pScreen = pScrnInfo->pScreen;
1180    PixmapPtr pspix;
1181
1182    pspix = (*pScreen->GetScreenPixmap) (pScreen);
1183    if (enable)
1184    {
1185	/*
1186	 * Restore the screen pixmap devPrivate field
1187	 */
1188	pspix->devPrivate = pScrnInfo->pixmapPrivate;
1189	/*
1190	 * Restore all of the clip lists on the screen
1191	 */
1192	if (!xf86Resetting)
1193	    xf86SetRootClip (pScreen, TRUE);
1194
1195    }
1196    else
1197    {
1198	/*
1199	 * Empty all of the clip lists on the screen
1200	 */
1201	xf86SetRootClip (pScreen, FALSE);
1202	/*
1203	 * save the screen pixmap devPrivate field and
1204	 * replace it with NULL so accidental references
1205	 * to the frame buffer are caught
1206	 */
1207	pScrnInfo->pixmapPrivate = pspix->devPrivate;
1208	pspix->devPrivate.ptr = NULL;
1209    }
1210}
1211
1212/* Print driver messages in the standard format */
1213
1214#undef PREFIX_SIZE
1215#define PREFIX_SIZE 14
1216
1217void
1218xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1219		va_list args)
1220{
1221    char *tmpFormat;
1222
1223    /* Prefix the scrnIndex name to the format string. */
1224    if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
1225	xf86Screens[scrnIndex]->name) {
1226	tmpFormat = malloc(strlen(format) +
1227			   strlen(xf86Screens[scrnIndex]->name) +
1228			   PREFIX_SIZE + 1);
1229	if (!tmpFormat)
1230	    return;
1231
1232	snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
1233		 xf86Screens[scrnIndex]->name, scrnIndex);
1234
1235	strcat(tmpFormat, format);
1236	LogVMessageVerb(type, verb, tmpFormat, args);
1237	free(tmpFormat);
1238    } else
1239	LogVMessageVerb(type, verb, format, args);
1240}
1241#undef PREFIX_SIZE
1242
1243/* Print driver messages, with verbose level specified directly */
1244void
1245xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1246	       ...)
1247{
1248    va_list ap;
1249
1250    va_start(ap, format);
1251    xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
1252    va_end(ap);
1253}
1254
1255/* Print driver messages, with verbose level of 1 (default) */
1256void
1257xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
1258{
1259    va_list ap;
1260
1261    va_start(ap, format);
1262    xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
1263    va_end(ap);
1264}
1265
1266/* Print non-driver messages with verbose level specified directly */
1267void
1268xf86MsgVerb(MessageType type, int verb, const char *format, ...)
1269{
1270    va_list ap;
1271
1272    va_start(ap, format);
1273    xf86VDrvMsgVerb(-1, type, verb, format, ap);
1274    va_end(ap);
1275}
1276
1277/* Print non-driver messages with verbose level of 1 (default) */
1278void
1279xf86Msg(MessageType type, const char *format, ...)
1280{
1281    va_list ap;
1282
1283    va_start(ap, format);
1284    xf86VDrvMsgVerb(-1, type, 1, format, ap);
1285    va_end(ap);
1286}
1287
1288/* Just like ErrorF, but with the verbose level checked */
1289void
1290xf86ErrorFVerb(int verb, const char *format, ...)
1291{
1292    va_list ap;
1293
1294    va_start(ap, format);
1295    if (xf86Verbose >= verb || xf86LogVerbose >= verb)
1296	LogVWrite(verb, format, ap);
1297    va_end(ap);
1298}
1299
1300/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
1301void
1302xf86ErrorF(const char *format, ...)
1303{
1304    va_list ap;
1305
1306    va_start(ap, format);
1307    if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
1308	LogVWrite(1, format, ap);
1309    va_end(ap);
1310}
1311
1312
1313void
1314xf86LogInit(void)
1315{
1316    char *lf = NULL;
1317
1318#define LOGSUFFIX ".log"
1319#define LOGOLDSUFFIX ".old"
1320
1321    /* Get the log file name */
1322    if (xf86LogFileFrom == X_DEFAULT) {
1323	/* Append the display number and ".log" */
1324	lf = malloc(strlen(xf86LogFile) + strlen("%s") +
1325		    strlen(LOGSUFFIX) + 1);
1326	if (!lf)
1327	    FatalError("Cannot allocate space for the log file name\n");
1328	sprintf(lf, "%s%%s" LOGSUFFIX, xf86LogFile);
1329	xf86LogFile = lf;
1330    }
1331
1332    xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
1333    xf86LogFileWasOpened = TRUE;
1334
1335    xf86SetVerbosity(xf86Verbose);
1336    xf86SetLogVerbosity(xf86LogVerbose);
1337
1338#undef LOGSUFFIX
1339#undef LOGOLDSUFFIX
1340
1341    free(lf);
1342}
1343
1344void
1345xf86CloseLog(void)
1346{
1347    LogClose();
1348}
1349
1350
1351/*
1352 * Drivers can use these for using their own SymTabRecs.
1353 */
1354
1355const char *
1356xf86TokenToString(SymTabPtr table, int token)
1357{
1358    int i;
1359
1360    for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
1361	;
1362
1363    if (table[i].token < 0)
1364	return NULL;
1365    else
1366	return table[i].name;
1367}
1368
1369int
1370xf86StringToToken(SymTabPtr table, const char *string)
1371{
1372    int i;
1373
1374    if (string == NULL)
1375	return -1;
1376
1377    for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
1378	;
1379
1380    return table[i].token;
1381}
1382
1383/*
1384 * helper to display the clocks found on a card
1385 */
1386void
1387xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
1388{
1389    int j;
1390
1391    xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
1392    for (j=0; j < scrp->numClocks; j++) {
1393	if ((j % 4) == 0) {
1394	    xf86ErrorF("\n");
1395	    xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
1396	}
1397	xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
1398    }
1399    xf86ErrorF("\n");
1400}
1401
1402
1403/*
1404 * This prints out the driver identify message, including the names of
1405 * the supported chipsets.
1406 *
1407 * XXX This makes assumptions about the line width, etc.  Maybe we could
1408 * use a more general "pretty print" function for messages.
1409 */
1410void
1411xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
1412{
1413    int len, i;
1414
1415    len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
1416    xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
1417    for (i = 0; chips[i].name != NULL; i++) {
1418	if (i != 0) {
1419	    xf86ErrorF(",");
1420	    len++;
1421	}
1422	if (len + 2 + strlen(chips[i].name) < 78) {
1423	    xf86ErrorF(" ");
1424	    len++;
1425	} else {
1426	    xf86ErrorF("\n\t");
1427	    len = 8;
1428	}
1429	xf86ErrorF("%s", chips[i].name);
1430	len += strlen(chips[i].name);
1431    }
1432    xf86ErrorF("\n");
1433}
1434
1435
1436int
1437xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
1438{
1439    GDevPtr       gdp, *pgdp = NULL;
1440    confScreenPtr screensecptr;
1441    int i,j;
1442
1443    if (sectlist)
1444	*sectlist = NULL;
1445
1446    /*
1447     * This can happen when running Xorg -showopts and a module like ati
1448     * or vmware tries to load its submodules when xf86ConfigLayout is empty
1449     */
1450    if (!xf86ConfigLayout.screens)
1451	return 0;
1452
1453    /*
1454     * This is a very important function that matches the device sections
1455     * as they show up in the config file with the drivers that the server
1456     * loads at run time.
1457     *
1458     * ChipProbe can call
1459     * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
1460     * with its driver name. The function allocates an array of GDevPtr and
1461     * returns this via sectlist and returns the number of elements in
1462     * this list as return value. 0 means none found, -1 means fatal error.
1463     *
1464     * It can figure out which of the Device sections to use for which card
1465     * (using things like the Card statement, etc). For single headed servers
1466     * there will of course be just one such Device section.
1467     */
1468    i = 0;
1469
1470    /*
1471     * first we need to loop over all the Screens sections to get to all
1472     * 'active' device sections
1473     */
1474    for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
1475        screensecptr = xf86ConfigLayout.screens[j].screen;
1476        if ((screensecptr->device->driver != NULL)
1477            && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
1478            && (! screensecptr->device->claimed)) {
1479            /*
1480             * we have a matching driver that wasn't claimed, yet
1481             */
1482            pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
1483            pgdp[i++] = screensecptr->device;
1484        }
1485    }
1486
1487    /* Then handle the inactive devices */
1488    j = 0;
1489    while (xf86ConfigLayout.inactives[j].identifier) {
1490	gdp = &xf86ConfigLayout.inactives[j];
1491	if (gdp->driver && !gdp->claimed &&
1492	    !xf86NameCmp(gdp->driver,drivername)) {
1493	    /* we have a matching driver that wasn't claimed yet */
1494	    pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
1495	    pgdp[i++] = gdp;
1496	}
1497	j++;
1498    }
1499
1500    /*
1501     * make the array NULL terminated and return its address
1502     */
1503    if (i)
1504        pgdp[i] = NULL;
1505
1506    if (sectlist)
1507	*sectlist = pgdp;
1508    else
1509	free(pgdp);
1510    return i;
1511}
1512
1513/*
1514 * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
1515 */
1516void
1517xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
1518	      void (*ProtectRegs)(ScrnInfoPtr, Bool),
1519	      void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
1520	      int maskval, int knownclkindex, int knownclkvalue)
1521{
1522    register int status = vertsyncreg;
1523    unsigned long i, cnt, rcnt, sync;
1524
1525    /* First save registers that get written on */
1526    (*ClockFunc)(pScrn, CLK_REG_SAVE);
1527
1528    if (num > MAXCLOCKS)
1529	num = MAXCLOCKS;
1530
1531    for (i = 0; i < num; i++)
1532    {
1533	if (ProtectRegs)
1534	    (*ProtectRegs)(pScrn, TRUE);
1535	if (!(*ClockFunc)(pScrn, i))
1536	{
1537	    pScrn->clock[i] = -1;
1538	    continue;
1539	}
1540	if (ProtectRegs)
1541	    (*ProtectRegs)(pScrn, FALSE);
1542	if (BlankScreen)
1543	    (*BlankScreen)(pScrn, FALSE);
1544
1545    	usleep(50000);     /* let VCO stabilise */
1546
1547    	cnt  = 0;
1548    	sync = 200000;
1549
1550	while ((inb(status) & maskval) == 0x00)
1551	    if (sync-- == 0) goto finish;
1552	/* Something appears to be happening, so reset sync count */
1553	sync = 200000;
1554	while ((inb(status) & maskval) == maskval)
1555	    if (sync-- == 0) goto finish;
1556	/* Something appears to be happening, so reset sync count */
1557	sync = 200000;
1558	while ((inb(status) & maskval) == 0x00)
1559	    if (sync-- == 0) goto finish;
1560
1561	for (rcnt = 0; rcnt < 5; rcnt++)
1562	{
1563	    while (!(inb(status) & maskval))
1564		cnt++;
1565	    while ((inb(status) & maskval))
1566		cnt++;
1567	}
1568
1569finish:
1570	pScrn->clock[i] = cnt ? cnt : -1;
1571	if (BlankScreen)
1572            (*BlankScreen)(pScrn, TRUE);
1573    }
1574
1575    for (i = 0; i < num; i++)
1576    {
1577	if (i != knownclkindex)
1578	{
1579	    if (pScrn->clock[i] == -1)
1580	    {
1581		pScrn->clock[i] = 0;
1582	    }
1583	    else
1584	    {
1585		pScrn->clock[i] = (int)(0.5 +
1586                    (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
1587	            (pScrn->clock[i]));
1588		/* Round to nearest 10KHz */
1589		pScrn->clock[i] += 5;
1590		pScrn->clock[i] /= 10;
1591		pScrn->clock[i] *= 10;
1592	    }
1593	}
1594    }
1595
1596    pScrn->clock[knownclkindex] = knownclkvalue;
1597    pScrn->numClocks = num;
1598
1599    /* Restore registers that were written on */
1600    (*ClockFunc)(pScrn, CLK_REG_RESTORE);
1601}
1602
1603const char *
1604xf86GetVisualName(int visual)
1605{
1606    if (visual < 0 || visual > DirectColor)
1607	return NULL;
1608
1609    return xf86VisualNames[visual];
1610}
1611
1612
1613int
1614xf86GetVerbosity(void)
1615{
1616    return max(xf86Verbose, xf86LogVerbose);
1617}
1618
1619Pix24Flags
1620xf86GetPix24(void)
1621{
1622    return xf86Info.pixmap24;
1623}
1624
1625
1626int
1627xf86GetDepth(void)
1628{
1629    return xf86Depth;
1630}
1631
1632
1633rgb
1634xf86GetWeight(void)
1635{
1636    return xf86Weight;
1637}
1638
1639
1640Gamma
1641xf86GetGamma(void)
1642{
1643    return xf86Gamma;
1644}
1645
1646
1647Bool
1648xf86GetFlipPixels(void)
1649{
1650    return xf86FlipPixels;
1651}
1652
1653
1654const char *
1655xf86GetServerName(void)
1656{
1657    return xf86ServerName;
1658}
1659
1660
1661Bool
1662xf86ServerIsExiting(void)
1663{
1664    return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
1665}
1666
1667
1668Bool
1669xf86ServerIsResetting(void)
1670{
1671    return xf86Resetting;
1672}
1673
1674
1675Bool
1676xf86ServerIsInitialising(void)
1677{
1678    return xf86Initialising;
1679}
1680
1681
1682Bool
1683xf86ServerIsOnlyDetecting(void)
1684{
1685    return xf86DoConfigure;
1686}
1687
1688
1689Bool
1690xf86CaughtSignal(void)
1691{
1692    return xf86Info.caughtSignal;
1693}
1694
1695
1696Bool
1697xf86GetVidModeAllowNonLocal(void)
1698{
1699    return xf86Info.vidModeAllowNonLocal;
1700}
1701
1702
1703Bool
1704xf86GetVidModeEnabled(void)
1705{
1706    return xf86Info.vidModeEnabled;
1707}
1708
1709Bool
1710xf86GetModInDevAllowNonLocal(void)
1711{
1712    return xf86Info.miscModInDevAllowNonLocal;
1713}
1714
1715
1716Bool
1717xf86GetModInDevEnabled(void)
1718{
1719    return xf86Info.miscModInDevEnabled;
1720}
1721
1722
1723Bool
1724xf86GetAllowMouseOpenFail(void)
1725{
1726    return xf86Info.allowMouseOpenFail;
1727}
1728
1729
1730Bool
1731xf86IsPc98(void)
1732{
1733#if SUPPORT_PC98
1734    return xf86Info.pc98;
1735#else
1736    return FALSE;
1737#endif
1738}
1739
1740void
1741xf86DisableRandR(void)
1742{
1743    xf86Info.disableRandR = TRUE;
1744    xf86Info.randRFrom = X_PROBED;
1745}
1746
1747CARD32
1748xf86GetModuleVersion(pointer module)
1749{
1750    return (CARD32)LoaderGetModuleVersion(module);
1751}
1752
1753pointer
1754xf86LoadDrvSubModule(DriverPtr drv, const char *name)
1755{
1756    pointer ret;
1757    int errmaj = 0, errmin = 0;
1758
1759    ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
1760			&errmaj, &errmin);
1761    if (!ret)
1762	LoaderErrorMsg(NULL, name, errmaj, errmin);
1763    return ret;
1764}
1765
1766pointer
1767xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
1768{
1769    pointer ret;
1770    int errmaj = 0, errmin = 0;
1771
1772    ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
1773			&errmaj, &errmin);
1774    if (!ret)
1775	LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
1776    return ret;
1777}
1778
1779/*
1780 * xf86LoadOneModule loads a single module.
1781 */
1782pointer
1783xf86LoadOneModule(char *name, pointer opt)
1784{
1785    int errmaj, errmin;
1786    char *Name;
1787    pointer mod;
1788
1789    if (!name)
1790	return NULL;
1791
1792    /* Normalise the module name */
1793    Name = xf86NormalizeName(name);
1794
1795    /* Skip empty names */
1796    if (Name == NULL)
1797	return NULL;
1798    if (*Name == '\0') {
1799	free(Name);
1800	return NULL;
1801    }
1802
1803    mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
1804    if (!mod)
1805	LoaderErrorMsg(NULL, Name, errmaj, errmin);
1806    free(Name);
1807    return mod;
1808}
1809
1810void
1811xf86UnloadSubModule(pointer mod)
1812{
1813    /*
1814     * This is disabled for now.  The loader isn't smart enough yet to undo
1815     * relocations.
1816     */
1817#if 0
1818    UnloadSubModule(mod);
1819#endif
1820}
1821
1822Bool
1823xf86LoaderCheckSymbol(const char *name)
1824{
1825    return LoaderSymbol(name) != NULL;
1826}
1827
1828typedef enum {
1829   OPTION_BACKING_STORE
1830} BSOpts;
1831
1832static const OptionInfoRec BSOptions[] = {
1833   { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
1834   { -1,                   NULL,           OPTV_NONE,    {0}, FALSE }
1835};
1836
1837void
1838xf86SetBackingStore(ScreenPtr pScreen)
1839{
1840    Bool useBS = FALSE;
1841    MessageType from = X_DEFAULT;
1842    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1843    OptionInfoPtr options;
1844
1845    options = xnfalloc(sizeof(BSOptions));
1846    (void)memcpy(options, BSOptions, sizeof(BSOptions));
1847    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
1848
1849    /* check for commandline option here */
1850    if (xf86bsEnableFlag) {
1851	from = X_CMDLINE;
1852	useBS = TRUE;
1853    } else if (xf86bsDisableFlag) {
1854	from = X_CMDLINE;
1855	useBS = FALSE;
1856    } else {
1857	if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
1858	    from = X_CONFIG;
1859    }
1860    free(options);
1861    pScreen->backingStoreSupport = useBS ? Always : NotUseful;
1862    if (serverGeneration == 1)
1863	xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
1864		   useBS ? "enabled" : "disabled");
1865}
1866
1867
1868typedef enum {
1869   OPTION_SILKEN_MOUSE
1870} SMOpts;
1871
1872static const OptionInfoRec SMOptions[] = {
1873   { OPTION_SILKEN_MOUSE, "SilkenMouse",   OPTV_BOOLEAN, {0}, FALSE },
1874   { -1,                   NULL,           OPTV_NONE,    {0}, FALSE }
1875};
1876
1877void
1878xf86SetSilkenMouse (ScreenPtr pScreen)
1879{
1880    Bool useSM = TRUE;
1881    MessageType from = X_DEFAULT;
1882    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1883    OptionInfoPtr options;
1884
1885    options = xnfalloc(sizeof(SMOptions));
1886    (void)memcpy(options, SMOptions, sizeof(SMOptions));
1887    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
1888
1889    /* check for commandline option here */
1890    /* disable if screen shares resources */
1891	/* TODO VGA arb disable silken mouse */
1892    if (xf86silkenMouseDisableFlag) {
1893        from = X_CMDLINE;
1894	useSM = FALSE;
1895    } else {
1896	if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
1897	    from = X_CONFIG;
1898    }
1899    free(options);
1900    /*
1901     * XXX quick hack to report correctly for OSs that can't do SilkenMouse
1902     * yet.  Should handle this differently so that alternate async methods
1903     * work correctly with this too.
1904     */
1905    pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
1906    if (serverGeneration == 1)
1907	xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
1908		   pScrn->silkenMouse ? "enabled" : "disabled");
1909}
1910
1911/* Wrote this function for the PM2 Xv driver, preliminary. */
1912
1913pointer
1914xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
1915		  char **adaptor_name, pointer *adaptor_options)
1916{
1917    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1918    confXvAdaptorPtr adaptor;
1919    int i;
1920
1921    if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
1922	if (adaptor_name) *adaptor_name = NULL;
1923	if (adaptor_options) *adaptor_options = NULL;
1924	return NULL;
1925    }
1926
1927    adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
1928    if (adaptor_name) *adaptor_name = adaptor->identifier;
1929    if (adaptor_options) *adaptor_options = adaptor->options;
1930
1931    for (i = 0; i < adaptor->numports; i++)
1932	if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
1933	    return adaptor->ports[i].options;
1934
1935    return NULL;
1936}
1937
1938/* Rather than duplicate loader's get OS function, just include it directly */
1939#define LoaderGetOS xf86GetOS
1940#include "loader/os.c"
1941
1942static void
1943xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
1944			   EntityProc enter, EntityProc leave, pointer private)
1945{
1946    ScrnInfoPtr pScrn;
1947
1948    if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
1949	xf86RemoveEntityFromScreen(pScrn,pEnt->index);
1950    xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
1951}
1952
1953ScrnInfoPtr
1954xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
1955		   EntityProc init, EntityProc enter, EntityProc leave,
1956		   pointer private)
1957{
1958    EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
1959    if (!pEnt) return pScrn;
1960
1961    if (!(pEnt->location.type == BUS_NONE)) {
1962	free(pEnt);
1963	return pScrn;
1964    }
1965
1966    if (!pEnt->active) {
1967	xf86ConfigFbEntityInactive(pEnt, init,  enter, leave,  private);
1968	free(pEnt);
1969	return pScrn;
1970    }
1971
1972    if (!pScrn)
1973	pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
1974    xf86AddEntityToScreen(pScrn,entityIndex);
1975
1976    xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
1977
1978    return pScrn;
1979}
1980
1981Bool
1982xf86IsScreenPrimary(int scrnIndex)
1983{
1984    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1985    int i;
1986
1987    for (i=0 ; i < pScrn->numEntities; i++) {
1988	if (xf86IsEntityPrimary(i))
1989	    return TRUE;
1990    }
1991    return FALSE;
1992}
1993
1994int
1995xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
1996			       int format, unsigned long len, pointer value )
1997{
1998    RootWinPropPtr pNewProp = NULL, pRegProp;
1999    int i;
2000    Bool existing = FALSE;
2001
2002    DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
2003	   ScrnIndex, property, type, format, len, value);
2004
2005    if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
2006      return BadMatch;
2007    }
2008
2009    if (xf86RegisteredPropertiesTable &&
2010	xf86RegisteredPropertiesTable[ScrnIndex]) {
2011      for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
2012	   pNewProp; pNewProp = pNewProp->next) {
2013	if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
2014	  break;
2015      }
2016    }
2017
2018    if (!pNewProp) {
2019      if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) {
2020	return BadAlloc;
2021      }
2022      /*
2023       * We will put this property at the end of the list so that
2024       * the changes are made in the order they were requested.
2025       */
2026      pNewProp->next = NULL;
2027    } else {
2028      free(pNewProp->name);
2029      existing = TRUE;
2030    }
2031
2032    pNewProp->name = xnfstrdup(NameForAtom(property));
2033    pNewProp->type = type;
2034    pNewProp->format = format;
2035    pNewProp->size = len;
2036    pNewProp->data = value;
2037
2038    DebugF("new property filled\n");
2039
2040    if (NULL==xf86RegisteredPropertiesTable) {
2041      DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
2042	     xf86NumScreens);
2043      if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
2044	return BadAlloc;
2045      }
2046      for (i=0; i<xf86NumScreens; i++) {
2047	xf86RegisteredPropertiesTable[i] = NULL;
2048      }
2049    }
2050
2051    DebugF("xf86RegisteredPropertiesTable %p\n",
2052	   (void *)xf86RegisteredPropertiesTable);
2053    DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
2054	   ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
2055
2056    if (!existing) {
2057      if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
2058	xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
2059      } else {
2060	pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
2061	while (pRegProp->next != NULL) {
2062	  DebugF("- next %p\n", (void *)pRegProp);
2063	  pRegProp = pRegProp->next;
2064        }
2065	pRegProp->next = pNewProp;
2066      }
2067    }
2068    DebugF("xf86RegisterRootWindowProperty succeeded\n");
2069    return Success;
2070}
2071
2072Bool
2073xf86IsUnblank(int mode)
2074{
2075    switch(mode) {
2076    case SCREEN_SAVER_OFF:
2077    case SCREEN_SAVER_FORCER:
2078	return TRUE;
2079    case SCREEN_SAVER_ON:
2080    case SCREEN_SAVER_CYCLE:
2081	return FALSE;
2082    default:
2083	xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
2084	return TRUE;
2085    }
2086}
2087
2088void
2089xf86MotionHistoryAllocate(LocalDevicePtr local)
2090{
2091    AllocateMotionHistory(local->dev);
2092}
2093