xserver

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

shadow.c (5339B)


      1 /*
      2  * Copyright © 2000 Keith Packard
      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 Keith Packard not be used in
      9  * advertising or publicity pertaining to distribution of the software without
     10  * specific, written prior permission.  Keith Packard 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  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     16  * EVENT SHALL KEITH PACKARD 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 
     23 #ifdef HAVE_DIX_CONFIG_H
     24 #include <dix-config.h>
     25 #endif
     26 
     27 #include <stdlib.h>
     28 
     29 #include    <X11/X.h>
     30 #include    "scrnintstr.h"
     31 #include    "windowstr.h"
     32 #include    "dixfontstr.h"
     33 #include    "mi.h"
     34 #include    "regionstr.h"
     35 #include    "globals.h"
     36 #include    "gcstruct.h"
     37 #include    "shadow.h"
     38 
     39 static DevPrivateKeyRec shadowScrPrivateKeyRec;
     40 #define shadowScrPrivateKey (&shadowScrPrivateKeyRec)
     41 
     42 #define shadowGetBuf(pScr) ((shadowBufPtr) \
     43     dixLookupPrivate(&(pScr)->devPrivates, shadowScrPrivateKey))
     44 #define shadowBuf(pScr)            shadowBufPtr pBuf = shadowGetBuf(pScr)
     45 
     46 #define wrap(priv, real, mem) {\
     47     priv->mem = real->mem; \
     48     real->mem = shadow##mem; \
     49 }
     50 
     51 #define unwrap(priv, real, mem) {\
     52     real->mem = priv->mem; \
     53 }
     54 
     55 static void
     56 shadowRedisplay(ScreenPtr pScreen)
     57 {
     58     shadowBuf(pScreen);
     59     RegionPtr pRegion;
     60 
     61     if (!pBuf || !pBuf->pDamage || !pBuf->update)
     62         return;
     63     pRegion = DamageRegion(pBuf->pDamage);
     64     if (RegionNotEmpty(pRegion)) {
     65         (*pBuf->update) (pScreen, pBuf);
     66         DamageEmpty(pBuf->pDamage);
     67     }
     68 }
     69 
     70 static void
     71 shadowBlockHandler(ScreenPtr pScreen, void *timeout)
     72 {
     73     shadowBuf(pScreen);
     74 
     75     shadowRedisplay(pScreen);
     76 
     77     unwrap(pBuf, pScreen, BlockHandler);
     78     pScreen->BlockHandler(pScreen, timeout);
     79     wrap(pBuf, pScreen, BlockHandler);
     80 }
     81 
     82 static void
     83 shadowGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
     84                unsigned int format, unsigned long planeMask, char *pdstLine)
     85 {
     86     ScreenPtr pScreen = pDrawable->pScreen;
     87 
     88     shadowBuf(pScreen);
     89 
     90     /* Many apps use GetImage to sync with the visible frame buffer */
     91     if (pDrawable->type == DRAWABLE_WINDOW)
     92         shadowRedisplay(pScreen);
     93     unwrap(pBuf, pScreen, GetImage);
     94     pScreen->GetImage(pDrawable, sx, sy, w, h, format, planeMask, pdstLine);
     95     wrap(pBuf, pScreen, GetImage);
     96 }
     97 
     98 static Bool
     99 shadowCloseScreen(ScreenPtr pScreen)
    100 {
    101     shadowBuf(pScreen);
    102 
    103     unwrap(pBuf, pScreen, GetImage);
    104     unwrap(pBuf, pScreen, CloseScreen);
    105     unwrap(pBuf, pScreen, BlockHandler);
    106     shadowRemove(pScreen, pBuf->pPixmap);
    107     DamageDestroy(pBuf->pDamage);
    108     if (pBuf->pPixmap)
    109         pScreen->DestroyPixmap(pBuf->pPixmap);
    110     free(pBuf);
    111     return pScreen->CloseScreen(pScreen);
    112 }
    113 
    114 Bool
    115 shadowSetup(ScreenPtr pScreen)
    116 {
    117     shadowBufPtr pBuf;
    118 
    119     if (!dixRegisterPrivateKey(&shadowScrPrivateKeyRec, PRIVATE_SCREEN, 0))
    120         return FALSE;
    121 
    122     if (!DamageSetup(pScreen))
    123         return FALSE;
    124 
    125     pBuf = malloc(sizeof(shadowBufRec));
    126     if (!pBuf)
    127         return FALSE;
    128     pBuf->pDamage = DamageCreate((DamageReportFunc) NULL,
    129                                  (DamageDestroyFunc) NULL,
    130                                  DamageReportNone, TRUE, pScreen, pScreen);
    131     if (!pBuf->pDamage) {
    132         free(pBuf);
    133         return FALSE;
    134     }
    135 
    136     wrap(pBuf, pScreen, CloseScreen);
    137     wrap(pBuf, pScreen, GetImage);
    138     wrap(pBuf, pScreen, BlockHandler);
    139     pBuf->update = 0;
    140     pBuf->window = 0;
    141     pBuf->pPixmap = 0;
    142     pBuf->closure = 0;
    143     pBuf->randr = 0;
    144 
    145     dixSetPrivate(&pScreen->devPrivates, shadowScrPrivateKey, pBuf);
    146     return TRUE;
    147 }
    148 
    149 Bool
    150 shadowAdd(ScreenPtr pScreen, PixmapPtr pPixmap, ShadowUpdateProc update,
    151           ShadowWindowProc window, int randr, void *closure)
    152 {
    153     shadowBuf(pScreen);
    154 
    155     /*
    156      * Map simple rotation values to bitmasks; fortunately,
    157      * these are all unique
    158      */
    159     switch (randr) {
    160     case 0:
    161         randr = SHADOW_ROTATE_0;
    162         break;
    163     case 90:
    164         randr = SHADOW_ROTATE_90;
    165         break;
    166     case 180:
    167         randr = SHADOW_ROTATE_180;
    168         break;
    169     case 270:
    170         randr = SHADOW_ROTATE_270;
    171         break;
    172     }
    173     pBuf->update = update;
    174     pBuf->window = window;
    175     pBuf->randr = randr;
    176     pBuf->closure = closure;
    177     pBuf->pPixmap = pPixmap;
    178     DamageRegister(&pPixmap->drawable, pBuf->pDamage);
    179     return TRUE;
    180 }
    181 
    182 void
    183 shadowRemove(ScreenPtr pScreen, PixmapPtr pPixmap)
    184 {
    185     shadowBuf(pScreen);
    186 
    187     if (pBuf->pPixmap) {
    188         DamageUnregister(pBuf->pDamage);
    189         pBuf->update = 0;
    190         pBuf->window = 0;
    191         pBuf->randr = 0;
    192         pBuf->closure = 0;
    193         pBuf->pPixmap = 0;
    194     }
    195 }