Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xnest / Screen.c
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
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
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
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
105 xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
106 {
107 return FALSE;
108 }
109
110 static void
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
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 = (VisualPtr) malloc(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 = (VisualPtr) realloc(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 /* PixmapPerDepth */
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 pScreen->SourceValidate = NULL;
267
268 /* Window Procedures */
269
270 pScreen->CreateWindow = xnestCreateWindow;
271 pScreen->DestroyWindow = xnestDestroyWindow;
272 pScreen->PositionWindow = xnestPositionWindow;
273 pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes;
274 pScreen->RealizeWindow = xnestRealizeWindow;
275 pScreen->UnrealizeWindow = xnestUnrealizeWindow;
276 pScreen->PostValidateTree = NULL;
277 pScreen->WindowExposures = xnestWindowExposures;
278 pScreen->CopyWindow = xnestCopyWindow;
279 pScreen->ClipNotify = xnestClipNotify;
280
281 /* Pixmap procedures */
282
283 pScreen->CreatePixmap = xnestCreatePixmap;
284 pScreen->DestroyPixmap = xnestDestroyPixmap;
285 pScreen->ModifyPixmapHeader = xnestModifyPixmapHeader;
286
287 /* Font procedures */
288
289 pScreen->RealizeFont = xnestRealizeFont;
290 pScreen->UnrealizeFont = xnestUnrealizeFont;
291
292 /* GC procedures */
293
294 pScreen->CreateGC = xnestCreateGC;
295
296 /* Colormap procedures */
297
298 pScreen->CreateColormap = xnestCreateColormap;
299 pScreen->DestroyColormap = xnestDestroyColormap;
300 pScreen->InstallColormap = xnestInstallColormap;
301 pScreen->UninstallColormap = xnestUninstallColormap;
302 pScreen->ListInstalledColormaps = xnestListInstalledColormaps;
303 pScreen->StoreColors = xnestStoreColors;
304 pScreen->ResolveColor = xnestResolveColor;
305
306 pScreen->BitmapToRegion = xnestPixmapToRegion;
307
308 /* OS layer procedures */
309
310 pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
311 pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
312
313 miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */
314 PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
315 xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs;
316 dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey,
317 &xnestCursorFuncs);
318 PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
319
320 pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
321 DefaultScreen(xnestDisplay))
322 / DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay));
323 pScreen->mmHeight =
324 xnestHeight * DisplayHeightMM(xnestDisplay,
325 DefaultScreen(xnestDisplay)) /
326 DisplayHeight(xnestDisplay, DefaultScreen(xnestDisplay));
327
328 /* overwrite miCloseScreen with our own */
329 pScreen->CloseScreen = xnestCloseScreen;
330
331 if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL))
332 return FALSE;
333
334 /* overwrite miSetShape with our own */
335 pScreen->SetShape = xnestSetShape;
336
337 /* devPrivates */
338
339 #define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
340
341 if (xnestDoFullGeneration) {
342
343 valuemask = CWBackPixel | CWEventMask | CWColormap;
344 attributes.background_pixel = xnestWhitePixel;
345 attributes.event_mask = xnestEventMask;
346 attributes.colormap =
347 xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
348
349 if (xnestParentWindow != 0) {
350 xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
351 XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
352 xnestEventMask);
353 }
354 else
355 xnestDefaultWindows[pScreen->myNum] =
356 XCreateWindow(xnestDisplay,
357 DefaultRootWindow(xnestDisplay),
358 xnestX + POSITION_OFFSET,
359 xnestY + POSITION_OFFSET,
360 xnestWidth, xnestHeight,
361 xnestBorderWidth,
362 pScreen->rootDepth,
363 InputOutput,
364 xnestDefaultVisual(pScreen),
365 valuemask, &attributes);
366
367 if (!xnestWindowName)
368 xnestWindowName = argv[0];
369
370 sizeHints.flags = PPosition | PSize | PMaxSize;
371 sizeHints.x = xnestX + POSITION_OFFSET;
372 sizeHints.y = xnestY + POSITION_OFFSET;
373 sizeHints.width = sizeHints.max_width = xnestWidth;
374 sizeHints.height = sizeHints.max_height = xnestHeight;
375 if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
376 sizeHints.flags |= USPosition;
377 if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
378 sizeHints.flags |= USSize;
379 XSetStandardProperties(xnestDisplay,
380 xnestDefaultWindows[pScreen->myNum],
381 xnestWindowName,
382 xnestWindowName,
383 xnestIconBitmap, argv, argc, &sizeHints);
384
385 XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
386
387 valuemask = CWBackPixmap | CWColormap;
388 attributes.background_pixmap = xnestScreenSaverPixmap;
389 attributes.colormap =
390 DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
391 xnestScreenSaverWindows[pScreen->myNum] =
392 XCreateWindow(xnestDisplay,
393 xnestDefaultWindows[pScreen->myNum],
394 0, 0, xnestWidth, xnestHeight, 0,
395 DefaultDepth(xnestDisplay,
396 DefaultScreen(xnestDisplay)),
397 InputOutput, DefaultVisual(xnestDisplay,
398 DefaultScreen
399 (xnestDisplay)), valuemask,
400 &attributes);
401 }
402
403 if (!xnestCreateDefaultColormap(pScreen))
404 return False;
405
406 return True;
407 }
408
409 Bool
410 xnestCloseScreen(ScreenPtr pScreen)
411 {
412 int i;
413
414 for (i = 0; i < pScreen->numDepths; i++)
415 free(pScreen->allowedDepths[i].vids);
416 free(pScreen->allowedDepths);
417 free(pScreen->visuals);
418 free(pScreen->devPrivate);
419
420 /*
421 If xnestDoFullGeneration all x resources will be destroyed upon closing
422 the display connection. There is no need to generate extra protocol.
423 */
424
425 return True;
426 }