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