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