Home | History | Annotate | Line # | Download | only in src
      1 /*
      2  *
      3  * Copyright  2002 Keith Packard
      4  *
      5  * Permission to use, copy, modify, distribute, and sell this software and its
      6  * documentation for any purpose is hereby granted without fee, provided that
      7  * the above copyright notice appear in all copies and that both that
      8  * copyright notice and this permission notice appear in supporting
      9  * documentation, and that the name of Keith Packard not be used in
     10  * advertising or publicity pertaining to distribution of the software without
     11  * specific, written prior permission.  Keith Packard makes no
     12  * representations about the suitability of this software for any purpose.  It
     13  * is provided "as is" without express or implied warranty.
     14  *
     15  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     17  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     21  * PERFORMANCE OF THIS SOFTWARE.
     22  */
     23 
     24 #ifdef HAVE_CONFIG_H
     25 #include <config.h>
     26 #endif
     27 #include "Xrenderint.h"
     28 #include <limits.h>
     29 
     30 XFilters *
     31 XRenderQueryFilters (Display *dpy, Drawable drawable)
     32 {
     33     XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
     34     XRenderInfo			*xri;
     35     xRenderQueryFiltersReq	*req;
     36     xRenderQueryFiltersReply	rep;
     37     XFilters			*filters;
     38     char			*name;
     39     char			len;
     40     unsigned int		i;
     41     unsigned long		nbytesName, reply_left;
     42 
     43     if (!RenderHasExtension (info))
     44 	return NULL;
     45 
     46     if (!XRenderQueryFormats (dpy))
     47 	return NULL;
     48 
     49     xri = info->info;
     50     if (xri->minor_version < 6)
     51 	return NULL;
     52 
     53     LockDisplay (dpy);
     54     GetReq (RenderQueryFilters, req);
     55     req->reqType = (CARD8) info->codes->major_opcode;
     56     req->renderReqType = X_RenderQueryFilters;
     57     req->drawable = (CARD32) drawable;
     58     if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
     59     {
     60 	UnlockDisplay (dpy);
     61 	SyncHandle ();
     62 	return NULL;
     63     }
     64 
     65     /*
     66      * Limit each component of combined size to 1/4 the max, which is far
     67      * more than they should ever possibly need.
     68      */
     69     if ((rep.length < (INT_MAX >> 2)) &&
     70 	(rep.numFilters < ((INT_MAX / 4) / sizeof (char *))) &&
     71 	(rep.numAliases < ((INT_MAX / 4) / sizeof (short)))) {
     72 	unsigned long		nbytes, nbytesAlias;
     73 
     74 	/*
     75 	 * Compute total number of bytes for filter names
     76 	 */
     77 	nbytes = (unsigned long)rep.length << 2;
     78 	nbytesAlias = rep.numAliases * 2;
     79 	if (rep.numAliases & 1)
     80 	    nbytesAlias += 2;
     81 	nbytesName = nbytes - nbytesAlias;
     82 
     83 	/*
     84 	 * Allocate one giant block for the whole data structure
     85 	 */
     86 	filters = Xmalloc (sizeof (XFilters) +
     87 			   (rep.numFilters * sizeof (char *)) +
     88 			   (rep.numAliases * sizeof (short)) +
     89 			   nbytesName);
     90     } else
     91 	filters = NULL;
     92 
     93     if (!filters)
     94     {
     95 	_XEatDataWords(dpy, rep.length);
     96 	UnlockDisplay (dpy);
     97 	SyncHandle ();
     98 	return NULL;
     99     }
    100 
    101     /*
    102      * Layout:
    103      *	XFilters
    104      *	numFilters  char * pointers to filter names
    105      *	numAliases  short alias values
    106      *	nbytesName  char strings
    107      */
    108 
    109     filters->nfilter = (int) rep.numFilters;
    110     filters->nalias = (int) rep.numAliases;
    111     filters->filter = (char **) (filters + 1);
    112     filters->alias = (short *) (filters->filter + rep.numFilters);
    113     name = (char *) (filters->alias + rep.numAliases);
    114 
    115     /*
    116      * Read the filter aliases
    117      */
    118     _XRead16Pad (dpy, filters->alias, 2 * rep.numAliases);
    119     reply_left = 8 + rep.length - 2 * rep.numAliases;;
    120 
    121     /*
    122      * Read the filter names
    123      */
    124     for (i = 0; i < rep.numFilters; i++)
    125     {
    126 	int	l;
    127 	_XRead (dpy, &len, 1);
    128 	reply_left--;
    129 	l = len & 0xff;
    130 	if ((unsigned long)l + 1 > nbytesName) {
    131             _XEatDataWords(dpy, reply_left);
    132 	    Xfree(filters);
    133 	    UnlockDisplay (dpy);
    134 	    SyncHandle ();
    135 	    return NULL;
    136 	}
    137 	nbytesName -= (unsigned long) (l + 1);
    138 	filters->filter[i] = name;
    139 	_XRead (dpy, name, l);
    140         reply_left -= (unsigned long) l;
    141 	name[l] = '\0';
    142 	name += l + 1;
    143     }
    144     i = (unsigned) (name - (char *) (filters->alias + rep.numAliases));
    145 
    146     if (i & 3)
    147 	_XEatData (dpy, 4 - (i & 3));
    148 
    149     UnlockDisplay (dpy);
    150     SyncHandle ();
    151     return filters;
    152 }
    153 
    154 void
    155 XRenderSetPictureFilter  (Display   *dpy,
    156 			  Picture   picture,
    157 			  const char *filter,
    158 			  XFixed    *params,
    159 			  int	    nparams)
    160 {
    161     XRenderExtDisplayInfo	*info = XRenderFindDisplay (dpy);
    162     xRenderSetPictureFilterReq	*req;
    163     int				nbytes = (int) strlen (filter);
    164 
    165     RenderSimpleCheckExtension (dpy, info);
    166     LockDisplay(dpy);
    167     GetReq(RenderSetPictureFilter, req);
    168     req->reqType = (CARD8) info->codes->major_opcode;
    169     req->renderReqType = X_RenderSetPictureFilter;
    170     req->picture = (CARD32) picture;
    171     req->nbytes = (CARD16) nbytes;
    172     req->length = (CARD16) (req->length + (((nbytes + 3) >> 2) + nparams));
    173     Data (dpy, filter, nbytes);
    174     Data (dpy, (_Xconst char *)params, (nparams << 2));
    175     UnlockDisplay(dpy);
    176     SyncHandle();
    177 }
    178