xserver

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

filter.c (10050B)


      1 /*
      2  * Copyright © 2002 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 "misc.h"
     28 #include "scrnintstr.h"
     29 #include "os.h"
     30 #include "regionstr.h"
     31 #include "validate.h"
     32 #include "windowstr.h"
     33 #include "input.h"
     34 #include "resource.h"
     35 #include "colormapst.h"
     36 #include "cursorstr.h"
     37 #include "dixstruct.h"
     38 #include "gcstruct.h"
     39 #include "servermd.h"
     40 #include "picturestr.h"
     41 
     42 static char **filterNames;
     43 static int nfilterNames;
     44 
     45 /*
     46  * standard but not required filters don't have constant indices
     47  */
     48 
     49 int
     50 PictureGetFilterId(const char *filter, int len, Bool makeit)
     51 {
     52     int i;
     53     char *name;
     54     char **names;
     55 
     56     if (len < 0)
     57         len = strlen(filter);
     58     for (i = 0; i < nfilterNames; i++)
     59         if (!CompareISOLatin1Lowered((const unsigned char *) filterNames[i], -1,
     60                                      (const unsigned char *) filter, len))
     61             return i;
     62     if (!makeit)
     63         return -1;
     64     name = malloc(len + 1);
     65     if (!name)
     66         return -1;
     67     memcpy(name, filter, len);
     68     name[len] = '\0';
     69     if (filterNames)
     70         names = reallocarray(filterNames, nfilterNames + 1, sizeof(char *));
     71     else
     72         names = malloc(sizeof(char *));
     73     if (!names) {
     74         free(name);
     75         return -1;
     76     }
     77     filterNames = names;
     78     i = nfilterNames++;
     79     filterNames[i] = name;
     80     return i;
     81 }
     82 
     83 static Bool
     84 PictureSetDefaultIds(void)
     85 {
     86     /* careful here -- this list must match the #define values */
     87 
     88     if (PictureGetFilterId(FilterNearest, -1, TRUE) != PictFilterNearest)
     89         return FALSE;
     90     if (PictureGetFilterId(FilterBilinear, -1, TRUE) != PictFilterBilinear)
     91         return FALSE;
     92 
     93     if (PictureGetFilterId(FilterFast, -1, TRUE) != PictFilterFast)
     94         return FALSE;
     95     if (PictureGetFilterId(FilterGood, -1, TRUE) != PictFilterGood)
     96         return FALSE;
     97     if (PictureGetFilterId(FilterBest, -1, TRUE) != PictFilterBest)
     98         return FALSE;
     99 
    100     if (PictureGetFilterId(FilterConvolution, -1, TRUE) !=
    101         PictFilterConvolution)
    102         return FALSE;
    103     return TRUE;
    104 }
    105 
    106 char *
    107 PictureGetFilterName(int id)
    108 {
    109     if (0 <= id && id < nfilterNames)
    110         return filterNames[id];
    111     else
    112         return 0;
    113 }
    114 
    115 static void
    116 PictureFreeFilterIds(void)
    117 {
    118     int i;
    119 
    120     for (i = 0; i < nfilterNames; i++)
    121         free(filterNames[i]);
    122     free(filterNames);
    123     nfilterNames = 0;
    124     filterNames = 0;
    125 }
    126 
    127 int
    128 PictureAddFilter(ScreenPtr pScreen,
    129                  const char *filter,
    130                  PictFilterValidateParamsProcPtr ValidateParams,
    131                  int width, int height)
    132 {
    133     PictureScreenPtr ps = GetPictureScreen(pScreen);
    134     int id = PictureGetFilterId(filter, -1, TRUE);
    135     int i;
    136     PictFilterPtr filters;
    137 
    138     if (id < 0)
    139         return -1;
    140     /*
    141      * It's an error to attempt to reregister a filter
    142      */
    143     for (i = 0; i < ps->nfilters; i++)
    144         if (ps->filters[i].id == id)
    145             return -1;
    146     if (ps->filters)
    147         filters =
    148             reallocarray(ps->filters, ps->nfilters + 1, sizeof(PictFilterRec));
    149     else
    150         filters = malloc(sizeof(PictFilterRec));
    151     if (!filters)
    152         return -1;
    153     ps->filters = filters;
    154     i = ps->nfilters++;
    155     ps->filters[i].name = PictureGetFilterName(id);
    156     ps->filters[i].id = id;
    157     ps->filters[i].ValidateParams = ValidateParams;
    158     ps->filters[i].width = width;
    159     ps->filters[i].height = height;
    160     return id;
    161 }
    162 
    163 Bool
    164 PictureSetFilterAlias(ScreenPtr pScreen, const char *filter, const char *alias)
    165 {
    166     PictureScreenPtr ps = GetPictureScreen(pScreen);
    167     int filter_id = PictureGetFilterId(filter, -1, FALSE);
    168     int alias_id = PictureGetFilterId(alias, -1, TRUE);
    169     int i;
    170 
    171     if (filter_id < 0 || alias_id < 0)
    172         return FALSE;
    173     for (i = 0; i < ps->nfilterAliases; i++)
    174         if (ps->filterAliases[i].alias_id == alias_id)
    175             break;
    176     if (i == ps->nfilterAliases) {
    177         PictFilterAliasPtr aliases;
    178 
    179         if (ps->filterAliases)
    180             aliases = reallocarray(ps->filterAliases,
    181                                    ps->nfilterAliases + 1,
    182                                    sizeof(PictFilterAliasRec));
    183         else
    184             aliases = malloc(sizeof(PictFilterAliasRec));
    185         if (!aliases)
    186             return FALSE;
    187         ps->filterAliases = aliases;
    188         ps->filterAliases[i].alias = PictureGetFilterName(alias_id);
    189         ps->filterAliases[i].alias_id = alias_id;
    190         ps->nfilterAliases++;
    191     }
    192     ps->filterAliases[i].filter_id = filter_id;
    193     return TRUE;
    194 }
    195 
    196 PictFilterPtr
    197 PictureFindFilter(ScreenPtr pScreen, char *name, int len)
    198 {
    199     PictureScreenPtr ps = GetPictureScreen(pScreen);
    200     int id = PictureGetFilterId(name, len, FALSE);
    201     int i;
    202 
    203     if (id < 0)
    204         return 0;
    205     /* Check for an alias, allow them to recurse */
    206     for (i = 0; i < ps->nfilterAliases; i++)
    207         if (ps->filterAliases[i].alias_id == id) {
    208             id = ps->filterAliases[i].filter_id;
    209             i = 0;
    210         }
    211     /* find the filter */
    212     for (i = 0; i < ps->nfilters; i++)
    213         if (ps->filters[i].id == id)
    214             return &ps->filters[i];
    215     return 0;
    216 }
    217 
    218 static Bool
    219 convolutionFilterValidateParams(ScreenPtr pScreen,
    220                                 int filter,
    221                                 xFixed * params,
    222                                 int nparams, int *width, int *height)
    223 {
    224     int w, h;
    225 
    226     if (nparams < 3)
    227         return FALSE;
    228 
    229     if (xFixedFrac(params[0]) || xFixedFrac(params[1]))
    230         return FALSE;
    231 
    232     w = xFixedToInt(params[0]);
    233     h = xFixedToInt(params[1]);
    234 
    235     nparams -= 2;
    236     if (w * h > nparams)
    237         return FALSE;
    238 
    239     *width = w;
    240     *height = h;
    241     return TRUE;
    242 }
    243 
    244 Bool
    245 PictureSetDefaultFilters(ScreenPtr pScreen)
    246 {
    247     if (!filterNames)
    248         if (!PictureSetDefaultIds())
    249             return FALSE;
    250     if (PictureAddFilter(pScreen, FilterNearest, 0, 1, 1) < 0)
    251         return FALSE;
    252     if (PictureAddFilter(pScreen, FilterBilinear, 0, 2, 2) < 0)
    253         return FALSE;
    254 
    255     if (!PictureSetFilterAlias(pScreen, FilterNearest, FilterFast))
    256         return FALSE;
    257     if (!PictureSetFilterAlias(pScreen, FilterBilinear, FilterGood))
    258         return FALSE;
    259     if (!PictureSetFilterAlias(pScreen, FilterBilinear, FilterBest))
    260         return FALSE;
    261 
    262     if (PictureAddFilter
    263         (pScreen, FilterConvolution, convolutionFilterValidateParams, 0, 0) < 0)
    264         return FALSE;
    265 
    266     return TRUE;
    267 }
    268 
    269 void
    270 PictureResetFilters(ScreenPtr pScreen)
    271 {
    272     PictureScreenPtr ps = GetPictureScreen(pScreen);
    273 
    274     free(ps->filters);
    275     free(ps->filterAliases);
    276 
    277     /* Free the filters when the last screen is closed */
    278     if (pScreen->myNum == 0)
    279         PictureFreeFilterIds();
    280 }
    281 
    282 int
    283 SetPictureFilter(PicturePtr pPicture, char *name, int len, xFixed * params,
    284                  int nparams)
    285 {
    286     PictFilterPtr pFilter;
    287     ScreenPtr pScreen;
    288 
    289     if (pPicture->pDrawable != NULL)
    290         pScreen = pPicture->pDrawable->pScreen;
    291     else
    292         pScreen = screenInfo.screens[0];
    293 
    294     pFilter = PictureFindFilter(pScreen, name, len);
    295 
    296     if (!pFilter)
    297         return BadName;
    298 
    299     if (pPicture->pDrawable == NULL) {
    300         int s;
    301 
    302         /* For source pictures, the picture isn't tied to a screen.  So, ensure
    303          * that all screens can handle a filter we set for the picture.
    304          */
    305         for (s = 1; s < screenInfo.numScreens; s++) {
    306             PictFilterPtr pScreenFilter;
    307 
    308             pScreenFilter = PictureFindFilter(screenInfo.screens[s], name, len);
    309             if (!pScreenFilter || pScreenFilter->id != pFilter->id)
    310                 return BadMatch;
    311         }
    312     }
    313     return SetPicturePictFilter(pPicture, pFilter, params, nparams);
    314 }
    315 
    316 int
    317 SetPicturePictFilter(PicturePtr pPicture, PictFilterPtr pFilter,
    318                      xFixed * params, int nparams)
    319 {
    320     ScreenPtr pScreen;
    321     int i;
    322 
    323     if (pPicture->pDrawable)
    324         pScreen = pPicture->pDrawable->pScreen;
    325     else
    326         pScreen = screenInfo.screens[0];
    327 
    328     if (pFilter->ValidateParams) {
    329         int width, height;
    330 
    331         if (!(*pFilter->ValidateParams)
    332             (pScreen, pFilter->id, params, nparams, &width, &height))
    333             return BadMatch;
    334     }
    335     else if (nparams)
    336         return BadMatch;
    337 
    338     if (nparams != pPicture->filter_nparams) {
    339         xFixed *new_params = xallocarray(nparams, sizeof(xFixed));
    340 
    341         if (!new_params && nparams)
    342             return BadAlloc;
    343         free(pPicture->filter_params);
    344         pPicture->filter_params = new_params;
    345         pPicture->filter_nparams = nparams;
    346     }
    347     for (i = 0; i < nparams; i++)
    348         pPicture->filter_params[i] = params[i];
    349     pPicture->filter = pFilter->id;
    350 
    351     if (pPicture->pDrawable) {
    352         PictureScreenPtr ps = GetPictureScreen(pScreen);
    353         int result;
    354 
    355         result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter,
    356                                              params, nparams);
    357         return result;
    358     }
    359     return Success;
    360 }