diff options
Diffstat (limited to 'xorg-server/render/filter.c')
-rw-r--r-- | xorg-server/render/filter.c | 718 |
1 files changed, 359 insertions, 359 deletions
diff --git a/xorg-server/render/filter.c b/xorg-server/render/filter.c index 89cc0646a..53fb86f3d 100644 --- a/xorg-server/render/filter.c +++ b/xorg-server/render/filter.c @@ -1,359 +1,359 @@ -/* - * 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 = xalloc (len + 1); - if (!name) - return -1; - memcpy (name, filter, len); - name[len] = '\0'; - if (filterNames) - names = xrealloc (filterNames, (nfilterNames + 1) * sizeof (char *)); - else - names = xalloc (sizeof (char *)); - if (!names) - { - xfree (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++) - xfree (filterNames[i]); - xfree (filterNames); - nfilterNames = 0; - filterNames = 0; -} - -int -PictureAddFilter (ScreenPtr pScreen, - char *filter, - PictFilterValidateParamsProcPtr ValidateParams, - int width, - int height) -{ - 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 = xrealloc (ps->filters, (ps->nfilters + 1) * sizeof (PictFilterRec)); - else - filters = xalloc (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; - ps->filters[i].width = width; - ps->filters[i].height = height; - return id; -} - -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 = xrealloc (ps->filterAliases, - (ps->nfilterAliases + 1) * - sizeof (PictFilterAliasRec)); - else - aliases = xalloc (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 (ScreenPtr pScreen, - int filter, - xFixed *params, - int nparams, - int *width, - int *height) -{ - int w, h; - if (nparams < 3) - return FALSE; - - if (xFixedFrac (params[0]) || xFixedFrac (params[1])) - return FALSE; - - w = xFixedToInt (params[0]); - h = xFixedToInt (params[1]); - - nparams -= 2; - if (w * h > nparams) - return FALSE; - - *width = w; - *height = h; - return TRUE; -} - - -Bool -PictureSetDefaultFilters (ScreenPtr pScreen) -{ - if (!filterNames) - if (!PictureSetDefaultIds ()) - return FALSE; - if (PictureAddFilter (pScreen, FilterNearest, 0, 1, 1) < 0) - return FALSE; - if (PictureAddFilter (pScreen, FilterBilinear, 0, 2, 2) < 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, 0) < 0) - return FALSE; - - return TRUE; -} - -void -PictureResetFilters (ScreenPtr pScreen) -{ - PictureScreenPtr ps = GetPictureScreen(pScreen); - - xfree (ps->filters); - xfree (ps->filterAliases); - PictureFreeFilterIds (); -} - -int -SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int nparams) -{ - PictFilterPtr pFilter; - ScreenPtr pScreen; - - if (pPicture->pDrawable != NULL) - pScreen = pPicture->pDrawable->pScreen; - else - pScreen = screenInfo.screens[0]; - - pFilter = PictureFindFilter (pScreen, name, len); - - if (!pFilter) - return BadName; - - if (pPicture->pDrawable == NULL) - { - int s; - /* 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 = 1; s < screenInfo.numScreens; s++) - { - PictFilterPtr pScreenFilter; - pScreenFilter = PictureFindFilter (screenInfo.screens[s], - name, len); - if (!pScreenFilter || pScreenFilter->id != pFilter->id) - return BadMatch; - } - } - return SetPicturePictFilter (pPicture, pFilter, params, nparams); -} - -int -SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter, - xFixed *params, int nparams) -{ - ScreenPtr pScreen; - int i; - - if (pPicture->pDrawable) - pScreen = pPicture->pDrawable->pScreen; - else - pScreen = screenInfo.screens[0]; - - if (pFilter->ValidateParams) - { - int width, height; - if (!(*pFilter->ValidateParams) (pScreen, pFilter->id, params, nparams, &width, &height)) - return BadMatch; - } - else if (nparams) - return BadMatch; - - if (nparams != pPicture->filter_nparams) - { - xFixed *new_params = xalloc (nparams * sizeof (xFixed)); - if (!new_params && nparams) - return BadAlloc; - xfree (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) - { - PictureScreenPtr ps = GetPictureScreen(pScreen); - int result; - - result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter, - params, nparams); - return result; - } - return Success; -} +/*
+ * 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;
+}
+
+int
+PictureAddFilter (ScreenPtr pScreen,
+ char *filter,
+ PictFilterValidateParamsProcPtr ValidateParams,
+ int width,
+ int height)
+{
+ 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;
+ ps->filters[i].width = width;
+ ps->filters[i].height = height;
+ return id;
+}
+
+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 (ScreenPtr pScreen,
+ int filter,
+ xFixed *params,
+ int nparams,
+ int *width,
+ int *height)
+{
+ int w, h;
+ if (nparams < 3)
+ return FALSE;
+
+ if (xFixedFrac (params[0]) || xFixedFrac (params[1]))
+ return FALSE;
+
+ w = xFixedToInt (params[0]);
+ h = xFixedToInt (params[1]);
+
+ nparams -= 2;
+ if (w * h > nparams)
+ return FALSE;
+
+ *width = w;
+ *height = h;
+ return TRUE;
+}
+
+
+Bool
+PictureSetDefaultFilters (ScreenPtr pScreen)
+{
+ if (!filterNames)
+ if (!PictureSetDefaultIds ())
+ return FALSE;
+ if (PictureAddFilter (pScreen, FilterNearest, 0, 1, 1) < 0)
+ return FALSE;
+ if (PictureAddFilter (pScreen, FilterBilinear, 0, 2, 2) < 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, 0) < 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;
+ ScreenPtr pScreen;
+
+ if (pPicture->pDrawable != NULL)
+ pScreen = pPicture->pDrawable->pScreen;
+ else
+ pScreen = screenInfo.screens[0];
+
+ pFilter = PictureFindFilter (pScreen, name, len);
+
+ if (!pFilter)
+ return BadName;
+
+ if (pPicture->pDrawable == NULL)
+ {
+ int s;
+ /* 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 = 1; s < screenInfo.numScreens; s++)
+ {
+ PictFilterPtr pScreenFilter;
+ pScreenFilter = PictureFindFilter (screenInfo.screens[s],
+ name, len);
+ if (!pScreenFilter || pScreenFilter->id != pFilter->id)
+ return BadMatch;
+ }
+ }
+ return SetPicturePictFilter (pPicture, pFilter, params, nparams);
+}
+
+int
+SetPicturePictFilter (PicturePtr pPicture, PictFilterPtr pFilter,
+ xFixed *params, int nparams)
+{
+ ScreenPtr pScreen;
+ int i;
+
+ if (pPicture->pDrawable)
+ pScreen = pPicture->pDrawable->pScreen;
+ else
+ pScreen = screenInfo.screens[0];
+
+ if (pFilter->ValidateParams)
+ {
+ int width, height;
+ if (!(*pFilter->ValidateParams) (pScreen, pFilter->id, params, nparams, &width, &height))
+ return BadMatch;
+ }
+ else if (nparams)
+ return BadMatch;
+
+ if (nparams != pPicture->filter_nparams)
+ {
+ xFixed *new_params = malloc(nparams * sizeof (xFixed));
+ if (!new_params && nparams)
+ 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)
+ {
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ int result;
+
+ result = (*ps->ChangePictureFilter) (pPicture, pPicture->filter,
+ params, nparams);
+ return result;
+ }
+ return Success;
+}
|