540 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			540 lines
		
	
	
		
			19 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.
 | |
| 
 | |
| */
 | |
| 
 | |
| #ifdef HAVE_XNEST_CONFIG_H
 | |
| #include <xnest-config.h>
 | |
| #endif
 | |
| 
 | |
| #include <xcb/xcb.h>
 | |
| #include <xcb/xcb_aux.h>
 | |
| 
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xdefs.h>
 | |
| #include <X11/Xproto.h>
 | |
| 
 | |
| #include <xcb/xcb_icccm.h>
 | |
| 
 | |
| #include "mi/mi_priv.h"
 | |
| 
 | |
| #include "scrnintstr.h"
 | |
| #include "dix.h"
 | |
| #include "mi.h"
 | |
| #include "micmap.h"
 | |
| #include "colormapst.h"
 | |
| #include "resource.h"
 | |
| 
 | |
| #include "xnest-xcb.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 "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:
 | |
|             xcb_map_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
 | |
|             uint32_t value = XCB_STACK_MODE_ABOVE;
 | |
|             xcb_configure_window(xnestUpstreamInfo.conn,
 | |
|                                  xnestScreenSaverWindows[pScreen->myNum],
 | |
|                                  XCB_CONFIG_WINDOW_STACK_MODE,
 | |
|                                  &value);
 | |
|             xnestSetScreenSaverColormapWindow(pScreen);
 | |
|             break;
 | |
| 
 | |
|         case SCREEN_SAVER_OFF:
 | |
|             xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
 | |
|             xnestSetInstalledColormapWindows(pScreen);
 | |
|             break;
 | |
| 
 | |
|         case SCREEN_SAVER_FORCER:
 | |
|             lastEventTime = GetTimeInMillis();
 | |
|             xcb_unmap_window(xnestUpstreamInfo.conn, xnestScreenSaverWindows[pScreen->myNum]);
 | |
|             xnestSetInstalledColormapWindows(pScreen);
 | |
|             break;
 | |
| 
 | |
|         case SCREEN_SAVER_CYCLE:
 | |
|             xcb_unmap_window(xnestUpstreamInfo.conn, 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
 | |
| };
 | |
| 
 | |
| static int add_depth_visual(DepthPtr depths, int numDepths, int nplanes, VisualID vid)
 | |
| {
 | |
|     DepthPtr walk = NULL;
 | |
| 
 | |
|     for (int j = 0; j < numDepths; j++)
 | |
|         if (depths[j].depth == nplanes) {
 | |
|             walk = &depths[j];
 | |
|             break;
 | |
|         }
 | |
| 
 | |
|     if (!walk) {
 | |
|         walk = &depths[numDepths++];
 | |
|         walk->depth = nplanes;
 | |
|         walk->numVids = 0;
 | |
|         walk->vids = (VisualID *) malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
 | |
|     }
 | |
|     if (walk->numVids >= MAXVISUALSPERDEPTH) {
 | |
|         FatalError("Visual table overflow");
 | |
|     }
 | |
|     walk->vids[walk->numVids] = vid;
 | |
|     walk->numVids++;
 | |
| 
 | |
|     return numDepths;
 | |
| }
 | |
| 
 | |
| Bool
 | |
| xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[])
 | |
| {
 | |
|     unsigned long valuemask;
 | |
|     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;
 | |
| 
 | |
|     int numVisuals = 0;
 | |
|     VisualPtr visuals = calloc(1, sizeof(VisualRec));
 | |
|     int numDepths = 1;
 | |
|     DepthPtr depths = calloc(MAXDEPTH, sizeof(DepthRec));
 | |
| 
 | |
|     if (!visuals || !depths) {
 | |
|         free(visuals);
 | |
|         free(depths);
 | |
|         return FALSE;
 | |
|     }
 | |
| 
 | |
|     if (!xnestVisualMap)
 | |
|         xnestVisualMap = calloc(1, sizeof(xnest_visual_t));
 | |
|     else
 | |
|         xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(xnest_visual_t));
 | |
| 
 | |
|     depths[0].depth = 1;
 | |
|     depths[0].numVids = 0;
 | |
|     depths[0].vids = calloc(MAXVISUALSPERDEPTH, sizeof(VisualID));
 | |
| 
 | |
|     int found_default_visual = 0;
 | |
|     xcb_depth_iterator_t depth_iter;
 | |
|     for (depth_iter = xcb_screen_allowed_depths_iterator(xnestUpstreamInfo.screenInfo);
 | |
|          depth_iter.rem;
 | |
|          xcb_depth_next(&depth_iter))
 | |
