1706f2543Smrg/*
2706f2543Smrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
3706f2543Smrg *
4706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5706f2543Smrg * copy of this software and associated documentation files (the "Software"),
6706f2543Smrg * to deal in the Software without restriction, including without limitation
7706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the
9706f2543Smrg * Software is furnished to do so, subject to the following conditions:
10706f2543Smrg *
11706f2543Smrg * The above copyright notice and this permission notice shall be included in
12706f2543Smrg * all copies or substantial portions of the Software.
13706f2543Smrg *
14706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17706f2543Smrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20706f2543Smrg * OTHER DEALINGS IN THE SOFTWARE.
21706f2543Smrg *
22706f2543Smrg * Except as contained in this notice, the name of the copyright holder(s)
23706f2543Smrg * and author(s) shall not be used in advertising or otherwise to promote
24706f2543Smrg * the sale, use or other dealings in this Software without prior written
25706f2543Smrg * authorization from the copyright holder(s) and author(s).
26706f2543Smrg */
27706f2543Smrg
28706f2543Smrg/*
29706f2543Smrg * Authors: Dirk Hohndel <hohndel@XFree86.Org>
30706f2543Smrg *          David Dawes <dawes@XFree86.Org>
31706f2543Smrg *          ... and others
32706f2543Smrg *
33706f2543Smrg * This file includes the helper functions that the server provides for
34706f2543Smrg * different drivers.
35706f2543Smrg */
36706f2543Smrg
37706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
38706f2543Smrg#include <xorg-config.h>
39706f2543Smrg#endif
40706f2543Smrg
41706f2543Smrg#include <X11/X.h>
42706f2543Smrg#include "os.h"
43706f2543Smrg#include "servermd.h"
44706f2543Smrg#include "pixmapstr.h"
45706f2543Smrg#include "windowstr.h"
46706f2543Smrg#include "propertyst.h"
47706f2543Smrg#include "gcstruct.h"
48706f2543Smrg#include "loaderProcs.h"
49706f2543Smrg#include "xf86.h"
50706f2543Smrg#include "xf86Priv.h"
51706f2543Smrg#include "xf86_OSlib.h"
52706f2543Smrg#include "micmap.h"
53706f2543Smrg#include "xf86DDC.h"
54706f2543Smrg#include "xf86Xinput.h"
55706f2543Smrg#include "xf86InPriv.h"
56706f2543Smrg#include "mivalidate.h"
57706f2543Smrg#include "xf86Crtc.h"
58706f2543Smrg
59706f2543Smrg/* For xf86GetClocks */
60706f2543Smrg#if defined(CSRG_BASED) || defined(__GNU__)
61706f2543Smrg#define HAS_SETPRIORITY
62706f2543Smrg#include <sys/resource.h>
63706f2543Smrg#endif
64706f2543Smrg
65706f2543Smrgstatic int xf86ScrnInfoPrivateCount = 0;
66706f2543Smrg
67706f2543Smrg
68706f2543Smrg/* Add a pointer to a new DriverRec to xf86DriverList */
69706f2543Smrg
70706f2543Smrgvoid
71706f2543Smrgxf86AddDriver(DriverPtr driver, pointer module, int flags)
72706f2543Smrg{
73706f2543Smrg    /* Don't add null entries */
74706f2543Smrg    if (!driver)
75706f2543Smrg	return;
76706f2543Smrg
77706f2543Smrg    if (xf86DriverList == NULL)
78706f2543Smrg	xf86NumDrivers = 0;
79706f2543Smrg
80706f2543Smrg    xf86NumDrivers++;
81706f2543Smrg    xf86DriverList = xnfrealloc(xf86DriverList,
82706f2543Smrg				xf86NumDrivers * sizeof(DriverPtr));
83706f2543Smrg    xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
84706f2543Smrg    if (flags & HaveDriverFuncs)
85706f2543Smrg	*xf86DriverList[xf86NumDrivers - 1] = *driver;
86706f2543Smrg    else {
87706f2543Smrg	(void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
88706f2543Smrg		       sizeof( DriverRec ) );
89706f2543Smrg	(void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
90706f2543Smrg		       sizeof(DriverRec1));
91706f2543Smrg
92706f2543Smrg    }
93706f2543Smrg    xf86DriverList[xf86NumDrivers - 1]->module = module;
94706f2543Smrg    xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
95706f2543Smrg}
96706f2543Smrg
97706f2543Smrgvoid
98706f2543Smrgxf86DeleteDriver(int drvIndex)
99706f2543Smrg{
100706f2543Smrg    if (xf86DriverList[drvIndex]
101706f2543Smrg	&& (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
102706f2543Smrg	if (xf86DriverList[drvIndex]->module)
103706f2543Smrg	    UnloadModule(xf86DriverList[drvIndex]->module);
104706f2543Smrg	free(xf86DriverList[drvIndex]);
105706f2543Smrg	xf86DriverList[drvIndex] = NULL;
106706f2543Smrg    }
107706f2543Smrg}
108706f2543Smrg
109706f2543Smrg/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
110706f2543Smrg
111706f2543Smrgvoid
112706f2543Smrgxf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
113706f2543Smrg{
114706f2543Smrg    /* Don't add null entries */
115706f2543Smrg    if (!driver)
116706f2543Smrg	return;
117706f2543Smrg
118706f2543Smrg    if (xf86InputDriverList == NULL)
119706f2543Smrg	xf86NumInputDrivers = 0;
120706f2543Smrg
121706f2543Smrg    xf86NumInputDrivers++;
122706f2543Smrg    xf86InputDriverList = xnfrealloc(xf86InputDriverList,
123706f2543Smrg				xf86NumInputDrivers * sizeof(InputDriverPtr));
124706f2543Smrg    xf86InputDriverList[xf86NumInputDrivers - 1] =
125706f2543Smrg				xnfalloc(sizeof(InputDriverRec));
126706f2543Smrg    *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
127706f2543Smrg    xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
128706f2543Smrg}
129706f2543Smrg
130706f2543Smrgvoid
131706f2543Smrgxf86DeleteInputDriver(int drvIndex)
132706f2543Smrg{
133706f2543Smrg    if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
134706f2543Smrg	UnloadModule(xf86InputDriverList[drvIndex]->module);
135706f2543Smrg    free(xf86InputDriverList[drvIndex]);
136706f2543Smrg    xf86InputDriverList[drvIndex] = NULL;
137706f2543Smrg}
138706f2543Smrg
139706f2543SmrgInputDriverPtr
140706f2543Smrgxf86LookupInputDriver(const char *name)
141706f2543Smrg{
142706f2543Smrg    int i;
143706f2543Smrg
144706f2543Smrg    for (i = 0; i < xf86NumInputDrivers; i++) {
145706f2543Smrg       if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
146706f2543Smrg           xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
147706f2543Smrg           return xf86InputDriverList[i];
148706f2543Smrg    }
149706f2543Smrg    return NULL;
150706f2543Smrg}
151706f2543Smrg
152706f2543SmrgInputInfoPtr
153706f2543Smrgxf86LookupInput(const char *name)
154706f2543Smrg{
155706f2543Smrg    InputInfoPtr p;
156706f2543Smrg
157706f2543Smrg    for (p = xf86InputDevs; p != NULL; p = p->next) {
158706f2543Smrg        if (strcmp(name, p->name) == 0)
159706f2543Smrg            return p;
160706f2543Smrg    }
161706f2543Smrg
162706f2543Smrg    return NULL;
163706f2543Smrg}
164706f2543Smrg
165706f2543Smrg/* Allocate a new ScrnInfoRec in xf86Screens */
166706f2543Smrg
167706f2543SmrgScrnInfoPtr
168706f2543Smrgxf86AllocateScreen(DriverPtr drv, int flags)
169706f2543Smrg{
170706f2543Smrg    int i;
171706f2543Smrg
172706f2543Smrg    if (xf86Screens == NULL)
173706f2543Smrg	xf86NumScreens = 0;
174706f2543Smrg
175706f2543Smrg    i = xf86NumScreens++;
176706f2543Smrg    xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
177706f2543Smrg    xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
178706f2543Smrg    xf86Screens[i]->scrnIndex = i;	/* Changes when a screen is removed */
179706f2543Smrg    xf86Screens[i]->origIndex = i;	/* This never changes */
180706f2543Smrg    xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
181706f2543Smrg					 xf86ScrnInfoPrivateCount);
182706f2543Smrg    /*
183706f2543Smrg     * EnableDisableFBAccess now gets initialized in InitOutput()
184706f2543Smrg     * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
185706f2543Smrg     */
186706f2543Smrg
187706f2543Smrg    xf86Screens[i]->drv = drv;
188706f2543Smrg    drv->refCount++;
189706f2543Smrg    xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
190706f2543Smrg
191706f2543Smrg    xf86Screens[i]->DriverFunc = drv->driverFunc;
192706f2543Smrg
193706f2543Smrg    return xf86Screens[i];
194706f2543Smrg}
195706f2543Smrg
196706f2543Smrg
197706f2543Smrg/*
198706f2543Smrg * Remove an entry from xf86Screens.  Ideally it should free all allocated
199706f2543Smrg * data.  To do this properly may require a driver hook.
200706f2543Smrg */
201706f2543Smrg
202706f2543Smrgvoid
203706f2543Smrgxf86DeleteScreen(int scrnIndex, int flags)
204706f2543Smrg{
205706f2543Smrg    ScrnInfoPtr pScrn;
206706f2543Smrg    int i;
207706f2543Smrg
208706f2543Smrg    /* First check if the screen is valid */
209706f2543Smrg    if (xf86NumScreens == 0 || xf86Screens == NULL)
210706f2543Smrg	return;
211706f2543Smrg
212706f2543Smrg    if (scrnIndex > xf86NumScreens - 1)
213706f2543Smrg	return;
214706f2543Smrg
215706f2543Smrg    if (!(pScrn = xf86Screens[scrnIndex]))
216706f2543Smrg	return;
217706f2543Smrg
218706f2543Smrg    /* If a FreeScreen function is defined, call it here */
219706f2543Smrg    if (pScrn->FreeScreen != NULL)
220706f2543Smrg	pScrn->FreeScreen(scrnIndex, 0);
221706f2543Smrg
222706f2543Smrg    while (pScrn->modes)
223706f2543Smrg	xf86DeleteMode(&pScrn->modes, pScrn->modes);
224706f2543Smrg
225706f2543Smrg    while (pScrn->modePool)
226706f2543Smrg	xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
227706f2543Smrg
228706f2543Smrg    xf86OptionListFree(pScrn->options);
229706f2543Smrg
230706f2543Smrg    if (pScrn->module)
231706f2543Smrg	UnloadModule(pScrn->module);
232706f2543Smrg
233706f2543Smrg    if (pScrn->drv)
234706f2543Smrg	pScrn->drv->refCount--;
235706f2543Smrg
236706f2543Smrg    free(pScrn->privates);
237706f2543Smrg
238706f2543Smrg    xf86ClearEntityListForScreen(scrnIndex);
239706f2543Smrg
240706f2543Smrg    free(pScrn);
241706f2543Smrg
242706f2543Smrg    /* Move the other entries down, updating their scrnIndex fields */
243706f2543Smrg
244706f2543Smrg    xf86NumScreens--;
245706f2543Smrg
246706f2543Smrg    for (i = scrnIndex; i < xf86NumScreens; i++) {
247706f2543Smrg	xf86Screens[i] = xf86Screens[i + 1];
248706f2543Smrg	xf86Screens[i]->scrnIndex = i;
249706f2543Smrg	/* Also need to take care of the screen layout settings */
250706f2543Smrg    }
251706f2543Smrg}
252706f2543Smrg
253706f2543Smrg/*
254706f2543Smrg * Allocate a private in ScrnInfoRec.
255706f2543Smrg */
256706f2543Smrg
257706f2543Smrgint
258706f2543Smrgxf86AllocateScrnInfoPrivateIndex(void)
259706f2543Smrg{
260706f2543Smrg    int idx, i;
261706f2543Smrg    ScrnInfoPtr pScr;
262706f2543Smrg    DevUnion *nprivs;
263706f2543Smrg
264706f2543Smrg    idx = xf86ScrnInfoPrivateCount++;
265706f2543Smrg    for (i = 0; i < xf86NumScreens; i++) {
266706f2543Smrg	pScr = xf86Screens[i];
267706f2543Smrg	nprivs = xnfrealloc(pScr->privates,
268706f2543Smrg			    xf86ScrnInfoPrivateCount * sizeof(DevUnion));
269706f2543Smrg	/* Zero the new private */
270706f2543Smrg	memset(&nprivs[idx], 0, sizeof(DevUnion));
271706f2543Smrg	pScr->privates = nprivs;
272706f2543Smrg    }
273706f2543Smrg    return idx;
274706f2543Smrg}
275706f2543Smrg
276706f2543SmrgBool
277706f2543Smrgxf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
278706f2543Smrg{
279706f2543Smrg    int i;
280706f2543Smrg
281706f2543Smrg    if (pScrn->numFormats >= MAXFORMATS)
282706f2543Smrg	return FALSE;
283706f2543Smrg
284706f2543Smrg    if (bpp <= 0) {
285706f2543Smrg	if (depth == 1)
286706f2543Smrg	    bpp = 1;
287706f2543Smrg	else if (depth <= 8)
288706f2543Smrg	    bpp = 8;
289706f2543Smrg	else if (depth <= 16)
290706f2543Smrg	    bpp = 16;
291706f2543Smrg	else if (depth <= 32)
292706f2543Smrg	    bpp = 32;
293706f2543Smrg	else
294706f2543Smrg	    return FALSE;
295706f2543Smrg    }
296706f2543Smrg    if (pad <= 0)
297706f2543Smrg	pad = BITMAP_SCANLINE_PAD;
298706f2543Smrg
299706f2543Smrg    i = pScrn->numFormats++;
300706f2543Smrg    pScrn->formats[i].depth = depth;
301706f2543Smrg    pScrn->formats[i].bitsPerPixel = bpp;
302706f2543Smrg    pScrn->formats[i].scanlinePad = pad;
303706f2543Smrg    return TRUE;
304706f2543Smrg}
305706f2543Smrg
306706f2543Smrg/*
307706f2543Smrg * Set the depth we are using based on (in the following order of preference):
308706f2543Smrg *  - values given on the command line
309706f2543Smrg *  - values given in the config file
310706f2543Smrg *  - values provided by the driver
311706f2543Smrg *  - an overall default when nothing else is given
312706f2543Smrg *
313706f2543Smrg * Also find a Display subsection matching the depth/bpp found.
314706f2543Smrg *
315706f2543Smrg * Sets the following ScrnInfoRec fields:
316706f2543Smrg *     bitsPerPixel, pixmap24, depth, display, imageByteOrder,
317706f2543Smrg *     bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
318706f2543Smrg *     formats, fbFormat.
319706f2543Smrg */
320706f2543Smrg
321706f2543Smrg/* Can the screen handle 24 bpp pixmaps */
322706f2543Smrg#define DO_PIX24(f) ((f & Support24bppFb) || \
323706f2543Smrg		     ((f & Support32bppFb) && (f & SupportConvert24to32)))
324706f2543Smrg
325706f2543Smrg/* Can the screen handle 32 bpp pixmaps */
326706f2543Smrg#define DO_PIX32(f) ((f & Support32bppFb) || \
327706f2543Smrg		     ((f & Support24bppFb) && (f & SupportConvert32to24)))
328706f2543Smrg
329706f2543Smrg/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
330706f2543Smrg#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
331706f2543Smrg			  && (f & PreferConvert24to32))
332706f2543Smrg
333706f2543Smrg/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
334706f2543Smrg#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
335706f2543Smrg			  && (f & PreferConvert32to24))
336706f2543Smrg
337706f2543Smrg/* Can the screen handle 32bpp pixmaps for 24bpp fb */
338706f2543Smrg#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
339706f2543Smrg
340706f2543Smrg/* Can the screen handle 24bpp pixmaps for 32bpp fb */
341706f2543Smrg#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
342706f2543Smrg
343706f2543Smrg#ifndef GLOBAL_DEFAULT_DEPTH
344706f2543Smrg#define GLOBAL_DEFAULT_DEPTH 24
345706f2543Smrg#endif
346706f2543Smrg
347706f2543SmrgBool
348706f2543Smrgxf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
349706f2543Smrg		int depth24flags)
350706f2543Smrg{
351706f2543Smrg    int i;
352706f2543Smrg    DispPtr disp;
353706f2543Smrg    Pix24Flags pix24 = xf86Info.pixmap24;
354706f2543Smrg    Bool nomatch = FALSE;
355706f2543Smrg
356706f2543Smrg    scrp->bitsPerPixel = -1;
357706f2543Smrg    scrp->depth = -1;
358706f2543Smrg    scrp->pixmap24 = Pix24DontCare;
359706f2543Smrg    scrp->bitsPerPixelFrom = X_DEFAULT;
360706f2543Smrg    scrp->depthFrom = X_DEFAULT;
361706f2543Smrg
362706f2543Smrg    if (xf86FbBpp > 0) {
363706f2543Smrg	scrp->bitsPerPixel = xf86FbBpp;
364706f2543Smrg	scrp->bitsPerPixelFrom = X_CMDLINE;
365706f2543Smrg    }
366706f2543Smrg
367706f2543Smrg    if (xf86Depth > 0) {
368706f2543Smrg	scrp->depth = xf86Depth;
369706f2543Smrg	scrp->depthFrom = X_CMDLINE;
370706f2543Smrg    }
371706f2543Smrg
372706f2543Smrg    if (xf86FbBpp < 0 && xf86Depth < 0) {
373706f2543Smrg	if (scrp->confScreen->defaultfbbpp > 0) {
374706f2543Smrg	    scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
375706f2543Smrg	    scrp->bitsPerPixelFrom = X_CONFIG;
376706f2543Smrg	}
377706f2543Smrg	if (scrp->confScreen->defaultdepth > 0) {
378706f2543Smrg	    scrp->depth = scrp->confScreen->defaultdepth;
379706f2543Smrg	    scrp->depthFrom = X_CONFIG;
380706f2543Smrg	}
381706f2543Smrg
382706f2543Smrg	if (scrp->confScreen->defaultfbbpp <= 0 &&
383706f2543Smrg	    scrp->confScreen->defaultdepth <= 0) {
384706f2543Smrg	    /*
385706f2543Smrg	     * Check for DefaultDepth and DefaultFbBpp options in the
386706f2543Smrg	     * Device sections.
387706f2543Smrg	     */
388706f2543Smrg	    int i;
389706f2543Smrg	    GDevPtr device;
390706f2543Smrg	    Bool found = FALSE;
391706f2543Smrg
392706f2543Smrg	    for (i = 0; i < scrp->numEntities; i++) {
393706f2543Smrg		device = xf86GetDevFromEntity(scrp->entityList[i],
394706f2543Smrg					      scrp->entityInstanceList[i]);
395706f2543Smrg		if (device && device->options) {
396706f2543Smrg		    if (xf86FindOption(device->options, "DefaultDepth")) {
397706f2543Smrg			scrp->depth = xf86SetIntOption(device->options,
398706f2543Smrg						       "DefaultDepth", -1);
399706f2543Smrg			scrp->depthFrom = X_CONFIG;
400706f2543Smrg			found = TRUE;
401706f2543Smrg		    }
402706f2543Smrg		    if (xf86FindOption(device->options, "DefaultFbBpp")) {
403706f2543Smrg			scrp->bitsPerPixel = xf86SetIntOption(device->options,
404706f2543Smrg							      "DefaultFbBpp",
405706f2543Smrg							      -1);
406706f2543Smrg			scrp->bitsPerPixelFrom = X_CONFIG;
407706f2543Smrg			found = TRUE;
408706f2543Smrg		    }
409706f2543Smrg		}
410706f2543Smrg		if (found)
411706f2543Smrg		    break;
412706f2543Smrg	    }
413706f2543Smrg	}
414706f2543Smrg    }
415706f2543Smrg
416706f2543Smrg    /* If none of these is set, pick a default */
417706f2543Smrg    if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
418706f2543Smrg        if (fbbpp > 0 || depth > 0) {
419706f2543Smrg	    if (fbbpp > 0)
420706f2543Smrg		scrp->bitsPerPixel = fbbpp;
421706f2543Smrg	    if (depth > 0)
422706f2543Smrg		scrp->depth = depth;
423706f2543Smrg	} else {
424706f2543Smrg	    scrp->depth = GLOBAL_DEFAULT_DEPTH;
425706f2543Smrg	}
426706f2543Smrg    }
427706f2543Smrg
428706f2543Smrg    /* If any are not given, determine a default for the others */
429706f2543Smrg
430706f2543Smrg    if (scrp->bitsPerPixel < 0) {
431706f2543Smrg	/* The depth must be set */
432706f2543Smrg	if (scrp->depth > -1) {
433706f2543Smrg	    if (scrp->depth == 1)
434706f2543Smrg		scrp->bitsPerPixel = 1;
435706f2543Smrg	    else if (scrp->depth <= 4)
436706f2543Smrg		scrp->bitsPerPixel = 4;
437706f2543Smrg	    else if (scrp->depth <= 8)
438706f2543Smrg		scrp->bitsPerPixel = 8;
439706f2543Smrg	    else if (scrp->depth <= 16)
440706f2543Smrg		scrp->bitsPerPixel = 16;
441706f2543Smrg	    else if (scrp->depth <= 24) {
442706f2543Smrg		/*
443706f2543Smrg		 * Figure out if a choice is possible based on the depth24
444706f2543Smrg		 * and pix24 flags.
445706f2543Smrg		 */
446706f2543Smrg		/* Check pix24 first */
447706f2543Smrg		if (pix24 != Pix24DontCare) {
448706f2543Smrg		    if (pix24 == Pix24Use32) {
449706f2543Smrg			if (DO_PIX32(depth24flags)) {
450706f2543Smrg			    if (CHOOSE24FOR32(depth24flags))
451706f2543Smrg				scrp->bitsPerPixel = 24;
452706f2543Smrg			    else
453706f2543Smrg				scrp->bitsPerPixel = 32;
454706f2543Smrg			} else {
455706f2543Smrg			    nomatch = TRUE;
456706f2543Smrg			}
457706f2543Smrg		    } else if (pix24 == Pix24Use24) {
458706f2543Smrg			if (DO_PIX24(depth24flags)) {
459706f2543Smrg			    if (CHOOSE32FOR24(depth24flags))
460706f2543Smrg				scrp->bitsPerPixel = 32;
461706f2543Smrg			    else
462706f2543Smrg				scrp->bitsPerPixel = 24;
463706f2543Smrg			} else {
464706f2543Smrg			    nomatch = TRUE;
465706f2543Smrg			}
466706f2543Smrg		    }
467706f2543Smrg		} else {
468706f2543Smrg		    if (DO_PIX32(depth24flags)) {
469706f2543Smrg			if (CHOOSE24FOR32(depth24flags))
470706f2543Smrg			    scrp->bitsPerPixel = 24;
471706f2543Smrg			else
472706f2543Smrg			    scrp->bitsPerPixel = 32;
473706f2543Smrg		    } else if (DO_PIX24(depth24flags)) {
474706f2543Smrg			if (CHOOSE32FOR24(depth24flags))
475706f2543Smrg			    scrp->bitsPerPixel = 32;
476706f2543Smrg			else
477706f2543Smrg			    scrp->bitsPerPixel = 24;
478706f2543Smrg		    }
479706f2543Smrg		}
480706f2543Smrg	    } else if (scrp->depth <= 32)
481706f2543Smrg		scrp->bitsPerPixel = 32;
482706f2543Smrg	    else {
483706f2543Smrg		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
484706f2543Smrg			   "Specified depth (%d) is greater than 32\n",
485706f2543Smrg			   scrp->depth);
486706f2543Smrg		return FALSE;
487706f2543Smrg	    }
488706f2543Smrg	} else {
489706f2543Smrg	    xf86DrvMsg(scrp->scrnIndex, X_ERROR,
490706f2543Smrg			"xf86SetDepthBpp: internal error: depth and fbbpp"
491706f2543Smrg			" are both not set\n");
492706f2543Smrg	    return FALSE;
493706f2543Smrg	}
494706f2543Smrg	if (scrp->bitsPerPixel < 0) {
495706f2543Smrg	    if (nomatch)
496706f2543Smrg		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
497706f2543Smrg			"Driver can't support depth 24 pixmap format (%d)\n",
498706f2543Smrg			PIX24TOBPP(pix24));
499706f2543Smrg	    else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
500706f2543Smrg		     NoDepth24Support)
501706f2543Smrg		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
502706f2543Smrg			"Driver can't support depth 24\n");
503706f2543Smrg	    else
504706f2543Smrg		xf86DrvMsg(scrp->scrnIndex, X_ERROR,
505706f2543Smrg			"Can't find fbbpp for depth 24\n");
506706f2543Smrg	    return FALSE;
507706f2543Smrg	}
508706f2543Smrg	scrp->bitsPerPixelFrom = X_PROBED;
509706f2543Smrg    }
510706f2543Smrg
511706f2543Smrg    if (scrp->depth <= 0) {
512706f2543Smrg	/* bitsPerPixel is already set */
513706f2543Smrg	switch (scrp->bitsPerPixel) {
514706f2543Smrg	case 32:
515706f2543Smrg	    scrp->depth = 24;
516706f2543Smrg	    break;
517706f2543Smrg	default:
518706f2543Smrg	    /* 1, 4, 8, 16 and 24 */
519706f2543Smrg	    scrp->depth = scrp->bitsPerPixel;
520706f2543Smrg	    break;
521706f2543Smrg	}
522706f2543Smrg	scrp->depthFrom = X_PROBED;
523706f2543Smrg    }
524706f2543Smrg
525706f2543Smrg    /* Sanity checks */
526706f2543Smrg    if (scrp->depth < 1 || scrp->depth > 32) {
527706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
528706f2543Smrg		   "Specified depth (%d) is not in the range 1-32\n",
529706f2543Smrg		    scrp->depth);
530706f2543Smrg	return FALSE;
531706f2543Smrg    }
532706f2543Smrg    switch (scrp->bitsPerPixel) {
533706f2543Smrg    case 1:
534706f2543Smrg    case 4:
535706f2543Smrg    case 8:
536706f2543Smrg    case 16:
537706f2543Smrg    case 24:
538706f2543Smrg    case 32:
539706f2543Smrg	break;
540706f2543Smrg    default:
541706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
542706f2543Smrg		   "Specified fbbpp (%d) is not a permitted value\n",
543706f2543Smrg		   scrp->bitsPerPixel);
544706f2543Smrg	return FALSE;
545706f2543Smrg    }
546706f2543Smrg    if (scrp->depth > scrp->bitsPerPixel) {
547706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
548706f2543Smrg		   "Specified depth (%d) is greater than the fbbpp (%d)\n",
549706f2543Smrg		   scrp->depth, scrp->bitsPerPixel);
550706f2543Smrg	return FALSE;
551706f2543Smrg    }
552706f2543Smrg
553706f2543Smrg    /* set scrp->pixmap24 if the driver isn't flexible */
554706f2543Smrg    if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
555706f2543Smrg	scrp->pixmap24 = Pix24Use24;
556706f2543Smrg    }
557706f2543Smrg    if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
558706f2543Smrg	scrp->pixmap24 = Pix24Use32;
559706f2543Smrg    }
560706f2543Smrg
561706f2543Smrg    /*
562706f2543Smrg     * Find the Display subsection matching the depth/fbbpp and initialise
563706f2543Smrg     * scrp->display with it.
564706f2543Smrg     */
565706f2543Smrg    for (i = 0, disp = scrp->confScreen->displays;
566706f2543Smrg	 i < scrp->confScreen->numdisplays; i++, disp++) {
567706f2543Smrg	if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
568706f2543Smrg	    || (disp->depth == scrp->depth && disp->fbbpp <= 0)
569706f2543Smrg	    || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
570706f2543Smrg	    scrp->display = disp;
571706f2543Smrg	    break;
572706f2543Smrg	}
573706f2543Smrg    }
574706f2543Smrg
575706f2543Smrg    /*
576706f2543Smrg     * If an exact match can't be found, see if there is one with no
577706f2543Smrg     * depth or fbbpp specified.
578706f2543Smrg     */
579706f2543Smrg    if (i == scrp->confScreen->numdisplays) {
580706f2543Smrg	for (i = 0, disp = scrp->confScreen->displays;
581706f2543Smrg	     i < scrp->confScreen->numdisplays; i++, disp++) {
582706f2543Smrg	    if (disp->depth <= 0 && disp->fbbpp <= 0) {
583706f2543Smrg		scrp->display = disp;
584706f2543Smrg		break;
585706f2543Smrg	    }
586706f2543Smrg	}
587706f2543Smrg    }
588706f2543Smrg
589706f2543Smrg    /*
590706f2543Smrg     * If all else fails, create a default one.
591706f2543Smrg     */
592706f2543Smrg    if (i == scrp->confScreen->numdisplays) {
593706f2543Smrg	scrp->confScreen->numdisplays++;
594706f2543Smrg	scrp->confScreen->displays =
595706f2543Smrg		xnfrealloc(scrp->confScreen->displays,
596706f2543Smrg			   scrp->confScreen->numdisplays * sizeof(DispRec));
597706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, X_INFO,
598706f2543Smrg		   "Creating default Display subsection in Screen section\n"
599706f2543Smrg		   "\t\"%s\" for depth/fbbpp %d/%d\n",
600706f2543Smrg		   scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
601706f2543Smrg	memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
602706f2543Smrg	scrp->confScreen->displays[i].blackColour.red = -1;
603706f2543Smrg	scrp->confScreen->displays[i].blackColour.green = -1;
604706f2543Smrg	scrp->confScreen->displays[i].blackColour.blue = -1;
605706f2543Smrg	scrp->confScreen->displays[i].whiteColour.red = -1;
606706f2543Smrg	scrp->confScreen->displays[i].whiteColour.green = -1;
607706f2543Smrg	scrp->confScreen->displays[i].whiteColour.blue = -1;
608706f2543Smrg	scrp->confScreen->displays[i].defaultVisual = -1;
609706f2543Smrg	scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
610706f2543Smrg	scrp->confScreen->displays[i].modes[0] = NULL;
611706f2543Smrg	scrp->confScreen->displays[i].depth = depth;
612706f2543Smrg	scrp->confScreen->displays[i].fbbpp = fbbpp;
613706f2543Smrg	scrp->display = &scrp->confScreen->displays[i];
614706f2543Smrg    }
615706f2543Smrg
616706f2543Smrg    /*
617706f2543Smrg     * Setup defaults for the display-wide attributes the framebuffer will
618706f2543Smrg     * need.  These defaults should eventually be set globally, and not
619706f2543Smrg     * dependent on the screens.
620706f2543Smrg     */
621706f2543Smrg    scrp->imageByteOrder = IMAGE_BYTE_ORDER;
622706f2543Smrg    scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
623706f2543Smrg    if (scrp->depth < 8) {
624706f2543Smrg	/* Planar modes need these settings */
625706f2543Smrg	scrp->bitmapScanlineUnit = 8;
626706f2543Smrg	scrp->bitmapBitOrder = MSBFirst;
627706f2543Smrg    } else {
628706f2543Smrg	scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
629706f2543Smrg	scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
630706f2543Smrg    }
631706f2543Smrg
632706f2543Smrg    /*
633706f2543Smrg     * If an unusual depth is required, add it to scrp->formats.  The formats
634706f2543Smrg     * for the common depths are handled globally in InitOutput
635706f2543Smrg     */
636706f2543Smrg    switch (scrp->depth) {
637706f2543Smrg    case 1:
638706f2543Smrg    case 4:
639706f2543Smrg    case 8:
640706f2543Smrg    case 15:
641706f2543Smrg    case 16:
642706f2543Smrg    case 24:
643706f2543Smrg	/* Common depths.  Nothing to do for them */
644706f2543Smrg	break;
645706f2543Smrg    default:
646706f2543Smrg	if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
647706f2543Smrg	    xf86DrvMsg(scrp->scrnIndex, X_ERROR,
648706f2543Smrg		       "Can't add pixmap format for depth %d\n", scrp->depth);
649706f2543Smrg	    return FALSE;
650706f2543Smrg	}
651706f2543Smrg    }
652706f2543Smrg
653706f2543Smrg    /* Initialise the framebuffer format for this screen */
654706f2543Smrg    scrp->fbFormat.depth = scrp->depth;
655706f2543Smrg    scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
656706f2543Smrg    scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
657706f2543Smrg
658706f2543Smrg    return TRUE;
659706f2543Smrg}
660706f2543Smrg
661706f2543Smrg/*
662706f2543Smrg * Print out the selected depth and bpp.
663706f2543Smrg */
664706f2543Smrgvoid
665706f2543Smrgxf86PrintDepthBpp(ScrnInfoPtr scrp)
666706f2543Smrg{
667706f2543Smrg    xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
668706f2543Smrg    xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
669706f2543Smrg}
670706f2543Smrg
671706f2543Smrg/*
672706f2543Smrg * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
673706f2543Smrg * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
674706f2543Smrg */
675706f2543SmrgBool
676706f2543Smrgxf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
677706f2543Smrg{
678706f2543Smrg    MessageType weightFrom = X_DEFAULT;
679706f2543Smrg
680706f2543Smrg    scrp->weight.red = 0;
681706f2543Smrg    scrp->weight.green = 0;
682706f2543Smrg    scrp->weight.blue = 0;
683706f2543Smrg
684706f2543Smrg    if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
685706f2543Smrg	scrp->weight = xf86Weight;
686706f2543Smrg	weightFrom = X_CMDLINE;
687706f2543Smrg    } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
688706f2543Smrg	       && scrp->display->weight.blue > 0) {
689706f2543Smrg	scrp->weight = scrp->display->weight;
690706f2543Smrg	weightFrom = X_CONFIG;
691706f2543Smrg    } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
692706f2543Smrg	scrp->weight = weight;
693706f2543Smrg    } else {
694706f2543Smrg	switch (scrp->depth) {
695706f2543Smrg	case 1:
696706f2543Smrg	case 4:
697706f2543Smrg	case 8:
698706f2543Smrg	    scrp->weight.red = scrp->weight.green =
699706f2543Smrg		scrp->weight.blue = scrp->rgbBits;
700706f2543Smrg	    break;
701706f2543Smrg	case 15:
702706f2543Smrg	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
703706f2543Smrg	    break;
704706f2543Smrg	case 16:
705706f2543Smrg	    scrp->weight.red = scrp->weight.blue = 5;
706706f2543Smrg	    scrp->weight.green = 6;
707706f2543Smrg	    break;
708706f2543Smrg	case 18:
709706f2543Smrg	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6;
710706f2543Smrg	    break;
711706f2543Smrg	case 24:
712706f2543Smrg	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
713706f2543Smrg	    break;
714706f2543Smrg	case 30:
715706f2543Smrg	    scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
716706f2543Smrg	    break;
717706f2543Smrg	}
718706f2543Smrg    }
719706f2543Smrg
720706f2543Smrg    if (scrp->weight.red)
721706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
722706f2543Smrg		   (int)scrp->weight.red, (int)scrp->weight.green,
723706f2543Smrg		   (int)scrp->weight.blue);
724706f2543Smrg
725706f2543Smrg    if (scrp->depth > MAX_PSEUDO_DEPTH &&
726706f2543Smrg	(scrp->depth != scrp->weight.red + scrp->weight.green +
727706f2543Smrg			scrp->weight.blue)) {
728706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
729706f2543Smrg		   "Weight given (%d%d%d) is inconsistent with the "
730706f2543Smrg		   "depth (%d)\n",
731706f2543Smrg		   (int)scrp->weight.red, (int)scrp->weight.green,
732706f2543Smrg		   (int)scrp->weight.blue, scrp->depth);
733706f2543Smrg	return FALSE;
734706f2543Smrg    }
735706f2543Smrg    if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
736706f2543Smrg	/*
737706f2543Smrg	 * XXX Does this even mean anything for TrueColor visuals?
738706f2543Smrg	 * If not, we shouldn't even be setting it here.  However, this
739706f2543Smrg	 * matches the behaviour of 3.x versions of XFree86.
740706f2543Smrg	 */
741706f2543Smrg	scrp->rgbBits = scrp->weight.red;
742706f2543Smrg	if (scrp->weight.green > scrp->rgbBits)
743706f2543Smrg	    scrp->rgbBits = scrp->weight.green;
744706f2543Smrg	if (scrp->weight.blue > scrp->rgbBits)
745706f2543Smrg	    scrp->rgbBits = scrp->weight.blue;
746706f2543Smrg    }
747706f2543Smrg
748706f2543Smrg    /* Set the mask and offsets */
749706f2543Smrg    if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
750706f2543Smrg	/* Default to a setting common to PC hardware */
751706f2543Smrg	scrp->offset.red = scrp->weight.green + scrp->weight.blue;
752706f2543Smrg	scrp->offset.green = scrp->weight.blue;
753706f2543Smrg	scrp->offset.blue = 0;
754706f2543Smrg	scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
755706f2543Smrg	scrp->mask.green = ((1 << scrp->weight.green) - 1)
756706f2543Smrg				<< scrp->offset.green;
757706f2543Smrg	scrp->mask.blue = (1 << scrp->weight.blue) - 1;
758706f2543Smrg    } else {
759706f2543Smrg	/* Initialise to the values passed */
760706f2543Smrg	scrp->mask.red = mask.red;
761706f2543Smrg	scrp->mask.green = mask.green;
762706f2543Smrg	scrp->mask.blue = mask.blue;
763706f2543Smrg	scrp->offset.red = ffs(mask.red);
764706f2543Smrg	scrp->offset.green = ffs(mask.green);
765706f2543Smrg	scrp->offset.blue = ffs(mask.blue);
766706f2543Smrg    }
767706f2543Smrg    return TRUE;
768706f2543Smrg}
769706f2543Smrg
770706f2543SmrgBool
771706f2543Smrgxf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
772706f2543Smrg{
773706f2543Smrg    MessageType visualFrom = X_DEFAULT;
774706f2543Smrg
775706f2543Smrg    if (defaultColorVisualClass >= 0) {
776706f2543Smrg	scrp->defaultVisual = defaultColorVisualClass;
777706f2543Smrg	visualFrom = X_CMDLINE;
778706f2543Smrg    } else if (scrp->display->defaultVisual >= 0) {
779706f2543Smrg	scrp->defaultVisual = scrp->display->defaultVisual;
780706f2543Smrg	visualFrom = X_CONFIG;
781706f2543Smrg    } else if (visual >= 0) {
782706f2543Smrg	scrp->defaultVisual = visual;
783706f2543Smrg    } else {
784706f2543Smrg	if (scrp->depth == 1)
785706f2543Smrg	    scrp->defaultVisual = StaticGray;
786706f2543Smrg	else if (scrp->depth == 4)
787706f2543Smrg	    scrp->defaultVisual = StaticColor;
788706f2543Smrg	else if (scrp->depth <= MAX_PSEUDO_DEPTH)
789706f2543Smrg	    scrp->defaultVisual = PseudoColor;
790706f2543Smrg	else
791706f2543Smrg	    scrp->defaultVisual = TrueColor;
792706f2543Smrg    }
793706f2543Smrg    switch (scrp->defaultVisual) {
794706f2543Smrg    case StaticGray:
795706f2543Smrg    case GrayScale:
796706f2543Smrg    case StaticColor:
797706f2543Smrg    case PseudoColor:
798706f2543Smrg    case TrueColor:
799706f2543Smrg    case DirectColor:
800706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
801706f2543Smrg		   xf86VisualNames[scrp->defaultVisual]);
802706f2543Smrg	    return TRUE;
803706f2543Smrg    default:
804706f2543Smrg
805706f2543Smrg	xf86DrvMsg(scrp->scrnIndex, X_ERROR,
806706f2543Smrg		   "Invalid default visual class (%d)\n", scrp->defaultVisual);
807706f2543Smrg	return FALSE;
808706f2543Smrg    }
809706f2543Smrg}
810706f2543Smrg
811706f2543Smrg#define TEST_GAMMA(g) \
812706f2543Smrg	(g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
813706f2543Smrg
814706f2543Smrg#define SET_GAMMA(g) \
815706f2543Smrg	(g) > GAMMA_ZERO ? (g) : 1.0
816706f2543Smrg
817706f2543SmrgBool
818706f2543Smrgxf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
819706f2543Smrg{
820706f2543Smrg    MessageType from = X_DEFAULT;
821706f2543Smrg#if 0
822706f2543Smrg    xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
823706f2543Smrg#endif
824706f2543Smrg    if (TEST_GAMMA(xf86Gamma)) {
825706f2543Smrg	from = X_CMDLINE;
826706f2543Smrg	scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
827706f2543Smrg	scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
828706f2543Smrg	scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
829706f2543Smrg    } else if (TEST_GAMMA(scrp->monitor->gamma)) {
830706f2543Smrg	from = X_CONFIG;
831706f2543Smrg	scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
832706f2543Smrg	scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
833706f2543Smrg	scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
834706f2543Smrg#if 0
835706f2543Smrg    } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
836706f2543Smrg        from = X_PROBED;
837706f2543Smrg	scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
838706f2543Smrg	scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
839706f2543Smrg	scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
840706f2543Smrg	/* EDID structure version 2 gives optional seperate red, green & blue gamma values
841706f2543Smrg	 * in bytes 0x57-0x59 */
842706f2543Smrg#endif
843706f2543Smrg    } else if (TEST_GAMMA(gamma)) {
844706f2543Smrg	scrp->gamma.red = SET_GAMMA(gamma.red);
845706f2543Smrg	scrp->gamma.green = SET_GAMMA(gamma.green);
846706f2543Smrg	scrp->gamma.blue = SET_GAMMA(gamma.blue);
847706f2543Smrg    } else {
848706f2543Smrg	scrp->gamma.red = 1.0;
849706f2543Smrg	scrp->gamma.green = 1.0;
850706f2543Smrg	scrp->gamma.blue = 1.0;
851706f2543Smrg    }
852706f2543Smrg    /* Pretend we succeeded if we support better a gamma system.
853706f2543Smrg     * This avoids a confusing message.
854706f2543Smrg     */
855706f2543Smrg    if (xf86_crtc_supports_gamma(scrp))
856706f2543Smrg	return TRUE;
857706f2543Smrg    xf86DrvMsg(scrp->scrnIndex, from,
858706f2543Smrg	       "Using gamma correction (%.1f, %.1f, %.1f)\n",
859706f2543Smrg	       scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
860706f2543Smrg
861706f2543Smrg    return TRUE;
862706f2543Smrg}
863706f2543Smrg
864706f2543Smrg#undef TEST_GAMMA
865706f2543Smrg#undef SET_GAMMA
866706f2543Smrg
867706f2543Smrg
868706f2543Smrg/*
869706f2543Smrg * Set the DPI from the command line option.  XXX should allow it to be
870706f2543Smrg * calculated from the widthmm/heightmm values.
871706f2543Smrg */
872706f2543Smrg
873706f2543Smrg#undef MMPERINCH
874706f2543Smrg#define MMPERINCH 25.4
875706f2543Smrg
876706f2543Smrgvoid
877706f2543Smrgxf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
878706f2543Smrg{
879706f2543Smrg    MessageType from = X_DEFAULT;
880706f2543Smrg    xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
881706f2543Smrg    int ddcWidthmm, ddcHeightmm;
882706f2543Smrg    int widthErr, heightErr;
883706f2543Smrg
884706f2543Smrg    /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
885706f2543Smrg    pScrn->widthmm = pScrn->monitor->widthmm;
886706f2543Smrg    pScrn->heightmm = pScrn->monitor->heightmm;
887706f2543Smrg
888706f2543Smrg    if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
889706f2543Smrg      /* DDC gives display size in mm for individual modes,
890706f2543Smrg       * but cm for monitor
891706f2543Smrg       */
892706f2543Smrg      ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
893706f2543Smrg      ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
894706f2543Smrg    } else {
895706f2543Smrg      ddcWidthmm = ddcHeightmm = 0;
896706f2543Smrg    }
897706f2543Smrg
898706f2543Smrg    if (monitorResolution > 0) {
899706f2543Smrg	pScrn->xDpi = monitorResolution;
900706f2543Smrg	pScrn->yDpi = monitorResolution;
901706f2543Smrg	from = X_CMDLINE;
902706f2543Smrg    } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
903706f2543Smrg	from = X_CONFIG;
904706f2543Smrg	if (pScrn->widthmm > 0) {
905706f2543Smrg	   pScrn->xDpi =
906706f2543Smrg		(int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
907706f2543Smrg	}
908706f2543Smrg	if (pScrn->heightmm > 0) {
909706f2543Smrg	   pScrn->yDpi =
910706f2543Smrg		(int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
911706f2543Smrg	}
912706f2543Smrg	if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
913706f2543Smrg	    pScrn->yDpi = pScrn->xDpi;
914706f2543Smrg	if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
915706f2543Smrg	    pScrn->xDpi = pScrn->yDpi;
916706f2543Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
917706f2543Smrg		   pScrn->widthmm, pScrn->heightmm);
918706f2543Smrg
919706f2543Smrg	/* Warn if config and probe disagree about display size */
920706f2543Smrg	if ( ddcWidthmm && ddcHeightmm ) {
921706f2543Smrg	  if (pScrn->widthmm > 0) {
922706f2543Smrg	    widthErr  = abs(ddcWidthmm  - pScrn->widthmm);
923706f2543Smrg	  } else {
924706f2543Smrg	    widthErr  = 0;
925706f2543Smrg	  }
926706f2543Smrg	  if (pScrn->heightmm > 0) {
927706f2543Smrg	    heightErr = abs(ddcHeightmm - pScrn->heightmm);
928706f2543Smrg	  } else {
929706f2543Smrg	    heightErr = 0;
930706f2543Smrg	  }
931706f2543Smrg	  if (widthErr>10 || heightErr>10) {
932706f2543Smrg	    /* Should include config file name for monitor here */
933706f2543Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
934706f2543Smrg		       "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
935706f2543Smrg		       ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
936706f2543Smrg	  }
937706f2543Smrg	}
938706f2543Smrg    } else if ( ddcWidthmm && ddcHeightmm ) {
939706f2543Smrg	from = X_PROBED;
940706f2543Smrg	xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
941706f2543Smrg		   ddcWidthmm, ddcHeightmm );
942706f2543Smrg	pScrn->widthmm = ddcWidthmm;
943706f2543Smrg	pScrn->heightmm = ddcHeightmm;
944706f2543Smrg	if (pScrn->widthmm > 0) {
945706f2543Smrg	   pScrn->xDpi =
946706f2543Smrg		(int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
947706f2543Smrg	}
948706f2543Smrg	if (pScrn->heightmm > 0) {
949706f2543Smrg	   pScrn->yDpi =
950706f2543Smrg		(int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
951706f2543Smrg	}
952706f2543Smrg	if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
953706f2543Smrg	    pScrn->yDpi = pScrn->xDpi;
954706f2543Smrg	if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
955706f2543Smrg	    pScrn->xDpi = pScrn->yDpi;
956706f2543Smrg    } else {
957706f2543Smrg	if (x > 0)
958706f2543Smrg	    pScrn->xDpi = x;
959706f2543Smrg	else
960706f2543Smrg	    pScrn->xDpi = DEFAULT_DPI;
961706f2543Smrg	if (y > 0)
962706f2543Smrg	    pScrn->yDpi = y;
963706f2543Smrg	else
964706f2543Smrg	    pScrn->yDpi = DEFAULT_DPI;
965706f2543Smrg    }
966706f2543Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
967706f2543Smrg	       pScrn->xDpi, pScrn->yDpi);
968706f2543Smrg}
969706f2543Smrg
970706f2543Smrg#undef MMPERINCH
971706f2543Smrg
972706f2543Smrg
973706f2543Smrgvoid
974706f2543Smrgxf86SetBlackWhitePixels(ScreenPtr pScreen)
975706f2543Smrg{
976706f2543Smrg    if (xf86FlipPixels) {
977706f2543Smrg	pScreen->whitePixel = 0;
978706f2543Smrg	pScreen->blackPixel = 1;
979706f2543Smrg    } else {
980706f2543Smrg	pScreen->whitePixel = 1;
981706f2543Smrg	pScreen->blackPixel = 0;
982706f2543Smrg    }
983706f2543Smrg}
984706f2543Smrg
985706f2543Smrg/*
986706f2543Smrg * xf86SetRootClip --
987706f2543Smrg *	Enable or disable rendering to the screen by
988706f2543Smrg *	setting the root clip list and revalidating
989706f2543Smrg *	all of the windows
990706f2543Smrg */
991706f2543Smrg
992706f2543Smrgstatic void
993706f2543Smrgxf86SetRootClip (ScreenPtr pScreen, Bool enable)
994706f2543Smrg{
995706f2543Smrg    WindowPtr	pWin = pScreen->root;
996706f2543Smrg    WindowPtr	pChild;
997706f2543Smrg    Bool	WasViewable = (Bool)(pWin->viewable);
998706f2543Smrg    Bool	anyMarked = FALSE;
999706f2543Smrg    WindowPtr   pLayerWin;
1000706f2543Smrg    BoxRec	box;
1001706f2543Smrg
1002706f2543Smrg    if (WasViewable)
1003706f2543Smrg    {
1004706f2543Smrg	for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
1005706f2543Smrg	{
1006706f2543Smrg	    (void) (*pScreen->MarkOverlappedWindows)(pChild,
1007706f2543Smrg						     pChild,
1008706f2543Smrg						     &pLayerWin);
1009706f2543Smrg	}
1010706f2543Smrg	(*pScreen->MarkWindow) (pWin);
1011706f2543Smrg	anyMarked = TRUE;
1012706f2543Smrg	if (pWin->valdata)
1013706f2543Smrg	{
1014706f2543Smrg	    if (HasBorder (pWin))
1015706f2543Smrg	    {
1016706f2543Smrg		RegionPtr	borderVisible;
1017706f2543Smrg
1018706f2543Smrg		borderVisible = RegionCreate(NullBox, 1);
1019706f2543Smrg		RegionSubtract(borderVisible,
1020706f2543Smrg				&pWin->borderClip, &pWin->winSize);
1021706f2543Smrg		pWin->valdata->before.borderVisible = borderVisible;
1022706f2543Smrg	    }
1023706f2543Smrg	    pWin->valdata->before.resized = TRUE;
1024706f2543Smrg	}
1025706f2543Smrg    }
1026706f2543Smrg
1027706f2543Smrg    /*
1028706f2543Smrg     * Use REGION_BREAK to avoid optimizations in ValidateTree
1029706f2543Smrg     * that assume the root borderClip can't change well, normally
1030706f2543Smrg     * it doesn't...)
1031706f2543Smrg     */
1032706f2543Smrg    if (enable)
1033706f2543Smrg    {
1034706f2543Smrg	box.x1 = 0;
1035706f2543Smrg	box.y1 = 0;
1036706f2543Smrg	box.x2 = pScreen->width;
1037706f2543Smrg	box.y2 = pScreen->height;
1038706f2543Smrg	RegionInit(&pWin->winSize, &box, 1);
1039706f2543Smrg	RegionInit(&pWin->borderSize, &box, 1);
1040706f2543Smrg	if (WasViewable)
1041706f2543Smrg	    RegionReset(&pWin->borderClip, &box);
1042706f2543Smrg	pWin->drawable.width = pScreen->width;
1043706f2543Smrg	pWin->drawable.height = pScreen->height;
1044706f2543Smrg        RegionBreak(&pWin->clipList);
1045706f2543Smrg    }
1046706f2543Smrg    else
1047706f2543Smrg    {
1048706f2543Smrg	RegionEmpty(&pWin->borderClip);
1049706f2543Smrg	RegionBreak(&pWin->clipList);
1050706f2543Smrg    }
1051706f2543Smrg
1052706f2543Smrg    ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
1053706f2543Smrg
1054706f2543Smrg    if (WasViewable)
1055706f2543Smrg    {
1056706f2543Smrg	if (pWin->firstChild)
1057706f2543Smrg	{
1058706f2543Smrg	    anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
1059706f2543Smrg							   pWin->firstChild,
1060706f2543Smrg							   (WindowPtr *)NULL);
1061706f2543Smrg	}
1062706f2543Smrg	else
1063706f2543Smrg	{
1064706f2543Smrg	    (*pScreen->MarkWindow) (pWin);
1065706f2543Smrg	    anyMarked = TRUE;
1066706f2543Smrg	}
1067706f2543Smrg
1068706f2543Smrg
1069706f2543Smrg	if (anyMarked)
1070706f2543Smrg	    (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
1071706f2543Smrg    }
1072706f2543Smrg
1073706f2543Smrg    if (WasViewable)
1074706f2543Smrg    {
1075706f2543Smrg	if (anyMarked)
1076706f2543Smrg	    (*pScreen->HandleExposures)(pWin);
1077706f2543Smrg	if (anyMarked && pScreen->PostValidateTree)
1078706f2543Smrg	    (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
1079706f2543Smrg    }
1080706f2543Smrg    if (pWin->realized)
1081706f2543Smrg	WindowsRestructured ();
1082706f2543Smrg    FlushAllOutput ();
1083706f2543Smrg}
1084706f2543Smrg
1085706f2543Smrg/*
1086706f2543Smrg * Function to enable/disable access to the frame buffer
1087706f2543Smrg *
1088706f2543Smrg * This is used when VT switching and when entering/leaving DGA direct mode.
1089706f2543Smrg *
1090706f2543Smrg * This has been rewritten again to eliminate the saved pixmap.  The
1091706f2543Smrg * devPrivate field in the screen pixmap is set to NULL to catch code
1092706f2543Smrg * accidentally referencing the frame buffer while the X server is not
1093706f2543Smrg * supposed to touch it.
1094706f2543Smrg *
1095706f2543Smrg * Here, we exchange the pixmap private data, rather than the pixmaps
1096706f2543Smrg * themselves to avoid having to find and change any references to the screen
1097706f2543Smrg * pixmap such as GC's, window privates etc.  This also means that this code
1098706f2543Smrg * does not need to know exactly how the pixmap pixels are accessed.  Further,
1099706f2543Smrg * this exchange is >not< done through the screen's ModifyPixmapHeader()
1100706f2543Smrg * vector.  This means the called frame buffer code layers can determine
1101706f2543Smrg * whether they are switched in or out by keeping track of the root pixmap's
1102706f2543Smrg * private data, and therefore don't need to access pScrnInfo->vtSema.
1103706f2543Smrg */
1104706f2543Smrgvoid
1105706f2543Smrgxf86EnableDisableFBAccess(int scrnIndex, Bool enable)
1106706f2543Smrg{
1107706f2543Smrg    ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
1108706f2543Smrg    ScreenPtr pScreen = pScrnInfo->pScreen;
1109706f2543Smrg    PixmapPtr pspix;
1110706f2543Smrg
1111706f2543Smrg    pspix = (*pScreen->GetScreenPixmap) (pScreen);
1112706f2543Smrg    if (enable)
1113706f2543Smrg    {
1114706f2543Smrg	/*
1115706f2543Smrg	 * Restore all of the clip lists on the screen
1116706f2543Smrg	 */
1117706f2543Smrg	if (!xf86Resetting)
1118706f2543Smrg	    xf86SetRootClip (pScreen, TRUE);
1119706f2543Smrg
1120706f2543Smrg    }
1121706f2543Smrg    else
1122706f2543Smrg    {
1123706f2543Smrg	/*
1124706f2543Smrg	 * Empty all of the clip lists on the screen
1125706f2543Smrg	 */
1126706f2543Smrg	xf86SetRootClip (pScreen, FALSE);
1127706f2543Smrg    }
1128706f2543Smrg}
1129706f2543Smrg
1130706f2543Smrg/* Print driver messages in the standard format */
1131706f2543Smrg
1132706f2543Smrg#undef PREFIX_SIZE
1133706f2543Smrg#define PREFIX_SIZE 14
1134706f2543Smrg
1135706f2543Smrgvoid
1136706f2543Smrgxf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1137706f2543Smrg		va_list args)
1138706f2543Smrg{
1139706f2543Smrg    char *tmpFormat;
1140706f2543Smrg
1141706f2543Smrg    /* Prefix the scrnIndex name to the format string. */
1142706f2543Smrg    if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
1143706f2543Smrg	xf86Screens[scrnIndex]->name) {
1144706f2543Smrg	tmpFormat = malloc(strlen(format) +
1145706f2543Smrg			   strlen(xf86Screens[scrnIndex]->name) +
1146706f2543Smrg			   PREFIX_SIZE + 1);
1147706f2543Smrg	if (!tmpFormat)
1148706f2543Smrg	    return;
1149706f2543Smrg
1150706f2543Smrg	snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
1151706f2543Smrg		 xf86Screens[scrnIndex]->name, scrnIndex);
1152706f2543Smrg
1153706f2543Smrg	strcat(tmpFormat, format);
1154706f2543Smrg	LogVMessageVerb(type, verb, tmpFormat, args);
1155706f2543Smrg	free(tmpFormat);
1156706f2543Smrg    } else
1157706f2543Smrg	LogVMessageVerb(type, verb, format, args);
1158706f2543Smrg}
1159706f2543Smrg#undef PREFIX_SIZE
1160706f2543Smrg
1161706f2543Smrg/* Print driver messages, with verbose level specified directly */
1162706f2543Smrgvoid
1163706f2543Smrgxf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1164706f2543Smrg	       ...)
1165706f2543Smrg{
1166706f2543Smrg    va_list ap;
1167706f2543Smrg
1168706f2543Smrg    va_start(ap, format);
1169706f2543Smrg    xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
1170706f2543Smrg    va_end(ap);
1171706f2543Smrg}
1172706f2543Smrg
1173706f2543Smrg/* Print driver messages, with verbose level of 1 (default) */
1174706f2543Smrgvoid
1175706f2543Smrgxf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
1176706f2543Smrg{
1177706f2543Smrg    va_list ap;
1178706f2543Smrg
1179706f2543Smrg    va_start(ap, format);
1180706f2543Smrg    xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
1181706f2543Smrg    va_end(ap);
1182706f2543Smrg}
1183706f2543Smrg
1184706f2543Smrg/* Print input driver messages in the standard format of
1185706f2543Smrg   <driver>: <device name>: <message> */
1186706f2543Smrgvoid
1187706f2543Smrgxf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
1188706f2543Smrg		 va_list args)
1189706f2543Smrg{
1190706f2543Smrg    char *msg;
1191706f2543Smrg
1192706f2543Smrg    if (asprintf(&msg, "%s: %s: %s", dev->drv->driverName, dev->name, format)
1193706f2543Smrg	== -1) {
1194706f2543Smrg	LogVMessageVerb(type, verb, "%s", args);
1195706f2543Smrg    } else {
1196706f2543Smrg	LogVMessageVerb(type, verb, msg, args);
1197706f2543Smrg	free(msg);
1198706f2543Smrg    }
1199706f2543Smrg}
1200706f2543Smrg
1201706f2543Smrg/* Print input driver message, with verbose level specified directly */
1202706f2543Smrgvoid
1203706f2543Smrgxf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
1204706f2543Smrg	       ...)
1205706f2543Smrg{
1206706f2543Smrg    va_list ap;
1207706f2543Smrg
1208706f2543Smrg    va_start(ap, format);
1209706f2543Smrg    xf86VIDrvMsgVerb(dev, type, verb, format, ap);
1210706f2543Smrg    va_end(ap);
1211706f2543Smrg}
1212706f2543Smrg
1213706f2543Smrg/* Print input driver messages, with verbose level of 1 (default) */
1214706f2543Smrgvoid
1215706f2543Smrgxf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...)
1216706f2543Smrg{
1217706f2543Smrg    va_list ap;
1218706f2543Smrg
1219706f2543Smrg    va_start(ap, format);
1220706f2543Smrg    xf86VIDrvMsgVerb(dev, type, 1, format, ap);
1221706f2543Smrg    va_end(ap);
1222706f2543Smrg}
1223706f2543Smrg
1224706f2543Smrg
1225706f2543Smrg/* Print non-driver messages with verbose level specified directly */
1226706f2543Smrgvoid
1227706f2543Smrgxf86MsgVerb(MessageType type, int verb, const char *format, ...)
1228706f2543Smrg{
1229706f2543Smrg    va_list ap;
1230706f2543Smrg
1231706f2543Smrg    va_start(ap, format);
1232706f2543Smrg    LogVMessageVerb(type, verb, format, ap);
1233706f2543Smrg    va_end(ap);
1234706f2543Smrg}
1235706f2543Smrg
1236706f2543Smrg/* Print non-driver messages with verbose level of 1 (default) */
1237706f2543Smrgvoid
1238706f2543Smrgxf86Msg(MessageType type, const char *format, ...)
1239706f2543Smrg{
1240706f2543Smrg    va_list ap;
1241706f2543Smrg
1242706f2543Smrg    va_start(ap, format);
1243706f2543Smrg    LogVMessageVerb(type, 1, format, ap);
1244706f2543Smrg    va_end(ap);
1245706f2543Smrg}
1246706f2543Smrg
1247706f2543Smrg/* Just like ErrorF, but with the verbose level checked */
1248706f2543Smrgvoid
1249706f2543Smrgxf86ErrorFVerb(int verb, const char *format, ...)
1250706f2543Smrg{
1251706f2543Smrg    va_list ap;
1252706f2543Smrg
1253706f2543Smrg    va_start(ap, format);
1254706f2543Smrg    if (xf86Verbose >= verb || xf86LogVerbose >= verb)
1255706f2543Smrg	LogVWrite(verb, format, ap);
1256706f2543Smrg    va_end(ap);
1257706f2543Smrg}
1258706f2543Smrg
1259706f2543Smrg/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
1260706f2543Smrgvoid
1261706f2543Smrgxf86ErrorF(const char *format, ...)
1262706f2543Smrg{
1263706f2543Smrg    va_list ap;
1264706f2543Smrg
1265706f2543Smrg    va_start(ap, format);
1266706f2543Smrg    if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
1267706f2543Smrg	LogVWrite(1, format, ap);
1268706f2543Smrg    va_end(ap);
1269706f2543Smrg}
1270706f2543Smrg
1271706f2543Smrg
1272706f2543Smrgvoid
1273706f2543Smrgxf86LogInit(void)
1274706f2543Smrg{
1275706f2543Smrg    char *lf = NULL;
1276706f2543Smrg
1277706f2543Smrg#define LOGSUFFIX ".log"
1278706f2543Smrg#define LOGOLDSUFFIX ".old"
1279706f2543Smrg
1280706f2543Smrg    /* Get the log file name */
1281706f2543Smrg    if (xf86LogFileFrom == X_DEFAULT) {
1282706f2543Smrg	/* Append the display number and ".log" */
1283706f2543Smrg	if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1)
1284706f2543Smrg	    FatalError("Cannot allocate space for the log file name\n");
1285706f2543Smrg	xf86LogFile = lf;
1286706f2543Smrg    }
1287706f2543Smrg
1288706f2543Smrg    xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
1289706f2543Smrg    xf86LogFileWasOpened = TRUE;
1290706f2543Smrg
1291706f2543Smrg    xf86SetVerbosity(xf86Verbose);
1292706f2543Smrg    xf86SetLogVerbosity(xf86LogVerbose);
1293706f2543Smrg
1294706f2543Smrg#undef LOGSUFFIX
1295706f2543Smrg#undef LOGOLDSUFFIX
1296706f2543Smrg
1297706f2543Smrg    free(lf);
1298706f2543Smrg}
1299706f2543Smrg
1300706f2543Smrgvoid
1301706f2543Smrgxf86CloseLog(void)
1302706f2543Smrg{
1303706f2543Smrg    LogClose();
1304706f2543Smrg}
1305706f2543Smrg
1306706f2543Smrg
1307706f2543Smrg/*
1308706f2543Smrg * Drivers can use these for using their own SymTabRecs.
1309706f2543Smrg */
1310706f2543Smrg
1311706f2543Smrgconst char *
1312706f2543Smrgxf86TokenToString(SymTabPtr table, int token)
1313706f2543Smrg{
1314706f2543Smrg    int i;
1315706f2543Smrg
1316706f2543Smrg    for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
1317706f2543Smrg	;
1318706f2543Smrg
1319706f2543Smrg    if (table[i].token < 0)
1320706f2543Smrg	return NULL;
1321706f2543Smrg    else
1322706f2543Smrg	return table[i].name;
1323706f2543Smrg}
1324706f2543Smrg
1325706f2543Smrgint
1326706f2543Smrgxf86StringToToken(SymTabPtr table, const char *string)
1327706f2543Smrg{
1328706f2543Smrg    int i;
1329706f2543Smrg
1330706f2543Smrg    if (string == NULL)
1331706f2543Smrg	return -1;
1332706f2543Smrg
1333706f2543Smrg    for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
1334706f2543Smrg	;
1335706f2543Smrg
1336706f2543Smrg    return table[i].token;
1337706f2543Smrg}
1338706f2543Smrg
1339706f2543Smrg/*
1340706f2543Smrg * helper to display the clocks found on a card
1341706f2543Smrg */
1342706f2543Smrgvoid
1343706f2543Smrgxf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
1344706f2543Smrg{
1345706f2543Smrg    int j;
1346706f2543Smrg
1347706f2543Smrg    xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
1348706f2543Smrg    for (j=0; j < scrp->numClocks; j++) {
1349706f2543Smrg	if ((j % 4) == 0) {
1350706f2543Smrg	    xf86ErrorF("\n");
1351706f2543Smrg	    xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
1352706f2543Smrg	}
1353706f2543Smrg	xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
1354706f2543Smrg    }
1355706f2543Smrg    xf86ErrorF("\n");
1356706f2543Smrg}
1357706f2543Smrg
1358706f2543Smrg
1359706f2543Smrg/*
1360706f2543Smrg * This prints out the driver identify message, including the names of
1361706f2543Smrg * the supported chipsets.
1362706f2543Smrg *
1363706f2543Smrg * XXX This makes assumptions about the line width, etc.  Maybe we could
1364706f2543Smrg * use a more general "pretty print" function for messages.
1365706f2543Smrg */
1366706f2543Smrgvoid
1367706f2543Smrgxf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
1368706f2543Smrg{
1369706f2543Smrg    int len, i;
1370706f2543Smrg
1371706f2543Smrg    len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
1372706f2543Smrg    xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
1373706f2543Smrg    for (i = 0; chips[i].name != NULL; i++) {
1374706f2543Smrg	if (i != 0) {
1375706f2543Smrg	    xf86ErrorF(",");
1376706f2543Smrg	    len++;
1377706f2543Smrg	}
1378706f2543Smrg	if (len + 2 + strlen(chips[i].name) < 78) {
1379706f2543Smrg	    xf86ErrorF(" ");
1380706f2543Smrg	    len++;
1381706f2543Smrg	} else {
1382706f2543Smrg	    xf86ErrorF("\n\t");
1383706f2543Smrg	    len = 8;
1384706f2543Smrg	}
1385706f2543Smrg	xf86ErrorF("%s", chips[i].name);
1386706f2543Smrg	len += strlen(chips[i].name);
1387706f2543Smrg    }
1388706f2543Smrg    xf86ErrorF("\n");
1389706f2543Smrg}
1390706f2543Smrg
1391706f2543Smrg
1392706f2543Smrgint
1393706f2543Smrgxf86MatchDevice(const char *drivername, GDevPtr **sectlist)
1394706f2543Smrg{
1395706f2543Smrg    GDevPtr       gdp, *pgdp = NULL;
1396706f2543Smrg    confScreenPtr screensecptr;
1397706f2543Smrg    int i,j;
1398706f2543Smrg
1399706f2543Smrg    if (sectlist)
1400706f2543Smrg	*sectlist = NULL;
1401706f2543Smrg
1402706f2543Smrg    /*
1403706f2543Smrg     * 20111009 jmcneill: This line was removed with the following commit upstream:
1404706f2543Smrg     *  http://cgit.freedesktop.org/xorg/xserver/commit/hw/xfree86/common/xf86Helper.c?id=0ceac6f64f5ad9bc2ac4b19be2dd245ffba78b05
1405706f2543Smrg     *
1406706f2543Smrg     * However, the log message is inaccurate: xf86MatchDevice will get called at
1407706f2543Smrg     * configuration time by drivers who still implement the legacy probing
1408706f2543Smrg     * API.
1409706f2543Smrg     */
1410706f2543Smrg    if (xf86DoConfigure && xf86DoConfigurePass1) return 1;
1411706f2543Smrg
1412706f2543Smrg    /*
1413706f2543Smrg     * This can happen when running Xorg -showopts and a module like ati
1414706f2543Smrg     * or vmware tries to load its submodules when xf86ConfigLayout is empty
1415706f2543Smrg     */
1416706f2543Smrg    if (!xf86ConfigLayout.screens)
1417706f2543Smrg	return 0;
1418706f2543Smrg
1419706f2543Smrg    /*
1420706f2543Smrg     * This is a very important function that matches the device sections
1421706f2543Smrg     * as they show up in the config file with the drivers that the server
1422706f2543Smrg     * loads at run time.
1423706f2543Smrg     *
1424706f2543Smrg     * ChipProbe can call
1425706f2543Smrg     * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
1426706f2543Smrg     * with its driver name. The function allocates an array of GDevPtr and
1427706f2543Smrg     * returns this via sectlist and returns the number of elements in
1428706f2543Smrg     * this list as return value. 0 means none found, -1 means fatal error.
1429706f2543Smrg     *
1430706f2543Smrg     * It can figure out which of the Device sections to use for which card
1431706f2543Smrg     * (using things like the Card statement, etc). For single headed servers
1432706f2543Smrg     * there will of course be just one such Device section.
1433706f2543Smrg     */
1434706f2543Smrg    i = 0;
1435706f2543Smrg
1436706f2543Smrg    /*
1437706f2543Smrg     * first we need to loop over all the Screens sections to get to all
1438706f2543Smrg     * 'active' device sections
1439706f2543Smrg     */
1440706f2543Smrg    for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
1441706f2543Smrg        screensecptr = xf86ConfigLayout.screens[j].screen;
1442706f2543Smrg        if ((screensecptr->device->driver != NULL)
1443706f2543Smrg            && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
1444706f2543Smrg            && (! screensecptr->device->claimed)) {
1445706f2543Smrg            /*
1446706f2543Smrg             * we have a matching driver that wasn't claimed, yet
1447706f2543Smrg             */
1448706f2543Smrg            pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
1449706f2543Smrg            pgdp[i++] = screensecptr->device;
1450706f2543Smrg        }
1451706f2543Smrg    }
1452706f2543Smrg
1453706f2543Smrg    /* Then handle the inactive devices */
1454706f2543Smrg    j = 0;
1455706f2543Smrg    while (xf86ConfigLayout.inactives[j].identifier) {
1456706f2543Smrg	gdp = &xf86ConfigLayout.inactives[j];
1457706f2543Smrg	if (gdp->driver && !gdp->claimed &&
1458706f2543Smrg	    !xf86NameCmp(gdp->driver,drivername)) {
1459706f2543Smrg	    /* we have a matching driver that wasn't claimed yet */
1460706f2543Smrg	    pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
1461706f2543Smrg	    pgdp[i++] = gdp;
1462706f2543Smrg	}
1463706f2543Smrg	j++;
1464706f2543Smrg    }
1465706f2543Smrg
1466706f2543Smrg    /*
1467706f2543Smrg     * make the array NULL terminated and return its address
1468706f2543Smrg     */
1469706f2543Smrg    if (i)
1470706f2543Smrg        pgdp[i] = NULL;
1471706f2543Smrg
1472706f2543Smrg    if (sectlist)
1473706f2543Smrg	*sectlist = pgdp;
1474706f2543Smrg    else
1475706f2543Smrg	free(pgdp);
1476706f2543Smrg    return i;
1477706f2543Smrg}
1478706f2543Smrg
1479706f2543Smrg/*
1480706f2543Smrg * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
1481706f2543Smrg */
1482706f2543Smrgvoid
1483706f2543Smrgxf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
1484706f2543Smrg	      void (*ProtectRegs)(ScrnInfoPtr, Bool),
1485706f2543Smrg	      void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
1486706f2543Smrg	      int maskval, int knownclkindex, int knownclkvalue)
1487706f2543Smrg{
1488706f2543Smrg    register int status = vertsyncreg;
1489706f2543Smrg    unsigned long i, cnt, rcnt, sync;
1490706f2543Smrg
1491706f2543Smrg    /* First save registers that get written on */
1492706f2543Smrg    (*ClockFunc)(pScrn, CLK_REG_SAVE);
1493706f2543Smrg
1494706f2543Smrg    if (num > MAXCLOCKS)
1495706f2543Smrg	num = MAXCLOCKS;
1496706f2543Smrg
1497706f2543Smrg    for (i = 0; i < num; i++)
1498706f2543Smrg    {
1499706f2543Smrg	if (ProtectRegs)
1500706f2543Smrg	    (*ProtectRegs)(pScrn, TRUE);
1501706f2543Smrg	if (!(*ClockFunc)(pScrn, i))
1502706f2543Smrg	{
1503706f2543Smrg	    pScrn->clock[i] = -1;
1504706f2543Smrg	    continue;
1505706f2543Smrg	}
1506706f2543Smrg	if (ProtectRegs)
1507706f2543Smrg	    (*ProtectRegs)(pScrn, FALSE);
1508706f2543Smrg	if (BlankScreen)
1509706f2543Smrg	    (*BlankScreen)(pScrn, FALSE);
1510706f2543Smrg
1511706f2543Smrg    	usleep(50000);     /* let VCO stabilise */
1512706f2543Smrg
1513706f2543Smrg    	cnt  = 0;
1514706f2543Smrg    	sync = 200000;
1515706f2543Smrg
1516706f2543Smrg	while ((inb(status) & maskval) == 0x00)
1517706f2543Smrg	    if (sync-- == 0) goto finish;
1518706f2543Smrg	/* Something appears to be happening, so reset sync count */
1519706f2543Smrg	sync = 200000;
1520706f2543Smrg	while ((inb(status) & maskval) == maskval)
1521706f2543Smrg	    if (sync-- == 0) goto finish;
1522706f2543Smrg	/* Something appears to be happening, so reset sync count */
1523706f2543Smrg	sync = 200000;
1524706f2543Smrg	while ((inb(status) & maskval) == 0x00)
1525706f2543Smrg	    if (sync-- == 0) goto finish;
1526706f2543Smrg
1527706f2543Smrg	for (rcnt = 0; rcnt < 5; rcnt++)
1528706f2543Smrg	{
1529706f2543Smrg	    while (!(inb(status) & maskval))
1530706f2543Smrg		cnt++;
1531706f2543Smrg	    while ((inb(status) & maskval))
1532706f2543Smrg		cnt++;
1533706f2543Smrg	}
1534706f2543Smrg
1535706f2543Smrgfinish:
1536706f2543Smrg	pScrn->clock[i] = cnt ? cnt : -1;
1537706f2543Smrg	if (BlankScreen)
1538706f2543Smrg            (*BlankScreen)(pScrn, TRUE);
1539706f2543Smrg    }
1540706f2543Smrg
1541706f2543Smrg    for (i = 0; i < num; i++)
1542706f2543Smrg    {
1543706f2543Smrg	if (i != knownclkindex)
1544706f2543Smrg	{
1545706f2543Smrg	    if (pScrn->clock[i] == -1)
1546706f2543Smrg	    {
1547706f2543Smrg		pScrn->clock[i] = 0;
1548706f2543Smrg	    }
1549706f2543Smrg	    else
1550706f2543Smrg	    {
1551706f2543Smrg		pScrn->clock[i] = (int)(0.5 +
1552706f2543Smrg                    (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
1553706f2543Smrg	            (pScrn->clock[i]));
1554706f2543Smrg		/* Round to nearest 10KHz */
1555706f2543Smrg		pScrn->clock[i] += 5;
1556706f2543Smrg		pScrn->clock[i] /= 10;
1557706f2543Smrg		pScrn->clock[i] *= 10;
1558706f2543Smrg	    }
1559706f2543Smrg	}
1560706f2543Smrg    }
1561706f2543Smrg
1562706f2543Smrg    pScrn->clock[knownclkindex] = knownclkvalue;
1563706f2543Smrg    pScrn->numClocks = num;
1564706f2543Smrg
1565706f2543Smrg    /* Restore registers that were written on */
1566706f2543Smrg    (*ClockFunc)(pScrn, CLK_REG_RESTORE);
1567706f2543Smrg}
1568706f2543Smrg
1569706f2543Smrgconst char *
1570706f2543Smrgxf86GetVisualName(int visual)
1571706f2543Smrg{
1572706f2543Smrg    if (visual < 0 || visual > DirectColor)
1573706f2543Smrg	return NULL;
1574706f2543Smrg
1575706f2543Smrg    return xf86VisualNames[visual];
1576706f2543Smrg}
1577706f2543Smrg
1578706f2543Smrg
1579706f2543Smrgint
1580706f2543Smrgxf86GetVerbosity(void)
1581706f2543Smrg{
1582706f2543Smrg    return max(xf86Verbose, xf86LogVerbose);
1583706f2543Smrg}
1584706f2543Smrg
1585706f2543SmrgPix24Flags
1586706f2543Smrgxf86GetPix24(void)
1587706f2543Smrg{
1588706f2543Smrg    return xf86Info.pixmap24;
1589706f2543Smrg}
1590706f2543Smrg
1591706f2543Smrg
1592706f2543Smrgint
1593706f2543Smrgxf86GetDepth(void)
1594706f2543Smrg{
1595706f2543Smrg    return xf86Depth;
1596706f2543Smrg}
1597706f2543Smrg
1598706f2543Smrg
1599706f2543Smrgrgb
1600706f2543Smrgxf86GetWeight(void)
1601706f2543Smrg{
1602706f2543Smrg    return xf86Weight;
1603706f2543Smrg}
1604706f2543Smrg
1605706f2543Smrg
1606706f2543SmrgGamma
1607706f2543Smrgxf86GetGamma(void)
1608706f2543Smrg{
1609706f2543Smrg    return xf86Gamma;
1610706f2543Smrg}
1611706f2543Smrg
1612706f2543Smrg
1613706f2543SmrgBool
1614706f2543Smrgxf86GetFlipPixels(void)
1615706f2543Smrg{
1616706f2543Smrg    return xf86FlipPixels;
1617706f2543Smrg}
1618706f2543Smrg
1619706f2543Smrg
1620706f2543Smrgconst char *
1621706f2543Smrgxf86GetServerName(void)
1622706f2543Smrg{
1623706f2543Smrg    return xf86ServerName;
1624706f2543Smrg}
1625706f2543Smrg
1626706f2543Smrg
1627706f2543SmrgBool
1628706f2543Smrgxf86ServerIsExiting(void)
1629706f2543Smrg{
1630706f2543Smrg    return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
1631706f2543Smrg}
1632706f2543Smrg
1633706f2543Smrg
1634706f2543SmrgBool
1635706f2543Smrgxf86ServerIsResetting(void)
1636706f2543Smrg{
1637706f2543Smrg    return xf86Resetting;
1638706f2543Smrg}
1639706f2543Smrg
1640706f2543Smrg
1641706f2543SmrgBool
1642706f2543Smrgxf86ServerIsInitialising(void)
1643706f2543Smrg{
1644706f2543Smrg    return xf86Initialising;
1645706f2543Smrg}
1646706f2543Smrg
1647706f2543Smrg
1648706f2543SmrgBool
1649706f2543Smrgxf86ServerIsOnlyDetecting(void)
1650706f2543Smrg{
1651706f2543Smrg    return xf86DoConfigure;
1652706f2543Smrg}
1653706f2543Smrg
1654706f2543Smrg
1655706f2543SmrgBool
1656706f2543Smrgxf86CaughtSignal(void)
1657706f2543Smrg{
1658706f2543Smrg    return xf86Info.caughtSignal;
1659706f2543Smrg}
1660706f2543Smrg
1661706f2543Smrg
1662706f2543SmrgBool
1663706f2543Smrgxf86GetVidModeAllowNonLocal(void)
1664706f2543Smrg{
1665706f2543Smrg    return xf86Info.vidModeAllowNonLocal;
1666706f2543Smrg}
1667706f2543Smrg
1668706f2543Smrg
1669706f2543SmrgBool
1670706f2543Smrgxf86GetVidModeEnabled(void)
1671706f2543Smrg{
1672706f2543Smrg    return xf86Info.vidModeEnabled;
1673706f2543Smrg}
1674706f2543Smrg
1675706f2543SmrgBool
1676706f2543Smrgxf86GetModInDevAllowNonLocal(void)
1677706f2543Smrg{
1678706f2543Smrg    return xf86Info.miscModInDevAllowNonLocal;
1679706f2543Smrg}
1680706f2543Smrg
1681706f2543Smrg
1682706f2543SmrgBool
1683706f2543Smrgxf86GetModInDevEnabled(void)
1684706f2543Smrg{
1685706f2543Smrg    return xf86Info.miscModInDevEnabled;
1686706f2543Smrg}
1687706f2543Smrg
1688706f2543Smrg
1689706f2543SmrgBool
1690706f2543Smrgxf86GetAllowMouseOpenFail(void)
1691706f2543Smrg{
1692706f2543Smrg    return xf86Info.allowMouseOpenFail;
1693706f2543Smrg}
1694706f2543Smrg
1695706f2543Smrg
1696706f2543SmrgBool
1697706f2543Smrgxf86IsPc98(void)
1698706f2543Smrg{
1699706f2543Smrg#if SUPPORT_PC98
1700706f2543Smrg    return xf86Info.pc98;
1701706f2543Smrg#else
1702706f2543Smrg    return FALSE;
1703706f2543Smrg#endif
1704706f2543Smrg}
1705706f2543Smrg
1706706f2543Smrgvoid
1707706f2543Smrgxf86DisableRandR(void)
1708706f2543Smrg{
1709706f2543Smrg    xf86Info.disableRandR = TRUE;
1710706f2543Smrg    xf86Info.randRFrom = X_PROBED;
1711706f2543Smrg}
1712706f2543Smrg
1713706f2543SmrgCARD32
1714706f2543Smrgxf86GetModuleVersion(pointer module)
1715706f2543Smrg{
1716706f2543Smrg    return (CARD32)LoaderGetModuleVersion(module);
1717706f2543Smrg}
1718706f2543Smrg
1719706f2543Smrgpointer
1720706f2543Smrgxf86LoadDrvSubModule(DriverPtr drv, const char *name)
1721706f2543Smrg{
1722706f2543Smrg    pointer ret;
1723706f2543Smrg    int errmaj = 0, errmin = 0;
1724706f2543Smrg
1725706f2543Smrg    ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
1726706f2543Smrg			&errmaj, &errmin);
1727706f2543Smrg    if (!ret)
1728706f2543Smrg	LoaderErrorMsg(NULL, name, errmaj, errmin);
1729706f2543Smrg    return ret;
1730706f2543Smrg}
1731706f2543Smrg
1732706f2543Smrgpointer
1733706f2543Smrgxf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
1734706f2543Smrg{
1735706f2543Smrg    pointer ret;
1736706f2543Smrg    int errmaj = 0, errmin = 0;
1737706f2543Smrg
1738706f2543Smrg    ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
1739706f2543Smrg			&errmaj, &errmin);
1740706f2543Smrg    if (!ret)
1741706f2543Smrg	LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
1742706f2543Smrg    return ret;
1743706f2543Smrg}
1744706f2543Smrg
1745706f2543Smrg/*
1746706f2543Smrg * xf86LoadOneModule loads a single module.
1747706f2543Smrg */
1748706f2543Smrgpointer
1749706f2543Smrgxf86LoadOneModule(char *name, pointer opt)
1750706f2543Smrg{
1751706f2543Smrg    int errmaj, errmin;
1752706f2543Smrg    char *Name;
1753706f2543Smrg    pointer mod;
1754706f2543Smrg
1755706f2543Smrg    if (!name)
1756706f2543Smrg	return NULL;
1757706f2543Smrg
1758706f2543Smrg    /* Normalise the module name */
1759706f2543Smrg    Name = xf86NormalizeName(name);
1760706f2543Smrg
1761706f2543Smrg    /* Skip empty names */
1762706f2543Smrg    if (Name == NULL)
1763706f2543Smrg	return NULL;
1764706f2543Smrg    if (*Name == '\0') {
1765706f2543Smrg	free(Name);
1766706f2543Smrg	return NULL;
1767706f2543Smrg    }
1768706f2543Smrg
1769706f2543Smrg    mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
1770706f2543Smrg    if (!mod)
1771706f2543Smrg	LoaderErrorMsg(NULL, Name, errmaj, errmin);
1772706f2543Smrg    free(Name);
1773706f2543Smrg    return mod;
1774706f2543Smrg}
1775706f2543Smrg
1776706f2543Smrgvoid
1777706f2543Smrgxf86UnloadSubModule(pointer mod)
1778706f2543Smrg{
1779706f2543Smrg    /*
1780706f2543Smrg     * This is disabled for now.  The loader isn't smart enough yet to undo
1781706f2543Smrg     * relocations.
1782706f2543Smrg     */
1783706f2543Smrg#if 0
1784706f2543Smrg    UnloadSubModule(mod);
1785706f2543Smrg#endif
1786706f2543Smrg}
1787706f2543Smrg
1788706f2543SmrgBool
1789706f2543Smrgxf86LoaderCheckSymbol(const char *name)
1790706f2543Smrg{
1791706f2543Smrg    return LoaderSymbol(name) != NULL;
1792706f2543Smrg}
1793706f2543Smrg
1794706f2543Smrgtypedef enum {
1795706f2543Smrg   OPTION_BACKING_STORE
1796706f2543Smrg} BSOpts;
1797706f2543Smrg
1798706f2543Smrgstatic const OptionInfoRec BSOptions[] = {
1799706f2543Smrg   { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
1800706f2543Smrg   { -1,                   NULL,           OPTV_NONE,    {0}, FALSE }
1801706f2543Smrg};
1802706f2543Smrg
1803706f2543Smrgvoid
1804706f2543Smrgxf86SetBackingStore(ScreenPtr pScreen)
1805706f2543Smrg{
1806706f2543Smrg    Bool useBS = FALSE;
1807706f2543Smrg    MessageType from = X_DEFAULT;
1808706f2543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1809706f2543Smrg    OptionInfoPtr options;
1810706f2543Smrg
1811706f2543Smrg    options = xnfalloc(sizeof(BSOptions));
1812706f2543Smrg    (void)memcpy(options, BSOptions, sizeof(BSOptions));
1813706f2543Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
1814706f2543Smrg
1815706f2543Smrg    /* check for commandline option here */
1816706f2543Smrg    if (xf86bsEnableFlag) {
1817706f2543Smrg	from = X_CMDLINE;
1818706f2543Smrg	useBS = TRUE;
1819706f2543Smrg    } else if (xf86bsDisableFlag) {
1820706f2543Smrg	from = X_CMDLINE;
1821706f2543Smrg	useBS = FALSE;
1822706f2543Smrg    } else {
1823706f2543Smrg	if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
1824706f2543Smrg	    from = X_CONFIG;
1825706f2543Smrg    }
1826706f2543Smrg    free(options);
1827706f2543Smrg    pScreen->backingStoreSupport = useBS ? Always : NotUseful;
1828706f2543Smrg    if (serverGeneration == 1)
1829706f2543Smrg	xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
1830706f2543Smrg		   useBS ? "enabled" : "disabled");
1831706f2543Smrg}
1832706f2543Smrg
1833706f2543Smrg
1834706f2543Smrgtypedef enum {
1835706f2543Smrg   OPTION_SILKEN_MOUSE
1836706f2543Smrg} SMOpts;
1837706f2543Smrg
1838706f2543Smrgstatic const OptionInfoRec SMOptions[] = {
1839706f2543Smrg   { OPTION_SILKEN_MOUSE, "SilkenMouse",   OPTV_BOOLEAN, {0}, FALSE },
1840706f2543Smrg   { -1,                   NULL,           OPTV_NONE,    {0}, FALSE }
1841706f2543Smrg};
1842706f2543Smrg
1843706f2543Smrgvoid
1844706f2543Smrgxf86SetSilkenMouse (ScreenPtr pScreen)
1845706f2543Smrg{
1846706f2543Smrg    Bool useSM = TRUE;
1847706f2543Smrg    MessageType from = X_DEFAULT;
1848706f2543Smrg    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1849706f2543Smrg    OptionInfoPtr options;
1850706f2543Smrg
1851706f2543Smrg    options = xnfalloc(sizeof(SMOptions));
1852706f2543Smrg    (void)memcpy(options, SMOptions, sizeof(SMOptions));
1853706f2543Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
1854706f2543Smrg
1855706f2543Smrg    /* check for commandline option here */
1856706f2543Smrg    /* disable if screen shares resources */
1857706f2543Smrg	/* TODO VGA arb disable silken mouse */
1858706f2543Smrg    if (xf86silkenMouseDisableFlag) {
1859706f2543Smrg        from = X_CMDLINE;
1860706f2543Smrg	useSM = FALSE;
1861706f2543Smrg    } else {
1862706f2543Smrg	if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
1863706f2543Smrg	    from = X_CONFIG;
1864706f2543Smrg    }
1865706f2543Smrg    free(options);
1866706f2543Smrg    /*
1867706f2543Smrg     * XXX quick hack to report correctly for OSs that can't do SilkenMouse
1868706f2543Smrg     * yet.  Should handle this differently so that alternate async methods
1869706f2543Smrg     * work correctly with this too.
1870706f2543Smrg     */
1871706f2543Smrg    pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
1872706f2543Smrg    if (serverGeneration == 1)
1873706f2543Smrg	xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
1874706f2543Smrg		   pScrn->silkenMouse ? "enabled" : "disabled");
1875706f2543Smrg}
1876706f2543Smrg
1877706f2543Smrg/* Wrote this function for the PM2 Xv driver, preliminary. */
1878706f2543Smrg
1879706f2543Smrgpointer
1880706f2543Smrgxf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
1881706f2543Smrg		  char **adaptor_name, pointer *adaptor_options)
1882706f2543Smrg{
1883706f2543Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1884706f2543Smrg    confXvAdaptorPtr adaptor;
1885706f2543Smrg    int i;
1886706f2543Smrg
1887706f2543Smrg    if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
1888706f2543Smrg	if (adaptor_name) *adaptor_name = NULL;
1889706f2543Smrg	if (adaptor_options) *adaptor_options = NULL;
1890706f2543Smrg	return NULL;
1891706f2543Smrg    }
1892706f2543Smrg
1893706f2543Smrg    adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
1894706f2543Smrg    if (adaptor_name) *adaptor_name = adaptor->identifier;
1895706f2543Smrg    if (adaptor_options) *adaptor_options = adaptor->options;
1896706f2543Smrg
1897706f2543Smrg    for (i = 0; i < adaptor->numports; i++)
1898706f2543Smrg	if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
1899706f2543Smrg	    return adaptor->ports[i].options;
1900706f2543Smrg
1901706f2543Smrg    return NULL;
1902706f2543Smrg}
1903706f2543Smrg
1904706f2543Smrg/* Rather than duplicate loader's get OS function, just include it directly */
1905706f2543Smrg#define LoaderGetOS xf86GetOS
1906706f2543Smrg#include "loader/os.c"
1907706f2543Smrg
1908706f2543Smrgstatic void
1909706f2543Smrgxf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
1910706f2543Smrg			   EntityProc enter, EntityProc leave, pointer private)
1911706f2543Smrg{
1912706f2543Smrg    ScrnInfoPtr pScrn;
1913706f2543Smrg
1914706f2543Smrg    if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
1915706f2543Smrg	xf86RemoveEntityFromScreen(pScrn,pEnt->index);
1916706f2543Smrg    xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
1917706f2543Smrg}
1918706f2543Smrg
1919706f2543SmrgScrnInfoPtr
1920706f2543Smrgxf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
1921706f2543Smrg		   EntityProc init, EntityProc enter, EntityProc leave,
1922706f2543Smrg		   pointer private)
1923706f2543Smrg{
1924706f2543Smrg    EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
1925706f2543Smrg    if (!pEnt) return pScrn;
1926706f2543Smrg
1927706f2543Smrg    if (!(pEnt->location.type == BUS_NONE)) {
1928706f2543Smrg	free(pEnt);
1929706f2543Smrg	return pScrn;
1930706f2543Smrg    }
1931706f2543Smrg
1932706f2543Smrg    if (!pEnt->active) {
1933706f2543Smrg	xf86ConfigFbEntityInactive(pEnt, init,  enter, leave,  private);
1934706f2543Smrg	free(pEnt);
1935706f2543Smrg	return pScrn;
1936706f2543Smrg    }
1937706f2543Smrg
1938706f2543Smrg    if (!pScrn)
1939706f2543Smrg	pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
1940706f2543Smrg    xf86AddEntityToScreen(pScrn,entityIndex);
1941706f2543Smrg
1942706f2543Smrg    xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
1943706f2543Smrg
1944706f2543Smrg    free(pEnt);
1945706f2543Smrg    return pScrn;
1946706f2543Smrg}
1947706f2543Smrg
1948706f2543SmrgBool
1949706f2543Smrgxf86IsScreenPrimary(int scrnIndex)
1950706f2543Smrg{
1951706f2543Smrg    ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1952706f2543Smrg    int i;
1953706f2543Smrg
1954706f2543Smrg    for (i=0 ; i < pScrn->numEntities; i++) {
1955706f2543Smrg	if (xf86IsEntityPrimary(i))
1956706f2543Smrg	    return TRUE;
1957706f2543Smrg    }
1958706f2543Smrg    return FALSE;
1959706f2543Smrg}
1960706f2543Smrg
1961706f2543Smrgint
1962706f2543Smrgxf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
1963706f2543Smrg			       int format, unsigned long len, pointer value )
1964706f2543Smrg{
1965706f2543Smrg    RootWinPropPtr pNewProp = NULL, pRegProp;
1966706f2543Smrg    int i;
1967706f2543Smrg    Bool existing = FALSE;
1968706f2543Smrg
1969706f2543Smrg    DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
1970706f2543Smrg	   ScrnIndex, property, type, format, len, value);
1971706f2543Smrg
1972706f2543Smrg    if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
1973706f2543Smrg      return BadMatch;
1974706f2543Smrg    }
1975706f2543Smrg
1976706f2543Smrg    if (xf86RegisteredPropertiesTable &&
1977706f2543Smrg	xf86RegisteredPropertiesTable[ScrnIndex]) {
1978706f2543Smrg      for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
1979706f2543Smrg	   pNewProp; pNewProp = pNewProp->next) {
1980706f2543Smrg	if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
1981706f2543Smrg	  break;
1982706f2543Smrg      }
1983706f2543Smrg    }
1984706f2543Smrg
1985706f2543Smrg    if (!pNewProp) {
1986706f2543Smrg      if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) {
1987706f2543Smrg	return BadAlloc;
1988706f2543Smrg      }
1989706f2543Smrg      /*
1990706f2543Smrg       * We will put this property at the end of the list so that
1991706f2543Smrg       * the changes are made in the order they were requested.
1992706f2543Smrg       */
1993706f2543Smrg      pNewProp->next = NULL;
1994706f2543Smrg    } else {
1995706f2543Smrg      free(pNewProp->name);
1996706f2543Smrg      existing = TRUE;
1997706f2543Smrg    }
1998706f2543Smrg
1999706f2543Smrg    pNewProp->name = xnfstrdup(NameForAtom(property));
2000706f2543Smrg    pNewProp->type = type;
2001706f2543Smrg    pNewProp->format = format;
2002706f2543Smrg    pNewProp->size = len;
2003706f2543Smrg    pNewProp->data = value;
2004706f2543Smrg
2005706f2543Smrg    DebugF("new property filled\n");
2006706f2543Smrg
2007706f2543Smrg    if (NULL==xf86RegisteredPropertiesTable) {
2008706f2543Smrg      DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
2009706f2543Smrg	     xf86NumScreens);
2010706f2543Smrg      if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
2011706f2543Smrg	return BadAlloc;
2012706f2543Smrg      }
2013706f2543Smrg      for (i=0; i<xf86NumScreens; i++) {
2014706f2543Smrg	xf86RegisteredPropertiesTable[i] = NULL;
2015706f2543Smrg      }
2016706f2543Smrg    }
2017706f2543Smrg
2018706f2543Smrg    DebugF("xf86RegisteredPropertiesTable %p\n",
2019706f2543Smrg	   (void *)xf86RegisteredPropertiesTable);
2020706f2543Smrg    DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
2021706f2543Smrg	   ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
2022706f2543Smrg
2023706f2543Smrg    if (!existing) {
2024706f2543Smrg      if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
2025706f2543Smrg	xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
2026706f2543Smrg      } else {
2027706f2543Smrg	pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
2028706f2543Smrg	while (pRegProp->next != NULL) {
2029706f2543Smrg	  DebugF("- next %p\n", (void *)pRegProp);
2030706f2543Smrg	  pRegProp = pRegProp->next;
2031706f2543Smrg        }
2032706f2543Smrg	pRegProp->next = pNewProp;
2033706f2543Smrg      }
2034706f2543Smrg    }
2035706f2543Smrg    DebugF("xf86RegisterRootWindowProperty succeeded\n");
2036706f2543Smrg    return Success;
2037706f2543Smrg}
2038706f2543Smrg
2039706f2543SmrgBool
2040706f2543Smrgxf86IsUnblank(int mode)
2041706f2543Smrg{
2042706f2543Smrg    switch(mode) {
2043706f2543Smrg    case SCREEN_SAVER_OFF:
2044706f2543Smrg    case SCREEN_SAVER_FORCER:
2045706f2543Smrg	return TRUE;
2046706f2543Smrg    case SCREEN_SAVER_ON:
2047706f2543Smrg    case SCREEN_SAVER_CYCLE:
2048706f2543Smrg	return FALSE;
2049706f2543Smrg    default:
2050706f2543Smrg	xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
2051706f2543Smrg	return TRUE;
2052706f2543Smrg    }
2053706f2543Smrg}
2054706f2543Smrg
2055706f2543Smrgvoid
2056706f2543Smrgxf86MotionHistoryAllocate(InputInfoPtr pInfo)
2057706f2543Smrg{
2058706f2543Smrg    AllocateMotionHistory(pInfo->dev);
2059706f2543Smrg}
2060