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 30XFilters * 31XRenderQueryFilters (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 154void 155XRenderSetPictureFilter (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