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 <X11/X.h>
20 #include <X11/Xproto.h>
21 #include "scrnintstr.h"
22 #include "dix.h"
23 #include "mi.h"
24 #include "micmap.h"
25 #include "colormapst.h"
26 #include "resource.h"
27
28 #include "Xnest.h"
29
30 #include "Display.h"
31 #include "Screen.h"
32 #include "XNGC.h"
33 #include "GCOps.h"
34 #include "Drawable.h"
35 #include "XNFont.h"
36 #include "Color.h"
37 #include "XNCursor.h"
38 #include "Visual.h"
39 #include "Events.h"
40 #include "Init.h"
41 #include "mipointer.h"
42 #include "Args.h"
43 #include "mipointrst.h"
44
45 Window xnestDefaultWindows[MAXSCREENS];
46 Window xnestScreenSaverWindows[MAXSCREENS];
47 DevPrivateKeyRec xnestCursorScreenKeyRec;
48
49 ScreenPtr
xnestScreen(Window window)50 xnestScreen(Window window)
51 {
52 int i;
53
54 for (i = 0; i < xnestNumScreens; i++)
55 if (xnestDefaultWindows[i] == window)
56 return screenInfo.screens[i];
57
58 return NULL;
59 }
60
61 static int
offset(unsigned long mask)62 offset(unsigned long mask)
63 {
64 int count;
65
66 for (count = 0; !(mask & 1) && count < 32; count++)
67 mask >>= 1;
68
69 return count;
70 }
71
72 static Bool
xnestSaveScreen(ScreenPtr pScreen,int what)73 xnestSaveScreen(ScreenPtr pScreen, int what)
74 {
75 if (xnestSoftwareScreenSaver)
76 return False;
77 else {
78 switch (what) {
79 case SCREEN_SAVER_ON:
80 XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
81 xnestSetScreenSaverColormapWindow(pScreen);
82 break;
83
84 case SCREEN_SAVER_OFF:
85 XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
86 xnestSetInstalledColormapWindows(pScreen);
87 break;
88
89 case SCREEN_SAVER_FORCER:
90 lastEventTime = GetTimeInMillis();
91 XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
92 xnestSetInstalledColormapWindows(pScreen);
93 break;
94
95 case SCREEN_SAVER_CYCLE:
96 XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
97 xnestSetInstalledColormapWindows(pScreen);
98 break;
99 }
100 return True;
101 }
102 }
103
104 static Bool
xnestCursorOffScreen(ScreenPtr * ppScreen,int * x,int * y)105 xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
106 {
107 return FALSE;
108 }
109
110 static void
xnestCrossScreen(ScreenPtr pScreen,Bool entering)111 xnestCrossScreen(ScreenPtr pScreen, Bool entering)
112 {
113 }
114
115 static miPointerScreenFuncRec xnestPointerCursorFuncs = {
116 xnestCursorOffScreen,
117 xnestCrossScreen,
118 miPointerWarpCursor
119 };
120
121 static miPointerSpriteFuncRec xnestPointerSpriteFuncs = {
122 xnestRealizeCursor,
123 xnestUnrealizeCursor,
124 xnestSetCursor,
125 xnestMoveCursor,
126 xnestDeviceCursorInitialize,
127 xnestDeviceCursorCleanup
128 };
129
130 Bool
xnestOpenScreen(ScreenPtr pScreen,int argc,char * argv[])131 xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
132 {
133 VisualPtr visuals;
134 DepthPtr depths;
135 int numVisuals, numDepths;
136 int i, j, depthIndex;
137 unsigned long valuemask;
138 XSetWindowAttributes attributes;
139 XWindowAttributes gattributes;
140 XSizeHints sizeHints;
141 VisualID defaultVisual;
142 int rootDepth;
143 miPointerScreenPtr PointPriv;
144
145 if (!dixRegisterPrivateKey
146 (&xnestWindowPrivateKeyRec, PRIVATE_WINDOW, sizeof(xnestPrivWin)))
147 return FALSE;
148 if (!dixRegisterPrivateKey
149 (&xnestGCPrivateKeyRec, PRIVATE_GC, sizeof(xnestPrivGC)))
150 return FALSE;
151 if (!dixRegisterPrivateKey
152 (&xnestPixmapPrivateKeyRec, PRIVATE_PIXMAP, sizeof(xnestPrivPixmap)))
153 return FALSE;
154 if (!dixRegisterPrivateKey
155 (&xnestColormapPrivateKeyRec, PRIVATE_COLORMAP,
156 sizeof(xnestPrivColormap)))
157 return FALSE;
158 if (!dixRegisterPrivateKey(&xnestCursorScreenKeyRec, PRIVATE_SCREEN, 0))
159 return FALSE;
160
161 visuals = xallocarray(xnestNumVisuals, sizeof(VisualRec));
162 numVisuals = 0;
163
164 depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
165 depths[0].depth = 1;
166 depths[0].numVids = 0;
167 depths[0].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
168 numDepths = 1;
169
170 for (i = 0; i < xnestNumVisuals; i++) {
171 visuals[numVisuals].class = xnestVisuals[i].class;
172 visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
173 visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
174 visuals[numVisuals].nplanes = xnestVisuals[i].depth;
175 visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
176 visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
177 visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
178 visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
179 visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
180 visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
181
182 /* Check for and remove duplicates. */
183 for (j = 0; j < numVisuals; j++) {
184 if (visuals[numVisuals].class == visuals[j].class &&
185 visuals[numVisuals].bitsPerRGBValue ==
186 visuals[j].bitsPerRGBValue &&
187 visuals[numVisuals].ColormapEntries ==
188 visuals[j].ColormapEntries &&
189 visuals[numVisuals].nplanes == visuals[j].nplanes &&
190 visuals[numVisuals].redMask == visuals[j].redMask &&
191 visuals[numVisuals].greenMask == visuals[j].greenMask &&
192 visuals[numVisuals].blueMask == visuals[j].blueMask &&
193 visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
194 visuals[numVisuals].offsetGreen == visuals[j].offsetGreen &&
195 visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
196 break;
197 }
198 if (j < numVisuals)
199 break;
200
201 visuals[numVisuals].vid = FakeClientID(0);
202
203 depthIndex = UNDEFINED;
204 for (j = 0; j < numDepths; j++)
205 if (depths[j].depth == xnestVisuals[i].depth) {
206 depthIndex = j;
207 break;
208 }
209
210 if (depthIndex == UNDEFINED) {
211 depthIndex = numDepths;
212 depths[depthIndex].depth = xnestVisuals[i].depth;
213 depths[depthIndex].numVids = 0;
214 depths[depthIndex].vids =
215 (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
216 numDepths++;
217 }
218 if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
219 FatalError("Visual table overflow");
220 }
221 depths[depthIndex].vids[depths[depthIndex].numVids] =
222 visuals[numVisuals].vid;
223 depths[depthIndex].numVids++;
224
225 numVisuals++;
226 }
227 visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
228
229 defaultVisual = visuals[xnestDefaultVisualIndex].vid;
230 rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
231
232 if (xnestParentWindow != 0) {
233 XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
234 xnestWidth = gattributes.width;
235 xnestHeight = gattributes.height;
236 }
237
238 /* myNum */
239 /* id */
240 miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth, rootDepth, numDepths, depths, defaultVisual, /* root visual */
241 numVisuals, visuals);
242
243 pScreen->defColormap = (Colormap) FakeClientID(0);
244 pScreen->minInstalledCmaps = MINCMAPS;
245 pScreen->maxInstalledCmaps = MAXCMAPS;
246 pScreen->backingStoreSupport = NotUseful;
247 pScreen->saveUnderSupport = NotUseful;
248 pScreen->whitePixel = xnestWhitePixel;
249 pScreen->blackPixel = xnestBlackPixel;
250 /* GCperDepth */
251 /* defaultStipple */
252 pScreen->devPrivate = NULL;
253 /* WindowPrivateLen */
254 /* WindowPrivateSizes */
255 /* totalWindowSize */
256 /* GCPrivateLen */
257 /* GCPrivateSizes */
258 /* totalGCSize */
259
260 /* Random screen procedures */
261
262 pScreen->QueryBestSize = xnestQueryBestSize;
263 pScreen->SaveScreen = xnestSaveScreen;
264 pScreen->GetImage = xnestGetImage;
265 pScreen->GetSpans = xnestGetSpans;
266
267 /* Window Procedures */
268
269 pScreen->CreateWindow = xnestCreateWindow;
270 pScreen->DestroyWindow = xnestDestroyWindow;
271 pScreen->PositionWindow = xnestPositionWindow;
272 pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes;
273 pScreen->RealizeWindow = xnestRealizeWindow;
274 pScreen->UnrealizeWindow = xnestUnrealizeWindow;
275 pScreen->PostValidateTree = NULL;
276 pScreen->WindowExposures = xnestWindowExposures;
277 pScreen->CopyWindow = xnestCopyWindow;
278 pScreen->ClipNotify = xnestClipNotify;
279
280 /* Pixmap procedures */
281
282 pScreen->CreatePixmap = xnestCreatePixmap;
283 pScreen->DestroyPixmap = xnestDestroyPixmap;
284 pScreen->ModifyPixmapHeader = xnestModifyPixmapHeader;
285
286 /* Font procedures */
287
288 pScreen->RealizeFont = xnestRealizeFont;
289 pScreen->UnrealizeFont = xnestUnrealizeFont;
290
291 /* GC procedures */
292
293 pScreen->CreateGC = xnestCreateGC;
294
295 /* Colormap procedures */
296
297 pScreen->CreateColormap = xnestCreateColormap;
298 pScreen->DestroyColormap = xnestDestroyColormap;
299 pScreen->InstallColormap = xnestInstallColormap;
300 pScreen->UninstallColormap = xnestUninstallColormap;
301 pScreen->ListInstalledColormaps = xnestListInstalledColormaps;
302 pScreen->StoreColors = xnestStoreColors;
303 pScreen->ResolveColor = xnestResolveColor;
304
305 pScreen->BitmapToRegion = xnestPixmapToRegion;
306
307 /* OS layer procedures */
308
309 pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
310 pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
311
312 miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */
313 PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
314 xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs;
315 dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey,
316 &xnestCursorFuncs);
317 PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
318
319 pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
320 DefaultScreen(xnestDisplay))
321 / DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay));
322 pScreen->mmHeight =
323 xnestHeight * DisplayHeightMM(xnestDisplay,
324 DefaultScreen(xnestDisplay)) /
325 DisplayHeight(xnestDisplay, DefaultScreen(xnestDisplay));
326
327 /* overwrite miCloseScreen with our own */
328 pScreen->CloseScreen = xnestCloseScreen;
329
330 if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL))
331 return FALSE;
332
333 /* overwrite miSetShape with our own */
334 pScreen->SetShape = xnestSetShape;
335
336 /* devPrivates */
337
338 #define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
339
340 if (xnestDoFullGeneration) {
341
342 valuemask = CWBackPixel | CWEventMask | CWColormap;
343 attributes.background_pixel = xnestWhitePixel;
344 attributes.event_mask = xnestEventMask;
345 attributes.colormap =
346 xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
347
348 if (xnestParentWindow != 0) {
349 xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
350 XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
351 xnestEventMask);
352 }
353 else
354 xnestDefaultWindows[pScreen->myNum] =
355 XCreateWindow(xnestDisplay,
356 DefaultRootWindow(xnestDisplay),
357 xnestX + POSITION_OFFSET,
358 xnestY + POSITION_OFFSET,
359 xnestWidth, xnestHeight,
360 xnestBorderWidth,
361 pScreen->rootDepth,
362 InputOutput,
363 xnestDefaultVisual(pScreen),
364 valuemask, &attributes);
365
366 if (!xnestWindowName)
367 xnestWindowName = argv[0];
368
369 sizeHints.flags = PPosition | PSize | PMaxSize;
370 sizeHints.x = xnestX + POSITION_OFFSET;
371 sizeHints.y = xnestY + POSITION_OFFSET;
372 sizeHints.width = sizeHints.max_width = xnestWidth;
373 sizeHints.height = sizeHints.max_height = xnestHeight;
374 if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
375 sizeHints.flags |= USPosition;
376 if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
377 sizeHints.flags |= USSize;
378 XSetStandardProperties(xnestDisplay,
379 xnestDefaultWindows[pScreen->myNum],
380 xnestWindowName,
381 xnestWindowName,
382 xnestIconBitmap, argv, argc, &sizeHints);
383
384 XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
385
386 valuemask = CWBackPixmap | CWColormap;
387 attributes.background_pixmap = xnestScreenSaverPixmap;
388 attributes.colormap =
389 DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
390 xnestScreenSaverWindows[pScreen->myNum] =
391 XCreateWindow(xnestDisplay,
392 xnestDefaultWindows[pScreen->myNum],
393 0, 0, xnestWidth, xnestHeight, 0,
394 DefaultDepth(xnestDisplay,
395 DefaultScreen(xnestDisplay)),
396 InputOutput, DefaultVisual(xnestDisplay,
397 DefaultScreen
398 (xnestDisplay)), valuemask,
399 &attributes);
400 }
401
402 if (!xnestCreateDefaultColormap(pScreen))
403 return False;
404
405 return True;
406 }
407
408 Bool
xnestCloseScreen(ScreenPtr pScreen)409 xnestCloseScreen(ScreenPtr pScreen)
410 {
411 int i;
412
413 for (i = 0; i < pScreen->numDepths; i++)
414 free(pScreen->allowedDepths[i].vids);
415 free(pScreen->allowedDepths);
416 free(pScreen->visuals);
417 free(pScreen->devPrivate);
418
419 /*
420 If xnestDoFullGeneration all x resources will be destroyed upon closing
421 the display connection. There is no need to generate extra protocol.
422 */
423
424 return True;
425 }
426