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