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