1 /*
2 
3 Copyright 1993 by Davor Matic
4 
5 Permission to use, copy, modify, distribute, and sell this software
6 and its documentation for any purpose is hereby granted without fee,
7 provided that the above copyright notice appear in all copies and that
8 both that copyright notice and this permission notice appear in
9 supporting documentation.  Davor Matic makes no representations about
10 the suitability of this software for any purpose.  It is provided "as
11 is" without express or implied warranty.
12 
13 */
14 
15 #ifdef HAVE_XNEST_CONFIG_H
16 #include <xnest-config.h>
17 #endif
18 
19 #include <string.h>
20 #include <errno.h>
21 
22 #include <X11/X.h>
23 #include <X11/Xproto.h>
24 #include "screenint.h"
25 #include "input.h"
26 #include "misc.h"
27 #include "scrnintstr.h"
28 #include "servermd.h"
29 
30 #include "Xnest.h"
31 
32 #include "Display.h"
33 #include "Init.h"
34 #include "Args.h"
35 
36 #include "icon"
37 #include "screensaver"
38 
39 Display *xnestDisplay = NULL;
40 XVisualInfo *xnestVisuals;
41 int xnestNumVisuals;
42 int xnestDefaultVisualIndex;
43 Colormap *xnestDefaultColormaps;
44 static int xnestNumDefaultColormaps;
45 int *xnestDepths;
46 int xnestNumDepths;
47 XPixmapFormatValues *xnestPixmapFormats;
48 int xnestNumPixmapFormats;
49 Pixel xnestBlackPixel;
50 Pixel xnestWhitePixel;
51 Drawable xnestDefaultDrawables[MAXDEPTH + 1];
52 Pixmap xnestIconBitmap;
53 Pixmap xnestScreenSaverPixmap;
54 XlibGC xnestBitmapGC;
55 unsigned long xnestEventMask;
56 
57 #ifdef __SUNPRO_C
58 /* prevent "Function has no return statement" error for x_io_error_handler */
59 #pragma does_not_return(exit)
60 #endif
61 
62 static int _X_NORETURN
x_io_error_handler(Display * dpy)63 x_io_error_handler(Display * dpy)
64 {
65     ErrorF("Lost connection to X server: %s\n", strerror(errno));
66     CloseWellKnownConnections();
67     OsCleanup(1);
68     exit(1);
69 }
70 
71 void
xnestOpenDisplay(int argc,char * argv[])72 xnestOpenDisplay(int argc, char *argv[])
73 {
74     XVisualInfo vi;
75     long mask;
76     int i, j;
77 
78     if (!xnestDoFullGeneration)
79         return;
80 
81     XSetIOErrorHandler(x_io_error_handler);
82 
83     xnestCloseDisplay();
84 
85     xnestDisplay = XOpenDisplay(xnestDisplayName);
86     if (xnestDisplay == NULL)
87         FatalError("Unable to open display \"%s\".\n",
88                    XDisplayName(xnestDisplayName));
89 
90     if (xnestSynchronize)
91         XSynchronize(xnestDisplay, True);
92 
93     mask = VisualScreenMask;
94     vi.screen = DefaultScreen(xnestDisplay);
95     xnestVisuals = XGetVisualInfo(xnestDisplay, mask, &vi, &xnestNumVisuals);
96     if (xnestNumVisuals == 0 || xnestVisuals == NULL)
97         FatalError("Unable to find any visuals.\n");
98 
99     if (xnestUserDefaultClass || xnestUserDefaultDepth) {
100         xnestDefaultVisualIndex = UNDEFINED;
101         for (i = 0; i < xnestNumVisuals; i++)
102             if ((!xnestUserDefaultClass ||
103                  xnestVisuals[i].class == xnestDefaultClass)
104                 &&
105                 (!xnestUserDefaultDepth ||
106                  xnestVisuals[i].depth == xnestDefaultDepth)) {
107                 xnestDefaultVisualIndex = i;
108                 break;
109             }
110         if (xnestDefaultVisualIndex == UNDEFINED)
111             FatalError("Unable to find desired default visual.\n");
112     }
113     else {
114         vi.visualid = XVisualIDFromVisual(DefaultVisual(xnestDisplay,
115                                                         DefaultScreen
116                                                         (xnestDisplay)));
117         xnestDefaultVisualIndex = 0;
118         for (i = 0; i < xnestNumVisuals; i++)
119             if (vi.visualid == xnestVisuals[i].visualid)
120                 xnestDefaultVisualIndex = i;
121     }
122 
123     xnestNumDefaultColormaps = xnestNumVisuals;
124     xnestDefaultColormaps = xallocarray(xnestNumDefaultColormaps,
125                                         sizeof(Colormap));
126     for (i = 0; i < xnestNumDefaultColormaps; i++)
127         xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay,
128                                                    DefaultRootWindow
129                                                    (xnestDisplay),
130                                                    xnestVisuals[i].visual,
131                                                    AllocNone);
132 
133     xnestDepths = XListDepths(xnestDisplay, DefaultScreen(xnestDisplay),
134                               &xnestNumDepths);
135 
136     xnestPixmapFormats = XListPixmapFormats(xnestDisplay,
137                                             &xnestNumPixmapFormats);
138 
139     xnestBlackPixel = BlackPixel(xnestDisplay, DefaultScreen(xnestDisplay));
140     xnestWhitePixel = WhitePixel(xnestDisplay, DefaultScreen(xnestDisplay));
141 
142     if (xnestParentWindow != (Window) 0)
143         xnestEventMask = StructureNotifyMask;
144     else
145         xnestEventMask = 0L;
146 
147     for (i = 0; i <= MAXDEPTH; i++)
148         xnestDefaultDrawables[i] = None;
149 
150     for (i = 0; i < xnestNumPixmapFormats; i++)
151         for (j = 0; j < xnestNumDepths; j++)
152             if (xnestPixmapFormats[i].depth == 1 ||
153                 xnestPixmapFormats[i].depth == xnestDepths[j]) {
154                 xnestDefaultDrawables[xnestPixmapFormats[i].depth] =
155                     XCreatePixmap(xnestDisplay, DefaultRootWindow(xnestDisplay),
156                                   1, 1, xnestPixmapFormats[i].depth);
157             }
158 
159     xnestBitmapGC = XCreateGC(xnestDisplay, xnestDefaultDrawables[1], 0L, NULL);
160 
161     if (!(xnestUserGeometry & XValue))
162         xnestX = 0;
163 
164     if (!(xnestUserGeometry & YValue))
165         xnestY = 0;
166 
167     if (xnestParentWindow == 0) {
168         if (!(xnestUserGeometry & WidthValue))
169             xnestWidth = 3 * DisplayWidth(xnestDisplay,
170                                           DefaultScreen(xnestDisplay)) / 4;
171 
172         if (!(xnestUserGeometry & HeightValue))
173             xnestHeight = 3 * DisplayHeight(xnestDisplay,
174                                             DefaultScreen(xnestDisplay)) / 4;
175     }
176 
177     if (!xnestUserBorderWidth)
178         xnestBorderWidth = 1;
179 
180     xnestIconBitmap =
181         XCreateBitmapFromData(xnestDisplay,
182                               DefaultRootWindow(xnestDisplay),
183                               (char *) icon_bits, icon_width, icon_height);
184 
185     xnestScreenSaverPixmap =
186         XCreatePixmapFromBitmapData(xnestDisplay,
187                                     DefaultRootWindow(xnestDisplay),
188                                     (char *) screensaver_bits,
189                                     screensaver_width,
190                                     screensaver_height,
191                                     xnestWhitePixel,
192                                     xnestBlackPixel,
193                                     DefaultDepth(xnestDisplay,
194                                                  DefaultScreen(xnestDisplay)));
195 }
196 
197 void
xnestCloseDisplay(void)198 xnestCloseDisplay(void)
199 {
200     if (!xnestDoFullGeneration || !xnestDisplay)
201         return;
202 
203     /*
204        If xnestDoFullGeneration all x resources will be destroyed upon closing
205        the display connection.  There is no need to generate extra protocol.
206      */
207 
208     free(xnestDefaultColormaps);
209     XFree(xnestVisuals);
210     XFree(xnestDepths);
211     XFree(xnestPixmapFormats);
212     XCloseDisplay(xnestDisplay);
213 }
214