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