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; i < scrp->confScreen->numdisplays; i++) {
529 disp = scrp->confScreen->displays[i];
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; i < scrp->confScreen->numdisplays; i++) {
544 disp = scrp->confScreen->displays[i];
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 scrp->confScreen->displays =
558 xnfreallocarray(scrp->confScreen->displays,
559 scrp->confScreen->numdisplays, sizeof(DispPtr));
560 xf86DrvMsg(scrp->scrnIndex, X_INFO,
561 "Creating default Display subsection in Screen section\n"
562 "\t\"%s\" for depth/fbbpp %d/%d\n",
563 scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
564 scrp->confScreen->displays[i] = xnfcalloc(1, sizeof(DispRec));
565 memset(scrp->confScreen->displays[i], 0, sizeof(DispRec));
566 scrp->confScreen->displays[i]->blackColour.red = -1;
567 scrp->confScreen->displays[i]->blackColour.green = -1;
568 scrp->confScreen->displays[i]->blackColour.blue = -1;
569 scrp->confScreen->displays[i]->whiteColour.red = -1;
570 scrp->confScreen->displays[i]->whiteColour.green = -1;
571 scrp->confScreen->displays[i]->whiteColour.blue = -1;
572 scrp->confScreen->displays[i]->defaultVisual = -1;
573 scrp->confScreen->displays[i]->modes = xnfalloc(sizeof(char *));
574 scrp->confScreen->displays[i]->modes[0] = NULL;
575 scrp->confScreen->displays[i]->depth = depth;
576 scrp->confScreen->displays[i]->fbbpp = fbbpp;
577 scrp->display = scrp->confScreen->displays[i];
578 }
579
580 /*
581 * Setup defaults for the display-wide attributes the framebuffer will
582 * need. These defaults should eventually be set globally, and not
583 * dependent on the screens.
584 */
585 scrp->imageByteOrder = IMAGE_BYTE_ORDER;
586 scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
587 if (scrp->depth < 8) {
588 /* Planar modes need these settings */
589 scrp->bitmapScanlineUnit = 8;
590 scrp->bitmapBitOrder = MSBFirst;
591 }
592 else {
593 scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
594 scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
595 }
596
597 /*
598 * If an unusual depth is required, add it to scrp->formats. The formats
599 * for the common depths are handled globally in InitOutput
600 */
601 switch (scrp->depth) {
602 case 1:
603 case 4:
604 case 8:
605 case 15:
606 case 16:
607 case 24:
608 /* Common depths. Nothing to do for them */
609 break;
610 default:
611 if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
612 xf86DrvMsg(scrp->scrnIndex, X_ERROR,
613 "Can't add pixmap format for depth %d\n", scrp->depth);
614 return FALSE;
615 }
616 }
617
618 /* Initialise the framebuffer format for this screen */
619 scrp->fbFormat.depth = scrp->depth;
620 scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
621 scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
622
623 return TRUE;
624 }
625
626 /*
627 * Print out the selected depth and bpp.
628 */
629 void
xf86PrintDepthBpp(ScrnInfoPtr scrp)630 xf86PrintDepthBpp(ScrnInfoPtr scrp)
631 {
632 xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
633 xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
634 }
635
636 /*
637 * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
638 * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
639 */
640 Bool
xf86SetWeight(ScrnInfoPtr scrp,rgb weight,rgb mask)641 xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
642 {
643 MessageType weightFrom = X_DEFAULT;
644
645 scrp->weight.red = 0;
646 scrp->weight.green = 0;
647 scrp->weight.blue = 0;
648
649 if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
650 scrp->weight = xf86Weight;
651 weightFrom = X_CMDLINE;
652 }
653 else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
654 && scrp->display->weight.blue > 0) {
655 scrp->weight = scrp->display->weight;
656 weightFrom = X_CONFIG;
657 }
658 else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
659 scrp->weight = weight;
660 }
661 else {
662 switch (scrp->depth) {
663 case 1:
664 case 4:
665 case 8:
666 scrp->weight.red = scrp->weight.green =
667 scrp->weight.blue = scrp->rgbBits;
668 break;
669 case 15:
670 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
671 break;
672 case 16:
673 scrp->weight.red = scrp->weight.blue = 5;
674 scrp->weight.green = 6;
675 break;
676 case 18:
677 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 6;
678 break;
679 case 24:
680 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
681 break;
682 case 30:
683 scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
684 break;
685 }
686 }
687
688 if (scrp->weight.red)
689 xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
690 (int) scrp->weight.red, (int) scrp->weight.green,
691 (int) scrp->weight.blue);
692
693 if (scrp->depth > MAX_PSEUDO_DEPTH &&
694 (scrp->depth != scrp->weight.red + scrp->weight.green +
695 scrp->weight.blue)) {
696 xf86DrvMsg(scrp->scrnIndex, X_ERROR,
697 "Weight given (%d%d%d) is inconsistent with the "
698 "depth (%d)\n",
699 (int) scrp->weight.red, (int) scrp->weight.green,
700 (int) scrp->weight.blue, scrp->depth);
701 return FALSE;
702 }
703 if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
704 /*
705 * XXX Does this even mean anything for TrueColor visuals?
706 * If not, we shouldn't even be setting it here. However, this
707 * matches the behaviour of 3.x versions of XFree86.
708 */
709 scrp->rgbBits = scrp->weight.red;
710 if (scrp->weight.green > scrp->rgbBits)
711 scrp->rgbBits = scrp->weight.green;
712 if (scrp->weight.blue > scrp->rgbBits)
713 scrp->rgbBits = scrp->weight.blue;
714 }
715
716 /* Set the mask and offsets */
717 if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
718 /* Default to a setting common to PC hardware */
719 scrp->offset.red = scrp->weight.green + scrp->weight.blue;
720 scrp->offset.green = scrp->weight.blue;
721 scrp->offset.blue = 0;
722 scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
723 scrp->mask.green = ((1 << scrp->weight.green) - 1)
724 << scrp->offset.green;
725 scrp->mask.blue = (1 << scrp->weight.blue) - 1;
726 }
727 else {
728 /* Initialise to the values passed */
729 scrp->mask.red = mask.red;
730 scrp->mask.green = mask.green;
731 scrp->mask.blue = mask.blue;
732 scrp->offset.red = ffs(mask.red);
733 scrp->offset.green = ffs(mask.green);
734 scrp->offset.blue = ffs(mask.blue);
735 }
736 return TRUE;
737 }
738
739 Bool
xf86SetDefaultVisual(ScrnInfoPtr scrp,int visual)740 xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
741 {
742 MessageType visualFrom = X_DEFAULT;
743
744 if (defaultColorVisualClass >= 0) {
745 scrp->defaultVisual = defaultColorVisualClass;
746 visualFrom = X_CMDLINE;
747 }
748 else if (scrp->display->defaultVisual >= 0) {
749 scrp->defaultVisual = scrp->display->defaultVisual;
750 visualFrom = X_CONFIG;
751 }
752 else if (visual >= 0) {
753 scrp->defaultVisual = visual;
754 }
755 else {
756 if (scrp->depth == 1)
757 scrp->defaultVisual = StaticGray;
758 else if (scrp->depth == 4)
759 scrp->defaultVisual = StaticColor;
760 else if (scrp->depth <= MAX_PSEUDO_DEPTH)
761 scrp->defaultVisual = PseudoColor;
762 else
763 scrp->defaultVisual = TrueColor;
764 }
765 switch (scrp->defaultVisual) {
766 case StaticGray:
767 case GrayScale:
768 case StaticColor:
769 case PseudoColor:
770 case TrueColor:
771 case DirectColor:
772 xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
773 xf86VisualNames[scrp->defaultVisual]);
774 return TRUE;
775 default:
776
777 xf86DrvMsg(scrp->scrnIndex, X_ERROR,
778 "Invalid default visual class (%d)\n", scrp->defaultVisual);
779 return FALSE;
780 }
781 }
782
783 #define TEST_GAMMA(g) \
784 (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
785
786 #define SET_GAMMA(g) \
787 (g) > GAMMA_ZERO ? (g) : 1.0
788
789 Bool
xf86SetGamma(ScrnInfoPtr scrp,Gamma gamma)790 xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
791 {
792 MessageType from = X_DEFAULT;
793
794 #if 0
795 xf86MonPtr DDC = (xf86MonPtr) (scrp->monitor->DDC);
796 #endif
797 if (TEST_GAMMA(xf86Gamma)) {
798 from = X_CMDLINE;
799 scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
800 scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
801 scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
802 }
803 else if (TEST_GAMMA(scrp->monitor->gamma)) {
804 from = X_CONFIG;
805 scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
806 scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
807 scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
808 #if 0
809 }
810 else if (DDC && DDC->features.gamma > GAMMA_ZERO) {
811 from = X_PROBED;
812 scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
813 scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
814 scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
815 /* EDID structure version 2 gives optional seperate red, green & blue gamma values
816 * in bytes 0x57-0x59 */
817 #endif
818 }
819 else if (TEST_GAMMA(gamma)) {
820 scrp->gamma.red = SET_GAMMA(gamma.red);
821 scrp->gamma.green = SET_GAMMA(gamma.green);
822 scrp->gamma.blue = SET_GAMMA(gamma.blue);
823 }
824 else {
825 scrp->gamma.red = 1.0;
826 scrp->gamma.green = 1.0;
827 scrp->gamma.blue = 1.0;
828 }
829
830 xf86DrvMsg(scrp->scrnIndex, from,
831 "Using gamma correction (%.1f, %.1f, %.1f)\n",
832 scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
833
834 return TRUE;
835 }
836
837 #undef TEST_GAMMA
838 #undef SET_GAMMA
839
840 /*
841 * Set the DPI from the command line option. XXX should allow it to be
842 * calculated from the widthmm/heightmm values.
843 */
844
845 #undef MMPERINCH
846 #define MMPERINCH 25.4
847
848 void
xf86SetDpi(ScrnInfoPtr pScrn,int x,int y)849 xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
850 {
851 MessageType from = X_DEFAULT;
852 xf86MonPtr DDC = (xf86MonPtr) (pScrn->monitor->DDC);
853 int ddcWidthmm, ddcHeightmm;
854 int widthErr, heightErr;
855
856 /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
857 pScrn->widthmm = pScrn->monitor->widthmm;
858 pScrn->heightmm = pScrn->monitor->heightmm;
859
860 if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0)) {
861 /* DDC gives display size in mm for individual modes,
862 * but cm for monitor
863 */
864 ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
865 ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
866 }
867 else {
868 ddcWidthmm = ddcHeightmm = 0;
869 }
870
871 if (monitorResolution > 0) {
872 pScrn->xDpi = monitorResolution;
873 pScrn->yDpi = monitorResolution;
874 from = X_CMDLINE;
875 }
876 else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
877 from = X_CONFIG;
878 if (pScrn->widthmm > 0) {
879 pScrn->xDpi =
880 (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);
881 }
882 if (pScrn->heightmm > 0) {
883 pScrn->yDpi =
884 (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm);
885 }
886 if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
887 pScrn->yDpi = pScrn->xDpi;
888 if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
889 pScrn->xDpi = pScrn->yDpi;
890 xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
891 pScrn->widthmm, pScrn->heightmm);
892
893 /* Warn if config and probe disagree about display size */
894 if (ddcWidthmm && ddcHeightmm) {
895 if (pScrn->widthmm > 0) {
896 widthErr = abs(ddcWidthmm - pScrn->widthmm);
897 }
898 else {
899 widthErr = 0;
900 }
901 if (pScrn->heightmm > 0) {
902 heightErr = abs(ddcHeightmm - pScrn->heightmm);
903 }
904 else {
905 heightErr = 0;
906 }
907 if (widthErr > 10 || heightErr > 10) {
908 /* Should include config file name for monitor here */
909 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
910 "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
911 ddcWidthmm, ddcHeightmm, pScrn->widthmm,
912 pScrn->heightmm);
913 }
914 }
915 }
916 else if (ddcWidthmm && ddcHeightmm) {
917 from = X_PROBED;
918 xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
919 ddcWidthmm, ddcHeightmm);
920 pScrn->widthmm = ddcWidthmm;
921 pScrn->heightmm = ddcHeightmm;
922 if (pScrn->widthmm > 0) {
923 pScrn->xDpi =
924 (int) ((double) pScrn->virtualX * MMPERINCH / pScrn->widthmm);
925 }
926 if (pScrn->heightmm > 0) {
927 pScrn->yDpi =
928 (int) ((double) pScrn->virtualY * MMPERINCH / pScrn->heightmm);
929 }
930 if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
931 pScrn->yDpi = pScrn->xDpi;
932 if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
933 pScrn->xDpi = pScrn->yDpi;
934 }
935 else {
936 if (x > 0)
937 pScrn->xDpi = x;
938 else
939 pScrn->xDpi = DEFAULT_DPI;
940 if (y > 0)
941 pScrn->yDpi = y;
942 else
943 pScrn->yDpi = DEFAULT_DPI;
944 }
945 xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
946 pScrn->xDpi, pScrn->yDpi);
947 }
948
949 #undef MMPERINCH
950
951 void
xf86SetBlackWhitePixels(ScreenPtr pScreen)952 xf86SetBlackWhitePixels(ScreenPtr pScreen)
953 {
954 if (xf86FlipPixels) {
955 pScreen->whitePixel = 0;
956 pScreen->blackPixel = 1;
957 }
958 else {
959 pScreen->whitePixel = 1;
960 pScreen->blackPixel = 0;
961 }
962 }
963
964 /*
965 * Function to enable/disable access to the frame buffer
966 *
967 * This is used when VT switching and when entering/leaving DGA direct mode.
968 *
969 * This has been rewritten again to eliminate the saved pixmap. The
970 * devPrivate field in the screen pixmap is set to NULL to catch code
971 * accidentally referencing the frame buffer while the X server is not
972 * supposed to touch it.
973 *
974 * Here, we exchange the pixmap private data, rather than the pixmaps
975 * themselves to avoid having to find and change any references to the screen
976 * pixmap such as GC's, window privates etc. This also means that this code
977 * does not need to know exactly how the pixmap pixels are accessed. Further,
978 * this exchange is >not< done through the screen's ModifyPixmapHeader()
979 * vector. This means the called frame buffer code layers can determine
980 * whether they are switched in or out by keeping track of the root pixmap's
981 * private data, and therefore don't need to access pScrnInfo->vtSema.
982 */
983 void
xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo,Bool enable)984 xf86EnableDisableFBAccess(ScrnInfoPtr pScrnInfo, Bool enable)
985 {
986 ScreenPtr pScreen = pScrnInfo->pScreen;
987
988 if (enable) {
989 /*
990 * Restore all of the clip lists on the screen
991 */
992 if (!xf86Resetting)
993 SetRootClip(pScreen, ROOT_CLIP_FULL);
994
995 }
996 else {
997 /*
998 * Empty all of the clip lists on the screen
999 */
1000 SetRootClip(pScreen, ROOT_CLIP_NONE);
1001 }
1002 }
1003
1004 /* Print driver messages in the standard format of
1005 (<type>) <screen name>(<screen index>): <message> */
1006 void
xf86VDrvMsgVerb(int scrnIndex,MessageType type,int verb,const char * format,va_list args)1007 xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1008 va_list args)
1009 {
1010 /* Prefix the scrnIndex name to the format string. */
1011 if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
1012 xf86Screens[scrnIndex]->name)
1013 LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
1014 xf86Screens[scrnIndex]->name, scrnIndex);
1015 else if (scrnIndex >= GPU_SCREEN_OFFSET &&
1016 scrnIndex < GPU_SCREEN_OFFSET + xf86NumGPUScreens &&
1017 xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name)
1018 LogHdrMessageVerb(type, verb, format, args, "%s(G%d): ",
1019 xf86GPUScreens[scrnIndex - GPU_SCREEN_OFFSET]->name, scrnIndex - GPU_SCREEN_OFFSET);
1020 else
1021 LogVMessageVerb(type, verb, format, args);
1022 }
1023
1024 /* Print driver messages, with verbose level specified directly */
1025 void
xf86DrvMsgVerb(int scrnIndex,MessageType type,int verb,const char * format,...)1026 xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
1027 ...)
1028 {
1029 va_list ap;
1030
1031 va_start(ap, format);
1032 xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
1033 va_end(ap);
1034 }
1035
1036 /* Print driver messages, with verbose level of 1 (default) */
1037 void
xf86DrvMsg(int scrnIndex,MessageType type,const char * format,...)1038 xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
1039 {
1040 va_list ap;
1041
1042 va_start(ap, format);
1043 xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
1044 va_end(ap);
1045 }
1046
1047 /* Print input driver messages in the standard format of
1048 (<type>) <driver>: <device name>: <message> */
1049 void
xf86VIDrvMsgVerb(InputInfoPtr dev,MessageType type,int verb,const char * format,va_list args)1050 xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb,
1051 const char *format, va_list args)
1052 {
1053 const char *driverName = NULL;
1054 const char *deviceName = NULL;
1055
1056 /* Prefix driver and device names to formatted message. */
1057 if (dev) {
1058 deviceName = dev->name;
1059 if (dev->drv)
1060 driverName = dev->drv->driverName;
1061 }
1062
1063 LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName,
1064 deviceName);
1065 }
1066
1067 /* Print input driver message, with verbose level specified directly */
1068 void
xf86IDrvMsgVerb(InputInfoPtr dev,MessageType type,int verb,const char * format,...)1069 xf86IDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb,
1070 const char *format, ...)
1071 {
1072 va_list ap;
1073
1074 va_start(ap, format);
1075 xf86VIDrvMsgVerb(dev, type, verb, format, ap);
1076 va_end(ap);
1077 }
1078
1079 /* Print input driver messages, with verbose level of 1 (default) */
1080 void
xf86IDrvMsg(InputInfoPtr dev,MessageType type,const char * format,...)1081 xf86IDrvMsg(InputInfoPtr dev, MessageType type, const char *format, ...)
1082 {
1083 va_list ap;
1084
1085 va_start(ap, format);
1086 xf86VIDrvMsgVerb(dev, type, 1, format, ap);
1087 va_end(ap);
1088 }
1089
1090 /* Print non-driver messages with verbose level specified directly */
1091 void
xf86MsgVerb(MessageType type,int verb,const char * format,...)1092 xf86MsgVerb(MessageType type, int verb, const char *format, ...)
1093 {
1094 va_list ap;
1095
1096 va_start(ap, format);
1097 LogVMessageVerb(type, verb, format, ap);
1098 va_end(ap);
1099 }
1100
1101 /* Print non-driver messages with verbose level of 1 (default) */
1102 void
xf86Msg(MessageType type,const char * format,...)1103 xf86Msg(MessageType type, const char *format, ...)
1104 {
1105 va_list ap;
1106
1107 va_start(ap, format);
1108 LogVMessageVerb(type, 1, format, ap);
1109 va_end(ap);
1110 }
1111
1112 /* Just like ErrorF, but with the verbose level checked */
1113 void
xf86ErrorFVerb(int verb,const char * format,...)1114 xf86ErrorFVerb(int verb, const char *format, ...)
1115 {
1116 va_list ap;
1117
1118 va_start(ap, format);
1119 if (xf86Verbose >= verb || xf86LogVerbose >= verb)
1120 LogVWrite(verb, format, ap);
1121 va_end(ap);
1122 }
1123
1124 /* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
1125 void
xf86ErrorF(const char * format,...)1126 xf86ErrorF(const char *format, ...)
1127 {
1128 va_list ap;
1129
1130 va_start(ap, format);
1131 if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
1132 LogVWrite(1, format, ap);
1133 va_end(ap);
1134 }
1135
1136 /* Note temporarily modifies the passed in buffer! */
xf86_mkdir_p(char * path)1137 static void xf86_mkdir_p(char *path)
1138 {
1139 char *sep = path;
1140
1141 while ((sep = strchr(sep + 1, '/'))) {
1142 *sep = 0;
1143 (void)mkdir(path, 0777);
1144 *sep = '/';
1145 }
1146 (void)mkdir(path, 0777);
1147 }
1148
1149 void
xf86LogInit(void)1150 xf86LogInit(void)
1151 {
1152 char *env, *lf = NULL;
1153 char buf[PATH_MAX];
1154
1155 #define LOGSUFFIX ".log"
1156 #define LOGOLDSUFFIX ".old"
1157
1158 /* Get the log file name */
1159 if (xf86LogFileFrom == X_DEFAULT) {
1160 /* When not running as root, we won't be able to write to /var/log */
1161 if (geteuid() != 0) {
1162 if ((env = getenv("XDG_DATA_HOME")))
1163 snprintf(buf, sizeof(buf), "%s/%s", env,
1164 DEFAULT_XDG_DATA_HOME_LOGDIR);
1165 else if ((env = getenv("HOME")))
1166 snprintf(buf, sizeof(buf), "%s/%s/%s", env,
1167 DEFAULT_XDG_DATA_HOME, DEFAULT_XDG_DATA_HOME_LOGDIR);
1168
1169 if (env) {
1170 xf86_mkdir_p(buf);
1171 strlcat(buf, "/" DEFAULT_LOGPREFIX, sizeof(buf));
1172 xf86LogFile = buf;
1173 }
1174 }
1175 /* Append the display number and ".log" */
1176 if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1)
1177 FatalError("Cannot allocate space for the log file name\n");
1178 xf86LogFile = lf;
1179 }
1180
1181 xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
1182 xf86LogFileWasOpened = TRUE;
1183
1184 xf86SetVerbosity(xf86Verbose);
1185 xf86SetLogVerbosity(xf86LogVerbose);
1186
1187 #undef LOGSUFFIX
1188 #undef LOGOLDSUFFIX
1189
1190 free(lf);
1191 }
1192
1193 void
xf86CloseLog(enum ExitCode error)1194 xf86CloseLog(enum ExitCode error)
1195 {
1196 LogClose(error);
1197 }
1198
1199 /*
1200 * Drivers can use these for using their own SymTabRecs.
1201 */
1202
1203 const char *
xf86TokenToString(SymTabPtr table,int token)1204 xf86TokenToString(SymTabPtr table, int token)
1205 {
1206 int i;
1207
1208 for (i = 0; table[i].token >= 0 && table[i].token != token; i++);
1209
1210 if (table[i].token < 0)
1211 return NULL;
1212 else
1213 return table[i].name;
1214 }
1215
1216 int
xf86StringToToken(SymTabPtr table,const char * string)1217 xf86StringToToken(SymTabPtr table, const char *string)
1218 {
1219 int i;
1220
1221 if (string == NULL)
1222 return -1;
1223
1224 for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++);
1225
1226 return table[i].token;
1227 }
1228
1229 /*
1230 * helper to display the clocks found on a card
1231 */
1232 void
xf86ShowClocks(ScrnInfoPtr scrp,MessageType from)1233 xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
1234 {
1235 int j;
1236
1237 xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
1238 for (j = 0; j < scrp->numClocks; j++) {
1239 if ((j % 4) == 0) {
1240 xf86ErrorF("\n");
1241 xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
1242 }
1243 xf86ErrorF(" %7.3f", (double) scrp->clock[j] / 1000.0);
1244 }
1245 xf86ErrorF("\n");
1246 }
1247
1248 /*
1249 * This prints out the driver identify message, including the names of
1250 * the supported chipsets.
1251 *
1252 * XXX This makes assumptions about the line width, etc. Maybe we could
1253 * use a more general "pretty print" function for messages.
1254 */
1255 void
xf86PrintChipsets(const char * drvname,const char * drvmsg,SymTabPtr chips)1256 xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
1257 {
1258 int len, i;
1259
1260 len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
1261 xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
1262 for (i = 0; chips[i].name != NULL; i++) {
1263 if (i != 0) {
1264 xf86ErrorF(",");
1265 len++;
1266 }
1267 if (len + 2 + strlen(chips[i].name) < 78) {
1268 xf86ErrorF(" ");
1269 len++;
1270 }
1271 else {
1272 xf86ErrorF("\n\t");
1273 len = 8;
1274 }
1275 xf86ErrorF("%s", chips[i].name);
1276 len += strlen(chips[i].name);
1277 }
1278 xf86ErrorF("\n");
1279 }
1280
1281 int
xf86MatchDevice(const char * drivername,GDevPtr ** sectlist)1282 xf86MatchDevice(const char *drivername, GDevPtr ** sectlist)
1283 {
1284 GDevPtr gdp, *pgdp = NULL;
1285 confScreenPtr screensecptr;
1286 int i, j, k;
1287
1288 if (sectlist)
1289 *sectlist = NULL;
1290
1291 /*
1292 * This can happen when running Xorg -showopts and a module like ati
1293 * or vmware tries to load its submodules when xf86ConfigLayout is empty
1294 */
1295 if (!xf86ConfigLayout.screens)
1296 return 0;
1297
1298 /*
1299 * This is a very important function that matches the device sections
1300 * as they show up in the config file with the drivers that the server
1301 * loads at run time.
1302 *
1303 * ChipProbe can call
1304 * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
1305 * with its driver name. The function allocates an array of GDevPtr and
1306 * returns this via sectlist and returns the number of elements in
1307 * this list as return value. 0 means none found, -1 means fatal error.
1308 *
1309 * It can figure out which of the Device sections to use for which card
1310 * (using things like the Card statement, etc). For single headed servers
1311 * there will of course be just one such Device section.
1312 */
1313 i = 0;
1314
1315 /*
1316 * first we need to loop over all the Screens sections to get to all
1317 * 'active' device sections
1318 */
1319 for (j = 0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
1320 screensecptr = xf86ConfigLayout.screens[j].screen;
1321 if ((screensecptr->device->driver != NULL)
1322 && (xf86NameCmp(screensecptr->device->driver, drivername) == 0)
1323 && (!screensecptr->device->claimed)) {
1324 /*
1325 * we have a matching driver that wasn't claimed, yet
1326 */
1327 pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
1328 pgdp[i++] = screensecptr->device;
1329 }
1330 for (k = 0; k < screensecptr->num_gpu_devices; k++) {
1331 if ((screensecptr->gpu_devices[k]->driver != NULL)
1332 && (xf86NameCmp(screensecptr->gpu_devices[k]->driver, drivername) == 0)
1333 && (!screensecptr->gpu_devices[k]->claimed)) {
1334 /*
1335 * we have a matching driver that wasn't claimed, yet
1336 */
1337 pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
1338 pgdp[i++] = screensecptr->gpu_devices[k];
1339 }
1340 }
1341 }
1342
1343 /* Then handle the inactive devices */
1344 j = 0;
1345 while (xf86ConfigLayout.inactives[j].identifier) {
1346 gdp = &xf86ConfigLayout.inactives[j];
1347 if (gdp->driver && !gdp->claimed &&
1348 !xf86NameCmp(gdp->driver, drivername)) {
1349 /* we have a matching driver that wasn't claimed yet */
1350 pgdp = xnfreallocarray(pgdp, i + 2, sizeof(GDevPtr));
1351 pgdp[i++] = gdp;
1352 }
1353 j++;
1354 }
1355
1356 /*
1357 * make the array NULL terminated and return its address
1358 */
1359 if (i)
1360 pgdp[i] = NULL;
1361
1362 if (sectlist)
1363 *sectlist = pgdp;
1364 else
1365 free(pgdp);
1366 return i;
1367 }
1368
1369 const char *
xf86GetVisualName(int visual)1370 xf86GetVisualName(int visual)
1371 {
1372 if (visual < 0 || visual > DirectColor)
1373 return NULL;
1374
1375 return xf86VisualNames[visual];
1376 }
1377
1378 int
xf86GetVerbosity(void)1379 xf86GetVerbosity(void)
1380 {
1381 return max(xf86Verbose, xf86LogVerbose);
1382 }
1383
1384 int
xf86GetDepth(void)1385 xf86GetDepth(void)
1386 {
1387 return xf86Depth;
1388 }
1389
1390 rgb
xf86GetWeight(void)1391 xf86GetWeight(void)
1392 {
1393 return xf86Weight;
1394 }
1395
1396 Gamma
xf86GetGamma(void)1397 xf86GetGamma(void)
1398 {
1399 return xf86Gamma;
1400 }
1401
1402 Bool
xf86GetFlipPixels(void)1403 xf86GetFlipPixels(void)
1404 {
1405 return xf86FlipPixels;
1406 }
1407
1408 const char *
xf86GetServerName(void)1409 xf86GetServerName(void)
1410 {
1411 return xf86ServerName;
1412 }
1413
1414 Bool
xf86ServerIsExiting(void)1415 xf86ServerIsExiting(void)
1416 {
1417 return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
1418 }
1419
1420 Bool
xf86ServerIsResetting(void)1421 xf86ServerIsResetting(void)
1422 {
1423 return xf86Resetting;
1424 }
1425
1426 Bool
xf86ServerIsOnlyDetecting(void)1427 xf86ServerIsOnlyDetecting(void)
1428 {
1429 return xf86DoConfigure;
1430 }
1431
1432 Bool
xf86GetVidModeAllowNonLocal(void)1433 xf86GetVidModeAllowNonLocal(void)
1434 {
1435 return xf86Info.vidModeAllowNonLocal;
1436 }
1437
1438 Bool
xf86GetVidModeEnabled(void)1439 xf86GetVidModeEnabled(void)
1440 {
1441 return xf86Info.vidModeEnabled;
1442 }
1443
1444 Bool
xf86GetModInDevAllowNonLocal(void)1445 xf86GetModInDevAllowNonLocal(void)
1446 {
1447 return xf86Info.miscModInDevAllowNonLocal;
1448 }
1449
1450 Bool
xf86GetModInDevEnabled(void)1451 xf86GetModInDevEnabled(void)
1452 {
1453 return xf86Info.miscModInDevEnabled;
1454 }
1455
1456 Bool
xf86GetAllowMouseOpenFail(void)1457 xf86GetAllowMouseOpenFail(void)
1458 {
1459 return xf86Info.allowMouseOpenFail;
1460 }
1461
1462 CARD32
xf86GetModuleVersion(void * module)1463 xf86GetModuleVersion(void *module)
1464 {
1465 return (CARD32) LoaderGetModuleVersion(module);
1466 }
1467
1468 void *
xf86LoadDrvSubModule(DriverPtr drv,const char * name)1469 xf86LoadDrvSubModule(DriverPtr drv, const char *name)
1470 {
1471 void *ret;
1472 int errmaj = 0, errmin = 0;
1473
1474 ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
1475 &errmaj, &errmin);
1476 if (!ret)
1477 LoaderErrorMsg(NULL, name, errmaj, errmin);
1478 return ret;
1479 }
1480
1481 void *
xf86LoadSubModule(ScrnInfoPtr pScrn,const char * name)1482 xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
1483 {
1484 void *ret;
1485 int errmaj = 0, errmin = 0;
1486
1487 ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
1488 &errmaj, &errmin);
1489 if (!ret)
1490 LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
1491 return ret;
1492 }
1493
1494 /*
1495 * xf86LoadOneModule loads a single module.
1496 */
1497 void *
xf86LoadOneModule(const char * name,void * opt)1498 xf86LoadOneModule(const char *name, void *opt)
1499 {
1500 int errmaj;
1501 char *Name;
1502 void *mod;
1503
1504 if (!name)
1505 return NULL;
1506
1507 /* Normalise the module name */
1508 Name = xf86NormalizeName(name);
1509
1510 /* Skip empty names */
1511 if (Name == NULL)
1512 return NULL;
1513 if (*Name == '\0') {
1514 free(Name);
1515 return NULL;
1516 }
1517
1518 mod = LoadModule(Name, opt, NULL, &errmaj);
1519 if (!mod)
1520 LoaderErrorMsg(NULL, Name, errmaj, 0);
1521 free(Name);
1522 return mod;
1523 }
1524
1525 void
xf86UnloadSubModule(void * mod)1526 xf86UnloadSubModule(void *mod)
1527 {
1528 UnloadSubModule(mod);
1529 }
1530
1531 Bool
xf86LoaderCheckSymbol(const char * name)1532 xf86LoaderCheckSymbol(const char *name)
1533 {
1534 return LoaderSymbol(name) != NULL;
1535 }
1536
1537 typedef enum {
1538 OPTION_BACKING_STORE
1539 } BSOpts;
1540
1541 static const OptionInfoRec BSOptions[] = {
1542 {OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE},
1543 {-1, NULL, OPTV_NONE, {0}, FALSE}
1544 };
1545
1546 void
xf86SetBackingStore(ScreenPtr pScreen)1547 xf86SetBackingStore(ScreenPtr pScreen)
1548 {
1549 Bool useBS = FALSE;
1550 MessageType from = X_DEFAULT;
1551 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1552 OptionInfoPtr options;
1553
1554 options = xnfalloc(sizeof(BSOptions));
1555 (void) memcpy(options, BSOptions, sizeof(BSOptions));
1556 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
1557
1558 /* check for commandline option here */
1559 if (xf86bsEnableFlag) {
1560 from = X_CMDLINE;
1561 useBS = TRUE;
1562 }
1563 else if (xf86bsDisableFlag) {
1564 from = X_CMDLINE;
1565 useBS = FALSE;
1566 }
1567 else {
1568 if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
1569 from = X_CONFIG;
1570 #ifdef COMPOSITE
1571 if (from != X_CONFIG)
1572 useBS = xf86ReturnOptValBool(options, OPTION_BACKING_STORE,
1573 !noCompositeExtension);
1574 #endif
1575 }
1576 free(options);
1577 pScreen->backingStoreSupport = useBS ? WhenMapped : NotUseful;
1578 if (serverGeneration == 1)
1579 xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
1580 useBS ? "enabled" : "disabled");
1581 }
1582
1583 typedef enum {
1584 OPTION_SILKEN_MOUSE
1585 } SMOpts;
1586
1587 static const OptionInfoRec SMOptions[] = {
1588 {OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE},
1589 {-1, NULL, OPTV_NONE, {0}, FALSE}
1590 };
1591
1592 void
xf86SetSilkenMouse(ScreenPtr pScreen)1593 xf86SetSilkenMouse(ScreenPtr pScreen)
1594 {
1595 Bool useSM = TRUE;
1596 MessageType from = X_DEFAULT;
1597 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1598 OptionInfoPtr options;
1599
1600 options = xnfalloc(sizeof(SMOptions));
1601 (void) memcpy(options, SMOptions, sizeof(SMOptions));
1602 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
1603
1604 /* check for commandline option here */
1605 /* disable if screen shares resources */
1606 /* TODO VGA arb disable silken mouse */
1607 if (xf86silkenMouseDisableFlag) {
1608 from = X_CMDLINE;
1609 useSM = FALSE;
1610 }
1611 else {
1612 if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
1613 from = X_CONFIG;
1614 }
1615 free(options);
1616 /*
1617 * Use silken mouse if requested and if we have threaded input
1618 */
1619 pScrn->silkenMouse = useSM && InputThreadEnable;
1620 if (serverGeneration == 1)
1621 xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
1622 pScrn->silkenMouse ? "enabled" : "disabled");
1623 }
1624
1625 /* Wrote this function for the PM2 Xv driver, preliminary. */
1626
1627 void *
xf86FindXvOptions(ScrnInfoPtr pScrn,int adaptor_index,const char * port_name,const char ** adaptor_name,void ** adaptor_options)1628 xf86FindXvOptions(ScrnInfoPtr pScrn, int adaptor_index, const char *port_name,
1629 const char **adaptor_name, void **adaptor_options)
1630 {
1631 confXvAdaptorPtr adaptor;
1632 int i;
1633
1634 if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
1635 if (adaptor_name)
1636 *adaptor_name = NULL;
1637 if (adaptor_options)
1638 *adaptor_options = NULL;
1639 return NULL;
1640 }
1641
1642 adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
1643 if (adaptor_name)
1644 *adaptor_name = adaptor->identifier;
1645 if (adaptor_options)
1646 *adaptor_options = adaptor->options;
1647
1648 for (i = 0; i < adaptor->numports; i++)
1649 if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
1650 return adaptor->ports[i].options;
1651
1652 return NULL;
1653 }
1654
1655 static void
xf86ConfigFbEntityInactive(EntityInfoPtr pEnt,EntityProc init,EntityProc enter,EntityProc leave,void * private)1656 xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
1657 EntityProc enter, EntityProc leave, void *private)
1658 {
1659 ScrnInfoPtr pScrn;
1660
1661 if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
1662 xf86RemoveEntityFromScreen(pScrn, pEnt->index);
1663 }
1664
1665 ScrnInfoPtr
xf86ConfigFbEntity(ScrnInfoPtr pScrn,int scrnFlag,int entityIndex,EntityProc init,EntityProc enter,EntityProc leave,void * private)1666 xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
1667 EntityProc init, EntityProc enter, EntityProc leave,
1668 void *private)
1669 {
1670 EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
1671
1672 if (init || enter || leave)
1673 FatalError("Legacy entity access functions are unsupported\n");
1674
1675 if (!pEnt)
1676 return pScrn;
1677
1678 if (!(pEnt->location.type == BUS_NONE)) {
1679 free(pEnt);
1680 return pScrn;
1681 }
1682
1683 if (!pEnt->active) {
1684 xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
1685 free(pEnt);
1686 return pScrn;
1687 }
1688
1689 if (!pScrn)
1690 pScrn = xf86AllocateScreen(pEnt->driver, scrnFlag);
1691 xf86AddEntityToScreen(pScrn, entityIndex);
1692
1693 free(pEnt);
1694 return pScrn;
1695 }
1696
1697 Bool
xf86IsScreenPrimary(ScrnInfoPtr pScrn)1698 xf86IsScreenPrimary(ScrnInfoPtr pScrn)
1699 {
1700 int i;
1701
1702 for (i = 0; i < pScrn->numEntities; i++) {
1703 if (xf86IsEntityPrimary(i))
1704 return TRUE;
1705 }
1706 return FALSE;
1707 }
1708
1709 Bool
xf86IsUnblank(int mode)1710 xf86IsUnblank(int mode)
1711 {
1712 switch (mode) {
1713 case SCREEN_SAVER_OFF:
1714 case SCREEN_SAVER_FORCER:
1715 return TRUE;
1716 case SCREEN_SAVER_ON:
1717 case SCREEN_SAVER_CYCLE:
1718 return FALSE;
1719 default:
1720 xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
1721 return TRUE;
1722 }
1723 }
1724
1725 void
xf86MotionHistoryAllocate(InputInfoPtr pInfo)1726 xf86MotionHistoryAllocate(InputInfoPtr pInfo)
1727 {
1728 AllocateMotionHistory(pInfo->dev);
1729 }
1730
1731 ScrnInfoPtr
xf86ScreenToScrn(ScreenPtr pScreen)1732 xf86ScreenToScrn(ScreenPtr pScreen)
1733 {
1734 if (pScreen->isGPU) {
1735 assert(pScreen->myNum - GPU_SCREEN_OFFSET < xf86NumGPUScreens);
1736 return xf86GPUScreens[pScreen->myNum - GPU_SCREEN_OFFSET];
1737 } else {
1738 assert(pScreen->myNum < xf86NumScreens);
1739 return xf86Screens[pScreen->myNum];
1740 }
1741 }
1742
1743 ScreenPtr
xf86ScrnToScreen(ScrnInfoPtr pScrn)1744 xf86ScrnToScreen(ScrnInfoPtr pScrn)
1745 {
1746 if (pScrn->is_gpu) {
1747 assert(pScrn->scrnIndex - GPU_SCREEN_OFFSET < screenInfo.numGPUScreens);
1748 return screenInfo.gpuscreens[pScrn->scrnIndex - GPU_SCREEN_OFFSET];
1749 } else {
1750 assert(pScrn->scrnIndex < screenInfo.numScreens);
1751 return screenInfo.screens[pScrn->scrnIndex];
1752 }
1753 }
1754
1755 void
xf86UpdateDesktopDimensions(void)1756 xf86UpdateDesktopDimensions(void)
1757 {
1758 update_desktop_dimensions();
1759 }
1760