Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Loosely based on code bearing the following copyright: | |
3 | * | |
4 | * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. | |
5 | */ | |
6 | /* | |
7 | * Copyright (c) 1992-2003 by The XFree86 Project, Inc. | |
8 | * | |
9 | * Permission is hereby granted, free of charge, to any person obtaining a | |
10 | * copy of this software and associated documentation files (the "Software"), | |
11 | * to deal in the Software without restriction, including without limitation | |
12 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
13 | * and/or sell copies of the Software, and to permit persons to whom the | |
14 | * Software is furnished to do so, subject to the following conditions: | |
15 | * | |
16 | * The above copyright notice and this permission notice shall be included in | |
17 | * all copies or substantial portions of the Software. | |
18 | * | |
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
22 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
23 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
24 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
25 | * OTHER DEALINGS IN THE SOFTWARE. | |
26 | * | |
27 | * Except as contained in this notice, the name of the copyright holder(s) | |
28 | * and author(s) shall not be used in advertising or otherwise to promote | |
29 | * the sale, use or other dealings in this Software without prior written | |
30 | * authorization from the copyright holder(s) and author(s). | |
31 | */ | |
32 | ||
33 | #ifdef HAVE_XORG_CONFIG_H | |
34 | #include <xorg-config.h> | |
35 | #endif | |
36 | ||
37 | #include <stdlib.h> | |
38 | #include <errno.h> | |
39 | ||
40 | #undef HAS_UTSNAME | |
41 | #if !defined(WIN32) | |
42 | #define HAS_UTSNAME 1 | |
43 | #include <sys/utsname.h> | |
44 | #endif | |
45 | ||
46 | #include <X11/X.h> | |
47 | #include <X11/Xmd.h> | |
48 | #include <X11/Xproto.h> | |
49 | #include <X11/Xatom.h> | |
50 | #include "input.h" | |
51 | #include "servermd.h" | |
52 | #include "windowstr.h" | |
53 | #include "scrnintstr.h" | |
54 | #include "site.h" | |
55 | #include "mi.h" | |
56 | ||
57 | #include "compiler.h" | |
58 | ||
59 | #include "loaderProcs.h" | |
60 | #ifdef XFreeXDGA | |
61 | #include "dgaproc.h" | |
62 | #endif | |
63 | ||
64 | #define XF86_OS_PRIVS | |
65 | #include "xf86.h" | |
66 | #include "xf86Priv.h" | |
67 | #include "xf86Config.h" | |
68 | #include "xf86_OSlib.h" | |
69 | #include "xf86cmap.h" | |
70 | #include "xorgVersion.h" | |
71 | #include "xf86Build.h" | |
72 | #include "mipointer.h" | |
73 | #include <X11/extensions/XI.h> | |
74 | #include <X11/extensions/XIproto.h> | |
75 | #include "xf86DDC.h" | |
76 | #include "xf86Xinput.h" | |
77 | #include "xf86InPriv.h" | |
78 | #include "picturestr.h" | |
79 | ||
80 | #include "xf86Bus.h" | |
81 | #ifdef XSERVER_LIBPCIACCESS | |
82 | #include "xf86VGAarbiter.h" | |
83 | #endif | |
84 | #include "globals.h" | |
85 | #include "xserver-properties.h" | |
86 | ||
87 | #ifdef DPMSExtension | |
88 | #include <X11/extensions/dpmsconst.h> | |
89 | #include "dpmsproc.h" | |
90 | #endif | |
91 | #include <hotplug.h> | |
92 | ||
93 | #ifdef XF86PM | |
94 | void (*xf86OSPMClose) (void) = NULL; | |
95 | #endif | |
96 | static Bool xorgHWOpenConsole = FALSE; | |
97 | ||
98 | /* Common pixmap formats */ | |
99 | ||
100 | static PixmapFormatRec formats[MAXFORMATS] = { | |
101 | {1, 1, BITMAP_SCANLINE_PAD}, | |
102 | {4, 8, BITMAP_SCANLINE_PAD}, | |
103 | {8, 8, BITMAP_SCANLINE_PAD}, | |
104 | {15, 16, BITMAP_SCANLINE_PAD}, | |
105 | {16, 16, BITMAP_SCANLINE_PAD}, | |
106 | {24, 32, BITMAP_SCANLINE_PAD}, | |
107 | {32, 32, BITMAP_SCANLINE_PAD}, | |
108 | }; | |
109 | ||
110 | static int numFormats = 7; | |
111 | static Bool formatsDone = FALSE; | |
112 | ||
113 | #ifndef OSNAME | |
114 | #define OSNAME " unknown" | |
115 | #endif | |
116 | #ifndef OSVENDOR | |
117 | #define OSVENDOR "" | |
118 | #endif | |
119 | #ifndef PRE_RELEASE | |
120 | #define PRE_RELEASE XORG_VERSION_SNAP | |
121 | #endif | |
122 | ||
123 | static void | |
124 | xf86PrintBanner(void) | |
125 | { | |
126 | #if PRE_RELEASE | |
127 | xf86ErrorFVerb(0, "\n" | |
128 | "This is a pre-release version of the X server from " | |
129 | XVENDORNAME ".\n" "It is not supported in any way.\n" | |
130 | "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n" | |
131 | "Select the \"xorg\" product for bugs you find in this release.\n" | |
132 | "Before reporting bugs in pre-release versions please check the\n" | |
133 | "latest version in the X.Org Foundation git repository.\n" | |
134 | "See http://wiki.x.org/wiki/GitPage for git access instructions.\n"); | |
135 | #endif | |
136 | xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d", | |
137 | XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH); | |
138 | #if XORG_VERSION_SNAP > 0 | |
139 | xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP); | |
140 | #endif | |
141 | ||
142 | #if XORG_VERSION_SNAP >= 900 | |
143 | /* When the minor number is 99, that signifies that the we are making | |
144 | * a release candidate for a major version. (X.0.0) | |
145 | * When the patch number is 99, that signifies that the we are making | |
146 | * a release candidate for a minor version. (X.Y.0) | |
147 | * When the patch number is < 99, then we are making a release | |
148 | * candidate for the next point release. (X.Y.Z) | |
149 | */ | |
150 | #if XORG_VERSION_MINOR >= 99 | |
151 | xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR + 1, | |
152 | XORG_VERSION_SNAP - 900); | |
153 | #elif XORG_VERSION_PATCH == 99 | |
154 | xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR, | |
155 | XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900); | |
156 | #else | |
157 | xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR, | |
158 | XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1, | |
159 | XORG_VERSION_SNAP - 900); | |
160 | #endif | |
161 | #endif | |
162 | ||
163 | #ifdef XORG_CUSTOM_VERSION | |
164 | xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION); | |
165 | #endif | |
166 | #ifndef XORG_DATE | |
167 | #define XORG_DATE "Unknown" | |
168 | #endif | |
169 | xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE); | |
170 | xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n", | |
171 | X_PROTOCOL, X_PROTOCOL_REVISION); | |
172 | xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR); | |
173 | #ifdef HAS_UTSNAME | |
174 | { | |
175 | struct utsname name; | |
176 | ||
177 | /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX, | |
178 | and Irix) and Single Unix Spec 3 just say that non-negative is success. | |
179 | All agree that failure is represented by a negative number. | |
180 | */ | |
181 | if (uname(&name) >= 0) { | |
182 | xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n", | |
183 | name.sysname, name.nodename, name.release, | |
184 | name.version, name.machine); | |
185 | #ifdef linux | |
186 | do { | |
187 | char buf[80]; | |
188 | int fd = open("/proc/cmdline", O_RDONLY); | |
189 | ||
190 | if (fd != -1) { | |
191 | xf86ErrorFVerb(0, "Kernel command line: "); | |
192 | memset(buf, 0, 80); | |
193 | while (read(fd, buf, 80) > 0) { | |
194 | xf86ErrorFVerb(0, "%.80s", buf); | |
195 | memset(buf, 0, 80); | |
196 | } | |
197 | close(fd); | |
198 | } | |
199 | } while (0); | |
200 | #endif | |
201 | } | |
202 | } | |
203 | #endif | |
204 | #if defined(BUILD_DATE) && (BUILD_DATE > 19000000) | |
205 | { | |
206 | struct tm t; | |
207 | char buf[100]; | |
208 | ||
209 | memset(&t, 0, sizeof(t)); | |
210 | memset(buf, 0, sizeof(buf)); | |
211 | t.tm_mday = BUILD_DATE % 100; | |
212 | t.tm_mon = (BUILD_DATE / 100) % 100 - 1; | |
213 | t.tm_year = BUILD_DATE / 10000 - 1900; | |
214 | #if defined(BUILD_TIME) | |
215 | t.tm_sec = BUILD_TIME % 100; | |
216 | t.tm_min = (BUILD_TIME / 100) % 100; | |
217 | t.tm_hour = (BUILD_TIME / 10000) % 100; | |
218 | if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t)) | |
219 | xf86ErrorFVerb(0, "Build Date: %s\n", buf); | |
220 | #else | |
221 | if (strftime(buf, sizeof(buf), "%d %B %Y", &t)) | |
222 | xf86ErrorFVerb(0, "Build Date: %s\n", buf); | |
223 | #endif | |
224 | } | |
225 | #endif | |
226 | #if defined(BUILDERSTRING) | |
227 | xf86ErrorFVerb(0, "%s \n", BUILDERSTRING); | |
228 | #endif | |
229 | xf86ErrorFVerb(0, "Current version of pixman: %s\n", | |
230 | pixman_version_string()); | |
231 | xf86ErrorFVerb(0, "\tBefore reporting problems, check " | |
232 | "" __VENDORDWEBSUPPORT__ "\n" | |
233 | "\tto make sure that you have the latest version.\n"); | |
234 | } | |
235 | ||
236 | static void | |
237 | xf86PrintMarkers(void) | |
238 | { | |
239 | LogPrintMarkers(); | |
240 | } | |
241 | ||
242 | Bool | |
243 | xf86PrivsElevated(void) | |
244 | { | |
245 | static Bool privsTested = FALSE; | |
246 | static Bool privsElevated = TRUE; | |
247 | ||
248 | if (!privsTested) { | |
249 | #if defined(WIN32) | |
250 | privsElevated = FALSE; | |
251 | #else | |
252 | if ((getuid() != geteuid()) || (getgid() != getegid())) { | |
253 | privsElevated = TRUE; | |
254 | } | |
255 | else { | |
256 | #if defined(HAVE_ISSETUGID) | |
257 | privsElevated = issetugid(); | |
258 | #elif defined(HAVE_GETRESUID) | |
259 | uid_t ruid, euid, suid; | |
260 | gid_t rgid, egid, sgid; | |
261 | ||
262 | if ((getresuid(&ruid, &euid, &suid) == 0) && | |
263 | (getresgid(&rgid, &egid, &sgid) == 0)) { | |
264 | privsElevated = (euid != suid) || (egid != sgid); | |
265 | } | |
266 | else { | |
267 | printf("Failed getresuid or getresgid"); | |
268 | /* Something went wrong, make defensive assumption */ | |
269 | privsElevated = TRUE; | |
270 | } | |
271 | #else | |
272 | if (getuid() == 0) { | |
273 | /* running as root: uid==euid==0 */ | |
274 | privsElevated = FALSE; | |
275 | } | |
276 | else { | |
277 | /* | |
278 | * If there are saved ID's the process might still be privileged | |
279 | * even though the above test succeeded. If issetugid() and | |
280 | * getresgid() aren't available, test this by trying to set | |
281 | * euid to 0. | |
282 | */ | |
283 | unsigned int oldeuid; | |
284 | ||
285 | oldeuid = geteuid(); | |
286 | ||
287 | if (seteuid(0) != 0) { | |
288 | privsElevated = FALSE; | |
289 | } | |
290 | else { | |
291 | if (seteuid(oldeuid) != 0) { | |
292 | FatalError("Failed to drop privileges. Exiting\n"); | |
293 | } | |
294 | privsElevated = TRUE; | |
295 | } | |
296 | } | |
297 | #endif | |
298 | } | |
299 | #endif | |
300 | privsTested = TRUE; | |
301 | } | |
302 | return privsElevated; | |
303 | } | |
304 | ||
305 | static Bool | |
306 | xf86CreateRootWindow(WindowPtr pWin) | |
307 | { | |
308 | int ret = TRUE; | |
309 | int err = Success; | |
310 | ScreenPtr pScreen = pWin->drawable.pScreen; | |
311 | RootWinPropPtr pProp; | |
312 | CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr) | |
313 | dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey); | |
314 | ||
315 | DebugF("xf86CreateRootWindow(%p)\n", pWin); | |
316 | ||
317 | if (pScreen->CreateWindow != xf86CreateRootWindow) { | |
318 | /* Can't find hook we are hung on */ | |
319 | xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */ , | |
320 | "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n", | |
321 | (void *) xf86CreateRootWindow, | |
322 | (void *) pScreen->CreateWindow); | |
323 | } | |
324 | ||
325 | /* Unhook this function ... */ | |
326 | pScreen->CreateWindow = CreateWindow; | |
327 | dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL); | |
328 | ||
329 | /* ... and call the previous CreateWindow fuction, if any */ | |
330 | if (NULL != pScreen->CreateWindow) { | |
331 | ret = (*pScreen->CreateWindow) (pWin); | |
332 | } | |
333 | ||
334 | /* Now do our stuff */ | |
335 | if (xf86RegisteredPropertiesTable != NULL) { | |
336 | if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) { | |
337 | for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum]; | |
338 | pProp != NULL && err == Success; pProp = pProp->next) { | |
339 | Atom prop; | |
340 | ||
341 | prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE); | |
342 | err = dixChangeWindowProperty(serverClient, pWin, | |
343 | prop, pProp->type, | |
344 | pProp->format, PropModeReplace, | |
345 | pProp->size, pProp->data, FALSE); | |
346 | } | |
347 | ||
348 | /* Look at err */ | |
349 | ret &= (err == Success); | |
350 | ||
351 | } | |
352 | else { | |
353 | xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with " | |
354 | "non-root window %p (parent %p)\n", | |
355 | (void *) pWin, (void *) pWin->parent); | |
356 | ret = FALSE; | |
357 | } | |
358 | } | |
359 | ||
360 | DebugF("xf86CreateRootWindow() returns %d\n", ret); | |
361 | return ret; | |
362 | } | |
363 | ||
364 | static void | |
365 | InstallSignalHandlers(void) | |
366 | { | |
367 | /* | |
368 | * Install signal handler for unexpected signals | |
369 | */ | |
370 | xf86Info.caughtSignal = FALSE; | |
371 | if (!xf86Info.notrapSignals) { | |
372 | OsRegisterSigWrapper(xf86SigWrapper); | |
373 | } | |
374 | else { | |
375 | signal(SIGSEGV, SIG_DFL); | |
376 | signal(SIGILL, SIG_DFL); | |
377 | #ifdef SIGEMT | |
378 | signal(SIGEMT, SIG_DFL); | |
379 | #endif | |
380 | signal(SIGFPE, SIG_DFL); | |
381 | signal(SIGBUS, SIG_DFL); | |
382 | signal(SIGSYS, SIG_DFL); | |
383 | signal(SIGXCPU, SIG_DFL); | |
384 | signal(SIGXFSZ, SIG_DFL); | |
385 | } | |
386 | } | |
387 | ||
388 | /* | |
389 | * InitOutput -- | |
390 | * Initialize screenInfo for all actually accessible framebuffers. | |
391 | * That includes vt-manager setup, querying all possible devices and | |
392 | * collecting the pixmap formats. | |
393 | */ | |
394 | void | |
395 | InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) | |
396 | { | |
397 | int i, j, k, scr_index; | |
398 | char **modulelist; | |
399 | pointer *optionlist; | |
400 | Pix24Flags screenpix24, pix24; | |
401 | MessageType pix24From = X_DEFAULT; | |
402 | Bool pix24Fail = FALSE; | |
403 | Bool autoconfig = FALSE; | |
404 | Bool sigio_blocked = FALSE; | |
405 | Bool want_hw_access = FALSE; | |
406 | GDevPtr configured_device; | |
407 | ||
408 | xf86Initialising = TRUE; | |
409 | ||
410 | config_pre_init(); | |
411 | ||
412 | if (serverGeneration == 1) { | |
413 | if ((xf86ServerName = strrchr(argv[0], '/')) != 0) | |
414 | xf86ServerName++; | |
415 | else | |
416 | xf86ServerName = argv[0]; | |
417 | ||
418 | xf86PrintBanner(); | |
419 | xf86PrintMarkers(); | |
420 | if (xf86LogFile) { | |
421 | time_t t; | |
422 | const char *ct; | |
423 | ||
424 | t = time(NULL); | |
425 | ct = ctime(&t); | |
426 | xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s", | |
427 | xf86LogFile, ct); | |
428 | } | |
429 | ||
430 | /* Read and parse the config file */ | |
431 | if (!xf86DoConfigure && !xf86DoShowOptions) { | |
432 | switch (xf86HandleConfigFile(FALSE)) { | |
433 | case CONFIG_OK: | |
434 | break; | |
435 | case CONFIG_PARSE_ERROR: | |
436 | xf86Msg(X_ERROR, "Error parsing the config file\n"); | |
437 | return; | |
438 | case CONFIG_NOFILE: | |
439 | autoconfig = TRUE; | |
440 | break; | |
441 | } | |
442 | } | |
443 | ||
444 | InstallSignalHandlers(); | |
445 | ||
446 | /* Initialise the loader */ | |
447 | LoaderInit(); | |
448 | ||
449 | /* Tell the loader the default module search path */ | |
450 | LoaderSetPath(xf86ModulePath); | |
451 | ||
452 | if (xf86Info.ignoreABI) { | |
453 | LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL); | |
454 | } | |
455 | ||
456 | if (xf86DoShowOptions) | |
457 | DoShowOptions(); | |
458 | ||
459 | /* Do a general bus probe. This will be a PCI probe for x86 platforms */ | |
460 | xf86BusProbe(); | |
461 | ||
462 | if (xf86DoConfigure) | |
463 | DoConfigure(); | |
464 | ||
465 | if (autoconfig) { | |
466 | if (!xf86AutoConfig()) { | |
467 | xf86Msg(X_ERROR, "Auto configuration failed\n"); | |
468 | return; | |
469 | } | |
470 | } | |
471 | ||
472 | #ifdef XF86PM | |
473 | xf86OSPMClose = xf86OSPMOpen(); | |
474 | #endif | |
475 | ||
476 | xf86ExtensionInit(); | |
477 | ||
478 | /* Load all modules specified explicitly in the config file */ | |
479 | if ((modulelist = xf86ModulelistFromConfig(&optionlist))) { | |
480 | xf86LoadModules(modulelist, optionlist); | |
481 | free(modulelist); | |
482 | free(optionlist); | |
483 | } | |
484 | ||
485 | /* Load all driver modules specified in the config file */ | |
486 | /* If there aren't any specified in the config file, autoconfig them */ | |
487 | /* FIXME: Does not handle multiple active screen sections, but I'm not | |
488 | * sure if we really want to handle that case*/ | |
489 | configured_device = xf86ConfigLayout.screens->screen->device; | |
490 | if ((!configured_device) || (!configured_device->driver)) { | |
491 | if (!autoConfigDevice(configured_device)) { | |
492 | xf86Msg(X_ERROR, "Automatic driver configuration failed\n"); | |
493 | return; | |
494 | } | |
495 | } | |
496 | if ((modulelist = xf86DriverlistFromConfig())) { | |
497 | xf86LoadModules(modulelist, NULL); | |
498 | free(modulelist); | |
499 | } | |
500 | ||
501 | /* Load all input driver modules specified in the config file. */ | |
502 | if ((modulelist = xf86InputDriverlistFromConfig())) { | |
503 | xf86LoadModules(modulelist, NULL); | |
504 | free(modulelist); | |
505 | } | |
506 | ||
507 | /* | |
508 | * It is expected that xf86AddDriver()/xf86AddInputDriver will be | |
509 | * called for each driver as it is loaded. Those functions save the | |
510 | * module pointers for drivers. | |
511 | * XXX Nothing keeps track of them for other modules. | |
512 | */ | |
513 | /* XXX What do we do if not all of these could be loaded? */ | |
514 | ||
515 | /* | |
516 | * At this point, xf86DriverList[] is all filled in with entries for | |
517 | * each of the drivers to try and xf86NumDrivers has the number of | |
518 | * drivers. If there are none, return now. | |
519 | */ | |
520 | ||
521 | if (xf86NumDrivers == 0) { | |
522 | xf86Msg(X_ERROR, "No drivers available.\n"); | |
523 | return; | |
524 | } | |
525 | ||
526 | /* | |
527 | * Call each of the Identify functions and call the driverFunc to check | |
528 | * if HW access is required. The Identify functions print out some | |
529 | * identifying information, and anything else that might be | |
530 | * needed at this early stage. | |
531 | */ | |
532 | ||
533 | for (i = 0; i < xf86NumDrivers; i++) { | |
534 | xorgHWFlags flags = HW_IO; | |
535 | ||
536 | if (xf86DriverList[i]->Identify != NULL) | |
537 | xf86DriverList[i]->Identify(0); | |
538 | ||
539 | if (xf86DriverList[i]->driverFunc) | |
540 | xf86DriverList[i]->driverFunc(NULL, | |
541 | GET_REQUIRED_HW_INTERFACES, | |
542 | &flags); | |
543 | ||
544 | if (NEED_IO_ENABLED(flags)) | |
545 | want_hw_access = TRUE; | |
546 | ||
547 | if (!(flags & HW_SKIP_CONSOLE)) | |
548 | xorgHWOpenConsole = TRUE; | |
549 | } | |
550 | ||
551 | if (xorgHWOpenConsole) | |
552 | xf86OpenConsole(); | |
553 | else | |
554 | xf86Info.dontVTSwitch = TRUE; | |
555 | ||
556 | /* Enable full I/O access */ | |
557 | if (want_hw_access) | |
558 | xorgHWAccess = xf86EnableIO(); | |
559 | ||
560 | if (xf86BusConfig() == FALSE) | |
561 | return; | |
562 | ||
563 | xf86PostProbe(); | |
564 | ||
565 | /* | |
566 | * Sort the drivers to match the requested ording. Using a slow | |
567 | * bubble sort. | |
568 | */ | |
569 | for (j = 0; j < xf86NumScreens - 1; j++) { | |
570 | for (i = 0; i < xf86NumScreens - j - 1; i++) { | |
571 | if (xf86Screens[i + 1]->confScreen->screennum < | |
572 | xf86Screens[i]->confScreen->screennum) { | |
573 | ScrnInfoPtr tmpScrn = xf86Screens[i + 1]; | |
574 | ||
575 | xf86Screens[i + 1] = xf86Screens[i]; | |
576 | xf86Screens[i] = tmpScrn; | |
577 | } | |
578 | } | |
579 | } | |
580 | /* Fix up the indexes */ | |
581 | for (i = 0; i < xf86NumScreens; i++) { | |
582 | xf86Screens[i]->scrnIndex = i; | |
583 | } | |
584 | ||
585 | /* | |
586 | * Call the driver's PreInit()'s to complete initialisation for the first | |
587 | * generation. | |
588 | */ | |
589 | ||
590 | for (i = 0; i < xf86NumScreens; i++) { | |
591 | xf86VGAarbiterScrnInit(xf86Screens[i]); | |
592 | xf86VGAarbiterLock(xf86Screens[i]); | |
593 | if (xf86Screens[i]->PreInit && | |
594 | xf86Screens[i]->PreInit(xf86Screens[i], 0)) | |
595 | xf86Screens[i]->configured = TRUE; | |
596 | xf86VGAarbiterUnlock(xf86Screens[i]); | |
597 | } | |
598 | for (i = 0; i < xf86NumScreens; i++) | |
599 | if (!xf86Screens[i]->configured) | |
600 | xf86DeleteScreen(xf86Screens[i--]); | |
601 | ||
602 | for (i = 0; i < xf86NumGPUScreens; i++) { | |
603 | xf86VGAarbiterScrnInit(xf86GPUScreens[i]); | |
604 | xf86VGAarbiterLock(xf86GPUScreens[i]); | |
605 | if (xf86GPUScreens[i]->PreInit && | |
606 | xf86GPUScreens[i]->PreInit(xf86GPUScreens[i], 0)) | |
607 | xf86GPUScreens[i]->configured = TRUE; | |
608 | xf86VGAarbiterUnlock(xf86GPUScreens[i]); | |
609 | } | |
610 | for (i = 0; i < xf86NumGPUScreens; i++) | |
611 | if (!xf86GPUScreens[i]->configured) | |
612 | xf86DeleteScreen(xf86GPUScreens[i--]); | |
613 | ||
614 | /* | |
615 | * If no screens left, return now. | |
616 | */ | |
617 | ||
618 | if (xf86NumScreens == 0) { | |
619 | xf86Msg(X_ERROR, | |
620 | "Screen(s) found, but none have a usable configuration.\n"); | |
621 | return; | |
622 | } | |
623 | ||
624 | for (i = 0; i < xf86NumScreens; i++) { | |
625 | if (xf86Screens[i]->name == NULL) { | |
626 | XNFasprintf(&xf86Screens[i]->name, "screen%d", i); | |
627 | xf86MsgVerb(X_WARNING, 0, | |
628 | "Screen driver %d has no name set, using `%s'.\n", | |
629 | i, xf86Screens[i]->name); | |
630 | } | |
631 | } | |
632 | ||
633 | /* Remove (unload) drivers that are not required */ | |
634 | for (i = 0; i < xf86NumDrivers; i++) | |
635 | if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0) | |
636 | xf86DeleteDriver(i); | |
637 | ||
638 | /* | |
639 | * At this stage we know how many screens there are. | |
640 | */ | |
641 | ||
642 | for (i = 0; i < xf86NumScreens; i++) | |
643 | xf86InitViewport(xf86Screens[i]); | |
644 | ||
645 | /* | |
646 | * Collect all pixmap formats and check for conflicts at the display | |
647 | * level. Should we die here? Or just delete the offending screens? | |
648 | */ | |
649 | screenpix24 = Pix24DontCare; | |
650 | for (i = 0; i < xf86NumScreens; i++) { | |
651 | if (xf86Screens[i]->imageByteOrder != | |
652 | xf86Screens[0]->imageByteOrder) | |
653 | FatalError("Inconsistent display bitmapBitOrder. Exiting\n"); | |
654 | if (xf86Screens[i]->bitmapScanlinePad != | |
655 | xf86Screens[0]->bitmapScanlinePad) | |
656 | FatalError | |
657 | ("Inconsistent display bitmapScanlinePad. Exiting\n"); | |
658 | if (xf86Screens[i]->bitmapScanlineUnit != | |
659 | xf86Screens[0]->bitmapScanlineUnit) | |
660 | FatalError | |
661 | ("Inconsistent display bitmapScanlineUnit. Exiting\n"); | |
662 | if (xf86Screens[i]->bitmapBitOrder != | |
663 | xf86Screens[0]->bitmapBitOrder) | |
664 | FatalError("Inconsistent display bitmapBitOrder. Exiting\n"); | |
665 | ||
666 | /* Determine the depth 24 pixmap format the screens would like */ | |
667 | if (xf86Screens[i]->pixmap24 != Pix24DontCare) { | |
668 | if (screenpix24 == Pix24DontCare) | |
669 | screenpix24 = xf86Screens[i]->pixmap24; | |
670 | else if (screenpix24 != xf86Screens[i]->pixmap24) | |
671 | FatalError | |
672 | ("Inconsistent depth 24 pixmap format. Exiting\n"); | |
673 | } | |
674 | } | |
675 | /* check if screenpix24 is consistent with the config/cmdline */ | |
676 | if (xf86Info.pixmap24 != Pix24DontCare) { | |
677 | pix24 = xf86Info.pixmap24; | |
678 | pix24From = xf86Info.pix24From; | |
679 | if (screenpix24 != Pix24DontCare && | |
680 | screenpix24 != xf86Info.pixmap24) | |
681 | pix24Fail = TRUE; | |
682 | } | |
683 | else if (screenpix24 != Pix24DontCare) { | |
684 | pix24 = screenpix24; | |
685 | pix24From = X_PROBED; | |
686 | } | |
687 | else | |
688 | pix24 = Pix24Use32; | |
689 | ||
690 | if (pix24Fail) | |
691 | FatalError("Screen(s) can't use the required depth 24 pixmap format" | |
692 | " (%d). Exiting\n", PIX24TOBPP(pix24)); | |
693 | ||
694 | /* Initialise the depth 24 format */ | |
695 | for (j = 0; j < numFormats && formats[j].depth != 24; j++); | |
696 | formats[j].bitsPerPixel = PIX24TOBPP(pix24); | |
697 | ||
698 | /* Collect additional formats */ | |
699 | for (i = 0; i < xf86NumScreens; i++) { | |
700 | for (j = 0; j < xf86Screens[i]->numFormats; j++) { | |
701 | for (k = 0;; k++) { | |
702 | if (k >= numFormats) { | |
703 | if (k >= MAXFORMATS) | |
704 | FatalError("Too many pixmap formats! Exiting\n"); | |
705 | formats[k] = xf86Screens[i]->formats[j]; | |
706 | numFormats++; | |
707 | break; | |
708 | } | |
709 | if (formats[k].depth == xf86Screens[i]->formats[j].depth) { | |
710 | if ((formats[k].bitsPerPixel == | |
711 | xf86Screens[i]->formats[j].bitsPerPixel) && | |
712 | (formats[k].scanlinePad == | |
713 | xf86Screens[i]->formats[j].scanlinePad)) | |
714 | break; | |
715 | FatalError("Inconsistent pixmap format for depth %d." | |
716 | " Exiting\n", formats[k].depth); | |
717 | } | |
718 | } | |
719 | } | |
720 | } | |
721 | formatsDone = TRUE; | |
722 | ||
723 | if (xf86Info.vtno >= 0) { | |
724 | #define VT_ATOM_NAME "XFree86_VT" | |
725 | Atom VTAtom = -1; | |
726 | CARD32 *VT = NULL; | |
727 | int ret; | |
728 | ||
729 | /* This memory needs to stay available until the screen has been | |
730 | initialized, and we can create the property for real. | |
731 | */ | |
732 | if ((VT = malloc(sizeof(CARD32))) == NULL) { | |
733 | FatalError | |
734 | ("Unable to make VT property - out of memory. Exiting...\n"); | |
735 | } | |
736 | *VT = xf86Info.vtno; | |
737 | ||
738 | VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE); | |
739 | ||
740 | for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; | |
741 | i++) { | |
742 | ret = | |
743 | xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex, | |
744 | VTAtom, XA_INTEGER, 32, 1, | |
745 | VT); | |
746 | if (ret != Success) | |
747 | xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING, | |
748 | "Failed to register VT property\n"); | |
749 | } | |
750 | } | |
751 | ||
752 | if (SeatId) { | |
753 | Atom SeatAtom; | |
754 | ||
755 | SeatAtom = | |
756 | MakeAtom(SEAT_ATOM_NAME, sizeof(SEAT_ATOM_NAME) - 1, TRUE); | |
757 | ||
758 | for (i = 0; i < xf86NumScreens; i++) { | |
759 | int ret; | |
760 | ||
761 | ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex, | |
762 | SeatAtom, XA_STRING, 8, | |
763 | strlen(SeatId) + 1, | |
764 | SeatId); | |
765 | if (ret != Success) { | |
766 | xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING, | |
767 | "Failed to register seat property\n"); | |
768 | } | |
769 | } | |
770 | } | |
771 | ||
772 | /* If a screen uses depth 24, show what the pixmap format is */ | |
773 | for (i = 0; i < xf86NumScreens; i++) { | |
774 | if (xf86Screens[i]->depth == 24) { | |
775 | xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n", | |
776 | PIX24TOBPP(pix24)); | |
777 | break; | |
778 | } | |
779 | } | |
780 | } | |
781 | else { | |
782 | /* | |
783 | * serverGeneration != 1; some OSs have to do things here, too. | |
784 | */ | |
785 | if (xorgHWOpenConsole) | |
786 | xf86OpenConsole(); | |
787 | ||
788 | #ifdef XF86PM | |
789 | /* | |
790 | should we reopen it here? We need to deal with an already opened | |
791 | device. We could leave this to the OS layer. For now we simply | |
792 | close it here | |
793 | */ | |
794 | if (xf86OSPMClose) | |
795 | xf86OSPMClose(); | |
796 | if ((xf86OSPMClose = xf86OSPMOpen()) != NULL) | |
797 | xf86MsgVerb(X_INFO, 3, "APM registered successfully\n"); | |
798 | #endif | |
799 | ||
800 | /* Make sure full I/O access is enabled */ | |
801 | if (xorgHWAccess) | |
802 | xf86EnableIO(); | |
803 | } | |
804 | ||
805 | /* | |
806 | * Use the previously collected parts to setup pScreenInfo | |
807 | */ | |
808 | ||
809 | pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder; | |
810 | pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad; | |
811 | pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit; | |
812 | pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder; | |
813 | pScreenInfo->numPixmapFormats = numFormats; | |
814 | for (i = 0; i < numFormats; i++) | |
815 | pScreenInfo->formats[i] = formats[i]; | |
816 | ||
817 | /* Make sure the server's VT is active */ | |
818 | ||
819 | if (serverGeneration != 1) { | |
820 | xf86Resetting = TRUE; | |
821 | /* All screens are in the same state, so just check the first */ | |
822 | if (!xf86VTOwner()) { | |
823 | #ifdef HAS_USL_VTS | |
824 | ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ); | |
825 | #endif | |
826 | xf86AccessEnter(); | |
827 | OsBlockSIGIO(); | |
828 | sigio_blocked = TRUE; | |
829 | } | |
830 | } | |
831 | ||
832 | for (i = 0; i < xf86NumScreens; i++) | |
833 | if (!xf86ColormapAllocatePrivates(xf86Screens[i])) | |
834 | FatalError("Cannot register DDX private keys"); | |
835 | ||
836 | if (!dixRegisterPrivateKey(&xf86ScreenKeyRec, PRIVATE_SCREEN, 0) || | |
837 | !dixRegisterPrivateKey(&xf86CreateRootWindowKeyRec, PRIVATE_SCREEN, 0)) | |
838 | FatalError("Cannot register DDX private keys"); | |
839 | ||
840 | for (i = 0; i < xf86NumGPUScreens; i++) { | |
841 | ScrnInfoPtr pScrn = xf86GPUScreens[i]; | |
842 | xf86VGAarbiterLock(pScrn); | |
843 | ||
844 | /* | |
845 | * Almost everything uses these defaults, and many of those that | |
846 | * don't, will wrap them. | |
847 | */ | |
848 | pScrn->EnableDisableFBAccess = xf86EnableDisableFBAccess; | |
849 | #ifdef XFreeXDGA | |
850 | pScrn->SetDGAMode = xf86SetDGAMode; | |
851 | #endif | |
852 | pScrn->DPMSSet = NULL; | |
853 | pScrn->LoadPalette = NULL; | |
854 | pScrn->SetOverscan = NULL; | |
855 | pScrn->DriverFunc = NULL; | |
856 | pScrn->pScreen = NULL; | |
857 | scr_index = AddGPUScreen(pScrn->ScreenInit, argc, argv); | |
858 | xf86VGAarbiterUnlock(pScrn); | |
859 | if (scr_index == i) { | |
860 | dixSetPrivate(&screenInfo.gpuscreens[scr_index]->devPrivates, | |
861 | xf86ScreenKey, xf86GPUScreens[i]); | |
862 | pScrn->pScreen = screenInfo.gpuscreens[scr_index]; | |
863 | /* The driver should set this, but make sure it is set anyway */ | |
864 | pScrn->vtSema = TRUE; | |
865 | } else { | |
866 | FatalError("AddScreen/ScreenInit failed for gpu driver %d %d\n", i, scr_index); | |
867 | } | |
868 | } | |
869 | ||
870 | for (i = 0; i < xf86NumScreens; i++) { | |
871 | xf86VGAarbiterLock(xf86Screens[i]); | |
872 | /* | |
873 | * Almost everything uses these defaults, and many of those that | |
874 | * don't, will wrap them. | |
875 | */ | |
876 | xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess; | |
877 | #ifdef XFreeXDGA | |
878 | xf86Screens[i]->SetDGAMode = xf86SetDGAMode; | |
879 | #endif | |
880 | xf86Screens[i]->DPMSSet = NULL; | |
881 | xf86Screens[i]->LoadPalette = NULL; | |
882 | xf86Screens[i]->SetOverscan = NULL; | |
883 | xf86Screens[i]->DriverFunc = NULL; | |
884 | xf86Screens[i]->pScreen = NULL; | |
885 | scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv); | |
886 | xf86VGAarbiterUnlock(xf86Screens[i]); | |
887 | if (scr_index == i) { | |
888 | /* | |
889 | * Hook in our ScrnInfoRec, and initialise some other pScreen | |
890 | * fields. | |
891 | */ | |
892 | dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates, | |
893 | xf86ScreenKey, xf86Screens[i]); | |
894 | xf86Screens[i]->pScreen = screenInfo.screens[scr_index]; | |
895 | /* The driver should set this, but make sure it is set anyway */ | |
896 | xf86Screens[i]->vtSema = TRUE; | |
897 | } | |
898 | else { | |
899 | /* This shouldn't normally happen */ | |
900 | FatalError("AddScreen/ScreenInit failed for driver %d\n", i); | |
901 | } | |
902 | ||
903 | DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n", | |
904 | i, xf86Screens[i]->pScreen); | |
905 | DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n", | |
906 | i, xf86Screens[i]->pScreen->CreateWindow); | |
907 | ||
908 | dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates, | |
909 | xf86CreateRootWindowKey, | |
910 | xf86Screens[i]->pScreen->CreateWindow); | |
911 | xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow; | |
912 | ||
913 | if (PictureGetSubpixelOrder(xf86Screens[i]->pScreen) == SubPixelUnknown) { | |
914 | xf86MonPtr DDC = (xf86MonPtr) (xf86Screens[i]->monitor->DDC); | |
915 | ||
916 | PictureSetSubpixelOrder(xf86Screens[i]->pScreen, | |
917 | DDC ? | |
918 | (DDC->features.input_type ? | |
919 | SubPixelHorizontalRGB : SubPixelNone) : | |
920 | SubPixelUnknown); | |
921 | } | |
922 | #ifdef RANDR | |
923 | if (!xf86Info.disableRandR) | |
924 | xf86RandRInit(screenInfo.screens[scr_index]); | |
925 | xf86Msg(xf86Info.randRFrom, "RandR %s\n", | |
926 | xf86Info.disableRandR ? "disabled" : "enabled"); | |
927 | #endif | |
928 | } | |
929 | ||
930 | for (i = 0; i < xf86NumGPUScreens; i++) | |
931 | AttachUnboundGPU(xf86Screens[0]->pScreen, xf86GPUScreens[i]->pScreen); | |
932 | ||
933 | xf86VGAarbiterWrapFunctions(); | |
934 | if (sigio_blocked) | |
935 | OsReleaseSIGIO(); | |
936 | ||
937 | xf86InitOrigins(); | |
938 | ||
939 | xf86Resetting = FALSE; | |
940 | xf86Initialising = FALSE; | |
941 | ||
942 | RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr) NoopDDA, xf86Wakeup, | |
943 | NULL); | |
944 | } | |
945 | ||
946 | /** | |
947 | * Initialize all supported input devices present and referenced in the | |
948 | * xorg.conf. | |
949 | */ | |
950 | void | |
951 | InitInput(int argc, char **argv) | |
952 | { | |
953 | InputInfoPtr *pInfo; | |
954 | DeviceIntPtr dev; | |
955 | ||
956 | xf86Info.vtRequestsPending = FALSE; | |
957 | ||
958 | mieqInit(); | |
959 | ||
960 | /* Initialize all configured input devices */ | |
961 | for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) { | |
962 | (*pInfo)->options = | |
963 | xf86AddNewOption((*pInfo)->options, "driver", (*pInfo)->driver); | |
964 | (*pInfo)->options = | |
965 | xf86AddNewOption((*pInfo)->options, "identifier", (*pInfo)->name); | |
966 | /* If one fails, the others will too */ | |
967 | if (NewInputDeviceRequest((*pInfo)->options, NULL, &dev) == BadAlloc) | |
968 | break; | |
969 | } | |
970 | ||
971 | config_init(); | |
972 | } | |
973 | ||
974 | void | |
975 | CloseInput(void) | |
976 | { | |
977 | config_fini(); | |
978 | mieqFini(); | |
979 | } | |
980 | ||
981 | /* | |
982 | * OsVendorInit -- | |
983 | * OS/Vendor-specific initialisations. Called from OsInit(), which | |
984 | * is called by dix before establishing the well known sockets. | |
985 | */ | |
986 | ||
987 | void | |
988 | OsVendorInit(void) | |
989 | { | |
990 | static Bool beenHere = FALSE; | |
991 | ||
992 | signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */ | |
993 | ||
994 | if (!beenHere) { | |
995 | umask(022); | |
996 | xf86LogInit(); | |
997 | } | |
998 | ||
999 | /* Set stderr to non-blocking. */ | |
1000 | #ifndef O_NONBLOCK | |
1001 | #if defined(FNDELAY) | |
1002 | #define O_NONBLOCK FNDELAY | |
1003 | #elif defined(O_NDELAY) | |
1004 | #define O_NONBLOCK O_NDELAY | |
1005 | #endif | |
1006 | ||
1007 | #ifdef O_NONBLOCK | |
1008 | if (!beenHere) { | |
1009 | if (xf86PrivsElevated()) { | |
1010 | int status; | |
1011 | ||
1012 | status = fcntl(fileno(stderr), F_GETFL, 0); | |
1013 | if (status != -1) { | |
1014 | fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK); | |
1015 | } | |
1016 | } | |
1017 | } | |
1018 | #endif | |
1019 | #endif | |
1020 | ||
1021 | beenHere = TRUE; | |
1022 | } | |
1023 | ||
1024 | /* | |
1025 | * ddxGiveUp -- | |
1026 | * Device dependent cleanup. Called by by dix before normal server death. | |
1027 | * For SYSV386 we must switch the terminal back to normal mode. No error- | |
1028 | * checking here, since there should be restored as much as possible. | |
1029 | */ | |
1030 | ||
1031 | void | |
1032 | ddxGiveUp(enum ExitCode error) | |
1033 | { | |
1034 | int i; | |
1035 | ||
1036 | xf86VGAarbiterFini(); | |
1037 | ||
1038 | #ifdef XF86PM | |
1039 | if (xf86OSPMClose) | |
1040 | xf86OSPMClose(); | |
1041 | xf86OSPMClose = NULL; | |
1042 | #endif | |
1043 | ||
1044 | for (i = 0; i < xf86NumScreens; i++) { | |
1045 | /* | |
1046 | * zero all access functions to | |
1047 | * trap calls when switched away. | |
1048 | */ | |
1049 | xf86Screens[i]->vtSema = FALSE; | |
1050 | } | |
1051 | ||
1052 | #ifdef XFreeXDGA | |
1053 | DGAShutdown(); | |
1054 | #endif | |
1055 | ||
1056 | if (xorgHWOpenConsole) | |
1057 | xf86CloseConsole(); | |
1058 | ||
1059 | xf86CloseLog(error); | |
1060 | ||
1061 | /* If an unexpected signal was caught, dump a core for debugging */ | |
1062 | if (xf86Info.caughtSignal) | |
1063 | OsAbort(); | |
1064 | } | |
1065 | ||
1066 | /* | |
1067 | * AbortDDX -- | |
1068 | * DDX - specific abort routine. Called by AbortServer(). The attempt is | |
1069 | * made to restore all original setting of the displays. Also all devices | |
1070 | * are closed. | |
1071 | */ | |
1072 | ||
1073 | void | |
1074 | AbortDDX(enum ExitCode error) | |
1075 | { | |
1076 | int i; | |
1077 | ||
1078 | OsBlockSIGIO(); | |
1079 | ||
1080 | /* | |
1081 | * try to restore the original video state | |
1082 | */ | |
1083 | #ifdef DPMSExtension /* Turn screens back on */ | |
1084 | if (DPMSPowerLevel != DPMSModeOn) | |
1085 | DPMSSet(serverClient, DPMSModeOn); | |
1086 | #endif | |
1087 | if (xf86Screens) { | |
1088 | for (i = 0; i < xf86NumScreens; i++) | |
1089 | if (xf86Screens[i]->vtSema) { | |
1090 | /* | |
1091 | * if we are aborting before ScreenInit() has finished | |
1092 | * we might not have been wrapped yet. Therefore enable | |
1093 | * screen explicitely. | |
1094 | */ | |
1095 | xf86VGAarbiterLock(xf86Screens[i]); | |
1096 | (xf86Screens[i]->LeaveVT) (xf86Screens[i]); | |
1097 | xf86VGAarbiterUnlock(xf86Screens[i]); | |
1098 | } | |
1099 | } | |
1100 | ||
1101 | xf86AccessLeave(); | |
1102 | ||
1103 | /* | |
1104 | * This is needed for an abnormal server exit, since the normal exit stuff | |
1105 | * MUST also be performed (i.e. the vt must be left in a defined state) | |
1106 | */ | |
1107 | ddxGiveUp(error); | |
1108 | } | |
1109 | ||
1110 | void | |
1111 | OsVendorFatalError(const char *f, va_list args) | |
1112 | { | |
1113 | #ifdef VENDORSUPPORT | |
1114 | ErrorFSigSafe("\nPlease refer to your Operating System Vendor support " | |
1115 | "pages\nat %s for support on this crash.\n", VENDORSUPPORT); | |
1116 | #else | |
1117 | ErrorFSigSafe("\nPlease consult the " XVENDORNAME " support \n\t at " | |
1118 | __VENDORDWEBSUPPORT__ "\n for help. \n"); | |
1119 | #endif | |
1120 | if (xf86LogFile && xf86LogFileWasOpened) | |
1121 | ErrorFSigSafe("Please also check the log file at \"%s\" for additional " | |
1122 | "information.\n", xf86LogFile); | |
1123 | ErrorFSigSafe("\n"); | |
1124 | } | |
1125 | ||
1126 | int | |
1127 | xf86SetVerbosity(int verb) | |
1128 | { | |
1129 | int save = xf86Verbose; | |
1130 | ||
1131 | xf86Verbose = verb; | |
1132 | LogSetParameter(XLOG_VERBOSITY, verb); | |
1133 | return save; | |
1134 | } | |
1135 | ||
1136 | int | |
1137 | xf86SetLogVerbosity(int verb) | |
1138 | { | |
1139 | int save = xf86LogVerbose; | |
1140 | ||
1141 | xf86LogVerbose = verb; | |
1142 | LogSetParameter(XLOG_FILE_VERBOSITY, verb); | |
1143 | return save; | |
1144 | } | |
1145 | ||
1146 | static void | |
1147 | xf86PrintDefaultModulePath(void) | |
1148 | { | |
1149 | ErrorF("%s\n", DEFAULT_MODULE_PATH); | |
1150 | } | |
1151 | ||
1152 | static void | |
1153 | xf86PrintDefaultLibraryPath(void) | |
1154 | { | |
1155 | ErrorF("%s\n", DEFAULT_LIBRARY_PATH); | |
1156 | } | |
1157 | ||
1158 | /* | |
1159 | * ddxProcessArgument -- | |
1160 | * Process device-dependent command line args. Returns 0 if argument is | |
1161 | * not device dependent, otherwise Count of number of elements of argv | |
1162 | * that are part of a device dependent commandline option. | |
1163 | * | |
1164 | */ | |
1165 | ||
1166 | /* ARGSUSED */ | |
1167 | int | |
1168 | ddxProcessArgument(int argc, char **argv, int i) | |
1169 | { | |
1170 | #define CHECK_FOR_REQUIRED_ARGUMENT() \ | |
1171 | if (((i + 1) >= argc) || (!argv[i + 1])) { \ | |
1172 | ErrorF("Required argument to %s not specified\n", argv[i]); \ | |
1173 | UseMsg(); \ | |
1174 | FatalError("Required argument to %s not specified\n", argv[i]); \ | |
1175 | } | |
1176 | ||
1177 | /* First the options that are not allowed with elevated privileges */ | |
1178 | if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) { | |
1179 | if (xf86PrivsElevated()) { | |
1180 | FatalError("The '%s' option cannot be used with " | |
1181 | "elevated privileges.\n", argv[i]); | |
1182 | } | |
1183 | else if (!strcmp(argv[i], "-modulepath")) { | |
1184 | char *mp; | |
1185 | ||
1186 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1187 | mp = strdup(argv[i + 1]); | |
1188 | if (!mp) | |
1189 | FatalError("Can't allocate memory for ModulePath\n"); | |
1190 | xf86ModulePath = mp; | |
1191 | xf86ModPathFrom = X_CMDLINE; | |
1192 | return 2; | |
1193 | } | |
1194 | else if (!strcmp(argv[i], "-logfile")) { | |
1195 | char *lf; | |
1196 | ||
1197 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1198 | lf = strdup(argv[i + 1]); | |
1199 | if (!lf) | |
1200 | FatalError("Can't allocate memory for LogFile\n"); | |
1201 | xf86LogFile = lf; | |
1202 | xf86LogFileFrom = X_CMDLINE; | |
1203 | return 2; | |
1204 | } | |
1205 | } | |
1206 | if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config")) { | |
1207 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1208 | if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) { | |
1209 | FatalError("\nInvalid argument for %s\n" | |
1210 | "\tWith elevated privileges, the file specified with %s must be\n" | |
1211 | "\ta relative path and must not contain any \"..\" elements.\n" | |
1212 | "\tUsing default " __XCONFIGFILE__ " search path.\n\n", | |
1213 | argv[i], argv[i]); | |
1214 | } | |
1215 | xf86ConfigFile = argv[i + 1]; | |
1216 | return 2; | |
1217 | } | |
1218 | if (!strcmp(argv[i], "-configdir")) { | |
1219 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1220 | if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) { | |
1221 | FatalError("\nInvalid argument for %s\n" | |
1222 | "\tWith elevated privileges, the file specified with %s must be\n" | |
1223 | "\ta relative path and must not contain any \"..\" elements.\n" | |
1224 | "\tUsing default " __XCONFIGDIR__ " search path.\n\n", | |
1225 | argv[i], argv[i]); | |
1226 | } | |
1227 | xf86ConfigDir = argv[i + 1]; | |
1228 | return 2; | |
1229 | } | |
1230 | if (!strcmp(argv[i], "-flipPixels")) { | |
1231 | xf86FlipPixels = TRUE; | |
1232 | return 1; | |
1233 | } | |
1234 | #ifdef XF86VIDMODE | |
1235 | if (!strcmp(argv[i], "-disableVidMode")) { | |
1236 | xf86VidModeDisabled = TRUE; | |
1237 | return 1; | |
1238 | } | |
1239 | if (!strcmp(argv[i], "-allowNonLocalXvidtune")) { | |
1240 | xf86VidModeAllowNonLocal = TRUE; | |
1241 | return 1; | |
1242 | } | |
1243 | #endif | |
1244 | if (!strcmp(argv[i], "-allowMouseOpenFail")) { | |
1245 | xf86AllowMouseOpenFail = TRUE; | |
1246 | return 1; | |
1247 | } | |
1248 | if (!strcmp(argv[i], "-ignoreABI")) { | |
1249 | LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL); | |
1250 | return 1; | |
1251 | } | |
1252 | if (!strcmp(argv[i], "-verbose")) { | |
1253 | if (++i < argc && argv[i]) { | |
1254 | char *end; | |
1255 | long val; | |
1256 | ||
1257 | val = strtol(argv[i], &end, 0); | |
1258 | if (*end == '\0') { | |
1259 | xf86SetVerbosity(val); | |
1260 | return 2; | |
1261 | } | |
1262 | } | |
1263 | xf86SetVerbosity(++xf86Verbose); | |
1264 | return 1; | |
1265 | } | |
1266 | if (!strcmp(argv[i], "-logverbose")) { | |
1267 | if (++i < argc && argv[i]) { | |
1268 | char *end; | |
1269 | long val; | |
1270 | ||
1271 | val = strtol(argv[i], &end, 0); | |
1272 | if (*end == '\0') { | |
1273 | xf86SetLogVerbosity(val); | |
1274 | return 2; | |
1275 | } | |
1276 | } | |
1277 | xf86SetLogVerbosity(++xf86LogVerbose); | |
1278 | return 1; | |
1279 | } | |
1280 | if (!strcmp(argv[i], "-quiet")) { | |
1281 | xf86SetVerbosity(-1); | |
1282 | return 1; | |
1283 | } | |
1284 | if (!strcmp(argv[i], "-showconfig") || !strcmp(argv[i], "-version")) { | |
1285 | xf86PrintBanner(); | |
1286 | exit(0); | |
1287 | } | |
1288 | if (!strcmp(argv[i], "-showDefaultModulePath")) { | |
1289 | xf86PrintDefaultModulePath(); | |
1290 | exit(0); | |
1291 | } | |
1292 | if (!strcmp(argv[i], "-showDefaultLibPath")) { | |
1293 | xf86PrintDefaultLibraryPath(); | |
1294 | exit(0); | |
1295 | } | |
1296 | /* Notice the -fp flag, but allow it to pass to the dix layer */ | |
1297 | if (!strcmp(argv[i], "-fp")) { | |
1298 | xf86fpFlag = TRUE; | |
1299 | return 0; | |
1300 | } | |
1301 | /* Notice the -bs flag, but allow it to pass to the dix layer */ | |
1302 | if (!strcmp(argv[i], "-bs")) { | |
1303 | xf86bsDisableFlag = TRUE; | |
1304 | return 0; | |
1305 | } | |
1306 | /* Notice the +bs flag, but allow it to pass to the dix layer */ | |
1307 | if (!strcmp(argv[i], "+bs")) { | |
1308 | xf86bsEnableFlag = TRUE; | |
1309 | return 0; | |
1310 | } | |
1311 | /* Notice the -s flag, but allow it to pass to the dix layer */ | |
1312 | if (!strcmp(argv[i], "-s")) { | |
1313 | xf86sFlag = TRUE; | |
1314 | return 0; | |
1315 | } | |
1316 | if (!strcmp(argv[i], "-pixmap24")) { | |
1317 | xf86Pix24 = Pix24Use24; | |
1318 | return 1; | |
1319 | } | |
1320 | if (!strcmp(argv[i], "-pixmap32")) { | |
1321 | xf86Pix24 = Pix24Use32; | |
1322 | return 1; | |
1323 | } | |
1324 | if (!strcmp(argv[i], "-fbbpp")) { | |
1325 | int bpp; | |
1326 | ||
1327 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1328 | if (sscanf(argv[++i], "%d", &bpp) == 1) { | |
1329 | xf86FbBpp = bpp; | |
1330 | return 2; | |
1331 | } | |
1332 | else { | |
1333 | ErrorF("Invalid fbbpp\n"); | |
1334 | return 0; | |
1335 | } | |
1336 | } | |
1337 | if (!strcmp(argv[i], "-depth")) { | |
1338 | int depth; | |
1339 | ||
1340 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1341 | if (sscanf(argv[++i], "%d", &depth) == 1) { | |
1342 | xf86Depth = depth; | |
1343 | return 2; | |
1344 | } | |
1345 | else { | |
1346 | ErrorF("Invalid depth\n"); | |
1347 | return 0; | |
1348 | } | |
1349 | } | |
1350 | if (!strcmp(argv[i], "-weight")) { | |
1351 | int red, green, blue; | |
1352 | ||
1353 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1354 | if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3) { | |
1355 | xf86Weight.red = red; | |
1356 | xf86Weight.green = green; | |
1357 | xf86Weight.blue = blue; | |
1358 | return 2; | |
1359 | } | |
1360 | else { | |
1361 | ErrorF("Invalid weighting\n"); | |
1362 | return 0; | |
1363 | } | |
1364 | } | |
1365 | if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") || | |
1366 | !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma")) { | |
1367 | double gamma; | |
1368 | ||
1369 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1370 | if (sscanf(argv[++i], "%lf", &gamma) == 1) { | |
1371 | if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) { | |
1372 | ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f" | |
1373 | " is valid\n", GAMMA_MIN, GAMMA_MAX); | |
1374 | return 0; | |
1375 | } | |
1376 | if (!strcmp(argv[i - 1], "-gamma")) | |
1377 | xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma; | |
1378 | else if (!strcmp(argv[i - 1], "-rgamma")) | |
1379 | xf86Gamma.red = gamma; | |
1380 | else if (!strcmp(argv[i - 1], "-ggamma")) | |
1381 | xf86Gamma.green = gamma; | |
1382 | else if (!strcmp(argv[i - 1], "-bgamma")) | |
1383 | xf86Gamma.blue = gamma; | |
1384 | return 2; | |
1385 | } | |
1386 | } | |
1387 | if (!strcmp(argv[i], "-layout")) { | |
1388 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1389 | xf86LayoutName = argv[++i]; | |
1390 | return 2; | |
1391 | } | |
1392 | if (!strcmp(argv[i], "-screen")) { | |
1393 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1394 | xf86ScreenName = argv[++i]; | |
1395 | return 2; | |
1396 | } | |
1397 | if (!strcmp(argv[i], "-pointer")) { | |
1398 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1399 | xf86PointerName = argv[++i]; | |
1400 | return 2; | |
1401 | } | |
1402 | if (!strcmp(argv[i], "-keyboard")) { | |
1403 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1404 | xf86KeyboardName = argv[++i]; | |
1405 | return 2; | |
1406 | } | |
1407 | if (!strcmp(argv[i], "-nosilk")) { | |
1408 | xf86silkenMouseDisableFlag = TRUE; | |
1409 | return 1; | |
1410 | } | |
1411 | #ifdef HAVE_ACPI | |
1412 | if (!strcmp(argv[i], "-noacpi")) { | |
1413 | xf86acpiDisableFlag = TRUE; | |
1414 | return 1; | |
1415 | } | |
1416 | #endif | |
1417 | if (!strcmp(argv[i], "-configure")) { | |
1418 | if (getuid() != 0 && geteuid() == 0) { | |
1419 | ErrorF("The '-configure' option can only be used by root.\n"); | |
1420 | exit(1); | |
1421 | } | |
1422 | xf86DoConfigure = TRUE; | |
1423 | xf86AllowMouseOpenFail = TRUE; | |
1424 | return 1; | |
1425 | } | |
1426 | if (!strcmp(argv[i], "-showopts")) { | |
1427 | if (getuid() != 0 && geteuid() == 0) { | |
1428 | ErrorF("The '-showopts' option can only be used by root.\n"); | |
1429 | exit(1); | |
1430 | } | |
1431 | xf86DoShowOptions = TRUE; | |
1432 | return 1; | |
1433 | } | |
1434 | #ifdef XSERVER_LIBPCIACCESS | |
1435 | if (!strcmp(argv[i], "-isolateDevice")) { | |
1436 | CHECK_FOR_REQUIRED_ARGUMENT(); | |
1437 | if (strncmp(argv[++i], "PCI:", 4)) { | |
1438 | FatalError("Bus types other than PCI not yet isolable\n"); | |
1439 | } | |
1440 | xf86PciIsolateDevice(argv[i]); | |
1441 | return 2; | |
1442 | } | |
1443 | #endif | |
1444 | /* Notice cmdline xkbdir, but pass to dix as well */ | |
1445 | if (!strcmp(argv[i], "-xkbdir")) { | |
1446 | xf86xkbdirFlag = TRUE; | |
1447 | return 0; | |
1448 | } | |
1449 | if (!strcmp(argv[i], "-novtswitch")) { | |
1450 | xf86Info.autoVTSwitch = FALSE; | |
1451 | return 1; | |
1452 | } | |
1453 | if (!strcmp(argv[i], "-sharevts")) { | |
1454 | xf86Info.ShareVTs = TRUE; | |
1455 | return 1; | |
1456 | } | |
1457 | ||
1458 | /* OS-specific processing */ | |
1459 | return xf86ProcessArgument(argc, argv, i); | |
1460 | } | |
1461 | ||
1462 | /* | |
1463 | * ddxUseMsg -- | |
1464 | * Print out correct use of device dependent commandline options. | |
1465 | * Maybe the user now knows what really to do ... | |
1466 | */ | |
1467 | ||
1468 | void | |
1469 | ddxUseMsg(void) | |
1470 | { | |
1471 | ErrorF("\n"); | |
1472 | ErrorF("\n"); | |
1473 | ErrorF("Device Dependent Usage\n"); | |
1474 | if (!xf86PrivsElevated()) { | |
1475 | ErrorF("-modulepath paths specify the module search path\n"); | |
1476 | ErrorF("-logfile file specify a log file name\n"); | |
1477 | ErrorF("-configure probe for devices and write an " | |
1478 | __XCONFIGFILE__ "\n"); | |
1479 | ErrorF | |
1480 | ("-showopts print available options for all installed drivers\n"); | |
1481 | } | |
1482 | ErrorF | |
1483 | ("-config file specify a configuration file, relative to the\n"); | |
1484 | ErrorF(" " __XCONFIGFILE__ | |
1485 | " search path, only root can use absolute\n"); | |
1486 | ErrorF | |
1487 | ("-configdir dir specify a configuration directory, relative to the\n"); | |
1488 | ErrorF(" " __XCONFIGDIR__ | |
1489 | " search path, only root can use absolute\n"); | |
1490 | ErrorF("-verbose [n] verbose startup messages\n"); | |
1491 | ErrorF("-logverbose [n] verbose log messages\n"); | |
1492 | ErrorF("-quiet minimal startup messages\n"); | |
1493 | ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n"); | |
1494 | ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n"); | |
1495 | ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n"); | |
1496 | ErrorF("-depth n set colour depth. Default: 8\n"); | |
1497 | ErrorF | |
1498 | ("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n"); | |
1499 | ErrorF("-rgamma f set gamma value for red phase\n"); | |
1500 | ErrorF("-ggamma f set gamma value for green phase\n"); | |
1501 | ErrorF("-bgamma f set gamma value for blue phase\n"); | |
1502 | ErrorF | |
1503 | ("-weight nnn set RGB weighting at 16 bpp. Default: 565\n"); | |
1504 | ErrorF("-layout name specify the ServerLayout section name\n"); | |
1505 | ErrorF("-screen name specify the Screen section name\n"); | |
1506 | ErrorF | |
1507 | ("-keyboard name specify the core keyboard InputDevice name\n"); | |
1508 | ErrorF | |
1509 | ("-pointer name specify the core pointer InputDevice name\n"); | |
1510 | ErrorF("-nosilk disable Silken Mouse\n"); | |
1511 | ErrorF("-flipPixels swap default black/white Pixel values\n"); | |
1512 | #ifdef XF86VIDMODE | |
1513 | ErrorF("-disableVidMode disable mode adjustments with xvidtune\n"); | |
1514 | ErrorF | |
1515 | ("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n"); | |
1516 | #endif | |
1517 | ErrorF | |
1518 | ("-allowMouseOpenFail start server even if the mouse can't be initialized\n"); | |
1519 | ErrorF("-ignoreABI make module ABI mismatches non-fatal\n"); | |
1520 | #ifdef XSERVER_LIBPCIACCESS | |
1521 | ErrorF | |
1522 | ("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n"); | |
1523 | #endif | |
1524 | ErrorF("-version show the server version\n"); | |
1525 | ErrorF("-showDefaultModulePath show the server default module path\n"); | |
1526 | ErrorF("-showDefaultLibPath show the server default library path\n"); | |
1527 | ErrorF | |
1528 | ("-novtswitch don't automatically switch VT at reset & exit\n"); | |
1529 | ErrorF("-sharevts share VTs with another X server\n"); | |
1530 | /* OS-specific usage */ | |
1531 | xf86UseMsg(); | |
1532 | ErrorF("\n"); | |
1533 | } | |
1534 | ||
1535 | /* | |
1536 | * xf86LoadModules iterates over a list that is being passed in. | |
1537 | */ | |
1538 | Bool | |
1539 | xf86LoadModules(char **list, pointer *optlist) | |
1540 | { | |
1541 | int errmaj, errmin; | |
1542 | pointer opt; | |
1543 | int i; | |
1544 | char *name; | |
1545 | Bool failed = FALSE; | |
1546 | ||
1547 | if (!list) | |
1548 | return TRUE; | |
1549 | ||
1550 | for (i = 0; list[i] != NULL; i++) { | |
1551 | ||
1552 | /* Normalise the module name */ | |
1553 | name = xf86NormalizeName(list[i]); | |
1554 | ||
1555 | /* Skip empty names */ | |
1556 | if (name == NULL || *name == '\0') { | |
1557 | free(name); | |
1558 | continue; | |
1559 | } | |
1560 | ||
1561 | /* Replace obsolete keyboard driver with kbd */ | |
1562 | if (!xf86NameCmp(name, "keyboard")) { | |
1563 | strcpy(name, "kbd"); | |
1564 | } | |
1565 | ||
1566 | if (optlist) | |
1567 | opt = optlist[i]; | |
1568 | else | |
1569 | opt = NULL; | |
1570 | ||
1571 | if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) { | |
1572 | LoaderErrorMsg(NULL, name, errmaj, errmin); | |
1573 | failed = TRUE; | |
1574 | } | |
1575 | free(name); | |
1576 | } | |
1577 | return !failed; | |
1578 | } | |
1579 | ||
1580 | /* Pixmap format stuff */ | |
1581 | ||
1582 | PixmapFormatPtr | |
1583 | xf86GetPixFormat(ScrnInfoPtr pScrn, int depth) | |
1584 | { | |
1585 | int i; | |
1586 | static PixmapFormatRec format; /* XXX not reentrant */ | |
1587 | ||
1588 | /* | |
1589 | * When the formats[] list initialisation isn't complete, check the | |
1590 | * depth 24 pixmap config/cmdline options and screen-specified formats. | |
1591 | */ | |
1592 | ||
1593 | if (!formatsDone) { | |
1594 | if (depth == 24) { | |
1595 | Pix24Flags pix24 = Pix24DontCare; | |
1596 | ||
1597 | format.depth = 24; | |
1598 | format.scanlinePad = BITMAP_SCANLINE_PAD; | |
1599 | if (xf86Info.pixmap24 != Pix24DontCare) | |
1600 | pix24 = xf86Info.pixmap24; | |
1601 | else if (pScrn->pixmap24 != Pix24DontCare) | |
1602 | pix24 = pScrn->pixmap24; | |
1603 | if (pix24 == Pix24Use24) | |
1604 | format.bitsPerPixel = 24; | |
1605 | else | |
1606 | format.bitsPerPixel = 32; | |
1607 | return &format; | |
1608 | } | |
1609 | } | |
1610 | ||
1611 | for (i = 0; i < numFormats; i++) | |
1612 | if (formats[i].depth == depth) | |
1613 | break; | |
1614 | if (i != numFormats) | |
1615 | return &formats[i]; | |
1616 | else if (!formatsDone) { | |
1617 | /* Check for screen-specified formats */ | |
1618 | for (i = 0; i < pScrn->numFormats; i++) | |
1619 | if (pScrn->formats[i].depth == depth) | |
1620 | break; | |
1621 | if (i != pScrn->numFormats) | |
1622 | return &pScrn->formats[i]; | |
1623 | } | |
1624 | return NULL; | |
1625 | } | |
1626 | ||
1627 | int | |
1628 | xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth) | |
1629 | { | |
1630 | PixmapFormatPtr format; | |
1631 | ||
1632 | format = xf86GetPixFormat(pScrn, depth); | |
1633 | if (format) | |
1634 | return format->bitsPerPixel; | |
1635 | else | |
1636 | return 0; | |
1637 | } | |
1638 | ||
1639 | #ifdef DDXBEFORERESET | |
1640 | void | |
1641 | ddxBeforeReset(void) | |
1642 | { | |
1643 | } | |
1644 | #endif |