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