1/*
2
3Copyright 1993 by Davor Matic
4
5Permission to use, copy, modify, distribute, and sell this software
6and its documentation for any purpose is hereby granted without fee,
7provided that the above copyright notice appear in all copies and that
8both that copyright notice and this permission notice appear in
9supporting documentation.  Davor Matic makes no representations about
10the suitability of this software for any purpose.  It is provided "as
11is" 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
39Display *xnestDisplay = NULL;
40XVisualInfo *xnestVisuals;
41int xnestNumVisuals;
42int xnestDefaultVisualIndex;
43Colormap *xnestDefaultColormaps;
44static unsigned int xnestNumDefaultColormaps;
45int *xnestDepths;
46int xnestNumDepths;
47XPixmapFormatValues *xnestPixmapFormats;
48int xnestNumPixmapFormats;
49Pixel xnestBlackPixel;
50Pixel xnestWhitePixel;
51Drawable xnestDefaultDrawables[MAXDEPTH + 1];
52Pixmap xnestIconBitmap;
53Pixmap xnestScreenSaverPixmap;
54XlibGC xnestBitmapGC;
55unsigned 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
62static int _X_NORETURN
63x_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
71void
72xnestOpenDisplay(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
197void
198xnestCloseDisplay(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