xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

compinit.c (13546B)


      1 /*
      2  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice (including the next
     12  * paragraph) shall be included in all copies or substantial portions of the
     13  * Software.
     14  *
     15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
     21  * DEALINGS IN THE SOFTWARE.
     22  *
     23  * Copyright © 2003 Keith Packard
     24  *
     25  * Permission to use, copy, modify, distribute, and sell this software and its
     26  * documentation for any purpose is hereby granted without fee, provided that
     27  * the above copyright notice appear in all copies and that both that
     28  * copyright notice and this permission notice appear in supporting
     29  * documentation, and that the name of Keith Packard not be used in
     30  * advertising or publicity pertaining to distribution of the software without
     31  * specific, written prior permission.  Keith Packard makes no
     32  * representations about the suitability of this software for any purpose.  It
     33  * is provided "as is" without express or implied warranty.
     34  *
     35  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     36  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     37  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     38  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     39  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     40  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     41  * PERFORMANCE OF THIS SOFTWARE.
     42  */
     43 
     44 #ifdef HAVE_DIX_CONFIG_H
     45 #include <dix-config.h>
     46 #endif
     47 
     48 #include "compint.h"
     49 #include "compositeext.h"
     50 
     51 DevPrivateKeyRec CompScreenPrivateKeyRec;
     52 DevPrivateKeyRec CompWindowPrivateKeyRec;
     53 DevPrivateKeyRec CompSubwindowsPrivateKeyRec;
     54 
     55 static Bool
     56 compCloseScreen(ScreenPtr pScreen)
     57 {
     58     CompScreenPtr cs = GetCompScreen(pScreen);
     59     Bool ret;
     60 
     61     free(cs->alternateVisuals);
     62 
     63     pScreen->CloseScreen = cs->CloseScreen;
     64     pScreen->InstallColormap = cs->InstallColormap;
     65     pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
     66     pScreen->ReparentWindow = cs->ReparentWindow;
     67     pScreen->ConfigNotify = cs->ConfigNotify;
     68     pScreen->MoveWindow = cs->MoveWindow;
     69     pScreen->ResizeWindow = cs->ResizeWindow;
     70     pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
     71 
     72     pScreen->ClipNotify = cs->ClipNotify;
     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     pScreen->SourceValidate = cs->SourceValidate;
     80 
     81     free(cs);
     82     dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL);
     83     ret = (*pScreen->CloseScreen) (pScreen);
     84 
     85     return ret;
     86 }
     87 
     88 static void
     89 compInstallColormap(ColormapPtr pColormap)
     90 {
     91     VisualPtr pVisual = pColormap->pVisual;
     92     ScreenPtr pScreen = pColormap->pScreen;
     93     CompScreenPtr cs = GetCompScreen(pScreen);
     94     int a;
     95 
     96     for (a = 0; a < cs->numAlternateVisuals; a++)
     97         if (pVisual->vid == cs->alternateVisuals[a])
     98             return;
     99     pScreen->InstallColormap = cs->InstallColormap;
    100     (*pScreen->InstallColormap) (pColormap);
    101     cs->InstallColormap = pScreen->InstallColormap;
    102     pScreen->InstallColormap = compInstallColormap;
    103 }
    104 
    105 static void
    106 compCheckBackingStore(WindowPtr pWin)
    107 {
    108     if (pWin->backingStore != NotUseful) {
    109         compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
    110     }
    111     else {
    112         compUnredirectWindow(serverClient, pWin,
    113                              CompositeRedirectAutomatic);
    114     }
    115 }
    116 
    117 /* Fake backing store via automatic redirection */
    118 static Bool
    119 compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
    120 {
    121     ScreenPtr pScreen = pWin->drawable.pScreen;
    122     CompScreenPtr cs = GetCompScreen(pScreen);
    123     Bool ret;
    124 
    125     pScreen->ChangeWindowAttributes = cs->ChangeWindowAttributes;
    126     ret = pScreen->ChangeWindowAttributes(pWin, mask);
    127 
    128     if (ret && (mask & CWBackingStore) &&
    129         pScreen->backingStoreSupport != NotUseful)
    130         compCheckBackingStore(pWin);
    131 
    132     pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
    133 
    134     return ret;
    135 }
    136 
    137 static void
    138 compSourceValidate(DrawablePtr pDrawable,
    139                    int x, int y,
    140                    int width, int height, unsigned int subWindowMode)
    141 {
    142     ScreenPtr pScreen = pDrawable->pScreen;
    143     CompScreenPtr cs = GetCompScreen(pScreen);
    144 
    145     pScreen->SourceValidate = cs->SourceValidate;
    146     if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors)
    147         compPaintChildrenToWindow((WindowPtr) pDrawable);
    148     (*pScreen->SourceValidate) (pDrawable, x, y, width, height,
    149                                 subWindowMode);
    150     cs->SourceValidate = pScreen->SourceValidate;
    151     pScreen->SourceValidate = compSourceValidate;
    152 }
    153 
    154 /*
    155  * Add alternate visuals -- always expose an ARGB32 and RGB24 visual
    156  */
    157 
    158 static DepthPtr
    159 compFindVisuallessDepth(ScreenPtr pScreen, int d)
    160 {
    161     int i;
    162 
    163     for (i = 0; i < pScreen->numDepths; i++) {
    164         DepthPtr depth = &pScreen->allowedDepths[i];
    165 
    166         if (depth->depth == d) {
    167             /*
    168              * Make sure it doesn't have visuals already
    169              */
    170             if (depth->numVids)
    171                 return 0;
    172             /*
    173              * looks fine
    174              */
    175             return depth;
    176         }
    177     }
    178     /*
    179      * If there isn't one, then it's gonna be hard to have
    180      * an associated visual
    181      */
    182     return 0;
    183 }
    184 
    185 /*
    186  * Add a list of visual IDs to the list of visuals to implicitly redirect.
    187  */
    188 static Bool
    189 compRegisterAlternateVisuals(CompScreenPtr cs, VisualID * vids, int nVisuals)
    190 {
    191     VisualID *p;
    192 
    193     p = reallocarray(cs->alternateVisuals,
    194                      cs->numAlternateVisuals + nVisuals, sizeof(VisualID));
    195     if (p == NULL)
    196         return FALSE;
    197 
    198     memcpy(&p[cs->numAlternateVisuals], vids, sizeof(VisualID) * nVisuals);
    199 
    200     cs->alternateVisuals = p;
    201     cs->numAlternateVisuals += nVisuals;
    202 
    203     return TRUE;
    204 }
    205 
    206 Bool
    207 CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids,
    208                                   int nVisuals)
    209 {
    210     CompScreenPtr cs = GetCompScreen(pScreen);
    211 
    212     return compRegisterAlternateVisuals(cs, vids, nVisuals);
    213 }
    214 
    215 Bool
    216 CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
    217                                               VisualID parentVisual,
    218                                               VisualID winVisual)
    219 {
    220     CompScreenPtr cs = GetCompScreen(pScreen);
    221     CompImplicitRedirectException *p;
    222 
    223     p = reallocarray(cs->implicitRedirectExceptions,
    224                      cs->numImplicitRedirectExceptions + 1, sizeof(p[0]));
    225     if (p == NULL)
    226         return FALSE;
    227 
    228     p[cs->numImplicitRedirectExceptions].parentVisual = parentVisual;
    229     p[cs->numImplicitRedirectExceptions].winVisual = winVisual;
    230 
    231     cs->implicitRedirectExceptions = p;
    232     cs->numImplicitRedirectExceptions++;
    233 
    234     return TRUE;
    235 }
    236 
    237 typedef struct _alternateVisual {
    238     int depth;
    239     CARD32 format;
    240 } CompAlternateVisual;
    241 
    242 static CompAlternateVisual altVisuals[] = {
    243 #if COMP_INCLUDE_RGB24_VISUAL
    244     {24, PICT_r8g8b8},
    245 #endif
    246     {32, PICT_a8r8g8b8},
    247 };
    248 
    249 static Bool
    250 compAddAlternateVisual(ScreenPtr pScreen, CompScreenPtr cs,
    251                        CompAlternateVisual * alt)
    252 {
    253     VisualPtr visual;
    254     DepthPtr depth;
    255     PictFormatPtr pPictFormat;
    256     unsigned long alphaMask;
    257 
    258     /*
    259      * The ARGB32 visual is always available.  Other alternate depth visuals
    260      * are only provided if their depth is less than the root window depth.
    261      * There's no deep reason for this.
    262      */
    263     if (alt->depth >= pScreen->rootDepth && alt->depth != 32)
    264         return FALSE;
    265 
    266     depth = compFindVisuallessDepth(pScreen, alt->depth);
    267     if (!depth)
    268         /* alt->depth doesn't exist or already has alternate visuals. */
    269         return TRUE;
    270 
    271     pPictFormat = PictureMatchFormat(pScreen, alt->depth, alt->format);
    272     if (!pPictFormat)
    273         return FALSE;
    274 
    275     if (ResizeVisualArray(pScreen, 1, depth) == FALSE) {
    276         return FALSE;
    277     }
    278 
    279     visual = pScreen->visuals + (pScreen->numVisuals - 1);      /* the new one */
    280 
    281     /* Initialize the visual */
    282     visual->bitsPerRGBValue = 8;
    283     if (PICT_FORMAT_TYPE(alt->format) == PICT_TYPE_COLOR) {
    284         visual->class = PseudoColor;
    285         visual->nplanes = PICT_FORMAT_BPP(alt->format);
    286         visual->ColormapEntries = 1 << visual->nplanes;
    287     }
    288     else {
    289         DirectFormatRec *direct = &pPictFormat->direct;
    290 
    291         visual->class = TrueColor;
    292         visual->redMask = ((unsigned long) direct->redMask) << direct->red;
    293         visual->greenMask =
    294             ((unsigned long) direct->greenMask) << direct->green;
    295         visual->blueMask = ((unsigned long) direct->blueMask) << direct->blue;
    296         alphaMask = ((unsigned long) direct->alphaMask) << direct->alpha;
    297         visual->offsetRed = direct->red;
    298         visual->offsetGreen = direct->green;
    299         visual->offsetBlue = direct->blue;
    300         /*
    301          * Include A bits in this (unlike GLX which includes only RGB)
    302          * This lets DIX compute suitable masks for colormap allocations
    303          */
    304         visual->nplanes = Ones(visual->redMask |
    305                                visual->greenMask |
    306                                visual->blueMask | alphaMask);
    307         /* find widest component */
    308         visual->ColormapEntries = (1 << max(Ones(visual->redMask),
    309                                             max(Ones(visual->greenMask),
    310                                                 Ones(visual->blueMask))));
    311     }
    312 
    313     /* remember the visual ID to detect auto-update windows */
    314     compRegisterAlternateVisuals(cs, &visual->vid, 1);
    315 
    316     return TRUE;
    317 }
    318 
    319 static Bool
    320 compAddAlternateVisuals(ScreenPtr pScreen, CompScreenPtr cs)
    321 {
    322     int alt, ret = 0;
    323 
    324     for (alt = 0; alt < ARRAY_SIZE(altVisuals); alt++)
    325         ret |= compAddAlternateVisual(pScreen, cs, altVisuals + alt);
    326 
    327     return ! !ret;
    328 }
    329 
    330 Bool
    331 compScreenInit(ScreenPtr pScreen)
    332 {
    333     CompScreenPtr cs;
    334 
    335     if (!dixRegisterPrivateKey(&CompScreenPrivateKeyRec, PRIVATE_SCREEN, 0))
    336         return FALSE;
    337     if (!dixRegisterPrivateKey(&CompWindowPrivateKeyRec, PRIVATE_WINDOW, 0))
    338         return FALSE;
    339     if (!dixRegisterPrivateKey(&CompSubwindowsPrivateKeyRec, PRIVATE_WINDOW, 0))
    340         return FALSE;
    341 
    342     if (GetCompScreen(pScreen))
    343         return TRUE;
    344     cs = (CompScreenPtr) malloc(sizeof(CompScreenRec));
    345     if (!cs)
    346         return FALSE;
    347 
    348     cs->overlayWid = FakeClientID(0);
    349     cs->pOverlayWin = NULL;
    350     cs->pOverlayClients = NULL;
    351 
    352     cs->pendingScreenUpdate = FALSE;
    353 
    354     cs->numAlternateVisuals = 0;
    355     cs->alternateVisuals = NULL;
    356     cs->numImplicitRedirectExceptions = 0;
    357     cs->implicitRedirectExceptions = NULL;
    358 
    359     if (!compAddAlternateVisuals(pScreen, cs)) {
    360         free(cs);
    361         return FALSE;
    362     }
    363 
    364     if (!disableBackingStore)
    365         pScreen->backingStoreSupport = WhenMapped;
    366 
    367     cs->PositionWindow = pScreen->PositionWindow;
    368     pScreen->PositionWindow = compPositionWindow;
    369 
    370     cs->CopyWindow = pScreen->CopyWindow;
    371     pScreen->CopyWindow = compCopyWindow;
    372 
    373     cs->CreateWindow = pScreen->CreateWindow;
    374     pScreen->CreateWindow = compCreateWindow;
    375 
    376     cs->DestroyWindow = pScreen->DestroyWindow;
    377     pScreen->DestroyWindow = compDestroyWindow;
    378 
    379     cs->RealizeWindow = pScreen->RealizeWindow;
    380     pScreen->RealizeWindow = compRealizeWindow;
    381 
    382     cs->UnrealizeWindow = pScreen->UnrealizeWindow;
    383     pScreen->UnrealizeWindow = compUnrealizeWindow;
    384 
    385     cs->ClipNotify = pScreen->ClipNotify;
    386     pScreen->ClipNotify = compClipNotify;
    387 
    388     cs->ConfigNotify = pScreen->ConfigNotify;
    389     pScreen->ConfigNotify = compConfigNotify;
    390 
    391     cs->MoveWindow = pScreen->MoveWindow;
    392     pScreen->MoveWindow = compMoveWindow;
    393 
    394     cs->ResizeWindow = pScreen->ResizeWindow;
    395     pScreen->ResizeWindow = compResizeWindow;
    396 
    397     cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
    398     pScreen->ChangeBorderWidth = compChangeBorderWidth;
    399 
    400     cs->ReparentWindow = pScreen->ReparentWindow;
    401     pScreen->ReparentWindow = compReparentWindow;
    402 
    403     cs->InstallColormap = pScreen->InstallColormap;
    404     pScreen->InstallColormap = compInstallColormap;
    405 
    406     cs->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
    407     pScreen->ChangeWindowAttributes = compChangeWindowAttributes;
    408 
    409     cs->CloseScreen = pScreen->CloseScreen;
    410     pScreen->CloseScreen = compCloseScreen;
    411 
    412     cs->SourceValidate = pScreen->SourceValidate;
    413     pScreen->SourceValidate = compSourceValidate;
    414 
    415     dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs);
    416 
    417     RegisterRealChildHeadProc(CompositeRealChildHead);
    418 
    419     return TRUE;
    420 }