Screen.c (14268B)
1 /* 2 3 Copyright 1993 by Davor Matic 4 5 Permission to use, copy, modify, distribute, and sell this software 6 and its documentation for any purpose is hereby granted without fee, 7 provided that the above copyright notice appear in all copies and that 8 both that copyright notice and this permission notice appear in 9 supporting documentation. Davor Matic makes no representations about 10 the suitability of this software for any purpose. It is provided "as 11 is" 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 45 Window xnestDefaultWindows[MAXSCREENS]; 46 Window xnestScreenSaverWindows[MAXSCREENS]; 47 DevPrivateKeyRec xnestCursorScreenKeyRec; 48 49 ScreenPtr 50 xnestScreen(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 61 static int 62 offset(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 72 static Bool 73 xnestSaveScreen(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 104 static Bool 105 xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 106 { 107 return FALSE; 108 } 109 110 static void 111 xnestCrossScreen(ScreenPtr pScreen, Bool entering) 112 { 113 } 114 115 static miPointerScreenFuncRec xnestPointerCursorFuncs = { 116 xnestCursorOffScreen, 117 xnestCrossScreen, 118 miPointerWarpCursor 119 }; 120 121 static miPointerSpriteFuncRec xnestPointerSpriteFuncs = { 122 xnestRealizeCursor, 123 xnestUnrealizeCursor, 124 xnestSetCursor, 125 xnestMoveCursor, 126 xnestDeviceCursorInitialize, 127 xnestDeviceCursorCleanup 128 }; 129 130 Bool 131 xnestOpenScreen(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 /* defaultStipple */ 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 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 pScreen->ModifyPixmapHeader = xnestModifyPixmapHeader; 285 286 /* Font procedures */ 287 288 pScreen->RealizeFont = xnestRealizeFont; 289 pScreen->UnrealizeFont = xnestUnrealizeFont; 290 291 /* GC procedures */ 292 293 pScreen->CreateGC = xnestCreateGC; 294 295 /* Colormap procedures */ 296 297 pScreen->CreateColormap = xnestCreateColormap; 298 pScreen->DestroyColormap = xnestDestroyColormap; 299 pScreen->InstallColormap = xnestInstallColormap; 300 pScreen->UninstallColormap = xnestUninstallColormap; 301 pScreen->ListInstalledColormaps = xnestListInstalledColormaps; 302 pScreen->StoreColors = xnestStoreColors; 303 pScreen->ResolveColor = xnestResolveColor; 304 305 pScreen->BitmapToRegion = xnestPixmapToRegion; 306 307 /* OS layer procedures */ 308 309 pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA; 310 pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA; 311 312 miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */ 313 PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); 314 xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs; 315 dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey, 316 &xnestCursorFuncs); 317 PointPriv->spriteFuncs = &xnestPointerSpriteFuncs; 318 319 pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay, 320 DefaultScreen(xnestDisplay)) 321 / DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay)); 322 pScreen->mmHeight = 323 xnestHeight * DisplayHeightMM(xnestDisplay, 324 DefaultScreen(xnestDisplay)) / 325 DisplayHeight(xnestDisplay, 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 = 346 xnestDefaultVisualColormap(xnestDefaultVisual(pScreen)); 347 348 if (xnestParentWindow != 0) { 349 xnestDefaultWindows[pScreen->myNum] = xnestParentWindow; 350 XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum], 351 xnestEventMask); 352 } 353 else 354 xnestDefaultWindows[pScreen->myNum] = 355 XCreateWindow(xnestDisplay, 356 DefaultRootWindow(xnestDisplay), 357 xnestX + POSITION_OFFSET, 358 xnestY + POSITION_OFFSET, 359 xnestWidth, xnestHeight, 360 xnestBorderWidth, 361 pScreen->rootDepth, 362 InputOutput, 363 xnestDefaultVisual(pScreen), 364 valuemask, &attributes); 365 366 if (!xnestWindowName) 367 xnestWindowName = argv[0]; 368 369 sizeHints.flags = PPosition | PSize | PMaxSize; 370 sizeHints.x = xnestX + POSITION_OFFSET; 371 sizeHints.y = xnestY + POSITION_OFFSET; 372 sizeHints.width = sizeHints.max_width = xnestWidth; 373 sizeHints.height = sizeHints.max_height = xnestHeight; 374 if (xnestUserGeometry & XValue || xnestUserGeometry & YValue) 375 sizeHints.flags |= USPosition; 376 if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue) 377 sizeHints.flags |= USSize; 378 XSetStandardProperties(xnestDisplay, 379 xnestDefaultWindows[pScreen->myNum], 380 xnestWindowName, 381 xnestWindowName, 382 xnestIconBitmap, 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, 395 DefaultScreen(xnestDisplay)), 396 InputOutput, DefaultVisual(xnestDisplay, 397 DefaultScreen 398 (xnestDisplay)), valuemask, 399 &attributes); 400 } 401 402 if (!xnestCreateDefaultColormap(pScreen)) 403 return False; 404 405 return True; 406 } 407 408 Bool 409 xnestCloseScreen(ScreenPtr pScreen) 410 { 411 int i; 412 413 for (i = 0; i < pScreen->numDepths; i++) 414 free(pScreen->allowedDepths[i].vids); 415 free(pScreen->allowedDepths); 416 free(pScreen->visuals); 417 free(pScreen->devPrivate); 418 419 /* 420 If xnestDoFullGeneration all x resources will be destroyed upon closing 421 the display connection. There is no need to generate extra protocol. 422 */ 423 424 return True; 425 }