diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:49 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:49 +0000 |
commit | 35a608915a0512ca419fb0d4f3116fd68d2d8bc5 (patch) | |
tree | 873678b8071055f68b904166058a24714305f3e5 /src |
Diffstat (limited to 'src')
-rw-r--r-- | src/Color.c | 90 | ||||
-rw-r--r-- | src/Composite.c | 65 | ||||
-rw-r--r-- | src/Cursor.c | 77 | ||||
-rw-r--r-- | src/FillRect.c | 104 | ||||
-rw-r--r-- | src/FillRects.c | 77 | ||||
-rw-r--r-- | src/Filter.c | 150 | ||||
-rw-r--r-- | src/Glyph.c | 710 | ||||
-rw-r--r-- | src/Picture.c | 241 | ||||
-rw-r--r-- | src/Poly.c | 300 | ||||
-rw-r--r-- | src/Trap.c | 72 | ||||
-rw-r--r-- | src/Tri.c | 167 | ||||
-rw-r--r-- | src/Xrender.c | 657 | ||||
-rw-r--r-- | src/Xrenderint.h | 99 |
13 files changed, 2809 insertions, 0 deletions
diff --git a/src/Color.c b/src/Color.c new file mode 100644 index 0000000..53af267 --- /dev/null +++ b/src/Color.c @@ -0,0 +1,90 @@ +/* + * $XFree86: xc/lib/Xrender/Color.c,v 1.1 2002/05/17 22:34:18 keithp Exp $ + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * 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. + */ + +#include "Xrenderint.h" + +Status +XRenderParseColor(Display *dpy, char *spec, XRenderColor *def) +{ + + if (!strncmp (spec, "rgba:", 5)) + { + unsigned short elements[4]; + unsigned short *pShort; + int i, n; + char c; + + spec += 5; + /* + * Attempt to parse the value portion. + */ + pShort = elements; + for (i = 0; i < 4; i++, pShort++, spec++) { + n = 0; + *pShort = 0; + while (*spec != '/' && *spec != '\0') { + if (++n > 4) { + return 0; + } + c = *spec++; + *pShort <<= 4; + if (c >= '0' && c <= '9') + *pShort |= c - '0'; + /* assume string in lowercase + else if (c >= 'A' && c <= 'F') + *pShort |= c - ('A' - 10); + */ + else if (c >= 'a' && c <= 'f') + *pShort |= c - ('a' - 10); + else return 0; + } + if (n == 0) + return 0; + if (n < 4) { + *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1); + } + } + def->red = elements[0]; + def->green = elements[1]; + def->blue = elements[2]; + def->alpha = elements[3]; + } + else + { + XColor coreColor; + Colormap colormap; + + colormap = DefaultColormap (dpy, DefaultScreen (dpy)); + if (!XParseColor (dpy, colormap, spec, &coreColor)) + return 0; + def->red = coreColor.red; + def->green = coreColor.green; + def->blue = coreColor.blue; + def->alpha = 0xffff; + } + def->red = (def->red * def->alpha) / 65535; + def->green = (def->green * def->alpha) / 65535; + def->blue = (def->blue * def->alpha) / 65535; + return 1; +} diff --git a/src/Composite.c b/src/Composite.c new file mode 100644 index 0000000..b58c935 --- /dev/null +++ b/src/Composite.c @@ -0,0 +1,65 @@ +/* + * $XFree86: xc/lib/Xrender/Composite.c,v 1.2 2000/08/28 02:43:13 tsi Exp $ + * + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#include "Xrenderint.h" + +void +XRenderComposite (Display *dpy, + int op, + Picture src, + Picture mask, + Picture dst, + int src_x, + int src_y, + int mask_x, + int mask_y, + int dst_x, + int dst_y, + unsigned int width, + unsigned int height) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderCompositeReq *req; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + GetReq(RenderComposite, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderComposite; + req->op = (CARD8) op; + req->src = src; + req->mask = mask; + req->dst = dst; + req->xSrc = src_x; + req->ySrc = src_y; + req->xMask = mask_x; + req->yMask = mask_y; + req->xDst = dst_x; + req->yDst = dst_y; + req->width = width; + req->height = height; + UnlockDisplay(dpy); + SyncHandle(); +} diff --git a/src/Cursor.c b/src/Cursor.c new file mode 100644 index 0000000..b1a8e2b --- /dev/null +++ b/src/Cursor.c @@ -0,0 +1,77 @@ +/* + * $XFree86: xc/lib/Xrender/Cursor.c,v 1.3 2002/11/24 21:46:15 tsi Exp $ + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * 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. + */ + +#include "Xrenderint.h" + +Cursor +XRenderCreateCursor (Display *dpy, + Picture source, + unsigned int x, + unsigned int y) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + Cursor cid; + xRenderCreateCursorReq *req; + + RenderCheckExtension (dpy, info, 0); + LockDisplay(dpy); + GetReq(RenderCreateCursor, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCreateCursor; + req->cid = cid = XAllocID (dpy); + req->src = source; + req->x = x; + req->y = y; + + UnlockDisplay(dpy); + SyncHandle(); + return cid; +} + +Cursor +XRenderCreateAnimCursor (Display *dpy, + int ncursor, + XAnimCursor *cursors) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + Cursor cid; + xRenderCreateAnimCursorReq *req; + long len; + + RenderCheckExtension (dpy, info, 0); + LockDisplay(dpy); + GetReq(RenderCreateAnimCursor, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCreateAnimCursor; + req->cid = cid = XAllocID (dpy); + + len = (long) ncursor * SIZEOF (xAnimCursorElt) >> 2; + SetReqLen (req, len, len); + len <<= 2; + Data32 (dpy, (long *) cursors, len); + + UnlockDisplay(dpy); + SyncHandle(); + return cid; +} diff --git a/src/FillRect.c b/src/FillRect.c new file mode 100644 index 0000000..15e3875 --- /dev/null +++ b/src/FillRect.c @@ -0,0 +1,104 @@ +/* + * $XFree86: xc/lib/Xrender/FillRect.c,v 1.2 2001/12/16 18:27:55 keithp Exp $ + * + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#include "Xrenderint.h" + +/* precompute the maximum size of batching request allowed */ + +#define size (SIZEOF(xRenderFillRectanglesReq) + FRCTSPERBATCH * SIZEOF(xRectangle)) + +void +XRenderFillRectangle (Display *dpy, + int op, + Picture dst, + _Xconst XRenderColor *color, + int x, + int y, + unsigned int width, + unsigned int height) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRectangle *rect; + xRenderFillRectanglesReq *req; +#ifdef MUSTCOPY + xRectangle rectdata; + long len = SIZEOF(xRectangle); + + rect = &rectdata; +#endif /* MUSTCOPY */ + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + req = (xRenderFillRectanglesReq *) dpy->last_req; + /* if same as previous request, with same drawable, batch requests */ + if (req->reqType == info->codes->major_opcode && + req->renderReqType == X_RenderFillRectangles && + req->op == op && + req->dst == dst && + req->color.red == color->red && + req->color.green == color->green && + req->color.blue == color->blue && + req->color.alpha == color->alpha && + dpy->bufptr + SIZEOF(xRectangle) <= dpy->bufmax && + (char *)dpy->bufptr - (char *)req < size) + { + req->length += SIZEOF(xRectangle) >> 2; +#ifndef MUSTCOPY + rect = (xRectangle *) dpy->bufptr; + dpy->bufptr += SIZEOF(xRectangle); +#endif /* not MUSTCOPY */ + } + else + { + GetReqExtra(RenderFillRectangles, SIZEOF(xRectangle), req); + + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderFillRectangles; + req->op = op; + req->dst = dst; + req->color.red = color->red; + req->color.green = color->green; + req->color.blue = color->blue; + req->color.alpha = color->alpha; + +#ifdef MUSTCOPY + dpy->bufptr -= SIZEOF(xRectangle); +#else + rect = (xRectangle *) NEXTPTR(req,xRenderFillRectanglesReq); +#endif /* MUSTCOPY */ + } + rect->x = x; + rect->y = y; + rect->width = width; + rect->height = height; + +#ifdef MUSTCOPY + Data (dpy, (char *) rect, len); +#endif /* MUSTCOPY */ + UnlockDisplay(dpy); + SyncHandle(); +} + diff --git a/src/FillRects.c b/src/FillRects.c new file mode 100644 index 0000000..b251930 --- /dev/null +++ b/src/FillRects.c @@ -0,0 +1,77 @@ +/* + * $XFree86: xc/lib/Xrender/FillRects.c,v 1.2 2001/12/16 18:27:55 keithp Exp $ + * + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#include "Xrenderint.h" + +/* precompute the maximum size of batching request allowed */ + +#define size (SIZEOF(xRenderFillRectanglesReq) + FRCTSPERBATCH * SIZEOF(xRectangle)) + +void +XRenderFillRectangles (Display *dpy, + int op, + Picture dst, + _Xconst XRenderColor *color, + _Xconst XRectangle *rectangles, + int n_rects) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderFillRectanglesReq *req; + long len; + int n; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + while (n_rects) + { + GetReq(RenderFillRectangles, req); + + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderFillRectangles; + req->op = op; + req->dst = dst; + req->color.red = color->red; + req->color.green = color->green; + req->color.blue = color->blue; + req->color.alpha = color->alpha; + + n = n_rects; + len = ((long)n) << 1; + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) + { + n = (dpy->max_request_size - req->length) >> 1; + len = ((long)n) << 1; + } + SetReqLen(req, len, len); + len <<= 2; /* watch out for macros... */ + Data16 (dpy, (short *) rectangles, len); + n_rects -= n; + rectangles += n; + } + UnlockDisplay(dpy); + SyncHandle(); +} + diff --git a/src/Filter.c b/src/Filter.c new file mode 100644 index 0000000..dfc5480 --- /dev/null +++ b/src/Filter.c @@ -0,0 +1,150 @@ +/* + * $XFree86: xc/lib/Xrender/Filter.c,v 1.1 2002/09/26 02:56:52 keithp Exp $ + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * 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. + */ + +#include "Xrenderint.h" + +XFilters * +XRenderQueryFilters (Display *dpy, Drawable drawable) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + XRenderInfo *xri; + xRenderQueryFiltersReq *req; + xRenderQueryFiltersReply rep; + XFilters *filters; + char *name; + char len; + int i; + long nbytes, nbytesAlias, nbytesName; + + if (!XextHasExtension (info)) + return 0; + + if (!XRenderQueryFormats (dpy)) + return 0; + + xri = (XRenderInfo *) info->data; + if (xri->minor_version < 6) + return 0; + + LockDisplay (dpy); + GetReq (RenderQueryFilters, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderQueryFilters; + req->drawable = drawable; + if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) + { + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + /* + * Compute total number of bytes for filter names + */ + nbytes = (long)rep.length << 2; + nbytesAlias = rep.numAliases * 2; + if (rep.numAliases & 1) + nbytesAlias += 2; + nbytesName = nbytes - nbytesAlias; + + /* + * Allocate one giant block for the whole data structure + */ + filters = Xmalloc (sizeof (XFilters) + + rep.numFilters * sizeof (char *) + + rep.numAliases * sizeof (short) + + nbytesName); + + if (!filters) + { + _XEatData (dpy, (unsigned long) rep.length << 2); + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + + /* + * Layout: + * XFilters + * numFilters char * pointers to filter names + * numAliases short alias values + * nbytesName char strings + */ + + filters->nfilter = rep.numFilters; + filters->nalias = rep.numAliases; + filters->filter = (char **) (filters + 1); + filters->alias = (short *) (filters->filter + rep.numFilters); + name = (char *) (filters->alias + rep.numAliases); + + /* + * Read the filter aliases + */ + _XRead16Pad (dpy, filters->alias, 2 * rep.numAliases); + + /* + * Read the filter names + */ + for (i = 0; i < rep.numFilters; i++) + { + int l; + _XRead (dpy, &len, 1); + l = len & 0xff; + filters->filter[i] = name; + _XRead (dpy, name, l); + name[l] = '\0'; + name += l + 1; + } + i = name - (char *) (filters->alias + rep.numAliases); + + if (i & 3) + _XEatData (dpy, 4 - (i & 3)); + + UnlockDisplay (dpy); + return filters; +} + +void +XRenderSetPictureFilter (Display *dpy, + Picture picture, + char *filter, + XFixed *params, + int nparams) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderSetPictureFilterReq *req; + int nbytes = strlen (filter); + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + GetReq(RenderSetPictureFilter, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderSetPictureFilter; + req->picture = picture; + req->nbytes = nbytes; + req->length += ((nbytes + 3) >> 2) + nparams; + Data (dpy, filter, nbytes); + Data32 (dpy, params, nparams << 2); + UnlockDisplay(dpy); + SyncHandle(); +} diff --git a/src/Glyph.c b/src/Glyph.c new file mode 100644 index 0000000..6495e53 --- /dev/null +++ b/src/Glyph.c @@ -0,0 +1,710 @@ +/* + * $XFree86: xc/lib/Xrender/Glyph.c,v 1.12 2002/11/05 23:22:35 keithp Exp $ + * + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#include "Xrenderint.h" + +GlyphSet +XRenderCreateGlyphSet (Display *dpy, _Xconst XRenderPictFormat *format) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + GlyphSet gsid; + xRenderCreateGlyphSetReq *req; + + RenderCheckExtension (dpy, info, 0); + LockDisplay(dpy); + GetReq(RenderCreateGlyphSet, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCreateGlyphSet; + req->gsid = gsid = XAllocID(dpy); + req->format = format->id; + UnlockDisplay(dpy); + SyncHandle(); + return gsid; +} + +GlyphSet +XRenderReferenceGlyphSet (Display *dpy, GlyphSet existing) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + GlyphSet gsid; + xRenderReferenceGlyphSetReq *req; + + RenderCheckExtension (dpy, info, 0); + LockDisplay(dpy); + GetReq(RenderReferenceGlyphSet, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderReferenceGlyphSet; + req->gsid = gsid = XAllocID(dpy); + req->existing = existing; + UnlockDisplay(dpy); + SyncHandle(); + return gsid; +} + +void +XRenderFreeGlyphSet (Display *dpy, GlyphSet glyphset) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderFreeGlyphSetReq *req; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + GetReq(RenderFreeGlyphSet, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderFreeGlyphSet; + req->glyphset = glyphset; + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderAddGlyphs (Display *dpy, + GlyphSet glyphset, + _Xconst Glyph *gids, + _Xconst XGlyphInfo *glyphs, + int nglyphs, + _Xconst char *images, + int nbyte_images) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderAddGlyphsReq *req; + long len; + + if (nbyte_images & 3) + nbyte_images += 4 - (nbyte_images & 3); + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + GetReq(RenderAddGlyphs, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderAddGlyphs; + req->glyphset = glyphset; + req->nglyphs = nglyphs; + len = (nglyphs * (SIZEOF (xGlyphInfo) + 4) + nbyte_images) >> 2; + SetReqLen(req, len, len); + Data32 (dpy, (long *) gids, nglyphs * 4); + Data16 (dpy, (short *) glyphs, nglyphs * SIZEOF (xGlyphInfo)); + Data (dpy, images, nbyte_images); + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderFreeGlyphs (Display *dpy, + GlyphSet glyphset, + _Xconst Glyph *gids, + int nglyphs) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderFreeGlyphsReq *req; + long len; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + GetReq(RenderFreeGlyphs, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderFreeGlyphs; + req->glyphset = glyphset; + len = nglyphs; + SetReqLen(req, len, len); + len <<= 2; + Data32 (dpy, (long *) gids, len); + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderCompositeString8 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + GlyphSet glyphset, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst char *string, + int nchar) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderCompositeGlyphs8Req *req; + long len; + xGlyphElt *elt; + int nbytes; + + if (!nchar) + return; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + GetReq(RenderCompositeGlyphs8, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCompositeGlyphs8; + req->op = op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : None; + req->glyphset = glyphset; + req->xSrc = xSrc; + req->ySrc = ySrc; + + /* + * xGlyphElt must be aligned on a 32-bit boundary; this is + * easily done by filling no more than 252 glyphs in each + * bucket + */ + +#define MAX_8 252 + + len = SIZEOF(xGlyphElt) * ((nchar + MAX_8-1) / MAX_8) + nchar; + + req->length += (len + 3)>>2; /* convert to number of 32-bit words */ + + /* + * If the entire request does not fit into the remaining space in the + * buffer, flush the buffer first. + */ + + if (dpy->bufptr + len > dpy->bufmax) + _XFlush (dpy); + + while(nchar > MAX_8) + { + nbytes = MAX_8 + SIZEOF(xGlyphElt); + BufAlloc (xGlyphElt *, elt, nbytes); + elt->len = MAX_8; + elt->deltax = xDst; + elt->deltay = yDst; + xDst = 0; + yDst = 0; + memcpy ((char *) (elt + 1), string, MAX_8); + nchar = nchar - MAX_8; + string += MAX_8; + } + + if (nchar) + { + nbytes = (nchar + SIZEOF(xGlyphElt) + 3) & ~3; + BufAlloc (xGlyphElt *, elt, nbytes); + elt->len = nchar; + elt->deltax = xDst; + elt->deltay = yDst; + memcpy ((char *) (elt + 1), string, nchar); + } +#undef MAX_8 + + UnlockDisplay(dpy); + SyncHandle(); +} +void +XRenderCompositeString16 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + GlyphSet glyphset, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst unsigned short *string, + int nchar) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderCompositeGlyphs8Req *req; + long len; + xGlyphElt *elt; + int nbytes; + + if (!nchar) + return; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + GetReq(RenderCompositeGlyphs16, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCompositeGlyphs16; + req->op = op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : None; + req->glyphset = glyphset; + req->xSrc = xSrc; + req->ySrc = ySrc; + +#define MAX_16 254 + + len = SIZEOF(xGlyphElt) * ((nchar + MAX_16-1) / MAX_16) + nchar * 2; + + req->length += (len + 3)>>2; /* convert to number of 32-bit words */ + + /* + * If the entire request does not fit into the remaining space in the + * buffer, flush the buffer first. + */ + + if (dpy->bufptr + len > dpy->bufmax) + _XFlush (dpy); + + while(nchar > MAX_16) + { + nbytes = MAX_16 * 2 + SIZEOF(xGlyphElt); + BufAlloc (xGlyphElt *, elt, nbytes); + elt->len = MAX_16; + elt->deltax = xDst; + elt->deltay = yDst; + xDst = 0; + yDst = 0; + memcpy ((char *) (elt + 1), (char *) string, MAX_16 * 2); + nchar = nchar - MAX_16; + string += MAX_16; + } + + if (nchar) + { + nbytes = (nchar * 2 + SIZEOF(xGlyphElt) + 3) & ~3; + BufAlloc (xGlyphElt *, elt, nbytes); + elt->len = nchar; + elt->deltax = xDst; + elt->deltay = yDst; + memcpy ((char *) (elt + 1), (char *) string, nchar * 2); + } +#undef MAX_16 + + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderCompositeString32 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + GlyphSet glyphset, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst unsigned int *string, + int nchar) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderCompositeGlyphs8Req *req; + long len; + xGlyphElt *elt; + int nbytes; + + if (!nchar) + return; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + GetReq(RenderCompositeGlyphs32, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCompositeGlyphs32; + req->op = op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : None; + req->glyphset = glyphset; + req->xSrc = xSrc; + req->ySrc = ySrc; + +#define MAX_32 254 + + len = SIZEOF(xGlyphElt) * ((nchar + MAX_32-1) / MAX_32) + nchar * 4; + + req->length += (len + 3)>>2; /* convert to number of 32-bit words */ + + /* + * If the entire request does not fit into the remaining space in the + * buffer, flush the buffer first. + */ + + if (dpy->bufptr + len > dpy->bufmax) + _XFlush (dpy); + + while(nchar > MAX_32) + { + nbytes = MAX_32 * 4 + SIZEOF(xGlyphElt); + BufAlloc (xGlyphElt *, elt, nbytes); + elt->len = MAX_32; + elt->deltax = xDst; + elt->deltay = yDst; + xDst = 0; + yDst = 0; + memcpy ((char *) (elt + 1), (char *) string, MAX_32 * 4); + nchar = nchar - MAX_32; + string += MAX_32; + } + + if (nchar) + { + nbytes = nchar * 4 + SIZEOF(xGlyphElt); + BufAlloc (xGlyphElt *, elt, nbytes); + elt->len = nchar; + elt->deltax = xDst; + elt->deltay = yDst; + memcpy ((char *) (elt + 1), (char *) string, nchar * 4); + } +#undef MAX_32 + + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderCompositeText8 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XGlyphElt8 *elts, + int nelt) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderCompositeGlyphs8Req *req; + GlyphSet glyphset; + long len; + long elen; + xGlyphElt *elt; + int i; + _Xconst char *chars; + int nchars; + + if (!nelt) + return; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + GetReq(RenderCompositeGlyphs8, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCompositeGlyphs8; + req->op = op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : None; + req->glyphset = elts[0].glyphset; + req->xSrc = xSrc; + req->ySrc = ySrc; + + /* + * Compute the space necessary + */ + len = 0; + +#define MAX_8 252 + + glyphset = elts[0].glyphset; + for (i = 0; i < nelt; i++) + { + /* + * Check for glyphset change + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; + len += (SIZEOF (xGlyphElt) + 4) >> 2; + } + nchars = elts[i].nchars; + /* + * xGlyphElt must be aligned on a 32-bit boundary; this is + * easily done by filling no more than 252 glyphs in each + * bucket + */ + elen = SIZEOF(xGlyphElt) * ((nchars + MAX_8-1) / MAX_8) + nchars; + len += (elen + 3) >> 2; + } + + req->length += len; + + /* + * Send the glyphs + */ + glyphset = elts[0].glyphset; + for (i = 0; i < nelt; i++) + { + /* + * Switch glyphsets + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; + BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); + elt->len = 0xff; + elt->deltax = 0; + elt->deltay = 0; + Data32(dpy, &glyphset, 4); + } + nchars = elts[i].nchars; + xDst = elts[i].xOff; + yDst = elts[i].yOff; + chars = elts[i].chars; + while (nchars) + { + int this_chars = nchars > MAX_8 ? MAX_8 : nchars; + + BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) + elt->len = this_chars; + elt->deltax = xDst; + elt->deltay = yDst; + xDst = 0; + yDst = 0; + Data (dpy, chars, this_chars); + nchars -= this_chars; + chars += this_chars; + } + } +#undef MAX_8 + + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderCompositeText16 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XGlyphElt16 *elts, + int nelt) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderCompositeGlyphs16Req *req; + GlyphSet glyphset; + long len; + long elen; + xGlyphElt *elt; + int i; + _Xconst unsigned short *chars; + int nchars; + + if (!nelt) + return; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + GetReq(RenderCompositeGlyphs16, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCompositeGlyphs16; + req->op = op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : None; + req->glyphset = elts[0].glyphset; + req->xSrc = xSrc; + req->ySrc = ySrc; + + /* + * Compute the space necessary + */ + len = 0; + +#define MAX_16 254 + + glyphset = elts[0].glyphset; + for (i = 0; i < nelt; i++) + { + /* + * Check for glyphset change + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; + len += (SIZEOF (xGlyphElt) + 4) >> 2; + } + nchars = elts[i].nchars; + /* + * xGlyphElt must be aligned on a 32-bit boundary; this is + * easily done by filling no more than 254 glyphs in each + * bucket + */ + elen = SIZEOF(xGlyphElt) * ((nchars + MAX_16-1) / MAX_16) + nchars * 2; + len += (elen + 3) >> 2; + } + + req->length += len; + + glyphset = elts[0].glyphset; + for (i = 0; i < nelt; i++) + { + /* + * Switch glyphsets + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; + BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); + elt->len = 0xff; + elt->deltax = 0; + elt->deltay = 0; + Data32(dpy, &glyphset, 4); + } + nchars = elts[i].nchars; + xDst = elts[i].xOff; + yDst = elts[i].yOff; + chars = elts[i].chars; + while (nchars) + { + int this_chars = nchars > MAX_16 ? MAX_16 : nchars; + int this_bytes = this_chars * 2; + + BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) + elt->len = this_chars; + elt->deltax = xDst; + elt->deltay = yDst; + xDst = 0; + yDst = 0; + Data16 (dpy, chars, this_bytes); + nchars -= this_chars; + chars += this_chars; + } + } +#undef MAX_16 + + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderCompositeText32 (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XGlyphElt32 *elts, + int nelt) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderCompositeGlyphs32Req *req; + GlyphSet glyphset; + long len; + long elen; + xGlyphElt *elt; + int i; + _Xconst unsigned int *chars; + int nchars; + + if (!nelt) + return; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + + + GetReq(RenderCompositeGlyphs32, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCompositeGlyphs32; + req->op = op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : None; + req->glyphset = elts[0].glyphset; + req->xSrc = xSrc; + req->ySrc = ySrc; + + /* + * Compute the space necessary + */ + len = 0; + +#define MAX_32 254 + + glyphset = elts[0].glyphset; + for (i = 0; i < nelt; i++) + { + /* + * Check for glyphset change + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; + len += (SIZEOF (xGlyphElt) + 4) >> 2; + } + nchars = elts[i].nchars; + elen = SIZEOF(xGlyphElt) * ((nchars + MAX_32) / MAX_32) + nchars *4; + len += (elen + 3) >> 2; + } + + req->length += len; + + glyphset = elts[0].glyphset; + for (i = 0; i < nelt; i++) + { + /* + * Switch glyphsets + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; + BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); + elt->len = 0xff; + elt->deltax = 0; + elt->deltay = 0; + Data32(dpy, &glyphset, 4); + } + nchars = elts[i].nchars; + xDst = elts[i].xOff; + yDst = elts[i].yOff; + chars = elts[i].chars; + while (nchars) + { + int this_chars = nchars > MAX_32 ? MAX_32 : nchars; + int this_bytes = this_chars * 4; + BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) + elt->len = this_chars; + elt->deltax = xDst; + elt->deltay = yDst; + xDst = 0; + yDst = 0; + DataInt32 (dpy, chars, this_bytes); + nchars -= this_chars; + chars += this_chars; + } + } +#undef MAX_32 + + UnlockDisplay(dpy); + SyncHandle(); +} diff --git a/src/Picture.c b/src/Picture.c new file mode 100644 index 0000000..32ab263 --- /dev/null +++ b/src/Picture.c @@ -0,0 +1,241 @@ +/* + * $XFree86: xc/lib/Xrender/Picture.c,v 1.9 2002/09/26 02:56:52 keithp Exp $ + * + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#include "Xrenderint.h" +#include "region.h" + +static void +_XRenderProcessPictureAttributes (Display *dpy, + xRenderChangePictureReq *req, + unsigned long valuemask, + _Xconst XRenderPictureAttributes *attributes) +{ + unsigned long values[32]; + register unsigned long *value = values; + unsigned int nvalues; + + if (valuemask & CPRepeat) + *value++ = attributes->repeat; + if (valuemask & CPAlphaMap) + *value++ = attributes->alpha_map; + if (valuemask & CPAlphaXOrigin) + *value++ = attributes->alpha_x_origin; + if (valuemask & CPAlphaYOrigin) + *value++ = attributes->alpha_y_origin; + if (valuemask & CPClipXOrigin) + *value++ = attributes->clip_x_origin; + if (valuemask & CPClipYOrigin) + *value++ = attributes->clip_y_origin; + if (valuemask & CPClipMask) + *value++ = attributes->clip_mask; + if (valuemask & CPGraphicsExposure) + *value++ = attributes->graphics_exposures; + if (valuemask & CPSubwindowMode) + *value++ = attributes->subwindow_mode; + if (valuemask & CPPolyEdge) + *value++ = attributes->poly_edge; + if (valuemask & CPPolyMode) + *value++ = attributes->poly_mode; + if (valuemask & CPDither) + *value++ = attributes->dither; + if (valuemask & CPComponentAlpha) + *value++ = attributes->component_alpha; + + req->length += (nvalues = value - values); + + nvalues <<= 2; /* watch out for macros... */ + Data32 (dpy, (long *) values, (long)nvalues); +} + +Picture +XRenderCreatePicture (Display *dpy, + Drawable drawable, + _Xconst XRenderPictFormat *format, + unsigned long valuemask, + _Xconst XRenderPictureAttributes *attributes) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + Picture pid; + xRenderCreatePictureReq *req; + + RenderCheckExtension (dpy, info, 0); + LockDisplay(dpy); + GetReq(RenderCreatePicture, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderCreatePicture; + req->pid = pid = XAllocID(dpy); + req->drawable = drawable; + req->format = format->id; + if ((req->mask = valuemask)) + _XRenderProcessPictureAttributes (dpy, + (xRenderChangePictureReq *) req, + valuemask, + attributes); + UnlockDisplay(dpy); + SyncHandle(); + return pid; +} + +void +XRenderChangePicture (Display *dpy, + Picture picture, + unsigned long valuemask, + _Xconst XRenderPictureAttributes *attributes) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderChangePictureReq *req; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + GetReq(RenderChangePicture, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderChangePicture; + req->picture = picture; + req->mask = valuemask; + _XRenderProcessPictureAttributes (dpy, + req, + valuemask, + attributes); + UnlockDisplay(dpy); + SyncHandle(); +} + +static void +_XRenderSetPictureClipRectangles (Display *dpy, + XExtDisplayInfo *info, + Picture picture, + int xOrigin, + int yOrigin, + _Xconst XRectangle *rects, + int n) +{ + xRenderSetPictureClipRectanglesReq *req; + long len; + + GetReq (RenderSetPictureClipRectangles, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderSetPictureClipRectangles; + req->picture = picture; + req->xOrigin = xOrigin; + req->yOrigin = yOrigin; + len = ((long) n) << 1; + SetReqLen (req, len, 1); + len <<= 2; + Data16 (dpy, (short *) rects, len); +} + +void +XRenderSetPictureClipRectangles (Display *dpy, + Picture picture, + int xOrigin, + int yOrigin, + _Xconst XRectangle *rects, + int n) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + _XRenderSetPictureClipRectangles (dpy, info, picture, + xOrigin, yOrigin, rects, n); + UnlockDisplay (dpy); + SyncHandle (); +} + +void +XRenderSetPictureClipRegion (Display *dpy, + Picture picture, + Region r) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + int i; + XRectangle *xr, *pr; + BOX *pb; + unsigned long total; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + total = r->numRects * sizeof (XRectangle); + if ((xr = (XRectangle *) _XAllocTemp(dpy, total))) { + for (pr = xr, pb = r->rects, i = r->numRects; --i >= 0; pr++, pb++) { + pr->x = pb->x1; + pr->y = pb->y1; + pr->width = pb->x2 - pb->x1; + pr->height = pb->y2 - pb->y1; + } + } + if (xr || !r->numRects) + _XRenderSetPictureClipRectangles (dpy, info, picture, 0, 0, + xr, r->numRects); + if (xr) + _XFreeTemp(dpy, (char *)xr, total); + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderSetPictureTransform (Display *dpy, + Picture picture, + XTransform *transform) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderSetPictureTransformReq *req; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay (dpy); + GetReq(RenderSetPictureTransform, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderSetPictureTransform; + req->picture = picture; + req->transform.matrix11 = transform->matrix[0][0]; + req->transform.matrix12 = transform->matrix[0][1]; + req->transform.matrix13 = transform->matrix[0][2]; + req->transform.matrix21 = transform->matrix[1][0]; + req->transform.matrix22 = transform->matrix[1][1]; + req->transform.matrix23 = transform->matrix[1][2]; + req->transform.matrix31 = transform->matrix[2][0]; + req->transform.matrix32 = transform->matrix[2][1]; + req->transform.matrix33 = transform->matrix[2][2]; + UnlockDisplay(dpy); + SyncHandle(); + +} + +void +XRenderFreePicture (Display *dpy, + Picture picture) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderFreePictureReq *req; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + GetReq(RenderFreePicture, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderFreePicture; + req->picture = picture; + UnlockDisplay(dpy); + SyncHandle(); +} diff --git a/src/Poly.c b/src/Poly.c new file mode 100644 index 0000000..a6856fb --- /dev/null +++ b/src/Poly.c @@ -0,0 +1,300 @@ +/* + * $XFree86: xc/lib/Xrender/Poly.c,v 1.7 2002/06/04 23:22:36 keithp Exp $ + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * 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. + */ + +#include "Xrenderint.h" + +typedef struct _Edge Edge; + +struct _Edge { + XLineFixed edge; + XFixed current_x; + Bool clockWise; + Edge *next, *prev; +}; + +static int +CompareEdge (const void *o1, const void *o2) +{ + const Edge *e1 = o1, *e2 = o2; + + return e1->edge.p1.y - e2->edge.p1.y; +} + +static XFixed +XRenderComputeX (XLineFixed *line, XFixed y) +{ + XFixed dx = line->p2.x - line->p1.x; + double ex = (double) (y - line->p1.y) * (double) dx; + XFixed dy = line->p2.y - line->p1.y; + + return (XFixed) line->p1.x + (XFixed) (ex / dy); +} + +static double +XRenderComputeInverseSlope (XLineFixed *l) +{ + return (XFixedToDouble (l->p2.x - l->p1.x) / + XFixedToDouble (l->p2.y - l->p1.y)); +} + +static double +XRenderComputeXIntercept (XLineFixed *l, double inverse_slope) +{ + return XFixedToDouble (l->p1.x) - inverse_slope * XFixedToDouble (l->p1.y); +} + +static XFixed +XRenderComputeIntersect (XLineFixed *l1, XLineFixed *l2) +{ + /* + * x = m1y + b1 + * x = m2y + b2 + * m1y + b1 = m2y + b2 + * y * (m1 - m2) = b2 - b1 + * y = (b2 - b1) / (m1 - m2) + */ + double m1 = XRenderComputeInverseSlope (l1); + double b1 = XRenderComputeXIntercept (l1, m1); + double m2 = XRenderComputeInverseSlope (l2); + double b2 = XRenderComputeXIntercept (l2, m2); + + return XDoubleToFixed ((b2 - b1) / (m1 - m2)); +} + +static int +XRenderComputeTrapezoids (Edge *edges, + int nedges, + int winding, + XTrapezoid *traps) +{ + int ntraps = 0; + int inactive; + Edge *active; + Edge *e, *en, *next; + XFixed y, next_y, intersect; + + qsort (edges, nedges, sizeof (Edge), CompareEdge); + + y = edges[0].edge.p1.y; + active = 0; + inactive = 0; + while (active || inactive < nedges) + { + /* insert new active edges into list */ + while (inactive < nedges) + { + e = &edges[inactive]; + if (e->edge.p1.y > y) + break; + /* move this edge into the active list */ + inactive++; + e->next = active; + e->prev = 0; + if (active) + active->prev = e; + active = e; + } + /* compute x coordinates along this group */ + for (e = active; e; e = e->next) + e->current_x = XRenderComputeX (&e->edge, y); + + /* sort active list */ + for (e = active; e; e = next) + { + next = e->next; + /* + * Find one later in the list that belongs before the + * current one + */ + for (en = next; en; en = en->next) + { + if (en->current_x < e->current_x || + (en->current_x == e->current_x && + en->edge.p2.x < e->edge.p2.x)) + { + /* + * insert en before e + * + * extract en + */ + en->prev->next = en->next; + if (en->next) + en->next->prev = en->prev; + /* + * insert en + */ + if (e->prev) + e->prev->next = en; + else + active = en; + en->prev = e->prev; + e->prev = en; + en->next = e; + /* + * start over at en + */ + next = en; + break; + } + } + } +#if 0 + printf ("y: %6.3g:", y / 65536.0); + for (e = active; e; e = e->next) + { + printf (" %6.3g", e->current_x / 65536.0); + } + printf ("\n"); +#endif + /* find next inflection point */ + next_y = active->edge.p2.y; + for (e = active; e; e = en) + { + if (e->edge.p2.y < next_y) + next_y = e->edge.p2.y; + en = e->next; + /* check intersect */ + if (en && e->edge.p2.x > en->edge.p2.x) + { + intersect = XRenderComputeIntersect (&e->edge, &e->next->edge); + /* make sure this point is below the actual intersection */ + intersect = intersect + 1; + if (intersect < next_y) + next_y = intersect; + } + } + /* check next inactive point */ + if (inactive < nedges && edges[inactive].edge.p1.y < next_y) + next_y = edges[inactive].edge.p1.y; + + /* walk the list generating trapezoids */ + for (e = active; e && (en = e->next); e = en->next) + { + traps->top = y; + traps->bottom = next_y; + traps->left = e->edge; + traps->right = en->edge; + traps++; + ntraps++; + } + + y = next_y; + + /* delete inactive edges from list */ + for (e = active; e; e = next) + { + next = e->next; + if (e->edge.p2.y <= y) + { + if (e->prev) + e->prev->next = e->next; + else + active = e->next; + if (e->next) + e->next->prev = e->prev; + } + } + } + return ntraps; +} + +void +XRenderCompositeDoublePoly (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + int xDst, + int yDst, + _Xconst XPointDouble *fpoints, + int npoints, + int winding) +{ + Edge *edges; + XTrapezoid *traps; + int i, nedges, ntraps; + XFixed x, y, prevx = 0, prevy = 0, firstx = 0, firsty = 0; + XFixed top = 0, bottom = 0; /* GCCism */ + + edges = (Edge *) Xmalloc (npoints * sizeof (Edge) + + (npoints * npoints * sizeof (XTrapezoid))); + if (!edges) + return; + traps = (XTrapezoid *) (edges + npoints); + nedges = 0; + for (i = 0; i <= npoints; i++) + { + if (i == npoints) + { + x = firstx; + y = firsty; + } + else + { + x = XDoubleToFixed (fpoints[i].x); + y = XDoubleToFixed (fpoints[i].y); + } + if (i) + { + if (y < top) + top = y; + else if (y > bottom) + bottom = y; + if (prevy < y) + { + edges[nedges].edge.p1.x = prevx; + edges[nedges].edge.p1.y = prevy; + edges[nedges].edge.p2.x = x; + edges[nedges].edge.p2.y = y; + edges[nedges].clockWise = True; + nedges++; + } + else if (prevy > y) + { + edges[nedges].edge.p1.x = x; + edges[nedges].edge.p1.y = y; + edges[nedges].edge.p2.x = prevx; + edges[nedges].edge.p2.y = prevy; + edges[nedges].clockWise = False; + nedges++; + } + /* drop horizontal edges */ + } + else + { + top = y; + bottom = y; + firstx = x; + firsty = y; + } + prevx = x; + prevy = y; + } + ntraps = XRenderComputeTrapezoids (edges, nedges, winding, traps); + /* XXX adjust xSrc/xDst */ + XRenderCompositeTrapezoids (dpy, op, src, dst, maskFormat, xSrc, ySrc, traps, ntraps); + Xfree (edges); +} diff --git a/src/Trap.c b/src/Trap.c new file mode 100644 index 0000000..07304f5 --- /dev/null +++ b/src/Trap.c @@ -0,0 +1,72 @@ +/* + * $XFree86: xc/lib/Xrender/Trap.c,v 1.3 2002/11/05 23:22:35 keithp Exp $ + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * 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. + */ + +#include "Xrenderint.h" + +void +XRenderCompositeTrapezoids (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XTrapezoid *traps, + int ntrap) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderTrapezoidsReq *req; + int n; + long len; + unsigned long max_req = dpy->bigreq_size ? dpy->bigreq_size : dpy->max_request_size; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + while (ntrap) + { + GetReq(RenderTrapezoids, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderTrapezoids; + req->op = (CARD8) op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : 0; + req->xSrc = xSrc; + req->ySrc = ySrc; + n = ntrap; + len = ((long) n) * (SIZEOF (xTrapezoid) >> 2); + if (len > (max_req - req->length)) { + n = (max_req - req->length) / (SIZEOF (xTrapezoid) >> 2); + len = ((long)n) * (SIZEOF (xTrapezoid) >> 2); + } + SetReqLen (req, len, len); + len <<= 2; + DataInt32 (dpy, (int *) traps, len); + ntrap -= n; + traps += n; + } + UnlockDisplay(dpy); + SyncHandle(); +} + diff --git a/src/Tri.c b/src/Tri.c new file mode 100644 index 0000000..ead95a3 --- /dev/null +++ b/src/Tri.c @@ -0,0 +1,167 @@ +/* + * $XFree86: xc/lib/Xrender/Tri.c,v 1.3 2002/11/05 23:22:35 keithp Exp $ + * + * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. + * + * 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. + */ + +#include "Xrenderint.h" + +void +XRenderCompositeTriangles (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XTriangle *triangles, + int ntriangle) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderTrianglesReq *req; + int n; + long len; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + while (ntriangle) + { + GetReq(RenderTriangles, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderTriangles; + req->op = (CARD8) op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : 0; + req->xSrc = xSrc; + req->ySrc = ySrc; + n = ntriangle; + len = ((long) n) * (SIZEOF (xTriangle) >> 2); + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) { + n = (dpy->max_request_size - req->length) / (SIZEOF (xTriangle) >> 2); + len = ((long)n) * (SIZEOF (xTriangle) >> 2); + } + SetReqLen (req, len, len); + len <<= 2; + DataInt32 (dpy, (int *) triangles, len); + ntriangle -= n; + triangles += n; + } + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderCompositeTriStrip (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XPointFixed *points, + int npoint) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderTriStripReq *req; + int n; + long len; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + while (npoint > 2) + { + GetReq(RenderTriStrip, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderTriStrip; + req->op = (CARD8) op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : 0; + req->xSrc = xSrc; + req->ySrc = ySrc; + n = npoint; + len = ((long) n) * (SIZEOF (xPointFixed) >> 2); + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) { + n = (dpy->max_request_size - req->length) / (SIZEOF (xPointFixed) >> 2); + len = ((long)n) * (SIZEOF (xPointFixed) >> 2); + } + SetReqLen (req, len, len); + len <<= 2; + DataInt32 (dpy, (int *) points, len); + npoint -= (n - 2); + points += (n - 2); + } + UnlockDisplay(dpy); + SyncHandle(); +} + +void +XRenderCompositeTriFan (Display *dpy, + int op, + Picture src, + Picture dst, + _Xconst XRenderPictFormat *maskFormat, + int xSrc, + int ySrc, + _Xconst XPointFixed *points, + int npoint) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + _Xconst XPointFixed *first = points; + xPointFixed *p; + xRenderTriFanReq *req; + int n; + long len; + + RenderSimpleCheckExtension (dpy, info); + LockDisplay(dpy); + points++; + npoint--; + while (npoint > 1) + { + GetReqExtra(RenderTriFan, SIZEOF (xPointFixed), req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderTriFan; + req->op = (CARD8) op; + req->src = src; + req->dst = dst; + req->maskFormat = maskFormat ? maskFormat->id : 0; + req->xSrc = xSrc; + req->ySrc = ySrc; + p = (xPointFixed *) (req + 1); + p->x = first->x; + p->y = first->y; + n = npoint; + len = ((long) n) * (SIZEOF (xPointFixed) >> 2); + if (!dpy->bigreq_size && len > (dpy->max_request_size - req->length)) { + n = (dpy->max_request_size - req->length) / (SIZEOF (xPointFixed) >> 2); + len = ((long)n) * (SIZEOF (xPointFixed) >> 2); + } + SetReqLen (req, len, len); + len <<= 2; + DataInt32 (dpy, (int *) points, len); + npoint -= (n - 1); + points += (n - 1); + } + UnlockDisplay(dpy); + SyncHandle(); +} diff --git a/src/Xrender.c b/src/Xrender.c new file mode 100644 index 0000000..45d929d --- /dev/null +++ b/src/Xrender.c @@ -0,0 +1,657 @@ +/* + * $XFree86: xc/lib/Xrender/Xrender.c,v 1.14 2002/11/22 02:10:41 keithp Exp $ + * + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#include "Xrenderint.h" + +XExtensionInfo XRenderExtensionInfo; +char XRenderExtensionName[] = RENDER_NAME; + +static int XRenderCloseDisplay(Display *dpy, XExtCodes *codes); + +static /* const */ XExtensionHooks render_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + XRenderCloseDisplay, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +XExtDisplayInfo * +XRenderFindDisplay (Display *dpy) +{ + XExtDisplayInfo *dpyinfo; + + dpyinfo = XextFindDisplay (&XRenderExtensionInfo, dpy); + if (!dpyinfo) + dpyinfo = XextAddDisplay (&XRenderExtensionInfo, dpy, + XRenderExtensionName, + &render_extension_hooks, + 0, 0); + return dpyinfo; +} + +static int +XRenderCloseDisplay (Display *dpy, XExtCodes *codes) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + if (info->data) XFree (info->data); + + return XextRemoveDisplay (&XRenderExtensionInfo, dpy); +} + +/**************************************************************************** + * * + * Render public interfaces * + * * + ****************************************************************************/ + +Bool XRenderQueryExtension (Display *dpy, int *event_basep, int *error_basep) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +Status XRenderQueryVersion (Display *dpy, + int *major_versionp, + int *minor_versionp) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + XRenderInfo *xri; + + if (!XextHasExtension (info)) + return 0; + + if (!XRenderQueryFormats (dpy)) + return 0; + + xri = (XRenderInfo *) info->data; + *major_versionp = xri->major_version; + *minor_versionp = xri->minor_version; + return 1; +} + +static XRenderPictFormat * +_XRenderFindFormat (XRenderInfo *xri, PictFormat format) +{ + int nf; + + for (nf = 0; nf < xri->nformat; nf++) + if (xri->format[nf].id == format) + return &xri->format[nf]; + return 0; +} + +static Visual * +_XRenderFindVisual (Display *dpy, VisualID vid) +{ + return _XVIDtoVisual (dpy, vid); +} + +typedef struct _renderVersionState { + unsigned long version_seq; + Bool error; + int major_version; + int minor_version; + +} _XrenderVersionState; + +static Bool +_XRenderVersionHandler (Display *dpy, + xReply *rep, + char *buf, + int len, + XPointer data) +{ + xRenderQueryVersionReply replbuf; + xRenderQueryVersionReply *repl; + _XrenderVersionState *state = (_XrenderVersionState *) data; + + if (dpy->last_request_read != state->version_seq) + return False; + if (rep->generic.type == X_Error) + { + state->error = True; + return False; + } + repl = (xRenderQueryVersionReply *) + _XGetAsyncReply(dpy, (char *)&replbuf, rep, buf, len, + (SIZEOF(xRenderQueryVersionReply) - SIZEOF(xReply)) >> 2, + True); + state->major_version = repl->majorVersion; + state->minor_version = repl->minorVersion; + return True; +} + +Status +XRenderQueryFormats (Display *dpy) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + _XAsyncHandler async; + _XrenderVersionState async_state; + xRenderQueryVersionReq *vreq; + xRenderQueryPictFormatsReply rep; + xRenderQueryPictFormatsReq *req; + XRenderInfo *xri; + XRenderPictFormat *format; + XRenderScreen *screen; + XRenderDepth *depth; + XRenderVisual *visual; + xPictFormInfo *xFormat; + xPictScreen *xScreen; + xPictDepth *xDepth; + xPictVisual *xVisual; + CARD32 *xSubpixel; + void *xData; + int nf, ns, nd, nv; + int rlength; + int nbytes; + + RenderCheckExtension (dpy, info, 0); + LockDisplay (dpy); + if (info->data) + { + UnlockDisplay (dpy); + return 1; + } + GetReq (RenderQueryVersion, vreq); + vreq->reqType = info->codes->major_opcode; + vreq->renderReqType = X_RenderQueryVersion; + vreq->majorVersion = RENDER_MAJOR; + vreq->minorVersion = RENDER_MINOR; + + async_state.version_seq = dpy->request; + async_state.error = False; + async.next = dpy->async_handlers; + async.handler = _XRenderVersionHandler; + async.data = (XPointer) &async_state; + dpy->async_handlers = &async; + + GetReq (RenderQueryPictFormats, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderQueryPictFormats; + + if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) + { + DeqAsyncHandler (dpy, &async); + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + DeqAsyncHandler (dpy, &async); + if (async_state.error) + { + UnlockDisplay(dpy); + SyncHandle(); + return 0; + } + /* + * Check for the lack of sub-pixel data + */ + if (async_state.major_version == 0 && async_state.minor_version < 6) + rep.numSubpixel = 0; + + xri = (XRenderInfo *) Xmalloc (sizeof (XRenderInfo) + + rep.numFormats * sizeof (XRenderPictFormat) + + rep.numScreens * sizeof (XRenderScreen) + + rep.numDepths * sizeof (XRenderDepth) + + rep.numVisuals * sizeof (XRenderVisual)); + xri->major_version = async_state.major_version; + xri->minor_version = async_state.minor_version; + xri->format = (XRenderPictFormat *) (xri + 1); + xri->nformat = rep.numFormats; + xri->screen = (XRenderScreen *) (xri->format + rep.numFormats); + xri->nscreen = rep.numScreens; + xri->depth = (XRenderDepth *) (xri->screen + rep.numScreens); + xri->ndepth = rep.numDepths; + xri->visual = (XRenderVisual *) (xri->depth + rep.numDepths); + xri->nvisual = rep.numVisuals; + rlength = (rep.numFormats * sizeof (xPictFormInfo) + + rep.numScreens * sizeof (xPictScreen) + + rep.numDepths * sizeof (xPictDepth) + + rep.numVisuals * sizeof (xPictVisual) + + rep.numSubpixel * 4); + xData = (void *) Xmalloc (rlength); + nbytes = (int) rep.length << 2; + + if (!xri || !xData || nbytes < rlength) + { + if (xri) Xfree (xri); + if (xData) Xfree (xData); + _XEatData (dpy, nbytes); + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + _XRead (dpy, (char *) xData, rlength); + format = xri->format; + xFormat = (xPictFormInfo *) xData; + for (nf = 0; nf < rep.numFormats; nf++) + { + format->id = xFormat->id; + format->type = xFormat->type; + format->depth = xFormat->depth; + format->direct.red = xFormat->direct.red; + format->direct.redMask = xFormat->direct.redMask; + format->direct.green = xFormat->direct.green; + format->direct.greenMask = xFormat->direct.greenMask; + format->direct.blue = xFormat->direct.blue; + format->direct.blueMask = xFormat->direct.blueMask; + format->direct.alpha = xFormat->direct.alpha; + format->direct.alphaMask = xFormat->direct.alphaMask; + format->colormap = xFormat->colormap; + format++; + xFormat++; + } + xScreen = (xPictScreen *) xFormat; + screen = xri->screen; + depth = xri->depth; + visual = xri->visual; + for (ns = 0; ns < xri->nscreen; ns++) + { + screen->depths = depth; + screen->ndepths = xScreen->nDepth; + screen->fallback = _XRenderFindFormat (xri, xScreen->fallback); + screen->subpixel = SubPixelUnknown; + xDepth = (xPictDepth *) (xScreen + 1); + for (nd = 0; nd < screen->ndepths; nd++) + { + depth->depth = xDepth->depth; + depth->nvisuals = xDepth->nPictVisuals; + depth->visuals = visual; + xVisual = (xPictVisual *) (xDepth + 1); + for (nv = 0; nv < depth->nvisuals; nv++) + { + visual->visual = _XRenderFindVisual (dpy, xVisual->visual); + visual->format = _XRenderFindFormat (xri, xVisual->format); + visual++; + xVisual++; + } + depth++; + xDepth = (xPictDepth *) xVisual; + } + screen++; + xScreen = (xPictScreen *) xDepth; + } + xSubpixel = (CARD32 *) xScreen; + screen = xri->screen; + for (ns = 0; ns < rep.numSubpixel; ns++) + { + screen->subpixel = *xSubpixel; + xSubpixel++; + screen++; + } + info->data = (XPointer) xri; + /* + * Skip any extra data + */ + if (nbytes > rlength) + _XEatData (dpy, (unsigned long) (nbytes - rlength)); + + UnlockDisplay (dpy); + SyncHandle (); + Xfree (xData); + return 1; +} + +int +XRenderQuerySubpixelOrder (Display *dpy, int screen) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + XRenderInfo *xri; + + if (!XextHasExtension (info)) + return SubPixelUnknown; + + if (!XRenderQueryFormats (dpy)) + return SubPixelUnknown; + + xri = (XRenderInfo *) info->data; + return xri->screen[screen].subpixel; +} + +Bool +XRenderSetSubpixelOrder (Display *dpy, int screen, int subpixel) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + XRenderInfo *xri; + + if (!XextHasExtension (info)) + return False; + + if (!XRenderQueryFormats (dpy)) + return False; + + xri = (XRenderInfo *) info->data; + xri->screen[screen].subpixel = subpixel; + return True; +} + +XRenderPictFormat * +XRenderFindVisualFormat (Display *dpy, _Xconst Visual *visual) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + int nv; + XRenderInfo *xri; + XRenderVisual *xrv; + + RenderCheckExtension (dpy, info, 0); + if (!XRenderQueryFormats (dpy)) + return 0; + xri = (XRenderInfo *) info->data; + for (nv = 0, xrv = xri->visual; nv < xri->nvisual; nv++, xrv++) + if (xrv->visual == visual) + return xrv->format; + return 0; +} + +XRenderPictFormat * +XRenderFindFormat (Display *dpy, + unsigned long mask, + _Xconst XRenderPictFormat *template, + int count) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + int nf; + XRenderInfo *xri; + + RenderCheckExtension (dpy, info, 0); + if (!XRenderQueryFormats (dpy)) + return 0; + xri = (XRenderInfo *) info->data; + for (nf = 0; nf < xri->nformat; nf++) + { + if (mask & PictFormatID) + if (template->id != xri->format[nf].id) + continue; + if (mask & PictFormatType) + if (template->type != xri->format[nf].type) + continue; + if (mask & PictFormatDepth) + if (template->depth != xri->format[nf].depth) + continue; + if (mask & PictFormatRed) + if (template->direct.red != xri->format[nf].direct.red) + continue; + if (mask & PictFormatRedMask) + if (template->direct.redMask != xri->format[nf].direct.redMask) + continue; + if (mask & PictFormatGreen) + if (template->direct.green != xri->format[nf].direct.green) + continue; + if (mask & PictFormatGreenMask) + if (template->direct.greenMask != xri->format[nf].direct.greenMask) + continue; + if (mask & PictFormatBlue) + if (template->direct.blue != xri->format[nf].direct.blue) + continue; + if (mask & PictFormatBlueMask) + if (template->direct.blueMask != xri->format[nf].direct.blueMask) + continue; + if (mask & PictFormatAlpha) + if (template->direct.alpha != xri->format[nf].direct.alpha) + continue; + if (mask & PictFormatAlphaMask) + if (template->direct.alphaMask != xri->format[nf].direct.alphaMask) + continue; + if (mask & PictFormatColormap) + if (template->colormap != xri->format[nf].colormap) + continue; + if (count-- == 0) + return &xri->format[nf]; + } + return 0; +} + +XRenderPictFormat * +XRenderFindStandardFormat (Display *dpy, + int format) +{ + static struct { + XRenderPictFormat templ; + unsigned long mask; + } standardFormats[PictStandardNUM] = { + /* PictStandardARGB32 */ + { + { + 0, /* id */ + PictTypeDirect, /* type */ + 32, /* depth */ + { /* direct */ + 16, /* direct.red */ + 0xff, /* direct.redMask */ + 8, /* direct.green */ + 0xff, /* direct.greenMask */ + 0, /* direct.blue */ + 0xff, /* direct.blueMask */ + 24, /* direct.alpha */ + 0xff, /* direct.alphaMask */ + }, + 0, /* colormap */ + }, + PictFormatType | + PictFormatDepth | + PictFormatRed | + PictFormatRedMask | + PictFormatGreen | + PictFormatGreenMask | + PictFormatBlue | + PictFormatBlueMask | + PictFormatAlpha | + PictFormatAlphaMask, + }, + /* PictStandardRGB24 */ + { + { + 0, /* id */ + PictTypeDirect, /* type */ + 24, /* depth */ + { /* direct */ + 16, /* direct.red */ + 0xff, /* direct.redMask */ + 8, /* direct.green */ + 0xff, /* direct.greenMask */ + 0, /* direct.blue */ + 0xff, /* direct.blueMask */ + 0, /* direct.alpha */ + 0x00, /* direct.alphaMask */ + }, + 0, /* colormap */ + }, + PictFormatType | + PictFormatDepth | + PictFormatRed | + PictFormatRedMask | + PictFormatGreen | + PictFormatGreenMask | + PictFormatBlue | + PictFormatBlueMask | + PictFormatAlphaMask, + }, + /* PictStandardA8 */ + { + { + 0, /* id */ + PictTypeDirect, /* type */ + 8, /* depth */ + { /* direct */ + 0, /* direct.red */ + 0x00, /* direct.redMask */ + 0, /* direct.green */ + 0x00, /* direct.greenMask */ + 0, /* direct.blue */ + 0x00, /* direct.blueMask */ + 0, /* direct.alpha */ + 0xff, /* direct.alphaMask */ + }, + 0, /* colormap */ + }, + PictFormatType | + PictFormatDepth | + PictFormatRedMask | + PictFormatGreenMask | + PictFormatBlueMask | + PictFormatAlpha | + PictFormatAlphaMask, + }, + /* PictStandardA4 */ + { + { + 0, /* id */ + PictTypeDirect, /* type */ + 4, /* depth */ + { /* direct */ + 0, /* direct.red */ + 0x00, /* direct.redMask */ + 0, /* direct.green */ + 0x00, /* direct.greenMask */ + 0, /* direct.blue */ + 0x00, /* direct.blueMask */ + 0, /* direct.alpha */ + 0x0f, /* direct.alphaMask */ + }, + 0, /* colormap */ + }, + PictFormatType | + PictFormatDepth | + PictFormatRedMask | + PictFormatGreenMask | + PictFormatBlueMask | + PictFormatAlpha | + PictFormatAlphaMask, + }, + /* PictStandardA1 */ + { + { + 0, /* id */ + PictTypeDirect, /* type */ + 1, /* depth */ + { /* direct */ + 0, /* direct.red */ + 0x00, /* direct.redMask */ + 0, /* direct.green */ + 0x00, /* direct.greenMask */ + 0, /* direct.blue */ + 0x00, /* direct.blueMask */ + 0, /* direct.alpha */ + 0x01, /* direct.alphaMask */ + }, + 0, /* colormap */ + }, + PictFormatType | + PictFormatDepth | + PictFormatRedMask | + PictFormatGreenMask | + PictFormatBlueMask | + PictFormatAlpha | + PictFormatAlphaMask, + }, + }; + + if (0 <= format && format < PictStandardNUM) + return XRenderFindFormat (dpy, + standardFormats[format].mask, + &standardFormats[format].templ, + 0); + return 0; +} + +XIndexValue * +XRenderQueryPictIndexValues(Display *dpy, + _Xconst XRenderPictFormat *format, + int *num) +{ + XExtDisplayInfo *info = XRenderFindDisplay (dpy); + xRenderQueryPictIndexValuesReq *req; + xRenderQueryPictIndexValuesReply rep; + XIndexValue *values; + int nbytes, nread, rlength, i; + + RenderCheckExtension (dpy, info, 0); + + LockDisplay (dpy); + GetReq (RenderQueryPictIndexValues, req); + req->reqType = info->codes->major_opcode; + req->renderReqType = X_RenderQueryPictIndexValues; + req->format = format->id; + if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) + { + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + + /* request data length */ + nbytes = (long)rep.length << 2; + /* bytes of actual data in the request */ + nread = rep.numIndexValues * SIZEOF (xIndexValue); + /* size of array returned to application */ + rlength = rep.numIndexValues * sizeof (XIndexValue); + + /* allocate returned data */ + values = (XIndexValue *)Xmalloc (rlength); + if (!values) + { + _XEatData (dpy, nbytes); + UnlockDisplay (dpy); + SyncHandle (); + return 0; + } + + /* read the values one at a time and convert */ + *num = rep.numIndexValues; + for(i = 0; i < rep.numIndexValues; i++) + { + xIndexValue value; + + _XRead (dpy, (char *) &value, SIZEOF (xIndexValue)); + values[i].pixel = value.pixel; + values[i].red = value.red; + values[i].green = value.green; + values[i].blue = value.blue; + values[i].alpha = value.alpha; + } + /* skip any padding */ + if(nbytes > nread) + { + _XEatData (dpy, (unsigned long) (nbytes - nread)); + } + UnlockDisplay (dpy); + SyncHandle (); + return values; +} diff --git a/src/Xrenderint.h b/src/Xrenderint.h new file mode 100644 index 0000000..cfd5824 --- /dev/null +++ b/src/Xrenderint.h @@ -0,0 +1,99 @@ +/* + * $XFree86: xc/lib/Xrender/Xrenderint.h,v 1.4 2002/11/05 23:22:35 keithp Exp $ + * + * Copyright © 2000 SuSE, Inc. + * + * 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 SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * 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. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifndef _XRENDERINT_H_ +#define _XRENDERINT_H_ + +#define NEED_EVENTS +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "Xext.h" /* in ../include */ +#include "extutil.h" /* in ../include */ +#include "Xrender.h" +#include "renderproto.h" + +typedef struct { + Visual *visual; + XRenderPictFormat *format; +} XRenderVisual; + +typedef struct { + int depth; + int nvisuals; + XRenderVisual *visuals; +} XRenderDepth; + +typedef struct { + XRenderDepth *depths; + int ndepths; + XRenderPictFormat *fallback; + int subpixel; +} XRenderScreen; + +typedef struct _XRenderInfo { + int major_version; + int minor_version; + XRenderPictFormat *format; + int nformat; + XRenderScreen *screen; + int nscreen; + XRenderDepth *depth; + int ndepth; + XRenderVisual *visual; + int nvisual; + int *subpixel; + int nsubpixel; + char **filter; + int nfilter; + short *filter_alias; + int nfilter_alias; +} XRenderInfo; + +extern XExtensionInfo XRenderExtensionInfo; +extern char XRenderExtensionName[]; + +#define RenderCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, XRenderExtensionName, val) + +#define RenderSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, XRenderExtensionName) + +XExtDisplayInfo * +XRenderFindDisplay (Display *dpy); + +/* + * Xlib uses long for 32-bit values. Xrender uses int. This + * matters on alpha. Note that this macro assumes that int is 32 bits + * except on WORD64 machines where it is 64 bits. + */ + +#ifdef WORD64 +#define DataInt32(dpy,d,len) Data32(dpy,(long *) (d),len) +#else +#define DataInt32(dpy,d,len) Data(dpy,(char *) (d),len) +#endif + +#endif /* _XRENDERINT_H_ */ |