compinit.c revision 4642e01f
1/* 2 * Copyright © 2006 Sun Microsystems 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Sun Microsystems not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Sun Microsystems makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 * 22 * Copyright © 2003 Keith Packard 23 * 24 * Permission to use, copy, modify, distribute, and sell this software and its 25 * documentation for any purpose is hereby granted without fee, provided that 26 * the above copyright notice appear in all copies and that both that 27 * copyright notice and this permission notice appear in supporting 28 * documentation, and that the name of Keith Packard not be used in 29 * advertising or publicity pertaining to distribution of the software without 30 * specific, written prior permission. Keith Packard makes no 31 * representations about the suitability of this software for any purpose. It 32 * is provided "as is" without express or implied warranty. 33 * 34 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 35 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 36 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 37 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 38 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 39 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 40 * PERFORMANCE OF THIS SOFTWARE. 41 */ 42 43#ifdef HAVE_DIX_CONFIG_H 44#include <dix-config.h> 45#endif 46 47#include "compint.h" 48 49static int CompScreenPrivateKeyIndex; 50DevPrivateKey CompScreenPrivateKey = &CompScreenPrivateKeyIndex; 51static int CompWindowPrivateKeyIndex; 52DevPrivateKey CompWindowPrivateKey = &CompWindowPrivateKeyIndex; 53static int CompSubwindowsPrivateKeyIndex; 54DevPrivateKey CompSubwindowsPrivateKey = &CompSubwindowsPrivateKeyIndex; 55 56 57static Bool 58compCloseScreen (int index, ScreenPtr pScreen) 59{ 60 CompScreenPtr cs = GetCompScreen (pScreen); 61 Bool ret; 62 63 xfree (cs->alternateVisuals); 64 65 pScreen->CloseScreen = cs->CloseScreen; 66 pScreen->BlockHandler = cs->BlockHandler; 67 pScreen->InstallColormap = cs->InstallColormap; 68 pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; 69 pScreen->ReparentWindow = cs->ReparentWindow; 70 pScreen->MoveWindow = cs->MoveWindow; 71 pScreen->ResizeWindow = cs->ResizeWindow; 72 pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; 73 74 pScreen->ClipNotify = cs->ClipNotify; 75 pScreen->UnrealizeWindow = cs->UnrealizeWindow; 76 pScreen->RealizeWindow = cs->RealizeWindow; 77 pScreen->DestroyWindow = cs->DestroyWindow; 78 pScreen->CreateWindow = cs->CreateWindow; 79 pScreen->CopyWindow = cs->CopyWindow; 80 pScreen->PositionWindow = cs->PositionWindow; 81 82 xfree (cs); 83 dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL); 84 ret = (*pScreen->CloseScreen) (index, pScreen); 85 86 return ret; 87} 88 89static void 90compInstallColormap (ColormapPtr pColormap) 91{ 92 VisualPtr pVisual = pColormap->pVisual; 93 ScreenPtr pScreen = pColormap->pScreen; 94 CompScreenPtr cs = GetCompScreen (pScreen); 95 int a; 96 97 for (a = 0; a < cs->numAlternateVisuals; a++) 98 if (pVisual->vid == cs->alternateVisuals[a]) 99 return; 100 pScreen->InstallColormap = cs->InstallColormap; 101 (*pScreen->InstallColormap) (pColormap); 102 cs->InstallColormap = pScreen->InstallColormap; 103 pScreen->InstallColormap = compInstallColormap; 104} 105 106/* Fake backing store via automatic redirection */ 107static Bool 108compChangeWindowAttributes(WindowPtr pWin, unsigned long mask) 109{ 110 ScreenPtr pScreen = pWin->drawable.pScreen; 111 CompScreenPtr cs = GetCompScreen (pScreen); 112 Bool ret; 113 114 pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; 115 ret = pScreen->ChangeWindowAttributes(pWin, mask); 116 117 if (ret && (mask & CWBackingStore) && 118 pScreen->backingStoreSupport != NotUseful) { 119 if (pWin->backingStore != NotUseful) { 120 compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); 121 pWin->backStorage = (pointer) (intptr_t) 1; 122 } else { 123 compUnredirectWindow(serverClient, pWin, 124 CompositeRedirectAutomatic); 125 pWin->backStorage = NULL; 126 } 127 } 128 129 pScreen->ChangeWindowAttributes = compChangeWindowAttributes; 130 131 return ret; 132} 133 134static void 135compScreenUpdate (ScreenPtr pScreen) 136{ 137 CompScreenPtr cs = GetCompScreen (pScreen); 138 139 compCheckTree (pScreen); 140 if (cs->damaged) 141 { 142 compWindowUpdate (WindowTable[pScreen->myNum]); 143 cs->damaged = FALSE; 144 } 145} 146 147static void 148compBlockHandler (int i, 149 pointer blockData, 150 pointer pTimeout, 151 pointer pReadmask) 152{ 153 ScreenPtr pScreen = screenInfo.screens[i]; 154 CompScreenPtr cs = GetCompScreen (pScreen); 155 156 pScreen->BlockHandler = cs->BlockHandler; 157 compScreenUpdate (pScreen); 158 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 159 cs->BlockHandler = pScreen->BlockHandler; 160 pScreen->BlockHandler = compBlockHandler; 161} 162 163/* 164 * Add alternate visuals -- always expose an ARGB32 and RGB24 visual 165 */ 166 167static DepthPtr 168compFindVisuallessDepth (ScreenPtr pScreen, int d) 169{ 170 int i; 171 172 for (i = 0; i < pScreen->numDepths; i++) 173 { 174 DepthPtr depth = &pScreen->allowedDepths[i]; 175 if (depth->depth == d) 176 { 177 /* 178 * Make sure it doesn't have visuals already 179 */ 180 if (depth->numVids) 181 return 0; 182 /* 183 * looks fine 184 */ 185 return depth; 186 } 187 } 188 /* 189 * If there isn't one, then it's gonna be hard to have 190 * an associated visual 191 */ 192 return 0; 193} 194 195/* 196 * Add a list of visual IDs to the list of visuals to implicitly redirect. 197 */ 198static Bool 199compRegisterAlternateVisuals (CompScreenPtr cs, VisualID *vids, int nVisuals) 200{ 201 VisualID *p; 202 203 p = xrealloc(cs->alternateVisuals, 204 sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals)); 205 if(p == NULL) 206 return FALSE; 207 208 memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals); 209 210 cs->alternateVisuals = p; 211 cs->numAlternateVisuals += nVisuals; 212 213 return TRUE; 214} 215 216_X_EXPORT 217Bool CompositeRegisterAlternateVisuals (ScreenPtr pScreen, VisualID *vids, 218 int nVisuals) 219{ 220 CompScreenPtr cs = GetCompScreen (pScreen); 221 return compRegisterAlternateVisuals(cs, vids, nVisuals); 222} 223 224typedef struct _alternateVisual { 225 int depth; 226 CARD32 format; 227} CompAlternateVisual; 228 229static CompAlternateVisual altVisuals[] = { 230#if COMP_INCLUDE_RGB24_VISUAL 231 { 24, PICT_r8g8b8 }, 232#endif 233 { 32, PICT_a8r8g8b8 }, 234}; 235 236static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) / 237 sizeof(CompAlternateVisual); 238 239static Bool 240compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs, 241 CompAlternateVisual *alt) 242{ 243 VisualPtr visual, visuals; 244 int i; 245 int numVisuals; 246 XID *installedCmaps; 247 ColormapPtr installedCmap; 248 int numInstalledCmaps; 249 DepthPtr depth; 250 PictFormatPtr pPictFormat; 251 VisualID *vid; 252 unsigned long alphaMask; 253 254 /* 255 * The ARGB32 visual is always available. Other alternate depth visuals 256 * are only provided if their depth is less than the root window depth. 257 * There's no deep reason for this. 258 */ 259 if (alt->depth >= pScreen->rootDepth && alt->depth != 32) 260 return FALSE; 261 262 depth = compFindVisuallessDepth (pScreen, alt->depth); 263 if (!depth) 264 /* alt->depth doesn't exist or already has alternate visuals. */ 265 return TRUE; 266 267 pPictFormat = PictureMatchFormat (pScreen, alt->depth, alt->format); 268 if (!pPictFormat) 269 return FALSE; 270 271 vid = xalloc(sizeof(VisualID)); 272 if (!vid) 273 return FALSE; 274 275 /* Find the installed colormaps */ 276 installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID)); 277 if (!installedCmaps) { 278 xfree(vid); 279 return FALSE; 280 } 281 numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen, 282 installedCmaps); 283 284 /* realloc the visual array to fit the new one in place */ 285 numVisuals = pScreen->numVisuals; 286 visuals = xrealloc(pScreen->visuals, (numVisuals + 1) * sizeof(VisualRec)); 287 if (!visuals) { 288 xfree(vid); 289 xfree(installedCmaps); 290 return FALSE; 291 } 292 293 /* 294 * Fix up any existing installed colormaps -- we'll assume that 295 * the only ones created so far have been installed. If this 296 * isn't true, we'll have to walk the resource database looking 297 * for all colormaps. 298 */ 299 for (i = 0; i < numInstalledCmaps; i++) { 300 int j; 301 302 installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP); 303 if (!installedCmap) 304 continue; 305 j = installedCmap->pVisual - pScreen->visuals; 306 installedCmap->pVisual = &visuals[j]; 307 } 308 309 xfree(installedCmaps); 310 311 pScreen->visuals = visuals; 312 visual = visuals + pScreen->numVisuals; /* the new one */ 313 pScreen->numVisuals++; 314 315 /* Initialize the visual */ 316 visual->vid = FakeClientID (0); 317 visual->bitsPerRGBValue = 8; 318 if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) { 319 visual->class = PseudoColor; 320 visual->nplanes = PICT_FORMAT_BPP(alt->format); 321 visual->ColormapEntries = 1 << visual->nplanes; 322 } else { 323 DirectFormatRec *direct = &pPictFormat->direct; 324 visual->class = TrueColor; 325 visual->redMask = ((unsigned long)direct->redMask) << direct->red; 326 visual->greenMask = ((unsigned long)direct->greenMask) << direct->green; 327 visual->blueMask = ((unsigned long)direct->blueMask) << direct->blue; 328 alphaMask = ((unsigned long)direct->alphaMask) << direct->alpha; 329 visual->offsetRed = direct->red; 330 visual->offsetGreen = direct->green; 331 visual->offsetBlue = direct->blue; 332 /* 333 * Include A bits in this (unlike GLX which includes only RGB) 334 * This lets DIX compute suitable masks for colormap allocations 335 */ 336 visual->nplanes = Ones (visual->redMask | 337 visual->greenMask | 338 visual->blueMask | 339 alphaMask); 340 /* find widest component */ 341 visual->ColormapEntries = (1 << max (Ones (visual->redMask), 342 max (Ones (visual->greenMask), 343 Ones (visual->blueMask)))); 344 } 345 346 /* remember the visual ID to detect auto-update windows */ 347 compRegisterAlternateVisuals(cs, &visual->vid, 1); 348 349 /* Fix up the depth */ 350 *vid = visual->vid; 351 depth->numVids = 1; 352 depth->vids = vid; 353 return TRUE; 354} 355 356static Bool 357compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs) 358{ 359 int alt, ret = 0; 360 361 for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++) 362 ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt); 363 364 return !!ret; 365} 366 367Bool 368compScreenInit (ScreenPtr pScreen) 369{ 370 CompScreenPtr cs; 371 372 if (GetCompScreen (pScreen)) 373 return TRUE; 374 cs = (CompScreenPtr) xalloc (sizeof (CompScreenRec)); 375 if (!cs) 376 return FALSE; 377 378 cs->damaged = FALSE; 379 cs->overlayWid = FakeClientID(0); 380 cs->pOverlayWin = NULL; 381 cs->pOverlayClients = NULL; 382 383 cs->numAlternateVisuals = 0; 384 cs->alternateVisuals = NULL; 385 386 if (!compAddAlternateVisuals (pScreen, cs)) 387 { 388 xfree (cs); 389 return FALSE; 390 } 391 392 cs->PositionWindow = pScreen->PositionWindow; 393 pScreen->PositionWindow = compPositionWindow; 394 395 cs->CopyWindow = pScreen->CopyWindow; 396 pScreen->CopyWindow = compCopyWindow; 397 398 cs->CreateWindow = pScreen->CreateWindow; 399 pScreen->CreateWindow = compCreateWindow; 400 401 cs->DestroyWindow = pScreen->DestroyWindow; 402 pScreen->DestroyWindow = compDestroyWindow; 403 404 cs->RealizeWindow = pScreen->RealizeWindow; 405 pScreen->RealizeWindow = compRealizeWindow; 406 407 cs->UnrealizeWindow = pScreen->UnrealizeWindow; 408 pScreen->UnrealizeWindow = compUnrealizeWindow; 409 410 cs->ClipNotify = pScreen->ClipNotify; 411 pScreen->ClipNotify = compClipNotify; 412 413 cs->MoveWindow = pScreen->MoveWindow; 414 pScreen->MoveWindow = compMoveWindow; 415 416 cs->ResizeWindow = pScreen->ResizeWindow; 417 pScreen->ResizeWindow = compResizeWindow; 418 419 cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; 420 pScreen->ChangeBorderWidth = compChangeBorderWidth; 421 422 cs->ReparentWindow = pScreen->ReparentWindow; 423 pScreen->ReparentWindow = compReparentWindow; 424 425 cs->InstallColormap = pScreen->InstallColormap; 426 pScreen->InstallColormap = compInstallColormap; 427 428 cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; 429 pScreen->ChangeWindowAttributes = compChangeWindowAttributes; 430 431 cs->BlockHandler = pScreen->BlockHandler; 432 pScreen->BlockHandler = compBlockHandler; 433 434 cs->CloseScreen = pScreen->CloseScreen; 435 pScreen->CloseScreen = compCloseScreen; 436 437 dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs); 438 439 RegisterRealChildHeadProc(CompositeRealChildHead); 440 441 return TRUE; 442} 443