Screen.c revision 35c4bbdf
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 = 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    /* 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}
427