123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- /*
- *
- * Copyright © 2002 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- #ifdef HAVE_DIX_CONFIG_H
- #include <dix-config.h>
- #endif
- #include "misc.h"
- #include "scrnintstr.h"
- #include "os.h"
- #include "regionstr.h"
- #include "validate.h"
- #include "windowstr.h"
- #include "input.h"
- #include "resource.h"
- #include "colormapst.h"
- #include "cursorstr.h"
- #include "dixstruct.h"
- #include "gcstruct.h"
- #include "servermd.h"
- #include "picturestr.h"
- static char **filterNames;
- static int nfilterNames;
- /*
- * standard but not required filters don't have constant indices
- */
- int
- PictureGetFilterId(char *filter, int len, Bool makeit)
- {
- int i;
- char *name;
- char **names;
- if (len < 0)
- len = strlen(filter);
- for (i = 0; i < nfilterNames; i++)
- if (!CompareISOLatin1Lowered
- ((unsigned char *) filterNames[i], -1, (unsigned char *) filter,
- len))
- return i;
- if (!makeit)
- return -1;
- name = malloc(len + 1);
- if (!name)
- return -1;
- memcpy(name, filter, len);
- name[len] = '\0';
- if (filterNames)
- names = realloc(filterNames, (nfilterNames + 1) * sizeof(char *));
- else
- names = malloc(sizeof(char *));
- if (!names) {
- free(name);
- return -1;
- }
- filterNames = names;
- i = nfilterNames++;
- filterNames[i] = name;
- return i;
- }
- static Bool
- PictureSetDefaultIds(void)
- {
- /* careful here -- this list must match the #define values */
- if (PictureGetFilterId(FilterNearest, -1, TRUE) != PictFilterNearest)
- return FALSE;
- if (PictureGetFilterId(FilterBilinear, -1, TRUE) != PictFilterBilinear)
- return FALSE;
- if (PictureGetFilterId(FilterFast, -1, TRUE) != PictFilterFast)
- return FALSE;
- if (PictureGetFilterId(FilterGood, -1, TRUE) != PictFilterGood)
- return FALSE;
- if (PictureGetFilterId(FilterBest, -1, TRUE) != PictFilterBest)
- return FALSE;
- if (PictureGetFilterId(FilterConvolution, -1, TRUE) !=
- PictFilterConvolution)
- return FALSE;
- return TRUE;
- }
- char *
- PictureGetFilterName(int id)
- {
- if (0 <= id && id < nfilterNames)
- return filterNames[id];
- else
- return 0;
- }
- static void
- PictureFreeFilterIds(void)
- {
- int i;
- for (i = 0; i < nfilterNames; i++)
- free(filterNames[i]);
- free(filterNames);
- nfilterNames = 0;
- filterNames = 0;
- }
- _X_EXPORT int
- PictureAddFilter(ScreenPtr pScreen,
- char *filter, PictFilterValidateParamsProcPtr ValidateParams)
- {
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- int id = PictureGetFilterId(filter, -1, TRUE);
- int i;
- PictFilterPtr filters;
- if (id < 0)
- return -1;
- /*
- * It's an error to attempt to reregister a filter
- */
- for (i = 0; i < ps->nfilters; i++)
- if (ps->filters[i].id == id)
- return -1;
- if (ps->filters)
- filters =
- realloc(ps->filters, (ps->nfilters + 1) * sizeof(PictFilterRec));
- else
- filters = malloc(sizeof(PictFilterRec));
- if (!filters)
- return -1;
- ps->filters = filters;
- i = ps->nfilters++;
- ps->filters[i].name = PictureGetFilterName(id);
- ps->filters[i].id = id;
- ps->filters[i].ValidateParams = ValidateParams;
- return id;
- }
- _X_EXPORT Bool
- PictureSetFilterAlias(ScreenPtr pScreen, char *filter, char *alias)
- {
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- int filter_id = PictureGetFilterId(filter, -1, FALSE);
- int alias_id = PictureGetFilterId(alias, -1, TRUE);
- int i;
- if (filter_id < 0 || alias_id < 0)
- return FALSE;
- for (i = 0; i < ps->nfilterAliases; i++)
- if (ps->filterAliases[i].alias_id == alias_id)
- break;
- if (i == ps->nfilterAliases) {
- PictFilterAliasPtr aliases;
- if (ps->filterAliases)
- aliases = realloc(ps->filterAliases,
- (ps->nfilterAliases + 1) *
- sizeof(PictFilterAliasRec));
- else
- aliases = malloc(sizeof(PictFilterAliasRec));
- if (!aliases)
- return FALSE;
- ps->filterAliases = aliases;
- ps->filterAliases[i].alias = PictureGetFilterName(alias_id);
- ps->filterAliases[i].alias_id = alias_id;
- ps->nfilterAliases++;
- }
- ps->filterAliases[i].filter_id = filter_id;
- return TRUE;
- }
- PictFilterPtr
- PictureFindFilter(ScreenPtr pScreen, char *name, int len)
- {
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- int id = PictureGetFilterId(name, len, FALSE);
- int i;
- if (id < 0)
- return 0;
- /* Check for an alias, allow them to recurse */
- for (i = 0; i < ps->nfilterAliases; i++)
- if (ps->filterAliases[i].alias_id == id) {
- id = ps->filterAliases[i].filter_id;
- i = 0;
- }
- /* find the filter */
- for (i = 0; i < ps->nfilters; i++)
- if (ps->filters[i].id == id)
- return &ps->filters[i];
- return 0;
- }
- static Bool
- convolutionFilterValidateParams(PicturePtr pPicture,
- int filter, xFixed * params, int nparams)
- {
- if (nparams < 3)
- return FALSE;
- if (xFixedFrac(params[0]) || xFixedFrac(params[1]))
- return FALSE;
- nparams -= 2;
- if ((xFixedToInt(params[0]) * xFixedToInt(params[1])) > nparams)
- return FALSE;
- return TRUE;
- }
- Bool
- PictureSetDefaultFilters(ScreenPtr pScreen)
- {
- if (!filterNames)
- if (!PictureSetDefaultIds())
- return FALSE;
- if (PictureAddFilter(pScreen, FilterNearest, 0) < 0)
- return FALSE;
- if (PictureAddFilter(pScreen, FilterBilinear, 0) < 0)
- return FALSE;
- if (!PictureSetFilterAlias(pScreen, FilterNearest, FilterFast))
- return FALSE;
- if (!PictureSetFilterAlias(pScreen, FilterBilinear, FilterGood))
- return FALSE;
- if (!PictureSetFilterAlias(pScreen, FilterBilinear, FilterBest))
- return FALSE;
- if (PictureAddFilter
- (pScreen, FilterConvolution, convolutionFilterValidateParams) < 0)
- return FALSE;
- return TRUE;
- }
- void
- PictureResetFilters(ScreenPtr pScreen)
- {
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- free(ps->filters);
- free(ps->filterAliases);
- PictureFreeFilterIds();
- }
- int
- SetPictureFilter(PicturePtr pPicture, char *name, int len, xFixed * params,
- int nparams)
- {
- PictFilterPtr pFilter;
- xFixed *new_params;
- int i, s, result;
- pFilter = PictureFindFilter(screenInfo.screens[0], name, len);
- if (!pFilter)
- return BadName;
- if (pPicture->pDrawable == NULL) {
- /* For source pictures, the picture isn't tied to a screen. So, ensure
- * that all screens can handle a filter we set for the picture.
- */
- for (s = 0; s < screenInfo.numScreens; s++) {
- PictFilterPtr tmp = PictureFindFilter(screenInfo.screens[s], name, len);
- if (!tmp) return BadName;
- if (tmp->id != pFilter->id) {
- return BadMatch;
- }
- }
- }
- if (pFilter->ValidateParams) {
- if (!(*pFilter->ValidateParams)
- (pPicture, pFilter->id, params, nparams))
- return BadMatch;
- }
- else if (nparams)
- return BadMatch;
- if (nparams != pPicture->filter_nparams) {
- new_params = malloc(nparams * sizeof(xFixed));
- if (!new_params)
- return BadAlloc;
- free(pPicture->filter_params);
- pPicture->filter_params = new_params;
- pPicture->filter_nparams = nparams;
- }
- for (i = 0; i < nparams; i++)
- pPicture->filter_params[i] = params[i];
- pPicture->filter = pFilter->id;
- if (pPicture->pDrawable) {
- ScreenPtr pScreen = pPicture->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter,
- params, nparams);
- return result;
- }
- return Success;
- }
|