Screen.c revision 706f2543
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(&xnestColormapPrivateKeyRec, PRIVATE_COLORMAP, sizeof (xnestPrivColormap))) 155 return FALSE; 156 if (!dixRegisterPrivateKey(&xnestCursorScreenKeyRec, PRIVATE_SCREEN, 0)) 157 return FALSE; 158 159 visuals = (VisualPtr)malloc(xnestNumVisuals * sizeof(VisualRec)); 160 numVisuals = 0; 161 162 depths = (DepthPtr)malloc(MAXDEPTH * sizeof(DepthRec)); 163 depths[0].depth = 1; 164 depths[0].numVids = 0; 165 depths[0].vids = (VisualID *)malloc(MAXVISUALSPERDEPTH * sizeof(VisualID)); 166 numDepths = 1; 167 168 for (i = 0; i < xnestNumVisuals; i++) { 169 visuals[numVisuals].class = xnestVisuals[i].class; 170 visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb; 171 visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size; 172 visuals[numVisuals].nplanes = xnestVisuals[i].depth; 173 visuals[numVisuals].redMask = xnestVisuals[i].red_mask; 174 visuals[numVisuals].greenMask = xnestVisuals[i].green_mask; 175 visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask; 176 visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask); 177 visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask); 178 visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask); 179 180 /* Check for and remove duplicates. */ 181 for (j = 0; j < numVisuals; j++) { 182 if (visuals[numVisuals].class == visuals[j].class && 183 visuals[numVisuals].bitsPerRGBValue == visuals[j].bitsPerRGBValue && 184 visuals[numVisuals].ColormapEntries == visuals[j].ColormapEntries && 185 visuals[numVisuals].nplanes == visuals[j].nplanes && 186 visuals[numVisuals].redMask == visuals[j].redMask && 187 visuals[numVisuals].greenMask == visuals[j].greenMask && 188 visuals[numVisuals].blueMask == visuals[j].blueMask && 189 visuals[numVisuals].offsetRed == visuals[j].offsetRed && 190 visuals[numVisuals].offsetGreen == visuals[j].offsetGreen && 191 visuals[numVisuals].offsetBlue == visuals[j].offsetBlue) 192 break; 193 } 194 if (j < numVisuals) 195 break; 196 197 visuals[numVisuals].vid = FakeClientID(0); 198 199 depthIndex = UNDEFINED; 200 for (j = 0; j < numDepths; j++) 201 if (depths[j].depth == xnestVisuals[i].depth) { 202 depthIndex = j; 203 break; 204 } 205 206 if (depthIndex == UNDEFINED) { 207 depthIndex = numDepths; 208 depths[depthIndex].depth = xnestVisuals[i].depth; 209 depths[depthIndex].numVids = 0; 210 depths[depthIndex].vids = 211 (VisualID *)malloc(MAXVISUALSPERDEPTH * sizeof(VisualID)); 212 numDepths++; 213 } 214 if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) { 215 FatalError("Visual table overflow"); 216 } 217 depths[depthIndex].vids[depths[depthIndex].numVids] = 218 visuals[numVisuals].vid; 219 depths[depthIndex].numVids++; 220 221 numVisuals++; 222 } 223 visuals = (VisualPtr)realloc(visuals, numVisuals * sizeof(VisualRec)); 224 225 defaultVisual = visuals[xnestDefaultVisualIndex].vid; 226 rootDepth = visuals[xnestDefaultVisualIndex].nplanes; 227 228 if (xnestParentWindow != 0) { 229 XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes); 230 xnestWidth = gattributes.width; 231 xnestHeight = gattributes.height; 232 } 233 234 /* myNum */ 235 /* id */ 236 miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth, 237 rootDepth, 238 numDepths, depths, 239 defaultVisual, /* root visual */ 240 numVisuals, visuals); 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