|     {
 | |
|         int vlen = xcb_depth_visuals_length (depth_iter.data);
 | |
|         xcb_visualtype_t *vts = xcb_depth_visuals (depth_iter.data);
 | |
|         for (int x=0; x<vlen; x++) {
 | |
|             for (int j = 0; j < numVisuals; j++) {
 | |
|                 if (vts[x]._class == visuals[j].class &&
 | |
|                     vts[x].bits_per_rgb_value == visuals[j].bitsPerRGBValue &&
 | |
|                     vts[x].colormap_entries == visuals[j].ColormapEntries &&
 | |
|                     depth_iter.data->depth == visuals[j].nplanes &&
 | |
|                     vts[x].red_mask == visuals[j].redMask &&
 | |
|                     vts[x].green_mask == visuals[j].greenMask &&
 | |
|                     vts[x].blue_mask == visuals[j].blueMask &&
 | |
|                     offset(vts[x].red_mask) == visuals[j].offsetRed &&
 | |
|                     offset(vts[x].green_mask) == visuals[j].offsetGreen &&
 | |
|                     offset(vts[x].blue_mask) == visuals[j].offsetBlue)
 | |
|                         goto breakout;
 | |
|             }
 | |
| 
 | |
|             visuals[numVisuals] = (VisualRec) {
 | |
|                 .class = vts[x]._class,
 | |
|                 .bitsPerRGBValue = vts[x].bits_per_rgb_value,
 | |
|                 .ColormapEntries = vts[x].colormap_entries,
 | |
|                 .nplanes = depth_iter.data->depth,
 | |
|                 .redMask = vts[x].red_mask,
 | |
|                 .greenMask = vts[x].green_mask,
 | |
|                 .blueMask = vts[x].blue_mask,
 | |
|                 .offsetRed = offset(vts[x].red_mask),
 | |
|                 .offsetGreen = offset(vts[x].green_mask),
 | |
|                 .offsetBlue = offset(vts[x].blue_mask),
 | |
|                 .vid = FakeClientID(0),
 | |
|             };
 | |
| 
 | |
|             xnestVisualMap[xnestNumVisualMap] = (xnest_visual_t) {
 | |
|                 .ourXID = visuals[numVisuals].vid,
 | |
|                 .ourVisual = &visuals[numVisuals],
 | |
|                 .upstreamDepth = depth_iter.data,
 | |
|                 .upstreamVisual = &vts[x],
 | |
|                 .upstreamCMap = xcb_generate_id(xnestUpstreamInfo.conn),
 | |
|             };
 | |
| 
 | |
|             xcb_create_colormap(xnestUpstreamInfo.conn,
 | |
|                                 XCB_COLORMAP_ALLOC_NONE,
 | |
|                                 xnestVisualMap[xnestNumVisualMap].upstreamCMap,
 | |
|                                 xnestUpstreamInfo.screenInfo->root,
 | |
|                                 xnestVisualMap[xnestNumVisualMap].upstreamVisual->visual_id);
 | |
| 
 | |
|             numDepths = add_depth_visual(depths, numDepths, visuals[numVisuals].nplanes, visuals[numVisuals].vid);
 | |
| 
 | |
|             if (xnestUserDefaultClass || xnestUserDefaultDepth) {
 | |
|                 if ((!xnestDefaultClass || visuals[numVisuals].class == xnestDefaultClass) &&
 | |
|                     (!xnestDefaultDepth || visuals[numVisuals].nplanes == xnestDefaultDepth))
 | |
|                 {
 | |
|                     defaultVisual = visuals[numVisuals].vid;
 | |
|                     rootDepth = visuals[numVisuals].nplanes;
 | |
|                     found_default_visual = 1;
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 VisualID visual_id = xnestUpstreamInfo.screenInfo->root_visual;
 | |
|                 if (visual_id == vts[x].visual_id) {
 | |
|                     defaultVisual = visuals[numVisuals].vid;
 | |
|                     rootDepth = visuals[numVisuals].nplanes;
 | |
|                     found_default_visual = 1;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             numVisuals++;
 | |
|             xnestNumVisualMap++;
 | |
|             visuals = reallocarray(visuals, numVisuals+1, sizeof(VisualRec));
 | |
|             xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(xnest_visual_t));
 | |
|         }
 | |
|     }
 | |
| breakout:
 | |
|     visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec));
 | |
|     xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap, sizeof(xnest_visual_t));
 | |
