105b261ecSmrg/*
205b261ecSmrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
305b261ecSmrg *
405b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
505b261ecSmrg * copy of this software and associated documentation files (the "Software"),
605b261ecSmrg * to deal in the Software without restriction, including without limitation
705b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
805b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
905b261ecSmrg * Software is furnished to do so, subject to the following conditions:
1005b261ecSmrg *
1105b261ecSmrg * The above copyright notice and this permission notice shall be included in
1205b261ecSmrg * all copies or substantial portions of the Software.
1305b261ecSmrg *
1405b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1705b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1805b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1905b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2005b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE.
2105b261ecSmrg *
2205b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s)
2305b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote
2405b261ecSmrg * the sale, use or other dealings in this Software without prior written
2505b261ecSmrg * authorization from the copyright holder(s) and author(s).
2605b261ecSmrg */
2705b261ecSmrg
2805b261ecSmrg/*
2905b261ecSmrg * Authors: Dirk Hohndel <hohndel@XFree86.Org>
3005b261ecSmrg *          David Dawes <dawes@XFree86.Org>
3105b261ecSmrg *          ... and others
3205b261ecSmrg *
3305b261ecSmrg * This file includes the helper functions that the server provides for
3405b261ecSmrg * different drivers.
3505b261ecSmrg */
3605b261ecSmrg
3705b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
3805b261ecSmrg#include <xorg-config.h>
3905b261ecSmrg#endif
4005b261ecSmrg
4105b261ecSmrg#include <X11/X.h>
425a112b11Smrg#include "mi.h"
4305b261ecSmrg#include "os.h"
4405b261ecSmrg#include "servermd.h"
4505b261ecSmrg#include "pixmapstr.h"
4605b261ecSmrg#include "windowstr.h"
4705b261ecSmrg#include "propertyst.h"
4805b261ecSmrg#include "gcstruct.h"
4905b261ecSmrg#include "loaderProcs.h"
5005b261ecSmrg#include "xf86.h"
5105b261ecSmrg#include "xf86Priv.h"
5205b261ecSmrg#include "xf86_OSlib.h"
5305b261ecSmrg#include "micmap.h"
5405b261ecSmrg#include "xf86DDC.h"
5505b261ecSmrg#include "xf86Xinput.h"
5605b261ecSmrg#include "xf86InPriv.h"
5705b261ecSmrg#include "mivalidate.h"
5805b261ecSmrg
5905b261ecSmrg/* For xf86GetClocks */
6005b261ecSmrg#if defined(CSRG_BASED) || defined(__GNU__)
6105b261ecSmrg#define HAS_SETPRIORITY
6205b261ecSmrg#include <sys/resource.h>
6305b261ecSmrg#endif
6405b261ecSmrg
6505b261ecSmrgstatic int xf86ScrnInfoPrivateCount = 0;
6605b261ecSmrg
6705b261ecSmrg/* Add a pointer to a new DriverRec to xf86DriverList */
6805b261ecSmrg
696747b715Smrgvoid
70f7df2e56Smrgxf86AddDriver(DriverPtr driver, void *module, int flags)
7105b261ecSmrg{
7205b261ecSmrg    /* Don't add null entries */
7305b261ecSmrg    if (!driver)
74f7df2e56Smrg        return;
7505b261ecSmrg
7605b261ecSmrg    if (xf86DriverList == NULL)
77f7df2e56Smrg        xf86NumDrivers = 0;
7805b261ecSmrg
7905b261ecSmrg    xf86NumDrivers++;
80f7df2e56Smrg    xf86DriverList = xnfreallocarray(xf86DriverList,
81f7df2e56Smrg                                     xf86NumDrivers, sizeof(DriverPtr));
8205b261ecSmrg    xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
837e31ba66Smrg    *xf86DriverList[xf86NumDrivers - 1] = *driver;
8405b261ecSmrg    xf86DriverList[xf86NumDrivers - 1]->module = module;
8505b261ecSmrg    xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
8605b261ecSmrg}
8705b261ecSmrg
886747b715Smrgvoid
8905b261ecSmrgxf86DeleteDriver(int drvIndex)
9005b261ecSmrg{
9105b261ecSmrg    if (xf86DriverList[drvIndex]
92f7df2e56Smrg        && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
93f7df2e56Smrg        if (xf86DriverList[drvIndex]->module)
94f7df2e56Smrg            UnloadModule(xf86DriverList[drvIndex]->module);
95f7df2e56Smrg        free(xf86DriverList[drvIndex]);
96f7df2e56Smrg        xf86DriverList[drvIndex] = NULL;
9705b261ecSmrg    }
9805b261ecSmrg}
9905b261ecSmrg
10005b261ecSmrg/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
10105b261ecSmrg
1026747b715Smrgvoid
103f7df2e56Smrgxf86AddInputDriver(InputDriverPtr driver, void *module, int flags)
10405b261ecSmrg{
10505b261ecSmrg    /* Don't add null entries */
10605b261ecSmrg    if (!driver)
107f7df2e56Smrg        return;
10805b261ecSmrg
10905b261ecSmrg    if (xf86InputDriverList == NULL)
110f7df2e56Smrg        xf86NumInputDrivers = 0;
11105b261ecSmrg
11205b261ecSmrg    xf86NumInputDrivers++;
113f7df2e56Smrg    xf86InputDriverList = xnfreallocarray(xf86InputDriverList,
114f7df2e56Smrg                                          xf86NumInputDrivers,
115f7df2e56Smrg                                          sizeof(InputDriverPtr));
11605b261ecSmrg    xf86InputDriverList[xf86NumInputDrivers - 1] =
117f7df2e56Smrg        xnfalloc(sizeof(InputDriverRec));
11805b261ecSmrg    *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
11905b261ecSmrg    xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
12005b261ecSmrg}
12105b261ecSmrg
12205b261ecSmrgvoid
12305b261ecSmrgxf86DeleteInputDriver(int drvIndex)
12405b261ecSmrg{
12505b261ecSmrg    if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
126f7df2e56Smrg        UnloadModule(xf86InputDriverList[drvIndex]->module);
1276747b715Smrg    free(xf86InputDriverList[drvIndex]);
12805b261ecSmrg    xf86InputDriverList[drvIndex] = NULL;
12905b261ecSmrg}
13005b261ecSmrg
13105b261ecSmrgInputDriverPtr
13205b261ecSmrgxf86LookupInputDriver(const char *name)
13305b261ecSmrg{
13405b261ecSmrg    int i;
13505b261ecSmrg
13605b261ecSmrg    for (i = 0; i < xf86NumInputDrivers; i++) {
137f7df2e56Smrg        if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
138f7df2e56Smrg            xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
139f7df2e56Smrg            return xf86InputDriverList[i];
14005b261ecSmrg    }
14105b261ecSmrg    return NULL;
14205b261ecSmrg}
14305b261ecSmrg
14405b261ecSmrgInputInfoPtr
14505b261ecSmrgxf86LookupInput(const char *name)
14605b261ecSmrg{
14705b261ecSmrg    InputInfoPtr p;
14805b261ecSmrg
14905b261ecSmrg    for (p = xf86InputDevs; p != NULL; p = p->next) {
15005b261ecSmrg        if (strcmp(name, p->name) == 0)
15105b261ecSmrg            return p;
15205b261ecSmrg    }
15305b261ecSmrg
15405b261ecSmrg    return NULL;
15505b261ecSmrg}
15605b261ecSmrg
15705b261ecSmrg/* Allocate a new ScrnInfoRec in xf86Screens */
15805b261ecSmrg
1596747b715SmrgScrnInfoPtr
16005b261ecSmrgxf86AllocateScreen(DriverPtr drv, int flags)
16105b261ecSmrg{
16205b261ecSmrg    int i;
163f7df2e56Smrg    ScrnInfoPtr pScrn;
164f7df2e56Smrg
165f7df2e56Smrg    if (flags & XF86_ALLOCATE_GPU_SCREEN) {
166f7df2e56Smrg        if (xf86GPUScreens == NULL)
167f7df2e56Smrg            xf86NumGPUScreens = 0;
168f7df2e56Smrg        i = xf86NumGPUScreens++;
169f7df2e56Smrg        xf86GPUScreens = xnfreallocarray(xf86GPUScreens, xf86NumGPUScreens,
170f7df2e56Smrg                                         sizeof(ScrnInfoPtr));
171f7df2e56Smrg        xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
172f7df2e56Smrg        pScrn = xf86GPUScreens[i];
173f7df2e56Smrg        pScrn->scrnIndex = i + GPU_SCREEN_OFFSET;      /* Changes when a screen is removed */
174f7df2e56Smrg        pScrn->is_gpu = TRUE;
175f7df2e56Smrg    } else {
176f7df2e56Smrg        if (xf86Screens == NULL)
177f7df2e56Smrg            xf86NumScreens = 0;
178f7df2e56Smrg
179f7df2e56Smrg        i = xf86NumScreens++;
180f7df2e56Smrg        xf86Screens = xnfreallocarray(xf86Screens, xf86NumScreens,
181f7df2e56Smrg                                      sizeof(ScrnInfoPtr));
182f7df2e56Smrg        xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
183f7df2e56Smrg        pScrn = xf86Screens[i];
18405b261ecSmrg
185f7df2e56Smrg        pScrn->scrnIndex = i;      /* Changes when a screen is removed */
186f7df2e56Smrg    }
18705b261ecSmrg
188f7df2e56Smrg    pScrn->origIndex = pScrn->scrnIndex;      /* This never changes */
189f7df2e56Smrg    pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount);
19005b261ecSmrg    /*
19105b261ecSmrg     * EnableDisableFBAccess now gets initialized in InitOutput()
192f7df2e56Smrg     * pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
19305b261ecSmrg     */
19405b261ecSmrg
195f7df2e56Smrg    pScrn->drv = drv;
19605b261ecSmrg    drv->refCount++;
197f7df2e56Smrg    pScrn->module = DuplicateModule(drv->module, NULL);
19805b261ecSmrg
199f7df2e56Smrg    pScrn->DriverFunc = drv->driverFunc;
20005b261ecSmrg
201f7df2e56Smrg    return pScrn;
20205b261ecSmrg}
20305b261ecSmrg
20405b261ecSmrg/*
20505b261ecSmrg * Remove an entry from xf86Screens.  Ideally it should free all allocated
20605b261ecSmrg * data.  To do this properly may require a driver hook.
20705b261ecSmrg */
20805b261ecSmrg
2096747b715Smrgvoid
210f7df2e56Smrgxf86DeleteScreen(ScrnInfoPtr pScrn)
21105b261ecSmrg{
21205b261ecSmrg    int i;
213f7df2e56Smrg    int scrnIndex;
214f7df2e56Smrg    Bool is_gpu = FALSE;
21505b261ecSmrg
216f7df2e56Smrg    if (!pScrn)
217f7df2e56Smrg        return;
21805b261ecSmrg
219f7df2e56Smrg    if (pScrn->is_gpu) {
220f7df2e56Smrg        /* First check if the screen is valid */
221f7df2e56Smrg        if (xf86NumGPUScreens == 0 || xf86GPUScreens == NULL)
222f7df2e56Smrg            return;
223f7df2e56Smrg        is_gpu = TRUE;
224f7df2e56Smrg    } else {
225f7df2e56Smrg        /* First check if the screen is valid */
226f7df2e56Smrg        if (xf86NumScreens == 0 || xf86Screens == NULL)
227f7df2e56Smrg            return;
228f7df2e56Smrg    }
22905b261ecSmrg
230f7df2e56Smrg    scrnIndex = pScrn->scrnIndex;
23105b261ecSmrg    /* If a FreeScreen function is defined, call it here */
23205b261ecSmrg    if (pScrn->FreeScreen != NULL)
233f7df2e56Smrg        pScrn->FreeScreen(pScrn);
23405b261ecSmrg
23505b261ecSmrg    while (pScrn->modes)
236f7df2e56Smrg        xf86DeleteMode(&pScrn->modes, pScrn->modes);
23705b261ecSmrg
23805b261ecSmrg    while (pScrn->modePool)
239f7df2e56Smrg        xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
24005b261ecSmrg
24105b261ecSmrg    xf86OptionListFree(pScrn->options);
24205b261ecSmrg
24305b261ecSmrg    if (pScrn->module)
244f7df2e56Smrg        UnloadModule(pScrn->module);
24505b261ecSmrg
24605b261ecSmrg    if (pScrn->drv)
247f7df2e56Smrg        pScrn->drv->refCount--;
24805b261ecSmrg
2496747b715Smrg    free(pScrn->privates);
25005b261ecSmrg
251f7df2e56Smrg    xf86ClearEntityListForScreen(pScrn);
25205b261ecSmrg
2536747b715Smrg    free(pScrn);
25405b261ecSmrg
25505b261ecSmrg    /* Move the other entries down, updating their scrnIndex fields */
25605b261ecSmrg
257f7df2e56Smrg    if (is_gpu) {
258f7df2e56Smrg        xf86NumGPUScreens--;
259f7df2e56Smrg        scrnIndex -= GPU_SCREEN_OFFSET;
260f7df2e56Smrg        for (i = scrnIndex; i < xf86NumGPUScreens; i++) {
261f7df2e56Smrg            xf86GPUScreens[i] = xf86GPUScreens[i + 1];
262f7df2e56Smrg            xf86GPUScreens[i]->scrnIndex = i + GPU_SCREEN_OFFSET;
263f7df2e56Smrg            /* Also need to take care of the screen layout settings */
264f7df2e56Smrg        }
265f7df2e56Smrg    }
266f7df2e56Smrg    else {
267f7df2e56Smrg        xf86NumScreens--;
26805b261ecSmrg
269f7df2e56Smrg        for (i = scrnIndex; i < xf86NumScreens; i++) {
270f7df2e56Smrg            xf86Screens[i] = xf86Screens[i + 1];
271f7df2e56Smrg            xf86Screens[i]->scrnIndex = i;
272f7df2e56Smrg            /* Also need to take care of the screen layout settings */
273f7df2e56Smrg        }
27405b261ecSmrg    }
27505b261ecSmrg}
27605b261ecSmrg
27705b261ecSmrg/*
27805b261ecSmrg * Allocate a private in ScrnInfoRec.
27905b261ecSmrg */
28005b261ecSmrg
2816747b715Smrgint
28205b261ecSmrgxf86AllocateScrnInfoPrivateIndex(void)
28305b261ecSmrg{
28405b261ecSmrg    int idx, i;
28505b261ecSmrg    ScrnInfoPtr pScr;
28605b261ecSmrg    DevUnion *nprivs;
28705b261ecSmrg
28805b261ecSmrg    idx = xf86ScrnInfoPrivateCount++;
28905b261ecSmrg    for (i = 0; i < xf86NumScreens; i++) {
290f7df2e56Smrg        pScr = xf86Screens[i];
291f7df2e56Smrg        nprivs = xnfreallocarray(pScr->privates,
292f7df2e56Smrg                                 xf86ScrnInfoPrivateCount, sizeof(DevUnion));
293f7df2e56Smrg        /* Zero the new private */
294f7df2e56Smrg        memset(&nprivs[idx], 0, sizeof(DevUnion));
295f7df2e56Smrg        pScr->privates = nprivs;
296f7df2e56Smrg    }
297f7df2e56Smrg    for (i = 0; i < xf86NumGPUScreens; i++) {
298f7df2e56Smrg        pScr = xf86GPUScreens[i];
299f7df2e56Smrg        nprivs = xnfreallocarray(pScr->privates,
300f7df2e56Smrg                                 xf86ScrnInfoPrivateCount, sizeof(DevUnion));
301f7df2e56Smrg        /* Zero the new private */
302f7df2e56Smrg        memset(&nprivs[idx], 0, sizeof(DevUnion));
303f7df2e56Smrg        pScr->privates = nprivs;
30405b261ecSmrg    }
30505b261ecSmrg    return idx;
30605b261ecSmrg}
30705b261ecSmrg
3086747b715SmrgBool
30905b261ecSmrgxf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
31005b261ecSmrg{
31105b261ecSmrg    int i;
31205b261ecSmrg
31305b261ecSmrg    if (pScrn->numFormats >= MAXFORMATS)
314f7df2e56Smrg        return FALSE;
31505b261ecSmrg
31605b261ecSmrg    if (bpp <= 0) {
317f7df2e56Smrg        if (depth == 1)
318f7df2e56Smrg            bpp = 1;
319f7df2e56Smrg        else if (depth <= 8)
320f7df2e56Smrg            bpp = 8;
321f7df2e56Smrg        else if (depth <= 16)
322f7df2e56Smrg            bpp = 16;
323f7df2e56Smrg        else if (depth <= 32)
324f7df2e56Smrg            bpp = 32;
325f7df2e56Smrg        else
326f7df2e56Smrg            return FALSE;
32705b261ecSmrg    }
32805b261ecSmrg    if (pad <= 0)
329f7df2e56Smrg        pad = BITMAP_SCANLINE_PAD;
33005b261ecSmrg
33105b261ecSmrg    i = pScrn->numFormats++;
33205b261ecSmrg    pScrn->formats[i].depth = depth;
33305b261ecSmrg    pScrn->formats[i].bitsPerPixel = bpp;
33405b261ecSmrg    pScrn->formats[i].scanlinePad = pad;
33505b261ecSmrg    return TRUE;
33605b261ecSmrg}
33705b261ecSmrg
33805b261ecSmrg/*
33905b261ecSmrg * Set the depth we are using based on (in the following order of preference):
34005b261ecSmrg *  - values given on the command line
34105b261ecSmrg *  - values given in the config file
34205b261ecSmrg *  - values provided by the driver
34305b261ecSmrg *  - an overall default when nothing else is given
34405b261ecSmrg *
34505b261ecSmrg * Also find a Display subsection matching the depth/bpp found.
34605b261ecSmrg *
34705b261ecSmrg * Sets the following ScrnInfoRec fields:
3487e31ba66Smrg *     bitsPerPixel, depth, display, imageByteOrder,
34905b261ecSmrg *     bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
35005b261ecSmrg *     formats, fbFormat.
35105b261ecSmrg */
35205b261ecSmrg
35305b261ecSmrg/* Can the screen handle 32 bpp pixmaps */
35405b261ecSmrg#define DO_PIX32(f) ((f & Support32bppFb) || \
35505b261ecSmrg		     ((f & Support24bppFb) && (f & SupportConvert32to24)))
35605b261ecSmrg
35705b261ecSmrg#ifndef GLOBAL_DEFAULT_DEPTH
35805b261ecSmrg#define GLOBAL_DEFAULT_DEPTH 24
35905b261ecSmrg#endif
36005b261ecSmrg
3616747b715SmrgBool
36205b261ecSmrgxf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
363f7df2e56Smrg                int depth24flags)
36405b261ecSmrg{
36505b261ecSmrg    int i;
36605b261ecSmrg    DispPtr disp;
36705b261ecSmrg
36805b261ecSmrg    scrp->bitsPerPixel = -1;
36905b261ecSmrg    scrp->depth = -1;
37005b261ecSmrg    scrp->bitsPerPixelFrom = X_DEFAULT;
37105b261ecSmrg    scrp->depthFrom = X_DEFAULT;
37205b261ecSmrg
37305b261ecSmrg    if (xf86FbBpp > 0) {
3747e31ba66Smrg        if (xf86FbBpp == 24) /* lol no */
3757e31ba66Smrg            xf86FbBpp = 32;
376f7df2e56Smrg        scrp->bitsPerPixel = xf86FbBpp;
377f7df2e56Smrg        scrp->bitsPerPixelFrom = X_CMDLINE;
37805b261ecSmrg    }
37905b261ecSmrg
38005b261ecSmrg    if (xf86Depth > 0) {
381f7df2e56Smrg        scrp->depth = xf86Depth;
382f7df2e56Smrg        scrp->depthFrom = X_CMDLINE;
38305b261ecSmrg    }
38405b261ecSmrg
38505b261ecSmrg    if (xf86FbBpp < 0 && xf86Depth < 0) {
386f7df2e56Smrg        if (scrp->confScreen->defaultfbbpp > 0) {
387f7df2e56Smrg            scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
388f7df2e56Smrg            scrp->bitsPerPixelFrom = X_CONFIG;
389f7df2e56Smrg        }
390f7df2e56Smrg        if (scrp->confScreen->defaultdepth > 0) {
391f7df2e56Smrg            scrp->depth = scrp->confScreen->defaultdepth;
392f7df2e56Smrg            scrp->depthFrom = X_CONFIG;
393f7df2e56Smrg        }
394f7df2e56Smrg
395f7df2e56Smrg        if (scrp->confScreen->defaultfbbpp <= 0 &&
396f7df2e56Smrg            scrp->confScreen->defaultdepth <= 0) {
397f7df2e56Smrg            /*
398f7df2e56Smrg             * Check for DefaultDepth and DefaultFbBpp options in the
399f7df2e56Smrg             * Device sections.
400f7df2e56Smrg             */
401f7df2e56Smrg            GDevPtr device;
402f7df2e56Smrg            Bool found = FALSE;
403f7df2e56Smrg
404f7df2e56Smrg            for (i = 0; i < scrp->numEntities; i++) {
405f7df2e56Smrg                device = xf86GetDevFromEntity(scrp->entityList[i],
406f7df2e56Smrg                                              scrp->entityInstanceList[i]);
407f7df2e56Smrg                if (device && device->options) {
408f7df2e56Smrg                    if (xf86FindOption(device->options, "DefaultDepth")) {
409f7df2e56Smrg                        scrp->depth = xf86SetIntOption(device->options,
410f7df2e56Smrg                                                       "DefaultDepth", -1);
411f7df2e56Smrg                        scrp->depthFrom = X_CONFIG;
412f7df2e56Smrg                        found = TRUE;
413f7df2e56Smrg                    }
414f7df2e56Smrg                    if (xf86FindOption(device->options, "DefaultFbBpp")) {
415f7df2e56Smrg                        scrp->bitsPerPixel = xf86SetIntOption(device->options,
416f7df2e56Smrg                                                              "DefaultFbBpp",
417f7df2e56Smrg                                                              -1);
418f7df2e56Smrg                        scrp->bitsPerPixelFrom = X_CONFIG;
419f7df2e56Smrg                        found = TRUE;
420f7df2e56Smrg                    }
421f7df2e56Smrg                }
422f7df2e56Smrg                if (found)
423f7df2e56Smrg                    break;
424f7df2e56Smrg            }
425f7df2e56Smrg        }
42605b261ecSmrg    }
42705b261ecSmrg
42805b261ecSmrg    /* If none of these is set, pick a default */
42905b261ecSmrg    if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
43005b261ecSmrg        if (fbbpp > 0 || depth > 0) {
431f7df2e56Smrg            if (fbbpp > 0)
432f7df2e56Smrg                scrp->bitsPerPixel = fbbpp;
433f7df2e56Smrg            if (depth > 0)
434f7df2e56Smrg                scrp->depth = depth;
435f7df2e56Smrg        }
436f7df2e56Smrg        else {
437f7df2e56Smrg            scrp->depth = GLOBAL_DEFAULT_DEPTH;
438f7df2e56Smrg        }
43905b261ecSmrg    }
44005b261ecSmrg
44105b261ecSmrg    /* If any are not given, determine a default for the others */
44205b261ecSmrg
44305b261ecSmrg    if (scrp->bitsPerPixel < 0) {
444f7df2e56Smrg        /* The depth must be set */
445f7df2e56Smrg        if (scrp->depth > -1) {
446f7df2e56Smrg            if (scrp->depth == 1)
447f7df2e56Smrg                scrp->bitsPerPixel = 1;
448f7df2e56Smrg            else if (scrp->depth <= 4)
449f7df2e56Smrg                scrp->bitsPerPixel = 4;
450f7df2e56Smrg            else if (scrp->depth <= 8)
451f7df2e56Smrg                scrp->bitsPerPixel = 8;
452f7df2e56Smrg            else if (scrp->depth <= 16)
453f7df2e56Smrg                scrp->bitsPerPixel = 16;
4547e31ba66Smrg            else if (scrp->depth <= 24 && DO_PIX32(depth24flags)) {
4557e31ba66Smrg                scrp->bitsPerPixel = 32;
456f7df2e56Smrg            }
457f7df2e56Smrg            else if (scrp->depth <= 32)
458f7df2e56Smrg                scrp->bitsPerPixel = 32;
459f7df2e56Smrg            else {
460f7df2e56Smrg                xf86DrvMsg(scrp->scrnIndex, X_ERROR,
4617e31ba66Smrg                           "No bpp for depth (%d)\n", scrp->depth);
462f7df2e56Smrg                return FALSE;
463f7df2e56Smrg            }
464f7df2e56Smrg        }
465f7df2e56Smrg        else {
466f7df2e56Smrg            xf86DrvMsg(scrp->scrnIndex, X_ERROR,
467f7df2e56Smrg                       "xf86SetDepthBpp: internal error: depth and fbbpp"
468f7df2e56Smrg                       " are both not set\n");
469f7df2e56Smrg            return FALSE;
470f7df2e56Smrg        }
471f7df2e56Smrg        if (scrp->bitsPerPixel < 0) {
4727e31ba66Smrg            if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
473f7df2e56Smrg                     NoDepth24Support)
474f7df2e56Smrg                xf86DrvMsg(scrp->scrnIndex, X_ERROR,
475f7df2e56Smrg                           "Driver can't support depth 24\n");
476f7df2e56Smrg            else
477f7df2e56Smrg                xf86DrvMsg(scrp->scrnIndex, X_ERROR,
478f7df2e56Smrg                           "Can't find fbbpp for depth 24\n");
479f7df2e56Smrg            return FALSE;
480f7df2e56Smrg        }
481f7df2e56Smrg        scrp->bitsPerPixelFrom = X_PROBED;
48205b261ecSmrg    }
48305b261ecSmrg
48405b261ecSmrg    if (scrp->depth <= 0) {
485f7df2e56Smrg        /* bitsPerPixel is already set */
486f7df2e56Smrg        switch (scrp->bitsPerPixel) {
487f7df2e56Smrg        case 32:
488f7df2e56Smrg            scrp->depth = 24;
489f7df2e56Smrg            break;
490f7df2e56Smrg        default:
491f7df2e56Smrg            /* 1, 4, 8, 16 and 24 */
492f7df2e56Smrg            scrp->depth = scrp->bitsPerPixel;
493f7df2e56Smrg            break;
494f7df2e56Smrg        }
495f7df2e56Smrg        scrp->depthFrom = X_PROBED;
49605b261ecSmrg    }
49705b261ecSmrg
49805b261ecSmrg    /* Sanity checks */
49905b261ecSmrg    if (scrp->depth < 1 || scrp->depth > 32) {
500f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, X_ERROR,
501f7df2e56Smrg                   "Specified depth (%d) is not in the range 1-32\n",
502f7df2e56Smrg                   scrp->depth);
503f7df2e56Smrg        return FALSE;
50405b261ecSmrg    }
50505b261ecSmrg    switch (scrp->bitsPerPixel) {
50605b261ecSmrg    case 1:
50705b261ecSmrg    case 4:
50805b261ecSmrg    case 8:
50905b261ecSmrg    case 16:
51005b261ecSmrg    case 32:
511f7df2e56Smrg        break;
51205b261ecSmrg    default:
513f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, X_ERROR,
514f7df2e56Smrg                   "Specified fbbpp (%d) is not a permitted value\n",
515f7df2e56Smrg                   scrp->bitsPerPixel);
516f7df2e56Smrg        return FALSE;
51705b261ecSmrg    }
51805b261ecSmrg    if (scrp->depth > scrp->bitsPerPixel) {
519f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, X_ERROR,
520f7df2e56Smrg                   "Specified depth (%d) is greater than the fbbpp (%d)\n",
521f7df2e56Smrg                   scrp->depth, scrp->bitsPerPixel);
522f7df2e56Smrg        return FALSE;
52305b261ecSmrg    }
52405b261ecSmrg
52505b261ecSmrg    /*
52605b261ecSmrg     * Find the Display subsection matching the depth/fbbpp and initialise
52705b261ecSmrg     * scrp->display with it.
52805b261ecSmrg     */
529d44ca368Smrg    for (i = 0; i < scrp->confScreen->numdisplays; i++) {
530d44ca368Smrg        disp = scrp->confScreen->displays[i];
531f7df2e56Smrg        if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
532f7df2e56Smrg            || (disp->depth == scrp->depth && disp->fbbpp <= 0)
533f7df2e56Smrg            || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
534f7df2e56Smrg            scrp->display = disp;
535f7df2e56Smrg            break;
536f7df2e56Smrg        }
53705b261ecSmrg    }
53805b261ecSmrg
53905b261ecSmrg    /*
54005b261ecSmrg     * If an exact match can't be found, see if there is one with no
54105b261ecSmrg     * depth or fbbpp specified.
54205b261ecSmrg     */
54305b261ecSmrg    if (i == scrp->confScreen->numdisplays) {
544d44ca368Smrg        for (i = 0; i < scrp->confScreen->numdisplays; i++) {
545d44ca368Smrg            disp = scrp->confScreen->displays[i];
546f7df2e56Smrg            if (disp->depth <= 0 && disp->fbbpp <= 0) {
547f7df2e56Smrg                scrp->display = disp;
548f7df2e56Smrg                break;
549f7df2e56Smrg            }
550f7df2e56Smrg        }
55105b261ecSmrg    }
55205b261ecSmrg
55305b261ecSmrg    /*
55405b261ecSmrg     * If all else fails, create a default one.
55505b261ecSmrg     */
55605b261ecSmrg    if (i == scrp->confScreen->numdisplays) {
557f7df2e56Smrg        scrp->confScreen->numdisplays++;
558f7df2e56Smrg        scrp->confScreen->displays =
559f7df2e56Smrg            xnfreallocarray(scrp->confScreen->displays,
560d44ca368Smrg                            scrp->confScreen->numdisplays, sizeof(DispPtr));
561f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, X_INFO,
562f7df2e56Smrg                   "Creating default Display subsection in Screen section\n"
563f7df2e56Smrg                   "\t\"%s\" for depth/fbbpp %d/%d\n",
564f7df2e56Smrg                   scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
565d44ca368Smrg        scrp->confScreen->displays[i] = xnfcalloc(1, sizeof(DispRec));
566d44ca368Smrg        memset(scrp->confScreen->displays[i], 0, sizeof(DispRec));
567d44ca368Smrg        scrp->confScreen->displays[i]->blackColour.red = -1;
568d44ca368Smrg        scrp->confScreen->displays[i]->blackColour.green = -1;
569d44ca368Smrg        scrp->confScreen->displays[i]->blackColour.blue = -1;
570d44ca368Smrg        scrp->confScreen->displays[i]->whiteColour.red = -1;
571d44ca368Smrg        scrp->confScreen->displays[i]->whiteColour.green = -1;
572d44ca368Smrg        scrp->confScreen->displays[i]->whiteColour.blue = -1;
573d44ca368Smrg        scrp->confScreen->displays[i]->defaultVisual = -1;
574d44ca368Smrg        scrp->confScreen->displays[i]->modes = xnfalloc(sizeof(char *));
575d44ca368Smrg        scrp->confScreen->displays[i]->modes[0] = NULL;
576d44ca368Smrg        scrp->confScreen->displays[i]->depth = depth;
577d44ca368Smrg        scrp->confScreen->displays[i]->fbbpp = fbbpp;
578d44ca368Smrg        scrp->display = scrp->confScreen->displays[i];
57905b261ecSmrg    }
58005b261ecSmrg
58105b261ecSmrg    /*
58205b261ecSmrg     * Setup defaults for the display-wide attributes the framebuffer will
58305b261ecSmrg     * need.  These defaults should eventually be set globally, and not
58405b261ecSmrg     * dependent on the screens.
58505b261ecSmrg     */
58605b261ecSmrg    scrp->imageByteOrder = IMAGE_BYTE_ORDER;
58705b261ecSmrg    scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
58805b261ecSmrg    if (scrp->depth < 8) {
589f7df2e56Smrg        /* Planar modes need these settings */
590f7df2e56Smrg        scrp->bitmapScanlineUnit = 8;
591f7df2e56Smrg        scrp->bitmapBitOrder = MSBFirst;
592f7df2e56Smrg    }
593f7df2e56Smrg    else {
594f7df2e56Smrg        scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
595f7df2e56Smrg        scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
59605b261ecSmrg    }
59705b261ecSmrg
59805b261ecSmrg    /*
59905b261ecSmrg     * If an unusual depth is required, add it to scrp->formats.  The formats
60005b261ecSmrg     * for the common depths are handled globally in InitOutput
60105b261ecSmrg     */
60205b261ecSmrg    switch (scrp->depth) {
60305b261ecSmrg    case 1:
60405b261ecSmrg    case 4:
60505b261ecSmrg    case 8:
60605b261ecSmrg    case 15:
60705b261ecSmrg    case 16:
60805b261ecSmrg    case 24:
609f7df2e56Smrg        /* Common depths.  Nothing to do for them */
610f7df2e56Smrg        break;
61105b261ecSmrg    default:
612f7df2e56Smrg        if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
613f7df2e56Smrg            xf86DrvMsg(scrp->scrnIndex, X_ERROR,
614f7df2e56Smrg                       "Can't add pixmap format for depth %d\n", scrp->depth);
615f7df2e56Smrg            return FALSE;
616f7df2e56Smrg        }
61705b261ecSmrg    }
61805b261ecSmrg
61905b261ecSmrg    /* Initialise the framebuffer format for this screen */
62005b261ecSmrg    scrp->fbFormat.depth = scrp->depth;
62105b261ecSmrg    scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
62205b261ecSmrg    scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
62305b261ecSmrg
62405b261ecSmrg    return TRUE;
62505b261ecSmrg}
62605b261ecSmrg
62705b261ecSmrg/*
62805b261ecSmrg * Print out the selected depth and bpp.
62905b261ecSmrg */
6306747b715Smrgvoid
63105b261ecSmrgxf86PrintDepthBpp(ScrnInfoPtr scrp)
63205b261ecSmrg{
63305b261ecSmrg    xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
63405b261ecSmrg    xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
63505b261ecSmrg}
63605b261ecSmrg
63705b261ecSmrg/*
63805b261ecSmrg * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
63905b261ecSmrg * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
64005b261ecSmrg */
6416747b715SmrgBool
64205b261ecSmrgxf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
64305b261ecSmrg{
64405b261ecSmrg    MessageType weightFrom = X_DEFAULT;
64505b261ecSmrg
64605b261ecSmrg    scrp->weight.red = 0;
64705b261ecSmrg    scrp->weight.green = 0;
64805b261ecSmrg    scrp->weight.blue = 0;
64905b261ecSmrg
65005b261ecSmrg    if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
651f7df2e56Smrg        scrp->weight = xf86Weight;
652f7df2e56Smrg        weightFrom = X_CMDLINE;
653f7df2e56Smrg    }
654f7df2e56Smrg    else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
655f7df2e56Smrg             && scrp->display->weight.blue > 0) {
656f7df2e56Smrg        scrp->weight = scrp->display->weight;
657f7df2e56Smrg        weightFrom = X_CONFIG;
658f7df2e56Smrg    }
659f7df2e56Smrg    else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
660f7df2e56Smrg        scrp->weight = weight;
661f7df2e56Smrg    }
662f7df2e56Smrg    else {
663f7df2e56Smrg        switch (scrp->depth) {
664f7df2e56Smrg        case 1:
665f7df2e56Smrg        case 4:
666f7df2e56Smrg        case 8:
667f7df2e56Smrg            scrp->weight.red = scrp->weight.green =
668f7df2e56Smrg                scrp->weight.blue = scrp->rgbBits;
669f7df2e56Smrg            break;
670f7df2e56Smrg        case 15:
671f7df2e56Smrg            scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
672f7df2e56Smrg            break;
673f7df2e56Smrg        case 16:
674f7df2e56Smrg            scrp->weight.red = scrp->weight.blue = 5;
675f7df2e56Smrg            scrp->weight.green = 6;
676f7df2e56Smrg            break;
677f7df2e56Smrg        case 18:
678f7df2e56Smrg            scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6;
679f7df2e56Smrg            break;
680f7df2e56Smrg        case 24:
681f7df2e56Smrg            scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
682f7df2e56Smrg            break;
683f7df2e56Smrg        case 30:
684f7df2e56Smrg            scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
685f7df2e56Smrg            break;
686f7df2e56Smrg        }
68705b261ecSmrg    }
68805b261ecSmrg
68905b261ecSmrg    if (scrp->weight.red)
690f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
691f7df2e56Smrg                   (int) scrp->weight.red, (int) scrp->weight.green,
692f7df2e56Smrg                   (int) scrp->weight.blue);
69305b261ecSmrg
69405b261ecSmrg    if (scrp->depth > MAX_PSEUDO_DEPTH &&
695f7df2e56Smrg        (scrp->depth != scrp->weight.red + scrp->weight.green +
696f7df2e56Smrg         scrp->weight.blue)) {
697f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, X_ERROR,
698f7df2e56Smrg                   "Weight given (%d%d%d) is inconsistent with the "
699f7df2e56Smrg                   "depth (%d)\n",
700f7df2e56Smrg                   (int) scrp->weight.red, (int) scrp->weight.green,
701f7df2e56Smrg                   (int) scrp->weight.blue, scrp->depth);
702f7df2e56Smrg        return FALSE;
70305b261ecSmrg    }
70405b261ecSmrg    if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
705f7df2e56Smrg        /*
706f7df2e56Smrg         * XXX Does this even mean anything for TrueColor visuals?
707f7df2e56Smrg         * If not, we shouldn't even be setting it here.  However, this
708f7df2e56Smrg         * matches the behaviour of 3.x versions of XFree86.
709f7df2e56Smrg         */
710f7df2e56Smrg        scrp->rgbBits = scrp->weight.red;
711f7df2e56Smrg        if (scrp->weight.green > scrp->rgbBits)
712f7df2e56Smrg            scrp->rgbBits = scrp->weight.green;
713f7df2e56Smrg        if (scrp->weight.blue > scrp->rgbBits)
714f7df2e56Smrg            scrp->rgbBits = scrp->weight.blue;
71505b261ecSmrg    }
71605b261ecSmrg
71705b261ecSmrg    /* Set the mask and offsets */
71805b261ecSmrg    if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
719f7df2e56Smrg        /* Default to a setting common to PC hardware */
720f7df2e56Smrg        scrp->offset.red = scrp->weight.green + scrp->weight.blue;
721f7df2e56Smrg        scrp->offset.green = scrp->weight.blue;
722f7df2e56Smrg        scrp->offset.blue = 0;
723f7df2e56Smrg        scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
724f7df2e56Smrg        scrp->mask.green = ((1 << scrp->weight.green) - 1)
725f7df2e56Smrg            << scrp->offset.green;
726f7df2e56Smrg        scrp->mask.blue = (1 << scrp->weight.blue) - 1;
727f7df2e56Smrg    }
728f7df2e56Smrg    else {
729f7df2e56Smrg        /* Initialise to the values passed */
730f7df2e56Smrg        scrp->mask.red = mask.red;
731f7df2e56Smrg        scrp->mask.green = mask.green;
732f7df2e56Smrg        scrp->mask.blue = mask.blue;
7335a112b11Smrg        scrp->offset.red = ffs(mask.red) - 1;
7345a112b11Smrg        scrp->offset.green = ffs(mask.green) - 1;
7355a112b11Smrg        scrp->offset.blue = ffs(mask.blue) - 1;
73605b261ecSmrg    }
73705b261ecSmrg    return TRUE;
73805b261ecSmrg}
73905b261ecSmrg
7406747b715SmrgBool
74105b261ecSmrgxf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
74205b261ecSmrg{
74305b261ecSmrg    MessageType visualFrom = X_DEFAULT;
74405b261ecSmrg
74505b261ecSmrg    if (defaultColorVisualClass >= 0) {
746f7df2e56Smrg        scrp->defaultVisual = defaultColorVisualClass;
747f7df2e56Smrg        visualFrom = X_CMDLINE;
748f7df2e56Smrg    }
749f7df2e56Smrg    else if (scrp->display->defaultVisual >= 0) {
750f7df2e56Smrg        scrp->defaultVisual = scrp->display->defaultVisual;
751f7df2e56Smrg        visualFrom = X_CONFIG;
752f7df2e56Smrg    }
753f7df2e56Smrg    else if (visual >= 0) {
754f7df2e56Smrg        scrp->defaultVisual = visual;
755f7df2e56Smrg    }
756f7df2e56Smrg    else {
757f7df2e56Smrg        if (scrp->depth == 1)
758f7df2e56Smrg            scrp->defaultVisual = StaticGray;
759f7df2e56Smrg        else if (scrp->depth == 4)
760f7df2e56Smrg            scrp->defaultVisual = StaticColor;
761f7df2e56Smrg        else if (scrp->depth <= MAX_PSEUDO_DEPTH)
762f7df2e56Smrg            scrp->defaultVisual = PseudoColor;
763f7df2e56Smrg        else
764f7df2e56Smrg            scrp->defaultVisual = TrueColor;
76505b261ecSmrg    }
76605b261ecSmrg    switch (scrp->defaultVisual) {
76705b261ecSmrg    case StaticGray:
76805b261ecSmrg    case GrayScale:
76905b261ecSmrg    case StaticColor:
77005b261ecSmrg    case PseudoColor:
77105b261ecSmrg    case TrueColor:
77205b261ecSmrg    case DirectColor:
773f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
774f7df2e56Smrg                   xf86VisualNames[scrp->defaultVisual]);
775f7df2e56Smrg        return TRUE;
77605b261ecSmrg    default:
77705b261ecSmrg
778f7df2e56Smrg        xf86DrvMsg(scrp->scrnIndex, X_ERROR,
779f7df2e56Smrg                   "Invalid default visual class (%d)\n", scrp->defaultVisual);
780f7df2e56Smrg        return FALSE;
78105b261ecSmrg    }
78205b261ecSmrg}
78305b261ecSmrg
78405b261ecSmrg#define TEST_GAMMA(g) \
78505b261ecSmrg	(g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
78605b261ecSmrg
78705b261ecSmrg#define SET_GAMMA(g) \
78805b261ecSmrg	(g) > GAMMA_ZERO ? (g) : 1.0
78905b261ecSmrg
7906747b715SmrgBool
79105b261ecSmrgxf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
79205b261ecSmrg{
79305b261ecSmrg    MessageType from = X_DEFAULT;
794f7df2e56Smrg
79505b261ecSmrg#if 0
796f7df2e56Smrg    xf86MonPtr DDC = (xf86MonPtr) (scrp->monitor->DDC);
79705b261ecSmrg#endif
79805b261ecSmrg    if (TEST_GAMMA(xf86Gamma)) {
799f7df2e56Smrg        from = X_CMDLINE;
800f7df2e56Smrg        scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
801f7df2e56Smrg        scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
802f7df2e56Smrg        scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
803f7df2e56Smrg    }
804f7df2e56Smrg    else if (TEST_GAMMA(scrp->monitor->gamma)) {
805f7df2e56Smrg        from = X_CONFIG;
806f7df2e56Smrg        scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
807f7df2e56Smrg        scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
808f7df2e56Smrg        scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
80905b261ecSmrg#if 0
810f7df2e56Smrg    }
811f7df2e56Smrg    else if (DDC && DDC->features.gamma > GAMMA_ZERO) {
81205b261ecSmrg        from = X_PROBED;
813f7df2e56Smrg        scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
814f7df2e56Smrg        scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
815f7df2e56Smrg        scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
8165a112b11Smrg        /* EDID structure version 2 gives optional separate red, green & blue
8175a112b11Smrg         * gamma values in bytes 0x57-0x59 */
81805b261ecSmrg#endif
819f7df2e56Smrg    }
820f7df2e56Smrg    else if (TEST_GAMMA(gamma)) {
821f7df2e56Smrg        scrp->gamma.red = SET_GAMMA(gamma.red);
822f7df2e56Smrg        scrp->gamma.green = SET_GAMMA(gamma.green);
823f7df2e56Smrg        scrp->gamma.blue = SET_GAMMA(gamma.blue);
824f7df2e56Smrg    }
825f7df2e56Smrg    else {
826f7df2e56Smrg        scrp->gamma.red = 1.0;
827f7df2e56Smrg        scrp->gamma.green = 1.0;
828f7df2e56Smrg        scrp->gamma.blue = 1.0;
82905b261ecSmrg    }
8307e31ba66Smrg
83105b261ecSmrg    xf86DrvMsg(scrp->scrnIndex, from,
832f7df2e56Smrg               "Using gamma correction (%.1f, %.1f, %.1f)\n",
833f7df2e56Smrg               scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
83405b261ecSmrg
83505b261ecSmrg    return TRUE;
83605b261ecSmrg}
83705b261ecSmrg
83805b261ecSmrg#undef TEST_GAMMA
83905b261ecSmrg#undef SET_GAMMA
84005b261ecSmrg
84105b261ecSmrg/*
84205b261ecSmrg * Set the DPI from the command line option.  XXX should allow it to be
84305b261ecSmrg * calculated from the widthmm/heightmm values.
84405b261ecSmrg */
84505b261ecSmrg
84605b261ecSmrg#undef MMPERINCH
84705b261ecSmrg#define MMPERINCH 25.4
84805b261ecSmrg
8496747b715Smrgvoid
85005b261ecSmrgxf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
85105b261ecSmrg{
85205b261ecSmrg    MessageType from = X_DEFAULT;
853f7df2e56Smrg    xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC);
85405b261ecSmrg    int ddcWidthmm, ddcHeightmm;
85505b261ecSmrg    int widthErr, heightErr;
85605b261ecSmrg
85705b261ecSmrg    /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
85805b261ecSmrg    pScrn->widthmm = pScrn->monitor->widthmm;
85905b261ecSmrg    pScrn->heightmm = pScrn->monitor->heightmm;
86005b261ecSmrg
861f7df2e56Smrg    if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0)) {
862f7df2e56Smrg        /* DDC gives display size in mm for individual modes,
863f7df2e56Smrg         * but cm for monitor
864f7df2e56Smrg         */
865f7df2e56Smrg        ddcWidthmm = DDC->features.hsize * 10;  /* 10mm in 1cm */
866f7df2e56Smrg        ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
867f7df2e56Smrg    }
868f7df2e56Smrg    else {
869f7df2e56Smrg        ddcWidthmm = ddcHeightmm = 0;
87005b261ecSmrg    }
87105b261ecSmrg
87205b261ecSmrg    if (monitorResolution > 0) {
873f7df2e56Smrg        pScrn->xDpi = monitorResolution;
874f7df2e56Smrg        pScrn->yDpi = monitorResolution;
875f7df2e56Smrg        from = X_CMDLINE;
876f7df2e56Smrg    }
877f7df2e56Smrg    else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
878f7df2e56Smrg        from = X_CONFIG;
879f7df2e56Smrg        if (pScrn->widthmm > 0) {
880f7df2e56Smrg            pScrn->xDpi =
881f7df2e56Smrg                (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);
882f7df2e56Smrg        }
883f7df2e56Smrg        if (pScrn->heightmm > 0) {
884f7df2e56Smrg            pScrn->yDpi =
885f7df2e56Smrg                (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm);
886f7df2e56Smrg        }
887f7df2e56Smrg        if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
888f7df2e56Smrg            pScrn->yDpi = pScrn->xDpi;
889f7df2e56Smrg        if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
890f7df2e56Smrg            pScrn->xDpi = pScrn->yDpi;
891f7df2e56Smrg        xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
892f7df2e56Smrg                   pScrn->widthmm, pScrn->heightmm);
893f7df2e56Smrg
894f7df2e56Smrg        /* Warn if config and probe disagree about display size */
895f7df2e56Smrg        if (ddcWidthmm && ddcHeightmm) {
896f7df2e56Smrg            if (pScrn->widthmm > 0) {
897f7df2e56Smrg                widthErr = abs(ddcWidthmm - pScrn->widthmm);
898f7df2e56Smrg            }
899f7df2e56Smrg            else {
900f7df2e56Smrg                widthErr = 0;
901f7df2e56Smrg            }
902f7df2e56Smrg            if (pScrn->heightmm > 0) {
903f7df2e56Smrg                heightErr = abs(ddcHeightmm - pScrn->heightmm);
904f7df2e56Smrg            }
905f7df2e56Smrg            else {
906f7df2e56Smrg                heightErr = 0;
907f7df2e56Smrg            }
908f7df2e56Smrg            if (widthErr > 10 || heightErr > 10) {
909f7df2e56Smrg                /* Should include config file name for monitor here */
910f7df2e56Smrg                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
911f7df2e56Smrg                           "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
912f7df2e56Smrg                           ddcWidthmm, ddcHeightmm, pScrn->widthmm,
913f7df2e56Smrg                           pScrn->heightmm);
914f7df2e56Smrg            }
915f7df2e56Smrg        }
916f7df2e56Smrg    }
917f7df2e56Smrg    else if (ddcWidthmm && ddcHeightmm) {
918f7df2e56Smrg        from = X_PROBED;
919f7df2e56Smrg        xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
920f7df2e56Smrg                   ddcWidthmm, ddcHeightmm);
921f7df2e56Smrg        pScrn->widthmm = ddcWidthmm;
922f7df2e56Smrg        pScrn->heightmm = ddcHeightmm;
923f7df2e56Smrg        if (pScrn->widthmm > 0) {
924f7df2e56Smrg            pScrn->xDpi =
925f7df2e56Smrg                (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);
926f7df2e56Smrg        }
927f7df2e56Smrg        if (pScrn->heightmm > 0) {
928f7df2e56Smrg            pScrn->yDpi =
929f7df2e56Smrg                (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm);
930f7df2e56Smrg        }
931f7df2e56Smrg        if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
932f7df2e56Smrg            pScrn->yDpi = pScrn->xDpi;
933f7df2e56Smrg        if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
934f7df2e56Smrg            pScrn->xDpi = pScrn->yDpi;
935f7df2e56Smrg    }
936f7df2e56Smrg    else {
937f7df2e56Smrg        if (x > 0)
938f7df2e56Smrg            pScrn->xDpi = x;
939f7df2e56Smrg        else
940f7df2e56Smrg            pScrn->xDpi = DEFAULT_DPI;
941f7df2e56Smrg        if (y > 0)
942f7df2e56Smrg            pScrn->yDpi = y;
943f7df2e56Smrg        else
944f7df2e56Smrg            pScrn->yDpi = DEFAULT_DPI;
94505b261ecSmrg    }
94605b261ecSmrg    xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
947f7df2e56Smrg               pScrn->xDpi, pScrn->yDpi);
94805b261ecSmrg}
94905b261ecSmrg
95005b261ecSmrg#undef MMPERINCH
95105b261ecSmrg
9526747b715Smrgvoid
95305b261ecSmrgxf86SetBlackWhitePixels(ScreenPtr pScreen)
95405b261ecSmrg{
9559b06bd19Stsutsui    if (xf86FlipPixels) {
9569b06bd19Stsutsui        pScreen->whitePixel = 0;
9579b06bd19Stsutsui        pScreen->blackPixel = 1;
9589b06bd19Stsutsui    }
9599b06bd19Stsutsui    else {
9609b06bd19Stsutsui        pScreen->whitePixel = 1;
9619b06bd19Stsutsui        pScreen->blackPixel = 0;
9629b06bd19Stsutsui    }
96305b261ecSmrg}
96405b261ecSmrg
96505b261ecSmrg/*
96605b261ecSmrg * Function to enable/disable access to the frame buffer
96705b261ecSmrg *
96805b261ecSmrg * This is used when VT switching and when entering/leaving DGA direct mode.
96905b261ecSmrg *
97005b261ecSmrg * This has been rewritten again to eliminate the saved pixmap.  The
97105b261ecSmrg * devPrivate field in the screen pixmap is set to NULL to catch code
97205b261ecSmrg * accidentally referencing the frame buffer while the X server is not
97305b261ecSmrg * supposed to touch it.
97405b261ecSmrg *
97505b261ecSmrg * Here, we exchange the pixmap private data, rather than the pixmaps
97605b261ecSmrg * themselves to avoid having to find and change any references to the screen
97705b261ecSmrg * pixmap such as GC's, window privates etc.  This also means that this code
97805b261ecSmrg * does not need to know exactly how the pixmap pixels are accessed.  Further,
97905b261ecSmrg * this exchange is >not< done through the screen's ModifyPixmapHeader()
98005b261ecSmrg * vector.  This means the called frame buffer code layers can determine
98105b261ecSmrg * whether they are switched in or out by keeping track of the root pixmap's
98205b261ecSmrg * private data, and therefore don't need to access pScrnInfo->vtSema.
98305b261ecSmrg */
9846747b715Smrgvoid
985f7df2e56Smrgxf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable)
98605b261ecSmrg{
98705b261ecSmrg    ScreenPtr pScreen = pScrnInfo->pScreen;
98805b261ecSmrg
989f7df2e56Smrg    if (enable) {
990f7df2e56Smrg        /*
991f7df2e56Smrg         * Restore all of the clip lists on the screen
992f7df2e56Smrg         */
993f7df2e56Smrg        if (!xf86Resetting)
994f7df2e56Smrg            SetRootClip(pScreen, ROOT_CLIP_FULL);
99505b261ecSmrg
99605b261ecSmrg    }
997f7df2e56Smrg    else {
998f7df2e56Smrg        /*
999f7df2e56Smrg         * Empty all of the clip lists on the screen
1000f7df2e56Smrg         */
1001f7df2e56Smrg        SetRootClip(pScreen, ROOT_CLIP_NONE);
100205b261ecSmrg    }
100305b261ecSmrg}
100405b261ecSmrg
1005f7df2e56Smrg/* Print driver messages in the standard format of
1006f7df2e56Smrg   (<type>) <screen name>(<screen index>): <message> */
10076747b715Smrgvoid
100805b261ecSmrgxf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1009f7df2e56Smrg                va_list args)
101005b261ecSmrg{
101105b261ecSmrg    /* Prefix the scrnIndex name to the format string. */
101205b261ecSmrg    if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
1013f7df2e56Smrg        xf86Screens[scrnIndex]->name)
1014f7df2e56Smrg        LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
1015f7df2e56Smrg                          xf86Screens[scrnIndex]->name, scrnIndex);
1016f7df2e56Smrg    else if (scrnIndex >= GPU_SCREEN_OFFSET &&
1017f7df2e56Smrg             scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens &&
1018f7df2e56Smrg             xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name)
1019f7df2e56Smrg        LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ",
1020f7df2e56Smrg                          xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET);
1021f7df2e56Smrg    else
1022f7df2e56Smrg        LogVMessageVerb(type, verb, format, args);
102305b261ecSmrg}
102405b261ecSmrg
102505b261ecSmrg/* Print driver messages, with verbose level specified directly */
10266747b715Smrgvoid
102705b261ecSmrgxf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1028f7df2e56Smrg               ...)
102905b261ecSmrg{
103005b261ecSmrg    va_list ap;
103105b261ecSmrg
103205b261ecSmrg    va_start(ap, format);
103305b261ecSmrg    xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
103405b261ecSmrg    va_end(ap);
103505b261ecSmrg}
103605b261ecSmrg
103705b261ecSmrg/* Print driver messages, with verbose level of 1 (default) */
10386747b715Smrgvoid
103905b261ecSmrgxf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
104005b261ecSmrg{
104105b261ecSmrg    va_list ap;
104205b261ecSmrg
104305b261ecSmrg    va_start(ap, format);
104405b261ecSmrg    xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
104505b261ecSmrg    va_end(ap);
104605b261ecSmrg}
104705b261ecSmrg
10489ace9065Smrg/* Print input driver messages in the standard format of
1049f7df2e56Smrg   (<type>) <driver>: <device name>: <message> */
10509ace9065Smrgvoid
1051f7df2e56Smrgxf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb,
1052f7df2e56Smrg                 const char *format, va_list args)
10539ace9065Smrg{
1054f7df2e56Smrg    const char *driverName = NULL;
1055f7df2e56Smrg    const char *deviceName = NULL;
10569ace9065Smrg
1057f7df2e56Smrg    /* Prefix driver and device names to formatted message. */
1058f7df2e56Smrg    if (dev) {
1059f7df2e56Smrg        deviceName = dev->name;
1060f7df2e56Smrg        if (dev->drv)
1061f7df2e56Smrg            driverName = dev->drv->driverName;
10629ace9065Smrg    }
1063f7df2e56Smrg
1064f7df2e56Smrg    LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName,
1065f7df2e56Smrg                      deviceName);
10669ace9065Smrg}
10679ace9065Smrg
10689ace9065Smrg/* Print input driver message, with verbose level specified directly */
10699ace9065Smrgvoid
1070f7df2e56Smrgxf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb,
1071f7df2e56Smrg                const char *format, ...)
10729ace9065Smrg{
10739ace9065Smrg    va_list ap;
10749ace9065Smrg
10759ace9065Smrg    va_start(ap, format);
10769ace9065Smrg    xf86VIDrvMsgVerb(dev, type, verb, format, ap);
10779ace9065Smrg    va_end(ap);
10789ace9065Smrg}
10799ace9065Smrg
10809ace9065Smrg/* Print input driver messages, with verbose level of 1 (default) */
10819ace9065Smrgvoid
10829ace9065Smrgxf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...)
10839ace9065Smrg{
10849ace9065Smrg    va_list ap;
10859ace9065Smrg
10869ace9065Smrg    va_start(ap, format);
10879ace9065Smrg    xf86VIDrvMsgVerb(dev, type, 1, format, ap);
10889ace9065Smrg    va_end(ap);
10899ace9065Smrg}
10909ace9065Smrg
109105b261ecSmrg/* Print non-driver messages with verbose level specified directly */
10926747b715Smrgvoid
109305b261ecSmrgxf86MsgVerb(MessageType type, int verb, const char *format, ...)
109405b261ecSmrg{
109505b261ecSmrg    va_list ap;
109605b261ecSmrg
109705b261ecSmrg    va_start(ap, format);
10989ace9065Smrg    LogVMessageVerb(type, verb, format, ap);
109905b261ecSmrg    va_end(ap);
110005b261ecSmrg}
110105b261ecSmrg
110205b261ecSmrg/* Print non-driver messages with verbose level of 1 (default) */
11036747b715Smrgvoid
110405b261ecSmrgxf86Msg(MessageType type, const char *format, ...)
110505b261ecSmrg{
110605b261ecSmrg    va_list ap;
110705b261ecSmrg
110805b261ecSmrg    va_start(ap, format);
11099ace9065Smrg    LogVMessageVerb(type, 1, format, ap);
111005b261ecSmrg    va_end(ap);
111105b261ecSmrg}
111205b261ecSmrg
111305b261ecSmrg/* Just like ErrorF, but with the verbose level checked */
11146747b715Smrgvoid
111505b261ecSmrgxf86ErrorFVerb(int verb, const char *format, ...)
111605b261ecSmrg{
111705b261ecSmrg    va_list ap;
111805b261ecSmrg
111905b261ecSmrg    va_start(ap, format);
112005b261ecSmrg    if (xf86Verbose >= verb || xf86LogVerbose >= verb)
1121f7df2e56Smrg        LogVWrite(verb, format, ap);
112205b261ecSmrg    va_end(ap);
112305b261ecSmrg}
112405b261ecSmrg
112505b261ecSmrg/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
11266747b715Smrgvoid
112705b261ecSmrgxf86ErrorF(const char *format, ...)
112805b261ecSmrg{
112905b261ecSmrg    va_list ap;
113005b261ecSmrg
113105b261ecSmrg    va_start(ap, format);
113205b261ecSmrg    if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
1133f7df2e56Smrg        LogVWrite(1, format, ap);
113405b261ecSmrg    va_end(ap);
113505b261ecSmrg}
113605b261ecSmrg
1137f7df2e56Smrg/* Note temporarily modifies the passed in buffer! */
1138f7df2e56Smrgstatic void xf86_mkdir_p(char *path)
1139f7df2e56Smrg{
1140f7df2e56Smrg    char *sep = path;
1141f7df2e56Smrg
1142f7df2e56Smrg    while ((sep = strchr(sep + 1, '/'))) {
1143f7df2e56Smrg        *sep = 0;
1144f7df2e56Smrg        (void)mkdir(path, 0777);
1145f7df2e56Smrg        *sep = '/';
1146f7df2e56Smrg    }
1147f7df2e56Smrg    (void)mkdir(path, 0777);
1148f7df2e56Smrg}
114905b261ecSmrg
115005b261ecSmrgvoid
11516747b715Smrgxf86LogInit(void)
115205b261ecSmrg{
1153f7df2e56Smrg    char *env, *lf = NULL;
1154f7df2e56Smrg    char buf[PATH_MAX];
115505b261ecSmrg
115605b261ecSmrg#define LOGSUFFIX ".log"
115705b261ecSmrg#define LOGOLDSUFFIX ".old"
115805b261ecSmrg
115905b261ecSmrg    /* Get the log file name */
116005b261ecSmrg    if (xf86LogFileFrom == X_DEFAULT) {
1161f7df2e56Smrg        /* When not running as root, we won't be able to write to /var/log */
1162f7df2e56Smrg        if (geteuid() != 0) {
1163f7df2e56Smrg            if ((env = getenv("XDG_DATA_HOME")))
1164f7df2e56Smrg                snprintf(buf, sizeof(buf), "%s/%s", env,
1165f7df2e56Smrg                         DEFAULT_XDG_DATA_HOME_LOGDIR);
1166f7df2e56Smrg            else if ((env = getenv("HOME")))
1167f7df2e56Smrg                snprintf(buf, sizeof(buf), "%s/%s/%s", env,
1168f7df2e56Smrg                         DEFAULT_XDG_DATA_HOME, DEFAULT_XDG_DATA_HOME_LOGDIR);
1169f7df2e56Smrg
1170f7df2e56Smrg            if (env) {
1171f7df2e56Smrg                xf86_mkdir_p(buf);
1172f7df2e56Smrg                strlcat(buf, "/" DEFAULT_LOGPREFIX, sizeof(buf));
1173f7df2e56Smrg                xf86LogFile = buf;
1174f7df2e56Smrg            }
1175f7df2e56Smrg        }
1176f7df2e56Smrg        /* Append the display number and ".log" */
1177f7df2e56Smrg        if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1)
1178f7df2e56Smrg            FatalError("Cannot allocate space for the log file name\n");
1179f7df2e56Smrg        xf86LogFile = lf;
118005b261ecSmrg    }
118105b261ecSmrg
118205b261ecSmrg    xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
118305b261ecSmrg    xf86LogFileWasOpened = TRUE;
118405b261ecSmrg
118505b261ecSmrg    xf86SetVerbosity(xf86Verbose);
118605b261ecSmrg    xf86SetLogVerbosity(xf86LogVerbose);
118705b261ecSmrg
118805b261ecSmrg#undef LOGSUFFIX
118905b261ecSmrg#undef LOGOLDSUFFIX
11904642e01fSmrg
11914642e01fSmrg    free(lf);
119205b261ecSmrg}
119305b261ecSmrg
119405b261ecSmrgvoid
1195f7df2e56Smrgxf86CloseLog(enum ExitCode error)
119605b261ecSmrg{
1197f7df2e56Smrg    LogClose(error);
119805b261ecSmrg}
119905b261ecSmrg
120005b261ecSmrg/*
120105b261ecSmrg * Drivers can use these for using their own SymTabRecs.
120205b261ecSmrg */
120305b261ecSmrg
12046747b715Smrgconst char *
120505b261ecSmrgxf86TokenToString(SymTabPtr table, int token)
120605b261ecSmrg{
120705b261ecSmrg    int i;
120805b261ecSmrg
1209f7df2e56Smrg    for (i = 0; table[i].token >= 0 && table[i].token != token; i++);
121005b261ecSmrg
121105b261ecSmrg    if (table[i].token < 0)
1212f7df2e56Smrg        return NULL;
121305b261ecSmrg    else
1214f7df2e56Smrg        return table[i].name;
121505b261ecSmrg}
121605b261ecSmrg
12176747b715Smrgint
121805b261ecSmrgxf86StringToToken(SymTabPtr table, const char *string)
121905b261ecSmrg{
122005b261ecSmrg    int i;
122105b261ecSmrg
122205b261ecSmrg    if (string == NULL)
1223f7df2e56Smrg        return -1;
122405b261ecSmrg
1225f7df2e56Smrg    for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++);
122605b261ecSmrg
12276747b715Smrg    return table[i].token;
122805b261ecSmrg}
122905b261ecSmrg
123005b261ecSmrg/*
123105b261ecSmrg * helper to display the clocks found on a card
123205b261ecSmrg */
12336747b715Smrgvoid
123405b261ecSmrgxf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
123505b261ecSmrg{
123605b261ecSmrg    int j;
123705b261ecSmrg
123805b261ecSmrg    xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
1239f7df2e56Smrg    for (j = 0; j < scrp->numClocks; j++) {
1240f7df2e56Smrg        if ((j % 4) == 0) {
1241f7df2e56Smrg            xf86ErrorF("\n");
1242f7df2e56Smrg            xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
1243f7df2e56Smrg        }
1244f7df2e56Smrg        xf86ErrorF(" %7.3f", (double) scrp->clock[j] / 1000.0);
124505b261ecSmrg    }
124605b261ecSmrg    xf86ErrorF("\n");
124705b261ecSmrg}
124805b261ecSmrg
124905b261ecSmrg/*
125005b261ecSmrg * This prints out the driver identify message, including the names of
125105b261ecSmrg * the supported chipsets.
125205b261ecSmrg *
125305b261ecSmrg * XXX This makes assumptions about the line width, etc.  Maybe we could
125405b261ecSmrg * use a more general "pretty print" function for messages.
125505b261ecSmrg */
12566747b715Smrgvoid
125705b261ecSmrgxf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
125805b261ecSmrg{
125905b261ecSmrg    int len, i;
126005b261ecSmrg
126105b261ecSmrg    len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
126205b261ecSmrg    xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
126305b261ecSmrg    for (i = 0; chips[i].name != NULL; i++) {
1264f7df2e56Smrg        if (i != 0) {
1265f7df2e56Smrg            xf86ErrorF(",");
1266f7df2e56Smrg            len++;
1267f7df2e56Smrg        }
1268f7df2e56Smrg        if (len + 2 + strlen(chips[i].name) < 78) {
1269f7df2e56Smrg            xf86ErrorF(" ");
1270f7df2e56Smrg            len++;
1271f7df2e56Smrg        }
1272f7df2e56Smrg        else {
1273f7df2e56Smrg            xf86ErrorF("\n\t");
1274f7df2e56Smrg            len = 8;
1275f7df2e56Smrg        }
1276f7df2e56Smrg        xf86ErrorF("%s", chips[i].name);
1277f7df2e56Smrg        len += strlen(chips[i].name);
127805b261ecSmrg    }
127905b261ecSmrg    xf86ErrorF("\n");
128005b261ecSmrg}
128105b261ecSmrg
12826747b715Smrgint
1283f7df2e56Smrgxf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
128405b261ecSmrg{
1285f7df2e56Smrg    GDevPtr gdp, *pgdp = NULL;
128605b261ecSmrg    confScreenPtr screensecptr;
1287f7df2e56Smrg    int i, j, k;
128805b261ecSmrg
128905b261ecSmrg    if (sectlist)
1290f7df2e56Smrg        *sectlist = NULL;
129105b261ecSmrg
1292d77c0cdcSjmcneill    /*
1293d77c0cdcSjmcneill     * 20111009 jmcneill: This line was removed with the following commit upstream:
1294d77c0cdcSjmcneill     *  http://cgit.freedesktop.org/xorg/xserver/commit/hw/xfree86/common/xf86Helper.c?id=0ceac6f64f5ad9bc2ac4b19be2dd245ffba78b05
1295d77c0cdcSjmcneill     *
1296d77c0cdcSjmcneill     * However, the log message is inaccurate: xf86MatchDevice will get called at
1297d77c0cdcSjmcneill     * configuration time by drivers who still implement the legacy probing
1298d77c0cdcSjmcneill     * API.
1299d77c0cdcSjmcneill     */
1300d77c0cdcSjmcneill    if (xf86DoConfigure && xf86DoConfigurePass1) return 1;
1301d77c0cdcSjmcneill
13026747b715Smrg    /*
13036747b715Smrg     * This can happen when running Xorg -showopts and a module like ati
13046747b715Smrg     * or vmware tries to load its submodules when xf86ConfigLayout is empty
13056747b715Smrg     */
13066747b715Smrg    if (!xf86ConfigLayout.screens)
1307f7df2e56Smrg        return 0;
130805b261ecSmrg
130905b261ecSmrg    /*
131005b261ecSmrg     * This is a very important function that matches the device sections
131105b261ecSmrg     * as they show up in the config file with the drivers that the server
131205b261ecSmrg     * loads at run time.
131305b261ecSmrg     *
131405b261ecSmrg     * ChipProbe can call
131505b261ecSmrg     * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
131605b261ecSmrg     * with its driver name. The function allocates an array of GDevPtr and
131705b261ecSmrg     * returns this via sectlist and returns the number of elements in
131805b261ecSmrg     * this list as return value. 0 means none found, -1 means fatal error.
131905b261ecSmrg     *
132005b261ecSmrg     * It can figure out which of the Device sections to use for which card
132105b261ecSmrg     * (using things like the Card statement, etc). For single headed servers
132205b261ecSmrg     * there will of course be just one such Device section.
132305b261ecSmrg     */
132405b261ecSmrg    i = 0;
132505b261ecSmrg
132605b261ecSmrg    /*
132705b261ecSmrg     * first we need to loop over all the Screens sections to get to all
132805b261ecSmrg     * 'active' device sections
132905b261ecSmrg     */
1330f7df2e56Smrg    for (j = 0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
133105b261ecSmrg        screensecptr = xf86ConfigLayout.screens[j].screen;
13322f76b07dSmrg        if ((screensecptr->device != NULL)
13332f76b07dSmrg            && (screensecptr->device->driver != NULL)
1334f7df2e56Smrg            && (xf86NameCmp(screensecptr->device->driver, drivername) == 0)
1335f7df2e56Smrg            && (!screensecptr->device->claimed)) {
133605b261ecSmrg            /*
133705b261ecSmrg             * we have a matching driver that wasn't claimed, yet
133805b261ecSmrg             */
1339f7df2e56Smrg            pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
134005b261ecSmrg            pgdp[i++] = screensecptr->device;
134105b261ecSmrg        }
1342f7df2e56Smrg        for (k = 0; k < screensecptr->num_gpu_devices; k++) {
1343f7df2e56Smrg            if ((screensecptr->gpu_devices[k]->driver != NULL)
1344f7df2e56Smrg            && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0)
1345f7df2e56Smrg                && (!screensecptr->gpu_devices[k]->claimed)) {
1346f7df2e56Smrg                /*
1347f7df2e56Smrg                 * we have a matching driver that wasn't claimed, yet
1348f7df2e56Smrg                 */
1349f7df2e56Smrg                pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
1350f7df2e56Smrg                pgdp[i++] = screensecptr->gpu_devices[k];
1351f7df2e56Smrg            }
1352f7df2e56Smrg        }
135305b261ecSmrg    }
135405b261ecSmrg
135505b261ecSmrg    /* Then handle the inactive devices */
135605b261ecSmrg    j = 0;
135705b261ecSmrg    while (xf86ConfigLayout.inactives[j].identifier) {
1358f7df2e56Smrg        gdp = &xf86ConfigLayout.inactives[j];
1359f7df2e56Smrg        if (gdp->driver && !gdp->claimed &&
1360f7df2e56Smrg            !xf86NameCmp(gdp->driver, drivername)) {
1361f7df2e56Smrg            /* we have a matching driver that wasn't claimed yet */
1362f7df2e56Smrg            pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
1363f7df2e56Smrg            pgdp[i++] = gdp;
1364f7df2e56Smrg        }
1365f7df2e56Smrg        j++;
136605b261ecSmrg    }
136705b261ecSmrg
136805b261ecSmrg    /*
136905b261ecSmrg     * make the array NULL terminated and return its address
137005b261ecSmrg     */
137105b261ecSmrg    if (i)
137205b261ecSmrg        pgdp[i] = NULL;
137305b261ecSmrg
137405b261ecSmrg    if (sectlist)
1375f7df2e56Smrg        *sectlist = pgdp;
137605b261ecSmrg    else
1377f7df2e56Smrg        free(pgdp);
137805b261ecSmrg    return i;
137905b261ecSmrg}
138005b261ecSmrg
13816747b715Smrgconst char *
138205b261ecSmrgxf86GetVisualName(int visual)
138305b261ecSmrg{
138405b261ecSmrg    if (visual < 0 || visual > DirectColor)
1385f7df2e56Smrg        return NULL;
138605b261ecSmrg
138705b261ecSmrg    return xf86VisualNames[visual];
138805b261ecSmrg}
138905b261ecSmrg
13906747b715Smrgint
13916747b715Smrgxf86GetVerbosity(void)
139205b261ecSmrg{
139305b261ecSmrg    return max(xf86Verbose, xf86LogVerbose);
139405b261ecSmrg}
139505b261ecSmrg
13966747b715Smrgint
13976747b715Smrgxf86GetDepth(void)
139805b261ecSmrg{
139905b261ecSmrg    return xf86Depth;
140005b261ecSmrg}
140105b261ecSmrg
14026747b715Smrgrgb
14036747b715Smrgxf86GetWeight(void)
140405b261ecSmrg{
140505b261ecSmrg    return xf86Weight;
140605b261ecSmrg}
140705b261ecSmrg
14086747b715SmrgGamma
14096747b715Smrgxf86GetGamma(void)
141005b261ecSmrg{
141105b261ecSmrg    return xf86Gamma;
141205b261ecSmrg}
141305b261ecSmrg
14149b06bd19StsutsuiBool
14159b06bd19Stsutsuixf86GetFlipPixels(void)
14169b06bd19Stsutsui{
14179b06bd19Stsutsui    return xf86FlipPixels;
14189b06bd19Stsutsui}
14199b06bd19Stsutsui
14206747b715SmrgBool
14216747b715Smrgxf86ServerIsExiting(void)
142205b261ecSmrg{
142305b261ecSmrg    return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
142405b261ecSmrg}
142505b261ecSmrg
14266747b715SmrgBool
14276747b715Smrgxf86ServerIsResetting(void)
142805b261ecSmrg{
142905b261ecSmrg    return xf86Resetting;
143005b261ecSmrg}
143105b261ecSmrg
14326747b715SmrgBool
143305b261ecSmrgxf86ServerIsOnlyDetecting(void)
143405b261ecSmrg{
14356747b715Smrg    return xf86DoConfigure;
143605b261ecSmrg}
143705b261ecSmrg
14386747b715SmrgBool
14396747b715Smrgxf86GetVidModeAllowNonLocal(void)
144005b261ecSmrg{
144105b261ecSmrg    return xf86Info.vidModeAllowNonLocal;
144205b261ecSmrg}
144305b261ecSmrg
14446747b715SmrgBool
14456747b715Smrgxf86GetVidModeEnabled(void)
144605b261ecSmrg{
144705b261ecSmrg    return xf86Info.vidModeEnabled;
144805b261ecSmrg}
144905b261ecSmrg
14506747b715SmrgBool
14516747b715Smrgxf86GetModInDevAllowNonLocal(void)
145205b261ecSmrg{
145305b261ecSmrg    return xf86Info.miscModInDevAllowNonLocal;
145405b261ecSmrg}
145505b261ecSmrg
14566747b715SmrgBool
14576747b715Smrgxf86GetModInDevEnabled(void)
145805b261ecSmrg{
145905b261ecSmrg    return xf86Info.miscModInDevEnabled;
146005b261ecSmrg}
146105b261ecSmrg
14626747b715SmrgBool
14636747b715Smrgxf86GetAllowMouseOpenFail(void)
146405b261ecSmrg{
146505b261ecSmrg    return xf86Info.allowMouseOpenFail;
146605b261ecSmrg}
146705b261ecSmrg
14686747b715SmrgCARD32
1469f7df2e56Smrgxf86GetModuleVersion(void *module)
147005b261ecSmrg{
1471f7df2e56Smrg    return (CARD32) LoaderGetModuleVersion(module);
147205b261ecSmrg}
147305b261ecSmrg
1474f7df2e56Smrgvoid *
147505b261ecSmrgxf86LoadDrvSubModule(DriverPtr drv, const char *name)
147605b261ecSmrg{
1477f7df2e56Smrg    void *ret;
147805b261ecSmrg    int errmaj = 0, errmin = 0;
147905b261ecSmrg
148005b261ecSmrg    ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
1481f7df2e56Smrg                        &errmaj, &errmin);
148205b261ecSmrg    if (!ret)
1483f7df2e56Smrg        LoaderErrorMsg(NULL, name, errmaj, errmin);
148405b261ecSmrg    return ret;
148505b261ecSmrg}
148605b261ecSmrg
1487f7df2e56Smrgvoid *
148805b261ecSmrgxf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
148905b261ecSmrg{
1490f7df2e56Smrg    void *ret;
149105b261ecSmrg    int errmaj = 0, errmin = 0;
149205b261ecSmrg
149305b261ecSmrg    ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
1494f7df2e56Smrg                        &errmaj, &errmin);
149505b261ecSmrg    if (!ret)
1496f7df2e56Smrg        LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
149705b261ecSmrg    return ret;
149805b261ecSmrg}
149905b261ecSmrg
150005b261ecSmrg/*
150105b261ecSmrg * xf86LoadOneModule loads a single module.
150205b261ecSmrg */
1503f7df2e56Smrgvoid *
1504f7df2e56Smrgxf86LoadOneModule(const char *name, void *opt)
150505b261ecSmrg{
15067e31ba66Smrg    int errmaj;
150705b261ecSmrg    char *Name;
1508f7df2e56Smrg    void *mod;
150905b261ecSmrg
151005b261ecSmrg    if (!name)
1511f7df2e56Smrg        return NULL;
151205b261ecSmrg
151305b261ecSmrg    /* Normalise the module name */
151405b261ecSmrg    Name = xf86NormalizeName(name);
151505b261ecSmrg
151605b261ecSmrg    /* Skip empty names */
151705b261ecSmrg    if (Name == NULL)
1518f7df2e56Smrg        return NULL;
151905b261ecSmrg    if (*Name == '\0') {
1520f7df2e56Smrg        free(Name);
1521f7df2e56Smrg        return NULL;
152205b261ecSmrg    }
152305b261ecSmrg
15247e31ba66Smrg    mod = LoadModule(Name, opt, NULL, &errmaj);
152505b261ecSmrg    if (!mod)
15267e31ba66Smrg        LoaderErrorMsg(NULL, Name, errmaj, 0);
15276747b715Smrg    free(Name);
152805b261ecSmrg    return mod;
152905b261ecSmrg}
153005b261ecSmrg
15316747b715Smrgvoid
1532f7df2e56Smrgxf86UnloadSubModule(void *mod)
153305b261ecSmrg{
153405b261ecSmrg    UnloadSubModule(mod);
153505b261ecSmrg}
153605b261ecSmrg
15376747b715SmrgBool
153805b261ecSmrgxf86LoaderCheckSymbol(const char *name)
153905b261ecSmrg{
154005b261ecSmrg    return LoaderSymbol(name) != NULL;
154105b261ecSmrg}
154205b261ecSmrg
154305b261ecSmrgtypedef enum {
1544f7df2e56Smrg    OPTION_BACKING_STORE
154505b261ecSmrg} BSOpts;
154605b261ecSmrg
154705b261ecSmrgstatic const OptionInfoRec BSOptions[] = {
1548f7df2e56Smrg    {OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE},
1549f7df2e56Smrg    {-1, NULL, OPTV_NONE, {0}, FALSE}
155005b261ecSmrg};
155105b261ecSmrg
15526747b715Smrgvoid
155305b261ecSmrgxf86SetBackingStore(ScreenPtr pScreen)
155405b261ecSmrg{
155505b261ecSmrg    Bool useBS = FALSE;
155605b261ecSmrg    MessageType from = X_DEFAULT;
1557f7df2e56Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
155805b261ecSmrg    OptionInfoPtr options;
155905b261ecSmrg
156005b261ecSmrg    options = xnfalloc(sizeof(BSOptions));
1561f7df2e56Smrg    (void) memcpy(options, BSOptions, sizeof(BSOptions));
156205b261ecSmrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
156305b261ecSmrg
156405b261ecSmrg    /* check for commandline option here */
156505b261ecSmrg    if (xf86bsEnableFlag) {
1566f7df2e56Smrg        from = X_CMDLINE;
1567f7df2e56Smrg        useBS = TRUE;
1568f7df2e56Smrg    }
1569f7df2e56Smrg    else if (xf86bsDisableFlag) {
1570f7df2e56Smrg        from = X_CMDLINE;
1571f7df2e56Smrg        useBS = FALSE;
1572f7df2e56Smrg    }
1573f7df2e56Smrg    else {
1574f7df2e56Smrg        if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
1575f7df2e56Smrg            from = X_CONFIG;
1576f7df2e56Smrg#ifdef COMPOSITE
1577f7df2e56Smrg        if (from != X_CONFIG)
1578f7df2e56Smrg            useBS = xf86ReturnOptValBool(options, OPTION_BACKING_STORE,
1579f7df2e56Smrg                                         !noCompositeExtension);
1580f7df2e56Smrg#endif
158105b261ecSmrg    }
15826747b715Smrg    free(options);
1583f7df2e56Smrg    pScreen->backingStoreSupport = useBS ? WhenMapped : NotUseful;
158405b261ecSmrg    if (serverGeneration == 1)
1585f7df2e56Smrg        xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
1586f7df2e56Smrg                   useBS ? "enabled" : "disabled");
158705b261ecSmrg}
158805b261ecSmrg
158905b261ecSmrgtypedef enum {
1590f7df2e56Smrg    OPTION_SILKEN_MOUSE
159105b261ecSmrg} SMOpts;
159205b261ecSmrg
159305b261ecSmrgstatic const OptionInfoRec SMOptions[] = {
1594f7df2e56Smrg    {OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE},
1595f7df2e56Smrg    {-1, NULL, OPTV_NONE, {0}, FALSE}
159605b261ecSmrg};
159705b261ecSmrg
15986747b715Smrgvoid
1599f7df2e56Smrgxf86SetSilkenMouse(ScreenPtr pScreen)
160005b261ecSmrg{
160105b261ecSmrg    Bool useSM = TRUE;
160205b261ecSmrg    MessageType from = X_DEFAULT;
1603f7df2e56Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
160405b261ecSmrg    OptionInfoPtr options;
160505b261ecSmrg
160605b261ecSmrg    options = xnfalloc(sizeof(SMOptions));
1607f7df2e56Smrg    (void) memcpy(options, SMOptions, sizeof(SMOptions));
160805b261ecSmrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
160905b261ecSmrg
161005b261ecSmrg    /* check for commandline option here */
161105b261ecSmrg    /* disable if screen shares resources */
1612f7df2e56Smrg    /* TODO VGA arb disable silken mouse */
16136747b715Smrg    if (xf86silkenMouseDisableFlag) {
161405b261ecSmrg        from = X_CMDLINE;
1615f7df2e56Smrg        useSM = FALSE;
1616f7df2e56Smrg    }
1617f7df2e56Smrg    else {
1618f7df2e56Smrg        if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
1619f7df2e56Smrg            from = X_CONFIG;
162005b261ecSmrg    }
16216747b715Smrg    free(options);
162205b261ecSmrg    /*
16237e31ba66Smrg     * Use silken mouse if requested and if we have threaded input
162405b261ecSmrg     */
16257e31ba66Smrg    pScrn->silkenMouse = useSM && InputThreadEnable;
162605b261ecSmrg    if (serverGeneration == 1)
1627f7df2e56Smrg        xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
1628f7df2e56Smrg                   pScrn->silkenMouse ? "enabled" : "disabled");
162905b261ecSmrg}
163005b261ecSmrg
163105b261ecSmrg/* Wrote this function for the PM2 Xv driver, preliminary. */
163205b261ecSmrg
1633f7df2e56Smrgvoid *
1634f7df2e56Smrgxf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name,
1635f7df2e56Smrg                  const char **adaptor_name, void **adaptor_options)
163605b261ecSmrg{
163705b261ecSmrg    confXvAdaptorPtr adaptor;
163805b261ecSmrg    int i;
163905b261ecSmrg
164005b261ecSmrg    if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
1641f7df2e56Smrg        if (adaptor_name)
1642f7df2e56Smrg            *adaptor_name = NULL;
1643f7df2e56Smrg        if (adaptor_options)
1644f7df2e56Smrg            *adaptor_options = NULL;
1645f7df2e56Smrg        return NULL;
164605b261ecSmrg    }
164705b261ecSmrg
164805b261ecSmrg    adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
1649f7df2e56Smrg    if (adaptor_name)
1650f7df2e56Smrg        *adaptor_name = adaptor->identifier;
1651f7df2e56Smrg    if (adaptor_options)
1652f7df2e56Smrg        *adaptor_options = adaptor->options;
165305b261ecSmrg
165405b261ecSmrg    for (i = 0; i < adaptor->numports; i++)
1655f7df2e56Smrg        if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
1656f7df2e56Smrg            return adaptor->ports[i].options;
165705b261ecSmrg
165805b261ecSmrg    return NULL;
165905b261ecSmrg}
166005b261ecSmrg
16616747b715Smrgstatic void
16626747b715Smrgxf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
1663f7df2e56Smrg                           EntityProc enter, EntityProc leave, void *private)
166405b261ecSmrg{
16656747b715Smrg    ScrnInfoPtr pScrn;
166605b261ecSmrg
16676747b715Smrg    if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
1668f7df2e56Smrg        xf86RemoveEntityFromScreen(pScrn, pEnt->index);
166905b261ecSmrg}
167005b261ecSmrg
16716747b715SmrgScrnInfoPtr
167205b261ecSmrgxf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
1673f7df2e56Smrg                   EntityProc init, EntityProc enter, EntityProc leave,
1674f7df2e56Smrg                   void *private)
167505b261ecSmrg{
167605b261ecSmrg    EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
1677f7df2e56Smrg
16787e31ba66Smrg    if (init || enter || leave)
16797e31ba66Smrg        FatalError("Legacy entity access functions are unsupported\n");
16807e31ba66Smrg
1681f7df2e56Smrg    if (!pEnt)
1682f7df2e56Smrg        return pScrn;
168305b261ecSmrg
168405b261ecSmrg    if (!(pEnt->location.type == BUS_NONE)) {
1685f7df2e56Smrg        free(pEnt);
1686f7df2e56Smrg        return pScrn;
168705b261ecSmrg    }
168805b261ecSmrg
168905b261ecSmrg    if (!pEnt->active) {
1690f7df2e56Smrg        xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
1691f7df2e56Smrg        free(pEnt);
1692f7df2e56Smrg        return pScrn;
169305b261ecSmrg    }
169405b261ecSmrg
169505b261ecSmrg    if (!pScrn)
1696f7df2e56Smrg        pScrn = xf86AllocateScreen(pEnt->driver, scrnFlag);
1697f7df2e56Smrg    xf86AddEntityToScreen(pScrn, entityIndex);
169805b261ecSmrg
16999ace9065Smrg    free(pEnt);
170005b261ecSmrg    return pScrn;
170105b261ecSmrg}
170205b261ecSmrg
17036747b715SmrgBool
1704f7df2e56Smrgxf86IsScreenPrimary(ScrnInfoPtr pScrn)
170505b261ecSmrg{
170605b261ecSmrg    int i;
170705b261ecSmrg
1708f7df2e56Smrg    for (i = 0; i < pScrn->numEntities; i++) {
1709f7df2e56Smrg        if (xf86IsEntityPrimary(i))
1710f7df2e56Smrg            return TRUE;
171105b261ecSmrg    }
171205b261ecSmrg    return FALSE;
171305b261ecSmrg}
171405b261ecSmrg
17156747b715SmrgBool
171605b261ecSmrgxf86IsUnblank(int mode)
171705b261ecSmrg{
1718f7df2e56Smrg    switch (mode) {
171905b261ecSmrg    case SCREEN_SAVER_OFF:
172005b261ecSmrg    case SCREEN_SAVER_FORCER:
1721f7df2e56Smrg        return TRUE;
172205b261ecSmrg    case SCREEN_SAVER_ON:
172305b261ecSmrg    case SCREEN_SAVER_CYCLE:
1724f7df2e56Smrg        return FALSE;
172505b261ecSmrg    default:
1726f7df2e56Smrg        xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
1727f7df2e56Smrg        return TRUE;
172805b261ecSmrg    }
172905b261ecSmrg}
173005b261ecSmrg
17316747b715Smrgvoid
17329ace9065Smrgxf86MotionHistoryAllocate(InputInfoPtr pInfo)
173305b261ecSmrg{
17349ace9065Smrg    AllocateMotionHistory(pInfo->dev);
173505b261ecSmrg}
1736f7df2e56Smrg
1737f7df2e56SmrgScrnInfoPtr
1738f7df2e56Smrgxf86ScreenToScrn(ScreenPtr pScreen)
1739f7df2e56Smrg{
1740f7df2e56Smrg    if (pScreen->isGPU) {
1741f7df2e56Smrg        assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens);
1742f7df2e56Smrg        return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET];
1743f7df2e56Smrg    } else {
1744f7df2e56Smrg        assert(pScreen->myNum < xf86NumScreens);
1745f7df2e56Smrg        return xf86Screens[pScreen->myNum];
1746f7df2e56Smrg    }
1747f7df2e56Smrg}
1748f7df2e56Smrg
1749f7df2e56SmrgScreenPtr
1750f7df2e56Smrgxf86ScrnToScreen(ScrnInfoPtr pScrn)
1751f7df2e56Smrg{
1752f7df2e56Smrg    if (pScrn->is_gpu) {
1753f7df2e56Smrg        assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens);
1754f7df2e56Smrg        return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET];
1755f7df2e56Smrg    } else {
1756f7df2e56Smrg        assert(pScrn->scrnIndex < screenInfo.numScreens);
1757f7df2e56Smrg        return screenInfo.screens[pScrn->scrnIndex];
1758f7df2e56Smrg    }
1759f7df2e56Smrg}
1760f7df2e56Smrg
1761f7df2e56Smrgvoid
1762f7df2e56Smrgxf86UpdateDesktopDimensions(void)
1763f7df2e56Smrg{
1764f7df2e56Smrg    update_desktop_dimensions();
1765f7df2e56Smrg}
17665a112b11Smrg
17675a112b11Smrg
17685a112b11Smrgvoid
17695a112b11Smrgxf86AddInputEventDrainCallback(CallbackProcPtr callback, void *param)
17705a112b11Smrg{
17715a112b11Smrg    mieqAddCallbackOnDrained(callback, param);
17725a112b11Smrg}
17735a112b11Smrg
17745a112b11Smrgvoid
17755a112b11Smrgxf86RemoveInputEventDrainCallback(CallbackProcPtr callback, void *param)
17765a112b11Smrg{
17775a112b11Smrg    mieqRemoveCallbackOnDrained(callback, param);
17785a112b11Smrg}
1779