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