| 
 | |
|     if (!found_default_visual) {
 | |
|         ErrorF("Xnest: can't find matching visual for user specified depth %d\n", xnestDefaultDepth);
 | |
|         defaultVisual = visuals[0].vid;
 | |
|         rootDepth = visuals[0].nplanes;
 | |
|     }
 | |
| 
 | |
|     if (xnestParentWindow != 0) {
 | |
|         xRectangle r = xnest_get_geometry(xnestUpstreamInfo.conn, xnestParentWindow);
 | |
|         xnestGeometry.width = r.width;
 | |
|         xnestGeometry.height = r.height;
 | |
|     }
 | |
| 
 | |
|     /* myNum */
 | |
|     /* id */
 | |
|     if (!miScreenInit(pScreen, NULL, xnestGeometry.width, xnestGeometry.height,
 | |
|                       1, 1, xnestGeometry.width, rootDepth, numDepths, depths, defaultVisual, /* root visual */
 | |
|                       numVisuals, visuals))
 | |
|         return FALSE;
 | |
| 
 | |
|     pScreen->defColormap = (Colormap) FakeClientID(0);
 | |
|     pScreen->minInstalledCmaps = MINCMAPS;
 | |
|     pScreen->maxInstalledCmaps = MAXCMAPS;
 | |
|     pScreen->backingStoreSupport = XCB_BACKING_STORE_NOT_USEFUL;
 | |
|     pScreen->saveUnderSupport = XCB_BACKING_STORE_NOT_USEFUL;
 | |
|     pScreen->whitePixel = xnestUpstreamInfo.screenInfo->white_pixel;
 | |
|     pScreen->blackPixel = xnestUpstreamInfo.screenInfo->black_pixel;
 | |
|     /* 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 = miWindowExposures;
 | |
|     pScreen->CopyWindow = xnestCopyWindow;
 | |
|     pScreen->ClipNotify = xnestClipNotify;
 | |
|     pScreen->ClearToBackground = xnest_screen_ClearToBackground;
 | |
| 
 | |
|     /* 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 =
 | |
|         xnestGeometry.width * xnestUpstreamInfo.screenInfo->width_in_millimeters /
 | |
|         xnestUpstreamInfo.screenInfo->width_in_pixels;
 | |
|     pScreen->mmHeight =
 | |
|         xnestGeometry.height * xnestUpstreamInfo.screenInfo->height_in_millimeters /
 | |
|         xnestUpstreamInfo.screenInfo->height_in_pixels;
 | |
| 
 | |
|     /* overwrite miCloseScreen with our own */
 | |
|     pScreen->CloseScreen = xnestCloseScreen;
 | |
| 
 | |
|     /* overwrite miSetShape with our own */
 | |
|     pScreen->SetShape = xnestSetShape;
 | |
| 
 | |
|     /* devPrivates */
 | |
| 
 | |
| #define POSITION_OFFSET (pScreen->myNum * (xnestGeometry.width + xnestGeometry.height) / 32)
 | |
| 
 | |
