429 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			429 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
| 
 | |
| Copyright 1993 by Davor Matic
 | |
| 
 | |
| Permission to use, copy, modify, distribute, and sell this software
 | |
| and its documentation for any purpose is hereby granted without fee,
 | |
| provided that the above copyright notice appear in all copies and that
 | |
| both that copyright notice and this permission notice appear in
 | |
| supporting documentation.  Davor Matic makes no representations about
 | |
| the suitability of this software for any purpose.  It is provided "as
 | |
| is" without express or implied warranty.
 | |
| 
 | |
| */
 | |
| #include <dix-config.h>
 | |
| 
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xdefs.h>
 | |
| #include <X11/Xproto.h>
 | |
| 
 | |
| #include "mi/mi_priv.h"
 | |
| #include "mi/mipointer_priv.h"
 | |
| 
 | |
| #include "scrnintstr.h"
 | |
| #include "dix.h"
 | |
| #include "micmap.h"
 | |
| #include "colormapst.h"
 | |
| #include "resource.h"
 | |
| 
 | |
| #include "Xnest.h"
 | |
| 
 | |
| #include "Display.h"
 | |
| #include "Screen.h"
 | |
| #include "XNGC.h"
 | |
| #include "GCOps.h"
 | |
| #include "Drawable.h"
 | |
| #include "XNFont.h"
 | |
| #include "Color.h"
 | |
| #include "XNCursor.h"
 | |
| #include "Visual.h"
 | |
| #include "Events.h"
 | |
| #include "Init.h"
 | |
| #include "mipointer.h"
 | |
| #include "Args.h"
 | |
| #include "mipointrst.h"
 | |
| 
 | |
| Window xnestDefaultWindows[MAXSCREENS];
 | |
| Window xnestScreenSaverWindows[MAXSCREENS];
 | |
| DevPrivateKeyRec xnestScreenCursorFuncKeyRec;
 | |
| DevScreenPrivateKeyRec xnestScreenCursorPrivKeyRec;
 | |
| 
 | |
| ScreenPtr
 | |
| xnestScreen(Window window)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for (i = 0; i < xnestNumScreens; i++)
 | |
|         if (xnestDefaultWindows[i] == window)
 | |
|             return screenInfo.screens[i];
 | |
| 
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| static int
 | |
| offset(unsigned long mask)
 | |
