xserver

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

Color.c (15034B)


      1 /*
      2 
      3 Copyright 1993 by Davor Matic
      4 
      5 Permission to use, copy, modify, distribute, and sell this software
      6 and its documentation for any purpose is hereby granted without fee,
      7 provided that the above copyright notice appear in all copies and that
      8 both that copyright notice and this permission notice appear in
      9 supporting documentation.  Davor Matic makes no representations about
     10 the suitability of this software for any purpose.  It is provided "as
     11 is" without express or implied warranty.
     12 
     13 */
     14 
     15 #ifdef HAVE_XNEST_CONFIG_H
     16 #include <xnest-config.h>
     17 #endif
     18 
     19 #include <X11/X.h>
     20 #include <X11/Xproto.h>
     21 #include "scrnintstr.h"
     22 #include "window.h"
     23 #include "windowstr.h"
     24 #include "colormapst.h"
     25 #include "resource.h"
     26 
     27 #include "Xnest.h"
     28 
     29 #include "Display.h"
     30 #include "Screen.h"
     31 #include "Color.h"
     32 #include "Visual.h"
     33 #include "XNWindow.h"
     34 #include "Args.h"
     35 
     36 DevPrivateKeyRec xnestColormapPrivateKeyRec;
     37 
     38 static DevPrivateKeyRec cmapScrPrivateKeyRec;
     39 
     40 #define cmapScrPrivateKey (&cmapScrPrivateKeyRec)
     41 
     42 #define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
     43 #define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
     44 
     45 Bool
     46 xnestCreateColormap(ColormapPtr pCmap)
     47 {
     48     VisualPtr pVisual;
     49     XColor *colors;
     50     int i, ncolors;
     51     Pixel red, green, blue;
     52     Pixel redInc, greenInc, blueInc;
     53 
     54     pVisual = pCmap->pVisual;
     55     ncolors = pVisual->ColormapEntries;
     56 
     57     xnestColormapPriv(pCmap)->colormap =
     58         XCreateColormap(xnestDisplay,
     59                         xnestDefaultWindows[pCmap->pScreen->myNum],
     60                         xnestVisual(pVisual),
     61                         (pVisual->class & DynamicClass) ? AllocAll : AllocNone);
     62 
     63     switch (pVisual->class) {
     64     case StaticGray:           /* read only */
     65         colors = xallocarray(ncolors, sizeof(XColor));
     66         for (i = 0; i < ncolors; i++)
     67             colors[i].pixel = i;
     68         XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
     69         for (i = 0; i < ncolors; i++) {
     70             pCmap->red[i].co.local.red = colors[i].red;
     71             pCmap->red[i].co.local.green = colors[i].red;
     72             pCmap->red[i].co.local.blue = colors[i].red;
     73         }
     74         free(colors);
     75         break;
     76 
     77     case StaticColor:          /* read only */
     78         colors = xallocarray(ncolors, sizeof(XColor));
     79         for (i = 0; i < ncolors; i++)
     80             colors[i].pixel = i;
     81         XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
     82         for (i = 0; i < ncolors; i++) {
     83             pCmap->red[i].co.local.red = colors[i].red;
     84             pCmap->red[i].co.local.green = colors[i].green;
     85             pCmap->red[i].co.local.blue = colors[i].blue;
     86         }
     87         free(colors);
     88         break;
     89 
     90     case TrueColor:            /* read only */
     91         colors = xallocarray(ncolors, sizeof(XColor));
     92         red = green = blue = 0L;
     93         redInc = lowbit(pVisual->redMask);
     94         greenInc = lowbit(pVisual->greenMask);
     95         blueInc = lowbit(pVisual->blueMask);
     96         for (i = 0; i < ncolors; i++) {
     97             colors[i].pixel = red | green | blue;
     98             red += redInc;
     99             if (red > pVisual->redMask)
    100                 red = 0L;
    101             green += greenInc;
    102             if (green > pVisual->greenMask)
    103                 green = 0L;
    104             blue += blueInc;
    105             if (blue > pVisual->blueMask)
    106                 blue = 0L;
    107         }
    108         XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
    109         for (i = 0; i < ncolors; i++) {
    110             pCmap->red[i].co.local.red = colors[i].red;
    111             pCmap->green[i].co.local.green = colors[i].green;
    112             pCmap->blue[i].co.local.blue = colors[i].blue;
    113         }
    114         free(colors);
    115         break;
    116 
    117     case GrayScale:            /* read and write */
    118         break;
    119 
    120     case PseudoColor:          /* read and write */
    121         break;
    122 
    123     case DirectColor:          /* read and write */
    124         break;
    125     }
    126 
    127     return True;
    128 }
    129 
    130 void
    131 xnestDestroyColormap(ColormapPtr pCmap)
    132 {
    133     XFreeColormap(xnestDisplay, xnestColormap(pCmap));
    134 }
    135 
    136 #define SEARCH_PREDICATE \
    137   (xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
    138 
    139 static int
    140 xnestCountInstalledColormapWindows(WindowPtr pWin, void *ptr)
    141 {
    142     xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *) ptr;
    143     int i;
    144 
    145     for (i = 0; i < icws->numCmapIDs; i++)
    146         if (SEARCH_PREDICATE) {
    147             icws->numWindows++;
    148             return WT_DONTWALKCHILDREN;
    149         }
    150 
    151     return WT_WALKCHILDREN;
    152 }
    153 
    154 static int
    155 xnestGetInstalledColormapWindows(WindowPtr pWin, void *ptr)
    156 {
    157     xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *) ptr;
    158     int i;
    159 
    160     for (i = 0; i < icws->numCmapIDs; i++)
    161         if (SEARCH_PREDICATE) {
    162             icws->windows[icws->index++] = xnestWindow(pWin);
    163             return WT_DONTWALKCHILDREN;
    164         }
    165 
    166     return WT_WALKCHILDREN;
    167 }
    168 
    169 static Window *xnestOldInstalledColormapWindows = NULL;
    170 static int xnestNumOldInstalledColormapWindows = 0;
    171 
    172 static Bool
    173 xnestSameInstalledColormapWindows(Window *windows, int numWindows)
    174 {
    175     if (xnestNumOldInstalledColormapWindows != numWindows)
    176         return False;
    177 
    178     if (xnestOldInstalledColormapWindows == windows)
    179         return True;
    180 
    181     if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
    182         return False;
    183 
    184     if (memcmp(xnestOldInstalledColormapWindows, windows,
    185                numWindows * sizeof(Window)))
    186         return False;
    187 
    188     return True;
    189 }
    190 
    191 void
    192 xnestSetInstalledColormapWindows(ScreenPtr pScreen)
    193 {
    194     xnestInstalledColormapWindows icws;
    195     int numWindows;
    196 
    197     icws.cmapIDs = xallocarray(pScreen->maxInstalledCmaps, sizeof(Colormap));
    198     icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
    199     icws.numWindows = 0;
    200     WalkTree(pScreen, xnestCountInstalledColormapWindows, (void *) &icws);
    201     if (icws.numWindows) {
    202         icws.windows = xallocarray(icws.numWindows + 1, sizeof(Window));
    203         icws.index = 0;
    204         WalkTree(pScreen, xnestGetInstalledColormapWindows, (void *) &icws);
    205         icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
    206         numWindows = icws.numWindows + 1;
    207     }
    208     else {
    209         icws.windows = NULL;
    210         numWindows = 0;
    211     }
    212 
    213     free(icws.cmapIDs);
    214 
    215     if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
    216         free(xnestOldInstalledColormapWindows);
    217 
    218 #ifdef _XSERVER64
    219         {
    220             int i;
    221             Window64 *windows = xallocarray(numWindows, sizeof(Window64));
    222 
    223             for (i = 0; i < numWindows; ++i)
    224                 windows[i] = icws.windows[i];
    225             XSetWMColormapWindows(xnestDisplay,
    226                                   xnestDefaultWindows[pScreen->myNum], windows,
    227                                   numWindows);
    228             free(windows);
    229         }
    230 #else
    231         XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
    232                               icws.windows, numWindows);
    233 #endif
    234 
    235         xnestOldInstalledColormapWindows = icws.windows;
    236         xnestNumOldInstalledColormapWindows = icws.numWindows;
    237 
    238 #ifdef DUMB_WINDOW_MANAGERS
    239         /*
    240            This code is for dumb window managers.
    241            This will only work with default local visual colormaps.
    242          */
    243         if (icws.numWindows) {
    244             WindowPtr pWin;
    245             Visual *visual;
    246             ColormapPtr pCmap;
    247 
    248             pWin = xnestWindowPtr(icws.windows[0]);
    249             visual = xnestVisualFromID(pScreen, wVisual(pWin));
    250 
    251             if (visual == xnestDefaultVisual(pScreen))
    252                 dixLookupResourceByType((void **) &pCmap, wColormap(pWin),
    253                                         RT_COLORMAP, serverClient,
    254                                         DixUseAccess);
    255             else
    256                 dixLookupResourceByType((void **) &pCmap,
    257                                         pScreen->defColormap, RT_COLORMAP,
    258                                         serverClient, DixUseAccess);
    259 
    260             XSetWindowColormap(xnestDisplay,
    261                                xnestDefaultWindows[pScreen->myNum],
    262                                xnestColormap(pCmap));
    263         }
    264 #endif                          /* DUMB_WINDOW_MANAGERS */
    265     }
    266     else
    267         free(icws.windows);
    268 }
    269 
    270 void
    271 xnestSetScreenSaverColormapWindow(ScreenPtr pScreen)
    272 {
    273     free(xnestOldInstalledColormapWindows);
    274 
    275 #ifdef _XSERVER64
    276     {
    277         Window64 window;
    278 
    279         window = xnestScreenSaverWindows[pScreen->myNum];
    280         XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
    281                               &window, 1);
    282         xnestScreenSaverWindows[pScreen->myNum] = window;
    283     }
    284 #else
    285     XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
    286                           &xnestScreenSaverWindows[pScreen->myNum], 1);
    287 #endif                          /* _XSERVER64 */
    288 
    289     xnestOldInstalledColormapWindows = NULL;
    290     xnestNumOldInstalledColormapWindows = 0;
    291 
    292     xnestDirectUninstallColormaps(pScreen);
    293 }
    294 
    295 void
    296 xnestDirectInstallColormaps(ScreenPtr pScreen)
    297 {
    298     int i, n;
    299     Colormap pCmapIDs[MAXCMAPS];
    300 
    301     if (!xnestDoDirectColormaps)
    302         return;
    303 
    304     n = (*pScreen->ListInstalledColormaps) (pScreen, pCmapIDs);
    305 
    306     for (i = 0; i < n; i++) {
    307         ColormapPtr pCmap;
    308 
    309         dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], RT_COLORMAP,
    310                                 serverClient, DixInstallAccess);
    311         if (pCmap)
    312             XInstallColormap(xnestDisplay, xnestColormap(pCmap));
    313     }
    314 }
    315 
    316 void
    317 xnestDirectUninstallColormaps(ScreenPtr pScreen)
    318 {
    319     int i, n;
    320     Colormap pCmapIDs[MAXCMAPS];
    321 
    322     if (!xnestDoDirectColormaps)
    323         return;
    324 
    325     n = (*pScreen->ListInstalledColormaps) (pScreen, pCmapIDs);
    326 
    327     for (i = 0; i < n; i++) {
    328         ColormapPtr pCmap;
    329 
    330         dixLookupResourceByType((void **) &pCmap, pCmapIDs[i], RT_COLORMAP,
    331                                 serverClient, DixUninstallAccess);
    332         if (pCmap)
    333             XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
    334     }
    335 }
    336 
    337 void
    338 xnestInstallColormap(ColormapPtr pCmap)
    339 {
    340     ColormapPtr pOldCmap = GetInstalledColormap(pCmap->pScreen);
    341 
    342     if (pCmap != pOldCmap) {
    343         xnestDirectUninstallColormaps(pCmap->pScreen);
    344 
    345         /* Uninstall pInstalledMap. Notify all interested parties. */
    346         if (pOldCmap != (ColormapPtr) None)
    347             WalkTree(pCmap->pScreen, TellLostMap, (void *) &pOldCmap->mid);
    348 
    349         SetInstalledColormap(pCmap->pScreen, pCmap);
    350         WalkTree(pCmap->pScreen, TellGainedMap, (void *) &pCmap->mid);
    351 
    352         xnestSetInstalledColormapWindows(pCmap->pScreen);
    353         xnestDirectInstallColormaps(pCmap->pScreen);
    354     }
    355 }
    356 
    357 void
    358 xnestUninstallColormap(ColormapPtr pCmap)
    359 {
    360     ColormapPtr pCurCmap = GetInstalledColormap(pCmap->pScreen);
    361 
    362     if (pCmap == pCurCmap) {
    363         if (pCmap->mid != pCmap->pScreen->defColormap) {
    364             dixLookupResourceByType((void **) &pCurCmap,
    365                                     pCmap->pScreen->defColormap,
    366                                     RT_COLORMAP,
    367                                     serverClient, DixInstallAccess);
    368             (*pCmap->pScreen->InstallColormap) (pCurCmap);
    369         }
    370     }
    371 }
    372 
    373 static Bool xnestInstalledDefaultColormap = False;
    374 
    375 int
    376 xnestListInstalledColormaps(ScreenPtr pScreen, Colormap * pCmapIDs)
    377 {
    378     if (xnestInstalledDefaultColormap) {
    379         *pCmapIDs = GetInstalledColormap(pScreen)->mid;
    380         return 1;
    381     }
    382     else
    383         return 0;
    384 }
    385 
    386 void
    387 xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem * pColors)
    388 {
    389     if (pCmap->pVisual->class & DynamicClass)
    390 #ifdef _XSERVER64
    391     {
    392         int i;
    393         XColor *pColors64 = xallocarray(nColors, sizeof(XColor));
    394 
    395         for (i = 0; i < nColors; ++i) {
    396             pColors64[i].pixel = pColors[i].pixel;
    397             pColors64[i].red = pColors[i].red;
    398             pColors64[i].green = pColors[i].green;
    399             pColors64[i].blue = pColors[i].blue;
    400             pColors64[i].flags = pColors[i].flags;
    401         }
    402         XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
    403         free(pColors64);
    404     }
    405 #else
    406         XStoreColors(xnestDisplay, xnestColormap(pCmap),
    407                      (XColor *) pColors, nColors);
    408 #endif
    409 }
    410 
    411 void
    412 xnestResolveColor(unsigned short *pRed, unsigned short *pGreen,
    413                   unsigned short *pBlue, VisualPtr pVisual)
    414 {
    415     int shift;
    416     unsigned int lim;
    417 
    418     shift = 16 - pVisual->bitsPerRGBValue;
    419     lim = (1 << pVisual->bitsPerRGBValue) - 1;
    420 
    421     if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor)) {
    422         /* rescale to rgb bits */
    423         *pRed = ((*pRed >> shift) * 65535) / lim;
    424         *pGreen = ((*pGreen >> shift) * 65535) / lim;
    425         *pBlue = ((*pBlue >> shift) * 65535) / lim;
    426     }
    427     else if (pVisual->class == GrayScale) {
    428         /* rescale to gray then rgb bits */
    429         *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
    430         *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
    431     }
    432     else if (pVisual->class == StaticGray) {
    433         unsigned int limg;
    434 
    435         limg = pVisual->ColormapEntries - 1;
    436         /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
    437         *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
    438         *pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
    439         *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
    440     }
    441     else {
    442         unsigned limr, limg, limb;
    443 
    444         limr = pVisual->redMask >> pVisual->offsetRed;
    445         limg = pVisual->greenMask >> pVisual->offsetGreen;
    446         limb = pVisual->blueMask >> pVisual->offsetBlue;
    447         /* rescale to [0..limN] then [0..65535] then rgb bits */
    448         *pRed = ((((((*pRed * (limr + 1)) >> 16) *
    449                     65535) / limr) >> shift) * 65535) / lim;
    450         *pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
    451                       65535) / limg) >> shift) * 65535) / lim;
    452         *pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
    453                      65535) / limb) >> shift) * 65535) / lim;
    454     }
    455 }
    456 
    457 Bool
    458 xnestCreateDefaultColormap(ScreenPtr pScreen)
    459 {
    460     VisualPtr pVisual;
    461     ColormapPtr pCmap;
    462     unsigned short zero = 0, ones = 0xFFFF;
    463     Pixel wp, bp;
    464 
    465     if (!dixRegisterPrivateKey(&cmapScrPrivateKeyRec, PRIVATE_SCREEN, 0))
    466         return FALSE;
    467 
    468     for (pVisual = pScreen->visuals;
    469          pVisual->vid != pScreen->rootVisual; pVisual++);
    470 
    471     if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
    472                        (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
    473                        0)
    474         != Success)
    475         return False;
    476 
    477     wp = pScreen->whitePixel;
    478     bp = pScreen->blackPixel;
    479     if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
    480          Success) ||
    481         (AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) != Success))
    482         return FALSE;
    483     pScreen->whitePixel = wp;
    484     pScreen->blackPixel = bp;
    485     (*pScreen->InstallColormap) (pCmap);
    486 
    487     xnestInstalledDefaultColormap = True;
    488 
    489     return True;
    490 }