|     if (xnestDoFullGeneration) {
 | |
| 
 | |
|         xcb_params_cw_t attributes = {
 | |
|             .back_pixel = xnestUpstreamInfo.screenInfo->white_pixel,
 | |
|             .event_mask = xnestEventMask,
 | |
|             .colormap = xnest_visual_to_upstream_cmap(pScreen->rootVisual),
 | |
|         };
 | |
| 
 | |
|         valuemask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
 | |
| 
 | |
|         if (xnestParentWindow != 0) {
 | |
|             xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
 | |
|             xcb_change_window_attributes(xnestUpstreamInfo.conn,
 | |
|                                          xnestDefaultWindows[pScreen->myNum],
 | |
|                                          XCB_CW_EVENT_MASK,
 | |
|                                          &xnestEventMask);
 | |
|         }
 | |
|         else {
 | |
|             xnestDefaultWindows[pScreen->myNum] = xcb_generate_id(xnestUpstreamInfo.conn);
 | |
|             xcb_aux_create_window(xnestUpstreamInfo.conn,
 | |
|                                   pScreen->rootDepth,
 | |
|                                   xnestDefaultWindows[pScreen->myNum],
 | |
|                                   xnestUpstreamInfo.screenInfo->root,
 | |
|                                   xnestGeometry.x + POSITION_OFFSET,
 | |
|                                   xnestGeometry.y + POSITION_OFFSET,
 | |
|                                   xnestGeometry.width,
 | |
|                                   xnestGeometry.height,
 | |
|                                   xnestBorderWidth,
 | |
|                                   XCB_WINDOW_CLASS_INPUT_OUTPUT,
 | |
|                                   xnest_visual_map_to_upstream(pScreen->rootVisual),
 | |
|                                   valuemask,
 | |
|                                   &attributes);
 | |
|         }
 | |
| 
 | |
|         if (!xnestWindowName)
 | |
|             xnestWindowName = argv[0];
 | |
| 
 | |
|         xcb_size_hints_t sizeHints = {
 | |
|             .flags = XCB_ICCCM_SIZE_HINT_P_POSITION | XCB_ICCCM_SIZE_HINT_P_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE,
 | |
|             .x = xnestGeometry.x + POSITION_OFFSET,
 | |
|             .y = xnestGeometry.y + POSITION_OFFSET,
 | |
|             .width = xnestGeometry.width,
 | |
|             .height = xnestGeometry.height,
 | |
|             .max_width = xnestGeometry.width,
 | |
|             .max_height = xnestGeometry.height,
 | |
|         };
 | |
| 
 | |
|         if (xnestUserGeometry & XCB_CONFIG_WINDOW_X ||
 | |
|             xnestUserGeometry & XCB_CONFIG_WINDOW_Y)
 | |
|             sizeHints.flags |= XCB_ICCCM_SIZE_HINT_US_POSITION;
 | |
|         if (xnestUserGeometry & XCB_CONFIG_WINDOW_WIDTH ||
 | |
|             xnestUserGeometry & XCB_CONFIG_WINDOW_HEIGHT)
 | |
|             sizeHints.flags |= XCB_ICCCM_SIZE_HINT_US_SIZE;
 | |
| 
 | |
|         const size_t windowNameLen = strlen(xnestWindowName);
 | |
| 
 | |
|         xcb_icccm_set_wm_name_checked(xnestUpstreamInfo.conn,
 | |
|                                       xnestDefaultWindows[pScreen->myNum],
 | |
|                                       XCB_ATOM_STRING,
 | |
|                                       8,
 | |
|                                       windowNameLen,
 | |
|                                       xnestWindowName);
 | |
| 
 | |
|         xcb_icccm_set_wm_icon_name_checked(xnestUpstreamInfo.conn,
 | |
|                                            xnestDefaultWindows[pScreen->myNum],
 | |
|                                            XCB_ATOM_STRING,
 | |
|                                            8,
 | |
|                                            windowNameLen,
 | |
|                                            xnestWindowName);
 | |
| 
 | |
|         xnest_set_command(xnestUpstreamInfo.conn,
 | |
|                           xnestDefaultWindows[pScreen->myNum],
 | |
|                           argv, argc);
 | |
| 
 | |
|         xcb_icccm_wm_hints_t wmhints = {
 | |
|             .icon_pixmap = xnestIconBitmap,
 | |
|             .flags = XCB_ICCCM_WM_HINT_ICON_PIXMAP,
 | |
|         };
 | |
| 
 | |
|         xcb_icccm_set_wm_hints_checked(xnestUpstreamInfo.conn,
 | |
|                                        xnestDefaultWindows[pScreen->myNum],
 | |
|                                        &wmhints);
 | |
| 
 | |
|         xcb_map_window(xnestUpstreamInfo.conn, xnestDefaultWindows[pScreen->myNum]);
 | |
| 
 | |
|         valuemask = XCB_CW_BACK_PIXMAP | XCB_CW_COLORMAP;
 | |
|         attributes.back_pixmap = xnestScreenSaverPixmap;
 | |
|         attributes.colormap = xnestUpstreamInfo.screenInfo->default_colormap;
 | |
| 
 | |
|         xnestScreenSaverWindows[pScreen->myNum] = xcb_generate_id(xnestUpstreamInfo.conn);
 | |
|         xcb_aux_create_window(xnestUpstreamInfo.conn,
 | |
|                               xnestUpstreamInfo.screenInfo->root_depth,
 | |
|                               xnestScreenSaverWindows[pScreen->myNum],
 | |
|                               xnestDefaultWindows[pScreen->myNum],
 | |
|                               0,
 | |
|                               0,
 | |
|                               xnestGeometry.width,
 | |
|                               xnestGeometry.height,
 | |
|                               0,
 | |
|                               XCB_WINDOW_CLASS_INPUT_OUTPUT,
 | |
|                               xnestUpstreamInfo.screenInfo->root_visual,
 | |
|                               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;
 | |
| }
 |