Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xnest / Screen.c
CommitLineData
a09e091a
JB
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 <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
45Window xnestDefaultWindows[MAXSCREENS];
46Window xnestScreenSaverWindows[MAXSCREENS];
47DevPrivateKeyRec xnestCursorScreenKeyRec;
48
49ScreenPtr
50xnestScreen(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
61static int
62offset(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
72static Bool
73xnestSaveScreen(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
104static Bool
105xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
106{
107 return FALSE;
108}
109
110static void
111xnestCrossScreen(ScreenPtr pScreen, Bool entering)
112{
113}
114
115static miPointerScreenFuncRec xnestPointerCursorFuncs = {
116 xnestCursorOffScreen,
117 xnestCrossScreen,
118 miPointerWarpCursor
119};
120
121static miPointerSpriteFuncRec xnestPointerSpriteFuncs = {
122 xnestRealizeCursor,
123 xnestUnrealizeCursor,
124 xnestSetCursor,
125 xnestMoveCursor,
126 xnestDeviceCursorInitialize,
127 xnestDeviceCursorCleanup
128};
129
130Bool
131xnestOpenScreen(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
409Bool
410xnestCloseScreen(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}