xserver

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

micmap.c (17580B)


      1 /*
      2  * Copyright (c) 1987, 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 
     24 /*
     25  * This is based on cfbcmap.c.  The functions here are useful independently
     26  * of cfb, which is the reason for including them here.  How "mi" these
     27  * are may be debatable.
     28  */
     29 
     30 #ifdef HAVE_DIX_CONFIG_H
     31 #include <dix-config.h>
     32 #endif
     33 
     34 #include <X11/X.h>
     35 #include <X11/Xproto.h>
     36 #include "scrnintstr.h"
     37 #include "colormapst.h"
     38 #include "resource.h"
     39 #include "globals.h"
     40 #include "micmap.h"
     41 
     42 DevPrivateKeyRec micmapScrPrivateKeyRec;
     43 
     44 int
     45 miListInstalledColormaps(ScreenPtr pScreen, Colormap * pmaps)
     46 {
     47     if (GetInstalledmiColormap(pScreen)) {
     48         *pmaps = GetInstalledmiColormap(pScreen)->mid;
     49         return 1;
     50     }
     51     return 0;
     52 }
     53 
     54 void
     55 miInstallColormap(ColormapPtr pmap)
     56 {
     57     ColormapPtr oldpmap = GetInstalledmiColormap(pmap->pScreen);
     58 
     59     if (pmap != oldpmap) {
     60         /* Uninstall pInstalledMap. No hardware changes required, just
     61          * notify all interested parties. */
     62         if (oldpmap != (ColormapPtr) None)
     63             WalkTree(pmap->pScreen, TellLostMap, (char *) &oldpmap->mid);
     64         /* Install pmap */
     65         SetInstalledmiColormap(pmap->pScreen, pmap);
     66         WalkTree(pmap->pScreen, TellGainedMap, (char *) &pmap->mid);
     67 
     68     }
     69 }
     70 
     71 void
     72 miUninstallColormap(ColormapPtr pmap)
     73 {
     74     ColormapPtr curpmap = GetInstalledmiColormap(pmap->pScreen);
     75 
     76     if (pmap == curpmap) {
     77         if (pmap->mid != pmap->pScreen->defColormap) {
     78             dixLookupResourceByType((void **) &curpmap,
     79                                     pmap->pScreen->defColormap,
     80                                     RT_COLORMAP, serverClient, DixUseAccess);
     81             (*pmap->pScreen->InstallColormap) (curpmap);
     82         }
     83     }
     84 }
     85 
     86 void
     87 miResolveColor(unsigned short *pred, unsigned short *pgreen,
     88                unsigned short *pblue, VisualPtr pVisual)
     89 {
     90     int shift = 16 - pVisual->bitsPerRGBValue;
     91     unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
     92 
     93     if ((pVisual->class | DynamicClass) == GrayScale) {
     94         /* rescale to gray then rgb bits */
     95         *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
     96         *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
     97     }
     98     else {
     99         /* rescale to rgb bits */
    100         *pred = ((*pred >> shift) * 65535) / lim;
    101         *pgreen = ((*pgreen >> shift) * 65535) / lim;
    102         *pblue = ((*pblue >> shift) * 65535) / lim;
    103     }
    104 }
    105 
    106 Bool
    107 miInitializeColormap(ColormapPtr pmap)
    108 {
    109     unsigned i;
    110     VisualPtr pVisual;
    111     unsigned lim, maxent, shift;
    112 
    113     pVisual = pmap->pVisual;
    114     lim = (1 << pVisual->bitsPerRGBValue) - 1;
    115     shift = 16 - pVisual->bitsPerRGBValue;
    116     maxent = pVisual->ColormapEntries - 1;
    117     if (pVisual->class == TrueColor) {
    118         unsigned limr, limg, limb;
    119 
    120         limr = pVisual->redMask >> pVisual->offsetRed;
    121         limg = pVisual->greenMask >> pVisual->offsetGreen;
    122         limb = pVisual->blueMask >> pVisual->offsetBlue;
    123         for (i = 0; i <= maxent; i++) {
    124             /* rescale to [0..65535] then rgb bits */
    125             pmap->red[i].co.local.red =
    126                 ((((i * 65535) / limr) >> shift) * 65535) / lim;
    127             pmap->green[i].co.local.green =
    128                 ((((i * 65535) / limg) >> shift) * 65535) / lim;
    129             pmap->blue[i].co.local.blue =
    130                 ((((i * 65535) / limb) >> shift) * 65535) / lim;
    131         }
    132     }
    133     else if (pVisual->class == StaticColor) {
    134         unsigned limr, limg, limb;
    135 
    136         limr = pVisual->redMask >> pVisual->offsetRed;
    137         limg = pVisual->greenMask >> pVisual->offsetGreen;
    138         limb = pVisual->blueMask >> pVisual->offsetBlue;
    139         for (i = 0; i <= maxent; i++) {
    140             /* rescale to [0..65535] then rgb bits */
    141             pmap->red[i].co.local.red =
    142                 ((((((i & pVisual->redMask) >> pVisual->offsetRed)
    143                     * 65535) / limr) >> shift) * 65535) / lim;
    144             pmap->red[i].co.local.green =
    145                 ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
    146                     * 65535) / limg) >> shift) * 65535) / lim;
    147             pmap->red[i].co.local.blue =
    148                 ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
    149                     * 65535) / limb) >> shift) * 65535) / lim;
    150         }
    151     }
    152     else if (pVisual->class == StaticGray) {
    153         for (i = 0; i <= maxent; i++) {
    154             /* rescale to [0..65535] then rgb bits */
    155             pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
    156                                          * 65535) / lim;
    157             pmap->red[i].co.local.green = pmap->red[i].co.local.red;
    158             pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
    159         }
    160     }
    161     return TRUE;
    162 }
    163 
    164 /* When simulating DirectColor on PseudoColor hardware, multiple
    165    entries of the colormap must be updated
    166  */
    167 
    168 #define AddElement(mask) { \
    169     pixel = red | green | blue; \
    170     for (i = 0; i < nresult; i++) \
    171   	if (outdefs[i].pixel == pixel) \
    172     	    break; \
    173     if (i == nresult) \
    174     { \
    175    	nresult++; \
    176 	outdefs[i].pixel = pixel; \
    177 	outdefs[i].flags = 0; \
    178     } \
    179     outdefs[i].flags |= (mask); \
    180     outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
    181     outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
    182     outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
    183 }
    184 
    185 int
    186 miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem * indefs,
    187                      xColorItem * outdefs)
    188 {
    189     int red, green, blue;
    190     int maxred, maxgreen, maxblue;
    191     int stepred, stepgreen, stepblue;
    192     VisualPtr pVisual;
    193     int pixel;
    194     int nresult;
    195     int i;
    196 
    197     pVisual = pmap->pVisual;
    198 
    199     stepred = 1 << pVisual->offsetRed;
    200     stepgreen = 1 << pVisual->offsetGreen;
    201     stepblue = 1 << pVisual->offsetBlue;
    202     maxred = pVisual->redMask;
    203     maxgreen = pVisual->greenMask;
    204     maxblue = pVisual->blueMask;
    205     nresult = 0;
    206     for (; ndef--; indefs++) {
    207         if (indefs->flags & DoRed) {
    208             red = indefs->pixel & pVisual->redMask;
    209             for (green = 0; green <= maxgreen; green += stepgreen) {
    210                 for (blue = 0; blue <= maxblue; blue += stepblue) {
    211                     AddElement(DoRed)
    212                 }
    213             }
    214         }
    215         if (indefs->flags & DoGreen) {
    216             green = indefs->pixel & pVisual->greenMask;
    217             for (red = 0; red <= maxred; red += stepred) {
    218                 for (blue = 0; blue <= maxblue; blue += stepblue) {
    219                     AddElement(DoGreen)
    220                 }
    221             }
    222         }
    223         if (indefs->flags & DoBlue) {
    224             blue = indefs->pixel & pVisual->blueMask;
    225             for (red = 0; red <= maxred; red += stepred) {
    226                 for (green = 0; green <= maxgreen; green += stepgreen) {
    227                     AddElement(DoBlue)
    228                 }
    229             }
    230         }
    231     }
    232     return nresult;
    233 }
    234 
    235 Bool
    236 miCreateDefColormap(ScreenPtr pScreen)
    237 {
    238     unsigned short zero = 0, ones = 0xFFFF;
    239     Pixel wp, bp;
    240     VisualPtr pVisual;
    241     ColormapPtr cmap;
    242     int alloctype;
    243 
    244     if (!dixRegisterPrivateKey(&micmapScrPrivateKeyRec, PRIVATE_SCREEN, 0))
    245         return FALSE;
    246 
    247     for (pVisual = pScreen->visuals;
    248          pVisual->vid != pScreen->rootVisual; pVisual++);
    249 
    250     if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass))
    251         alloctype = AllocNone;
    252     else
    253         alloctype = AllocAll;
    254 
    255     if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
    256                        alloctype, 0) != Success)
    257         return FALSE;
    258 
    259     if (pScreen->rootDepth > 1) {
    260         wp = pScreen->whitePixel;
    261         bp = pScreen->blackPixel;
    262         if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
    263              Success) ||
    264             (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != Success))
    265             return FALSE;
    266         pScreen->whitePixel = wp;
    267         pScreen->blackPixel = bp;
    268     }
    269 
    270     (*pScreen->InstallColormap) (cmap);
    271     return TRUE;
    272 }
    273 
    274 /*
    275  * Default true color bitmasks, should be overridden by
    276  * driver
    277  */
    278 
    279 #define _RZ(d) ((d + 2) / 3)
    280 #define _RS(d) 0
    281 #define _RM(d) ((1U << _RZ(d)) - 1)
    282 #define _GZ(d) ((d - _RZ(d) + 1) / 2)
    283 #define _GS(d) _RZ(d)
    284 #define _GM(d) (((1U << _GZ(d)) - 1) << _GS(d))
    285 #define _BZ(d) (d - _RZ(d) - _GZ(d))
    286 #define _BS(d) (_RZ(d) + _GZ(d))
    287 #define _BM(d) (((1U << _BZ(d)) - 1) << _BS(d))
    288 #define _CE(d) (1U << _RZ(d))
    289 
    290 typedef struct _miVisuals {
    291     struct _miVisuals *next;
    292     int depth;
    293     int bitsPerRGB;
    294     int visuals;
    295     int count;
    296     int preferredCVC;
    297     Pixel redMask, greenMask, blueMask;
    298 } miVisualsRec, *miVisualsPtr;
    299 
    300 static int miVisualPriority[] = {
    301     PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray
    302 };
    303 
    304 #define NUM_PRIORITY	6
    305 
    306 static miVisualsPtr miVisuals;
    307 
    308 void
    309 miClearVisualTypes(void)
    310 {
    311     miVisualsPtr v;
    312 
    313     while ((v = miVisuals)) {
    314         miVisuals = v->next;
    315         free(v);
    316     }
    317 }
    318 
    319 Bool
    320 miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
    321                          int preferredCVC,
    322                          Pixel redMask, Pixel greenMask, Pixel blueMask)
    323 {
    324     miVisualsPtr new, *prev, v;
    325     int count;
    326 
    327     new = malloc(sizeof *new);
    328     if (!new)
    329         return FALSE;
    330     if (!redMask || !greenMask || !blueMask) {
    331         redMask = _RM(depth);
    332         greenMask = _GM(depth);
    333         blueMask = _BM(depth);
    334     }
    335     new->next = 0;
    336     new->depth = depth;
    337     new->visuals = visuals;
    338     new->bitsPerRGB = bitsPerRGB;
    339     new->preferredCVC = preferredCVC;
    340     new->redMask = redMask;
    341     new->greenMask = greenMask;
    342     new->blueMask = blueMask;
    343     count = (visuals >> 1) & 033333333333;
    344     count = visuals - count - ((count >> 1) & 033333333333);
    345     count = (((count + (count >> 3)) & 030707070707) % 077);    /* HAKMEM 169 */
    346     new->count = count;
    347     for (prev = &miVisuals; (v = *prev); prev = &v->next);
    348     *prev = new;
    349     return TRUE;
    350 }
    351 
    352 Bool
    353 miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
    354 {
    355     return miSetVisualTypesAndMasks(depth, visuals, bitsPerRGB,
    356                                     preferredCVC, 0, 0, 0);
    357 }
    358 
    359 int
    360 miGetDefaultVisualMask(int depth)
    361 {
    362     if (depth > MAX_PSEUDO_DEPTH)
    363         return LARGE_VISUALS;
    364     else if (depth >= MIN_TRUE_DEPTH)
    365         return ALL_VISUALS;
    366     else if (depth == 1)
    367         return StaticGrayMask;
    368     else
    369         return SMALL_VISUALS;
    370 }
    371 
    372 static Bool
    373 miVisualTypesSet(int depth)
    374 {
    375     miVisualsPtr visuals;
    376 
    377     for (visuals = miVisuals; visuals; visuals = visuals->next)
    378         if (visuals->depth == depth)
    379             return TRUE;
    380     return FALSE;
    381 }
    382 
    383 Bool
    384 miSetPixmapDepths(void)
    385 {
    386     int d, f;
    387 
    388     /* Add any unlisted depths from the pixmap formats */
    389     for (f = 0; f < screenInfo.numPixmapFormats; f++) {
    390         d = screenInfo.formats[f].depth;
    391         if (!miVisualTypesSet(d)) {
    392             if (!miSetVisualTypes(d, 0, 0, -1))
    393                 return FALSE;
    394         }
    395     }
    396     return TRUE;
    397 }
    398 
    399 /*
    400  * Distance to least significant one bit
    401  */
    402 static int
    403 maskShift(Pixel p)
    404 {
    405     int s;
    406 
    407     if (!p)
    408         return 0;
    409     s = 0;
    410     while (!(p & 1)) {
    411         s++;
    412         p >>= 1;
    413     }
    414     return s;
    415 }
    416 
    417 /*
    418  * Given a list of formats for a screen, create a list
    419  * of visuals and depths for the screen which correspond to
    420  * the set which can be used with this version of cfb.
    421  */
    422 
    423 Bool
    424 miInitVisuals(VisualPtr * visualp, DepthPtr * depthp, int *nvisualp,
    425               int *ndepthp, int *rootDepthp, VisualID * defaultVisp,
    426               unsigned long sizes, int bitsPerRGB, int preferredVis)
    427 {
    428     int i, j = 0, k;
    429     VisualPtr visual;
    430     DepthPtr depth;
    431     VisualID *vid;
    432     int d, b;
    433     int f;
    434     int ndepth, nvisual;
    435     int nvtype;
    436     int vtype;
    437     miVisualsPtr visuals, nextVisuals;
    438     int *preferredCVCs, *prefp;
    439     int first_depth;
    440 
    441     /* none specified, we'll guess from pixmap formats */
    442     if (!miVisuals) {
    443         for (f = 0; f < screenInfo.numPixmapFormats; f++) {
    444             d = screenInfo.formats[f].depth;
    445             b = screenInfo.formats[f].bitsPerPixel;
    446             if (sizes & (1 << (b - 1)))
    447                 vtype = miGetDefaultVisualMask(d);
    448             else
    449                 vtype = 0;
    450             if (!miSetVisualTypes(d, vtype, bitsPerRGB, -1))
    451                 return FALSE;
    452         }
    453     }
    454     nvisual = 0;
    455     ndepth = 0;
    456     for (visuals = miVisuals; visuals; visuals = nextVisuals) {
    457         nextVisuals = visuals->next;
    458         ndepth++;
    459         nvisual += visuals->count;
    460     }
    461     depth = xallocarray(ndepth, sizeof(DepthRec));
    462     visual = xallocarray(nvisual, sizeof(VisualRec));
    463     preferredCVCs = xallocarray(ndepth, sizeof(int));
    464     if (!depth || !visual || !preferredCVCs) {
    465         free(depth);
    466         free(visual);
    467         free(preferredCVCs);
    468         return FALSE;
    469     }
    470     *depthp = depth;
    471     *visualp = visual;
    472     *ndepthp = ndepth;
    473     *nvisualp = nvisual;
    474     prefp = preferredCVCs;
    475     for (visuals = miVisuals; visuals; visuals = nextVisuals) {
    476         nextVisuals = visuals->next;
    477         d = visuals->depth;
    478         vtype = visuals->visuals;
    479         nvtype = visuals->count;
    480         *prefp = visuals->preferredCVC;
    481         prefp++;
    482         vid = NULL;
    483         if (nvtype) {
    484             vid = xallocarray(nvtype, sizeof(VisualID));
    485             if (!vid) {
    486                 free(depth);
    487                 free(visual);
    488                 free(preferredCVCs);
    489                 return FALSE;
    490             }
    491         }
    492         depth->depth = d;
    493         depth->numVids = nvtype;
    494         depth->vids = vid;
    495         depth++;
    496         for (i = 0; i < NUM_PRIORITY; i++) {
    497             if (!(vtype & (1 << miVisualPriority[i])))
    498                 continue;
    499             visual->class = miVisualPriority[i];
    500             visual->bitsPerRGBValue = visuals->bitsPerRGB;
    501             visual->ColormapEntries = 1 << d;
    502             visual->nplanes = d;
    503             visual->vid = *vid = FakeClientID(0);
    504             switch (visual->class) {
    505             case PseudoColor:
    506             case GrayScale:
    507             case StaticGray:
    508                 visual->redMask = 0;
    509                 visual->greenMask = 0;
    510                 visual->blueMask = 0;
    511                 visual->offsetRed = 0;
    512                 visual->offsetGreen = 0;
    513                 visual->offsetBlue = 0;
    514                 break;
    515             case DirectColor:
    516             case TrueColor:
    517                 visual->ColormapEntries = _CE(d);
    518                 /* fall through */
    519             case StaticColor:
    520                 visual->redMask = visuals->redMask;
    521                 visual->greenMask = visuals->greenMask;
    522                 visual->blueMask = visuals->blueMask;
    523                 visual->offsetRed = maskShift(visuals->redMask);
    524                 visual->offsetGreen = maskShift(visuals->greenMask);
    525                 visual->offsetBlue = maskShift(visuals->blueMask);
    526             }
    527             vid++;
    528             visual++;
    529         }
    530         free(visuals);
    531     }
    532     miVisuals = NULL;
    533     visual = *visualp;
    534     depth = *depthp;
    535 
    536     /*
    537      * if we did not supplyied by a preferred visual class
    538      * check if there is a preferred class in one of the depth
    539      * structures - if there is, we want to start looking for the
    540      * default visual/depth from that depth.
    541      */
    542     first_depth = 0;
    543     if (preferredVis < 0 && defaultColorVisualClass < 0) {
    544         for (i = 0; i < ndepth; i++) {
    545             if (preferredCVCs[i] >= 0) {
    546                 first_depth = i;
    547                 break;
    548             }
    549         }
    550     }
    551 
    552     for (i = first_depth; i < ndepth; i++) {
    553         int prefColorVisualClass = -1;
    554 
    555         if (defaultColorVisualClass >= 0)
    556             prefColorVisualClass = defaultColorVisualClass;
    557         else if (preferredVis >= 0)
    558             prefColorVisualClass = preferredVis;
    559         else if (preferredCVCs[i] >= 0)
    560             prefColorVisualClass = preferredCVCs[i];
    561 
    562         if (*rootDepthp && *rootDepthp != depth[i].depth)
    563             continue;
    564 
    565         for (j = 0; j < depth[i].numVids; j++) {
    566             for (k = 0; k < nvisual; k++)
    567                 if (visual[k].vid == depth[i].vids[j])
    568                     break;
    569             if (k == nvisual)
    570                 continue;
    571             if (prefColorVisualClass < 0 ||
    572                 visual[k].class == prefColorVisualClass)
    573                 break;
    574         }
    575         if (j != depth[i].numVids)
    576             break;
    577     }
    578     if (i == ndepth) {
    579         i = 0;
    580         j = 0;
    581     }
    582     *rootDepthp = depth[i].depth;
    583     *defaultVisp = depth[i].vids[j];
    584     free(preferredCVCs);
    585 
    586     return TRUE;
    587 }