Screen.c revision 35c4bbdf
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 "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 45Window xnestDefaultWindows[MAXSCREENS]; 46Window xnestScreenSaverWindows[MAXSCREENS]; 47DevPrivateKeyRec xnestCursorScreenKeyRec; 48 49ScreenPtr 50xnestScreen(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 61static int 62offset(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 72static Bool 73xnestSaveScreen(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 104static Bool 105xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 106{ 107 return FALSE; 108} 109 110static void 111xnestCrossScreen(ScreenPtr pScreen, Bool entering) 112{ 113} 114 115static miPointerScreenFuncRec xnestPointerCursorFuncs = { 116 xnestCursorOffScreen, 117 xnestCrossScreen, 118 miPointerWarpCursor 119}; 120 121static miPointerSpriteFuncRec xnestPointerSpriteFuncs = { 122 xnestRealizeCursor, 123 xnestUnrealizeCursor, 124 xnestSetCursor, 125 xnestMoveCursor, 126 xnestDeviceCursorInitialize, 127 xnestDeviceCursorCleanup 128}; 129 130Bool 131xnestOpenScreen(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 /* PixmapPerDepth */ 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 pScreen->SourceValidate = NULL; 267 268 /* Window Procedures */ 269 270 pScreen->CreateWindow = xnestCreateWindow; 271 pScreen->DestroyWindow = xnestDestroyWindow; 272 pScreen->PositionWindow = xnestPositionWindow; 273 pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes; 274 pScreen->RealizeWindow = xnestRealizeWindow; 275 pScreen->UnrealizeWindow = xnestUnrealizeWindow; 276 pScreen->PostValidateTree = NULL; 277 pScreen->WindowExposures = xnestWindowExposures; 278 pScreen->CopyWindow = xnestCopyWindow; 279 pScreen->ClipNotify = xnestClipNotify; 280 281 /* Pixmap procedures */ 282 283 pScreen->CreatePixmap = xnestCreatePixmap; 284 pScreen->DestroyPixmap = xnestDestroyPixmap; 285 pScreen->ModifyPixmapHeader = xnestModifyPixmapHeader; 286 287 /* Font procedures */ 288 289 pScreen->RealizeFont = xnestRealizeFont; 290 pScreen->UnrealizeFont = xnestUnrealizeFont; 291 292 /* GC procedures */ 293 294 pScreen->CreateGC = xnestCreateGC; 295 296 /* Colormap procedures */ 297 298 pScreen->CreateColormap = xnestCreateColormap; 299 pScreen->DestroyColormap = xnestDestroyColormap; 300 pScreen->InstallColormap = xnestInstallColormap; 301 pScreen->UninstallColormap = xnestUninstallColormap; 302 pScreen->ListInstalledColormaps = xnestListInstalledColormaps; 303 pScreen->StoreColors = xnestStoreColors; 304 pScreen->ResolveColor = xnestResolveColor; 305 306 pScreen->BitmapToRegion = xnestPixmapToRegion; 307 308 /* OS layer procedures */ 309 310 pScreen->BlockHandler = (ScreenBlockHandlerProcPtr) NoopDDA; 311 pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr) NoopDDA; 312 313 miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */ 314 PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); 315 xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs; 316 dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey, 317 &xnestCursorFuncs); 318 PointPriv->spriteFuncs = &xnestPointerSpriteFuncs; 319 320 pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay, 321 DefaultScreen(xnestDisplay)) 322 / DisplayWidth(xnestDisplay, DefaultScreen(xnestDisplay)); 323 pScreen->mmHeight = 324 xnestHeight * DisplayHeightMM(xnestDisplay, 325 DefaultScreen(xnestDisplay)) / 326 DisplayHeight(xnestDisplay, 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 = 347 xnestDefaultVisualColormap(xnestDefaultVisual(pScreen)); 348 349 if (xnestParentWindow != 0) { 350 xnestDefaultWindows[pScreen->myNum] = xnestParentWindow; 351 XSelectInput(xnestDisplay, xnestDefaultWindows[pScreen->myNum], 352 xnestEventMask); 353 } 354 else 355 xnestDefaultWindows[pScreen->myNum] = 356 XCreateWindow(xnestDisplay, 357 DefaultRootWindow(xnestDisplay), 358 xnestX + POSITION_OFFSET, 359 xnestY + POSITION_OFFSET, 360 xnestWidth, xnestHeight, 361 xnestBorderWidth, 362 pScreen->rootDepth, 363 InputOutput, 364 xnestDefaultVisual(pScreen), 365 valuemask, &attributes); 366 367 if (!xnestWindowName) 368 xnestWindowName = argv[0]; 369 370 sizeHints.flags = PPosition | PSize | PMaxSize; 371 sizeHints.x = xnestX + POSITION_OFFSET; 372 sizeHints.y = xnestY + POSITION_OFFSET; 373 sizeHints.width = sizeHints.max_width = xnestWidth; 374 sizeHints.height = sizeHints.max_height = xnestHeight; 375 if (xnestUserGeometry & XValue || xnestUserGeometry & YValue) 376 sizeHints.flags |= USPosition; 377 if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue) 378 sizeHints.flags |= USSize; 379 XSetStandardProperties(xnestDisplay, 380 xnestDefaultWindows[pScreen->myNum], 381 xnestWindowName, 382 xnestWindowName, 383 xnestIconBitmap, argv, argc, &sizeHints); 384 385 XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]); 386 387 valuemask = CWBackPixmap | CWColormap; 388 attributes.background_pixmap = xnestScreenSaverPixmap; 389 attributes.colormap = 390 DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay)); 391 xnestScreenSaverWindows[pScreen->myNum] = 392 XCreateWindow(xnestDisplay, 393 xnestDefaultWindows[pScreen->myNum], 394 0, 0, xnestWidth, xnestHeight, 0, 395 DefaultDepth(xnestDisplay, 396 DefaultScreen(xnestDisplay)), 397 InputOutput, DefaultVisual(xnestDisplay, 398 DefaultScreen 399 (xnestDisplay)), valuemask, 400 &attributes); 401 } 402 403 if (!xnestCreateDefaultColormap(pScreen)) 404 return False; 405 406 return True; 407} 408 409Bool 410xnestCloseScreen(ScreenPtr pScreen) 411{ 412 int i; 413 414 for (i = 0; i < pScreen->numDepths; i++) 415 free(pScreen->allowedDepths[i].vids); 416 free(pScreen->allowedDepths); 417 free(pScreen->visuals); 418 free(pScreen->devPrivate); 419 420 /* 421 If xnestDoFullGeneration all x resources will be destroyed upon closing 422 the display connection. There is no need to generate extra protocol. 423 */ 424 425 return True; 426} 427