Commit | Line | Data |
---|---|---|
a09e091a JB |
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 | } |