Commit | Line | Data |
---|---|---|
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 | ||
65 | static int xf86ScrnInfoPrivateCount = 0; | |
66 | ||
67 | /* Add a pointer to a new DriverRec to xf86DriverList */ | |
68 | ||
69 | void | |
70 | xf86AddDriver(DriverPtr driver, pointer module, int flags) | |
71 | { | |
72 | /* Don't add null entries */ | |
73 | if (!driver) | |
74 | return; | |
75 | ||
76 | if (xf86DriverList == NULL) | |
77 | xf86NumDrivers = 0; | |
78 | ||
79 | xf86NumDrivers++; | |
80 | xf86DriverList = xnfrealloc(xf86DriverList, | |
81 | xf86NumDrivers * sizeof(DriverPtr)); | |
82 | xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec)); | |
83 | if (flags & HaveDriverFuncs) | |
84 | *xf86DriverList[xf86NumDrivers - 1] = *driver; | |
85 | else { | |
86 | (void) memset(xf86DriverList[xf86NumDrivers - 1], 0, sizeof(DriverRec)); | |
87 | (void) memcpy(xf86DriverList[xf86NumDrivers - 1], driver, | |
88 | sizeof(DriverRec1)); | |
89 | ||
90 | } | |
91 | xf86DriverList[xf86NumDrivers - 1]->module = module; | |
92 | xf86DriverList[xf86NumDrivers - 1]->refCount = 0; | |
93 | } | |
94 | ||
95 | void | |
96 | xf86DeleteDriver(int drvIndex) | |
97 | { | |
98 | if (xf86DriverList[drvIndex] | |
99 | && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) { | |
100 | if (xf86DriverList[drvIndex]->module) | |
101 | UnloadModule(xf86DriverList[drvIndex]->module); | |
102 | free(xf86DriverList[drvIndex]); | |
103 | xf86DriverList[drvIndex] = NULL; | |
104 | } | |
105 | } | |
106 | ||
107 | /* Add a pointer to a new InputDriverRec to xf86InputDriverList */ | |
108 | ||
109 | void | |
110 | xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags) | |
111 | { | |
112 | /* Don't add null entries */ | |
113 | if (!driver) | |
114 | return; | |
115 | ||
116 | if (xf86InputDriverList == NULL) | |
117 | xf86NumInputDrivers = 0; | |
118 | ||
119 | xf86NumInputDrivers++; | |
120 | xf86InputDriverList = xnfrealloc(xf86InputDriverList, | |
121 | xf86NumInputDrivers * | |
122 | sizeof(InputDriverPtr)); | |
123 | xf86InputDriverList[xf86NumInputDrivers - 1] = | |
124 | xnfalloc(sizeof(InputDriverRec)); | |
125 | *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver; | |
126 | xf86InputDriverList[xf86NumInputDrivers - 1]->module = module; | |
127 | } | |
128 | ||
129 | void | |
130 | xf86DeleteInputDriver(int drvIndex) | |
131 | { | |
132 | if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module) | |
133 | UnloadModule(xf86InputDriverList[drvIndex]->module); | |
134 | free(xf86InputDriverList[drvIndex]); | |
135 | xf86InputDriverList[drvIndex] = NULL; | |
136 | } | |
137 | ||
138 | InputDriverPtr | |
139 | xf86LookupInputDriver(const char *name) | |
140 | { | |
141 | int i; | |
142 | ||
143 | for (i = 0; i < xf86NumInputDrivers; i++) { | |
144 | if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && | |
145 | xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0) | |
146 | return xf86InputDriverList[i]; | |
147 | } | |
148 | return NULL; | |
149 | } | |
150 | ||
151 | InputInfoPtr | |
152 | xf86LookupInput(const char *name) | |
153 | { | |
154 | InputInfoPtr p; | |
155 | ||
156 | for (p = xf86InputDevs; p != NULL; p = p->next) { | |
157 | if (strcmp(name, p->name) == 0) | |
158 | return p; | |
159 | } | |
160 | ||
161 | return NULL; | |
162 | } | |
163 | ||
164 | /* Allocate a new ScrnInfoRec in xf86Screens */ | |
165 | ||
166 | ScrnInfoPtr | |
167 | xf86AllocateScreen(DriverPtr drv, int flags) | |
168 | { | |
169 | int i; | |
170 | ScrnInfoPtr pScrn; | |
171 | ||
172 | if (flags & XF86_ALLOCATE_GPU_SCREEN) { | |
173 | if (xf86GPUScreens == NULL) | |
174 | xf86NumGPUScreens = 0; | |
175 | i = xf86NumGPUScreens++; | |
176 | xf86GPUScreens = xnfrealloc(xf86GPUScreens, xf86NumGPUScreens * sizeof(ScrnInfoPtr)); | |
177 | xf86GPUScreens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); | |
178 | pScrn = xf86GPUScreens[i]; | |
179 | pScrn->scrnIndex = i + GPU_SCREEN_OFFSET; /* Changes when a screen is removed */ | |
180 | pScrn->is_gpu = TRUE; | |
181 | } else { | |
182 | if (xf86Screens == NULL) | |
183 | xf86NumScreens = 0; | |
184 | ||
185 | i = xf86NumScreens++; | |
186 | xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr)); | |
187 | xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1); | |
188 | pScrn = xf86Screens[i]; | |
189 | ||
190 | pScrn->scrnIndex = i; /* Changes when a screen is removed */ | |
191 | } | |
192 | ||
193 | pScrn->origIndex = pScrn->scrnIndex; /* This never changes */ | |
194 | pScrn->privates = xnfcalloc(sizeof(DevUnion), xf86ScrnInfoPrivateCount); | |
195 | /* | |
196 | * EnableDisableFBAccess now gets initialized in InitOutput() | |
197 | * pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess; | |
198 | */ | |
199 | ||
200 | pScrn->drv = drv; | |
201 | drv->refCount++; | |
202 | pScrn->module = DuplicateModule(drv->module, NULL); | |
203 | ||
204 | pScrn->DriverFunc = drv->driverFunc; | |
205 | ||
206 | return pScrn; | |
207 | } | |
208 | ||
209 | /* | |
210 | * Remove an entry from xf86Screens. Ideally it should free all allocated | |
211 | * data. To do this properly may require a driver hook. | |
212 | */ | |
213 | ||
214 | void | |
215 | xf86DeleteScreen(ScrnInfoPtr pScrn) | |
216 | { | |
217 | int i; | |
218 | int scrnIndex; | |
219 | Bool is_gpu = FALSE; | |
220 | ||
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 | ||
286 | int | |
287 | xf86AllocateScrnInfoPrivateIndex(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 | ||
313 | Bool | |
314 | xf86AddPixFormat(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 | ||
384 | Bool | |
385 | xf86SetDepthBpp(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 | */ | |
710 | void | |
711 | xf86PrintDepthBpp(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 | */ | |
721 | Bool | |
722 | xf86SetWeight(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 | ||
820 | Bool | |
821 | xf86SetDefaultVisual(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 | ||
870 | Bool | |
871 | xf86SetGamma(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 | ||
933 | void | |
934 | xf86SetDpi(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 | ||
1036 | void | |
1037 | xf86SetBlackWhitePixels(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 | */ | |
1068 | void | |
1069 | xf86EnableDisableFBAccess(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> */ | |
1093 | void | |
1094 | xf86VDrvMsgVerb(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 */ | |
1112 | void | |
1113 | xf86DrvMsgVerb(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) */ | |
1124 | void | |
1125 | xf86DrvMsg(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> */ | |
1136 | void | |
1137 | xf86VIDrvMsgVerb(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 */ | |
1155 | void | |
1156 | xf86IDrvMsgVerb(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) */ | |
1167 | void | |
1168 | xf86IDrvMsg(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 */ | |
1178 | void | |
1179 | xf86MsgVerb(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) */ | |
1189 | void | |
1190 | xf86Msg(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 */ | |
1200 | void | |
1201 | xf86ErrorFVerb(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 */ | |
1212 | void | |
1213 | xf86ErrorF(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 | ||
1223 | void | |
1224 | xf86LogInit(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 | ||
1251 | void | |
1252 | xf86CloseLog(enum ExitCode error) | |
1253 | { | |
1254 | LogClose(error); | |
1255 | } | |
1256 | ||
1257 | /* | |
1258 | * Drivers can use these for using their own SymTabRecs. | |
1259 | */ | |
1260 | ||
1261 | const char * | |
1262 | xf86TokenToString(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 | ||
1274 | int | |
1275 | xf86StringToToken(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 | */ | |
1290 | void | |
1291 | xf86ShowClocks(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 | */ | |
1313 | void | |
1314 | xf86PrintChipsets(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 | ||
1339 | int | |
1340 | xf86MatchDevice(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 | ||
1416 | const char * | |
1417 | xf86GetVisualName(int visual) | |
1418 | { | |
1419 | if (visual < 0 || visual > DirectColor) | |
1420 | return NULL; | |
1421 | ||
1422 | return xf86VisualNames[visual]; | |
1423 | } | |
1424 | ||
1425 | int | |
1426 | xf86GetVerbosity(void) | |
1427 | { | |
1428 | return max(xf86Verbose, xf86LogVerbose); | |
1429 | } | |
1430 | ||
1431 | Pix24Flags | |
1432 | xf86GetPix24(void) | |
1433 | { | |
1434 | return xf86Info.pixmap24; | |
1435 | } | |
1436 | ||
1437 | int | |
1438 | xf86GetDepth(void) | |
1439 | { | |
1440 | return xf86Depth; | |
1441 | } | |
1442 | ||
1443 | rgb | |
1444 | xf86GetWeight(void) | |
1445 | { | |
1446 | return xf86Weight; | |
1447 | } | |
1448 | ||
1449 | Gamma | |
1450 | xf86GetGamma(void) | |
1451 | { | |
1452 | return xf86Gamma; | |
1453 | } | |
1454 | ||
1455 | Bool | |
1456 | xf86GetFlipPixels(void) | |
1457 | { | |
1458 | return xf86FlipPixels; | |
1459 | } | |
1460 | ||
1461 | const char * | |
1462 | xf86GetServerName(void) | |
1463 | { | |
1464 | return xf86ServerName; | |
1465 | } | |
1466 | ||
1467 | Bool | |
1468 | xf86ServerIsExiting(void) | |
1469 | { | |
1470 | return (dispatchException & DE_TERMINATE) == DE_TERMINATE; | |
1471 | } | |
1472 | ||
1473 | Bool | |
1474 | xf86ServerIsResetting(void) | |
1475 | { | |
1476 | return xf86Resetting; | |
1477 | } | |
1478 | ||
1479 | Bool | |
1480 | xf86ServerIsInitialising(void) | |
1481 | { | |
1482 | return xf86Initialising; | |
1483 | } | |
1484 | ||
1485 | Bool | |
1486 | xf86ServerIsOnlyDetecting(void) | |
1487 | { | |
1488 | return xf86DoConfigure; | |
1489 | } | |
1490 | ||
1491 | Bool | |
1492 | xf86CaughtSignal(void) | |
1493 | { | |
1494 | return xf86Info.caughtSignal; | |
1495 | } | |
1496 | ||
1497 | Bool | |
1498 | xf86GetVidModeAllowNonLocal(void) | |
1499 | { | |
1500 | return xf86Info.vidModeAllowNonLocal; | |
1501 | } | |
1502 | ||
1503 | Bool | |
1504 | xf86GetVidModeEnabled(void) | |
1505 | { | |
1506 | return xf86Info.vidModeEnabled; | |
1507 | } | |
1508 | ||
1509 | Bool | |
1510 | xf86GetModInDevAllowNonLocal(void) | |
1511 | { | |
1512 | return xf86Info.miscModInDevAllowNonLocal; | |
1513 | } | |
1514 | ||
1515 | Bool | |
1516 | xf86GetModInDevEnabled(void) | |
1517 | { | |
1518 | return xf86Info.miscModInDevEnabled; | |
1519 | } | |
1520 | ||
1521 | Bool | |
1522 | xf86GetAllowMouseOpenFail(void) | |
1523 | { | |
1524 | return xf86Info.allowMouseOpenFail; | |
1525 | } | |
1526 | ||
1527 | void | |
1528 | xf86DisableRandR(void) | |
1529 | { | |
1530 | xf86Info.disableRandR = TRUE; | |
1531 | xf86Info.randRFrom = X_PROBED; | |
1532 | } | |
1533 | ||
1534 | CARD32 | |
1535 | xf86GetModuleVersion(pointer module) | |
1536 | { | |
1537 | return (CARD32) LoaderGetModuleVersion(module); | |
1538 | } | |
1539 | ||
1540 | pointer | |
1541 | xf86LoadDrvSubModule(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 | ||
1553 | pointer | |
1554 | xf86LoadSubModule(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 | */ | |
1569 | pointer | |
1570 | xf86LoadOneModule(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 | ||
1597 | void | |
1598 | xf86UnloadSubModule(pointer mod) | |
1599 | { | |
1600 | UnloadSubModule(mod); | |
1601 | } | |
1602 | ||
1603 | Bool | |
1604 | xf86LoaderCheckSymbol(const char *name) | |
1605 | { | |
1606 | return LoaderSymbol(name) != NULL; | |
1607 | } | |
1608 | ||
1609 | typedef enum { | |
1610 | OPTION_BACKING_STORE | |
1611 | } BSOpts; | |
1612 | ||
1613 | static const OptionInfoRec BSOptions[] = { | |
1614 | {OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE}, | |
1615 | {-1, NULL, OPTV_NONE, {0}, FALSE} | |
1616 | }; | |
1617 | ||
1618 | void | |
1619 | xf86SetBackingStore(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 | ||
1655 | typedef enum { | |
1656 | OPTION_SILKEN_MOUSE | |
1657 | } SMOpts; | |
1658 | ||
1659 | static const OptionInfoRec SMOptions[] = { | |
1660 | {OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE}, | |
1661 | {-1, NULL, OPTV_NONE, {0}, FALSE} | |
1662 | }; | |
1663 | ||
1664 | void | |
1665 | xf86SetSilkenMouse(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 | ||
1701 | pointer | |
1702 | xf86FindXvOptions(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 | ||
1733 | static void | |
1734 | xf86ConfigFbEntityInactive(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 | ||
1744 | ScrnInfoPtr | |
1745 | xf86ConfigFbEntity(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 | ||
1775 | Bool | |
1776 | xf86IsScreenPrimary(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 | ||
1787 | int | |
1788 | xf86RegisterRootWindowProperty(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 | ||
1862 | Bool | |
1863 | xf86IsUnblank(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 | ||
1878 | void | |
1879 | xf86MotionHistoryAllocate(InputInfoPtr pInfo) | |
1880 | { | |
1881 | AllocateMotionHistory(pInfo->dev); | |
1882 | } | |
1883 | ||
1884 | ScrnInfoPtr | |
1885 | xf86ScreenToScrn(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 | ||
1896 | ScreenPtr | |
1897 | xf86ScrnToScreen(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 | ||
1908 | void | |
1909 | xf86UpdateDesktopDimensions(void) | |
1910 | { | |
1911 | update_desktop_dimensions(); | |
1912 | } |