diff options
author | Jamey Sharp <jamey@minilop.net> | 2006-06-12 03:28:10 -0700 |
---|---|---|
committer | Jamey Sharp <jamey@minilop.net> | 2006-06-12 03:28:10 -0700 |
commit | 9a72efce997f21bd28e218e4596e6431bfb46be5 (patch) | |
tree | ee785552cebec3dcf8192b1bcf885e9f3177fe55 /renderutil | |
parent | 4abc512d3e08e2e84f50901299d7dda241cebef8 (diff) |
New utility library: port of libXrender utility functions.
Diffstat (limited to 'renderutil')
-rw-r--r-- | renderutil/Makefile.am | 14 | ||||
-rw-r--r-- | renderutil/cache.c | 239 | ||||
-rw-r--r-- | renderutil/util.c | 250 | ||||
-rw-r--r-- | renderutil/xcb-renderutil.pc.in | 11 | ||||
-rw-r--r-- | renderutil/xcb_renderutil.h | 75 |
5 files changed, 589 insertions, 0 deletions
diff --git a/renderutil/Makefile.am b/renderutil/Makefile.am new file mode 100644 index 0000000..0d43b04 --- /dev/null +++ b/renderutil/Makefile.am @@ -0,0 +1,14 @@ + +MAINTAINERCLEANFILES = Makefile.in + +lib_LTLIBRARIES = libXCBRenderUtil.la + +xcbinclude_HEADERS = xcb_renderutil.h + +libXCBRenderUtil_la_SOURCES = cache.c util.c +libXCBRenderUtil_la_CFLAGS = $(XCB_CFLAGS) $(XCB_RENDER_CFLAGS) +libXCBRenderUtil_la_LIBADD = $(XCB_LIBS) $(XCB_RENDER_LIBS) + +pkgconfig_DATA = xcb-renderutil.pc + +EXTRA_DIST=xcb-renderutil.pc.in diff --git a/renderutil/cache.c b/renderutil/cache.c new file mode 100644 index 0000000..7cc19ba --- /dev/null +++ b/renderutil/cache.c @@ -0,0 +1,239 @@ +/* Copyright © 2006 Jamey Sharp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "xcb_renderutil.h" +#include <stdlib.h> +#include <pthread.h> + +typedef struct connection_cache { + struct connection_cache *next; /* keep a linked list */ + XCBConnection *c; /* which display this is */ + XCBRenderQueryVersionRep *version; + XCBRenderQueryPictFormatsRep *formats; +} connection_cache; + +static struct { + pthread_mutex_t lock; + connection_cache *head; /* start of the list */ + connection_cache *cur; /* most recently used */ +} connections = { PTHREAD_MUTEX_INITIALIZER }; + +/* + * If the server is missing support for any of the required depths on + * any screen, tell the application that Render is not present. + */ + +#define DEPTH_MASK(d) (1 << ((d) - 1)) + +/* + * Render requires support for depth 1, 4, 8, 24 and 32 pixmaps + */ + +#define REQUIRED_DEPTHS (DEPTH_MASK(1) | \ + DEPTH_MASK(4) | \ + DEPTH_MASK(8) | \ + DEPTH_MASK(24) | \ + DEPTH_MASK(32)) + +/* FIXME: XCB's "Plan 7" needs to be implemented before this code will work. */ +extern XCBVoidCookie XCBCreatePixmapChecked(XCBConnection *, int, XCBPIXMAP, XCBDRAWABLE, int, int); +extern XCBVoidCookie XCBFreePixmapChecked(XCBConnection *, XCBPIXMAP); +extern XCBGenericError *XCBRequestCheck(XCBConnection *, XCBVoidCookie); + +/* Test each depth not explicitly advertised to see if pixmap creation + * succeeds: if it does, that depth is usable. */ +static int +pixmap_depths_usable (XCBConnection *c, CARD32 missing, XCBPIXMAP pixmap, XCBDRAWABLE root) +{ + XCBVoidCookie create_cookie[32] = { { 0 } }; + XCBVoidCookie free_cookie[32] = { { 0 } }; + int d; + int success = 1; + for (d = 1; d <= 32; d++) + if (missing & DEPTH_MASK(d)) + { + create_cookie[d - 1] = XCBCreatePixmapChecked (c, d, pixmap, root, 1, 1); + free_cookie[d - 1] = XCBFreePixmapChecked (c, pixmap); + if (!create_cookie[d - 1].sequence || !free_cookie[d - 1].sequence) + { + success = 0; + break; + } + } + for (d = 0; d < 32; d++) + if (create_cookie[d].sequence || free_cookie[d].sequence) + { + XCBGenericError *create_error = XCBRequestCheck (c, create_cookie[d]); + XCBGenericError *free_error = XCBRequestCheck (c, free_cookie[d]); + success = success && !create_error; + free(create_error); + free(free_error); + } + return success; +} + +static int +has_required_depths (XCBConnection *c) +{ + XCBSCREENIter screens; + XCBPIXMAP pixmap = { -1 }; + for (screens = XCBSetupRootsIter(XCBGetSetup(c)); screens.rem; XCBSCREENNext(&screens)) + { + XCBDEPTHIter depths; + CARD32 missing = REQUIRED_DEPTHS; + XCBDRAWABLE root; + + for (depths = XCBSCREENAllowedDepthsIter(screens.data); depths.rem; XCBDEPTHNext(&depths)) + missing &= ~DEPTH_MASK(depths.data->depth); + if (!missing) + continue; + + /* + * Ok, this is ugly. It should be sufficient at this + * point to just return false, but Xinerama is broken at + * this point and only advertises depths which have an + * associated visual. Of course, the other depths still + * work, but the only way to find out is to try them. + */ + if (pixmap.xid == -1) + pixmap = XCBPIXMAPNew(c); + root.window = screens.data->root; + if (!pixmap_depths_usable (c, missing, pixmap, root)) + return 0; + } + return 1; +} + +static connection_cache * +find_or_create_display (XCBConnection *c) +{ + connection_cache *info; + XCBRenderQueryVersionCookie version_cookie; + XCBRenderQueryPictFormatsCookie formats_cookie; + int present; + + /* + * look for display in list + */ + for (info = connections.head; info; info = info->next) + if (info->c == c) { + connections.cur = info; /* cache most recently used */ + return info; + } + + /* + * don't already have this display: add it. + */ + info = malloc (sizeof (connection_cache)); + if (!info) + return NULL; + info->c = c; + + version_cookie = XCBRenderQueryVersion(c, 0, 10); + formats_cookie = XCBRenderQueryPictFormats(c); + XCBFlush(c); + present = has_required_depths (c); + info->version = XCBRenderQueryVersionReply(c, version_cookie, 0); + info->formats = XCBRenderQueryPictFormatsReply(c, formats_cookie, 0); + + if (!present || !info->version || !info->formats) + { + free(info->version); + info->version = 0; + free(info->formats); + info->formats = 0; + } + /* Check for the lack of sub-pixel data */ + else if (info->version->major_version == 0 && info->version->minor_version < 6) + info->formats->num_subpixel = 0; + + /* + * now, chain it onto the list + */ + info->next = connections.head; + connections.head = info; + connections.cur = info; + + return info; +} + +static connection_cache * +find_display (XCBConnection *c) +{ + connection_cache *info; + + /* + * see if this was the most recently accessed display + */ + if ((info = connections.cur) && info->c == c) + return info; + + pthread_mutex_lock(&connections.lock); + info = find_or_create_display (c); + pthread_mutex_unlock(&connections.lock); + return info; +} + +const XCBRenderQueryVersionRep * +XCBRenderUtilQueryVersion (XCBConnection *c) +{ + connection_cache *info = find_display (c); + if (!info) + return 0; + return info->version; +} + +const XCBRenderQueryPictFormatsRep * +XCBRenderUtilQueryFormats (XCBConnection *c) +{ + connection_cache *info = find_display (c); + if (!info) + return 0; + return info->formats; +} + +int +XCBRenderUtilDisconnect (XCBConnection *c) +{ + connection_cache **prev, *cur = NULL; + pthread_mutex_lock(&connections.lock); + for(prev = &connections.head; *prev; prev = &(*prev)->next) + if((*prev)->c == c) + { + cur = *prev; + *prev = cur->next; + if(cur == connections.cur) + connections.cur = NULL; /* flush cache */ + free(cur->version); + free(cur->formats); + free(cur); + break; + } + pthread_mutex_unlock(&connections.lock); + return cur != NULL; +} diff --git a/renderutil/util.c b/renderutil/util.c new file mode 100644 index 0000000..c8bf356 --- /dev/null +++ b/renderutil/util.c @@ -0,0 +1,250 @@ +/* Copyright © 2000 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. + */ + +#include "xcb_renderutil.h" + +XCBRenderPICTVISUAL * +XCBRenderUtilFindVisualFormat (XCBRenderQueryPictFormatsRep *formats, const XCBVISUALID visual) +{ + XCBRenderPICTSCREENIter screens; + XCBRenderPICTDEPTHIter depths; + XCBRenderPICTVISUALIter visuals; + if (!formats) + return 0; + for (screens = XCBRenderQueryPictFormatsScreensIter(formats); screens.rem; XCBRenderPICTSCREENNext(&screens)) + for (depths = XCBRenderPICTSCREENDepthsIter(screens.data); depths.rem; XCBRenderPICTDEPTHNext(&depths)) + for (visuals = XCBRenderPICTDEPTHVisualsIter(depths.data); visuals.rem; XCBRenderPICTVISUALNext(&visuals)) + if (visuals.data->visual.id == visual.id) + return visuals.data; + return 0; +} + +XCBRenderPICTFORMINFO * +XCBRenderUtilFindFormat (const XCBRenderQueryPictFormatsRep *formats, + unsigned long mask, + const XCBRenderPICTFORMINFO *template, + int count) +{ + XCBRenderPICTFORMINFOIter i; + if (!formats) + return 0; + for (i = XCBRenderQueryPictFormatsFormatsIter(formats); i.rem; XCBRenderPICTFORMINFONext(&i)) + { + if (mask & PictFormatID) + if (template->id.xid != i.data->id.xid) + continue; + if (mask & PictFormatType) + if (template->type != i.data->type) + continue; + if (mask & PictFormatDepth) + if (template->depth != i.data->depth) + continue; + if (mask & PictFormatRed) + if (template->direct.red_shift != i.data->direct.red_shift) + continue; + if (mask & PictFormatRedMask) + if (template->direct.red_mask != i.data->direct.red_mask) + continue; + if (mask & PictFormatGreen) + if (template->direct.green_shift != i.data->direct.green_shift) + continue; + if (mask & PictFormatGreenMask) + if (template->direct.green_mask != i.data->direct.green_mask) + continue; + if (mask & PictFormatBlue) + if (template->direct.blue_shift != i.data->direct.blue_shift) + continue; + if (mask & PictFormatBlueMask) + if (template->direct.blue_mask != i.data->direct.blue_mask) + continue; + if (mask & PictFormatAlpha) + if (template->direct.alpha_shift != i.data->direct.alpha_shift) + continue; + if (mask & PictFormatAlphaMask) + if (template->direct.alpha_mask != i.data->direct.alpha_mask) + continue; + if (mask & PictFormatColormap) + if (template->colormap.xid != i.data->colormap.xid) + continue; + if (count-- == 0) + return i.data; + } + return 0; +} + +XCBRenderPICTFORMINFO * +XCBRenderUtilFindStandardFormat (const XCBRenderQueryPictFormatsRep *formats, + int format) +{ + static const struct { + XCBRenderPICTFORMINFO templ; + unsigned long mask; + } standardFormats[] = { + /* PictStandardARGB32 */ + { + { + { 0 }, /* id */ + XCBRenderPictTypeDirect, /* type */ + 32, /* depth */ + { 0 }, /* pad */ + { /* 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 */ + XCBRenderPictTypeDirect, /* type */ + 24, /* depth */ + { 0 }, /* pad */ + { /* 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 */ + XCBRenderPictTypeDirect, /* type */ + 8, /* depth */ + { 0 }, /* pad */ + { /* 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 */ + XCBRenderPictTypeDirect, /* type */ + 4, /* depth */ + { 0 }, /* pad */ + { /* 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 */ + XCBRenderPictTypeDirect, /* type */ + 1, /* depth */ + { 0 }, /* pad */ + { /* 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 (format < 0 || format >= sizeof(standardFormats) / sizeof(*standardFormats)) + return 0; + + return XCBRenderUtilFindFormat (formats, + standardFormats[format].mask, + &standardFormats[format].templ, + 0); +} diff --git a/renderutil/xcb-renderutil.pc.in b/renderutil/xcb-renderutil.pc.in new file mode 100644 index 0000000..62a0994 --- /dev/null +++ b/renderutil/xcb-renderutil.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: XCBRenderUtil +Description: XCB RENDER-extension utilities library +Version: @PACKAGE_VERSION@ +Requires: xcb xcb-render +Libs: -L${libdir} -lXCBRenderUtil @LIBS@ +Cflags: -I${includedir} diff --git a/renderutil/xcb_renderutil.h b/renderutil/xcb_renderutil.h new file mode 100644 index 0000000..e18c879 --- /dev/null +++ b/renderutil/xcb_renderutil.h @@ -0,0 +1,75 @@ +/* Copyright © 2006 Jamey Sharp. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the names of the authors or their + * institutions shall not be used in advertising or otherwise to promote the + * sale, use or other dealings in this Software without prior written + * authorization from the authors. + */ + +#ifndef XCB_RENDERUTIL +#define XCB_RENDERUTIL +#include <X11/XCB/render.h> + +/* FIXME: These PictFormat declarations should be in render.xml. */ +#define PictFormatID (1 << 0) +#define PictFormatType (1 << 1) +#define PictFormatDepth (1 << 2) +#define PictFormatRed (1 << 3) +#define PictFormatRedMask (1 << 4) +#define PictFormatGreen (1 << 5) +#define PictFormatGreenMask (1 << 6) +#define PictFormatBlue (1 << 7) +#define PictFormatBlueMask (1 << 8) +#define PictFormatAlpha (1 << 9) +#define PictFormatAlphaMask (1 << 10) +#define PictFormatColormap (1 << 11) + +enum { + PictStandardARGB32, + PictStandardRGB24, + PictStandardA8, + PictStandardA4, + PictStandardA1, + PictStandardNUM +}; + +XCBRenderPICTVISUAL * +XCBRenderUtilFindVisualFormat (XCBRenderQueryPictFormatsRep *formats, const XCBVISUALID visual); + +XCBRenderPICTFORMINFO * +XCBRenderUtilFindFormat (const XCBRenderQueryPictFormatsRep *formats, + unsigned long mask, + const XCBRenderPICTFORMINFO *template, + int count); + +XCBRenderPICTFORMINFO * +XCBRenderUtilFindStandardFormat (const XCBRenderQueryPictFormatsRep *formats, + int format); + +const XCBRenderQueryVersionRep * +XCBRenderUtilQueryVersion (XCBConnection *c); + +const XCBRenderQueryPictFormatsRep * +XCBRenderUtilQueryFormats (XCBConnection *c); + +int +XCBRenderUtilDisconnect (XCBConnection *c); + +#endif /* XCB_RENDERUTIL */ |