Screen.c revision 4642e01f
11.1.1.3Sjmcneill/*
21.1Sjmcneill
31.1SjmcneillCopyright 1993 by Davor Matic
41.1Sjmcneill
51.1.1.2SjmcneillPermission to use, copy, modify, distribute, and sell this software
61.1Sjmcneilland its documentation for any purpose is hereby granted without fee,
71.1Sjmcneillprovided that the above copyright notice appear in all copies and that
81.1Sjmcneillboth that copyright notice and this permission notice appear in
91.1Sjmcneillsupporting documentation.  Davor Matic makes no representations about
101.1Sjmcneillthe suitability of this software for any purpose.  It is provided "as
111.1Sjmcneillis" without express or implied warranty.
121.1Sjmcneill
131.1Sjmcneill*/
141.1Sjmcneill
151.1Sjmcneill#ifdef HAVE_XNEST_CONFIG_H
161.1Sjmcneill#include <xnest-config.h>
171.1Sjmcneill#endif
181.1Sjmcneill
191.1Sjmcneill#include <X11/X.h>
201.1Sjmcneill#include <X11/Xproto.h>
211.1Sjmcneill#include "scrnintstr.h"
221.1Sjmcneill#include "dix.h"
231.1Sjmcneill#include "mi.h"
241.1Sjmcneill#include "mibstore.h"
251.1Sjmcneill#include "micmap.h"
261.1Sjmcneill#include "colormapst.h"
271.1Sjmcneill#include "resource.h"
281.1Sjmcneill
291.1Sjmcneill#include "Xnest.h"
301.1Sjmcneill
311.1Sjmcneill#include "Display.h"
321.1Sjmcneill#include "Screen.h"
331.1Sjmcneill#include "XNGC.h"
341.1Sjmcneill#include "GCOps.h"
351.1Sjmcneill#include "Drawable.h"
361.1Sjmcneill#include "XNFont.h"
371.1Sjmcneill#include "Color.h"
381.1Sjmcneill#include "XNCursor.h"
391.1.1.2Sjmcneill#include "Visual.h"
401.1.1.2Sjmcneill#include "Events.h"
411.1.1.2Sjmcneill#include "Init.h"
421.1.1.2Sjmcneill#include "mipointer.h"
431.1.1.2Sjmcneill#include "Args.h"
441.1.1.2Sjmcneill#include "mipointrst.h"
451.1.1.2Sjmcneill
461.1.1.2SjmcneillWindow xnestDefaultWindows[MAXSCREENS];
471.1.1.2SjmcneillWindow xnestScreenSaverWindows[MAXSCREENS];
481.1.1.2Sjmcneillstatic int xnestCursorScreenKeyIndex;
491.1.1.2SjmcneillDevPrivateKey xnestCursorScreenKey = &xnestCursorScreenKeyIndex;
501.1.1.2Sjmcneill
511.1.1.2SjmcneillScreenPtr
521.1.1.2SjmcneillxnestScreen(Window window)
531.1.1.2Sjmcneill{
541.1.1.2Sjmcneill  int i;
551.1.1.2Sjmcneill
561.1Sjmcneill  for (i = 0; i < xnestNumScreens; i++)
571.1.1.2Sjmcneill    if (xnestDefaultWindows[i] == window)
581.1.1.2Sjmcneill      return screenInfo.screens[i];
591.1.1.2Sjmcneill
601.1Sjmcneill  return NULL;
611.1Sjmcneill}
621.1Sjmcneill
631.1Sjmcneillstatic int
641.1.1.2Sjmcneilloffset(unsigned long mask)
651.1.1.2Sjmcneill{
661.1.1.2Sjmcneill  int count;
671.1Sjmcneill
681.1Sjmcneill  for (count = 0; !(mask & 1) && count < 32; count++)
691.1Sjmcneill    mask >>= 1;
701.1Sjmcneill
711.1Sjmcneill  return count;
721.1Sjmcneill}
731.1Sjmcneill
741.1Sjmcneillstatic Bool
751.1SjmcneillxnestSaveScreen(ScreenPtr pScreen, int what)
761.1Sjmcneill{
771.1Sjmcneill  if (xnestSoftwareScreenSaver)
78    return False;
79  else {
80    switch (what) {
81    case SCREEN_SAVER_ON:
82      XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
83      xnestSetScreenSaverColormapWindow(pScreen);
84      break;
85
86    case SCREEN_SAVER_OFF:
87      XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
88      xnestSetInstalledColormapWindows(pScreen);
89      break;
90
91    case SCREEN_SAVER_FORCER:
92      lastEventTime = GetTimeInMillis();
93      XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
94      xnestSetInstalledColormapWindows(pScreen);
95      break;
96
97    case SCREEN_SAVER_CYCLE:
98      XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
99      xnestSetInstalledColormapWindows(pScreen);
100      break;
101    }
102    return True;
103  }
104}
105
106static Bool
107xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
108{
109    return FALSE;
110}
111
112static void
113xnestCrossScreen(ScreenPtr pScreen, Bool entering)
114{
115}
116
117static miPointerScreenFuncRec xnestPointerCursorFuncs =
118{
119    xnestCursorOffScreen,
120    xnestCrossScreen,
121    miPointerWarpCursor
122};
123
124static miPointerSpriteFuncRec xnestPointerSpriteFuncs =
125{
126    xnestRealizeCursor,
127    xnestUnrealizeCursor,
128    xnestSetCursor,
129    xnestMoveCursor,
130    xnestDeviceCursorInitialize,
131    xnestDeviceCursorCleanup
132};
133
134Bool
135xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[])
136{
137  VisualPtr visuals;
138  DepthPtr depths;
139  int numVisuals, numDepths;
140  int i, j, depthIndex;
141  unsigned long valuemask;
142  XSetWindowAttributes attributes;
143  XWindowAttributes gattributes;
144  XSizeHints sizeHints;
145  VisualID defaultVisual;
146  int rootDepth;
147  miPointerScreenPtr PointPriv;
148
149  if (!dixRequestPrivate(xnestWindowPrivateKey, sizeof(xnestPrivWin)))
150      return False;
151  if (!dixRequestPrivate(xnestGCPrivateKey, sizeof(xnestPrivGC)))
152    return False;
153
154  visuals = (VisualPtr)xalloc(xnestNumVisuals * sizeof(VisualRec));
155  numVisuals = 0;
156
157  depths = (DepthPtr)xalloc(MAXDEPTH * sizeof(DepthRec));
158  depths[0].depth = 1;
159  depths[0].numVids = 0;
160  depths[0].vids = (VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
161  numDepths = 1;
162
163  for (i = 0; i < xnestNumVisuals; i++) {
164    visuals[numVisuals].class = xnestVisuals[i].class;
165    visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
166    visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
167    visuals[numVisuals].nplanes = xnestVisuals[i].depth;
168    visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
169    visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
170    visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
171    visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
172    visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
173    visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
174
175    /* Check for and remove duplicates. */
176    for (j = 0; j < numVisuals; j++) {
177      if (visuals[numVisuals].class           == visuals[j].class           &&
178	  visuals[numVisuals].bitsPerRGBValue == visuals[j].bitsPerRGBValue &&
179	  visuals[numVisuals].ColormapEntries == visuals[j].ColormapEntries &&
180	  visuals[numVisuals].nplanes         == visuals[j].nplanes         &&
181	  visuals[numVisuals].redMask         == visuals[j].redMask         &&
182	  visuals[numVisuals].greenMask       == visuals[j].greenMask       &&
183	  visuals[numVisuals].blueMask        == visuals[j].blueMask        &&
184	  visuals[numVisuals].offsetRed       == visuals[j].offsetRed       &&
185	  visuals[numVisuals].offsetGreen     == visuals[j].offsetGreen     &&
186	  visuals[numVisuals].offsetBlue      == visuals[j].offsetBlue)
187	break;
188    }
189    if (j < numVisuals)
190      break;
191
192    visuals[numVisuals].vid = FakeClientID(0);
193
194    depthIndex = UNDEFINED;
195    for (j = 0; j < numDepths; j++)
196      if (depths[j].depth == xnestVisuals[i].depth) {
197	depthIndex = j;
198	break;
199      }
200
201    if (depthIndex == UNDEFINED) {
202      depthIndex = numDepths;
203      depths[depthIndex].depth = xnestVisuals[i].depth;
204      depths[depthIndex].numVids = 0;
205      depths[depthIndex].vids =
206	(VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
207      numDepths++;
208    }
209    if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
210	FatalError("Visual table overflow");
211    }
212    depths[depthIndex].vids[depths[depthIndex].numVids] =
213      visuals[numVisuals].vid;
214    depths[depthIndex].numVids++;
215
216    numVisuals++;
217  }
218  visuals = (VisualPtr)xrealloc(visuals, numVisuals * sizeof(VisualRec));
219
220  defaultVisual = visuals[xnestDefaultVisualIndex].vid;
221  rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
222
223  if (xnestParentWindow != 0) {
224    XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
225    xnestWidth = gattributes.width;
226    xnestHeight = gattributes.height;
227  }
228
229  /* myNum */
230  /* id */
231  miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth,
232	       rootDepth,
233	       numDepths, depths,
234	       defaultVisual, /* root visual */
235	       numVisuals, visuals);
236
237/*  miInitializeBackingStore(pScreen); */
238
239  pScreen->defColormap = (Colormap) FakeClientID(0);
240  pScreen->minInstalledCmaps = MINCMAPS;
241  pScreen->maxInstalledCmaps = MAXCMAPS;
242  pScreen->backingStoreSupport = NotUseful;
243  pScreen->saveUnderSupport = NotUseful;
244  pScreen->whitePixel = xnestWhitePixel;
245  pScreen->blackPixel = xnestBlackPixel;
246  /* rgf */
247  /* GCperDepth */
248  /* PixmapPerDepth */
249  pScreen->devPrivate = NULL;
250  /* WindowPrivateLen */
251  /* WindowPrivateSizes */
252  /* totalWindowSize */
253  /* GCPrivateLen */
254  /* GCPrivateSizes */
255  /* totalGCSize */
256
257  /* Random screen procedures */
258
259  pScreen->QueryBestSize = xnestQueryBestSize;
260  pScreen->SaveScreen = xnestSaveScreen;
261  pScreen->GetImage = xnestGetImage;
262  pScreen->GetSpans = xnestGetSpans;
263  pScreen->PointerNonInterestBox = NULL;
264  pScreen->SourceValidate = NULL;
265
266  /* Window Procedures */
267
268  pScreen->CreateWindow = xnestCreateWindow;
269  pScreen->DestroyWindow = xnestDestroyWindow;
270  pScreen->PositionWindow = xnestPositionWindow;
271  pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes;
272  pScreen->RealizeWindow = xnestRealizeWindow;
273  pScreen->UnrealizeWindow = xnestUnrealizeWindow;
274  pScreen->PostValidateTree = NULL;
275  pScreen->WindowExposures = xnestWindowExposures;
276  pScreen->CopyWindow = xnestCopyWindow;
277  pScreen->ClipNotify = xnestClipNotify;
278
279  /* Pixmap procedures */
280
281  pScreen->CreatePixmap = xnestCreatePixmap;
282  pScreen->DestroyPixmap = xnestDestroyPixmap;
283
284  /* Font procedures */
285
286  pScreen->RealizeFont = xnestRealizeFont;
287  pScreen->UnrealizeFont = xnestUnrealizeFont;
288
289  /* GC procedures */
290
291  pScreen->CreateGC = xnestCreateGC;
292
293  /* Colormap procedures */
294
295  pScreen->CreateColormap = xnestCreateColormap;
296  pScreen->DestroyColormap = xnestDestroyColormap;
297  pScreen->InstallColormap = xnestInstallColormap;
298  pScreen->UninstallColormap = xnestUninstallColormap;
299  pScreen->ListInstalledColormaps = xnestListInstalledColormaps;
300  pScreen->StoreColors = xnestStoreColors;
301  pScreen->ResolveColor = xnestResolveColor;
302
303   pScreen->BitmapToRegion = xnestPixmapToRegion;
304
305  /* OS layer procedures */
306
307  pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
308  pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
309  pScreen->blockData = NULL;
310  pScreen->wakeupData = NULL;
311
312  miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */
313  PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
314  xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs;
315  dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey, &xnestCursorFuncs);
316  PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
317
318  pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
319		       DefaultScreen(xnestDisplay)) /
320			 DisplayWidth(xnestDisplay,
321			   DefaultScreen(xnestDisplay));
322  pScreen->mmHeight = xnestHeight * DisplayHeightMM(xnestDisplay,
323		        DefaultScreen(xnestDisplay)) /
324			  DisplayHeight(xnestDisplay,
325			    DefaultScreen(xnestDisplay));
326
327  /* overwrite miCloseScreen with our own */
328  pScreen->CloseScreen = xnestCloseScreen;
329
330  if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL))
331      return FALSE;
332
333  /* overwrite miSetShape with our own */
334  pScreen->SetShape = xnestSetShape;
335
336  /* devPrivates */
337
338#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
339
340  if (xnestDoFullGeneration) {
341
342    valuemask = CWBackPixel | CWEventMask | CWColormap;
343    attributes.background_pixel = xnestWhitePixel;
344    attributes.event_mask = xnestEventMask;
345    attributes.colormap = xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
346
347    if (xnestParentWindow != 0) {
348      xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
349      XSelectInput (xnestDisplay, xnestDefaultWindows[pScreen->myNum],
350		    xnestEventMask);
351    } else
352      xnestDefaultWindows[pScreen->myNum] =
353	XCreateWindow(xnestDisplay,
354		      DefaultRootWindow(xnestDisplay),
355		      xnestX + POSITION_OFFSET,
356		      xnestY + POSITION_OFFSET,
357		      xnestWidth, xnestHeight,
358		      xnestBorderWidth,
359		      pScreen->rootDepth,
360		      InputOutput,
361		      xnestDefaultVisual(pScreen),
362		      valuemask, &attributes);
363
364    if (!xnestWindowName)
365      xnestWindowName = argv[0];
366
367    sizeHints.flags = PPosition | PSize | PMaxSize;
368    sizeHints.x = xnestX + POSITION_OFFSET;
369    sizeHints.y = xnestY + POSITION_OFFSET;
370    sizeHints.width = sizeHints.max_width = xnestWidth;
371    sizeHints.height = sizeHints.max_height = xnestHeight;
372    if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
373      sizeHints.flags |= USPosition;
374    if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
375      sizeHints.flags |= USSize;
376    XSetStandardProperties(xnestDisplay,
377			   xnestDefaultWindows[pScreen->myNum],
378			   xnestWindowName,
379			   xnestWindowName,
380			   xnestIconBitmap,
381			   argv, argc, &sizeHints);
382
383    XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
384
385    valuemask = CWBackPixmap | CWColormap;
386    attributes.background_pixmap = xnestScreenSaverPixmap;
387    attributes.colormap =
388      DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
389    xnestScreenSaverWindows[pScreen->myNum] =
390      XCreateWindow(xnestDisplay,
391		    xnestDefaultWindows[pScreen->myNum],
392		    0, 0, xnestWidth, xnestHeight, 0,
393		    DefaultDepth(xnestDisplay, DefaultScreen(xnestDisplay)),
394		    InputOutput,
395		    DefaultVisual(xnestDisplay, DefaultScreen(xnestDisplay)),
396		    valuemask, &attributes);
397  }
398
399  if (!xnestCreateDefaultColormap(pScreen)) return False;
400
401  return True;
402}
403
404Bool
405xnestCloseScreen(int index, ScreenPtr pScreen)
406{
407  int i;
408
409  for (i = 0; i < pScreen->numDepths; i++)
410    xfree(pScreen->allowedDepths[i].vids);
411  xfree(pScreen->allowedDepths);
412  xfree(pScreen->visuals);
413  xfree(pScreen->devPrivate);
414
415  /*
416    If xnestDoFullGeneration all x resources will be destroyed upon closing
417    the display connection.  There is no need to generate extra protocol.
418    */
419
420  return True;
421}
422