compinit.c revision 6747b715
105b261ecSmrg/* 26747b715Smrg * Copyright © 2006 Sun Microsystems, Inc. All rights reserved. 305b261ecSmrg * 46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a 56747b715Smrg * copy of this software and associated documentation files (the "Software"), 66747b715Smrg * to deal in the Software without restriction, including without limitation 76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 96747b715Smrg * Software is furnished to do so, subject to the following conditions: 1005b261ecSmrg * 116747b715Smrg * The above copyright notice and this permission notice (including the next 126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 136747b715Smrg * Software. 146747b715Smrg * 156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 206747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 216747b715Smrg * DEALINGS IN THE SOFTWARE. 2205b261ecSmrg * 2305b261ecSmrg * Copyright © 2003 Keith Packard 2405b261ecSmrg * 2505b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 2605b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 2705b261ecSmrg * the above copyright notice appear in all copies and that both that 2805b261ecSmrg * copyright notice and this permission notice appear in supporting 2905b261ecSmrg * documentation, and that the name of Keith Packard not be used in 3005b261ecSmrg * advertising or publicity pertaining to distribution of the software without 3105b261ecSmrg * specific, written prior permission. Keith Packard makes no 3205b261ecSmrg * representations about the suitability of this software for any purpose. It 3305b261ecSmrg * is provided "as is" without express or implied warranty. 3405b261ecSmrg * 3505b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 3605b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 3705b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 3805b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 3905b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 4005b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 4105b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 4205b261ecSmrg */ 4305b261ecSmrg 4405b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 4505b261ecSmrg#include <dix-config.h> 4605b261ecSmrg#endif 4705b261ecSmrg 4805b261ecSmrg#include "compint.h" 496747b715Smrg#include "compositeext.h" 5005b261ecSmrg 516747b715SmrgDevPrivateKeyRec CompScreenPrivateKeyRec; 526747b715SmrgDevPrivateKeyRec CompWindowPrivateKeyRec; 536747b715SmrgDevPrivateKeyRec CompSubwindowsPrivateKeyRec; 5405b261ecSmrg 5505b261ecSmrgstatic Bool 5605b261ecSmrgcompCloseScreen (int index, ScreenPtr pScreen) 5705b261ecSmrg{ 5805b261ecSmrg CompScreenPtr cs = GetCompScreen (pScreen); 5905b261ecSmrg Bool ret; 6005b261ecSmrg 616747b715Smrg free(cs->alternateVisuals); 6205b261ecSmrg 6305b261ecSmrg pScreen->CloseScreen = cs->CloseScreen; 6405b261ecSmrg pScreen->BlockHandler = cs->BlockHandler; 6505b261ecSmrg pScreen->InstallColormap = cs->InstallColormap; 664642e01fSmrg pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; 6705b261ecSmrg pScreen->ReparentWindow = cs->ReparentWindow; 686747b715Smrg pScreen->ConfigNotify = cs->ConfigNotify; 6905b261ecSmrg pScreen->MoveWindow = cs->MoveWindow; 7005b261ecSmrg pScreen->ResizeWindow = cs->ResizeWindow; 7105b261ecSmrg pScreen->ChangeBorderWidth = cs->ChangeBorderWidth; 7205b261ecSmrg 7305b261ecSmrg pScreen->ClipNotify = cs->ClipNotify; 7405b261ecSmrg pScreen->UnrealizeWindow = cs->UnrealizeWindow; 7505b261ecSmrg pScreen->RealizeWindow = cs->RealizeWindow; 7605b261ecSmrg pScreen->DestroyWindow = cs->DestroyWindow; 7705b261ecSmrg pScreen->CreateWindow = cs->CreateWindow; 7805b261ecSmrg pScreen->CopyWindow = cs->CopyWindow; 7905b261ecSmrg pScreen->PositionWindow = cs->PositionWindow; 8005b261ecSmrg 816747b715Smrg free(cs); 824642e01fSmrg dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL); 8305b261ecSmrg ret = (*pScreen->CloseScreen) (index, pScreen); 8405b261ecSmrg 8505b261ecSmrg return ret; 8605b261ecSmrg} 8705b261ecSmrg 8805b261ecSmrgstatic void 8905b261ecSmrgcompInstallColormap (ColormapPtr pColormap) 9005b261ecSmrg{ 9105b261ecSmrg VisualPtr pVisual = pColormap->pVisual; 9205b261ecSmrg ScreenPtr pScreen = pColormap->pScreen; 9305b261ecSmrg CompScreenPtr cs = GetCompScreen (pScreen); 9405b261ecSmrg int a; 9505b261ecSmrg 9605b261ecSmrg for (a = 0; a < cs->numAlternateVisuals; a++) 9705b261ecSmrg if (pVisual->vid == cs->alternateVisuals[a]) 9805b261ecSmrg return; 9905b261ecSmrg pScreen->InstallColormap = cs->InstallColormap; 10005b261ecSmrg (*pScreen->InstallColormap) (pColormap); 10105b261ecSmrg cs->InstallColormap = pScreen->InstallColormap; 10205b261ecSmrg pScreen->InstallColormap = compInstallColormap; 10305b261ecSmrg} 10405b261ecSmrg 1054642e01fSmrg/* Fake backing store via automatic redirection */ 1064642e01fSmrgstatic Bool 1074642e01fSmrgcompChangeWindowAttributes(WindowPtr pWin, unsigned long mask) 1084642e01fSmrg{ 1094642e01fSmrg ScreenPtr pScreen = pWin->drawable.pScreen; 1104642e01fSmrg CompScreenPtr cs = GetCompScreen (pScreen); 1114642e01fSmrg Bool ret; 1124642e01fSmrg 1134642e01fSmrg pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes; 1144642e01fSmrg ret = pScreen->ChangeWindowAttributes(pWin, mask); 1154642e01fSmrg 1164642e01fSmrg if (ret && (mask & CWBackingStore) && 1174642e01fSmrg pScreen->backingStoreSupport != NotUseful) { 1184642e01fSmrg if (pWin->backingStore != NotUseful) { 1194642e01fSmrg compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic); 1204642e01fSmrg pWin->backStorage = (pointer) (intptr_t) 1; 1214642e01fSmrg } else { 1224642e01fSmrg compUnredirectWindow(serverClient, pWin, 1234642e01fSmrg CompositeRedirectAutomatic); 1244642e01fSmrg pWin->backStorage = NULL; 1254642e01fSmrg } 1264642e01fSmrg } 1274642e01fSmrg 1284642e01fSmrg pScreen->ChangeWindowAttributes = compChangeWindowAttributes; 1294642e01fSmrg 1304642e01fSmrg return ret; 1314642e01fSmrg} 1324642e01fSmrg 13305b261ecSmrgstatic void 13405b261ecSmrgcompScreenUpdate (ScreenPtr pScreen) 13505b261ecSmrg{ 13605b261ecSmrg CompScreenPtr cs = GetCompScreen (pScreen); 13705b261ecSmrg 13805b261ecSmrg compCheckTree (pScreen); 13905b261ecSmrg if (cs->damaged) 14005b261ecSmrg { 1416747b715Smrg compWindowUpdate (pScreen->root); 14205b261ecSmrg cs->damaged = FALSE; 14305b261ecSmrg } 14405b261ecSmrg} 14505b261ecSmrg 14605b261ecSmrgstatic void 14705b261ecSmrgcompBlockHandler (int i, 14805b261ecSmrg pointer blockData, 14905b261ecSmrg pointer pTimeout, 15005b261ecSmrg pointer pReadmask) 15105b261ecSmrg{ 15205b261ecSmrg ScreenPtr pScreen = screenInfo.screens[i]; 15305b261ecSmrg CompScreenPtr cs = GetCompScreen (pScreen); 15405b261ecSmrg 15505b261ecSmrg pScreen->BlockHandler = cs->BlockHandler; 15605b261ecSmrg compScreenUpdate (pScreen); 15705b261ecSmrg (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 15805b261ecSmrg cs->BlockHandler = pScreen->BlockHandler; 15905b261ecSmrg pScreen->BlockHandler = compBlockHandler; 16005b261ecSmrg} 16105b261ecSmrg 16205b261ecSmrg/* 16305b261ecSmrg * Add alternate visuals -- always expose an ARGB32 and RGB24 visual 16405b261ecSmrg */ 16505b261ecSmrg 16605b261ecSmrgstatic DepthPtr 16705b261ecSmrgcompFindVisuallessDepth (ScreenPtr pScreen, int d) 16805b261ecSmrg{ 16905b261ecSmrg int i; 17005b261ecSmrg 17105b261ecSmrg for (i = 0; i < pScreen->numDepths; i++) 17205b261ecSmrg { 17305b261ecSmrg DepthPtr depth = &pScreen->allowedDepths[i]; 17405b261ecSmrg if (depth->depth == d) 17505b261ecSmrg { 17605b261ecSmrg /* 17705b261ecSmrg * Make sure it doesn't have visuals already 17805b261ecSmrg */ 17905b261ecSmrg if (depth->numVids) 18005b261ecSmrg return 0; 18105b261ecSmrg /* 18205b261ecSmrg * looks fine 18305b261ecSmrg */ 18405b261ecSmrg return depth; 18505b261ecSmrg } 18605b261ecSmrg } 18705b261ecSmrg /* 18805b261ecSmrg * If there isn't one, then it's gonna be hard to have 18905b261ecSmrg * an associated visual 19005b261ecSmrg */ 19105b261ecSmrg return 0; 19205b261ecSmrg} 19305b261ecSmrg 19405b261ecSmrg/* 19505b261ecSmrg * Add a list of visual IDs to the list of visuals to implicitly redirect. 19605b261ecSmrg */ 19705b261ecSmrgstatic Bool 19805b261ecSmrgcompRegisterAlternateVisuals (CompScreenPtr cs, VisualID *vids, int nVisuals) 19905b261ecSmrg{ 20005b261ecSmrg VisualID *p; 20105b261ecSmrg 2026747b715Smrg p = realloc(cs->alternateVisuals, 20305b261ecSmrg sizeof(VisualID) * (cs->numAlternateVisuals + nVisuals)); 20405b261ecSmrg if(p == NULL) 20505b261ecSmrg return FALSE; 20605b261ecSmrg 20705b261ecSmrg memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals); 20805b261ecSmrg 20905b261ecSmrg cs->alternateVisuals = p; 21005b261ecSmrg cs->numAlternateVisuals += nVisuals; 21105b261ecSmrg 21205b261ecSmrg return TRUE; 21305b261ecSmrg} 21405b261ecSmrg 21505b261ecSmrgBool CompositeRegisterAlternateVisuals (ScreenPtr pScreen, VisualID *vids, 21605b261ecSmrg int nVisuals) 21705b261ecSmrg{ 21805b261ecSmrg CompScreenPtr cs = GetCompScreen (pScreen); 21905b261ecSmrg return compRegisterAlternateVisuals(cs, vids, nVisuals); 22005b261ecSmrg} 22105b261ecSmrg 22205b261ecSmrgtypedef struct _alternateVisual { 22305b261ecSmrg int depth; 22405b261ecSmrg CARD32 format; 22505b261ecSmrg} CompAlternateVisual; 22605b261ecSmrg 22705b261ecSmrgstatic CompAlternateVisual altVisuals[] = { 22805b261ecSmrg#if COMP_INCLUDE_RGB24_VISUAL 22905b261ecSmrg { 24, PICT_r8g8b8 }, 23005b261ecSmrg#endif 23105b261ecSmrg { 32, PICT_a8r8g8b8 }, 23205b261ecSmrg}; 23305b261ecSmrg 23405b261ecSmrgstatic const int NUM_COMP_ALTERNATE_VISUALS = sizeof(altVisuals) / 23505b261ecSmrg sizeof(CompAlternateVisual); 23605b261ecSmrg 23705b261ecSmrgstatic Bool 23805b261ecSmrgcompAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs, 23905b261ecSmrg CompAlternateVisual *alt) 24005b261ecSmrg{ 2416747b715Smrg VisualPtr visual; 24205b261ecSmrg DepthPtr depth; 24305b261ecSmrg PictFormatPtr pPictFormat; 24405b261ecSmrg unsigned long alphaMask; 24505b261ecSmrg 24605b261ecSmrg /* 24705b261ecSmrg * The ARGB32 visual is always available. Other alternate depth visuals 24805b261ecSmrg * are only provided if their depth is less than the root window depth. 24905b261ecSmrg * There's no deep reason for this. 25005b261ecSmrg */ 25105b261ecSmrg if (alt->depth >= pScreen->rootDepth && alt->depth != 32) 25205b261ecSmrg return FALSE; 25305b261ecSmrg 25405b261ecSmrg depth = compFindVisuallessDepth (pScreen, alt->depth); 25505b261ecSmrg if (!depth) 25605b261ecSmrg /* alt->depth doesn't exist or already has alternate visuals. */ 25705b261ecSmrg return TRUE; 25805b261ecSmrg 25905b261ecSmrg pPictFormat = PictureMatchFormat (pScreen, alt->depth, alt->format); 26005b261ecSmrg if (!pPictFormat) 26105b261ecSmrg return FALSE; 26205b261ecSmrg 2636747b715Smrg if (ResizeVisualArray(pScreen, 1, depth) == FALSE) { 2646747b715Smrg return FALSE; 26505b261ecSmrg } 26605b261ecSmrg 2676747b715Smrg visual = pScreen->visuals + (pScreen->numVisuals - 1); /* the new one */ 26805b261ecSmrg 26905b261ecSmrg /* Initialize the visual */ 27005b261ecSmrg visual->bitsPerRGBValue = 8; 27105b261ecSmrg if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) { 27205b261ecSmrg visual->class = PseudoColor; 27305b261ecSmrg visual->nplanes = PICT_FORMAT_BPP(alt->format); 27405b261ecSmrg visual->ColormapEntries = 1 << visual->nplanes; 27505b261ecSmrg } else { 27605b261ecSmrg DirectFormatRec *direct = &pPictFormat->direct; 27705b261ecSmrg visual->class = TrueColor; 27805b261ecSmrg visual->redMask = ((unsigned long)direct->redMask) << direct->red; 27905b261ecSmrg visual->greenMask = ((unsigned long)direct->greenMask) << direct->green; 28005b261ecSmrg visual->blueMask = ((unsigned long)direct->blueMask) << direct->blue; 28105b261ecSmrg alphaMask = ((unsigned long)direct->alphaMask) << direct->alpha; 28205b261ecSmrg visual->offsetRed = direct->red; 28305b261ecSmrg visual->offsetGreen = direct->green; 28405b261ecSmrg visual->offsetBlue = direct->blue; 28505b261ecSmrg /* 28605b261ecSmrg * Include A bits in this (unlike GLX which includes only RGB) 28705b261ecSmrg * This lets DIX compute suitable masks for colormap allocations 28805b261ecSmrg */ 28905b261ecSmrg visual->nplanes = Ones (visual->redMask | 29005b261ecSmrg visual->greenMask | 29105b261ecSmrg visual->blueMask | 29205b261ecSmrg alphaMask); 29305b261ecSmrg /* find widest component */ 29405b261ecSmrg visual->ColormapEntries = (1 << max (Ones (visual->redMask), 29505b261ecSmrg max (Ones (visual->greenMask), 29605b261ecSmrg Ones (visual->blueMask)))); 29705b261ecSmrg } 29805b261ecSmrg 29905b261ecSmrg /* remember the visual ID to detect auto-update windows */ 30005b261ecSmrg compRegisterAlternateVisuals(cs, &visual->vid, 1); 30105b261ecSmrg 30205b261ecSmrg return TRUE; 30305b261ecSmrg} 30405b261ecSmrg 30505b261ecSmrgstatic Bool 30605b261ecSmrgcompAddAlternateVisuals (ScreenPtr pScreen, CompScreenPtr cs) 30705b261ecSmrg{ 30805b261ecSmrg int alt, ret = 0; 30905b261ecSmrg 31005b261ecSmrg for (alt = 0; alt < NUM_COMP_ALTERNATE_VISUALS; alt++) 31105b261ecSmrg ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt); 31205b261ecSmrg 31305b261ecSmrg return !!ret; 31405b261ecSmrg} 31505b261ecSmrg 31605b261ecSmrgBool 31705b261ecSmrgcompScreenInit (ScreenPtr pScreen) 31805b261ecSmrg{ 31905b261ecSmrg CompScreenPtr cs; 32005b261ecSmrg 3216747b715Smrg if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 3226747b715Smrg return FALSE; 3236747b715Smrg if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0)) 3246747b715Smrg return FALSE; 3256747b715Smrg if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0)) 3266747b715Smrg return FALSE; 3276747b715Smrg 32805b261ecSmrg if (GetCompScreen (pScreen)) 32905b261ecSmrg return TRUE; 3306747b715Smrg cs = (CompScreenPtr) malloc(sizeof (CompScreenRec)); 33105b261ecSmrg if (!cs) 33205b261ecSmrg return FALSE; 33305b261ecSmrg 33405b261ecSmrg cs->damaged = FALSE; 3354642e01fSmrg cs->overlayWid = FakeClientID(0); 33605b261ecSmrg cs->pOverlayWin = NULL; 33705b261ecSmrg cs->pOverlayClients = NULL; 33805b261ecSmrg 33905b261ecSmrg cs->numAlternateVisuals = 0; 34005b261ecSmrg cs->alternateVisuals = NULL; 34105b261ecSmrg 34205b261ecSmrg if (!compAddAlternateVisuals (pScreen, cs)) 34305b261ecSmrg { 3446747b715Smrg free(cs); 34505b261ecSmrg return FALSE; 34605b261ecSmrg } 34705b261ecSmrg 34805b261ecSmrg cs->PositionWindow = pScreen->PositionWindow; 34905b261ecSmrg pScreen->PositionWindow = compPositionWindow; 35005b261ecSmrg 35105b261ecSmrg cs->CopyWindow = pScreen->CopyWindow; 35205b261ecSmrg pScreen->CopyWindow = compCopyWindow; 35305b261ecSmrg 35405b261ecSmrg cs->CreateWindow = pScreen->CreateWindow; 35505b261ecSmrg pScreen->CreateWindow = compCreateWindow; 35605b261ecSmrg 35705b261ecSmrg cs->DestroyWindow = pScreen->DestroyWindow; 35805b261ecSmrg pScreen->DestroyWindow = compDestroyWindow; 35905b261ecSmrg 36005b261ecSmrg cs->RealizeWindow = pScreen->RealizeWindow; 36105b261ecSmrg pScreen->RealizeWindow = compRealizeWindow; 36205b261ecSmrg 36305b261ecSmrg cs->UnrealizeWindow = pScreen->UnrealizeWindow; 36405b261ecSmrg pScreen->UnrealizeWindow = compUnrealizeWindow; 36505b261ecSmrg 36605b261ecSmrg cs->ClipNotify = pScreen->ClipNotify; 36705b261ecSmrg pScreen->ClipNotify = compClipNotify; 36805b261ecSmrg 3696747b715Smrg cs->ConfigNotify = pScreen->ConfigNotify; 3706747b715Smrg pScreen->ConfigNotify = compConfigNotify; 3716747b715Smrg 37205b261ecSmrg cs->MoveWindow = pScreen->MoveWindow; 37305b261ecSmrg pScreen->MoveWindow = compMoveWindow; 37405b261ecSmrg 37505b261ecSmrg cs->ResizeWindow = pScreen->ResizeWindow; 37605b261ecSmrg pScreen->ResizeWindow = compResizeWindow; 37705b261ecSmrg 37805b261ecSmrg cs->ChangeBorderWidth = pScreen->ChangeBorderWidth; 37905b261ecSmrg pScreen->ChangeBorderWidth = compChangeBorderWidth; 38005b261ecSmrg 38105b261ecSmrg cs->ReparentWindow = pScreen->ReparentWindow; 38205b261ecSmrg pScreen->ReparentWindow = compReparentWindow; 38305b261ecSmrg 38405b261ecSmrg cs->InstallColormap = pScreen->InstallColormap; 38505b261ecSmrg pScreen->InstallColormap = compInstallColormap; 38605b261ecSmrg 3874642e01fSmrg cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; 3884642e01fSmrg pScreen->ChangeWindowAttributes = compChangeWindowAttributes; 3894642e01fSmrg 39005b261ecSmrg cs->BlockHandler = pScreen->BlockHandler; 39105b261ecSmrg pScreen->BlockHandler = compBlockHandler; 39205b261ecSmrg 39305b261ecSmrg cs->CloseScreen = pScreen->CloseScreen; 39405b261ecSmrg pScreen->CloseScreen = compCloseScreen; 39505b261ecSmrg 3964642e01fSmrg dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs); 39705b261ecSmrg 39805b261ecSmrg RegisterRealChildHeadProc(CompositeRealChildHead); 39905b261ecSmrg 40005b261ecSmrg return TRUE; 40105b261ecSmrg} 402