compinit.c revision 05b261ec
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 49int CompScreenPrivateIndex; 50int CompWindowPrivateIndex; 51int CompSubwindowsPrivateIndex; 52static int CompGeneration; 53 54 55static Bool 56compCloseScreen (int index, ScreenPtr pScreen) 57{ 58 CompScreenPtr cs = GetCompScreen (pScreen); 59 Bool ret; 60 61 xfree (cs->alternateVisuals); 62 63 pScreen->CloseScreen = cs->CloseScreen; 64 pScreen->BlockHandler = cs->BlockHandler; 65 pScreen->InstallColormap = cs->InstallColormap; 66 pScreen->ReparentWindow = cs->ReparentWindow; 67 pScreen->MoveWindow = cs->MoveWindow; 68 pScreen->ResizeWindow = cs->ResizeWindow; 69 pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; 70 71 pScreen->ClipNotify = cs->ClipNotify; 72 pScreen->PaintWindowBackground = cs->PaintWindowBackground; 73 pScreen->UnrealizeWindow = cs->UnrealizeWindow; 74 pScreen->RealizeWindow = cs->RealizeWindow; 75 pScreen->DestroyWindow = cs->DestroyWindow; 76 pScreen->CreateWindow = cs->CreateWindow; 77 pScreen->CopyWindow = cs->CopyWindow; 78 pScreen->PositionWindow = cs->PositionWindow; 79 80 deleteCompOverlayClientsForScreen(pScreen); 81 82 /* 83 ** Note: no need to call DeleteWindow; the server has 84 ** already destroyed it. 85 */ 86 cs->pOverlayWin = NULL; 87 88 xfree (cs); 89 pScreen->devPrivates[CompScreenPrivateIndex].ptr = 0; 90 ret = (*pScreen->CloseScreen) (index, pScreen); 91 92 return ret; 93} 94 95static void 96compInstallColormap (ColormapPtr pColormap) 97{ 98 VisualPtr pVisual = pColormap->pVisual; 99 ScreenPtr pScreen = pColormap->pScreen; 100 CompScreenPtr cs = GetCompScreen (pScreen); 101 int a; 102 103 for (a = 0; a < cs->numAlternateVisuals; a++) 104 if (pVisual->vid == cs->alternateVisuals[a]) 105 return; 106 pScreen->InstallColormap = cs->InstallColormap; 107 (*pScreen->InstallColormap) (pColormap); 108 cs->InstallColormap = pScreen->InstallColormap; 109 pScreen->InstallColormap = compInstallColormap; 110} 111 112static void 113compScreenUpdate (ScreenPtr pScreen) 114{ 115 CompScreenPtr cs = GetCompScreen (pScreen); 116 117 compCheckTree (pScreen); 118 if (cs->damaged) 119 { 120 compWindowUpdate (WindowTable[pScreen->myNum]); 121 cs->damaged = FALSE; 122 } 123} 124 125static void 126compBlockHandler (int i, 127 pointer blockData, 128 pointer pTimeout, 129 pointer pReadmask) 130{ 131 ScreenPtr pScreen = screenInfo.screens[i]; 132 CompScreenPtr cs = GetCompScreen (pScreen); 133 134 pScreen->BlockHandler = cs->BlockHandler; 135 compScreenUpdate (pScreen); 136 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 137 cs->BlockHandler = pScreen->BlockHandler; 138 pScreen->BlockHandler = compBlockHandler; 139} 140 141/* 142 * Add alternate visuals -- always expose an ARGB32 and RGB24 visual 143 */ 144 145static DepthPtr 146compFindVisuallessDepth (ScreenPtr pScreen, int d) 147{ 148 int i; 149 150 for (i = 0; i < pScreen->numDepths; i++) 151 { 152 DepthPtr depth = &pScreen->allowedDepths[i]; 153 if (depth->depth == d) 154 { 155 /* 156 * Make sure it doesn't have visuals already 157 */ 158 if (depth->numVids) 159 return 0; 160 /* 161 * looks fine 162 */ 163 return depth; 164 } 165 } 166 /* 167 * If there isn't one, then it's gonna be hard to have 168 * an associated visual 169 */ 170 return 0; 171} 172 173/* 174 * Add a list of visual IDs to the list of visuals to implicitly redirect. 175 */ 176static Bool 177compRegisterAlternateVisuals (CompScreenPtr cs, VisualID *vids, int nVisuals) 178{ 179 VisualID *p; 180 181 p = xrealloc(cs->alternateVisuals, 182 sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals)); 183 if(p == NULL) 184 return FALSE; 185 186 memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals); 187 188 cs->alternateVisuals = p; 189 cs->numAlternateVisuals += nVisuals; 190 191 return TRUE; 192} 193 194_X_EXPORT 195Bool CompositeRegisterAlternateVisuals (ScreenPtr pScreen, VisualID *vids, 196 int nVisuals) 197{ 198 CompScreenPtr cs = GetCompScreen (pScreen); 199 return compRegisterAlternateVisuals(cs, vids, nVisuals); 200} 201 202typedef struct _alternateVisual { 203 int depth; 204 CARD32 format; 205} CompAlternateVisual; 206 207static CompAlternateVisual altVisuals[] = { 208#if COMP_INCLUDE_RGB24_VISUAL 209 { 24, PICT_r8g8b8 }, 210#endif 211 { 32, PICT_a8r8g8b8 }, 212}; 213 214static const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) / 215 sizeof(CompAlternateVisual); 216 217static Bool 218compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs, 219 CompAlternateVisual *alt) 220{ 221 VisualPtr visual, visuals; 222 int i; 223 int numVisuals; 224 XID *installedCmaps; 225 ColormapPtr installedCmap; 226 int numInstalledCmaps; 227 DepthPtr depth; 228 PictFormatPtr pPictFormat; 229 VisualID *vid; 230 unsigned long alphaMask; 231 232 /* 233 * The ARGB32 visual is always available. Other alternate depth visuals 234 * are only provided if their depth is less than the root window depth. 235 * There's no deep reason for this. 236 */ 237 if (alt->depth >= pScreen->rootDepth && alt->depth != 32) 238 return FALSE; 239 240 depth = compFindVisuallessDepth (pScreen, alt->depth); 241 if (!depth) 242 /* alt->depth doesn't exist or already has alternate visuals. */ 243 return TRUE; 244 245 pPictFormat = PictureMatchFormat (pScreen, alt->depth, alt->format); 246 if (!pPictFormat) 247 return FALSE; 248 249 vid = xalloc(sizeof(VisualID)); 250 if (!vid) 251 return FALSE; 252 253 /* Find the installed colormaps */ 254 installedCmaps = xalloc (pScreen->maxInstalledCmaps * sizeof (XID)); 255 if (!installedCmaps) { 256 xfree(vid); 257 return FALSE; 258 } 259 numInstalledCmaps = pScreen->ListInstalledColormaps(pScreen, 260 installedCmaps); 261 262 /* realloc the visual array to fit the new one in place */ 263 numVisuals = pScreen->numVisuals; 264 visuals = xrealloc(pScreen->visuals, (numVisuals + 1) * sizeof(VisualRec)); 265 if (!visuals) { 266 xfree(vid); 267 xfree(installedCmaps); 268 return FALSE; 269 } 270 271 /* 272 * Fix up any existing installed colormaps -- we'll assume that 273 * the only ones created so far have been installed. If this 274 * isn't true, we'll have to walk the resource database looking 275 * for all colormaps. 276 */ 277 for (i = 0; i < numInstalledCmaps; i++) { 278 int j; 279 280 installedCmap = LookupIDByType (installedCmaps[i], RT_COLORMAP); 281 if (!installedCmap) 282 continue; 283 j = installedCmap->pVisual - pScreen->visuals; 284 installedCmap->pVisual = &visuals[j]; 285 } 286 287 xfree(installedCmaps); 288 289 pScreen->visuals = visuals; 290 visual = visuals + pScreen->numVisuals; /* the new one */ 291 pScreen->numVisuals++; 292 293 /* Initialize the visual */ 294 visual->vid = FakeClientID (0); 295 visual->bitsPerRGBValue = 8; 296 if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) { 297 visual->class = PseudoColor; 298 visual->nplanes = PICT_FORMAT_BPP(alt->format); 299 visual->ColormapEntries = 1 << visual->nplanes; 300 } else { 301 DirectFormatRec *direct = &pPictFormat->direct; 302 visual->class = TrueColor; 303 visual->redMask = ((unsigned long)direct->redMask) << direct->red; 304 visual->greenMask = ((unsigned long)direct->greenMask) << direct->green; 305 visual->blueMask = ((unsigned long)direct->blueMask) << direct->blue; 306 alphaMask = ((unsigned long)direct->alphaMask) << direct->alpha; 307 visual->offsetRed = direct->red; 308 visual->offsetGreen = direct->green; 309 visual->offsetBlue = direct->blue; 310 /* 311 * Include A bits in this (unlike GLX which includes only RGB) 312 * This lets DIX compute suitable masks for colormap allocations 313 */ 314 visual->nplanes = Ones (visual->redMask | 315 visual->greenMask | 316 visual->blueMask | 317 alphaMask); 318 /* find widest component */ 319 visual->ColormapEntries = (1 << max (Ones (visual->redMask), 320 max (Ones (visual->greenMask), 321 Ones (visual->blueMask)))); 322 } 323 324 /* remember the visual ID to detect auto-update windows */ 325 compRegisterAlternateVisuals(cs, &visual->vid, 1); 326 327 /* Fix up the depth */ 328 *vid = visual->vid; 329 depth->numVids = 1; 330 depth->vids = vid; 331 return TRUE; 332} 333 334static Bool 335compAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs) 336{ 337 int alt, ret = 0; 338 339 for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++) 340 ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt); 341 342 return !!ret; 343} 344 345Bool 346compScreenInit (ScreenPtr pScreen) 347{ 348 CompScreenPtr cs; 349 350 if (CompGeneration != serverGeneration) 351 { 352 CompScreenPrivateIndex = AllocateScreenPrivateIndex (); 353 if (CompScreenPrivateIndex == -1) 354 return FALSE; 355 CompWindowPrivateIndex = AllocateWindowPrivateIndex (); 356 if (CompWindowPrivateIndex == -1) 357 return FALSE; 358 CompSubwindowsPrivateIndex = AllocateWindowPrivateIndex (); 359 if (CompSubwindowsPrivateIndex == -1) 360 return FALSE; 361 CompGeneration = serverGeneration; 362 } 363 if (!AllocateWindowPrivate (pScreen, CompWindowPrivateIndex, 0)) 364 return FALSE; 365 366 if (!AllocateWindowPrivate (pScreen, CompSubwindowsPrivateIndex, 0)) 367 return FALSE; 368 369 if (GetCompScreen (pScreen)) 370 return TRUE; 371 cs = (CompScreenPtr) xalloc (sizeof (CompScreenRec)); 372 if (!cs) 373 return FALSE; 374 375 cs->damaged = FALSE; 376 cs->pOverlayWin = NULL; 377 cs->pOverlayClients = NULL; 378 379 cs->numAlternateVisuals = 0; 380 cs->alternateVisuals = NULL; 381 382 if (!compAddAlternateVisuals (pScreen, cs)) 383 { 384 xfree (cs); 385 return FALSE; 386 } 387 388 cs->PositionWindow = pScreen->PositionWindow; 389 pScreen->PositionWindow = compPositionWindow; 390 391 cs->CopyWindow = pScreen->CopyWindow; 392 pScreen->CopyWindow = compCopyWindow; 393 394 cs->CreateWindow = pScreen->CreateWindow; 395 pScreen->CreateWindow = compCreateWindow; 396 397 cs->DestroyWindow = pScreen->DestroyWindow; 398 pScreen->DestroyWindow = compDestroyWindow; 399 400 cs->RealizeWindow = pScreen->RealizeWindow; 401 pScreen->RealizeWindow = compRealizeWindow; 402 403 cs->UnrealizeWindow = pScreen->UnrealizeWindow; 404 pScreen->UnrealizeWindow = compUnrealizeWindow; 405 406 cs->PaintWindowBackground = pScreen->PaintWindowBackground; 407 pScreen->PaintWindowBackground = compPaintWindowBackground; 408 409 cs->ClipNotify = pScreen->ClipNotify; 410 pScreen->ClipNotify = compClipNotify; 411 412 cs->MoveWindow = pScreen->MoveWindow; 413 pScreen->MoveWindow = compMoveWindow; 414 415 cs->ResizeWindow = pScreen->ResizeWindow; 416 pScreen->ResizeWindow = compResizeWindow; 417 418 cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; 419 pScreen->ChangeBorderWidth = compChangeBorderWidth; 420 421 cs->ReparentWindow = pScreen->ReparentWindow; 422 pScreen->ReparentWindow = compReparentWindow; 423 424 cs->InstallColormap = pScreen->InstallColormap; 425 pScreen->InstallColormap = compInstallColormap; 426 427 cs->BlockHandler = pScreen->BlockHandler; 428 pScreen->BlockHandler = compBlockHandler; 429 430 cs->CloseScreen = pScreen->CloseScreen; 431 pScreen->CloseScreen = compCloseScreen; 432 433 pScreen->devPrivates[CompScreenPrivateIndex].ptr = (pointer) cs; 434 435 RegisterRealChildHeadProc(CompositeRealChildHead); 436 437 return TRUE; 438} 439