| {
 | |
|     int count;
 | |
| 
 | |
|     for (count = 0; !(mask & 1) && count < 32; count++)
 | |
|         mask >>= 1;
 | |
| 
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| static Bool
 | |
| xnestSaveScreen(ScreenPtr pScreen, int what)
 | |
| {
 | |
|     if (xnestSoftwareScreenSaver)
 | |
|         return FALSE;
 | |
|     else {
 | |
|         switch (what) {
 | |
|         case SCREEN_SAVER_ON:
 | |
|             XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
 | |
|             xnestSetScreenSaverColormapWindow(pScreen);
 | |
|             break;
 | |
| 
 | |
|         case SCREEN_SAVER_OFF:
 | |
|             XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
 | |
|             xnestSetInstalledColormapWindows(pScreen);
 | |
|             break;
 | |
| 
 | |
|         case SCREEN_SAVER_FORCER:
 | |
|             lastEventTime = GetTimeInMillis();
 | |
|             XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
 | |
|             xnestSetInstalledColormapWindows(pScreen);
 | |
|             break;
 | |
| 
 | |
|         case SCREEN_SAVER_CYCLE:
 | |
|             XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
 | |
|             xnestSetInstalledColormapWindows(pScreen);
 | |
|             break;
 | |
|         }
 | |
|         return TRUE;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static Bool
 | |
| xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
 | |
| {
 | |
|     return FALSE;
 | |
| }
 | |
| 
 | |
| static void
 | |
| xnestCrossScreen(ScreenPtr pScreen, Bool entering)
 | |
| {
 | |
| }
 | |
| 
 | |
| static miPointerScreenFuncRec xnestPointerCursorFuncs = {
 | |
|     xnestCursorOffScreen,
 | |
|     xnestCrossScreen,
 | |
|     miPointerWarpCursor
 | |
| };
 | |
| 
 | |
| static miPointerSpriteFuncRec xnestPointerSpriteFuncs = {
 | |
|     xnestRealizeCursor,
 | |
|     xnestUnrealizeCursor,
 | |
|     xnestSetCursor,
 | |
|     xnestMoveCursor,
 | |
|     xnestDeviceCursorInitialize,
 | |
|     xnestDeviceCursorCleanup
 | |
| };
 | |
| 
 | |
| Bool
 | |
| xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
 | |
| {
 | |
|     VisualPtr visuals;
 | |
|     DepthPtr depths;
 | |
|     int numVisuals, numDepths;
 | |
|     int i, j, depthIndex;
 | |
|     unsigned long valuemask;
 | |
|     XSetWindowAttributes attributes;
 | |
|     XWindowAttributes gattributes;
 | |
|     XSizeHints sizeHints;
 | |
|     VisualID defaultVisual;
 | |
|     int rootDepth;
 | |
|     miPointerScreenPtr PointPriv;
 | |
| 
 | |
|     if (!dixRegisterPrivateKey
 | |
|         (&xnestWindowPrivateKeyRec, PRIVATE_WINDOW, sizeof(xnestPrivWin)))
 | |
|         return FALSE;
 | |
|     if (!dixRegisterPrivateKey
 | |
|         (&xnestGCPrivateKeyRec, PRIVATE_GC, sizeof(xnestPrivGC)))
 | |
|         return FALSE;
 | |
|     if (!dixRegisterPrivateKey
 | |
|         (&xnestPixmapPrivateKeyRec, PRIVATE_PIXMAP, sizeof(xnestPrivPixmap)))
 | |
|         return FALSE;
 | |
|     if (!dixRegisterPrivateKey
 | |
|         (&xnestColormapPrivateKeyRec, PRIVATE_COLORMAP,
 | |
|          sizeof(xnestPrivColormap)))
 | |
|         return FALSE;
 | |
|     if (!dixRegisterPrivateKey(&xnestScreenCursorFuncKeyRec, PRIVATE_SCREEN, 0))
 | |
|         return FALSE;
 | |
| 
 | |
|     if (!dixRegisterScreenPrivateKey(&xnestScreenCursorPrivKeyRec, pScreen,
 | |
|                                      PRIVATE_CURSOR, 0))
 | |
|         return FALSE;
 | |
| 
 | |
|     visuals = xallocarray(xnestNumVisuals, sizeof(VisualRec));
 | |
|     numVisuals = 0;
 | |
| 
 | |
|     depths = (DepthPtr) malloc(MAXDEPTH * sizeof(DepthRec));
 | |
|     depths[0].depth = 1;
 | |
|     depths[0].numVids = 0;
 | |
|     depths[0].vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
 | |
|     numDepths = 1;
 | |
| 
 | |
|     for (i = 0; i < xnestNumVisuals; i++) {
 | |
|         visuals[numVisuals].class = xnestVisuals[i].class;
 | |
|         visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
 | |
|         visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
 | |
|         visuals[numVisuals].nplanes = xnestVisuals[i].depth;
 | |
|         visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
 | |
|         visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
 | |
|         visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
 | |
|         visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
 | |
|         visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
 | |
|         visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
 | |
| 
 | |
|         /* Check for and remove duplicates. */
 | |
|         for (j = 0; j < numVisuals; j++) {
 | |
|             if (visuals[numVisuals].class == visuals[j].class &&
 | |
|                 visuals[numVisuals].bitsPerRGBValue ==
 | |
|                 visuals[j].bitsPerRGBValue &&
 | |
|                 visuals[numVisuals].ColormapEntries ==
 | |
|                 visuals[j].ColormapEntries &&
 | |
|                 visuals[numVisuals].nplanes == visuals[j].nplanes &&
 | |
|                 visuals[numVisuals].redMask == visuals[j].redMask &&
 | |
|                 visuals[numVisuals].greenMask == visuals[j].greenMask &&
 | |
|                 visuals[numVisuals].blueMask == visuals[j].blueMask &&
 | |
|                 visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
 | |
|                 visuals[numVisuals].offsetGreen == visuals[j].offsetGreen &&
 | |
|                 visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
 | |
|                 break;
 | |
|         }
 | |
|         if (j < numVisuals)
 | |
|             break;
 | |
| 
 | |
|         visuals[numVisuals].vid = FakeClientID(0);
 | |
| 
 | |
|         depthIndex = UNDEFINED;
 | |
|         for (j = 0; j < numDepths; j++)
 | |
|             if (depths[j].depth == xnestVisuals[i].depth) {
 | |
|                 depthIndex = j;
 | |
|                 break;
 | |
|             }
 | |
| 
 | |
|         if (depthIndex == UNDEFINED) {
 | |
|             depthIndex = numDepths;
 | |
|             depths[depthIndex].depth = xnestVisuals[i].depth;
 | |
|             depths[depthIndex].numVids = 0;
 | |
|             depths[depthIndex].vids =
 | |
|                 (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
 | |
|             numDepths++;
 | |
|         }
 | |
|         if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
 | |
|             FatalError("Visual table overflow");
 | |
|         }
 | |
|         depths[depthIndex].vids[depths[depthIndex].numVids] =
 | |
|             visuals[numVisuals].vid;
 | |
|         depths[depthIndex].numVids++;
 | |
| 
 | |
|         numVisuals++;
 | |
|     }
 | |
|     visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
 | |
| 
 | |
|     defaultVisual = visuals[xnestDefaultVisualIndex].vid;
 | |
|     rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
 | |
| 
 | |
|     if (xnestParentWindow != 0) {
 | |
|         XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
 | |
|         xnestWidth = gattributes.width;
 | |
|         xnestHeight = gattributes.height;
 | |
|     }
 | |
| 
 | |
|     /* myNum */
 | |
|     /* id */
 | |
|     if (!miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth, rootDepth, numDepths, depths, defaultVisual, /* root visual */
 | |
|                       numVisuals, visuals))
 | |
|         return FALSE;
 | |
| 
 | |
|     pScreen->defColormap = (Colormap) FakeClientID(0);
 | |
|     pScreen->minInstalledCmaps = MINCMAPS;
 | |
|     pScreen->maxInstalledCmaps = MAXCMAPS;
 | |
|     pScreen->backingStoreSupport = NotUseful;
 | |
|     pScreen->saveUnderSupport = NotUseful;
 | |
|     pScreen->whitePixel = xnestWhitePixel;
 | |
|     pScreen->blackPixel = xnestBlackPixel;
 | |
|     /* GCperDepth */
 | |
|     /* defaultStipple */
 | |
|     /* WindowPrivateLen */
 | |
|     /* WindowPrivateSizes */
 | |
|     /* totalWindowSize */
 | |
|     /* GCPrivateLen */
 | |
|     /* GCPrivateSizes */
 | |
|     /* totalGCSize */
 | |
| 
 | |
|     /* Random screen procedures */
 | |
| 
 | |
|     pScreen->QueryBestSize = xnestQueryBestSize;
 | |
|     pScreen->SaveScreen = xnestSaveScreen;
 | |
|     pScreen->GetImage = xnestGetImage;
 | |
|     pScreen->GetSpans = xnestGetSpans;
 | |
| 
 | |
|     /* Window Procedures */
 | |
| 
 | |
|     pScreen->CreateWindow = xnestCreateWindow;
 | |
|     pScreen->DestroyWindow = xnestDestroyWindow;
 | |
|     pScreen->PositionWindow = xnestPositionWindow;
 | |
|     pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes;
 | |
|     pScreen->RealizeWindow = xnestRealizeWindow;
 | |
|     pScreen->UnrealizeWindow = xnestUnrealizeWindow;
 | |
|     pScreen->PostValidateTree = NULL;
 | |
|     pScreen->WindowExposures = xnestWindowExposures;
 | |
|     pScreen->CopyWindow = xnestCopyWindow;
 | |
|     pScreen->ClipNotify = xnestClipNotify;
 | |
| 
 | |
|     /* Pixmap procedures */
 | |
| 
 | |
|     pScreen->CreatePixmap = xnestCreatePixmap;
 | |
|     pScreen->DestroyPixmap = xnestDestroyPixmap;
 | |
|     pScreen->ModifyPixmapHeader = xnestModifyPixmapHeader;
 | |
| 
 | |
|     /* Font procedures */
 | |
| 
 | |
|     pScreen->RealizeFont = xnestRealizeFont;
 | |
|     pScreen->UnrealizeFont = xnestUnrealizeFont;
 | |
| 
 | |
|     /* GC procedures */
 | |
| 
 | |
|     pScreen->CreateGC = xnestCreateGC;
 | |
| 
 | |
|     /* Colormap procedures */
 | |
| 
 | |
|     pScreen->CreateColormap = xnestCreateColormap;
 | |
|     pScreen->DestroyColormap = xnestDestroyColormap;
 | |
|     pScreen->InstallColormap = xnestInstallColormap;
 | |
|     pScreen->UninstallColormap = xnestUninstallColormap;
 | |
|     pScreen->ListInstalledColormaps = xnestListInstalledColormaps;
 | |
|     pScreen->StoreColors = xnestStoreColors;
 | |
|     pScreen->ResolveColor = xnestResolveColor;
 | |
| 
 | |
|     pScreen->BitmapToRegion = xnestPixmapToRegion;
 | |
| 
 | |
|     /* OS layer procedures */
 | |
| 
 | |
|     pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA;
 | |
|     pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA;
 | |
| 
 | |
|     miDCInitialize(pScreen, &xnestPointerCursorFuncs);  /* init SW rendering */
 | |
|     PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
 | |
|     xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs;
 | |
|     dixSetPrivate(&pScreen->devPrivates, &xnestScreenCursorFuncKeyRec,
 | |
|                   &xnestCursorFuncs);
 | |
|     PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
 | |
| 
 | |
|     pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
 | |
|                                                    DefaultScreen(xnestDisplay))
 | |
|         / DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay));
 | |
|     pScreen->mmHeight =
 | |
|         xnestHeight * DisplayHeightMM(xnestDisplay,
 | |
|                                       DefaultScreen(xnestDisplay)) /
 | |
|         DisplayHeight(xnestDisplay, DefaultScreen(xnestDisplay));
 | |
| 
 | |
|     /* overwrite miCloseScreen with our own */
 | |
|     pScreen->CloseScreen = xnestCloseScreen;
 | |
| 
 | |
|     /* overwrite miSetShape with our own */
 | |
|     pScreen->SetShape = xnestSetShape;
 | |
| 
 | |
|     /* devPrivates */
 | |
| 
 | |
| #define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
 | |
| 
 | |
|     if (xnestDoFullGeneration) {
 | |
| 
 | |
|         valuemask = CWBackPixel | CWEventMask | CWColormap;
 | |
|         attributes.background_pixel = xnestWhitePixel;
 | |
|         attributes.event_mask = xnestEventMask;
 | |
|         attributes.colormap =
 | |
|             xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
 | |
| 
 | |
|         if (xnestParentWindow != 0) {
 | |
|             xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
 | |
|             XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
 | |
|                          xnestEventMask);
 | |
|         }
 | |
|         else
 | |
|             xnestDefaultWindows[pScreen->myNum] =
 | |
|                 XCreateWindow(xnestDisplay,
 | |
|                               DefaultRootWindow(xnestDisplay),
 | |
|                               xnestX + POSITION_OFFSET,
 | |
|                               xnestY + POSITION_OFFSET,
 | |
|                               xnestWidth, xnestHeight,
 | |
|                               xnestBorderWidth,
 | |
|                               pScreen->rootDepth,
 | |
|                               InputOutput,
 | |
|                               xnestDefaultVisual(pScreen),
 | |
|                               valuemask, &attributes);
 | |
| 
 | |
|         if (!xnestWindowName)
 | |
|             xnestWindowName = argv[0];
 | |
| 
 | |
|         sizeHints.flags = PPosition | PSize | PMaxSize;
 | |
|         sizeHints.x = xnestX + POSITION_OFFSET;
 | |
|         sizeHints.y = xnestY + POSITION_OFFSET;
 | |
|         sizeHints.width = sizeHints.max_width = xnestWidth;
 | |
|         sizeHints.height = sizeHints.max_height = xnestHeight;
 | |
|         if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
 | |
|             sizeHints.flags |= USPosition;
 | |
|         if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
 | |
|             sizeHints.flags |= USSize;
 | |
|         XSetStandardProperties(xnestDisplay,
 | |
|                                xnestDefaultWindows[pScreen->myNum],
 | |
|                                xnestWindowName,
 | |
|                                xnestWindowName,
 | |
|                                xnestIconBitmap, argv, argc, &sizeHints);
 | |
| 
 | |
|         XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
 | |
| 
 | |
|         valuemask = CWBackPixmap | CWColormap;
 | |
|         attributes.background_pixmap = xnestScreenSaverPixmap;
 | |
|         attributes.colormap =
 | |
|             DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
 | |
|         xnestScreenSaverWindows[pScreen->myNum] =
 | |
|             XCreateWindow(xnestDisplay,
 | |
|                           xnestDefaultWindows[pScreen->myNum],
 | |
|                           0, 0, xnestWidth, xnestHeight, 0,
 | |
|                           DefaultDepth(xnestDisplay,
 | |
|                                        DefaultScreen(xnestDisplay)),
 | |
|                           InputOutput, DefaultVisual(xnestDisplay,
 | |
|                                                      DefaultScreen
 | |
|                                                      (xnestDisplay)), valuemask,
 | |
|                           &attributes);
 | |
|     }
 | |
| 
 | |
|     if (!xnestCreateDefaultColormap(pScreen))
 | |
|         return FALSE;
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| Bool
 | |
| xnestCloseScreen(ScreenPtr pScreen)
 | |
| {
 | |
|     int i;
 | |
| 
 | |
|     for (i = 0; i < pScreen->numDepths; i++)
 | |
|         free(pScreen->allowedDepths[i].vids);
 | |
|     free(pScreen->allowedDepths);
 | |
|     free(pScreen->visuals);
 | |
|     miScreenClose(pScreen);
 | |
| 
 | |
|     /*
 | |
|        If xnestDoFullGeneration all x resources will be destroyed upon closing
 | |
|        the display connection.  There is no need to generate extra protocol.
 | |
|      */
 | |
| 
 | |
|     return TRUE;
 | |
| }
 |