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