1 tsi 1.13 /* $XFree86: xc/programs/Xserver/hw/dmx/dmxinit.c,v 1.12tsi Exp $ */
|
2 martin 1.1 /*
3 * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
4 *
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation on the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial
17 * portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
23 martin 1.1 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
24 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29 /*
30 * Authors:
31 * Kevin E. Martin <kem@redhat.com>
32 * David H. Dawes <dawes@xfree86.org>
33 * Rickard E. (Rik) Faith <faith@redhat.com>
34 *
35 */
36
37 /** \file
38 * Provide expected functions for initialization from the ddx layer and
39 * global variables for the DMX server. */
40
41 #include "dmx.h"
42 #include "dmxinit.h"
43 #include "dmxsync.h"
44 martin 1.1 #include "dmxlog.h"
45 #include "dmxinput.h"
46 #include "dmxscrinit.h"
47 #include "dmxcursor.h"
48 #include "dmxfont.h"
49 #include "config/dmxconfig.h"
50 #include "dmxcb.h"
51 #include "dmxprop.h"
52 #include "dmxstat.h"
53 #ifdef RENDER
54 #include "dmxpict.h"
55 #endif
56
|
57 tsi 1.9 #include <X11/Xos.h> /* For gettimeofday */
|
58 martin 1.1 #include "dixstruct.h"
59 #include "panoramiXsrv.h"
60
61 #include <signal.h> /* For SIGQUIT */
62
|
63 tsi 1.4 #ifdef GLXPROXY
|
64 martin 1.1 #include <GL/glx.h>
65 #include <GL/glxint.h>
66 #include "dmx_glxvisuals.h"
|
67 tsi 1.9 #include <X11/extensions/Xext.h>
68 #include <X11/extensions/extutil.h>
|
69 martin 1.1
70 extern void GlxSetVisualConfigs(
71 int nconfigs,
72 __GLXvisualConfig *configs,
73 void **configprivs
74 );
|
75 tsi 1.4 #endif /* GLXPROXY */
|
76 martin 1.1
77 /* Global variables available to all Xserver/hw/dmx routines. */
78 int dmxNumScreens;
79 DMXScreenInfo *dmxScreens;
80
81 int dmxNumInputs;
82 DMXInputInfo *dmxInputs;
83
84 int dmxShadowFB = FALSE;
85
86 XErrorEvent dmxLastErrorEvent;
87 Bool dmxErrorOccurred = FALSE;
88
89 char *dmxFontPath = NULL;
90
91 Bool dmxOffScreenOpt = TRUE;
92
93 Bool dmxSubdividePrimitives = TRUE;
94
95 Bool dmxLazyWindowCreation = TRUE;
96
97 martin 1.1 Bool dmxUseXKB = TRUE;
98
99 int dmxDepth = 0;
100
101 Bool dmxNoRender = FALSE;
102
|
103 tsi 1.4 #ifndef GLXPROXY
|
104 martin 1.1 static Bool dmxGLXProxy = FALSE;
105 #else
106 Bool dmxGLXProxy = TRUE;
107
108 Bool dmxGLXSwapGroupSupport = TRUE;
109
110 Bool dmxGLXSyncSwap = FALSE;
111
112 Bool dmxGLXFinishSwap = FALSE;
113 #endif
114
115 Bool dmxIgnoreBadFontPaths = FALSE;
116
117 Bool dmxAddRemoveScreens = FALSE;
118
119 /* dmxErrorHandler catches errors that occur when calling one of the
120 * back-end servers. Some of this code is based on _XPrintDefaultError
121 * in xc/lib/X11/XlibInt.c */
122 static int dmxErrorHandler(Display *dpy, XErrorEvent *ev)
123 {
124 #define DMX_ERROR_BUF_SIZE 256
125 martin 1.1 /* RATS: these buffers are only used in
126 * length-limited calls. */
127 char buf[DMX_ERROR_BUF_SIZE];
128 char request[DMX_ERROR_BUF_SIZE];
129 _XExtension *ext = NULL;
130
131 dmxErrorOccurred = TRUE;
132 dmxLastErrorEvent = *ev;
133
134 XGetErrorText(dpy, ev->error_code, buf, sizeof(buf));
135 dmxLog(dmxWarning, "dmxErrorHandler: %s\n", buf);
136
137 /* Find major opcode name */
138 if (ev->request_code < 128) {
139 XmuSnprintf(request, sizeof(request), "%d", ev->request_code);
140 XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf));
141 } else {
142 for (ext = dpy->ext_procs;
143 ext && ext->codes.major_opcode != ev->request_code;
144 ext = ext->next);
145 if (ext) strncpy(buf, ext->name, sizeof(buf));
146 martin 1.1 else buf[0] = '\0';
147 }
148 dmxLog(dmxWarning, " Major opcode: %d (%s)\n",
149 ev->request_code, buf);
150
151 /* Find minor opcode name */
152 if (ev->request_code >= 128 && ext) {
153 XmuSnprintf(request, sizeof(request), "%d", ev->request_code);
154 XmuSnprintf(request, sizeof(request), "%s.%d",
155 ext->name, ev->minor_code);
156 XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf));
157 dmxLog(dmxWarning, " Minor opcode: %d (%s)\n",
158 ev->minor_code, buf);
159 }
160
161 /* Provide value information */
162 switch (ev->error_code) {
163 case BadValue:
164 dmxLog(dmxWarning, " Value: 0x%x\n",
165 ev->resourceid);
166 break;
167 martin 1.1 case BadAtom:
168 dmxLog(dmxWarning, " AtomID: 0x%x\n",
169 ev->resourceid);
170 break;
171 default:
172 dmxLog(dmxWarning, " ResourceID: 0x%x\n",
173 ev->resourceid);
174 break;
175 }
176
177 /* Provide serial number information */
178 dmxLog(dmxWarning, " Failed serial number: %d\n",
179 ev->serial);
180 dmxLog(dmxWarning, " Current serial number: %d\n",
181 dpy->request);
182 return 0;
183 }
184
|
185 tsi 1.4 #ifdef GLXPROXY
|
186 martin 1.1 static int dmxNOPErrorHandler(Display *dpy, XErrorEvent *ev)
187 {
188 return 0;
189 }
190 #endif
191
192 Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen)
193 {
194 if (!(dmxScreen->beDisplay = XOpenDisplay(dmxScreen->name)))
195 return FALSE;
196
197 dmxPropertyDisplay(dmxScreen);
198 return TRUE;
199 }
200
201 void dmxSetErrorHandler(DMXScreenInfo *dmxScreen)
202 {
203 XSetErrorHandler(dmxErrorHandler);
204 }
205
206 static void dmxPrintScreenInfo(DMXScreenInfo *dmxScreen)
207 martin 1.1 {
208 XWindowAttributes attribs;
209 int ndepths = 0, *depths = NULL;
210 int i;
211 Display *dpy = dmxScreen->beDisplay;
212 Screen *s = DefaultScreenOfDisplay(dpy);
213 int scr = DefaultScreen(dpy);
214
215 XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs);
216 if (!(depths = XListDepths(dpy, scr, &ndepths))) ndepths = 0;
217
218 dmxLogOutput(dmxScreen, "Name of display: %s\n", DisplayString(dpy));
219 dmxLogOutput(dmxScreen, "Version number: %d.%d\n",
220 ProtocolVersion(dpy), ProtocolRevision(dpy));
221 dmxLogOutput(dmxScreen, "Vendor string: %s\n", ServerVendor(dpy));
222 if (!strstr(ServerVendor(dpy), "XFree86")) {
223 dmxLogOutput(dmxScreen, "Vendor release: %d\n", VendorRelease(dpy));
224 } else {
225 /* This code based on xdpyinfo.c */
226 int v = VendorRelease(dpy);
227 int major = -1, minor = -1, patch = -1, subpatch = -1;
228 martin 1.1
229 if (v < 336)
230 major = v / 100, minor = (v / 10) % 10, patch = v % 10;
231 else if (v < 3900) {
232 major = v / 1000;
233 minor = (v / 100) % 10;
234 if (((v / 10) % 10) || (v % 10)) {
235 patch = (v / 10) % 10;
236 if (v % 10) subpatch = v % 10;
237 }
238 } else if (v < 40000000) {
239 major = v / 1000;
240 minor = (v / 10) % 10;
241 if (v % 10) patch = v % 10;
242 } else {
243 major = v / 10000000;
244 minor = (v / 100000) % 100;
245 patch = (v / 1000) % 100;
246 if (v % 1000) subpatch = v % 1000;
247 }
248 dmxLogOutput(dmxScreen, "Vendor release: %d (XFree86 version: %d.%d",
249 martin 1.1 v, major, minor);
250 if (patch > 0) dmxLogOutputCont(dmxScreen, ".%d", patch);
251 if (subpatch > 0) dmxLogOutputCont(dmxScreen, ".%d", subpatch);
252 dmxLogOutputCont(dmxScreen, ")\n");
253 }
254
255
256 dmxLogOutput(dmxScreen, "Dimensions: %dx%d pixels\n",
257 attribs.width, attribs.height);
258 dmxLogOutput(dmxScreen, "%d depths on screen %d: ", ndepths, scr);
259 for (i = 0; i < ndepths; i++)
260 dmxLogOutputCont(dmxScreen, "%c%d", i ? ',' : ' ', depths[i]);
261 dmxLogOutputCont(dmxScreen, "\n");
262 dmxLogOutput(dmxScreen, "Depth of root window: %d plane%s (%d)\n",
263 attribs.depth, attribs.depth == 1 ? "" : "s",
264 DisplayPlanes(dpy, scr));
265 dmxLogOutput(dmxScreen, "Number of colormaps: %d min, %d max\n",
266 MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
267 dmxLogOutput(dmxScreen, "Options: backing-store %s, save-unders %s\n",
268 (DoesBackingStore (s) == NotUseful) ? "no" :
269 ((DoesBackingStore (s) == Always) ? "yes" : "when mapped"),
270 martin 1.1 DoesSaveUnders (s) ? "yes" : "no");
271 dmxLogOutput(dmxScreen, "Window Manager running: %s\n",
272 (dmxScreen->WMRunningOnBE) ? "yes" : "no");
273
274 if (dmxScreen->WMRunningOnBE) {
275 dmxLogOutputWarning(dmxScreen,
276 "Window manager running "
277 "-- colormaps not supported\n");
278 }
279 XFree(depths);
280 }
281
282 void dmxGetScreenAttribs(DMXScreenInfo *dmxScreen)
283 {
284 XWindowAttributes attribs;
285 Display *dpy = dmxScreen->beDisplay;
|
286 tsi 1.4 #ifdef GLXPROXY
|
287 martin 1.1 int dummy;
288 #endif
289
290 XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs);
291
292 dmxScreen->beWidth = attribs.width;
293 dmxScreen->beHeight = attribs.height;
294
295 /* Fill in missing geometry information */
296 if (dmxScreen->scrnXSign < 0) {
297 if (dmxScreen->scrnWidth) {
298 dmxScreen->scrnX = (attribs.width - dmxScreen->scrnWidth
299 - dmxScreen->scrnX);
300 } else {
301 dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX;
302 dmxScreen->scrnX = 0;
303 }
304 }
305 if (dmxScreen->scrnYSign < 0) {
306 if (dmxScreen->scrnHeight) {
307 dmxScreen->scrnY = (attribs.height - dmxScreen->scrnHeight
308 martin 1.1 - dmxScreen->scrnY);
309 } else {
310 dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY;
311 dmxScreen->scrnY = 0;
312 }
313 }
314 if (!dmxScreen->scrnWidth)
315 dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX;
316 if (!dmxScreen->scrnHeight)
317 dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY;
318
319 if (!dmxScreen->rootWidth) dmxScreen->rootWidth = dmxScreen->scrnWidth;
320 if (!dmxScreen->rootHeight) dmxScreen->rootHeight = dmxScreen->scrnHeight;
321 if (dmxScreen->rootWidth + dmxScreen->rootX > dmxScreen->scrnWidth)
322 dmxScreen->rootWidth = dmxScreen->scrnWidth - dmxScreen->rootX;
323 if (dmxScreen->rootHeight + dmxScreen->rootY > dmxScreen->scrnHeight)
324 dmxScreen->rootHeight = dmxScreen->scrnHeight - dmxScreen->rootY;
325
326 /* FIXME: Get these from the back-end server */
327 dmxScreen->beXDPI = 75;
328 dmxScreen->beYDPI = 75;
329 martin 1.1
330 dmxScreen->beDepth = attribs.depth; /* FIXME: verify that this
331 * works always. In
332 * particular, this will work
333 * well for depth=16, will fail
334 * because of colormap issues
335 * at depth 8. More work needs
336 * to be done here. */
337
338 if (dmxScreen->beDepth <= 8) dmxScreen->beBPP = 8;
339 else if (dmxScreen->beDepth <= 16) dmxScreen->beBPP = 16;
340 else dmxScreen->beBPP = 32;
341
|
342 tsi 1.4 #ifdef GLXPROXY
|
343 martin 1.1 /* get the majorOpcode for the back-end GLX extension */
344 XQueryExtension(dpy, "GLX", &dmxScreen->glxMajorOpcode,
345 &dummy, &dmxScreen->glxErrorBase);
346 #endif
347
348 dmxPrintScreenInfo(dmxScreen);
349 dmxLogOutput(dmxScreen, "%dx%d+%d+%d on %dx%d at depth=%d, bpp=%d\n",
350 dmxScreen->scrnWidth, dmxScreen->scrnHeight,
351 dmxScreen->scrnX, dmxScreen->scrnY,
352 dmxScreen->beWidth, dmxScreen->beHeight,
353 dmxScreen->beDepth, dmxScreen->beBPP);
354 if (dmxScreen->beDepth == 8)
355 dmxLogOutputWarning(dmxScreen,
356 "Support for depth == 8 is not complete\n");
357 }
358
359 Bool dmxGetVisualInfo(DMXScreenInfo *dmxScreen)
360 {
361 int i;
362 XVisualInfo visinfo;
363
364 martin 1.1 visinfo.screen = DefaultScreen(dmxScreen->beDisplay);
365 dmxScreen->beVisuals = XGetVisualInfo(dmxScreen->beDisplay,
366 VisualScreenMask,
367 &visinfo,
368 &dmxScreen->beNumVisuals);
369
370 dmxScreen->beDefVisualIndex = -1;
371
372 if (defaultColorVisualClass >= 0 || dmxDepth > 0) {
373 for (i = 0; i < dmxScreen->beNumVisuals; i++)
374 if (defaultColorVisualClass >= 0) {
375 if (dmxScreen->beVisuals[i].class == defaultColorVisualClass) {
376 if (dmxDepth > 0) {
377 if (dmxScreen->beVisuals[i].depth == dmxDepth) {
378 dmxScreen->beDefVisualIndex = i;
379 break;
380 }
381 } else {
382 dmxScreen->beDefVisualIndex = i;
383 break;
384 }
385 martin 1.1 }
386 } else if (dmxScreen->beVisuals[i].depth == dmxDepth) {
387 dmxScreen->beDefVisualIndex = i;
388 break;
389 }
390 } else {
391 visinfo.visualid =
392 XVisualIDFromVisual(DefaultVisual(dmxScreen->beDisplay,
393 visinfo.screen));
394
395 for (i = 0; i < dmxScreen->beNumVisuals; i++)
396 if (visinfo.visualid == dmxScreen->beVisuals[i].visualid) {
397 dmxScreen->beDefVisualIndex = i;
398 break;
399 }
400 }
401
402 for (i = 0; i < dmxScreen->beNumVisuals; i++)
403 dmxLogVisual(dmxScreen, &dmxScreen->beVisuals[i],
404 (i == dmxScreen->beDefVisualIndex));
405
406 martin 1.1 return (dmxScreen->beDefVisualIndex >= 0);
407 }
408
409 void dmxGetColormaps(DMXScreenInfo *dmxScreen)
410 {
411 int i;
412
413 dmxScreen->beNumDefColormaps = dmxScreen->beNumVisuals;
414 dmxScreen->beDefColormaps = xalloc(dmxScreen->beNumDefColormaps *
415 sizeof(*dmxScreen->beDefColormaps));
416
417 for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
418 dmxScreen->beDefColormaps[i] =
419 XCreateColormap(dmxScreen->beDisplay,
420 DefaultRootWindow(dmxScreen->beDisplay),
421 dmxScreen->beVisuals[i].visual,
422 AllocNone);
423
424 dmxScreen->beBlackPixel = BlackPixel(dmxScreen->beDisplay,
425 DefaultScreen(dmxScreen->beDisplay));
426 dmxScreen->beWhitePixel = WhitePixel(dmxScreen->beDisplay,
427 martin 1.1 DefaultScreen(dmxScreen->beDisplay));
428 }
429
430 void dmxGetPixmapFormats(DMXScreenInfo *dmxScreen)
431 {
432 dmxScreen->beDepths =
433 XListDepths(dmxScreen->beDisplay, DefaultScreen(dmxScreen->beDisplay),
434 &dmxScreen->beNumDepths);
435
436 dmxScreen->bePixmapFormats =
437 XListPixmapFormats(dmxScreen->beDisplay,
438 &dmxScreen->beNumPixmapFormats);
439 }
440
441 static Bool dmxSetPixmapFormats(ScreenInfo *pScreenInfo,
442 DMXScreenInfo *dmxScreen)
443 {
444 XPixmapFormatValues *bePixmapFormat;
445 PixmapFormatRec *format;
446 int i, j;
447
448 martin 1.1 pScreenInfo->imageByteOrder = ImageByteOrder(dmxScreen->beDisplay);
449 pScreenInfo->bitmapScanlineUnit = BitmapUnit(dmxScreen->beDisplay);
450 pScreenInfo->bitmapScanlinePad = BitmapPad(dmxScreen->beDisplay);
451 pScreenInfo->bitmapBitOrder = BitmapBitOrder(dmxScreen->beDisplay);
452
453 pScreenInfo->numPixmapFormats = 0;
454 for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
455 bePixmapFormat = &dmxScreen->bePixmapFormats[i];
456 for (j = 0; j < dmxScreen->beNumDepths; j++)
457 if ((bePixmapFormat->depth == 1) ||
458 (bePixmapFormat->depth == dmxScreen->beDepths[j])) {
459 format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats];
460
461 format->depth = bePixmapFormat->depth;
462 format->bitsPerPixel = bePixmapFormat->bits_per_pixel;
463 format->scanlinePad = bePixmapFormat->scanline_pad;
464
465 pScreenInfo->numPixmapFormats++;
466 break;
467 }
468 }
469 martin 1.1
470 return TRUE;
471 }
472
473 void dmxCheckForWM(DMXScreenInfo *dmxScreen)
474 {
475 Status status;
476 XWindowAttributes xwa;
477
478 status = XGetWindowAttributes(dmxScreen->beDisplay,
479 DefaultRootWindow(dmxScreen->beDisplay),
480 &xwa);
481 dmxScreen->WMRunningOnBE =
482 (status &&
483 ((xwa.all_event_masks & SubstructureRedirectMask) ||
484 (xwa.all_event_masks & SubstructureNotifyMask)));
485 }
486
487 /** Initialize the display and collect relevant information about the
488 * display properties */
489 static void dmxDisplayInit(DMXScreenInfo *dmxScreen)
490 martin 1.1 {
491 if (!dmxOpenDisplay(dmxScreen))
492 dmxLog(dmxFatal,
493 "dmxOpenDisplay: Unable to open display %s\n",
494 dmxScreen->name);
495
496 dmxSetErrorHandler(dmxScreen);
497 dmxCheckForWM(dmxScreen);
498 dmxGetScreenAttribs(dmxScreen);
499
500 if (!dmxGetVisualInfo(dmxScreen))
501 dmxLog(dmxFatal, "dmxGetVisualInfo: No matching visuals found\n");
502
503 dmxGetColormaps(dmxScreen);
504 dmxGetPixmapFormats(dmxScreen);
505 }
506
507 /* If this doesn't compile, just add || defined(yoursystem) to the line
508 * below. This information is to help with bug reports and is not
509 * critical. */
|
510 tsi 1.7 #if !defined(_POSIX_SOURCE) && !defined(__sgi) && !defined(__UNIXOS2__)
|
511 martin 1.1 static const char *dmxExecOS(void) { return ""; }
512 #else
513 #include <sys/utsname.h>
514 static const char *dmxExecOS(void)
515 {
516 static char buffer[128];
517 static int initialized = 0;
518 struct utsname u;
519
520 if (!initialized++) {
521 memset(buffer, 0, sizeof(buffer));
|
522 tsi 1.10 if (uname(&u) >= 0)
523 XmuSnprintf(buffer, sizeof(buffer)-1, "%s %s %s",
524 u.sysname, u.release, u.version);
|
525 martin 1.1 }
526 return buffer;
527 }
528 #endif
529
530 static const char *dmxBuildCompiler(void)
531 {
532 static char buffer[128];
533 static int initialized = 0;
534
535 if (!initialized++) {
536 memset(buffer, 0, sizeof(buffer));
537 #if defined(__GNUC__) && defined(__GNUC_MINOR__) &&defined(__GNUC_PATCHLEVEL__)
538 XmuSnprintf(buffer, sizeof(buffer)-1, "gcc %d.%d.%d",
539 __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
540 #elif defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)
541 {
542 int a = _COMPILER_VERSION / 100;
543 int b = (_COMPILER_VERSION - a * 100) / 10;
544 int c = _COMPILER_VERSION - a * 100 - b * 10;
545 XmuSnprintf(buffer, sizeof(buffer)-1, "SGI MIPSpro %d.%d.%d",
546 martin 1.1 a, b, c);
547 }
548 #endif
549 }
550 return buffer;
551 }
552
553 static const char *dmxExecHost(void)
554 {
555 static char buffer[128];
556 static int initialized = 0;
557
558 if (!initialized++) {
559 memset(buffer, 0, sizeof(buffer));
560 XmuGetHostname(buffer, sizeof(buffer) - 1);
561 }
562 return buffer;
563 }
564
565 /** This routine is called in Xserver/dix/main.c from \a main(). */
|
566 tsi 1.12 void InitOutput(ScreenInfo *pScreenInfo, const int argc, const char *argv[])
|
567 martin 1.1 {
568 int i;
569 static unsigned long dmxGeneration = 0;
|
570 tsi 1.4 #ifdef GLXPROXY
|
571 martin 1.1 Bool glxSupported = TRUE;
572 #endif
573
574 if (dmxGeneration != serverGeneration) {
575 int vendrel = VENDOR_RELEASE;
576 int major, minor, year, month, day;
577
578 dmxGeneration = serverGeneration;
579
580 major = vendrel / 100000000;
581 vendrel -= major * 100000000;
582 minor = vendrel / 1000000;
583 vendrel -= minor * 1000000;
584 year = vendrel / 10000;
585 vendrel -= year * 10000;
586 month = vendrel / 100;
587 vendrel -= month * 100;
588 day = vendrel;
589
590 /* Add other epoch tests here */
591 if (major > 0 && minor > 0) year += 2000;
592 martin 1.1
593 dmxLog(dmxInfo, "Generation: %d\n", dmxGeneration);
594 dmxLog(dmxInfo, "DMX version: %d.%d.%02d%02d%02d (%s)\n",
595 major, minor, year, month, day, VENDOR_STRING);
596
597 SetVendorRelease(VENDOR_RELEASE);
598 SetVendorString(VENDOR_STRING);
599
600 if (dmxGeneration == 1) {
601 dmxLog(dmxInfo, "DMX Build OS: %s (%s)\n", OSNAME, OSVENDOR);
602 dmxLog(dmxInfo, "DMX Build Compiler: %s\n", dmxBuildCompiler());
603 dmxLog(dmxInfo, "DMX Execution OS: %s\n", dmxExecOS());
604 dmxLog(dmxInfo, "DMX Execution Host: %s\n", dmxExecHost());
605 }
606 dmxLog(dmxInfo, "MAXSCREENS: %d\n", MAXSCREENS);
607
608 for (i = 0; i < dmxNumScreens; i++) {
609 if (dmxScreens[i].beDisplay)
610 dmxLog(dmxWarning, "Display \"%s\" still open\n",
611 dmxScreens[i].name);
612 dmxStatFree(dmxScreens[i].stat);
613 martin 1.1 dmxScreens[i].stat = NULL;
614 }
615 for (i = 0; i < dmxNumInputs; i++) dmxInputFree(&dmxInputs[i]);
616 if (dmxScreens) free(dmxScreens);
617 if (dmxInputs) free(dmxInputs);
618 dmxScreens = NULL;
619 dmxInputs = NULL;
620 dmxNumScreens = 0;
621 dmxNumInputs = 0;
622 }
623
624 /* Make sure that the command-line arguments are sane. */
625 if (dmxAddRemoveScreens && (!dmxNoRender || dmxGLXProxy)) {
626 /* Currently it is not possible to support GLX and Render
627 * extensions with dynamic screen addition/removal due to the
628 * state that each extension keeps, which cannot be restored. */
629 dmxLog(dmxWarning,
630 "GLX Proxy and Render extensions do not yet support dynamic\n");
631 dmxLog(dmxWarning,
632 "screen addition and removal. Please specify -noglxproxy\n");
633 dmxLog(dmxWarning,
634 martin 1.1 "and -norender on the command line or in the configuration\n");
635 dmxLog(dmxWarning,
636 "file to disable these two extensions if you wish to use\n");
637 dmxLog(dmxWarning,
638 "the dynamic addition and removal of screens support.\n");
639 dmxLog(dmxFatal,
640 "Dynamic screen addition/removal error (see above).\n");
641 }
642
643 /* ddxProcessArgument has been called at this point, but any data
644 * from the configuration file has not been applied. Do so, and be
645 * sure we have at least one back-end display. */
646 dmxConfigConfigure();
647 if (!dmxNumScreens)
648 dmxLog(dmxFatal, "InitOutput: no back-end displays found\n");
649 if (!dmxNumInputs)
650 dmxLog(dmxInfo, "InitOutput: no inputs found\n");
651
652 /* Disable lazy window creation optimization if offscreen
653 * optimization is disabled */
654 if (!dmxOffScreenOpt && dmxLazyWindowCreation) {
655 martin 1.1 dmxLog(dmxInfo,
656 "InitOutput: Disabling lazy window creation optimization\n");
657 dmxLog(dmxInfo,
658 " since it requires the offscreen optimization\n");
659 dmxLog(dmxInfo,
660 " to function properly.\n");
661 dmxLazyWindowCreation = FALSE;
662 }
663
664 /* Open each display and gather information about it. */
665 for (i = 0; i < dmxNumScreens; i++)
666 dmxDisplayInit(&dmxScreens[i]);
667
|
668 tsi 1.3 #ifdef PANORAMIX
|
669 martin 1.1 /* Register a Xinerama callback which will run from within
670 * PanoramiXCreateConnectionBlock. We can use the callback to
671 * determine if Xinerama is loaded and to check the visuals
672 * determined by PanoramiXConsolidate. */
673 XineramaRegisterConnectionBlockCallback(dmxConnectionBlockCallback);
|
674 martin 1.2 #endif
|
675 martin 1.1
676 /* Since we only have a single screen thus far, we only need to set
677 the pixmap formats to match that screen. FIXME: this isn't true.*/
678 if (!dmxSetPixmapFormats(pScreenInfo, &dmxScreens[0])) return;
679
680 /* Might want to install a signal handler to allow cleaning up after
681 * unexpected signals. The DIX/OS layer already handles SIGINT and
682 * SIGTERM, so everything is OK for expected signals. --DD
683 *
684 * SIGHUP, SIGINT, and SIGTERM are trapped in os/connection.c
685 * SIGQUIT is another common signal that is sent from the keyboard.
686 * Trap it here, to ensure that the keyboard modifier map and other
687 * state for the input devices are restored. (This makes the
688 * behavior of SIGQUIT somewhat unexpected, since it will be the
689 * same as the behavior of SIGINT. However, leaving the modifier
690 * map of the input devices empty is even more unexpected.) --RF
691 */
692 OsSignal(SIGQUIT, GiveUp);
693
|
694 tsi 1.4 #ifdef GLXPROXY
|
695 martin 1.1 /* Check if GLX extension exists on all back-end servers */
696 for (i = 0; i < dmxNumScreens; i++)
697 glxSupported &= (dmxScreens[i].glxMajorOpcode > 0);
698 #endif
699
700 /* Tell dix layer about the backend displays */
701 for (i = 0; i < dmxNumScreens; i++) {
702
|
703 tsi 1.4 #ifdef GLXPROXY
|
704 martin 1.1 if (glxSupported) {
705 /*
706 * Builds GLX configurations from the list of visuals
707 * supported by the back-end server, and give that
708 * configuration list to the glx layer - so that he will
709 * build the visuals accordingly.
710 */
711
712 DMXScreenInfo *dmxScreen = &dmxScreens[i];
713 __GLXvisualConfig *configs = NULL;
714 dmxGlxVisualPrivate **configprivs = NULL;
715 int nconfigs = 0;
716 int (*oldErrorHandler)(Display *, XErrorEvent *);
717 int i;
718
719 /* Catch errors if when using an older GLX w/o FBconfigs */
720 oldErrorHandler = XSetErrorHandler(dmxNOPErrorHandler);
721
722 /* Get FBConfigs of the back-end server */
723 dmxScreen->fbconfigs = GetGLXFBConfigs(dmxScreen->beDisplay,
724 dmxScreen->glxMajorOpcode,
725 martin 1.1 &dmxScreen->numFBConfigs);
726
727 XSetErrorHandler(oldErrorHandler);
728
729 dmxScreen->glxVisuals =
730 GetGLXVisualConfigs(dmxScreen->beDisplay,
731 DefaultScreen(dmxScreen->beDisplay),
732 &dmxScreen->numGlxVisuals);
733
734 if (dmxScreen->fbconfigs) {
735 configs =
736 GetGLXVisualConfigsFromFBConfigs(dmxScreen->fbconfigs,
737 dmxScreen->numFBConfigs,
738 dmxScreen->beVisuals,
739 dmxScreen->beNumVisuals,
740 dmxScreen->glxVisuals,
741 dmxScreen->numGlxVisuals,
742 &nconfigs);
743 } else {
744 configs = dmxScreen->glxVisuals;
745 nconfigs = dmxScreen->numGlxVisuals;
746 martin 1.1 }
747
748 configprivs = xalloc(dmxScreen->beNumVisuals *
749 sizeof(dmxGlxVisualPrivate*));
750
751 if (configs != NULL && configprivs != NULL) {
752
753 /* Initialize our private info for each visual
754 * (currently only x_visual_depth and x_visual_class)
755 */
756 for (i = 0; i < nconfigs; i++) {
757
758 configprivs[i] = (dmxGlxVisualPrivate *)
759 xalloc(sizeof(dmxGlxVisualPrivate));
760 configprivs[i]->x_visual_depth = 0;
761 configprivs[i]->x_visual_class = 0;
762
763 /* Find the visual depth */
764 if (configs[i].vid > 0) {
765 int j;
766 for (j = 0; j < dmxScreen->beNumVisuals; j++) {
767 martin 1.1 if (dmxScreen->beVisuals[j].visualid ==
768 configs[i].vid) {
769 configprivs[i]->x_visual_depth =
770 dmxScreen->beVisuals[j].depth;
771 configprivs[i]->x_visual_class =
772 dmxScreen->beVisuals[j].class;
773 break;
774 }
775 }
776 }
777 }
778
779 /* Hand out the glx configs to glx extension */
780 GlxSetVisualConfigs(nconfigs, configs, (void**)configprivs);
781 }
782 }
|
783 tsi 1.4 #endif /* GLXPROXY */
|
784 martin 1.1
785 AddScreen(dmxScreenInit, argc, argv);
786 }
787
788 /* Compute origin information. */
789 dmxInitOrigins();
790
791 /* Compute overlap information. */
792 dmxInitOverlap();
793
794 /* Make sure there is a global width/height available */
795 dmxComputeWidthHeight(DMX_NO_RECOMPUTE_BOUNDING_BOX);
796
797 /* FIXME: The following is temporarily placed here. When the DMX
798 * extension is available, it will be move there.
799 */
800 dmxInitFonts();
801
802 #ifdef RENDER
803 /* Initialize the render extension */
804 if (!dmxNoRender)
805 martin 1.1 dmxInitRender();
806 #endif
807
808 /* Initialized things that need timer hooks */
809 dmxStatInit();
810 dmxSyncInit(); /* Calls RegisterBlockAndWakeupHandlers */
811
812 dmxLog(dmxInfo, "Shadow framebuffer support %s\n",
813 dmxShadowFB ? "enabled" : "disabled");
814 }
815
816 /* RATS: Assuming the fp string (which comes from the command-line argv
817 vector) is NULL-terminated, the buffer is large enough for the
818 strcpy. */
|
819 dawes 1.11 static void dmxSetDefaultFontPath(const char *fp)
|
820 martin 1.1 {
821 int fplen = strlen(fp) + 1;
822
823 if (dmxFontPath) {
824 int len;
825
826 len = strlen(dmxFontPath);
827 dmxFontPath = xrealloc(dmxFontPath, len+fplen+1);
828 dmxFontPath[len] = ',';
829 strncpy(&dmxFontPath[len+1], fp, fplen);
830 } else {
831 dmxFontPath = xalloc(fplen);
832 strncpy(dmxFontPath, fp, fplen);
833 }
834
835 defaultFontPath = dmxFontPath;
836 }
837
838 /** This function is called in Xserver/os/utils.c from \a AbortServer().
839 * We must ensure that backend and console state is restored in the
840 * event the server shutdown wasn't clean. */
841 martin 1.1 void AbortDDX(void)
842 {
843 int i;
844
845 for (i=0; i < dmxNumScreens; i++) {
846 DMXScreenInfo *dmxScreen = &dmxScreens[i];
847
848 if (dmxScreen->beDisplay) XCloseDisplay(dmxScreen->beDisplay);
849 dmxScreen->beDisplay = NULL;
850 }
851 }
852
853 /** This function is called in Xserver/dix/main.c from \a main() when
854 * dispatchException & DE_TERMINATE (which is the only way to exit the
855 * main loop without an interruption. */
856 void ddxGiveUp(void)
857 {
858 AbortDDX();
859 }
860
861 /** This function is called in Xserver/os/osinit.c from \a OsInit(). */
862 martin 1.1 void OsVendorPreInit(void)
863 {
864 }
865
866 /** This function is called in Xserver/os/osinit.c from \a OsInit(). */
867 void OsVendorInit(void)
868 {
869 }
870
871 /** This function is called in Xserver/os/utils.c from \a FatalError()
872 * and \a VFatalError(). (Note that setting the function pointer \a
873 * OsVendorVErrorFProc will cause \a VErrorF() (which is called by the
874 * two routines mentioned here, as well as by others) to use the
875 * referenced routine instead of \a vfprintf().) */
876 void OsVendorFatalError(void)
877 {
878 }
879
|
880 dawes 1.5 #if 0
|
881 martin 1.1 /** This funciton is called by InitGlobals from Xserver/os/utils.c to
882 * initialize any ddx specific globals at a very early point in the
883 * server startup. */
884 void ddxInitGlobals(void)
885 {
886 }
|
887 dawes 1.5 #endif
|
888 martin 1.1
889 /** Process our command line arguments. */
|
890 dawes 1.11 int ddxProcessArgument(int argc, const char *argv[], int i)
|
891 martin 1.1 {
892 int retval = 0;
893
894 if (!strcmp(argv[i], "-display")) {
895 if (++i < argc) dmxConfigStoreDisplay(argv[i]);
896 retval = 2;
897 } else if (!strcmp(argv[i], "-inputfrom") || !strcmp(argv[i], "-input")) {
898 if (++i < argc) dmxConfigStoreInput(argv[i]);
899 retval = 2;
900 } else if (!strcmp(argv[i], "-xinputfrom") || !strcmp(argv[i],"-xinput")) {
901 if (++i < argc) dmxConfigStoreXInput(argv[i]);
902 retval = 2;
903 } else if (!strcmp(argv[i], "-noshadowfb")) {
904 dmxLog(dmxWarning,
905 "-noshadowfb has been deprecated "
906 "since it is now the default\n");
907 dmxShadowFB = FALSE;
908 retval = 1;
909 } else if (!strcmp(argv[i], "-nomulticursor")) {
910 dmxCursorNoMulti();
911 retval = 1;
912 martin 1.1 } else if (!strcmp(argv[i], "-shadowfb")) {
913 dmxShadowFB = TRUE;
914 retval = 1;
915 } else if (!strcmp(argv[i], "-configfile")) {
916 if (++i < argc) dmxConfigStoreFile(argv[i]);
917 retval = 2;
918 } else if (!strcmp(argv[i], "-config")) {
919 if (++i < argc) dmxConfigStoreConfig(argv[i]);
920 retval = 2;
921 } else if (!strcmp(argv[i], "-fontpath")) {
922 if (++i < argc) dmxSetDefaultFontPath(argv[i]);
923 retval = 2;
924 } else if (!strcmp(argv[i], "-stat")) {
925 if ((i += 2) < argc) dmxStatActivate(argv[i-1], argv[i]);
926 retval = 3;
927 } else if (!strcmp(argv[i], "-syncbatch")) {
928 if (++i < argc) dmxSyncActivate(argv[i]);
929 retval = 2;
930 } else if (!strcmp(argv[i], "-nooffscreenopt")) {
931 dmxOffScreenOpt = FALSE;
932 retval = 1;
933 martin 1.1 } else if (!strcmp(argv[i], "-nosubdivprims")) {
934 dmxSubdividePrimitives = FALSE;
935 retval = 1;
936 } else if (!strcmp(argv[i], "-nowindowopt")) {
937 dmxLazyWindowCreation = FALSE;
938 retval = 1;
939 } else if (!strcmp(argv[i], "-noxkb")) {
940 dmxUseXKB = FALSE;
941 retval = 1;
942 } else if (!strcmp(argv[i], "-depth")) {
943 if (++i < argc) dmxDepth = atoi(argv[i]);
944 retval = 2;
945 } else if (!strcmp(argv[i], "-norender")) {
946 dmxNoRender = TRUE;
947 retval = 1;
|
948 tsi 1.4 #ifdef GLXPROXY
|
949 martin 1.1 } else if (!strcmp(argv[i], "-noglxproxy")) {
950 dmxGLXProxy = FALSE;
951 retval = 1;
952 } else if (!strcmp(argv[i], "-noglxswapgroup")) {
953 dmxGLXSwapGroupSupport = FALSE;
954 retval = 1;
955 } else if (!strcmp(argv[i], "-glxsyncswap")) {
956 dmxGLXSyncSwap = TRUE;
957 retval = 1;
958 } else if (!strcmp(argv[i], "-glxfinishswap")) {
959 dmxGLXFinishSwap = TRUE;
960 retval = 1;
961 #endif
962 } else if (!strcmp(argv[i], "-ignorebadfontpaths")) {
963 dmxIgnoreBadFontPaths = TRUE;
964 retval = 1;
965 } else if (!strcmp(argv[i], "-addremovescreens")) {
966 dmxAddRemoveScreens = TRUE;
967 retval = 1;
968 } else if (!strcmp(argv[i], "-param")) {
969 if ((i += 2) < argc) {
970 martin 1.1 if (!strcasecmp(argv[i-1], "xkbrules"))
971 dmxConfigSetXkbRules(argv[i]);
972 else if (!strcasecmp(argv[i-1], "xkbmodel"))
973 dmxConfigSetXkbModel(argv[i]);
974 else if (!strcasecmp(argv[i-1], "xkblayout"))
975 dmxConfigSetXkbLayout(argv[i]);
976 else if (!strcasecmp(argv[i-1], "xkbvariant"))
977 dmxConfigSetXkbVariant(argv[i]);
978 else if (!strcasecmp(argv[i-1], "xkboptions"))
979 dmxConfigSetXkbOptions(argv[i]);
980 else
981 dmxLog(dmxWarning,
982 "-param requires: XkbRules, XkbModel, XkbLayout,"
983 " XkbVariant, or XkbOptions\n");
984 }
985 retval = 3;
986 }
987 if (!serverGeneration) dmxConfigSetMaxScreens();
988 return retval;
989 }
990
991 martin 1.1 /** Provide succinct usage information for the DMX server. */
992 void ddxUseMsg(void)
993 {
994 ErrorF("\n\nDevice Dependent Usage:\n");
995 ErrorF("-display string Specify the back-end display(s)\n");
996 ErrorF("-input string Specify input source for core device\n");
997 ErrorF("-xinput string Specify input source for XInput device\n");
998 ErrorF("-shadowfb Enable shadow frame buffer\n");
999 ErrorF("-configfile file Read from a configuration file\n");
1000 ErrorF("-config config Select a specific configuration\n");
1001 ErrorF("-nomulticursor Turn of multiple cursor support\n");
1002 ErrorF("-fontpath Sets the default font path\n");
1003 ErrorF("-stat inter scrns Print out performance statistics\n");
1004 ErrorF("-syncbatch inter Set interval for XSync batching\n");
1005 ErrorF("-nooffscreenopt Disable offscreen optimization\n");
1006 ErrorF("-nosubdivprims Disable primitive subdivision\n");
1007 ErrorF(" optimization\n");
1008 ErrorF("-nowindowopt Disable lazy window creation optimization\n");
1009 ErrorF("-noxkb Disable use of the XKB extension with\n");
1010 ErrorF(" backend displays (cf. -kb).\n");
1011 ErrorF("-depth Specify the default root window depth\n");
1012 martin 1.1 ErrorF("-norender Disable RENDER extension support\n");
|
1013 tsi 1.4 #ifdef GLXPROXY
|
1014 martin 1.1 ErrorF("-noglxproxy Disable GLX Proxy\n");
1015 ErrorF("-noglxswapgroup Disable swap group and swap barrier\n");
1016 ErrorF(" extensions in GLX proxy\n");
1017 ErrorF("-glxsyncswap Force XSync after swap buffers\n");
1018 ErrorF("-glxfinishswap Force glFinish after swap buffers\n");
1019 #endif
1020 ErrorF("-ignorebadfontpaths Ignore bad font paths during initialization\n");
1021 ErrorF("-addremovescreens Enable dynamic screen addition/removal\n");
1022 ErrorF("-param ... Specify configuration parameters (e.g.,\n");
1023 ErrorF(" XkbRules, XkbModel, XkbLayout, etc.)\n");
1024 ErrorF("\n");
1025 ErrorF(" If the -input string matches a -display string, then input\n"
1026 " is taken from that backend display. (XInput cannot be taken\n"
1027 " from a backend display.) Placing \",console\" after the\n"
1028 " display name will force a console window to be opened on\n"
1029 " that display in addition to the backend input. This is\n"
1030 " useful if the backend window does not cover the whole\n"
1031 " physical display.\n\n");
1032
1033 ErrorF(" Otherwise, if the -input or -xinput string specifies another\n"
1034 " X display, then a console window will be created on that\n"
1035 martin 1.1 " display. Placing \",windows\" or \",nowindows\" after the\n"
1036 " display name will control the display of window outlines in\n"
1037 " the console.\n\n");
1038
1039 ErrorF(" -input or -xinput dummy specifies no input.\n");
1040 ErrorF(" -input or -xinput local specifies the use of a raw keyboard,\n"
1041 " mouse, or other (extension) device:\n"
1042 " -input local,kbd,ps2 will use a ps2 mouse\n"
1043 " -input local,kbd,ms will use a serial mouse\n"
1044 " -input local,usb-kbd,usb-mou will use USB devices \n"
1045 " -xinput local,usb-oth will use a non-mouse and\n"
1046 " non-keyboard USB device with XInput\n\n");
1047
1048 ErrorF(" Special Keys:\n");
1049 ErrorF(" Ctrl-Alt-g Server grab/ungrab (console only)\n");
1050 ErrorF(" Ctrl-Alt-f Fine (1-pixel) mouse mode (console only)\n");
1051 ErrorF(" Ctrl-Alt-q Quit (core devices only)\n");
1052 ErrorF(" Ctrl-Alt-F* Switch to VC (local only)\n");
1053 }
1054
1055 #ifdef DDXTIME
1056 martin 1.1 /** Return wall-clock time in milliseconds. */
1057 CARD32 GetTimeInMillis(void)
1058 {
1059 struct timeval tp;
1060
1061 gettimeofday(&tp, 0);
1062 return tp.tv_sec * 1000 + tp.tv_usec / 1000;
1063 }
1064 #endif
|
1065 dawes 1.6
1066 #ifdef __DARWIN__
1067 void
|
1068 tsi 1.13 DarwinHandleGUI(int argc, const char *argv[], char *envp[])
|
1069 dawes 1.6 {
1070 }
1071 #endif
|