xenocara/xserver/hw/xfree86/common/xf86Helper.c

1939 lines
55 KiB
C
Raw Normal View History

2006-11-26 11:13:41 -07:00
/*
* Copyright (c) 1997-2003 by The XFree86 Project, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
/*
* Authors: Dirk Hohndel <hohndel@XFree86.Org>
* David Dawes <dawes@XFree86.Org>
* ... and others
*
* This file includes the helper functions that the server provides for
* different drivers.
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#include <X11/X.h>
#include "os.h"
#include "servermd.h"
#include "pixmapstr.h"
#include "windowstr.h"
#include "propertyst.h"
#include "gcstruct.h"
#include "loaderProcs.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "micmap.h"
#include "xf86DDC.h"
#include "xf86Xinput.h"
#include "xf86InPriv.h"
#include "mivalidate.h"
#include "xf86Crtc.h"
2006-11-26 11:13:41 -07:00
/* For xf86GetClocks */
#if defined(CSRG_BASED) || defined(__GNU__)
#define HAS_SETPRIORITY
#include <sys/resource.h>
#endif
static int xf86ScrnInfoPrivateCount = 0;
/* Add a pointer to a new DriverRec to xf86DriverList */
void
xf86AddDriver(DriverPtr driver, void *module, int flags)
2006-11-26 11:13:41 -07:00
{
/* Don't add null entries */
if (!driver)
return;
2006-11-26 11:13:41 -07:00
if (xf86DriverList == NULL)
xf86NumDrivers = 0;
2006-11-26 11:13:41 -07:00
xf86NumDrivers++;
xf86DriverList = xnfrealloc(xf86DriverList,
xf86NumDrivers * sizeof(DriverPtr));
2006-11-26 11:13:41 -07:00
xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
if (flags & HaveDriverFuncs)
*xf86DriverList[xf86NumDrivers - 1] = *driver;
2006-11-26 11:13:41 -07:00
else {
(void) memset(xf86DriverList[xf86NumDrivers - 1], 0, sizeof(DriverRec));
(void) memcpy(xf86DriverList[xf86NumDrivers - 1], driver,
sizeof(DriverRec1));
2006-11-26 11:13:41 -07:00
}
xf86DriverList[xf86NumDrivers - 1]->module = module;
xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
}
void
2006-11-26 11:13:41 -07:00
xf86DeleteDriver(int drvIndex)
{
if (xf86DriverList[drvIndex]
&& (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
if (xf86DriverList[drvIndex]->module)
UnloadModule(xf86DriverList[drvIndex]->module);
free(xf86DriverList[drvIndex]);
xf86DriverList[drvIndex] = NULL;
2006-11-26 11:13:41 -07:00
}
}
/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
void
xf86AddInputDriver(InputDriverPtr driver, void *module, int flags)
2006-11-26 11:13:41 -07:00
{
/* Don't add null entries */
if (!driver)
return;
2006-11-26 11:13:41 -07:00
if (xf86InputDriverList == NULL)
xf86NumInputDrivers = 0;
2006-11-26 11:13:41 -07:00
xf86NumInputDrivers++;
xf86InputDriverList = xnfrealloc(xf86InputDriverList,
xf86NumInputDrivers *
sizeof(InputDriverPtr));
2006-11-26 11:13:41 -07:00
xf86InputDriverList[xf86NumInputDrivers - 1] =
xnfalloc(sizeof(InputDriverRec));
2006-11-26 11:13:41 -07:00
*xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
}
void
xf86DeleteInputDriver(int drvIndex)
{
if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
UnloadModule(xf86InputDriverList[drvIndex]->module);
free(xf86InputDriverList[drvIndex]);
2006-11-26 11:13:41 -07:00
xf86InputDriverList[drvIndex] = NULL;
}
2007-11-24 10:55:21 -07:00
InputDriverPtr
xf86LookupInputDriver(const char *name)
{
int i;
for (i = 0; i < xf86NumInputDrivers; i++) {
if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
return xf86InputDriverList[i];
2007-11-24 10:55:21 -07:00
}
return NULL;
}
InputInfoPtr
xf86LookupInput(const char *name)
{
InputInfoPtr p;
for (p = xf86InputDevs; p != NULL; p = p->next) {
if (strcmp(name, p->name) == 0)
return p;
}
return NULL;
}
2006-11-26 11:13:41 -07:00
/* Allocate a new ScrnInfoRec in xf86Screens */
ScrnInfoPtr
2006-11-26 11:13:41 -07:00
xf86AllocateScreen(DriverPtr drv, int flags)
{
int i;
ScrnInfoPtr pScrn;
2006-11-26 11:13:41 -07:00
if (flags & XF86_ALLOCATE_GPU_SCREEN) {
if (xf86GPUScreens == NULL)
xf86NumGPUScreens = 0;
i = xf86NumGPUScreens++;
xf86GPUScreens = xnfrealloc(xf86GPUScreens, xf86NumGPUScreens * sizeof(ScrnInfoPtr));
xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86GPUScreens[i];
pScrn->scrnIndex = i + GPU_SCREEN_OFFSET; /* Changes when a screen is removed */
pScrn->is_gpu = TRUE;
} else {
if (xf86Screens == NULL)
xf86NumScreens = 0;
i = xf86NumScreens++;
xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
pScrn = xf86Screens[i];
pScrn->scrnIndex = i; /* Changes when a screen is removed */
}
pScrn->origIndex = pScrn->scrnIndex; /* This never changes */
pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount);
2006-11-26 11:13:41 -07:00
/*
* EnableDisableFBAccess now gets initialized in InitOutput()
* pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess;
2006-11-26 11:13:41 -07:00
*/
pScrn->drv = drv;
2006-11-26 11:13:41 -07:00
drv->refCount++;
pScrn->module = DuplicateModule(drv->module, NULL);
2006-11-26 11:13:41 -07:00
pScrn->DriverFunc = drv->driverFunc;
2007-11-24 10:55:21 -07:00
return pScrn;
2006-11-26 11:13:41 -07:00
}
/*
* Remove an entry from xf86Screens. Ideally it should free all allocated
* data. To do this properly may require a driver hook.
*/
void
xf86DeleteScreen(ScrnInfoPtr pScrn)
2006-11-26 11:13:41 -07:00
{
int i;
int scrnIndex;
Bool is_gpu = FALSE;
if (!pScrn)
return;
if (pScrn->is_gpu) {
/* First check if the screen is valid */
if (xf86NumGPUScreens == 0 || xf86GPUScreens == NULL)
return;
is_gpu = TRUE;
} else {
/* First check if the screen is valid */
if (xf86NumScreens == 0 || xf86Screens == NULL)
return;
}
2006-11-26 11:13:41 -07:00
scrnIndex = pScrn->scrnIndex;
2006-11-26 11:13:41 -07:00
/* If a FreeScreen function is defined, call it here */
if (pScrn->FreeScreen != NULL)
pScrn->FreeScreen(pScrn);
2006-11-26 11:13:41 -07:00
while (pScrn->modes)
xf86DeleteMode(&pScrn->modes, pScrn->modes);
2006-11-26 11:13:41 -07:00
while (pScrn->modePool)
xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
2006-11-26 11:13:41 -07:00
xf86OptionListFree(pScrn->options);
if (pScrn->module)
UnloadModule(pScrn->module);
2006-11-26 11:13:41 -07:00
if (pScrn->drv)
pScrn->drv->refCount--;
2006-11-26 11:13:41 -07:00
free(pScrn->privates);
2006-11-26 11:13:41 -07:00
xf86ClearEntityListForScreen(pScrn);
2006-11-26 11:13:41 -07:00
free(pScrn);
2006-11-26 11:13:41 -07:00
/* Move the other entries down, updating their scrnIndex fields */
2007-11-24 10:55:21 -07:00
if (is_gpu) {
xf86NumGPUScreens--;
scrnIndex -= GPU_SCREEN_OFFSET;
for (i = scrnIndex; i < xf86NumGPUScreens; i++) {
xf86GPUScreens[i] = xf86GPUScreens[i + 1];
xf86GPUScreens[i]->scrnIndex = i + GPU_SCREEN_OFFSET;
/* Also need to take care of the screen layout settings */
}
}
else {
xf86NumScreens--;
2006-11-26 11:13:41 -07:00
for (i = scrnIndex; i < xf86NumScreens; i++) {
xf86Screens[i] = xf86Screens[i + 1];
xf86Screens[i]->scrnIndex = i;
/* Also need to take care of the screen layout settings */
}
2006-11-26 11:13:41 -07:00
}
}
/*
* Allocate a private in ScrnInfoRec.
*/
int
2006-11-26 11:13:41 -07:00
xf86AllocateScrnInfoPrivateIndex(void)
{
int idx, i;
ScrnInfoPtr pScr;
DevUnion *nprivs;
idx = xf86ScrnInfoPrivateCount++;
for (i = 0; i < xf86NumScreens; i++) {
pScr = xf86Screens[i];
nprivs = xnfrealloc(pScr->privates,
xf86ScrnInfoPrivateCount * sizeof(DevUnion));
/* Zero the new private */
memset(&nprivs[idx], 0, sizeof(DevUnion));
pScr->privates = nprivs;
2006-11-26 11:13:41 -07:00
}
for (i = 0; i < xf86NumGPUScreens; i++) {
pScr = xf86GPUScreens[i];
nprivs = xnfrealloc(pScr->privates,
xf86ScrnInfoPrivateCount * sizeof(DevUnion));
/* Zero the new private */
memset(&nprivs[idx], 0, sizeof(DevUnion));
pScr->privates = nprivs;
}
2006-11-26 11:13:41 -07:00
return idx;
}
Bool
2006-11-26 11:13:41 -07:00
xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
{
int i;
if (pScrn->numFormats >= MAXFORMATS)
return FALSE;
2006-11-26 11:13:41 -07:00
if (bpp <= 0) {
if (depth == 1)
bpp = 1;
else if (depth <= 8)
bpp = 8;
else if (depth <= 16)
bpp = 16;
else if (depth <= 32)
bpp = 32;
else
return FALSE;
2006-11-26 11:13:41 -07:00
}
if (pad <= 0)
pad = BITMAP_SCANLINE_PAD;
2006-11-26 11:13:41 -07:00
i = pScrn->numFormats++;
pScrn->formats[i].depth = depth;
pScrn->formats[i].bitsPerPixel = bpp;
pScrn->formats[i].scanlinePad = pad;
return TRUE;
}
/*
* Set the depth we are using based on (in the following order of preference):
* - values given on the command line
* - values given in the config file
* - values provided by the driver
* - an overall default when nothing else is given
*
* Also find a Display subsection matching the depth/bpp found.
*
* Sets the following ScrnInfoRec fields:
* bitsPerPixel, pixmap24, depth, display, imageByteOrder,
* bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
* formats, fbFormat.
*/
/* Can the screen handle 24 bpp pixmaps */
#define DO_PIX24(f) ((f & Support24bppFb) || \
((f & Support32bppFb) && (f & SupportConvert24to32)))
/* Can the screen handle 32 bpp pixmaps */
#define DO_PIX32(f) ((f & Support32bppFb) || \
((f & Support24bppFb) && (f & SupportConvert32to24)))
/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
&& (f & PreferConvert24to32))
/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
&& (f & PreferConvert32to24))
/* Can the screen handle 32bpp pixmaps for 24bpp fb */
#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
/* Can the screen handle 24bpp pixmaps for 32bpp fb */
#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
#ifndef GLOBAL_DEFAULT_DEPTH
#define GLOBAL_DEFAULT_DEPTH 24
#endif
Bool
2006-11-26 11:13:41 -07:00
xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
int depth24flags)
2006-11-26 11:13:41 -07:00
{
int i;
DispPtr disp;
Pix24Flags pix24 = xf86Info.pixmap24;
Bool nomatch = FALSE;
scrp->bitsPerPixel = -1;
scrp->depth = -1;
scrp->pixmap24 = Pix24DontCare;
scrp->bitsPerPixelFrom = X_DEFAULT;
scrp->depthFrom = X_DEFAULT;
if (xf86FbBpp > 0) {
scrp->bitsPerPixel = xf86FbBpp;
scrp->bitsPerPixelFrom = X_CMDLINE;
2006-11-26 11:13:41 -07:00
}
if (xf86Depth > 0) {
scrp->depth = xf86Depth;
scrp->depthFrom = X_CMDLINE;
2006-11-26 11:13:41 -07:00
}
if (xf86FbBpp < 0 && xf86Depth < 0) {
if (scrp->confScreen->defaultfbbpp > 0) {
scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
scrp->bitsPerPixelFrom = X_CONFIG;
}
if (scrp->confScreen->defaultdepth > 0) {
scrp->depth = scrp->confScreen->defaultdepth;
scrp->depthFrom = X_CONFIG;
}
if (scrp->confScreen->defaultfbbpp <= 0 &&
scrp->confScreen->defaultdepth <= 0) {
/*
* Check for DefaultDepth and DefaultFbBpp options in the
* Device sections.
*/
GDevPtr device;
Bool found = FALSE;
for (i = 0; i < scrp->numEntities; i++) {
device = xf86GetDevFromEntity(scrp->entityList[i],
scrp->entityInstanceList[i]);
if (device && device->options) {
if (xf86FindOption(device->options, "DefaultDepth")) {
scrp->depth = xf86SetIntOption(device->options,
"DefaultDepth", -1);
scrp->depthFrom = X_CONFIG;
found = TRUE;
}
if (xf86FindOption(device->options, "DefaultFbBpp")) {
scrp->bitsPerPixel = xf86SetIntOption(device->options,
"DefaultFbBpp",
-1);
scrp->bitsPerPixelFrom = X_CONFIG;
found = TRUE;
}
}
if (found)
break;
}
}
2006-11-26 11:13:41 -07:00
}
/* If none of these is set, pick a default */
if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
if (fbbpp > 0 || depth > 0) {
if (fbbpp > 0)
scrp->bitsPerPixel = fbbpp;
if (depth > 0)
scrp->depth = depth;
}
else {
scrp->depth = GLOBAL_DEFAULT_DEPTH;
}
2006-11-26 11:13:41 -07:00
}
/* If any are not given, determine a default for the others */
if (scrp->bitsPerPixel < 0) {
/* The depth must be set */
if (scrp->depth > -1) {
if (scrp->depth == 1)
scrp->bitsPerPixel = 1;
else if (scrp->depth <= 4)
scrp->bitsPerPixel = 4;
else if (scrp->depth <= 8)
scrp->bitsPerPixel = 8;
else if (scrp->depth <= 16)
scrp->bitsPerPixel = 16;
else if (scrp->depth <= 24) {
/*
* Figure out if a choice is possible based on the depth24
* and pix24 flags.
*/
/* Check pix24 first */
if (pix24 != Pix24DontCare) {
if (pix24 == Pix24Use32) {
if (DO_PIX32(depth24flags)) {
if (CHOOSE24FOR32(depth24flags))
scrp->bitsPerPixel = 24;
else
scrp->bitsPerPixel = 32;
}
else {
nomatch = TRUE;
}
}
else if (pix24 == Pix24Use24) {
if (DO_PIX24(depth24flags)) {
if (CHOOSE32FOR24(depth24flags))
scrp->bitsPerPixel = 32;
else
scrp->bitsPerPixel = 24;
}
else {
nomatch = TRUE;
}
}
}
else {
if (DO_PIX32(depth24flags)) {
if (CHOOSE24FOR32(depth24flags))
scrp->bitsPerPixel = 24;
else
scrp->bitsPerPixel = 32;
}
else if (DO_PIX24(depth24flags)) {
if (CHOOSE32FOR24(depth24flags))
scrp->bitsPerPixel = 32;
else
scrp->bitsPerPixel = 24;
}
}
}
else if (scrp->depth <= 32)
scrp->bitsPerPixel = 32;
else {
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Specified depth (%d) is greater than 32\n",
scrp->depth);
return FALSE;
}
}
else {
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"xf86SetDepthBpp: internal error: depth and fbbpp"
" are both not set\n");
return FALSE;
}
if (scrp->bitsPerPixel < 0) {
if (nomatch)
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Driver can't support depth 24 pixmap format (%d)\n",
PIX24TOBPP(pix24));
else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
NoDepth24Support)
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Driver can't support depth 24\n");
else
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Can't find fbbpp for depth 24\n");
return FALSE;
}
scrp->bitsPerPixelFrom = X_PROBED;
2006-11-26 11:13:41 -07:00
}
if (scrp->depth <= 0) {
/* bitsPerPixel is already set */
switch (scrp->bitsPerPixel) {
case 32:
scrp->depth = 24;
break;
default:
/* 1, 4, 8, 16 and 24 */
scrp->depth = scrp->bitsPerPixel;
break;
}
scrp->depthFrom = X_PROBED;
2006-11-26 11:13:41 -07:00
}
/* Sanity checks */
if (scrp->depth < 1 || scrp->depth > 32) {
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Specified depth (%d) is not in the range 1-32\n",
scrp->depth);
return FALSE;
2006-11-26 11:13:41 -07:00
}
switch (scrp->bitsPerPixel) {
case 1:
case 4:
case 8:
case 16:
case 24:
case 32:
break;
2006-11-26 11:13:41 -07:00
default:
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Specified fbbpp (%d) is not a permitted value\n",
scrp->bitsPerPixel);
return FALSE;
2006-11-26 11:13:41 -07:00
}
if (scrp->depth > scrp->bitsPerPixel) {
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Specified depth (%d) is greater than the fbbpp (%d)\n",
scrp->depth, scrp->bitsPerPixel);
return FALSE;
2006-11-26 11:13:41 -07:00
}
/* set scrp->pixmap24 if the driver isn't flexible */
if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
scrp->pixmap24 = Pix24Use24;
2006-11-26 11:13:41 -07:00
}
if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
scrp->pixmap24 = Pix24Use32;
2006-11-26 11:13:41 -07:00
}
/*
* Find the Display subsection matching the depth/fbbpp and initialise
* scrp->display with it.
*/
for (i = 0, disp = scrp->confScreen->displays;
i < scrp->confScreen->numdisplays; i++, disp++) {
if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
|| (disp->depth == scrp->depth && disp->fbbpp <= 0)
|| (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
scrp->display = disp;
break;
}
2006-11-26 11:13:41 -07:00
}
/*
* If an exact match can't be found, see if there is one with no
* depth or fbbpp specified.
*/
if (i == scrp->confScreen->numdisplays) {
for (i = 0, disp = scrp->confScreen->displays;
i < scrp->confScreen->numdisplays; i++, disp++) {
if (disp->depth <= 0 && disp->fbbpp <= 0) {
scrp->display = disp;
break;
}
}
2006-11-26 11:13:41 -07:00
}
/*
* If all else fails, create a default one.
*/
if (i == scrp->confScreen->numdisplays) {
scrp->confScreen->numdisplays++;
scrp->confScreen->displays =
xnfrealloc(scrp->confScreen->displays,
scrp->confScreen->numdisplays * sizeof(DispRec));
xf86DrvMsg(scrp->scrnIndex, X_INFO,
"Creating default Display subsection in Screen section\n"
"\t\"%s\" for depth/fbbpp %d/%d\n",
scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
scrp->confScreen->displays[i].blackColour.red = -1;
scrp->confScreen->displays[i].blackColour.green = -1;
scrp->confScreen->displays[i].blackColour.blue = -1;
scrp->confScreen->displays[i].whiteColour.red = -1;
scrp->confScreen->displays[i].whiteColour.green = -1;
scrp->confScreen->displays[i].whiteColour.blue = -1;
scrp->confScreen->displays[i].defaultVisual = -1;
scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
scrp->confScreen->displays[i].modes[0] = NULL;
scrp->confScreen->displays[i].depth = depth;
scrp->confScreen->displays[i].fbbpp = fbbpp;
scrp->display = &scrp->confScreen->displays[i];
2006-11-26 11:13:41 -07:00
}
/*
* Setup defaults for the display-wide attributes the framebuffer will
* need. These defaults should eventually be set globally, and not
* dependent on the screens.
*/
scrp->imageByteOrder = IMAGE_BYTE_ORDER;
scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
if (scrp->depth < 8) {
/* Planar modes need these settings */
scrp->bitmapScanlineUnit = 8;
scrp->bitmapBitOrder = MSBFirst;
}
else {
scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
2006-11-26 11:13:41 -07:00
}
/*
* If an unusual depth is required, add it to scrp->formats. The formats
* for the common depths are handled globally in InitOutput
*/
switch (scrp->depth) {
case 1:
case 4:
case 8:
case 15:
case 16:
case 24:
/* Common depths. Nothing to do for them */
break;
2006-11-26 11:13:41 -07:00
default:
if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Can't add pixmap format for depth %d\n", scrp->depth);
return FALSE;
}
2006-11-26 11:13:41 -07:00
}
/* Initialise the framebuffer format for this screen */
scrp->fbFormat.depth = scrp->depth;
scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
return TRUE;
}
/*
* Print out the selected depth and bpp.
*/
void
2006-11-26 11:13:41 -07:00
xf86PrintDepthBpp(ScrnInfoPtr scrp)
{
xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
}
/*
* xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
* greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
*/
Bool
2006-11-26 11:13:41 -07:00
xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
{
MessageType weightFrom = X_DEFAULT;
scrp->weight.red = 0;
scrp->weight.green = 0;
scrp->weight.blue = 0;
if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
scrp->weight = xf86Weight;
weightFrom = X_CMDLINE;
}
else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
&& scrp->display->weight.blue > 0) {
scrp->weight = scrp->display->weight;
weightFrom = X_CONFIG;
}
else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
scrp->weight = weight;
}
else {
switch (scrp->depth) {
case 1:
case 4:
case 8:
scrp->weight.red = scrp->weight.green =
scrp->weight.blue = scrp->rgbBits;
break;
case 15:
scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
break;
case 16:
scrp->weight.red = scrp->weight.blue = 5;
scrp->weight.green = 6;
break;
case 18:
scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6;
break;
case 24:
scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
break;
case 30:
scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
break;
}
2006-11-26 11:13:41 -07:00
}
if (scrp->weight.red)
xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
(int) scrp->weight.red, (int) scrp->weight.green,
(int) scrp->weight.blue);
2006-11-26 11:13:41 -07:00
if (scrp->depth > MAX_PSEUDO_DEPTH &&
(scrp->depth != scrp->weight.red + scrp->weight.green +
scrp->weight.blue)) {
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Weight given (%d%d%d) is inconsistent with the "
"depth (%d)\n",
(int) scrp->weight.red, (int) scrp->weight.green,
(int) scrp->weight.blue, scrp->depth);
return FALSE;
2006-11-26 11:13:41 -07:00
}
if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
/*
* XXX Does this even mean anything for TrueColor visuals?
* If not, we shouldn't even be setting it here. However, this
* matches the behaviour of 3.x versions of XFree86.
*/
scrp->rgbBits = scrp->weight.red;
if (scrp->weight.green > scrp->rgbBits)
scrp->rgbBits = scrp->weight.green;
if (scrp->weight.blue > scrp->rgbBits)
scrp->rgbBits = scrp->weight.blue;
2006-11-26 11:13:41 -07:00
}
/* Set the mask and offsets */
if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
/* Default to a setting common to PC hardware */
scrp->offset.red = scrp->weight.green + scrp->weight.blue;
scrp->offset.green = scrp->weight.blue;
scrp->offset.blue = 0;
scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
scrp->mask.green = ((1 << scrp->weight.green) - 1)
<< scrp->offset.green;
scrp->mask.blue = (1 << scrp->weight.blue) - 1;
}
else {
/* Initialise to the values passed */
scrp->mask.red = mask.red;
scrp->mask.green = mask.green;
scrp->mask.blue = mask.blue;
scrp->offset.red = ffs(mask.red);
scrp->offset.green = ffs(mask.green);
scrp->offset.blue = ffs(mask.blue);
2006-11-26 11:13:41 -07:00
}
return TRUE;
}
Bool
2006-11-26 11:13:41 -07:00
xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
{
MessageType visualFrom = X_DEFAULT;
if (defaultColorVisualClass >= 0) {
scrp->defaultVisual = defaultColorVisualClass;
visualFrom = X_CMDLINE;
}
else if (scrp->display->defaultVisual >= 0) {
scrp->defaultVisual = scrp->display->defaultVisual;
visualFrom = X_CONFIG;
}
else if (visual >= 0) {
scrp->defaultVisual = visual;
}
else {
if (scrp->depth == 1)
scrp->defaultVisual = StaticGray;
else if (scrp->depth == 4)
scrp->defaultVisual = StaticColor;
else if (scrp->depth <= MAX_PSEUDO_DEPTH)
scrp->defaultVisual = PseudoColor;
else
scrp->defaultVisual = TrueColor;
2006-11-26 11:13:41 -07:00
}
switch (scrp->defaultVisual) {
case StaticGray:
case GrayScale:
case StaticColor:
case PseudoColor:
case TrueColor:
case DirectColor:
xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
xf86VisualNames[scrp->defaultVisual]);
return TRUE;
2006-11-26 11:13:41 -07:00
default:
xf86DrvMsg(scrp->scrnIndex, X_ERROR,
"Invalid default visual class (%d)\n", scrp->defaultVisual);
return FALSE;
2006-11-26 11:13:41 -07:00
}
}
#define TEST_GAMMA(g) \
(g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
#define SET_GAMMA(g) \
(g) > GAMMA_ZERO ? (g) : 1.0
Bool
2006-11-26 11:13:41 -07:00
xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
{
MessageType from = X_DEFAULT;
2006-11-26 11:13:41 -07:00
#if 0
xf86MonPtr DDC = (xf86MonPtr) (scrp->monitor->DDC);
2006-11-26 11:13:41 -07:00
#endif
if (TEST_GAMMA(xf86Gamma)) {
from = X_CMDLINE;
scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
}
else if (TEST_GAMMA(scrp->monitor->gamma)) {
from = X_CONFIG;
scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
2006-11-26 11:13:41 -07:00
#if 0
}
else if (DDC && DDC->features.gamma > GAMMA_ZERO) {
2006-11-26 11:13:41 -07:00
from = X_PROBED;
scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
/* EDID structure version 2 gives optional seperate red, green & blue gamma values
* in bytes 0x57-0x59 */
2006-11-26 11:13:41 -07:00
#endif
}
else if (TEST_GAMMA(gamma)) {
scrp->gamma.red = SET_GAMMA(gamma.red);
scrp->gamma.green = SET_GAMMA(gamma.green);
scrp->gamma.blue = SET_GAMMA(gamma.blue);
}
else {
scrp->gamma.red = 1.0;
scrp->gamma.green = 1.0;
scrp->gamma.blue = 1.0;
2006-11-26 11:13:41 -07:00
}
/* Pretend we succeeded if we support better a gamma system.
* This avoids a confusing message.
*/
if (xf86_crtc_supports_gamma(scrp))
return TRUE;
2006-11-26 11:13:41 -07:00
xf86DrvMsg(scrp->scrnIndex, from,
"Using gamma correction (%.1f, %.1f, %.1f)\n",
scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
2006-11-26 11:13:41 -07:00
return TRUE;
}
#undef TEST_GAMMA
#undef SET_GAMMA
/*
* Set the DPI from the command line option. XXX should allow it to be
* calculated from the widthmm/heightmm values.
*/
#undef MMPERINCH
#define MMPERINCH 25.4
void
2006-11-26 11:13:41 -07:00
xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
{
MessageType from = X_DEFAULT;
xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC);
2006-11-26 11:13:41 -07:00
int ddcWidthmm, ddcHeightmm;
int widthErr, heightErr;
/* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
pScrn->widthmm = pScrn->monitor->widthmm;
pScrn->heightmm = pScrn->monitor->heightmm;
if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0)) {
/* DDC gives display size in mm for individual modes,
* but cm for monitor
*/
ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
}
else {
ddcWidthmm = ddcHeightmm = 0;
2006-11-26 11:13:41 -07:00
}
if (monitorResolution > 0) {
pScrn->xDpi = monitorResolution;
pScrn->yDpi = monitorResolution;
from = X_CMDLINE;
}
else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
from = X_CONFIG;
if (pScrn->widthmm > 0) {
pScrn->xDpi =
(int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);
}
if (pScrn->heightmm > 0) {
pScrn->yDpi =
(int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm);
}
if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
pScrn->yDpi = pScrn->xDpi;
if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
pScrn->xDpi = pScrn->yDpi;
xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
pScrn->widthmm, pScrn->heightmm);
/* Warn if config and probe disagree about display size */
if (ddcWidthmm && ddcHeightmm) {
if (pScrn->widthmm > 0) {
widthErr = abs(ddcWidthmm - pScrn->widthmm);
}
else {
widthErr = 0;
}
if (pScrn->heightmm > 0) {
heightErr = abs(ddcHeightmm - pScrn->heightmm);
}
else {
heightErr = 0;
}
if (widthErr > 10 || heightErr > 10) {
/* Should include config file name for monitor here */
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
ddcWidthmm, ddcHeightmm, pScrn->widthmm,
pScrn->heightmm);
}
}
}
else if (ddcWidthmm && ddcHeightmm) {
from = X_PROBED;
xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
ddcWidthmm, ddcHeightmm);
pScrn->widthmm = ddcWidthmm;
pScrn->heightmm = ddcHeightmm;
if (pScrn->widthmm > 0) {
pScrn->xDpi =
(int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);
}
if (pScrn->heightmm > 0) {
pScrn->yDpi =
(int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm);
}
if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
pScrn->yDpi = pScrn->xDpi;
if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
pScrn->xDpi = pScrn->yDpi;
}
else {
if (x > 0)
pScrn->xDpi = x;
else
pScrn->xDpi = DEFAULT_DPI;
if (y > 0)
pScrn->yDpi = y;
else
pScrn->yDpi = DEFAULT_DPI;
2006-11-26 11:13:41 -07:00
}
xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
pScrn->xDpi, pScrn->yDpi);
2006-11-26 11:13:41 -07:00
}
#undef MMPERINCH
void
2006-11-26 11:13:41 -07:00
xf86SetBlackWhitePixels(ScreenPtr pScreen)
{
if (xf86FlipPixels) {
pScreen->whitePixel = 0;
pScreen->blackPixel = 1;
}
else {
pScreen->whitePixel = 1;
pScreen->blackPixel = 0;
2006-11-26 11:13:41 -07:00
}
}
/*
* Function to enable/disable access to the frame buffer
*
* This is used when VT switching and when entering/leaving DGA direct mode.
*
* This has been rewritten again to eliminate the saved pixmap. The
* devPrivate field in the screen pixmap is set to NULL to catch code
* accidentally referencing the frame buffer while the X server is not
* supposed to touch it.
*
* Here, we exchange the pixmap private data, rather than the pixmaps
* themselves to avoid having to find and change any references to the screen
* pixmap such as GC's, window privates etc. This also means that this code
* does not need to know exactly how the pixmap pixels are accessed. Further,
* this exchange is >not< done through the screen's ModifyPixmapHeader()
* vector. This means the called frame buffer code layers can determine
* whether they are switched in or out by keeping track of the root pixmap's
* private data, and therefore don't need to access pScrnInfo->vtSema.
*/
void
xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable)
2006-11-26 11:13:41 -07:00
{
ScreenPtr pScreen = pScrnInfo->pScreen;
if (enable) {
/*
* Restore all of the clip lists on the screen
*/
if (!xf86Resetting)
SetRootClip(pScreen, TRUE);
2006-11-26 11:13:41 -07:00
}
else {
/*
* Empty all of the clip lists on the screen
*/
SetRootClip(pScreen, FALSE);
2006-11-26 11:13:41 -07:00
}
}
/* Print driver messages in the standard format of
(<type>) <screen name>(<screen index>): <message> */
void
2006-11-26 11:13:41 -07:00
xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
va_list args)
2006-11-26 11:13:41 -07:00
{
/* Prefix the scrnIndex name to the format string. */
if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
xf86Screens[scrnIndex]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
xf86Screens[scrnIndex]->name, scrnIndex);
else if (scrnIndex >= GPU_SCREEN_OFFSET &&
scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens &&
xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name)
LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ",
xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET);
else
LogVMessageVerb(type, verb, format, args);
2006-11-26 11:13:41 -07:00
}
/* Print driver messages, with verbose level specified directly */
void
2006-11-26 11:13:41 -07:00
xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
...)
2006-11-26 11:13:41 -07:00
{
va_list ap;
va_start(ap, format);
xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
va_end(ap);
}
/* Print driver messages, with verbose level of 1 (default) */
void
2006-11-26 11:13:41 -07:00
xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
{
va_list ap;
va_start(ap, format);
xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
va_end(ap);
}
2011-11-05 07:32:40 -06:00
/* Print input driver messages in the standard format of
(<type>) <driver>: <device name>: <message> */
2011-11-05 07:32:40 -06:00
void
xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb,
const char *format, va_list args)
2011-11-05 07:32:40 -06:00
{
const char *driverName = NULL;
const char *deviceName = NULL;
2011-11-05 07:32:40 -06:00
/* Prefix driver and device names to formatted message. */
if (dev) {
deviceName = dev->name;
if (dev->drv)
driverName = dev->drv->driverName;
2011-11-05 07:32:40 -06:00
}
LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName,
deviceName);
2011-11-05 07:32:40 -06:00
}
/* Print input driver message, with verbose level specified directly */
void
xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb,
const char *format, ...)
2011-11-05 07:32:40 -06:00
{
va_list ap;
va_start(ap, format);
xf86VIDrvMsgVerb(dev, type, verb, format, ap);
va_end(ap);
}
/* Print input driver messages, with verbose level of 1 (default) */
void
xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...)
{
va_list ap;
va_start(ap, format);
xf86VIDrvMsgVerb(dev, type, 1, format, ap);
va_end(ap);
}
2006-11-26 11:13:41 -07:00
/* Print non-driver messages with verbose level specified directly */
void
2006-11-26 11:13:41 -07:00
xf86MsgVerb(MessageType type, int verb, const char *format, ...)
{
va_list ap;
va_start(ap, format);
2011-11-05 07:32:40 -06:00
LogVMessageVerb(type, verb, format, ap);
2006-11-26 11:13:41 -07:00
va_end(ap);
}
/* Print non-driver messages with verbose level of 1 (default) */
void
2006-11-26 11:13:41 -07:00
xf86Msg(MessageType type, const char *format, ...)
{
va_list ap;
va_start(ap, format);
2011-11-05 07:32:40 -06:00
LogVMessageVerb(type, 1, format, ap);
2006-11-26 11:13:41 -07:00
va_end(ap);
}
/* Just like ErrorF, but with the verbose level checked */
void
2006-11-26 11:13:41 -07:00
xf86ErrorFVerb(int verb, const char *format, ...)
{
va_list ap;
va_start(ap, format);
if (xf86Verbose >= verb || xf86LogVerbose >= verb)
LogVWrite(verb, format, ap);
2006-11-26 11:13:41 -07:00
va_end(ap);
}
/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
void
2006-11-26 11:13:41 -07:00
xf86ErrorF(const char *format, ...)
{
va_list ap;
va_start(ap, format);
if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
LogVWrite(1, format, ap);
2006-11-26 11:13:41 -07:00
va_end(ap);
}
/* Note temporarily modifies the passed in buffer! */
static void xf86_mkdir_p(char *path)
{
char *sep = path;
while ((sep = strchr(sep + 1, '/'))) {
*sep = 0;
(void)mkdir(path, 0777);
*sep = '/';
}
(void)mkdir(path, 0777);
}
2006-11-26 11:13:41 -07:00
void
xf86LogInit(void)
2006-11-26 11:13:41 -07:00
{
char *env, *lf = NULL;
char buf[PATH_MAX];
2006-11-26 11:13:41 -07:00
#define LOGSUFFIX ".log"
#define LOGOLDSUFFIX ".old"
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
/* Get the log file name */
if (xf86LogFileFrom == X_DEFAULT) {
/* When not running as root, we won't be able to write to /var/log */
if (geteuid() != 0) {
if ((env = getenv("XDG_DATA_HOME")))
snprintf(buf, sizeof(buf), "%s/%s", env,
DEFAULT_XDG_DATA_HOME_LOGDIR);
else if ((env = getenv("HOME")))
snprintf(buf, sizeof(buf), "%s/%s/%s", env,
DEFAULT_XDG_DATA_HOME, DEFAULT_XDG_DATA_HOME_LOGDIR);
if (env) {
xf86_mkdir_p(buf);
strlcat(buf, "/" DEFAULT_LOGPREFIX, sizeof(buf));
xf86LogFile = buf;
}
}
/* Append the display number and ".log" */
if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1)
FatalError("Cannot allocate space for the log file name\n");
xf86LogFile = lf;
2006-11-26 11:13:41 -07:00
}
xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
xf86LogFileWasOpened = TRUE;
xf86SetVerbosity(xf86Verbose);
xf86SetLogVerbosity(xf86LogVerbose);
#undef LOGSUFFIX
#undef LOGOLDSUFFIX
free(lf);
2006-11-26 11:13:41 -07:00
}
void
2011-11-05 07:32:40 -06:00
xf86CloseLog(enum ExitCode error)
2006-11-26 11:13:41 -07:00
{
2011-11-05 07:32:40 -06:00
LogClose(error);
2006-11-26 11:13:41 -07:00
}
/*
* Drivers can use these for using their own SymTabRecs.
*/
const char *
2006-11-26 11:13:41 -07:00
xf86TokenToString(SymTabPtr table, int token)
{
int i;
for (i = 0; table[i].token >= 0 && table[i].token != token; i++);
2006-11-26 11:13:41 -07:00
if (table[i].token < 0)
return NULL;
2006-11-26 11:13:41 -07:00
else
return table[i].name;
2006-11-26 11:13:41 -07:00
}
int
2006-11-26 11:13:41 -07:00
xf86StringToToken(SymTabPtr table, const char *string)
{
int i;
if (string == NULL)
return -1;
2006-11-26 11:13:41 -07:00
for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++);
2006-11-26 11:13:41 -07:00
return table[i].token;
2006-11-26 11:13:41 -07:00
}
/*
* helper to display the clocks found on a card
*/
void
2006-11-26 11:13:41 -07:00
xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
{
int j;
xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
for (j = 0; j < scrp->numClocks; j++) {
if ((j % 4) == 0) {
xf86ErrorF("\n");
xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
}
xf86ErrorF(" %7.3f", (double) scrp->clock[j] / 1000.0);
2006-11-26 11:13:41 -07:00
}
xf86ErrorF("\n");
}
/*
* This prints out the driver identify message, including the names of
* the supported chipsets.
*
* XXX This makes assumptions about the line width, etc. Maybe we could
* use a more general "pretty print" function for messages.
*/
void
2006-11-26 11:13:41 -07:00
xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
{
int len, i;
len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
for (i = 0; chips[i].name != NULL; i++) {
if (i != 0) {
xf86ErrorF(",");
len++;
}
if (len + 2 + strlen(chips[i].name) < 78) {
xf86ErrorF(" ");
len++;
}
else {
xf86ErrorF("\n\t");
len = 8;
}
xf86ErrorF("%s", chips[i].name);
len += strlen(chips[i].name);
2006-11-26 11:13:41 -07:00
}
xf86ErrorF("\n");
}
int
xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
2006-11-26 11:13:41 -07:00
{
GDevPtr gdp, *pgdp = NULL;
2006-11-26 11:13:41 -07:00
confScreenPtr screensecptr;
int i, j;
2006-11-26 11:13:41 -07:00
if (sectlist)
*sectlist = NULL;
2006-11-26 11:13:41 -07:00
/*
* This can happen when running Xorg -showopts and a module like ati
* or vmware tries to load its submodules when xf86ConfigLayout is empty
*/
if (!xf86ConfigLayout.screens)
return 0;
2006-11-26 11:13:41 -07:00
/*
* This is a very important function that matches the device sections
* as they show up in the config file with the drivers that the server
* loads at run time.
*
2007-11-24 10:55:21 -07:00
* ChipProbe can call
* int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
2006-11-26 11:13:41 -07:00
* with its driver name. The function allocates an array of GDevPtr and
* returns this via sectlist and returns the number of elements in
* this list as return value. 0 means none found, -1 means fatal error.
2007-11-24 10:55:21 -07:00
*
2006-11-26 11:13:41 -07:00
* It can figure out which of the Device sections to use for which card
* (using things like the Card statement, etc). For single headed servers
* there will of course be just one such Device section.
*/
i = 0;
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
/*
* first we need to loop over all the Screens sections to get to all
* 'active' device sections
*/
for (j = 0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
2006-11-26 11:13:41 -07:00
screensecptr = xf86ConfigLayout.screens[j].screen;
if ((screensecptr->device->driver != NULL)
&& (xf86NameCmp(screensecptr->device->driver, drivername) == 0)
&& (!screensecptr->device->claimed)) {
2006-11-26 11:13:41 -07:00
/*
* we have a matching driver that wasn't claimed, yet
*/
pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
pgdp[i++] = screensecptr->device;
}
}
/* Then handle the inactive devices */
j = 0;
while (xf86ConfigLayout.inactives[j].identifier) {
gdp = &xf86ConfigLayout.inactives[j];
if (gdp->driver && !gdp->claimed &&
!xf86NameCmp(gdp->driver, drivername)) {
/* we have a matching driver that wasn't claimed yet */
pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
pgdp[i++] = gdp;
}
j++;
2006-11-26 11:13:41 -07:00
}
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
/*
* make the array NULL terminated and return its address
*/
if (i)
pgdp[i] = NULL;
if (sectlist)
*sectlist = pgdp;
2006-11-26 11:13:41 -07:00
else
free(pgdp);
2006-11-26 11:13:41 -07:00
return i;
}
const char *
2006-11-26 11:13:41 -07:00
xf86GetVisualName(int visual)
{
if (visual < 0 || visual > DirectColor)
return NULL;
2006-11-26 11:13:41 -07:00
return xf86VisualNames[visual];
}
int
xf86GetVerbosity(void)
2006-11-26 11:13:41 -07:00
{
return max(xf86Verbose, xf86LogVerbose);
}
Pix24Flags
xf86GetPix24(void)
2006-11-26 11:13:41 -07:00
{
return xf86Info.pixmap24;
}
int
xf86GetDepth(void)
2006-11-26 11:13:41 -07:00
{
return xf86Depth;
}
rgb
xf86GetWeight(void)
2006-11-26 11:13:41 -07:00
{
return xf86Weight;
}
Gamma
xf86GetGamma(void)
2006-11-26 11:13:41 -07:00
{
return xf86Gamma;
}
Bool
xf86GetFlipPixels(void)
2006-11-26 11:13:41 -07:00
{
return xf86FlipPixels;
}
const char *
xf86GetServerName(void)
2006-11-26 11:13:41 -07:00
{
return xf86ServerName;
}
Bool
xf86ServerIsExiting(void)
2006-11-26 11:13:41 -07:00
{
return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
}
Bool
xf86ServerIsResetting(void)
2006-11-26 11:13:41 -07:00
{
return xf86Resetting;
}
Bool
xf86ServerIsInitialising(void)
2006-11-26 11:13:41 -07:00
{
return xf86Initialising;
}
Bool
2006-11-26 11:13:41 -07:00
xf86ServerIsOnlyDetecting(void)
{
return xf86DoConfigure;
2006-11-26 11:13:41 -07:00
}
Bool
xf86CaughtSignal(void)
2006-11-26 11:13:41 -07:00
{
return xf86Info.caughtSignal;
}
Bool
xf86GetVidModeAllowNonLocal(void)
2006-11-26 11:13:41 -07:00
{
return xf86Info.vidModeAllowNonLocal;
}
Bool
xf86GetVidModeEnabled(void)
2006-11-26 11:13:41 -07:00
{
return xf86Info.vidModeEnabled;
}
Bool
xf86GetModInDevAllowNonLocal(void)
2006-11-26 11:13:41 -07:00
{
return xf86Info.miscModInDevAllowNonLocal;
}
Bool
xf86GetModInDevEnabled(void)
2006-11-26 11:13:41 -07:00
{
return xf86Info.miscModInDevEnabled;
}
Bool
xf86GetAllowMouseOpenFail(void)
2006-11-26 11:13:41 -07:00
{
return xf86Info.allowMouseOpenFail;
}
void
xf86DisableRandR(void)
2006-11-26 11:13:41 -07:00
{
xf86Info.disableRandR = TRUE;
xf86Info.randRFrom = X_PROBED;
}
CARD32
xf86GetModuleVersion(void *module)
2006-11-26 11:13:41 -07:00
{
return (CARD32) LoaderGetModuleVersion(module);
2006-11-26 11:13:41 -07:00
}
void *
2006-11-26 11:13:41 -07:00
xf86LoadDrvSubModule(DriverPtr drv, const char *name)
{
void *ret;
2006-11-26 11:13:41 -07:00
int errmaj = 0, errmin = 0;
ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
&errmaj, &errmin);
2006-11-26 11:13:41 -07:00
if (!ret)
LoaderErrorMsg(NULL, name, errmaj, errmin);
2006-11-26 11:13:41 -07:00
return ret;
}
void *
2006-11-26 11:13:41 -07:00
xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
{
void *ret;
2006-11-26 11:13:41 -07:00
int errmaj = 0, errmin = 0;
ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
&errmaj, &errmin);
2006-11-26 11:13:41 -07:00
if (!ret)
LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
2006-11-26 11:13:41 -07:00
return ret;
}
/*
* xf86LoadOneModule loads a single module.
2007-11-24 10:55:21 -07:00
*/
void *
xf86LoadOneModule(const char *name, void *opt)
2006-11-26 11:13:41 -07:00
{
int errmaj, errmin;
char *Name;
void *mod;
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
if (!name)
return NULL;
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
/* Normalise the module name */
Name = xf86NormalizeName(name);
/* Skip empty names */
if (Name == NULL)
return NULL;
2006-11-26 11:13:41 -07:00
if (*Name == '\0') {
free(Name);
return NULL;
2006-11-26 11:13:41 -07:00
}
mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
if (!mod)
LoaderErrorMsg(NULL, Name, errmaj, errmin);
free(Name);
2006-11-26 11:13:41 -07:00
return mod;
}
void
xf86UnloadSubModule(void *mod)
2006-11-26 11:13:41 -07:00
{
UnloadSubModule(mod);
}
Bool
2006-11-26 11:13:41 -07:00
xf86LoaderCheckSymbol(const char *name)
{
return LoaderSymbol(name) != NULL;
}
typedef enum {
OPTION_BACKING_STORE
2006-11-26 11:13:41 -07:00
} BSOpts;
static const OptionInfoRec BSOptions[] = {
{OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
2006-11-26 11:13:41 -07:00
};
void
2006-11-26 11:13:41 -07:00
xf86SetBackingStore(ScreenPtr pScreen)
{
Bool useBS = FALSE;
MessageType from = X_DEFAULT;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2006-11-26 11:13:41 -07:00
OptionInfoPtr options;
options = xnfalloc(sizeof(BSOptions));
(void) memcpy(options, BSOptions, sizeof(BSOptions));
2006-11-26 11:13:41 -07:00
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
/* check for commandline option here */
if (xf86bsEnableFlag) {
from = X_CMDLINE;
useBS = TRUE;
}
else if (xf86bsDisableFlag) {
from = X_CMDLINE;
useBS = FALSE;
}
else {
if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
from = X_CONFIG;
#ifdef COMPOSITE
if (from != X_CONFIG)
useBS = xf86ReturnOptValBool(options, OPTION_BACKING_STORE,
!noCompositeExtension);
#endif
2006-11-26 11:13:41 -07:00
}
free(options);
pScreen->backingStoreSupport = useBS ? WhenMapped : NotUseful;
2006-11-26 11:13:41 -07:00
if (serverGeneration == 1)
xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
useBS ? "enabled" : "disabled");
2006-11-26 11:13:41 -07:00
}
typedef enum {
OPTION_SILKEN_MOUSE
2006-11-26 11:13:41 -07:00
} SMOpts;
static const OptionInfoRec SMOptions[] = {
{OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
2006-11-26 11:13:41 -07:00
};
void
xf86SetSilkenMouse(ScreenPtr pScreen)
2006-11-26 11:13:41 -07:00
{
Bool useSM = TRUE;
MessageType from = X_DEFAULT;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
2006-11-26 11:13:41 -07:00
OptionInfoPtr options;
options = xnfalloc(sizeof(SMOptions));
(void) memcpy(options, SMOptions, sizeof(SMOptions));
2006-11-26 11:13:41 -07:00
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
/* check for commandline option here */
/* disable if screen shares resources */
/* TODO VGA arb disable silken mouse */
if (xf86silkenMouseDisableFlag) {
2006-11-26 11:13:41 -07:00
from = X_CMDLINE;
useSM = FALSE;
}
else {
if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
from = X_CONFIG;
2006-11-26 11:13:41 -07:00
}
free(options);
2006-11-26 11:13:41 -07:00
/*
* XXX quick hack to report correctly for OSs that can't do SilkenMouse
* yet. Should handle this differently so that alternate async methods
2007-11-24 10:55:21 -07:00
* work correctly with this too.
2006-11-26 11:13:41 -07:00
*/
pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
2006-11-26 11:13:41 -07:00
if (serverGeneration == 1)
xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
pScrn->silkenMouse ? "enabled" : "disabled");
2006-11-26 11:13:41 -07:00
}
/* Wrote this function for the PM2 Xv driver, preliminary. */
void *
xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name,
const char **adaptor_name, void **adaptor_options)
2006-11-26 11:13:41 -07:00
{
confXvAdaptorPtr adaptor;
int i;
if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
if (adaptor_name)
*adaptor_name = NULL;
if (adaptor_options)
*adaptor_options = NULL;
return NULL;
2006-11-26 11:13:41 -07:00
}
adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
if (adaptor_name)
*adaptor_name = adaptor->identifier;
if (adaptor_options)
*adaptor_options = adaptor->options;
2006-11-26 11:13:41 -07:00
for (i = 0; i < adaptor->numports; i++)
if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
return adaptor->ports[i].options;
2006-11-26 11:13:41 -07:00
return NULL;
}
/* Rather than duplicate loader's get OS function, just include it directly */
#define LoaderGetOS xf86GetOS
#include "loader/os.c"
static void
xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
EntityProc enter, EntityProc leave, void *private)
{
ScrnInfoPtr pScrn;
if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
xf86RemoveEntityFromScreen(pScrn, pEnt->index);
xf86SetEntityFuncs(pEnt->index, init, enter, leave, private);
}
ScrnInfoPtr
2006-11-26 11:13:41 -07:00
xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
EntityProc init, EntityProc enter, EntityProc leave,
void *private)
2006-11-26 11:13:41 -07:00
{
EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
if (!pEnt)
return pScrn;
2007-11-24 10:55:21 -07:00
2006-11-26 11:13:41 -07:00
if (!(pEnt->location.type == BUS_NONE)) {
free(pEnt);
return pScrn;
2006-11-26 11:13:41 -07:00
}
if (!pEnt->active) {
xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
free(pEnt);
return pScrn;
2006-11-26 11:13:41 -07:00
}
if (!pScrn)
pScrn = xf86AllocateScreen(pEnt->driver, scrnFlag);
xf86AddEntityToScreen(pScrn, entityIndex);
2006-11-26 11:13:41 -07:00
xf86SetEntityFuncs(entityIndex, init, enter, leave, private);
2006-11-26 11:13:41 -07:00
2011-11-05 07:32:40 -06:00
free(pEnt);
2006-11-26 11:13:41 -07:00
return pScrn;
}
Bool
xf86IsScreenPrimary(ScrnInfoPtr pScrn)
2006-11-26 11:13:41 -07:00
{
int i;
for (i = 0; i < pScrn->numEntities; i++) {
if (xf86IsEntityPrimary(i))
return TRUE;
2006-11-26 11:13:41 -07:00
}
return FALSE;
}
int
2006-11-26 11:13:41 -07:00
xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
int format, unsigned long len, void *value)
2006-11-26 11:13:41 -07:00
{
RootWinPropPtr pNewProp = NULL, pRegProp;
Bool existing = FALSE;
DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
ScrnIndex, property, type, format, len, value);
2006-11-26 11:13:41 -07:00
if (ScrnIndex < 0 || ScrnIndex >= xf86NumScreens) {
return BadMatch;
2006-11-26 11:13:41 -07:00
}
if (xf86RegisteredPropertiesTable &&
xf86RegisteredPropertiesTable[ScrnIndex]) {
for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
pNewProp; pNewProp = pNewProp->next) {
if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
break;
}
2006-11-26 11:13:41 -07:00
}
if (!pNewProp) {
if ((pNewProp = (RootWinPropPtr) malloc(sizeof(RootWinProp))) == NULL) {
return BadAlloc;
}
/*
* We will put this property at the end of the list so that
* the changes are made in the order they were requested.
*/
pNewProp->next = NULL;
}
else {
free((void *) pNewProp->name);
existing = TRUE;
2006-11-26 11:13:41 -07:00
}
pNewProp->name = xnfstrdup(NameForAtom(property));
pNewProp->type = type;
pNewProp->format = format;
pNewProp->size = len;
pNewProp->data = value;
2007-11-24 10:55:21 -07:00
DebugF("new property filled\n");
2006-11-26 11:13:41 -07:00
if (xf86RegisteredPropertiesTable == NULL) {
DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
xf86NumScreens);
xf86RegisteredPropertiesTable =
xnfcalloc(sizeof(RootWinProp), xf86NumScreens);
2006-11-26 11:13:41 -07:00
}
DebugF("xf86RegisteredPropertiesTable %p\n",
(void *) xf86RegisteredPropertiesTable);
DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
ScrnIndex, (void *) xf86RegisteredPropertiesTable[ScrnIndex]);
2006-11-26 11:13:41 -07:00
if (!existing) {
if (xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
}
else {
pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
while (pRegProp->next != NULL) {
DebugF("- next %p\n", (void *) pRegProp);
pRegProp = pRegProp->next;
}
pRegProp->next = pNewProp;
2006-11-26 11:13:41 -07:00
}
}
DebugF("xf86RegisterRootWindowProperty succeeded\n");
return Success;
2006-11-26 11:13:41 -07:00
}
Bool
2006-11-26 11:13:41 -07:00
xf86IsUnblank(int mode)
{
switch (mode) {
2006-11-26 11:13:41 -07:00
case SCREEN_SAVER_OFF:
case SCREEN_SAVER_FORCER:
return TRUE;
2006-11-26 11:13:41 -07:00
case SCREEN_SAVER_ON:
case SCREEN_SAVER_CYCLE:
return FALSE;
2006-11-26 11:13:41 -07:00
default:
xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
return TRUE;
2006-11-26 11:13:41 -07:00
}
}
2007-11-24 10:55:21 -07:00
void
2011-11-05 07:32:40 -06:00
xf86MotionHistoryAllocate(InputInfoPtr pInfo)
2007-11-24 10:55:21 -07:00
{
2011-11-05 07:32:40 -06:00
AllocateMotionHistory(pInfo->dev);
2007-11-24 10:55:21 -07:00
}
ScrnInfoPtr
xf86ScreenToScrn(ScreenPtr pScreen)
{
if (pScreen->isGPU) {
assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens);
return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET];
} else {
assert(pScreen->myNum < xf86NumScreens);
return xf86Screens[pScreen->myNum];
}
}
ScreenPtr
xf86ScrnToScreen(ScrnInfoPtr pScrn)
{
if (pScrn->is_gpu) {
assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens);
return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET];
} else {
assert(pScrn->scrnIndex < screenInfo.numScreens);
return screenInfo.screens[pScrn->scrnIndex];
}
}
void
xf86UpdateDesktopDimensions(void)
{
update_desktop_dimensions();
}