Screen.c revision 05b261ec
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 45Window xnestDefaultWindows[MAXSCREENS]; 46Window xnestScreenSaverWindows[MAXSCREENS]; 47 48#ifdef GLXEXT 49extern void GlxWrapInitVisuals(miInitVisualsProcPtr *); 50#endif 51 52static int xnestScreenGeneration = -1; 53 54ScreenPtr 55xnestScreen(Window window) 56{ 57 int i; 58 59 for (i = 0; i < xnestNumScreens; i++) 60 if (xnestDefaultWindows[i] == window) 61 return screenInfo.screens[i]; 62 63 return NULL; 64} 65 66static int 67offset(unsigned long mask) 68{ 69 int count; 70 71 for (count = 0; !(mask & 1) && count < 32; count++) 72 mask >>= 1; 73 74 return count; 75} 76 77static Bool 78xnestSaveScreen(ScreenPtr pScreen, int what) 79{ 80 if (xnestSoftwareScreenSaver) 81 return False; 82 else { 83 switch (what) { 84 case SCREEN_SAVER_ON: 85 XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 86 xnestSetScreenSaverColormapWindow(pScreen); 87 break; 88 89 case SCREEN_SAVER_OFF: 90 XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 91 xnestSetInstalledColormapWindows(pScreen); 92 break; 93 94 case SCREEN_SAVER_FORCER: 95 lastEventTime = GetTimeInMillis(); 96 XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 97 xnestSetInstalledColormapWindows(pScreen); 98 break; 99 100 case SCREEN_SAVER_CYCLE: 101 XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 102 xnestSetInstalledColormapWindows(pScreen); 103 break; 104 } 105 return True; 106 } 107} 108 109static Bool 110xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 111{ 112 return FALSE; 113} 114 115static void 116xnestCrossScreen(ScreenPtr pScreen, Bool entering) 117{ 118} 119 120static miPointerScreenFuncRec xnestPointerCursorFuncs = 121{ 122 xnestCursorOffScreen, 123 xnestCrossScreen, 124 miPointerWarpCursor 125}; 126 127static miPointerSpriteFuncRec xnestPointerSpriteFuncs = 128{ 129 xnestRealizeCursor, 130 xnestUnrealizeCursor, 131 xnestSetCursor, 132 xnestMoveCursor, 133}; 134 135Bool 136xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[]) 137{ 138 VisualPtr visuals; 139 DepthPtr depths; 140 int numVisuals, numDepths; 141 int i, j, depthIndex; 142 unsigned long valuemask; 143 XSetWindowAttributes attributes; 144 XWindowAttributes gattributes; 145 XSizeHints sizeHints; 146 VisualID defaultVisual; 147 int rootDepth; 148 149 if (!(AllocateWindowPrivate(pScreen, xnestWindowPrivateIndex, 150 sizeof(xnestPrivWin)) && 151 AllocateGCPrivate(pScreen, xnestGCPrivateIndex, 152 sizeof(xnestPrivGC)))) 153 return False; 154 155 if (xnestScreenGeneration != serverGeneration) { 156 if ((xnestPixmapPrivateIndex = AllocatePixmapPrivateIndex()) < 0) 157 return False; 158 xnestScreenGeneration = serverGeneration; 159 } 160 161 if (!AllocatePixmapPrivate(pScreen,xnestPixmapPrivateIndex, 162 sizeof (xnestPrivPixmap))) 163 return False; 164 visuals = (VisualPtr)xalloc(xnestNumVisuals * sizeof(VisualRec)); 165 numVisuals = 0; 166 167 depths = (DepthPtr)xalloc(MAXDEPTH * sizeof(DepthRec)); 168 depths[0].depth = 1; 169 depths[0].numVids = 0; 170 depths[0].vids = (VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID)); 171 numDepths = 1; 172 173 for (i = 0; i < xnestNumVisuals; i++) { 174 visuals[numVisuals].class = xnestVisuals[i].class; 175 visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb; 176 visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size; 177 visuals[numVisuals].nplanes = xnestVisuals[i].depth; 178 visuals[numVisuals].redMask = xnestVisuals[i].red_mask; 179 visuals[numVisuals].greenMask = xnestVisuals[i].green_mask; 180 visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask; 181 visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask); 182 visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask); 183 visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask); 184 185 /* Check for and remove duplicates. */ 186 for (j = 0; j < numVisuals; j++) { 187 if (visuals[numVisuals].class == visuals[j].class && 188 visuals[numVisuals].bitsPerRGBValue == visuals[j].bitsPerRGBValue && 189 visuals[numVisuals].ColormapEntries == visuals[j].ColormapEntries && 190 visuals[numVisuals].nplanes == visuals[j].nplanes && 191 visuals[numVisuals].redMask == visuals[j].redMask && 192 visuals[numVisuals].greenMask == visuals[j].greenMask && 193 visuals[numVisuals].blueMask == visuals[j].blueMask && 194 visuals[numVisuals].offsetRed == visuals[j].offsetRed && 195 visuals[numVisuals].offsetGreen == visuals[j].offsetGreen && 196 visuals[numVisuals].offsetBlue == visuals[j].offsetBlue) 197 break; 198 } 199 if (j < numVisuals) 200 break; 201 202 visuals[numVisuals].vid = FakeClientID(0); 203 204 depthIndex = UNDEFINED; 205 for (j = 0; j < numDepths; j++) 206 if (depths[j].depth == xnestVisuals[i].depth) { 207 depthIndex = j; 208 break; 209 } 210 211 if (depthIndex == UNDEFINED) { 212 depthIndex = numDepths; 213 depths[depthIndex].depth = xnestVisuals[i].depth; 214 depths[depthIndex].numVids = 0; 215 depths[depthIndex].vids = 216 (VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID)); 217 numDepths++; 218 } 219 if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) { 220 FatalError("Visual table overflow"); 221 } 222 depths[depthIndex].vids[depths[depthIndex].numVids] = 223 visuals[numVisuals].vid; 224 depths[depthIndex].numVids++; 225 226 numVisuals++; 227 } 228 visuals = (VisualPtr)xrealloc(visuals, numVisuals * sizeof(VisualRec)); 229 230 defaultVisual = visuals[xnestDefaultVisualIndex].vid; 231 rootDepth = visuals[xnestDefaultVisualIndex].nplanes; 232 233#ifdef GLXEXT 234 { 235 miInitVisualsProcPtr proc = NULL; 236 237 GlxWrapInitVisuals(&proc); 238 /* GlxInitVisuals ignores the last three arguments. */ 239 proc(&visuals, &depths, &numVisuals, &numDepths, 240 &rootDepth, &defaultVisual, 0, 0, 0); 241 } 242#endif 243 244 if (xnestParentWindow != 0) { 245 XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes); 246 xnestWidth = gattributes.width; 247 xnestHeight = gattributes.height; 248 } 249 250 /* myNum */ 251 /* id */ 252 miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth, 253 rootDepth, 254 numDepths, depths, 255 defaultVisual, /* root visual */ 256 numVisuals, visuals); 257 258/* miInitializeBackingStore(pScreen); */ 259 260 pScreen->defColormap = (Colormap) FakeClientID(0); 261 pScreen->minInstalledCmaps = MINCMAPS; 262 pScreen->maxInstalledCmaps = MAXCMAPS; 263 pScreen->backingStoreSupport = NotUseful; 264 pScreen->saveUnderSupport = NotUseful; 265 pScreen->whitePixel = xnestWhitePixel; 266 pScreen->blackPixel = xnestBlackPixel; 267 /* rgf */ 268 /* GCperDepth */ 269 /* PixmapPerDepth */ 270 pScreen->devPrivate = NULL; 271 /* WindowPrivateLen */ 272 /* WindowPrivateSizes */ 273 /* totalWindowSize */ 274 /* GCPrivateLen */ 275 /* GCPrivateSizes */ 276 /* totalGCSize */ 277 278 /* Random screen procedures */ 279 280 pScreen->QueryBestSize = xnestQueryBestSize; 281 pScreen->SaveScreen = xnestSaveScreen; 282 pScreen->GetImage = xnestGetImage; 283 pScreen->GetSpans = xnestGetSpans; 284 pScreen->PointerNonInterestBox = NULL; 285 pScreen->SourceValidate = NULL; 286 287 /* Window Procedures */ 288 289 pScreen->CreateWindow = xnestCreateWindow; 290 pScreen->DestroyWindow = xnestDestroyWindow; 291 pScreen->PositionWindow = xnestPositionWindow; 292 pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes; 293 pScreen->RealizeWindow = xnestRealizeWindow; 294 pScreen->UnrealizeWindow = xnestUnrealizeWindow; 295 pScreen->PostValidateTree = NULL; 296 pScreen->WindowExposures = xnestWindowExposures; 297 pScreen->PaintWindowBackground = xnestPaintWindowBackground; 298 pScreen->PaintWindowBorder = xnestPaintWindowBorder; 299 pScreen->CopyWindow = xnestCopyWindow; 300 pScreen->ClipNotify = xnestClipNotify; 301 302 /* Pixmap procedures */ 303 304 pScreen->CreatePixmap = xnestCreatePixmap; 305 pScreen->DestroyPixmap = xnestDestroyPixmap; 306 307 /* Backing store procedures */ 308 309 pScreen->SaveDoomedAreas = NULL; 310 pScreen->RestoreAreas = NULL; 311 pScreen->ExposeCopy = NULL; 312 pScreen->TranslateBackingStore = NULL; 313 pScreen->ClearBackingStore = NULL; 314 pScreen->DrawGuarantee = NULL; 315 316 /* Font procedures */ 317 318 pScreen->RealizeFont = xnestRealizeFont; 319 pScreen->UnrealizeFont = xnestUnrealizeFont; 320 321 /* GC procedures */ 322 323 pScreen->CreateGC = xnestCreateGC; 324 325 /* Colormap procedures */ 326 327 pScreen->CreateColormap = xnestCreateColormap; 328 pScreen->DestroyColormap = xnestDestroyColormap; 329 pScreen->InstallColormap = xnestInstallColormap; 330 pScreen->UninstallColormap = xnestUninstallColormap; 331 pScreen->ListInstalledColormaps = xnestListInstalledColormaps; 332 pScreen->StoreColors = xnestStoreColors; 333 pScreen->ResolveColor = xnestResolveColor; 334 335 pScreen->BitmapToRegion = xnestPixmapToRegion; 336 337 /* OS layer procedures */ 338 339 pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA; 340 pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA; 341 pScreen->blockData = NULL; 342 pScreen->wakeupData = NULL; 343 344 miPointerInitialize (pScreen, &xnestPointerSpriteFuncs, 345 &xnestPointerCursorFuncs, True); 346 347 pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay, 348 DefaultScreen(xnestDisplay)) / 349 DisplayWidth(xnestDisplay, 350 DefaultScreen(xnestDisplay)); 351 pScreen->mmHeight = xnestHeight * DisplayHeightMM(xnestDisplay, 352 DefaultScreen(xnestDisplay)) / 353 DisplayHeight(xnestDisplay, 354 DefaultScreen(xnestDisplay)); 355 356 /* overwrite miCloseScreen with our own */ 357 pScreen->CloseScreen = xnestCloseScreen; 358 359 if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL)) 360 return FALSE; 361 362#ifdef SHAPE 363 /* overwrite miSetShape with our own */ 364 pScreen->SetShape = xnestSetShape; 365#endif /* SHAPE */ 366 367 /* devPrivates */ 368 369#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32) 370 371 if (xnestDoFullGeneration) { 372 373 valuemask = CWBackPixel | CWEventMask | CWColormap; 374 attributes.background_pixel = xnestWhitePixel; 375 attributes.event_mask = xnestEventMask; 376 attributes.colormap = xnestDefaultVisualColormap(xnestDefaultVisual(pScreen)); 377 378 if (xnestParentWindow != 0) { 379 xnestDefaultWindows[pScreen->myNum] = xnestParentWindow; 380 XSelectInput (xnestDisplay, xnestDefaultWindows[pScreen->myNum], 381 xnestEventMask); 382 } else 383 xnestDefaultWindows[pScreen->myNum] = 384 XCreateWindow(xnestDisplay, 385 DefaultRootWindow(xnestDisplay), 386 xnestX + POSITION_OFFSET, 387 xnestY + POSITION_OFFSET, 388 xnestWidth, xnestHeight, 389 xnestBorderWidth, 390 pScreen->rootDepth, 391 InputOutput, 392 xnestDefaultVisual(pScreen), 393 valuemask, &attributes); 394 395 if (!xnestWindowName) 396 xnestWindowName = argv[0]; 397 398 sizeHints.flags = PPosition | PSize | PMaxSize; 399 sizeHints.x = xnestX + POSITION_OFFSET; 400 sizeHints.y = xnestY + POSITION_OFFSET; 401 sizeHints.width = sizeHints.max_width = xnestWidth; 402 sizeHints.height = sizeHints.max_height = xnestHeight; 403 if (xnestUserGeometry & XValue || xnestUserGeometry & YValue) 404 sizeHints.flags |= USPosition; 405 if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue) 406 sizeHints.flags |= USSize; 407 XSetStandardProperties(xnestDisplay, 408 xnestDefaultWindows[pScreen->myNum], 409 xnestWindowName, 410 xnestWindowName, 411 xnestIconBitmap, 412 argv, argc, &sizeHints); 413 414 XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]); 415 416 valuemask = CWBackPixmap | CWColormap; 417 attributes.background_pixmap = xnestScreenSaverPixmap; 418 attributes.colormap = 419 DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay)); 420 xnestScreenSaverWindows[pScreen->myNum] = 421 XCreateWindow(xnestDisplay, 422 xnestDefaultWindows[pScreen->myNum], 423 0, 0, xnestWidth, xnestHeight, 0, 424 DefaultDepth(xnestDisplay, DefaultScreen(xnestDisplay)), 425 InputOutput, 426 DefaultVisual(xnestDisplay, DefaultScreen(xnestDisplay)), 427 valuemask, &attributes); 428 } 429 430 if (!xnestCreateDefaultColormap(pScreen)) return False; 431 432 return True; 433} 434 435Bool 436xnestCloseScreen(int index, ScreenPtr pScreen) 437{ 438 int i; 439 440 for (i = 0; i < pScreen->numDepths; i++) 441 xfree(pScreen->allowedDepths[i].vids); 442 xfree(pScreen->allowedDepths); 443 xfree(pScreen->visuals); 444 xfree(pScreen->devPrivate); 445 446 /* 447 If xnestDoFullGeneration all x resources will be destroyed upon closing 448 the display connection. There is no need to generate extra protocol. 449 */ 450 451 return True; 452} 453