diff options
25 files changed, 6702 insertions, 16 deletions
@@ -14,29 +14,37 @@ pub fn build(b: *std.Build) void { const libXcb = buildXcb(b, &target, optimize, single_threaded); lib.linkLibrary(libXcb); - lib.addIncludePath(.{ .path = "depends/libxcb/include" }); - lib.addIncludePath(.{ .path = "depends/libxcb-keysyms" }); - lib.addIncludePath(.{ .path = "depends/libxcb/depends/xorgproto/include" }); - lib.addIncludePath(.{ .path = "depends/libxcb-render-util" }); lib.linkLibC(); lib.strip = optimize != std.builtin.OptimizeMode.Debug; lib.want_lto = optimize != std.builtin.OptimizeMode.Debug; lib.single_threaded = single_threaded; + lib.addIncludePath(.{ .path = "depends/libxcb/include" }); lib.installHeadersDirectory("depends/libxcb/include", "."); - lib.installHeadersDirectoryOptions(.{ - .source_dir = .{ .path = "depends/libxcb-keysyms" }, - .install_dir = .header, - .install_subdir = ".", - .exclude_extensions = &.{ ".c" }, - }); - lib.installHeadersDirectoryOptions(.{ - .source_dir = .{ .path = "depends/libxcb-render-util" }, - .install_dir = .header, - .install_subdir = ".", - .exclude_extensions = &.{ ".c" }, - }); + + lib.addIncludePath(.{ .path = "depends/libxcb/depends/xorgproto/include" }); lib.installHeadersDirectory("depends/libxcb/depends/xorgproto/include", "."); + + const util_deps = [_][]const u8 { + "depends/libxcb-keysyms", + "depends/libxcb-render-util", + "depends/libxcb-wm", + "depends/libxcb-util", + "depends/libxcb-image", + "depends/libxcb-errors", + "depends/libxcb-cursor", + }; + + for(&util_deps) |dep| { + lib.addIncludePath(.{ .path = dep }); + lib.installHeadersDirectoryOptions(.{ + .source_dir = .{ .path = dep }, + .install_dir = .header, + .install_subdir = ".", + .exclude_extensions = &.{ ".c" }, + }); + } + b.installArtifact(lib); } @@ -177,6 +185,25 @@ fn buildXcb(b: *std.Build, target: *const std.zig.CrossTarget, optimize: std.bui "depends/libxcb-render-util/xcb/cache.c", "depends/libxcb-render-util/xcb/glyph.c", "depends/libxcb-render-util/xcb/util.c", + + // libxcb-wm + "depends/libxcb-wm/xcb/icccm.c", + + // libxcb-util + "depends/libxcb-util/xcb/event.c", + "depends/libxcb-util/xcb/xcb_aux.c", + "depends/libxcb-util/xcb/atoms.c", + + // libxcb-image + "depends/libxcb-image/xcb/xcb_image.c", + + // libxcb-errors + "depends/libxcb-errors/xcb/xcb_errors.c", + + // libxcb-cursor + "depends/libxcb-cursor/xcb/parse_cursor_file.c", + "depends/libxcb-cursor/xcb/load_cursor.c", + "depends/libxcb-cursor/xcb/cursor.c", }, .flags = &.{ "-DHAVE_CONFIG_H", diff --git a/depends/libxcb-cursor/xcb/cursor.c b/depends/libxcb-cursor/xcb/cursor.c new file mode 100644 index 0000000..2f56f19 --- /dev/null +++ b/depends/libxcb-cursor/xcb/cursor.c @@ -0,0 +1,179 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * Copyright © 2013 Michael Stapelberg + * + * 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. + * + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <xcb/xcb.h> +#include <xcb/xcb_renderutil.h> + +#include "cursor.h" +#include "xcb_cursor.h" + +/* + * Parses the root window’s RESOURCE_MANAGER atom contents and stores the + * attributes declared above in resource_manager_val. + * + */ +static void parse_resource_manager(xcb_cursor_context_t *c, const xcb_get_property_reply_t *rm_reply) { + int rm_length; + char *rm = NULL; + char *saveptr = NULL; + char *line = NULL; + char *sep = NULL; + + if (rm_reply == NULL || (rm_length = xcb_get_property_value_length(rm_reply)) == 0) + return; + + if (asprintf(&rm, "%.*s", rm_length, (char*)xcb_get_property_value(rm_reply)) == -1) + return; + + for (char *str = rm; ; str = NULL) { + if ((line = strtok_r(str, "\n", &saveptr)) == NULL) + break; + /* Split the string at the delimiting : */ + if ((sep = strchr(line, ':')) == NULL) { + /* Invalid line?! */ + free(rm); + return; + } + *(sep++) = '\0'; + while (isspace(*sep)) + sep++; + /* strdup() may return NULL, which is interpreted later as the key not + * being available. */ + if (strcmp(line, "Xcursor.theme") == 0) { + free(c->rm[RM_XCURSOR_THEME]); + c->rm[RM_XCURSOR_THEME] = strdup(sep); + } else if (strcmp(line, "Xcursor.size") == 0) { + free(c->rm[RM_XCURSOR_SIZE]); + c->rm[RM_XCURSOR_SIZE] = strdup(sep); + } else if (strcmp(line, "Xft.dpi") == 0) { + free(c->rm[RM_XFT_DPI]); + c->rm[RM_XFT_DPI] = strdup(sep); + } + } + + free(rm); +} + +/* + * Tries to figure out the cursor size by checking: + * 1. The environment variable XCURSOR_SIZE + * 2. The RESOURCE_MANAGER entry Xcursor.size + * 3. Guess with the RESOURCE_MANAGER entry Xft.dpi * 16 / 72 + * 4. Guess with the display size. + * + */ +static uint32_t get_default_size(xcb_cursor_context_t *c, xcb_screen_t *screen) { + char *env; + uint16_t dim; + + if ((env = getenv("XCURSOR_SIZE")) != NULL) + return atoi(env); + + if (c->rm[RM_XCURSOR_SIZE] != NULL) + return atoi(c->rm[RM_XCURSOR_SIZE]); + + if (c->rm[RM_XFT_DPI] != NULL) { + const int dpi = atoi(c->rm[RM_XFT_DPI]); + if (dpi > 0) + return dpi * 16 / 72; + } + + if (screen->height_in_pixels < screen->width_in_pixels) + dim = screen->height_in_pixels; + else + dim = screen->width_in_pixels; + + return dim / 48; +} + +int xcb_cursor_context_new(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_context_t **ctx) { + xcb_cursor_context_t *c; + const xcb_query_extension_reply_t *ext; + xcb_get_property_cookie_t rm_cookie; + xcb_get_property_reply_t *rm_reply; + xcb_render_query_pict_formats_cookie_t pf_cookie; + xcb_render_query_version_cookie_t ver_cookie; + + if ((*ctx = calloc(1, sizeof(struct xcb_cursor_context_t))) == NULL) + return -errno; + + c = *ctx; + c->conn = conn; + c->root = screen->root; + c->render_version = RV_NONE; + + ext = xcb_get_extension_data(conn, &xcb_render_id); + + // XXX: Is it maybe necessary to ever use long_offset != 0? + // XXX: proper length? xlib seems to use 100 MB o_O + rm_cookie = xcb_get_property(conn, 0, c->root, XCB_ATOM_RESOURCE_MANAGER, XCB_ATOM_STRING, 0, 16 * 1024); + if (ext && ext->present) { + ver_cookie = xcb_render_query_version(conn, XCB_RENDER_MAJOR_VERSION, XCB_RENDER_MINOR_VERSION); + pf_cookie = xcb_render_query_pict_formats(conn); + } + c->cursor_font = xcb_generate_id(conn); + xcb_open_font(conn, c->cursor_font, strlen("cursor"), "cursor"); + + rm_reply = xcb_get_property_reply(conn, rm_cookie, NULL); + parse_resource_manager(c, rm_reply); + free(rm_reply); + + if (ext && ext->present) { + xcb_render_query_version_reply_t *reply = xcb_render_query_version_reply(conn, ver_cookie, NULL); + + if (reply && (reply->major_version >= 1 || reply->minor_version >= 8)) + c->render_version = RV_ANIM_CURSOR; + else if (reply && (reply->major_version >= 1 || reply->minor_version >= 5)) + c->render_version = RV_CURSOR; + free(reply); + + c->pf_reply = xcb_render_query_pict_formats_reply(conn, pf_cookie, NULL); + c->pict_format = xcb_render_util_find_standard_format(c->pf_reply, XCB_PICT_STANDARD_ARGB_32); + } + + c->size = get_default_size(c, screen); + + return 0; +} + +void xcb_cursor_context_free(xcb_cursor_context_t *c) { + free(c->rm[RM_XCURSOR_THEME]); + free(c->rm[RM_XCURSOR_SIZE]); + free(c->rm[RM_XFT_DPI]); + free(c->pf_reply); + free(c); +} diff --git a/depends/libxcb-cursor/xcb/cursor.h b/depends/libxcb-cursor/xcb/cursor.h new file mode 100644 index 0000000..455dc34 --- /dev/null +++ b/depends/libxcb-cursor/xcb/cursor.h @@ -0,0 +1,169 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * Copyright © 2013 Michael Stapelberg + * + * 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 CURSOR_H +#define CURSOR_H + +#include <xcb/render.h> + +#include "xcb_cursor.h" + +enum { + RM_XCURSOR_THEME = 0, + RM_XCURSOR_SIZE, + RM_XFT_DPI, + RM_MAX, +}; + +enum render_version { + RV_NONE = 0, + /* RENDER's CreateCursor was added in RENDER 0.5 */ + RV_CURSOR, + /* RENDER's CreateAnimCursor was added in RENDER 0.8 */ + RV_ANIM_CURSOR +}; + +struct xcb_cursor_context_t { + xcb_connection_t *conn; + xcb_window_t root; + + xcb_font_t cursor_font; + + xcb_render_query_pict_formats_reply_t *pf_reply; + + /* This is a pointer into pf_reply. */ + xcb_render_pictforminfo_t *pict_format; + + /* Specific values of the root window’s RESOURCE_MANAGER atom contents. */ + char *rm[RM_MAX]; + + /* Best cursor size. If a file contains multiple cursor images, the images + * which match the size best will be loaded. */ + uint32_t size; + + const char *home; + const char *path; + + enum render_version render_version; +}; + +/* + * Cursor files start with a header. The header + * contains a magic number, a version number and a + * table of contents which has type and offset information + * for the remaining tables in the file. + * + * File minor versions increment for compatible changes + * File major versions increment for incompatible changes (never, we hope) + * + * Chunks of the same type are always upward compatible. Incompatible + * changes are made with new chunk types; the old data can remain under + * the old type. Upward compatible changes can add header data as the + * header lengths are specified in the file. + * + * File: + * FileHeader + * LISTofChunk + * + * FileHeader: + * CARD32 magic magic number + * CARD32 header bytes in file header + * CARD32 version file version + * CARD32 ntoc number of toc entries + * LISTofFileToc toc table of contents + * + * FileToc: + * CARD32 type entry type + * CARD32 subtype entry subtype (size for images) + * CARD32 position absolute file position + */ + +/* little-endian */ +#define XCURSOR_MAGIC 0x72756358 + +typedef struct xcint_file_header_t { + uint32_t magic; + uint32_t header; + uint32_t version; + uint32_t ntoc; +} __attribute__((packed)) xcint_file_header_t; + +typedef struct xcint_file_toc_t { + uint32_t type; + uint32_t subtype; + uint32_t position; +} __attribute__((packed)) xcint_file_toc_t; + +typedef struct xcint_cursor_file_t { + xcint_file_header_t header; + xcint_file_toc_t *tocs; +} xcint_cursor_file_t; + +/* + * The rest of the file is a list of chunks, each tagged by type + * and version. + * + * Chunk: + * ChunkHeader + * <extra type-specific header fields> + * <type-specific data> + * + * ChunkHeader: + * CARD32 header bytes in chunk header + type header + * CARD32 type chunk type + * CARD32 subtype chunk subtype + * CARD32 version chunk type version + */ + +typedef struct xcint_chunk_header_t { + uint32_t header; + uint32_t type; + uint32_t subtype; + uint32_t version; +} __attribute__((packed)) xcint_chunk_header_t; + +#define XCURSOR_IMAGE_TYPE 0xfffd0002 +#define XCURSOR_IMAGE_VERSION 1 +#define XCURSOR_IMAGE_MAX_SIZE 0x7fff /* 32767x32767 max cursor size */ + +typedef struct xcint_image_t { + uint32_t width; + uint32_t height; + uint32_t xhot; + uint32_t yhot; + uint32_t delay; + uint32_t *pixels; +} __attribute__((packed)) xcint_image_t; + +/* shape_to_id.c */ +const int cursor_shape_to_id(const char *name); + +/* parse_cursor_file.c */ +int parse_cursor_file(xcb_cursor_context_t *c, const int fd, xcint_image_t **images, int *nimg); + +#endif diff --git a/depends/libxcb-cursor/xcb/load_cursor.c b/depends/libxcb-cursor/xcb/load_cursor.c new file mode 100644 index 0000000..0e96f8a --- /dev/null +++ b/depends/libxcb-cursor/xcb/load_cursor.c @@ -0,0 +1,290 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * Copyright © 2013 Michael Stapelberg + * Copyright © 2002 Keith Packard + * + * 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. + * + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include <xcb/xcb.h> +#include <xcb/render.h> +#include <xcb/xcb_image.h> + +#include "cursor.h" +#include "xcb_cursor.h" + +#ifdef O_CLOEXEC +#define FOPEN_CLOEXEC "e" +#else +#define FOPEN_CLOEXEC "" +#define O_CLOEXEC 0 +#endif + +#define XCURSORPATH "~/.icons:/usr/share/icons:/usr/share/pixmaps:/usr/X11R6/lib/X11/icons" + +static const char *cursor_path(struct xcb_cursor_context_t *c) { + if (c->path == NULL) { + c->path = getenv("XCURSOR_PATH"); + if (c->path == NULL) + c->path = XCURSORPATH; + } + return c->path; +} + +static const char *next_path(const char *path) { + const char *colon = strchr(path, ':'); + return (colon ? colon + 1 : NULL); +} + +/* + * _XcursorThemeInherits was directly copied from libxcursor so as to not break + * compatibility. + * + */ +#define XcursorWhite(c) ((c) == ' ' || (c) == '\t' || (c) == '\n') +#define XcursorSep(c) ((c) == ';' || (c) == ',') + +static char * +_XcursorThemeInherits (const char *full) +{ + char line[8192]; + char *result = NULL; + FILE *f; + + if (!full) + return NULL; + + f = fopen (full, "r" FOPEN_CLOEXEC); + if (f) + { + while (fgets (line, sizeof (line), f)) + { + if (!strncmp (line, "Inherits", 8)) + { + char *l = line + 8; + while (*l == ' ') l++; + if (*l != '=') continue; + l++; + while (*l == ' ') l++; + result = malloc (strlen (l) + 1); + if (result) + { + char *r = result; + while (*l) + { + while (XcursorSep(*l) || XcursorWhite (*l)) l++; + if (!*l) + break; + if (r != result) + *r++ = ':'; + while (*l && !XcursorWhite(*l) && + !XcursorSep(*l)) + *r++ = *l++; + } + *r++ = '\0'; + } + break; + } + } + fclose (f); + } + return result; +} + +/* + * Tries to open the cursor file “name” in the “theme”/cursors subfolder of + * each component of cursor_path(). When the file cannot be found, but a file + * “index.theme” in the component is present, the Inherits= key will be + * extracted and open_cursor_file calls itself recursively to search the + * specified inherited themes, too. + * + */ +static int open_cursor_file(xcb_cursor_context_t *c, const char *theme, const char *name, int *scan_core) { + int fd = -1; + char *inherits = NULL; + + *scan_core = -1; + + if (strcmp(theme, "core") == 0 && + (*scan_core = cursor_shape_to_id(name)) >= 0) { + return -1; + } + + if (c->home == NULL) + if ((c->home = getenv("HOME")) == NULL) + return -1; + + for (const char *path = cursor_path(c); + (path != NULL && fd == -1); + ) { + const char *sep = strchr(path, ':'); + const int pathlen = (sep ? (sep - path) : strlen(path)); + char *themedir = NULL; + char *full = NULL; + if (*path == '~') { + if (asprintf(&themedir, "%s%.*s/%s", c->home, pathlen - 1, path + 1, theme) == -1) + return -1; + } else { + if (asprintf(&themedir, "%.*s/%s", pathlen, path, theme) == -1) + return -1; + } + if (asprintf(&full, "%s/%s/%s", themedir, "cursors", name) == -1) { + free(themedir); + return -1; + } + fd = open(full, O_RDONLY | O_CLOEXEC); + free(full); + if (fd == -1 && inherits == NULL) { + if (asprintf(&full, "%s/index.theme", themedir) == -1) { + free(themedir); + return -1; + } + inherits = _XcursorThemeInherits(full); + free(full); + } + free(themedir); + path = (sep ? sep + 1 : NULL); + } + + for (const char *path = inherits; + (path != NULL && fd == -1); + (path = next_path(path))) { + fd = open_cursor_file(c, path, name, scan_core); + } + + if (inherits != NULL) + free(inherits); + + return fd; +} + +xcb_cursor_t xcb_cursor_load_cursor(xcb_cursor_context_t *c, const char *name) { + /* The character id of the X11 "cursor" font when falling back to un-themed + * cursors. */ + int core_char = -1; + int fd = -1; + xcint_image_t *images; + int nimg = 0; + xcb_pixmap_t pixmap = XCB_NONE; + xcb_gcontext_t gc = XCB_NONE; + uint32_t last_width = 0; + uint32_t last_height = 0; + xcb_cursor_t cid = XCB_NONE; + + // NB: if !render_present, fd will be -1 and thus the next if statement + // will trigger the fallback. + if (c->render_version != RV_NONE) { + if (c->rm[RM_XCURSOR_THEME]) + fd = open_cursor_file(c, c->rm[RM_XCURSOR_THEME], name, &core_char); + + if (fd == -1 && core_char == -1) + fd = open_cursor_file(c, "default", name, &core_char); + } + + if (fd == -1 || core_char > -1) { + if (core_char == -1) + core_char = cursor_shape_to_id(name); + if (core_char == -1) + return XCB_NONE; + + cid = xcb_generate_id(c->conn); + xcb_create_glyph_cursor(c->conn, cid, c->cursor_font, c->cursor_font, core_char, core_char + 1, 0, 0, 0, 65535, 65535, 65535); + return cid; + } + + if (parse_cursor_file(c, fd, &images, &nimg) < 0) { + close(fd); + return XCB_NONE; + } + + close(fd); + + /* create a cursor from it */ + xcb_render_animcursorelt_t elements[nimg]; + xcb_render_picture_t pic = xcb_generate_id(c->conn); + + for (int n = 0; n < nimg; n++) { + xcint_image_t *i = &(images[n]); + xcb_image_t *img = xcb_image_create_native(c->conn, i->width, i->height, XCB_IMAGE_FORMAT_Z_PIXMAP, 32, NULL, (i->width * i->height * sizeof(uint32_t)), (uint8_t*)i->pixels); + + if (pixmap == XCB_NONE || + (i->width != last_width) || + (i->height != last_height)) { + if (pixmap == XCB_NONE) { + pixmap = xcb_generate_id(c->conn); + gc = xcb_generate_id(c->conn); + } else { + xcb_free_pixmap(c->conn, pixmap); + xcb_free_gc(c->conn, gc); + } + + xcb_create_pixmap(c->conn, 32, pixmap, c->root, i->width, i->height); + xcb_create_gc(c->conn, gc, pixmap, 0, NULL); + + last_width = i->width; + last_height = i->height; + } + + xcb_image_put(c->conn, pixmap, gc, img, 0, 0, 0); + + xcb_render_create_picture(c->conn, pic, pixmap, c->pict_format->id, 0, NULL); + + elements[n].cursor = xcb_generate_id(c->conn); + elements[n].delay = i->delay; + + xcb_render_create_cursor(c->conn, elements[n].cursor, pic, i->xhot, i->yhot); + + xcb_render_free_picture(c->conn, pic); + xcb_image_destroy(img); + free(i->pixels); + } + + xcb_free_pixmap(c->conn, pixmap); + xcb_free_gc(c->conn, gc); + free(images); + + if (nimg == 1 || c->render_version == RV_CURSOR) { + /* non-animated cursor or no support for animated cursors */ + return elements[0].cursor; + } else { + cid = xcb_generate_id(c->conn); + xcb_render_create_anim_cursor (c->conn, cid, nimg, elements); + + for (int n = 0; n < nimg; n++) { + xcb_free_cursor(c->conn, elements[n].cursor); + } + + return cid; + } +} diff --git a/depends/libxcb-cursor/xcb/parse_cursor_file.c b/depends/libxcb-cursor/xcb/parse_cursor_file.c new file mode 100644 index 0000000..21f72bf --- /dev/null +++ b/depends/libxcb-cursor/xcb/parse_cursor_file.c @@ -0,0 +1,198 @@ +/* + * vim:ts=4:sw=4:expandtab + * + * Copyright © 2013 Michael Stapelberg + * + * 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. + * + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdbool.h> + +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#endif +#ifdef HAVE_SYS_ENDIAN_H +#include <sys/endian.h> +#endif +#ifdef HAVE_SYS_BYTEORDER_H +#include <sys/byteorder.h> +# ifndef HAVE_LE32TOH +# define le32toh(x) LE_32(x) +# endif +#elif defined(HAVE_LIBKERN_OSBYTEORDER_H) +#include <libkern/OSByteOrder.h> +#define le32toh(x) OSSwapLittleToHostInt32(x) +#endif + +#include <xcb/xcb.h> + +#include "cursor.h" +#include "xcb_cursor.h" + +static uint32_t dist(const uint32_t a, const uint32_t b) { + return (a > b ? (a - b) : (b - a)); +} + +static uint32_t find_best_size(xcint_cursor_file_t *cf, const uint32_t target, uint32_t *nsizesp) { + uint32_t best = 0; + /* Amount of cursors with the best size */ + uint32_t nsizes = 0; + for (int n = 0; n < cf->header.ntoc; n++) { + const uint32_t size = cf->tocs[n].subtype; + + if (cf->tocs[n].type != XCURSOR_IMAGE_TYPE) + continue; + + /* If the distance is less to the target size, this is a better fit. */ + if (best == 0 || dist(size, target) < dist(best, target)) { + best = size; + nsizes = 0; + } + + if (size == best) + nsizes++; + } + + *nsizesp = nsizes; + return best; +} + +/* Returns true if and only if the read() call read the entirety of the data it + * was supposed to read. */ +static bool read_entirely(int fd, void *buf, size_t count) { + return read(fd, buf, count) == count; +} + +int parse_cursor_file(xcb_cursor_context_t *c, const int fd, xcint_image_t **images, int *nimg) { + /* Read the header, verify the magic value. */ + xcint_cursor_file_t cf; + uint32_t nsizes = 0; + uint32_t best = 0; + uint32_t skip = 0; + /* The amount of images stored in 'images', used when cleaning up. */ + int cnt = 0; + + if (!read_entirely(fd, &(cf.header), sizeof(xcint_file_header_t))) + return -EINVAL; + + cf.header.magic = le32toh(cf.header.magic); + cf.header.header = le32toh(cf.header.header); + cf.header.version = le32toh(cf.header.version); + cf.header.ntoc = le32toh(cf.header.ntoc); + + if (cf.header.magic != XCURSOR_MAGIC) + return -EINVAL; + + if ((skip = (cf.header.header - sizeof(xcint_file_header_t))) > 0) + if (lseek(fd, skip, SEEK_CUR) == EOF) + return -EINVAL; + + if (cf.header.ntoc > 0x10000) + return -EINVAL; + + /* Read the table of contents */ + cf.tocs = malloc(cf.header.ntoc * sizeof(xcint_file_toc_t)); + if (!read_entirely(fd, cf.tocs, cf.header.ntoc * sizeof(xcint_file_toc_t))) + goto error; + + for (int n = 0; n < cf.header.ntoc; n++) { + cf.tocs[n].type = le32toh(cf.tocs[n].type); + cf.tocs[n].subtype = le32toh(cf.tocs[n].subtype); + cf.tocs[n].position = le32toh(cf.tocs[n].position); + } + + /* No images? Invalid file. */ + if ((best = find_best_size(&cf, c->size, &nsizes)) == 0 || nsizes == 0) + goto error; + + *nimg = nsizes; + if ((*images = calloc(nsizes, sizeof(xcint_image_t))) == NULL) + goto error; + + for (int n = 0; n < cf.header.ntoc; n++) { + xcint_chunk_header_t chunk; + /* for convenience */ + xcint_image_t *i = &((*images)[cnt]); + uint32_t numpixels = 0; + uint32_t *p = NULL; + + if (cf.tocs[n].type != XCURSOR_IMAGE_TYPE || + cf.tocs[n].subtype != best) + continue; + + lseek(fd, cf.tocs[n].position, SEEK_SET); + if (!read_entirely(fd, &chunk, sizeof(xcint_chunk_header_t))) + goto error2; + chunk.header = le32toh(chunk.header); + chunk.type = le32toh(chunk.type); + chunk.subtype = le32toh(chunk.subtype); + chunk.version = le32toh(chunk.version); + /* Sanity check, as libxcursor does it. */ + if (chunk.type != cf.tocs[n].type || + chunk.subtype != cf.tocs[n].subtype) + goto error2; + if (!read_entirely(fd, i, sizeof(xcint_image_t) - sizeof(uint32_t*))) // TODO: better type + goto error2; + i->width = le32toh(i->width); + i->height = le32toh(i->height); + i->xhot = le32toh(i->xhot); + i->yhot = le32toh(i->yhot); + i->delay = le32toh(i->delay); + + /* Read the actual image data and convert it to host byte order */ + /* Catch integer overflows */ + if (((uint64_t)i->width) * i->height > UINT32_MAX) + goto error2; + numpixels = i->width * i->height; + i->pixels = malloc(numpixels * sizeof(uint32_t)); + /* With the malloc, one more image is eligible for cleanup later. */ + cnt++; + if (!read_entirely(fd, i->pixels, numpixels * sizeof(uint32_t))) + goto error2; + p = i->pixels; + for (int j = 0; j < numpixels; j++, p++) + *p = le32toh(*p); + } + + free(cf.tocs); + return 0; + +error2: + /* Free the memory for all images that were read so far. */ + for (int n = 0; n < cnt; n++) + free((*images)[n].pixels); + free(*images); +error: + *images = NULL; + free(cf.tocs); + return -EINVAL; +} diff --git a/depends/libxcb-cursor/xcb/xcb_cursor.h b/depends/libxcb-cursor/xcb/xcb_cursor.h new file mode 100644 index 0000000..8752a9c --- /dev/null +++ b/depends/libxcb-cursor/xcb/xcb_cursor.h @@ -0,0 +1,124 @@ +#ifndef XCB_CURSOR_H +#define XCB_CURSOR_H + +/* Copyright © 2013 Michael Stapelberg + * + * 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. + */ + +#include <xcb/xcb.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup xcb__cursor_context_t XCB Cursor Functions + * + * These functions are the equivalent of libXcursor, but re-implemented for + * XCB. They respect the user’s configured cursor theme when loading cursors, + * specified by the X resources setting "Xcursor.theme". + * + * Here is how you would use these functions to change the X11 root window + * cursor to "watch": + * @code + * int screennr; + * xcb_connection_t *conn = xcb_connect(NULL, &screennr); + * if (conn == NULL || xcb_connection_has_error(conn)) + * err(EXIT_FAILURE, "Could not connect to X11"); + * + * xcb_screen_t *screen = xcb_aux_get_screen(conn, screennr); + * xcb_cursor_context_t *ctx; + * if (xcb_cursor_context_new(conn, screen, &ctx) < 0) + * err(EXIT_FAILURE, "Could not initialize xcb-cursor"); + * + * xcb_cursor_t cid = xcb_cursor_load_cursor(ctx, "watch"); + * + * xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; + * xcb_change_window_attributes(conn, screen->root, XCB_CW_CURSOR, (uint32_t[]){ cid }); + * xcb_free_cursor(conn, cid); + * xcb_flush(conn); + * + * xcb_cursor_context_free(ctx); + * xcb_disconnect(conn); + * @endcode + * + * @{ + */ + +/** + * @struct xcb_cursor_context_t + * Describes a context for using this library. + * + * Create a context with @ref xcb_cursor_context_new (), then load one or more + * cursors with @ref xcb_cursor_load_cursor () and destroy the context with @ref + * xcb_cursor_context_free (). + */ +typedef struct xcb_cursor_context_t xcb_cursor_context_t; + +/** + * Create a new @ref xcb_cursor_context_t. + * + * @param conn A working XCB connection, which will be used until you destroy + * the context with @ref xcb_cursor_context_free (). + * @param screen The xcb_screen_t to use (e.g. for getting the RESOURCE_MANAGER + * contents, for creating cursors on, for using the size as fallback when + * calculating the best cursor size). + * @param ctx A pointer to an xcb_cursor_context_t* which will be modified to + * refer to the newly created context. + * @return 0 on success, a negative error code otherwise. + * + * @ingroup xcb_cursor_context_t + */ +int xcb_cursor_context_new(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cursor_context_t **ctx); + +/** + * Loads the specified cursor, either from the cursor theme or by falling back + * to the X11 "cursor" font. + * + * @param ctx A cursor context, created with @ref xcb_cursor_context_new () + * @param name The name of the cursor to load, e.g. "watch". + * @returns The ID of the created cursor. When you are done using it, use + * xcb_free_cursor. Calling @ref xcb_cursor_context_free () will NOT free the + * created cursor. + * + */ +xcb_cursor_t xcb_cursor_load_cursor(xcb_cursor_context_t *ctx, const char *name); + +/** + * Frees the @ref xcb_cursor_context_t. + * + * @param ctx The context to free. + * + */ +void xcb_cursor_context_free(xcb_cursor_context_t *ctx); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/depends/libxcb-errors/xcb/errors.h b/depends/libxcb-errors/xcb/errors.h new file mode 100644 index 0000000..ec4fe88 --- /dev/null +++ b/depends/libxcb-errors/xcb/errors.h @@ -0,0 +1,50 @@ +#ifndef __ERRORS_H__ +#define __ERRORS_H__ + +/* Copyright © 2015 Uli Schlachter + * + * 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. + */ + +#include "xcb_errors.h" + +struct static_extension_info_t { + uint16_t num_minor; + uint16_t num_xge_events; + uint8_t num_events; + uint8_t num_errors; + const char *strings_minor; + const char *strings_xge_events; + const char *strings_events; + const char *strings_errors; + const char *name; +}; + +extern const struct static_extension_info_t xproto_info; + +int register_extensions(xcb_errors_context_t *ctx, xcb_connection_t *conn); +int register_extension(xcb_errors_context_t *ctx, xcb_connection_t *conn, + xcb_query_extension_cookie_t cookie, + const struct static_extension_info_t *static_info); + +#endif /* __ERRORS_H__ */ diff --git a/depends/libxcb-errors/xcb/xcb_errors.c b/depends/libxcb-errors/xcb/xcb_errors.c new file mode 100644 index 0000000..2eedc34 --- /dev/null +++ b/depends/libxcb-errors/xcb/xcb_errors.c @@ -0,0 +1,291 @@ +/* Copyright © 2015 Uli Schlachter + * + * 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. + */ + +#include "xcb_errors.h" +#include "errors.h" +#include <stdlib.h> +#include <string.h> + +#define CHECK_CONTEXT(ctx) do { \ + if ((ctx) == NULL) \ + return "xcb-errors API misuse: context argument is NULL"; \ +} while (0) + +struct extension_info_t { + struct extension_info_t *next; + const struct static_extension_info_t *static_info; + uint8_t major_opcode; + uint8_t first_event; + uint8_t first_error; +}; + +struct xcb_errors_context_t { + struct extension_info_t *extensions; +}; + +static const char *get_strings_entry(const char *strings, unsigned int index) { + while (index-- > 0) + strings += strlen(strings) + 1; + return strings; +} + +int register_extension(xcb_errors_context_t *ctx, xcb_connection_t *conn, + xcb_query_extension_cookie_t cookie, + const struct static_extension_info_t *static_info) +{ + struct extension_info_t *info; + xcb_query_extension_reply_t *reply; + + info = calloc(1, sizeof(*info)); + reply = xcb_query_extension_reply(conn, cookie, NULL); + + if (!info || !reply || !reply->present) { + int not_present = reply && !reply->present; + free(info); + free(reply); + if (not_present) + return 0; + return -1; + } + + info->static_info = static_info; + info->major_opcode = reply->major_opcode; + info->first_event = reply->first_event; + info->first_error = reply->first_error; + + info->next = ctx->extensions; + ctx->extensions = info; + free(reply); + + return 0; +} + +int xcb_errors_context_new(xcb_connection_t *conn, xcb_errors_context_t **c) +{ + xcb_errors_context_t *ctx = NULL; + + if ((*c = calloc(1, sizeof(*c))) == NULL) + goto error_out; + + ctx = *c; + ctx->extensions = NULL; + + if (register_extensions(ctx, conn) != 0) + goto error_out; + + return 0; + +error_out: + xcb_errors_context_free(ctx); + *c = NULL; + return -1; +} + +void xcb_errors_context_free(xcb_errors_context_t *ctx) +{ + struct extension_info_t *info; + + if (ctx == NULL) + return; + + info = ctx->extensions; + while (info) { + struct extension_info_t *prev = info; + info = info->next; + free(prev); + } + + free(ctx); +} + +const char *xcb_errors_get_name_for_major_code(xcb_errors_context_t *ctx, + uint8_t major_code) +{ + struct extension_info_t *info; + + CHECK_CONTEXT(ctx); + + info = ctx->extensions; + while (info && info->major_opcode != major_code) + info = info->next; + + if (info == NULL) + return get_strings_entry(xproto_info.strings_minor, major_code); + + return info->static_info->name; +} + +const char *xcb_errors_get_name_for_minor_code(xcb_errors_context_t *ctx, + uint8_t major_code, + uint16_t minor_code) +{ + struct extension_info_t *info; + + CHECK_CONTEXT(ctx); + + info = ctx->extensions; + while (info && info->major_opcode != major_code) + info = info->next; + + if (info == NULL || minor_code >= info->static_info->num_minor) + return NULL; + + return get_strings_entry(info->static_info->strings_minor, minor_code); +} + +const char *xcb_errors_get_name_for_xge_event(xcb_errors_context_t *ctx, + uint8_t major_code, uint16_t event_type) +{ + struct extension_info_t *info; + + CHECK_CONTEXT(ctx); + + info = ctx->extensions; + while (info && info->major_opcode != major_code) + info = info->next; + + if (info == NULL || event_type >= info->static_info->num_xge_events) + return NULL; + + return get_strings_entry(info->static_info->strings_xge_events, event_type); +} + +const char *xcb_errors_get_name_for_core_event(xcb_errors_context_t *ctx, + uint8_t event_code, const char **extension) +{ + struct extension_info_t *best = NULL; + struct extension_info_t *next; + + event_code &= 0x7f; + if (extension) + *extension = NULL; + + CHECK_CONTEXT(ctx); + + /* Find the extension with the largest first_event <= event_code. Thanks + * to this we do the right thing if the server only supports an older + * version of some extension which had less events. + */ + next = ctx->extensions; + while (next) { + struct extension_info_t *current = next; + next = next->next; + + if (current->first_event > event_code) + continue; + if (best != NULL && best->first_event > current->first_event) + continue; + best = current; + } + + if (best == NULL || best->first_event == 0 + || event_code - best->first_event >= best->static_info->num_events) { + /* Nothing found */ + return get_strings_entry(xproto_info.strings_events, event_code); + } + + if (extension) + *extension = best->static_info->name; + return get_strings_entry(best->static_info->strings_events, event_code - best->first_event); +} + +const char *xcb_errors_get_name_for_error(xcb_errors_context_t *ctx, + uint8_t error_code, const char **extension) +{ + struct extension_info_t *best = NULL; + struct extension_info_t *next; + + if (extension) + *extension = NULL; + + CHECK_CONTEXT(ctx); + + /* Find the extension with the largest first_error <= error_code. Thanks + * to this we do the right thing if the server only supports an older + * version of some extension which had less events. + */ + next = ctx->extensions; + while (next) { + struct extension_info_t *current = next; + next = next->next; + + if (current->first_error > error_code) + continue; + if (best != NULL && best->first_error > current->first_error) + continue; + best = current; + } + + if (best == NULL || best->first_error == 0 + || error_code - best->first_error >= best->static_info->num_errors) { + /* Nothing found */ + return get_strings_entry(xproto_info.strings_errors, error_code); + } + + if (extension) + *extension = best->static_info->name; + return get_strings_entry(best->static_info->strings_errors, error_code - best->first_error); +} + +const char *xcb_errors_get_name_for_xcb_event(xcb_errors_context_t *ctx, + xcb_generic_event_t *event, const char **extension) +{ + struct extension_info_t *xkb; + uint8_t response_type; + + if (extension) + *extension = NULL; + + CHECK_CONTEXT(ctx); + + /* Find the xkb extension, if present */ + xkb = ctx->extensions; + while (xkb != NULL && strcmp(xkb->static_info->name, "xkb") != 0) + xkb = xkb->next; + + response_type = event->response_type & 0x7f; + if (response_type == XCB_GE_GENERIC) { + /* XGE offers extension's major code and event sub-type. */ + xcb_ge_generic_event_t *ge = (void *) event; + if (extension) + *extension = xcb_errors_get_name_for_major_code(ctx, + ge->extension); + return xcb_errors_get_name_for_xge_event(ctx, + ge->extension, ge->event_type); + } + if (xkb != NULL && xkb->first_event != 0 + && response_type == xkb->first_event) { + /* There is no nice struct that defines the common fields for + * XKB events, but the event type is always in the second byte. + * In xcb_generic_event_t, this is the pad0 field. + */ + if (extension) + *extension = xkb->static_info->name; + return xcb_errors_get_name_for_xge_event(ctx, + xkb->major_opcode, event->pad0); + } + /* Generic case, decide only based on the response_type. */ + return xcb_errors_get_name_for_core_event(ctx, response_type, extension); +} diff --git a/depends/libxcb-errors/xcb/xcb_errors.h b/depends/libxcb-errors/xcb/xcb_errors.h new file mode 100644 index 0000000..baa0ec6 --- /dev/null +++ b/depends/libxcb-errors/xcb/xcb_errors.h @@ -0,0 +1,157 @@ +#ifndef __XCB_ERRORS_H__ +#define __XCB_ERRORS_H__ + +/* Copyright © 2015 Uli Schlachter + * + * 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. + */ + +#include <xcb/xcb.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * A context for using this library. + * + * Create a context with @ref xcb_errors_context_new () and destroy it with @ref + * xcb_errors_context_free (). Except for @ref xcb_errors_context_free (), all + * functions in this library are thread-safe and can be called from multiple + * threads at the same time, even on the same context. + */ +typedef struct xcb_errors_context_t xcb_errors_context_t; + +/** + * Create a new @ref xcb_errors_context_t. + * + * @param conn A XCB connection which will be used until you destroy the context + * with @ref xcb_errors_context_free (). + * @param ctx A pointer to an xcb_cursor_context_t* which will be modified to + * refer to the newly created context. + * @return 0 on success, -1 otherwise. This function may fail due to memory + * allocation failures or if the connection ends up in an error state. + */ +int xcb_errors_context_new(xcb_connection_t *conn, xcb_errors_context_t **ctx); + +/** + * Free the @ref xcb_cursor_context_t. + * + * @param ctx The context to free. + */ +void xcb_errors_context_free(xcb_errors_context_t *ctx); + +/** + * Get the name corresponding to some major code. This is either the name of + * some core request or the name of the extension that owns this major code. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param major_code The major code + * @return A string allocated in static storage that contains a name for this + * major code. This will never return NULL, but other functions in this library + * may. + */ +const char *xcb_errors_get_name_for_major_code(xcb_errors_context_t *ctx, + uint8_t major_code); + +/** + * Get the name corresponding to some minor code. When the major_code does not + * belong to any extension or the minor_code is not assigned inside this + * extension, NULL is returned. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param major_code The major code under which to look up the minor code + * @param major_code The minor code + * @return A string allocated in static storage that contains a name for this + * major code or NULL for unknown codes. + */ +const char *xcb_errors_get_name_for_minor_code(xcb_errors_context_t *ctx, + uint8_t major_code, + uint16_t minor_code); + +/** + * Get the name corresponding to some core event code. If possible, you should + * use @ref xcb_errors_get_name_for_xcb_event instead. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param event_code The response_type of an event. + * @param extension Will be set to the name of the extension that generated this + * event or NULL for unknown events or core X11 events. This argument may be + * NULL. + * @return A string allocated in static storage that contains a name for this + * major code. This will never return NULL, but other functions in this library + * may. + */ +const char *xcb_errors_get_name_for_core_event(xcb_errors_context_t *ctx, + uint8_t event_code, const char **extension); + +/** + * Get the name corresponding to some XGE or XKB event. XKB does not actually + * use the X generic event extension, but implements its own event multiplexing. + * This function also handles XKB's xkbType events as a event_type. + * + * If possible, you should use @ref xcb_errors_get_name_for_xcb_event instead. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param major_code The extension's major code + * @param event_type The type of the event in that extension. + * @return A string allocated in static storage that contains a name for this + * event or NULL for unknown event types. + */ +const char *xcb_errors_get_name_for_xge_event(xcb_errors_context_t *ctx, + uint8_t major_code, uint16_t event_type); + +/** + * Get a human printable name describing the type of some event. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param event The event to investigate. + * @param extension Will be set to the name of the extension that generated this + * event or NULL for unknown events or core X11 events. This argument may be + * NULL. + * @return A string allocated in static storage that contains a name for this + * event or NULL for unknown event types. + */ +const char *xcb_errors_get_name_for_xcb_event(xcb_errors_context_t *ctx, + xcb_generic_event_t *event, const char **extension); + +/** + * Get the name corresponding to some error. + * + * @param ctx An errors context, created with @ref xcb_errors_context_new () + * @param error_code The error_code of an error reply. + * @param extension Will be set to the name of the extension that generated this + * event or NULL for unknown errors or core X11 errors. This argument may be + * NULL. + * @return A string allocated in static storage that contains a name for this + * major code. This will never return NULL, but other functions in this library + * may. + */ +const char *xcb_errors_get_name_for_error(xcb_errors_context_t *ctx, + uint8_t error_code, const char **extension); + +#ifdef __cplusplus +} +#endif + +#endif /* __XCB_ERRORS_H__ */ diff --git a/depends/libxcb-image/config.h b/depends/libxcb-image/config.h new file mode 100644 index 0000000..4cd52e5 --- /dev/null +++ b/depends/libxcb-image/config.h @@ -0,0 +1,76 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdio.h> header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/shm.h> header file. */ +#define HAVE_SYS_SHM_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "xcb-util-image" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://gitlab.freedesktop.org/xorg/lib/libxcb-image/-/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "xcb-util-image" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "xcb-util-image 0.4.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "xcb-util-image" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.4.1" + +/* Major version of this package */ +#define PACKAGE_VERSION_MAJOR 0 + +/* Minor version of this package */ +#define PACKAGE_VERSION_MINOR 4 + +/* Patch version of this package */ +#define PACKAGE_VERSION_PATCHLEVEL 1 + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.4.1" diff --git a/depends/libxcb-image/xcb/xcb_bitops.h b/depends/libxcb-image/xcb/xcb_bitops.h new file mode 100644 index 0000000..a6872a1 --- /dev/null +++ b/depends/libxcb-image/xcb/xcb_bitops.h @@ -0,0 +1,212 @@ +#ifndef __XCB_BITOPS_H__ +#define __XCB_BITOPS_H__ + +/* Copyright (C) 2007 Bart Massey + * + * 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. + */ + +#include <assert.h> +#include <inttypes.h> +#include <X11/Xfuncproto.h> + +/** + * @defgroup xcb__bitops XCB Bit Operations + * + * Inline functions for common bit ops used in XCB and elsewhere. + * + * @{ + */ + + +/** + * Create a low-order bitmask. + * @param n Mask size. + * @return Mask. + * + * Create a bitmask with the lower @p n bits set and the + * rest of the word clear. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_mask(uint32_t n) +{ + return n == 32 ? ~0 : (1 << n) - 1; +} + + +/** + * Population count. + * @param n Integer representing a bitset. + * @return Number of 1 bits in the bitset. + * + * This is a reasonably fast algorithm for counting the bits + * in a 32-bit word. Currently a classic binary + * divide-and-conquer popcount: popcount_2() from + * http://en.wikipedia.org/wiki/Hamming_weight. + * @ingroup xcb__bitops + */ + + +/* 15 ops, 3 long immediates, 14 stages, 9 alu ops, 9 alu stages */ +_X_INLINE static uint32_t +xcb_popcount(uint32_t x) +{ + uint32_t m1 = 0x55555555; + uint32_t m2 = 0x33333333; + uint32_t m4 = 0x0f0f0f0f; + x -= (x >> 1) & m1; + x = (x & m2) + ((x >> 2) & m2); + x = (x + (x >> 4)) & m4; + x += x >> 8; + return (x + (x >> 16)) & 0x3f; +} + + +/** + * Round up to the next power-of-two unit size. + * @param base Number to be rounded up. + * @param pad Multiple to be rounded to; must be a power of two. + * @return Rounded-up number. + * + * Rounds @p base up to a multiple of @p pad, where @p pad + * is a power of two. The more general case is handled by + * xcb_roundup(). + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_roundup_2 (uint32_t base, uint32_t pad) +{ + return (base + pad - 1) & -pad; +} + +/** + * Round down to the next power-of-two unit size. + * @param base Number to be rounded down. + * @param pad Multiple to be rounded to; must be a power of two. + * @return Rounded-down number. + * + * Rounds @p base down to a multiple of @p pad, where @p pad + * is a power of two. The more general case is handled by + * xcb_rounddown(). + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_rounddown_2 (uint32_t base, uint32_t pad) +{ + return base & -pad; +} + +/** + * Round up to the next unit size. + * @param base Number to be rounded up. + * @param pad Multiple to be rounded to. + * @return Rounded-up number. + * + * This is a general routine for rounding @p base up + * to a multiple of @p pad. If you know that @p pad + * is a power of two, you should probably call xcb_roundup_2() + * instead. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_roundup (uint32_t base, uint32_t pad) +{ + uint32_t b = base + pad - 1; + /* faster if pad is a power of two */ + if (((pad - 1) & pad) == 0) + return b & -pad; + return b - b % pad; +} + + +/** + * Round down to the next unit size. + * @param base Number to be rounded down. + * @param pad Multiple to be rounded to. + * @return Rounded-down number. + * + * This is a general routine for rounding @p base down + * to a multiple of @p pad. If you know that @p pad + * is a power of two, you should probably call xcb_rounddown_2() + * instead. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_rounddown (uint32_t base, uint32_t pad) +{ + /* faster if pad is a power of two */ + if (((pad - 1) & pad) == 0) + return base & -pad; + return base - base % pad; +} + + +/** + * Reverse bits of word. + * @param x Target word. + * @param n Number of low-order bits to reverse. + * @return Word with low @p n bits reversed, all others 0. + * + * Reverses the bottom @p n bits of @p x. + * @ingroup xcb__bitops + */ +_X_INLINE static uint32_t +xcb_bit_reverse(uint32_t x, uint8_t n) { + uint32_t m1 = 0x00ff00ff; + uint32_t m2 = 0x0f0f0f0f; + uint32_t m3 = 0x33333333; + uint32_t m4 = 0x55555555; + x = ((x << 16) | (x >> 16)); + x = ((x & m1) << 8) | ((x >> 8) & m1); + x = ((x & m2) << 4) | ((x >> 4) & m2); + x = ((x & m3) << 2) | ((x >> 2) & m3); + x = ((x & m4) << 1) | ((x >> 1) & m4); + x >>= 32 - n; + return x; +} + + +/** + * Host byte order. + * @return The byte order of the host. + * + * Tests the host's byte order and returns either + * XCB_IMAGE_ORDER_MSB_FIRST or XCB_IMAGE_ORDER_LSB_FIRST + * as appropriate. + * @ingroup xcb__bitops + */ +_X_INLINE static xcb_image_order_t +xcb_host_byte_order(void) { + uint32_t endian_test = 0x01020304; + + switch (*(char *)&endian_test) { + case 0x01: + return XCB_IMAGE_ORDER_MSB_FIRST; + case 0x04: + return XCB_IMAGE_ORDER_LSB_FIRST; + } + assert(0); +} + +#endif /* __XCB_BITOPS_H__ */ diff --git a/depends/libxcb-image/xcb/xcb_image.c b/depends/libxcb-image/xcb/xcb_image.c new file mode 100644 index 0000000..4889c26 --- /dev/null +++ b/depends/libxcb-image/xcb/xcb_image.c @@ -0,0 +1,1013 @@ +/* Copyright © 2007 Bart Massey + * + * 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 <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <xcb/xcb.h> +#include <xcb/shm.h> +#include <xcb/xcb_aux.h> +#include "xcb_bitops.h" +#include "xcb_image.h" +#define BUILD +#include "xcb_pixel.h" + + +static xcb_format_t * +find_format_by_depth (const xcb_setup_t *setup, uint8_t depth) +{ + xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); + xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for(; fmt != fmtend; ++fmt) + if(fmt->depth == depth) + return fmt; + return 0; +} + + +static xcb_image_format_t +effective_format(xcb_image_format_t format, uint8_t bpp) +{ + if (format == XCB_IMAGE_FORMAT_Z_PIXMAP && bpp != 1) + return format; + return XCB_IMAGE_FORMAT_XY_PIXMAP; +} + + +static int +format_valid (uint8_t depth, uint8_t bpp, uint8_t unit, + xcb_image_format_t format, uint8_t xpad) +{ + xcb_image_format_t ef = effective_format(format, bpp); + if (depth > bpp) + return 0; + switch(ef) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + switch(unit) { + case 8: + case 16: + case 32: + break; + default: + return 0; + } + if (xpad < bpp) + return 0; + switch (xpad) { + case 8: + case 16: + case 32: + break; + default: + return 0; + } + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + switch (bpp) { + case 4: + if (unit != 8) + return 0; + break; + case 8: + case 16: + case 24: + case 32: + if (unit != bpp) + return 0; + break; + default: + return 0; + } + break; + default: + return 0; + } + return 1; +} + + +static int +image_format_valid (xcb_image_t *image) { + return format_valid(image->depth, + image->bpp, + image->unit, + image->format, + image->scanline_pad); +} + + +void +xcb_image_annotate (xcb_image_t *image) +{ + xcb_image_format_t ef = effective_format(image->format, image->bpp); + switch (ef) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + image->stride = xcb_roundup(image->width, image->scanline_pad) >> 3; + image->size = image->height * image->stride * image->depth; + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + image->stride = xcb_roundup((uint32_t)image->width * + (uint32_t)image->bpp, + image->scanline_pad) >> 3; + image->size = image->height * image->stride; + break; + default: + assert(0); + } +} + + +xcb_image_t * +xcb_image_create_native (xcb_connection_t * c, + uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t depth, + void * base, + uint32_t bytes, + uint8_t * data) +{ + const xcb_setup_t * setup = xcb_get_setup(c); + xcb_format_t * fmt; + xcb_image_format_t ef = format; + + if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP && depth == 1) + ef = XCB_IMAGE_FORMAT_XY_PIXMAP; + switch (ef) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + if (depth != 1) + return 0; + /* fall through */ + case XCB_IMAGE_FORMAT_XY_PIXMAP: + if (depth > 1) { + fmt = find_format_by_depth(setup, depth); + if (!fmt) + return 0; + } + return xcb_image_create(width, height, format, + setup->bitmap_format_scanline_pad, + depth, depth, setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + base, bytes, data); + case XCB_IMAGE_FORMAT_Z_PIXMAP: + fmt = find_format_by_depth(setup, depth); + if (!fmt) + return 0; + return xcb_image_create(width, height, format, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, 0, + setup->image_byte_order, + XCB_IMAGE_ORDER_MSB_FIRST, + base, bytes, data); + default: + assert(0); + } + assert(0); + return NULL; +} + + +xcb_image_t * +xcb_image_create (uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t xpad, + uint8_t depth, + uint8_t bpp, + uint8_t unit, + xcb_image_order_t byte_order, + xcb_image_order_t bit_order, + void * base, + uint32_t bytes, + uint8_t * data) +{ + xcb_image_t * image; + + if (unit == 0) { + switch (format) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + case XCB_IMAGE_FORMAT_XY_PIXMAP: + unit = 32; + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + if (bpp == 1) { + unit = 32; + break; + } + if (bpp < 8) { + unit = 8; + break; + } + unit = bpp; + break; + } + } + if (!format_valid(depth, bpp, unit, format, xpad)) + return 0; + image = malloc(sizeof(*image)); + if (image == 0) + return 0; + image->width = width; + image->height = height; + image->format = format; + image->scanline_pad = xpad; + image->depth = depth; + image->bpp = bpp; + image->unit = unit; + image->plane_mask = xcb_mask(depth); + image->byte_order = byte_order; + image->bit_order = bit_order; + xcb_image_annotate(image); + + /* + * Ways this function can be called: + * * with data: we fail if bytes isn't + * large enough, else leave well enough alone. + * * with base and !data: if bytes is zero, we + * default; otherwise we fail if bytes isn't + * large enough, else fill in data + * * with !base and !data: we malloc storage + * for the data, save that address as the base, + * and fail if malloc does. + * + * When successful, we establish the invariant that data + * points at sufficient storage that may have been + * supplied, and base is set iff it should be + * auto-freed when the image is destroyed. + * + * Except as a special case when base = 0 && data == 0 && + * bytes == ~0 we just return the image structure and let + * the caller deal with getting the allocation right. + */ + if (!base && !data && bytes == ~0) { + image->base = 0; + image->data = 0; + return image; + } + if (!base && data && bytes == 0) + bytes = image->size; + image->base = base; + image->data = data; + if (!image->data) { + if (image->base) { + image->data = image->base; + } else { + bytes = image->size; + image->base = malloc(bytes); + image->data = image->base; + } + } + if (!image->data || bytes < image->size) { + free(image); + return 0; + } + return image; +} + + +void +xcb_image_destroy (xcb_image_t *image) +{ + if (image->base) + free (image->base); + free (image); +} + + +xcb_image_t * +xcb_image_get (xcb_connection_t * conn, + xcb_drawable_t draw, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint32_t plane_mask, + xcb_image_format_t format) +{ + xcb_get_image_cookie_t image_cookie; + xcb_get_image_reply_t * imrep; + xcb_image_t * image = 0; + uint32_t bytes; + uint8_t * data; + + image_cookie = xcb_get_image(conn, format, draw, x, y, + width, height, plane_mask); + imrep = xcb_get_image_reply(conn, image_cookie, 0); + if (!imrep) + return 0; + bytes = xcb_get_image_data_length(imrep); + data = xcb_get_image_data(imrep); + switch (format) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + plane_mask &= xcb_mask(imrep->depth); + if (plane_mask != xcb_mask(imrep->depth)) { + int i; + uint32_t rpm = plane_mask; + uint32_t size; + uint8_t *src_plane = data; + uint8_t *dst_plane; + + image = xcb_image_create_native(conn, width, height, format, + imrep->depth, 0, 0, 0); + if (!image) { + free(imrep); + return 0; + } + image->plane_mask = plane_mask; + size = image->height * image->stride; + dst_plane = image->data; + for (i = imrep->depth - 1; i >= 0; --i) { + if (rpm & (1 << i)) { + memcpy(dst_plane, src_plane, size); + src_plane += size; + } else { + memset(dst_plane, 0, size); + } + dst_plane += size; + } + free(imrep); + break; + } + /* fall through */ + case XCB_IMAGE_FORMAT_Z_PIXMAP: + image = xcb_image_create_native(conn, width, height, format, + imrep->depth, imrep, bytes, data); + if (!image) { + free(imrep); + return 0; + } + assert(bytes == image->size); + break; + default: + assert(0); + } + return image; +} + + +xcb_image_t * +xcb_image_native (xcb_connection_t * c, + xcb_image_t * image, + int convert) +{ + xcb_image_t * tmp_image = 0; + const xcb_setup_t * setup = xcb_get_setup(c); + xcb_format_t * fmt = 0; + xcb_image_format_t ef = effective_format(image->format, image->bpp); + uint8_t bpp = 1; + + if (image->depth > 1 || ef == XCB_IMAGE_FORMAT_Z_PIXMAP) { + fmt = find_format_by_depth(setup, image->depth); + /* XXX For now, we don't do depth conversions, even + for xy-pixmaps */ + if (!fmt) + return 0; + bpp = fmt->bits_per_pixel; + } + switch (ef) { + case XCB_IMAGE_FORMAT_XY_PIXMAP: + if (setup->bitmap_format_scanline_unit != image->unit || + setup->bitmap_format_scanline_pad != image->scanline_pad || + setup->image_byte_order != image->byte_order || + setup->bitmap_format_bit_order != image->bit_order || + bpp != image->bpp) { + if (!convert) + return 0; + tmp_image = + xcb_image_create(image->width, image->height, image->format, + setup->bitmap_format_scanline_pad, + image->depth, bpp, + setup->bitmap_format_scanline_unit, + setup->image_byte_order, + setup->bitmap_format_bit_order, + 0, 0, 0); + if (!tmp_image) + return 0; + } + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + if (fmt->scanline_pad != image->scanline_pad || + setup->image_byte_order != image->byte_order || + bpp != image->bpp) { + if (!convert) + return 0; + tmp_image = + xcb_image_create(image->width, image->height, image->format, + fmt->scanline_pad, + image->depth, bpp, 0, + setup->image_byte_order, + XCB_IMAGE_ORDER_MSB_FIRST, + 0, 0, 0); + if (!tmp_image) + return 0; + } + break; + default: + assert(0); + } + if (tmp_image) { + if (!xcb_image_convert(image, tmp_image)) { + xcb_image_destroy(tmp_image); + return 0; + } + image = tmp_image; + } + return image; +} + + +xcb_void_cookie_t +xcb_image_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + int16_t x, + int16_t y, + uint8_t left_pad) +{ + return xcb_put_image(conn, image->format, draw, gc, + image->width, image->height, + x, y, left_pad, + image->depth, + image->size, + image->data); +} + + + +/* + * Shm stuff + */ + +xcb_image_t * +xcb_image_shm_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t src_x, + int16_t src_y, + int16_t dest_x, + int16_t dest_y, + uint16_t src_width, + uint16_t src_height, + uint8_t send_event) +{ + if (!xcb_image_native(conn, image, 0)) + return 0; + if (!shminfo.shmaddr) + return 0; + xcb_shm_put_image(conn, draw, gc, + image->width, image->height, + src_x, src_y, src_width, src_height, + dest_x, dest_y, + image->depth, image->format, + send_event, + shminfo.shmseg, + image->data - shminfo.shmaddr); + return image; +} + + +int +xcb_image_shm_get (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t x, + int16_t y, + uint32_t plane_mask) +{ + xcb_shm_get_image_reply_t * setup; + xcb_shm_get_image_cookie_t cookie; + xcb_generic_error_t * err = 0; + + if (!shminfo.shmaddr) + return 0; + cookie = xcb_shm_get_image(conn, draw, + x, y, + image->width, image->height, + plane_mask, + image->format, + shminfo.shmseg, + image->data - shminfo.shmaddr); + setup = xcb_shm_get_image_reply(conn, cookie, &err); + if (err) { + fprintf(stderr, "ShmGetImageReply error %d\n", (int)err->error_code); + free(err); + return 0; + } else { + free (setup); + return 1; + } +} + + +static uint32_t +xy_image_byte (xcb_image_t *image, uint32_t x) +{ + x >>= 3; + if (image->byte_order == image->bit_order) + return x; + switch (image->unit) { + default: + case 8: + return x; + case 16: + return x ^ 1; + case 32: + return x ^ 3; + } +} + +static uint32_t +xy_image_bit (xcb_image_t *image, uint32_t x) +{ + x &= 7; + if (image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST) + x = 7 - x; + return x; +} + +/* GetPixel/PutPixel */ + +/* XXX this is the most hideously done cut-and-paste + to below. Any bugs fixed there should be fixed here + and vice versa. */ +void +xcb_image_put_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel) +{ + uint8_t *row; + + if (x > image->width || y > image->height) + return; + row = image->data + (y * image->stride); + switch (effective_format(image->format, image->bpp)) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + case XCB_IMAGE_FORMAT_XY_PIXMAP: + /* block */ { + int p; + uint32_t plane_mask = image->plane_mask; + uint8_t * plane = row; + uint32_t byte = xy_image_byte(image, x); + uint32_t bit = xy_image_bit(image,x); + uint8_t mask = 1 << bit; + + for (p = image->bpp - 1; p >= 0; p--) { + if ((plane_mask >> p) & 1) { + uint8_t * bp = plane + byte; + uint8_t this_bit = ((pixel >> p) & 1) << bit; + *bp = (*bp & ~mask) | this_bit; + } + plane += image->stride * image->height; + } + } + break; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + switch (image->bpp) { + uint32_t mask; + case 4: + mask = 0xf; + pixel &= 0xf; + if ((x & 1) == + (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)) { + pixel <<= 4; + mask <<= 4; + } + row[x >> 1] = (row[x >> 1] & ~mask) | pixel; + break; + case 8: + row[x] = pixel; + break; + case 16: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + row[x << 1] = pixel; + row[(x << 1) + 1] = pixel >> 8; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + row[x << 1] = pixel >> 8; + row[(x << 1) + 1] = pixel; + break; + } + break; + case 24: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + row[x * 3] = pixel; + row[x * 3 + 1] = pixel >> 8; + row[x * 3 + 2] = pixel >> 16; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + row[x * 3] = pixel >> 16; + row[x * 3 + 1] = pixel >> 8; + row[x * 3 + 2] = pixel; + break; + } + break; + case 32: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + row[x << 2] = pixel; + row[(x << 2) + 1] = pixel >> 8; + row[(x << 2) + 2] = pixel >> 16; + row[(x << 2) + 3] = pixel >> 24; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + row[x << 2] = pixel >> 24; + row[(x << 2) + 1] = pixel >> 16; + row[(x << 2) + 2] = pixel >> 8; + row[(x << 2) + 3] = pixel; + break; + } + break; + default: + assert(0); + } + break; + default: + assert(0); + } +} + + +/* XXX this is the most hideously done cut-and-paste + from above. Any bugs fixed there should be fixed here + and vice versa. */ +uint32_t +xcb_image_get_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint32_t pixel = 0; + uint8_t *row; + + assert(x < image->width && y < image->height); + row = image->data + (y * image->stride); + switch (effective_format(image->format, image->bpp)) { + case XCB_IMAGE_FORMAT_XY_BITMAP: + case XCB_IMAGE_FORMAT_XY_PIXMAP: + /* block */ { + int p; + uint32_t plane_mask = image->plane_mask; + uint8_t * plane = row; + uint32_t byte = xy_image_byte(image, x); + uint32_t bit = xy_image_bit(image,x); + + for (p = image->bpp - 1; p >= 0; p--) { + pixel <<= 1; + if ((plane_mask >> p) & 1) { + uint8_t * bp = plane + byte; + pixel |= (*bp >> bit) & 1; + } + plane += image->stride * image->height; + } + } + return pixel; + case XCB_IMAGE_FORMAT_Z_PIXMAP: + switch (image->bpp) { + case 4: + if ((x & 1) == (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)) + return row[x >> 1] >> 4; + return row[x >> 1] & 0xf; + case 8: + return row[x]; + case 16: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + pixel = row[x << 1]; + pixel |= row[(x << 1) + 1] << 8; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + pixel = row[x << 1] << 8; + pixel |= row[(x << 1) + 1]; + break; + } + break; + case 24: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + pixel = row[x * 3]; + pixel |= row[x * 3 + 1] << 8; + pixel |= row[x * 3 + 2] << 16; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + pixel = row[x * 3] << 16; + pixel |= row[x * 3 + 1] << 8; + pixel |= row[x * 3 + 2]; + break; + } + break; + case 32: + switch (image->byte_order) { + case XCB_IMAGE_ORDER_LSB_FIRST: + pixel = row[x << 2]; + pixel |= row[(x << 2) + 1] << 8; + pixel |= row[(x << 2) + 2] << 16; + pixel |= row[(x << 2) + 3] << 24; + break; + case XCB_IMAGE_ORDER_MSB_FIRST: + pixel = row[x << 2] << 24; + pixel |= row[(x << 2) + 1] << 16; + pixel |= row[(x << 2) + 2] << 8; + pixel |= row[(x << 2) + 3]; + break; + } + break; + default: + assert(0); + } + return pixel; + default: + assert(0); + } + return 0; +} + + +xcb_image_t * +xcb_image_create_from_bitmap_data (uint8_t * data, + uint32_t width, + uint32_t height) +{ + return xcb_image_create(width, height, XCB_IMAGE_FORMAT_XY_PIXMAP, + 8, 1, 1, 8, + XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_LSB_FIRST, + 0, 0, data); +} + + +/* + * (Adapted from libX11.) + * + * xcb_create_pixmap_from_bitmap_data: Routine to make a pixmap of + * given depth from user supplied bitmap data. + * D is any drawable on the same screen that the pixmap will be used in. + * Data is a pointer to the bit data, and + * width & height give the size in bits of the pixmap. + * + * The following format is assumed for data: + * + * format=XY (will use XYPixmap for depth 1 and XYBitmap for larger) + * bit_order=LSBFirst + * padding=8 + * bitmap_unit=8 + */ +xcb_pixmap_t +xcb_create_pixmap_from_bitmap_data (xcb_connection_t * display, + xcb_drawable_t d, + uint8_t * data, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t fg, + uint32_t bg, + xcb_gcontext_t * gcp) +{ + xcb_pixmap_t pix; + xcb_image_t * image; + xcb_image_t * final_image; + xcb_gcontext_t gc; + uint32_t mask = 0; + xcb_params_gc_t gcv; + + image = xcb_image_create_from_bitmap_data(data, width, height); + if (!image) + return 0; + if (depth > 1) + image->format = XCB_IMAGE_FORMAT_XY_BITMAP; + final_image = xcb_image_native(display, image, 1); + if (!final_image) { + xcb_image_destroy(image); + return 0; + } + pix = xcb_generate_id(display); + xcb_create_pixmap(display, depth, pix, d, width, height); + gc = xcb_generate_id(display); + XCB_AUX_ADD_PARAM(&mask, &gcv, foreground, fg); + XCB_AUX_ADD_PARAM(&mask, &gcv, background, bg); + xcb_aux_create_gc(display, gc, pix, mask, &gcv); + xcb_image_put(display, pix, gc, final_image, 0, 0, 0); + if (final_image != image) + xcb_image_destroy(final_image); + xcb_image_destroy(image); + if (gcp) + *gcp = gc; + else + xcb_free_gc(display, gc); + return pix; +} + + +/* Thanks to Keith Packard <keithp@keithp.com> for this code */ +static void +swap_image(uint8_t * src, + uint32_t src_stride, + uint8_t * dst, + uint32_t dst_stride, + uint32_t height, + uint32_t byteswap, + int bitswap, + int nibbleswap) +{ + while (height--) { + uint32_t s; + + for (s = 0; s < src_stride; s++) { + uint8_t b; + uint32_t d = s ^ byteswap; + + if (d > dst_stride) + continue; + + b = src[s]; + if (bitswap) + b = xcb_bit_reverse(b, 8); + if (nibbleswap) + b = (b << 4) | (b >> 4); + dst[d] = b; + } + src += src_stride; + dst += dst_stride; + } +} + +/* Which order are bytes in (low two bits), given + * code which accesses an image one byte at a time + */ +static uint32_t +byte_order(xcb_image_t *i) +{ + uint32_t flip = i->byte_order == XCB_IMAGE_ORDER_MSB_FIRST; + + switch (i->bpp) { + default: + case 8: + return 0; + case 16: + return flip; + case 32: + return flip | (flip << 1); + } +} + +static uint32_t +bit_order(xcb_image_t *i) +{ + uint32_t flip = i->byte_order != i->bit_order; + + switch (i->unit) { + default: + case 8: + return 0; + case 16: + return flip; + case 32: + return flip | (flip << 1); + } +} + +/* Convert from one byte order to another by flipping the + * low two bits of the byte index along a scanline + */ +static uint32_t +conversion_byte_swap(xcb_image_t *src, xcb_image_t *dst) +{ + xcb_image_format_t ef = effective_format(src->format, src->bpp); + + /* src_ef == dst_ef in all callers of this function */ + if (ef == XCB_IMAGE_FORMAT_XY_PIXMAP) { + return bit_order(src) ^ bit_order(dst); + } else { + /* src_bpp == dst_bpp in all callers of this function */ + return byte_order(src) ^ byte_order(dst); + } +} + +xcb_image_t * +xcb_image_convert (xcb_image_t * src, + xcb_image_t * dst) +{ + xcb_image_format_t ef = effective_format(src->format, src->bpp); + + /* Things will go horribly wrong here if a bad + image is passed in, so we check some things + up front just to be nice. */ + assert(image_format_valid(src)); + assert(image_format_valid(dst)); + + /* images must be the same size + * (yes, we could copy a sub-set) + */ + if (src->width != dst->width || + src->height != dst->height) + return 0; + + if (ef == effective_format(dst->format, dst->bpp) && + src->bpp == dst->bpp) + { + if (src->unit == dst->unit && + src->scanline_pad == dst->scanline_pad && + src->byte_order == dst->byte_order && + (ef == XCB_IMAGE_FORMAT_Z_PIXMAP || + src->bit_order == dst->bit_order)) { + memcpy(dst->data, src->data, src->size); + } else { + int bitswap = 0; + int nibbleswap = 0; + uint32_t byteswap = conversion_byte_swap(src, dst); + uint32_t height = src->height;; + + if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP) { + if (src->bpp == 4 && src->byte_order != dst->byte_order) + nibbleswap = 1; + } else { + if (src->bit_order != dst->bit_order) + bitswap = 1; + height *= src->depth; + } + swap_image (src->data, src->stride, dst->data, dst->stride, + height, byteswap, bitswap, nibbleswap); + } + } + else + { + uint32_t x; + uint32_t y; + /* General case: Slow pixel copy. Should we optimize + Z24<->Z32 copies of either endianness? */ + for (y = 0; y < src->height; y++) { + for (x = 0; x < src->width; x++) { + uint32_t pixel = xcb_image_get_pixel(src, x, y); + xcb_image_put_pixel(dst, x, y, pixel); + } + } + } + return dst; +} + +xcb_image_t * +xcb_image_subimage(xcb_image_t * image, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + void * base, + uint32_t bytes, + uint8_t * data) +{ + int i, j; + xcb_image_t * result; + + if (x + width > image->width) + return 0; + if (y + height > image->height) + return 0; + result = xcb_image_create(width, height, image->format, + image->scanline_pad, image->depth, + image->bpp, image->unit, image->byte_order, + image->bit_order, + base, bytes, data); + if (!result) + return 0; + /* XXX FIXME For now, lose on performance. Sorry. */ + for (j = 0; j < height; j++) { + for (i = 0; i < width; i++) { + uint32_t pixel = xcb_image_get_pixel(image, x + i, y + j); + xcb_image_put_pixel(result, i, j, pixel); + } + } + return result; +} diff --git a/depends/libxcb-image/xcb/xcb_image.h b/depends/libxcb-image/xcb/xcb_image.h new file mode 100644 index 0000000..4ca04ac --- /dev/null +++ b/depends/libxcb-image/xcb/xcb_image.h @@ -0,0 +1,628 @@ +#ifndef __XCB_IMAGE_H__ +#define __XCB_IMAGE_H__ + +/* Copyright (C) 2007 Bart Massey + * + * 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. + */ + +#include <xcb/xcb.h> +#include <xcb/shm.h> + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup xcb__image_t XCB Image Functions + * + * These are functions used to create and manipulate X images. + * + * The X image format we use is specific to this software, + * which is probably a bug; it represents an intermediate + * position between the wire format used by the X GetImage + * and PutImage requests and standard formats like PBM. An + * image consists of a header of type @ref xcb_image_t + * describing the properties of the image, together with a + * pointer to the image data itself. + * + * X wire images come in three formats. An xy-bitmap is a + * bit-packed format that will be expanded to a two-color + * pixmap using a GC when sent over the wire by PutImage. + * An xy-pixmap is one or more bit-planes, each in the same + * format as xy-bitmap. A z-pixmap is a more conventional + * pixmap representation, with each pixel packed into a + * word. Pixmaps are sent and received over the wire only + * to/from drawables of their depth. + * + * Each X server defines, for each depth and format, + * properties of images in that format that are sent and + * received on the wire. We refer to this as a "native" + * image for a given X server. It is not uncommon to want + * to work with non-native images on the client side, or to + * convert between the native images of different servers. + * + * This library provides several things. Facilities for + * creating and destroying images are, of course, provided. + * Wrappers for xcb_get_image() and xcb_put_image() are + * provided; these utilize the image header to simplify the + * interface. Routines for getting and putting image pixels + * are provided: both a generic form that works with + * arbitrary images, and fastpath forms for some common + * cases. Conversion routines are provided for X images; + * these routines have been fairly well optimized for the + * common cases, and should run fast even on older hardware. + * A routine analogous to Xlib's XCreate*FromBitmapData() is + * provided for creating X images from xbm-format data; this + * routine is in this library only because it is a trivial + * use case for the library. + * + * @{ + */ + + +typedef struct xcb_image_t xcb_image_t; + +/** + * @struct xcb_image_t + * A structure that describes an xcb_image_t. + */ +struct xcb_image_t +{ + uint16_t width; /**< Width in pixels, excluding pads etc. */ + uint16_t height; /**< Height in pixels. */ + xcb_image_format_t format; /**< Format. */ + uint8_t scanline_pad; /**< Right pad in bits. Valid pads + * are 8, 16, 32. + */ + uint8_t depth; /**< Depth in bits. Valid depths + * are 1, 4, 8, 16, 24 for z format, + * 1 for xy-bitmap-format, anything + * for xy-pixmap-format. + */ + uint8_t bpp; /**< Storage per pixel in bits. + * Must be >= depth. Valid bpp + * are 1, 4, 8, 16, 24, 32 for z + * format, 1 for xy-bitmap format, + * anything for xy-pixmap-format. + */ + uint8_t unit; /**< Scanline unit in bits for + * xy formats and for bpp == 1, + * in which case valid scanline + * units are 8, 16, 32. Otherwise, + * will be max(8, bpp). Must be >= bpp. + */ + uint32_t plane_mask; /**< When format is + * xy-pixmap and depth > + * 1, this says which + * planes are "valid" in + * some vague sense. + * Currently used only + * by xcb_image_get/put_pixel(), + * and set only by + * xcb_image_get(). + */ + xcb_image_order_t byte_order; /**< Component byte order + * for z-pixmap, byte + * order of scanline unit + * for xy-bitmap and + * xy-pixmap. Nybble + * order for z-pixmap + * when bpp == 4. + */ + xcb_image_order_t bit_order; /**< Bit order of + * scanline unit for + * xy-bitmap and + * xy-pixmap. + */ + uint32_t stride; /**< Bytes per image row. + * Computable from other + * data, but cached for + * convenience/performance. + */ + uint32_t size; /**< Size of image data in bytes. + * Computable from other + * data, but cached for + * convenience/performance. + */ + void * base; /**< Malloced block of storage that + * will be freed by + * @ref xcb_image_destroy() if non-null. + */ + uint8_t * data; /**< The actual image. */ +}; + +typedef struct xcb_shm_segment_info_t xcb_shm_segment_info_t; + +/** + * @struct xcb_shm_segment_info_t + * A structure that stores the informations needed by the MIT Shm + * Extension. + */ +struct xcb_shm_segment_info_t +{ + xcb_shm_seg_t shmseg; + uint32_t shmid; + uint8_t *shmaddr; +}; + + +/** + * Update the cached data of an image. + * @param image The image. + * + * An image's size and stride, among other things, are + * cached in its structure. This function recomputes those + * cached values for the given image. + * @ingroup xcb__image_t + */ +void +xcb_image_annotate (xcb_image_t *image); + +/** + * Create a new image. + * @param width The width of the image, in pixels. + * @param height The height of the image, in pixels. + * @param format The format of the image. + * @param xpad The scanline pad of the image. + * @param depth The depth of the image. + * @param bpp The depth of the image storage. + * @param unit The unit of image representation, in bits. + * @param byte_order The byte order of the image. + * @param bit_order The bit order of the image. + * @param base The base address of malloced image data. + * @param bytes The size in bytes of the storage pointed to by base. + * If base == 0 and bytes == ~0 and data == 0 on + * entry, no storage will be auto-allocated. + * @param data The image data. If data is null and bytes != ~0, then + * an attempt will be made to fill in data; from + * base if it is non-null (and bytes is large enough), else + * by mallocing sufficient storage and filling in base. + * @return The new image. + * + * This function allocates the memory needed for an @ref xcb_image_t structure + * with the given properties. See the description of xcb_image_t for details. + * This function initializes and returns a pointer to the + * xcb_image_t structure. It may try to allocate or reserve data for the + * structure, depending on how @p base, @p bytes and @p data are set. + * + * The image must be destroyed with xcb_image_destroy(). + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_create (uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t xpad, + uint8_t depth, + uint8_t bpp, + uint8_t unit, + xcb_image_order_t byte_order, + xcb_image_order_t bit_order, + void * base, + uint32_t bytes, + uint8_t * data); + + +/** + * Create a new image in connection-native format. + * @param c The connection. + * @param width The width of the image, in pixels. + * @param height The height of the image, in pixels. + * @param format The format of the image. + * @param depth The depth of the image. + * @param base The base address of malloced image data. + * @param bytes The size in bytes of the storage pointed to by base. + * If base == 0 and bytes == ~0 and data == 0 on + * entry, no storage will be auto-allocated. + * @param data The image data. If data is null and bytes != ~0, then + * an attempt will be made to fill in data; from + * base if it is non-null (and bytes is large enough), else + * by mallocing sufficient storage and filling in base. + * @return The new image. + * + * This function calls @ref xcb_image_create() with the given + * properties, and with the remaining properties chosen + * according to the "native format" with the given + * properties on the current connection. + * + * It is usual to use this rather + * than calling xcb_image_create() directly. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_create_native (xcb_connection_t * c, + uint16_t width, + uint16_t height, + xcb_image_format_t format, + uint8_t depth, + void * base, + uint32_t bytes, + uint8_t * data); + + +/** + * Destroy an image. + * @param image The image to be destroyed. + * + * This function frees the memory associated with the @p image + * parameter. If its base pointer is non-null, it frees + * that also. + * @ingroup xcb__image_t + */ +void +xcb_image_destroy (xcb_image_t *image); + + +/** + * Get an image from the X server. + * @param conn The connection to the X server. + * @param draw The drawable to get the image from. + * @param x The x coordinate in pixels, relative to the origin of the + * drawable and defining the upper-left corner of the rectangle. + * @param y The y coordinate in pixels, relative to the origin of the + * drawable and defining the upper-left corner of the rectangle. + * @param width The width of the subimage in pixels. + * @param height The height of the subimage in pixels. + * @param plane_mask The plane mask. See the protocol document for details. + * @param format The format of the image. + * @return The subimage of @p draw defined by @p x, @p y, @p w, @p h. + * + + * This function returns a new image taken from the + * given drawable @p draw. + * The image will be in connection native format. If the @p format + * is xy-bitmap and the @p plane_mask masks bit planes out, those + * bit planes will be made part of the returned image anyway, + * by zero-filling them; this will require a fresh memory allocation + * and some copying. Otherwise, the resulting image will use the + * xcb_get_image_reply() record as its backing store. + * + * If a problem occurs, the function returns null. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_get (xcb_connection_t * conn, + xcb_drawable_t draw, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint32_t plane_mask, + xcb_image_format_t format); + + +/** + * Put an image onto the X server. + * @param conn The connection to the X server. + * @param draw The draw you get the image from. + * @param gc The graphic context. + * @param image The image you want to combine with the rectangle. + * @param x The x coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of the + * rectangle. + * @param y The y coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of + * the rectangle. + * @param left_pad Notionally shift an xy-bitmap or xy-pixmap image + * to the right some small amount, for some reason. XXX Not clear + * this is currently supported correctly. + * @return The cookie returned by xcb_put_image(). + * + * This function combines an image with a rectangle of the + * specified drawable @p draw. The image must be in native + * format for the connection. The image is drawn at the + * specified location in the drawable. For the xy-bitmap + * format, the foreground pixel in @p gc defines the source + * for the one bits in the image, and the background pixel + * defines the source for the zero bits. For xy-pixmap and + * z-pixmap formats, the depth of the image must match the + * depth of the drawable; the gc is ignored. + * + * @ingroup xcb__image_t + */ +xcb_void_cookie_t +xcb_image_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + int16_t x, + int16_t y, + uint8_t left_pad); + + +/** + * Check image for or convert image to native format. + * @param c The connection to the X server. + * @param image The image. + * @param convert If 0, just check the image for native format. + * Otherwise, actually convert it. + * @return Null if the image is not in native format and can or will not + * be converted. Otherwise, the native format image. + * + * Each X display has its own "native format" for images of a given + * format and depth. This function either checks whether the given + * @p image is in native format for the given connection @p c, or + * actually tries to convert the image to native format, depending + * on whether @p convert is true or false. + * + * When @p convert is true, and the image is not in native format + * but can be converted, it will be, and a pointer to the new image + * will be returned. The image passed in will be unharmed in this + * case; it is the caller's responsibility to check that the returned + * pointer is different and to dispose of the old image if desired. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_native (xcb_connection_t * c, + xcb_image_t * image, + int convert); + + +/** + * Put a pixel to an image. + * @param image The image. + * @param x The x coordinate of the pixel. + * @param y The y coordinate of the pixel. + * @param pixel The new pixel value. + * + * This function overwrites the pixel in the given @p image with the + * specified @p pixel value (in client format). The image must contain the @p x + * and @p y coordinates, as no clipping is done. This function honors + * the plane-mask for xy-pixmap images. + * @ingroup xcb__image_t + */ +void +xcb_image_put_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel); + +/** + * Get a pixel from an image. + * @param image The image. + * @param x The x coordinate of the pixel. + * @param y The y coordinate of the pixel. + * @return The pixel value. + * + * This function retrieves a pixel from the given @p image. + * The image must contain the @p x + * and @p y coordinates, as no clipping is done. This function honors + * the plane-mask for xy-pixmap images. + * @ingroup xcb__image_t + */ +uint32_t +xcb_image_get_pixel (xcb_image_t *image, + uint32_t x, + uint32_t y); + + +/** + * Convert an image to a new format. + * @param src Source image. + * @param dst Destination image. + * @return The @p dst image, or null on error. + * + * This function tries to convert the image data of the @p + * src image to the format implied by the @p dst image, + * overwriting the current destination image data. + * The source and destination must have the same + * width, height, and depth. When the source and destination + * are already the same format, a simple copy is done. Otherwise, + * when the destination has the same bits-per-pixel/scanline-unit + * as the source, an optimized copy routine (thanks to Keith Packard) + * is used for the conversion. Otherwise, the copy is done the + * slow, slow way with @ref xcb_image_get_pixel() and + * @ref xcb_image_put_pixel() calls. + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_convert (xcb_image_t * src, + xcb_image_t * dst); + + +/** + * Extract a subimage of an image. + * @param image Source image. + * @param x X coordinate of subimage. + * @param y Y coordinate of subimage. + * @param width Width of subimage. + * @param height Height of subimage. + * @param base Base of memory allocation. + * @param bytes Size of base allocation. + * @param data Memory allocation. + * @return The subimage, or null on error. + * + * Given an image, this function extracts the subimage at the + * given coordinates. The requested subimage must be entirely + * contained in the source @p image. The resulting image will have the same + * general image parameters as the source image. The @p base, @p bytes, + * and @p data arguments are passed to @ref xcb_create_image() unaltered + * to create the destination image---see its documentation for details. + * + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_subimage(xcb_image_t * image, + uint32_t x, + uint32_t y, + uint32_t width, + uint32_t height, + void * base, + uint32_t bytes, + uint8_t * data); + + +/* + * Shm stuff + */ + +/** + * Put the data of an xcb_image_t onto a drawable using the MIT Shm + * Extension. + * @param conn The connection to the X server. + * @param draw The draw you get the image from. + * @param gc The graphic context. + * @param image The image you want to combine with the rectangle. + * @param shminfo A @ref xcb_shm_segment_info_t structure. + * @param src_x The offset in x from the left edge of the image + * defined by the xcb_image_t structure. + * @param src_y The offset in y from the left edge of the image + * defined by the xcb_image_t structure. + * @param dest_x The x coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of the + * rectangle. + * @param dest_y The y coordinate, which is relative to the origin of the + * drawable and defines the x coordinate of the upper-left corner of + * the rectangle. + * @param src_width The width of the subimage, in pixels. + * @param src_height The height of the subimage, in pixels. + * @param send_event Indicates whether or not a completion event + * should occur when the image write is complete. + * @return a pointer to the source image if no problem occurs, otherwise 0. + * + * This function combines an image in memory with a shape of the + * specified drawable. The section of the image defined by the @p x, @p y, + * @p width, and @p height arguments is drawn on the specified part of + * the drawable. If XYBitmap format is used, the depth must be + * one, or a``BadMatch'' error results. The foreground pixel in the + * Graphic Context @p gc defines the source for the one bits in the + * image, and the background pixel defines the source for the zero + * bits. For XYPixmap and ZPixmap, the depth must match the depth of + * the drawable, or a ``BadMatch'' error results. + * + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_shm_put (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_gcontext_t gc, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t src_x, + int16_t src_y, + int16_t dest_x, + int16_t dest_y, + uint16_t src_width, + uint16_t src_height, + uint8_t send_event); + + +/** + * Read image data into a shared memory xcb_image_t. + * @param conn The connection to the X server. + * @param draw The draw you get the image from. + * @param image The image you want to combine with the rectangle. + * @param shminfo A @ref xcb_shm_segment_info_t structure. + * @param x The x coordinate, which are relative to the origin of the + * drawable and define the upper-left corner of the rectangle. + * @param y The y coordinate, which are relative to the origin of the + * drawable and define the upper-left corner of the rectangle. + * @param plane_mask The plane mask. + * @return The subimage of @p draw defined by @p x, @p y, @p w, @p h. + * + * This function reads image data into a shared memory xcb_image_t where + * @p conn is the connection to the X server, @p draw is the source + * drawable, @p image is the destination xcb_image_t, @p x and @p y are offsets + * within the drawable, and @p plane_mask defines which planes are to be + * read. + * + * If a problem occurs, the function returns @c 0. It returns 1 + * otherwise. + * @ingroup xcb__image_t + */ +int xcb_image_shm_get (xcb_connection_t * conn, + xcb_drawable_t draw, + xcb_image_t * image, + xcb_shm_segment_info_t shminfo, + int16_t x, + int16_t y, + uint32_t plane_mask); + + +/** + * Create an image from user-supplied bitmap data. + * @param data Image data in packed bitmap format. + * @param width Width in bits of image data. + * @param height Height in bits of image data. + * @return The image constructed from the image data, or 0 on error. + * + * This function creates an image from the user-supplied + * bitmap @p data. The bitmap data is assumed to be in + * xbm format (i.e., 8-bit scanline unit, LSB-first, 8-bit pad). + * @ingroup xcb__image_t + */ +xcb_image_t * +xcb_image_create_from_bitmap_data (uint8_t * data, + uint32_t width, + uint32_t height); + +/** + * Create a pixmap from user-supplied bitmap data. + * @param display The connection to the X server. + * @param d The parent drawable for the pixmap. + * @param data Image data in packed bitmap format. + * @param width Width in bits of image data. + * @param height Height in bits of image data. + * @param depth Depth of the desired pixmap. + * @param fg Pixel for one-bits of pixmaps with depth larger than one. + * @param bg Pixel for zero-bits of pixmaps with depth larger than one. + * @param gcp If this pointer is non-null, the GC created to + * fill in the pixmap is stored here; it will have its foreground + * and background set to the supplied value. Otherwise, the GC + * will be freed. + * @return The pixmap constructed from the image data, or 0 on error. + * + * This function creates a pixmap from the user-supplied + * bitmap @p data. The bitmap data is assumed to be in + * xbm format (i.e., 8-bit scanline unit, LSB-first, 8-bit pad). + * If @p depth is greater than 1, the + * bitmap will be expanded to a pixmap using the given + * foreground and background pixels @p fg and @p bg. + * @ingroup xcb__image_t + */ +xcb_pixmap_t +xcb_create_pixmap_from_bitmap_data (xcb_connection_t * display, + xcb_drawable_t d, + uint8_t * data, + uint32_t width, + uint32_t height, + uint32_t depth, + uint32_t fg, + uint32_t bg, + xcb_gcontext_t * gcp); + + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + + +#endif /* __XCB_IMAGE_H__ */ diff --git a/depends/libxcb-image/xcb/xcb_pixel.h b/depends/libxcb-image/xcb/xcb_pixel.h new file mode 100644 index 0000000..fcb22b4 --- /dev/null +++ b/depends/libxcb-image/xcb/xcb_pixel.h @@ -0,0 +1,171 @@ +#ifndef __XCB_PIXEL_H__ +#define __XCB_PIXEL_H__ + +/* Copyright (C) 2007 Bart Massey + * + * 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. + */ + +#include <inttypes.h> +#include <X11/Xfuncproto.h> +#ifndef BUILD +#include <xcb/xcb_bitops.h> +#include <xcb/xcb_image.h> +#endif + +/** + * XCB Image fast pixel ops. + * + * Fast inline versions of xcb_image_get_pixel() and + * xcb_image_put_pixel() for various common cases. + * The naming convention is xcb_image_put_pixel_FUB() + * where F is the format and is either XY for bitmaps + * or Z for pixmaps, U is the bitmap unit size or pixmap + * bits-per-pixel, and B is the endianness (if needed) + * and is either M for most-significant-first or L for + * least-significant-first. Note that no checking + * is done on the arguments to these routines---caller beware. + * Also note that the pixel type is chosen to be appropriate + * to the unit; bitmaps use int and pixmaps use the appropriate + * size of unsigned. + * @ingroup xcb__image_t + */ + +_X_INLINE static void +xcb_image_put_pixel_XY32M (xcb_image_t *image, + uint32_t x, + uint32_t y, + int pixel) +{ + uint32_t unit = (x >> 3) & ~xcb_mask(2); + uint32_t byte = xcb_mask(2) - ((x >> 3) & xcb_mask(2)); + uint32_t bit = xcb_mask(3) - (x & xcb_mask(3)); + uint8_t m = 1 << bit; + uint8_t p = pixel << bit; + uint8_t * bp = image->data + (y * image->stride) + (unit | byte); + *bp = (*bp & ~m) | p; +} + +_X_INLINE static void +xcb_image_put_pixel_XY32L (xcb_image_t *image, + uint32_t x, + uint32_t y, + int pixel) +{ + uint32_t bit = x & xcb_mask(3); + uint8_t m = 1 << bit; + uint8_t p = pixel << bit; + uint8_t * bp = image->data + (y * image->stride) + (x >> 3); + *bp = (*bp & ~m) | p; +} + +_X_INLINE static int +xcb_image_get_pixel_XY32M (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint32_t unit = (x >> 3) & ~xcb_mask(2); + uint32_t byte = xcb_mask(2) - ((x >> 3) & xcb_mask(2)); + uint32_t bit = xcb_mask(3) - (x & xcb_mask(3)); + uint8_t * bp = image->data + (y * image->stride) + (unit | byte); + return (*bp >> bit) & 1; +} + +_X_INLINE static int +xcb_image_get_pixel_XY32L (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint32_t bit = x & xcb_mask(3); + uint8_t * bp = image->data + (y * image->stride) + (x >> 3); + return (*bp >> bit) & 1; +} + +_X_INLINE static void +xcb_image_put_pixel_Z8 (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint8_t pixel) +{ + image->data[x + y * image->stride] = pixel; +} + +_X_INLINE static uint8_t +xcb_image_get_pixel_Z8 (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + return image->data[x + y * image->stride]; +} + +_X_INLINE static void +xcb_image_put_pixel_Z32M (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel) +{ + uint8_t * row = image->data + (y * image->stride); + row[x << 2] = pixel >> 24; + row[(x << 2) + 1] = pixel >> 16; + row[(x << 2) + 2] = pixel >> 8; + row[(x << 2) + 3] = pixel; +} + +_X_INLINE static void +xcb_image_put_pixel_Z32L (xcb_image_t *image, + uint32_t x, + uint32_t y, + uint32_t pixel) +{ + uint8_t * row = image->data + (y * image->stride); + row[x << 2] = pixel; + row[(x << 2) + 1] = pixel >> 8; + row[(x << 2) + 2] = pixel >> 16; + row[(x << 2) + 3] = pixel >> 24; +} + +_X_INLINE static uint32_t +xcb_image_get_pixel_Z32M (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint8_t * row = image->data + (y * image->stride); + uint32_t pixel = row[x << 2] << 24; + pixel |= row[(x << 2) + 1] << 16; + pixel |= row[(x << 2) + 2] << 8; + return pixel | row[(x << 2) + 3]; +} + +_X_INLINE static uint32_t +xcb_image_get_pixel_Z32L (xcb_image_t *image, + uint32_t x, + uint32_t y) +{ + uint8_t * row = image->data + (y * image->stride); + uint32_t pixel = row[x << 2]; + pixel |= row[(x << 2) + 1] << 8; + pixel |= row[(x << 2) + 2] << 16; + return pixel | row[(x << 2) + 3] << 24; +} + +#endif /* __XCB_PIXEL_H__ */ diff --git a/depends/libxcb-util/config.h b/depends/libxcb-util/config.h new file mode 100644 index 0000000..c9091db --- /dev/null +++ b/depends/libxcb-util/config.h @@ -0,0 +1,76 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdio.h> header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vasprintf' function. */ +#define HAVE_VASPRINTF 1 + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "xcb-util" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://gitlab.freedesktop.org/xorg/lib/libxcb-util/-/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "xcb-util" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "xcb-util 0.4.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "xcb-util" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.4.1" + +/* Major version of this package */ +#define PACKAGE_VERSION_MAJOR 0 + +/* Minor version of this package */ +#define PACKAGE_VERSION_MINOR 4 + +/* Patch version of this package */ +#define PACKAGE_VERSION_PATCHLEVEL 1 + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.4.1" diff --git a/depends/libxcb-util/xcb/atoms.c b/depends/libxcb-util/xcb/atoms.c new file mode 100644 index 0000000..fe7fe94 --- /dev/null +++ b/depends/libxcb-util/xcb/atoms.c @@ -0,0 +1,87 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Rely on vasprintf (GNU extension) instead of vsnprintf if + possible... */ +#define _GNU_SOURCE +#include <stdio.h> + +#include <xcb/xcb.h> +#include <stdlib.h> +#include <stdarg.h> +#include "xcb_atom.h" + +#ifndef __has_attribute +# define __has_attribute(x) 0 /* Compatibility with older compilers. */ +#endif + +#if __has_attribute(__format__) \ + || defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) +__attribute__((__format__(__printf__,1,2))) +#endif +static char *makename(const char *fmt, ...) +{ + char *ret; + int n; + va_list ap; + +#ifndef HAVE_VASPRINTF + char *np; + int size = 64; + + /* First allocate 'size' bytes, should be enough usually */ + if((ret = malloc(size)) == NULL) + return NULL; + + while(1) + { + va_start(ap, fmt); + n = vsnprintf(ret, size, fmt, ap); + va_end(ap); + + if(n < 0) + return NULL; + + if(n < size) + return ret; + + size = n + 1; + if((np = realloc(ret, size)) == NULL) + { + free(ret); + return NULL; + } + + ret = np; + } +#else + va_start(ap, fmt); + n = vasprintf(&ret, fmt, ap); + va_end(ap); + + if(n < 0) + return NULL; + + return ret; +#endif +} + +char *xcb_atom_name_by_screen(const char *base, uint8_t screen) +{ + return makename("%s_S%u", base, screen); +} + +char *xcb_atom_name_by_resource(const char *base, uint32_t resource) +{ + return makename("%s_R%08X", base, resource); +} + +char *xcb_atom_name_unique(const char *base, uint32_t id) +{ + if(base) + return makename("%s_U%u", base, id); + else + return makename("U%u", id); +} diff --git a/depends/libxcb-util/xcb/event.c b/depends/libxcb-util/xcb/event.c new file mode 100644 index 0000000..88058c4 --- /dev/null +++ b/depends/libxcb-util/xcb/event.c @@ -0,0 +1,259 @@ +/* + * Copyright © 2008-2009 Julien Danjou <julien@danjou.info> + * + * 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 <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "xcb_event.h" + +#include <sys/types.h> + +#define ssizeof(foo) (ssize_t)sizeof(foo) +#define countof(foo) (ssizeof(foo) / ssizeof(foo[0])) + +static const char *labelError[] = +{ + "Success", + "BadRequest", + "BadValue", + "BadWindow", + "BadPixmap", + "BadAtom", + "BadCursor", + "BadFont", + "BadMatch", + "BadDrawable", + "BadAccess", + "BadAlloc", + "BadColor", + "BadGC", + "BadIDChoice", + "BadName", + "BadLength", + "BadImplementation", +}; + +static const char *labelRequest[] = +{ + "no request", + "CreateWindow", + "ChangeWindowAttributes", + "GetWindowAttributes", + "DestroyWindow", + "DestroySubwindows", + "ChangeSaveSet", + "ReparentWindow", + "MapWindow", + "MapSubwindows", + "UnmapWindow", + "UnmapSubwindows", + "ConfigureWindow", + "CirculateWindow", + "GetGeometry", + "QueryTree", + "InternAtom", + "GetAtomName", + "ChangeProperty", + "DeleteProperty", + "GetProperty", + "ListProperties", + "SetSelectionOwner", + "GetSelectionOwner", + "ConvertSelection", + "SendEvent", + "GrabPointer", + "UngrabPointer", + "GrabButton", + "UngrabButton", + "ChangeActivePointerGrab", + "GrabKeyboard", + "UngrabKeyboard", + "GrabKey", + "UngrabKey", + "AllowEvents", + "GrabServer", + "UngrabServer", + "QueryPointer", + "GetMotionEvents", + "TranslateCoords", + "WarpPointer", + "SetInputFocus", + "GetInputFocus", + "QueryKeymap", + "OpenFont", + "CloseFont", + "QueryFont", + "QueryTextExtents", + "ListFonts", + "ListFontsWithInfo", + "SetFontPath", + "GetFontPath", + "CreatePixmap", + "FreePixmap", + "CreateGC", + "ChangeGC", + "CopyGC", + "SetDashes", + "SetClipRectangles", + "FreeGC", + "ClearArea", + "CopyArea", + "CopyPlane", + "PolyPoint", + "PolyLine", + "PolySegment", + "PolyRectangle", + "PolyArc", + "FillPoly", + "PolyFillRectangle", + "PolyFillArc", + "PutImage", + "GetImage", + "PolyText", + "PolyText", + "ImageText", + "ImageText", + "CreateColormap", + "FreeColormap", + "CopyColormapAndFree", + "InstallColormap", + "UninstallColormap", + "ListInstalledColormaps", + "AllocColor", + "AllocNamedColor", + "AllocColorCells", + "AllocColorPlanes", + "FreeColors", + "StoreColors", + "StoreNamedColor", + "QueryColors", + "LookupColor", + "CreateCursor", + "CreateGlyphCursor", + "FreeCursor", + "RecolorCursor", + "QueryBestSize", + "QueryExtension", + "ListExtensions", + "ChangeKeyboardMapping", + "GetKeyboardMapping", + "ChangeKeyboardControl", + "GetKeyboardControl", + "Bell", + "ChangePointerControl", + "GetPointerControl", + "SetScreenSaver", + "GetScreenSaver", + "ChangeHosts", + "ListHosts", + "SetAccessControl", + "SetCloseDownMode", + "KillClient", + "RotateProperties", + "ForceScreenSaver", + "SetPointerMapping", + "GetPointerMapping", + "SetModifierMapping", + "GetModifierMapping", + "major 120", + "major 121", + "major 122", + "major 123", + "major 124", + "major 125", + "major 126", + "NoOperation", +}; + +static const char *labelEvent[] = +{ + "error", + "reply", + "KeyPress", + "KeyRelease", + "ButtonPress", + "ButtonRelease", + "MotionNotify", + "EnterNotify", + "LeaveNotify", + "FocusIn", + "FocusOut", + "KeymapNotify", + "Expose", + "GraphicsExpose", + "NoExpose", + "VisibilityNotify", + "CreateNotify", + "DestroyNotify", + "UnmapNotify", + "MapNotify", + "MapRequest", + "ReparentNotify", + "ConfigureNotify", + "ConfigureRequest", + "GravityNotify", + "ResizeRequest", + "CirculateNotify", + "CirculateRequest", + "PropertyNotify", + "SelectionClear", + "SelectionRequest", + "SelectionNotify", + "ColormapNotify", + "ClientMessage", + "MappingNotify", +}; + +const char * +xcb_event_get_label(uint8_t type) +{ + if(type < countof(labelEvent)) + return labelEvent[type]; + return NULL; +} + +const char * +xcb_event_get_error_label(uint8_t type) +{ + if(type < countof(labelError)) + return labelError[type]; + return NULL; +} + +const char * +xcb_event_get_request_label(uint8_t type) +{ + if(type < countof(labelRequest)) + return labelRequest[type]; + return NULL; +} diff --git a/depends/libxcb-util/xcb/xcb_atom.h b/depends/libxcb-util/xcb/xcb_atom.h new file mode 100644 index 0000000..d5c4d6b --- /dev/null +++ b/depends/libxcb-util/xcb/xcb_atom.h @@ -0,0 +1,18 @@ +#ifndef __XCB_ATOM_H__ +#define __XCB_ATOM_H__ + +#include <xcb/xcb.h> + +#ifdef __cplusplus +extern "C" { +#endif + +char *xcb_atom_name_by_screen(const char *base, uint8_t screen); +char *xcb_atom_name_by_resource(const char *base, uint32_t resource); +char *xcb_atom_name_unique(const char *base, uint32_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* __XCB_ATOM_H__ */ diff --git a/depends/libxcb-util/xcb/xcb_aux.c b/depends/libxcb-util/xcb/xcb_aux.c new file mode 100644 index 0000000..c56ad61 --- /dev/null +++ b/depends/libxcb-util/xcb/xcb_aux.c @@ -0,0 +1,378 @@ +/* + * Copyright © 2008 Bart Massey <bart@cs.pdx.edu> + * Copyright © 2008 Ian Osgood <iano@quirkster.com> + * Copyright © 2008 Jamey Sharp <jamey@minilop.net> + * Copyright © 2008 Josh Triplett <josh@freedesktop.org> + * + * 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <xcb/xcb.h> +#include "xcb_aux.h" + +/* Connection related functions */ + +uint8_t +xcb_aux_get_depth (xcb_connection_t *c, + xcb_screen_t *screen) +{ + xcb_drawable_t drawable; + xcb_get_geometry_reply_t *geom; + uint8_t depth = 0; + + drawable = screen->root; + geom = xcb_get_geometry_reply (c, xcb_get_geometry(c, drawable), 0); + + if (geom) { + depth = geom->depth; + free (geom); + } + + return depth; +} + +uint8_t +xcb_aux_get_depth_of_visual (xcb_screen_t *screen, + xcb_visualid_t id) +{ + xcb_depth_iterator_t i; + xcb_visualtype_iterator_t j; + for (i = xcb_screen_allowed_depths_iterator(screen); + i.rem; xcb_depth_next(&i)) + for (j = xcb_depth_visuals_iterator(i.data); + j.rem; xcb_visualtype_next(&j)) + if (j.data->visual_id == id) + return i.data->depth; + return 0; +} + +xcb_screen_t * +xcb_aux_get_screen (xcb_connection_t *c, + int screen) +{ + xcb_screen_iterator_t i = xcb_setup_roots_iterator(xcb_get_setup(c)); + for (; i.rem; --screen, xcb_screen_next(&i)) + if (screen == 0) + return i.data; + return 0; +} + +xcb_visualtype_t * +xcb_aux_get_visualtype (xcb_connection_t *c, + int scr, + xcb_visualid_t vid) +{ + xcb_screen_t *screen; + xcb_depth_t *depth; + xcb_visualtype_iterator_t iter; + int cur; + + screen = xcb_aux_get_screen (c, scr); + if (!screen) return NULL; + + depth = xcb_screen_allowed_depths_iterator(screen).data; + if (!depth) return NULL; + + iter = xcb_depth_visuals_iterator(depth); + for (cur = 0 ; cur < iter.rem ; xcb_visualtype_next(&iter), ++cur) + if (vid == iter.data->visual_id) + return iter.data; + + return NULL; +} + +xcb_visualtype_t * +xcb_aux_find_visual_by_id (xcb_screen_t *screen, + xcb_visualid_t id) +{ + xcb_depth_iterator_t i; + xcb_visualtype_iterator_t j; + for (i = xcb_screen_allowed_depths_iterator(screen); + i.rem; xcb_depth_next(&i)) + for (j = xcb_depth_visuals_iterator(i.data); + j.rem; xcb_visualtype_next(&j)) + if (j.data->visual_id == id) + return j.data; + return 0; +} + +xcb_visualtype_t * +xcb_aux_find_visual_by_attrs (xcb_screen_t *screen, + int8_t class, + int8_t depth) +{ + xcb_depth_iterator_t i; + xcb_visualtype_iterator_t j; + for (i = xcb_screen_allowed_depths_iterator(screen); + i.rem; xcb_depth_next(&i)) { + if (depth != -1 && i.data->depth != depth) + continue; + for (j = xcb_depth_visuals_iterator(i.data); + j.rem; xcb_visualtype_next(&j)) + if (class == -1 || j.data->_class == class) + return j.data; + } + return 0; +} + +void +xcb_aux_sync (xcb_connection_t *c) +{ + free(xcb_get_input_focus_reply(c, xcb_get_input_focus(c), NULL)); +} + +/* structs instead of value lists */ +/* TODO: generate the struct types and functions from protocol masks and descriptions */ + +/* This generic implementation of pack_list depends on: + a) structs packed to uint32_t size + b) structs consist of just uint32_t/int32_t fields in the same order as bitmask +*/ + +static void +pack_list( uint32_t mask, const uint32_t *src, uint32_t *dest ) +{ + for ( ; mask; mask >>= 1, src++) + if (mask & 1) + *dest++ = *src; +} + +xcb_void_cookie_t +xcb_aux_create_window (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t _class, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_window(c, depth, wid, parent, + x, y, width, height, border_width, + _class, visual, mask, value_list); +} + +xcb_void_cookie_t +xcb_aux_create_window_checked (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t _class, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_window_checked(c, depth, wid, parent, + x, y, width, height, border_width, + _class, visual, mask, value_list); +} + +xcb_void_cookie_t +xcb_aux_change_window_attributes_checked (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_window_attributes_checked( c, window, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_change_window_attributes (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_window_attributes( c, window, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_configure_window (xcb_connection_t *c, + xcb_window_t window, + uint16_t mask, + const xcb_params_configure_window_t *params) +{ + uint32_t value_list[8]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_configure_window( c, window, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_create_gc (xcb_connection_t *c, + xcb_gcontext_t gid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_gc( c, gid, drawable, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_create_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_create_gc_checked( c, gid, drawable, mask, value_list); +} + +xcb_void_cookie_t +xcb_aux_change_gc (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_gc( c, gc, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_change_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params) +{ + uint32_t value_list[32]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_gc_checked( c, gc, mask, value_list ); +} + +xcb_void_cookie_t +xcb_aux_change_keyboard_control (xcb_connection_t *c, + uint32_t mask, + const xcb_params_keyboard_t *params) +{ + uint32_t value_list[16]; + pack_list(mask, (const uint32_t *)params, value_list); + return xcb_change_keyboard_control( c, mask, value_list ); +} + +/* Color related functions */ + +/* Return true if the given color name can be translated locally, + in which case load the components. Otherwise, a lookup_color request + will be needed, so return false. */ +int +xcb_aux_parse_color(const char *color_name, + uint16_t *red, uint16_t *green, uint16_t *blue) +{ + int n, r, g, b, i; + if (!color_name || *color_name != '#') + return 0; + /* + * Excitingly weird RGB parsing code from Xlib. + */ + n = strlen (color_name); + color_name++; + n--; + if (n != 3 && n != 6 && n != 9 && n != 12) + return 0; + n /= 3; + g = b = 0; + do { + r = g; + g = b; + b = 0; + for (i = n; --i >= 0; ) { + char c = *color_name++; + b <<= 4; + if (c >= '0' && c <= '9') + b |= c - '0'; + else if (c >= 'A' && c <= 'F') + b |= c - ('A' - 10); + else if (c >= 'a' && c <= 'f') + b |= c - ('a' - 10); + else return 0; + } + } while (*color_name != '\0'); + n <<= 2; + n = 16 - n; + *red = (uint16_t) (r << n); + *green = (uint16_t) (g << n); + *blue = (uint16_t) (b << n); + return 1; +} + +/* Drawing related functions */ + +/* Adapted from Xlib */ +xcb_void_cookie_t +xcb_aux_set_line_attributes_checked (xcb_connection_t *dpy, + xcb_gcontext_t gc, + uint16_t linewidth, + int32_t linestyle, + int32_t capstyle, + int32_t joinstyle) +{ + uint32_t mask = 0; + xcb_params_gc_t gv; + + XCB_AUX_ADD_PARAM(&mask, &gv, line_width, linewidth); + XCB_AUX_ADD_PARAM(&mask, &gv, line_style, linestyle); + XCB_AUX_ADD_PARAM(&mask, &gv, cap_style, capstyle); + XCB_AUX_ADD_PARAM(&mask, &gv, join_style, joinstyle); + return xcb_aux_change_gc_checked(dpy, gc, mask, &gv); +} + +/* Adapted from Xlib */ +/* XXX It would be wiser for apps just to call + clear_area() directly. */ +xcb_void_cookie_t +xcb_aux_clear_window(xcb_connection_t * dpy, + xcb_window_t w) +{ + return xcb_clear_area(dpy, 0, w, 0, 0, 0, 0); +} diff --git a/depends/libxcb-util/xcb/xcb_aux.h b/depends/libxcb-util/xcb/xcb_aux.h new file mode 100644 index 0000000..da4fb85 --- /dev/null +++ b/depends/libxcb-util/xcb/xcb_aux.h @@ -0,0 +1,214 @@ +#ifndef __XCB_AUX_H__ +#define __XCB_AUX_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + + +uint8_t xcb_aux_get_depth (xcb_connection_t *c, + xcb_screen_t *screen); + +uint8_t xcb_aux_get_depth_of_visual (xcb_screen_t *screen, + xcb_visualid_t id); + +xcb_screen_t *xcb_aux_get_screen (xcb_connection_t *c, + int screen); + +xcb_visualtype_t *xcb_aux_get_visualtype (xcb_connection_t *c, + int screen, + xcb_visualid_t vid); + +xcb_visualtype_t * +xcb_aux_find_visual_by_id (xcb_screen_t *screen, + xcb_visualid_t id); + +xcb_visualtype_t * +xcb_aux_find_visual_by_attrs (xcb_screen_t *screen, + int8_t class_, + int8_t depth); + +void xcb_aux_sync (xcb_connection_t *c); + +/* internal helper macro for XCB_AUX_ADD_PARAM +It gives the offset of the field 'param' in the structure pointed to by +'paramsp' in multiples of an uint32_t's size. */ +#define XCB_AUX_INTERNAL_OFFSETOF(paramsp, param) \ + ((uint32_t const*)(&((paramsp)->param))-(uint32_t const*)(paramsp)) + +/* add an optional parameter to an xcb_params_* structure +parameters: + maskp: pointer to bitmask whos bits mark used parameters + paramsp: pointer to structure with parameters + param: parameter to set + value: value to set the parameter to +*/ +#define XCB_AUX_ADD_PARAM(maskp, paramsp, param, value) \ + ((*(maskp)|=1<<XCB_AUX_INTERNAL_OFFSETOF((paramsp),param)), \ + ((paramsp)->param=(value))) + +typedef struct { + uint32_t back_pixmap; + uint32_t back_pixel; + uint32_t border_pixmap; + uint32_t border_pixel; + uint32_t bit_gravity; + uint32_t win_gravity; + uint32_t backing_store; + uint32_t backing_planes; + uint32_t backing_pixel; + uint32_t override_redirect; + uint32_t save_under; + uint32_t event_mask; + uint32_t dont_propagate; + uint32_t colormap; + uint32_t cursor; +} xcb_params_cw_t; + +xcb_void_cookie_t +xcb_aux_create_window (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t class_, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params); + +xcb_void_cookie_t +xcb_aux_create_window_checked (xcb_connection_t *c, + uint8_t depth, + xcb_window_t wid, + xcb_window_t parent, + int16_t x, + int16_t y, + uint16_t width, + uint16_t height, + uint16_t border_width, + uint16_t class_, + xcb_visualid_t visual, + uint32_t mask, + const xcb_params_cw_t *params); + +xcb_void_cookie_t +xcb_aux_change_window_attributes (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params); + +xcb_void_cookie_t +xcb_aux_change_window_attributes_checked (xcb_connection_t *c, + xcb_window_t window, + uint32_t mask, + const xcb_params_cw_t *params); + +typedef struct { + int32_t x; + int32_t y; + uint32_t width; + uint32_t height; + uint32_t border_width; + uint32_t sibling; + uint32_t stack_mode; +} xcb_params_configure_window_t; + +xcb_void_cookie_t +xcb_aux_configure_window (xcb_connection_t *c, + xcb_window_t window, + uint16_t mask, + const xcb_params_configure_window_t *params); + +typedef struct { + uint32_t function; + uint32_t plane_mask; + uint32_t foreground; + uint32_t background; + uint32_t line_width; + uint32_t line_style; + uint32_t cap_style; + uint32_t join_style; + uint32_t fill_style; + uint32_t fill_rule; + uint32_t tile; + uint32_t stipple; + uint32_t tile_stipple_origin_x; + uint32_t tile_stipple_origin_y; + uint32_t font; + uint32_t subwindow_mode; + uint32_t graphics_exposures; + uint32_t clip_originX; + uint32_t clip_originY; + uint32_t mask; + uint32_t dash_offset; + uint32_t dash_list; + uint32_t arc_mode; +} xcb_params_gc_t; + +xcb_void_cookie_t +xcb_aux_create_gc (xcb_connection_t *c, + xcb_gcontext_t cid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params); + +xcb_void_cookie_t +xcb_aux_create_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gid, + xcb_drawable_t drawable, + uint32_t mask, + const xcb_params_gc_t *params); +xcb_void_cookie_t +xcb_aux_change_gc (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params); + +xcb_void_cookie_t +xcb_aux_change_gc_checked (xcb_connection_t *c, + xcb_gcontext_t gc, + uint32_t mask, + const xcb_params_gc_t *params); +typedef struct { + uint32_t key_click_percent; + uint32_t bell_percent; + uint32_t bell_pitch; + uint32_t bell_duration; + uint32_t led; + uint32_t led_mode; + uint32_t key; + uint32_t auto_repeat_mode; +} xcb_params_keyboard_t; + +xcb_void_cookie_t +xcb_aux_change_keyboard_control (xcb_connection_t *c, + uint32_t mask, + const xcb_params_keyboard_t *params); + +int +xcb_aux_parse_color(const char *color_name, + uint16_t *red, uint16_t *green, uint16_t *blue); + +xcb_void_cookie_t +xcb_aux_set_line_attributes_checked (xcb_connection_t *dpy, + xcb_gcontext_t gc, + uint16_t linewidth, + int32_t linestyle, + int32_t capstyle, + int32_t joinstyle); + +xcb_void_cookie_t +xcb_aux_clear_window(xcb_connection_t * dpy, + xcb_window_t w); + +#ifdef __cplusplus +} +#endif + + +#endif /* __XCB_AUX_H__ */ diff --git a/depends/libxcb-util/xcb/xcb_event.h b/depends/libxcb-util/xcb/xcb_event.h new file mode 100644 index 0000000..ee911fc --- /dev/null +++ b/depends/libxcb-util/xcb/xcb_event.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2008-2009 Julien Danjou <julien@danjou.info> + * + * 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. + */ + +/** + * @defgroup xcb__event_t XCB Event Functions + * + * These functions ease the handling of X events received. + * + * @{ + */ + +#ifndef __XCB_EVENT_H__ +#define __XCB_EVENT_H__ + +#include <xcb/xcb.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Bit mask to find event type regardless of event source. + * + * Each event in the X11 protocol contains an 8-bit type code. + * The most-significant bit in this code is set if the event was + * generated from a SendEvent request. This mask can be used to + * determine the type of event regardless of how the event was + * generated. See the X11R6 protocol specification for details. + */ +#define XCB_EVENT_RESPONSE_TYPE_MASK (0x7f) +#define XCB_EVENT_RESPONSE_TYPE(e) (e->response_type & XCB_EVENT_RESPONSE_TYPE_MASK) +#define XCB_EVENT_SENT(e) (e->response_type & ~XCB_EVENT_RESPONSE_TYPE_MASK) + +/** + * @brief Convert an event response type to a label. + * @param type The event type. + * @return A string with the event name, or NULL if unknown. + */ +const char * xcb_event_get_label(uint8_t type); + +/** + * @brief Convert an event error type to a label. + * @param type The error type. + * @return A string with the event name, or NULL if unknown or if the event is + * not an error. + */ +const char * xcb_event_get_error_label(uint8_t type); + +/** + * @brief Convert an event request type to a label. + * @param type The request type. + * @return A string with the event name, or NULL if unknown or if the event is + * not an error. + */ +const char * xcb_event_get_request_label(uint8_t type); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __XCB_EVENT_H__ */ diff --git a/depends/libxcb-util/xcb/xcb_util.h b/depends/libxcb-util/xcb/xcb_util.h new file mode 100644 index 0000000..0f06f1b --- /dev/null +++ b/depends/libxcb-util/xcb/xcb_util.h @@ -0,0 +1,8 @@ +#ifndef __XCB_UTIL_H__ +#define __XCB_UTIL_H__ + +#include <xcb/xcb_atom.h> +#include <xcb/xcb_aux.h> +#include <xcb/xcb_event.h> + +#endif /* __XCB_UTIL_H__ */ diff --git a/depends/libxcb-wm/config.h b/depends/libxcb-wm/config.h new file mode 100644 index 0000000..976b4bc --- /dev/null +++ b/depends/libxcb-wm/config.h @@ -0,0 +1,73 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdio.h> header file. */ +#define HAVE_STDIO_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "xcb-util-wm" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://gitlab.freedesktop.org/xorg/lib/libxcb-wm/-/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "xcb-util-wm" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "xcb-util-wm 0.4.2" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "xcb-util-wm" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.4.2" + +/* Major version of this package */ +#define PACKAGE_VERSION_MAJOR 0 + +/* Minor version of this package */ +#define PACKAGE_VERSION_MINOR 4 + +/* Patch version of this package */ +#define PACKAGE_VERSION_PATCHLEVEL 2 + +/* Define to 1 if all of the C90 standard headers exist (not just the ones + required in a freestanding environment). This macro is provided for + backward compatibility; new code need not use it. */ +#define STDC_HEADERS 1 + +/* Version number of package */ +#define VERSION "0.4.2" diff --git a/depends/libxcb-wm/xcb/icccm.c b/depends/libxcb-wm/xcb/icccm.c new file mode 100644 index 0000000..f6daf0d --- /dev/null +++ b/depends/libxcb-wm/xcb/icccm.c @@ -0,0 +1,849 @@ +/* + * Copyright © 2008 Arnaud Fontaine <arnau@debian.org> + * Copyright © 2007-2008 Vincent Torri <vtorri@univ-evry.fr> + * + * 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 <stdlib.h> +#include <limits.h> +#include <string.h> + +#include <xcb/xcb.h> + +#include "xcb_icccm.h" + +xcb_get_property_cookie_t +xcb_icccm_get_text_property(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property) +{ + return xcb_get_property(c, 0, window, property, XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); +} + +xcb_get_property_cookie_t +xcb_icccm_get_text_property_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property) +{ + return xcb_get_property_unchecked(c, 0, window, property, XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); +} + +uint8_t +xcb_icccm_get_text_property_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + + if(!reply || reply->type == XCB_NONE) { + free(reply); + return 0; + } + + prop->_reply = reply; + prop->encoding = prop->_reply->type; + prop->format = prop->_reply->format; + prop->name_len = xcb_get_property_value_length(prop->_reply); + prop->name = xcb_get_property_value(prop->_reply); + + return 1; +} + +void +xcb_icccm_get_text_property_reply_wipe(xcb_icccm_get_text_property_reply_t *prop) +{ + free(prop->_reply); +} + +/* WM_NAME */ + +xcb_void_cookie_t +xcb_icccm_set_wm_name_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint8_t format, + uint32_t name_len, const char *name) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_NAME, encoding, format, + name_len, name); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_name(xcb_connection_t *c, xcb_window_t window, xcb_atom_t encoding, + uint8_t format, uint32_t name_len, const char *name) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_NAME, encoding, format, name_len, + name); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_name(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_icccm_get_text_property(c, window, XCB_ATOM_WM_NAME); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_name_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_icccm_get_text_property_unchecked(c, window, XCB_ATOM_WM_NAME); +} + +uint8_t +xcb_icccm_get_wm_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + return xcb_icccm_get_text_property_reply(c, cookie, prop, e); +} + +/* WM_ICON_NAME */ + +xcb_void_cookie_t +xcb_icccm_set_wm_icon_name_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint8_t format, + uint32_t name_len, const char *name) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_ICON_NAME, encoding, format, + name_len, name); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_icon_name(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint8_t format, uint32_t name_len, + const char *name) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_ICON_NAME, encoding, format, + name_len, name); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_icon_name(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_icccm_get_text_property(c, window, XCB_ATOM_WM_ICON_NAME); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_icon_name_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_icccm_get_text_property_unchecked(c, window, XCB_ATOM_WM_ICON_NAME); +} + +uint8_t +xcb_icccm_get_wm_icon_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + return xcb_icccm_get_text_property_reply(c, cookie, prop, e); +} + +/* WM_COLORMAP_WINDOWS */ + +xcb_void_cookie_t +xcb_icccm_set_wm_colormap_windows_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom, + uint32_t list_len, + const xcb_window_t *list) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + wm_colormap_windows_atom, XCB_ATOM_WINDOW, + 32, list_len, list); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_colormap_windows(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom, + uint32_t list_len, + const xcb_atom_t *list) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, + wm_colormap_windows_atom, XCB_ATOM_WINDOW, 32, + list_len, list); +} + + +xcb_get_property_cookie_t +xcb_icccm_get_wm_colormap_windows(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom ) +{ + return xcb_get_property(c, 0, window, wm_colormap_windows_atom, + XCB_ATOM_WINDOW, 0, UINT_MAX); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_colormap_windows_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom) +{ + return xcb_get_property_unchecked(c, 0, window, wm_colormap_windows_atom, + XCB_ATOM_WINDOW, 0, UINT_MAX); +} + +uint8_t +xcb_icccm_get_wm_colormap_windows_from_reply(xcb_get_property_reply_t *reply, + xcb_icccm_get_wm_colormap_windows_reply_t *colormap_windows) +{ + if(!reply || reply->type != XCB_ATOM_WINDOW || reply->format != 32) + return 0; + + colormap_windows->_reply = reply; + colormap_windows->windows_len = xcb_get_property_value_length(colormap_windows->_reply) / (reply->format / 8); + colormap_windows->windows = (xcb_window_t *) xcb_get_property_value(colormap_windows->_reply); + + return 1; +} + +uint8_t +xcb_icccm_get_wm_colormap_windows_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_wm_colormap_windows_reply_t *colormap_windows, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_icccm_get_wm_colormap_windows_from_reply(reply, colormap_windows); + if(!ret) + free(reply); + return ret; +} + +void +xcb_icccm_get_wm_colormap_windows_reply_wipe(xcb_icccm_get_wm_colormap_windows_reply_t *colormap_windows) +{ + free(colormap_windows->_reply); +} + +/* WM_CLIENT_MACHINE */ + +xcb_void_cookie_t +xcb_icccm_set_wm_client_machine_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint8_t format, + uint32_t name_len, const char *name) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_CLIENT_MACHINE, encoding, + format, name_len, name); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_client_machine(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint8_t format, + uint32_t name_len, const char *name) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_CLIENT_MACHINE, encoding, format, + name_len, name); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_client_machine(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_icccm_get_text_property(c, window, XCB_ATOM_WM_CLIENT_MACHINE); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_client_machine_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_icccm_get_text_property_unchecked(c, window, XCB_ATOM_WM_CLIENT_MACHINE); +} + +uint8_t +xcb_icccm_get_wm_client_machine_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e) +{ + return xcb_icccm_get_text_property_reply(c, cookie, prop, e); +} + +/* WM_CLASS */ + +xcb_void_cookie_t +xcb_icccm_set_wm_class_checked(xcb_connection_t *c, + xcb_window_t window, + uint32_t class_len, + const char *class) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, + class_len, class); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_class(xcb_connection_t *c, + xcb_window_t window, + uint32_t class_len, + const char *class) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 8, + class_len, class); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_class(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property(c, 0, window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0L, 2048L); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_class_unchecked(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property_unchecked(c, 0, window, XCB_ATOM_WM_CLASS, XCB_ATOM_STRING, 0L, 2048L); +} + +uint8_t +xcb_icccm_get_wm_class_from_reply(xcb_icccm_get_wm_class_reply_t *prop, + xcb_get_property_reply_t *reply) +{ + if(!reply || reply->type != XCB_ATOM_STRING || reply->format != 8) + return 0; + + prop->_reply = reply; + prop->instance_name = (char *) xcb_get_property_value(prop->_reply); + + int len = xcb_get_property_value_length(prop->_reply); + /* Ensure there's a C end-of-string at the end of the property. + Truncate the property if necessary (the spec says there's already + a 0 in the last position, so this only hurts invalid props). */ + if(len < reply->length * 4) + prop->instance_name[len] = 0; + else + prop->instance_name[len-1] = 0; + + int name_len = strlen(prop->instance_name); + if(name_len == len) + name_len--; + + prop->class_name = prop->instance_name + name_len + 1; + + return 1; +} + +uint8_t +xcb_icccm_get_wm_class_reply(xcb_connection_t *c, xcb_get_property_cookie_t cookie, + xcb_icccm_get_wm_class_reply_t *prop, xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_icccm_get_wm_class_from_reply(prop, reply); + /* if reply parsing failed, free the reply to avoid mem leak */ + if(!ret) + free(reply); + return ret; +} + +void +xcb_icccm_get_wm_class_reply_wipe(xcb_icccm_get_wm_class_reply_t *prop) +{ + free(prop->_reply); +} + +/* WM_TRANSIENT_FOR */ + +xcb_void_cookie_t +xcb_icccm_set_wm_transient_for_checked(xcb_connection_t *c, xcb_window_t window, + xcb_window_t transient_for_window) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_TRANSIENT_FOR, + XCB_ATOM_WINDOW, 32, 1, + &transient_for_window); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_transient_for(xcb_connection_t *c, xcb_window_t window, + xcb_window_t transient_for_window) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, + XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, + 1, &transient_for_window); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_transient_for(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property(c, 0, window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 1); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_transient_for_unchecked(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_get_property_unchecked(c, 0, window, XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 0, 1); +} + +uint8_t +xcb_icccm_get_wm_transient_for_from_reply(xcb_window_t *prop, + xcb_get_property_reply_t *reply) +{ + if(!reply || reply->type != XCB_ATOM_WINDOW || reply->format != 32 || !reply->length) + return 0; + + *prop = *((xcb_window_t *) xcb_get_property_value(reply)); + + return 1; +} + +uint8_t +xcb_icccm_get_wm_transient_for_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_window_t *prop, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_icccm_get_wm_transient_for_from_reply(prop, reply); + free(reply); + return ret; +} + +/* WM_SIZE_HINTS */ + +void +xcb_icccm_size_hints_set_position(xcb_size_hints_t *hints, int user_specified, + int32_t x, int32_t y) +{ + hints->flags &= ~(XCB_ICCCM_SIZE_HINT_US_POSITION | XCB_ICCCM_SIZE_HINT_P_POSITION); + if (user_specified) + hints->flags |= XCB_ICCCM_SIZE_HINT_US_POSITION; + else + hints->flags |= XCB_ICCCM_SIZE_HINT_P_POSITION; + hints->x = x; + hints->y = y; +} + +void +xcb_icccm_size_hints_set_size(xcb_size_hints_t *hints, int user_specified, + int32_t width, int32_t height) +{ + hints->flags &= ~(XCB_ICCCM_SIZE_HINT_US_SIZE | XCB_ICCCM_SIZE_HINT_P_SIZE); + if (user_specified) + hints->flags |= XCB_ICCCM_SIZE_HINT_US_SIZE; + else + hints->flags |= XCB_ICCCM_SIZE_HINT_P_SIZE; + hints->width = width; + hints->height = height; +} + +void +xcb_icccm_size_hints_set_min_size(xcb_size_hints_t *hints, int32_t min_width, + int32_t min_height) +{ + hints->flags |= XCB_ICCCM_SIZE_HINT_P_MIN_SIZE; + hints->min_width = min_width; + hints->min_height = min_height; +} + +void +xcb_icccm_size_hints_set_max_size(xcb_size_hints_t *hints, int32_t max_width, + int32_t max_height) +{ + hints->flags |= XCB_ICCCM_SIZE_HINT_P_MAX_SIZE; + hints->max_width = max_width; + hints->max_height = max_height; +} + +void +xcb_icccm_size_hints_set_resize_inc(xcb_size_hints_t *hints, int32_t width_inc, + int32_t height_inc) +{ + hints->flags |= XCB_ICCCM_SIZE_HINT_P_RESIZE_INC; + hints->width_inc = width_inc; + hints->height_inc = height_inc; +} + +void +xcb_icccm_size_hints_set_aspect(xcb_size_hints_t *hints, int32_t min_aspect_num, + int32_t min_aspect_den, int32_t max_aspect_num, + int32_t max_aspect_den) +{ + hints->flags |= XCB_ICCCM_SIZE_HINT_P_ASPECT; + hints->min_aspect_num = min_aspect_num; + hints->min_aspect_den = min_aspect_den; + hints->max_aspect_num = max_aspect_num; + hints->max_aspect_den = max_aspect_den; +} + +void +xcb_icccm_size_hints_set_base_size(xcb_size_hints_t *hints, int32_t base_width, + int32_t base_height) +{ + hints->flags |= XCB_ICCCM_SIZE_HINT_BASE_SIZE; + hints->base_width = base_width; + hints->base_height = base_height; +} + +void +xcb_icccm_size_hints_set_win_gravity(xcb_size_hints_t *hints, xcb_gravity_t win_gravity) +{ + hints->flags |= XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY; + hints->win_gravity = win_gravity; +} + +xcb_void_cookie_t +xcb_icccm_set_wm_size_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property, xcb_size_hints_t *hints) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, property, + XCB_ATOM_WM_SIZE_HINTS, 32, sizeof(*hints) >> 2, + hints); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_size_hints(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property, xcb_size_hints_t *hints) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, property, + XCB_ATOM_WM_SIZE_HINTS, 32, sizeof(*hints) >> 2, hints); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_size_hints(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property) +{ + return xcb_get_property(c, 0, window, property, XCB_ATOM_WM_SIZE_HINTS, 0L, XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_size_hints_unchecked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t property) +{ + return xcb_get_property_unchecked(c, 0, window, property, XCB_ATOM_WM_SIZE_HINTS, + 0L, XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS); +} + +uint8_t +xcb_icccm_get_wm_size_hints_from_reply(xcb_size_hints_t *hints, xcb_get_property_reply_t *reply) +{ + uint32_t flags; + int length; + + if(!reply) + return 0; + + if (!(reply->type == XCB_ATOM_WM_SIZE_HINTS && + reply->format == 32)) + return 0; + + length = xcb_get_property_value_length(reply) / (reply->format / 8); + + if(length > XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS) + length = XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS; + + memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value (reply), + length * (reply->format / 8)); + + flags = (XCB_ICCCM_SIZE_HINT_US_POSITION | XCB_ICCCM_SIZE_HINT_US_SIZE | + XCB_ICCCM_SIZE_HINT_P_POSITION | XCB_ICCCM_SIZE_HINT_P_SIZE | + XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | XCB_ICCCM_SIZE_HINT_P_MAX_SIZE | + XCB_ICCCM_SIZE_HINT_P_RESIZE_INC | XCB_ICCCM_SIZE_HINT_P_ASPECT); + + /* NumPropSizeElements = 18 (ICCCM version 1) */ + if(length >= 18) + flags |= (XCB_ICCCM_SIZE_HINT_BASE_SIZE | XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY); + else + { + hints->base_width = 0; + hints->base_height = 0; + hints->win_gravity = 0; + } + /* get rid of unwanted bits */ + hints->flags &= flags; + + return 1; +} + +uint8_t +xcb_icccm_get_wm_size_hints_reply(xcb_connection_t *c, xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_icccm_get_wm_size_hints_from_reply(hints, reply); + free(reply); + return ret; +} + +/* WM_NORMAL_HINTS */ + +xcb_void_cookie_t +xcb_icccm_set_wm_normal_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_size_hints_t *hints) +{ + return xcb_icccm_set_wm_size_hints_checked(c, window, XCB_ATOM_WM_NORMAL_HINTS, hints); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_normal_hints(xcb_connection_t *c, xcb_window_t window, + xcb_size_hints_t *hints) +{ + return xcb_icccm_set_wm_size_hints(c, window, XCB_ATOM_WM_NORMAL_HINTS, hints); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_normal_hints(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_icccm_get_wm_size_hints(c, window, XCB_ATOM_WM_NORMAL_HINTS); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_normal_hints_unchecked(xcb_connection_t *c, xcb_window_t window) +{ + return xcb_icccm_get_wm_size_hints_unchecked(c, window, XCB_ATOM_WM_NORMAL_HINTS); +} + +uint8_t +xcb_icccm_get_wm_normal_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, + xcb_generic_error_t **e) +{ + return xcb_icccm_get_wm_size_hints_reply(c, cookie, hints, e); +} + +/* WM_HINTS */ + +uint32_t +xcb_icccm_wm_hints_get_urgency(xcb_icccm_wm_hints_t *hints) +{ + return (hints->flags & XCB_ICCCM_WM_HINT_X_URGENCY); +} + +void +xcb_icccm_wm_hints_set_input(xcb_icccm_wm_hints_t *hints, uint8_t input) +{ + hints->input = input; + hints->flags |= XCB_ICCCM_WM_HINT_INPUT; +} + +void +xcb_icccm_wm_hints_set_iconic(xcb_icccm_wm_hints_t *hints) +{ + hints->initial_state = XCB_ICCCM_WM_STATE_ICONIC; + hints->flags |= XCB_ICCCM_WM_HINT_STATE; +} + +void +xcb_icccm_wm_hints_set_normal(xcb_icccm_wm_hints_t *hints) +{ + hints->initial_state = XCB_ICCCM_WM_STATE_NORMAL; + hints->flags |= XCB_ICCCM_WM_HINT_STATE; +} + +void +xcb_icccm_wm_hints_set_withdrawn(xcb_icccm_wm_hints_t *hints) +{ + hints->initial_state = XCB_ICCCM_WM_STATE_WITHDRAWN; + hints->flags |= XCB_ICCCM_WM_HINT_STATE; +} + +void +xcb_icccm_wm_hints_set_none(xcb_icccm_wm_hints_t *hints) +{ + hints->flags &= ~XCB_ICCCM_WM_HINT_STATE; +} + +void +xcb_icccm_wm_hints_set_icon_pixmap(xcb_icccm_wm_hints_t *hints, xcb_pixmap_t icon_pixmap) +{ + hints->icon_pixmap = icon_pixmap; + hints->flags |= XCB_ICCCM_WM_HINT_ICON_PIXMAP; +} + +void +xcb_icccm_wm_hints_set_icon_mask(xcb_icccm_wm_hints_t *hints, xcb_pixmap_t icon_mask) +{ + hints->icon_mask = icon_mask; + hints->flags |= XCB_ICCCM_WM_HINT_ICON_MASK; +} + +void +xcb_icccm_wm_hints_set_icon_window(xcb_icccm_wm_hints_t *hints, xcb_window_t icon_window) +{ + hints->icon_window = icon_window; + hints->flags |= XCB_ICCCM_WM_HINT_ICON_WINDOW; +} + +void +xcb_icccm_wm_hints_set_window_group(xcb_icccm_wm_hints_t *hints, xcb_window_t window_group) +{ + hints->window_group = window_group; + hints->flags |= XCB_ICCCM_WM_HINT_WINDOW_GROUP; +} + +void +xcb_icccm_wm_hints_set_urgency(xcb_icccm_wm_hints_t *hints) +{ + hints->flags |= XCB_ICCCM_WM_HINT_X_URGENCY; +} + +xcb_void_cookie_t +xcb_icccm_set_wm_hints_checked(xcb_connection_t *c, xcb_window_t window, + xcb_icccm_wm_hints_t *hints) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_HINTS, + XCB_ATOM_WM_HINTS, 32, sizeof(*hints) >> 2, hints); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_hints(xcb_connection_t *c, xcb_window_t window, + xcb_icccm_wm_hints_t *hints) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_HINTS, + XCB_ATOM_WM_HINTS, 32, sizeof(*hints) >> 2, hints); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_hints(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_property(c, 0, window, XCB_ATOM_WM_HINTS, XCB_ATOM_WM_HINTS, 0L, + XCB_ICCCM_NUM_WM_HINTS_ELEMENTS); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_hints_unchecked(xcb_connection_t *c, + xcb_window_t window) +{ + return xcb_get_property_unchecked(c, 0, window, XCB_ATOM_WM_HINTS, XCB_ATOM_WM_HINTS, 0L, + XCB_ICCCM_NUM_WM_HINTS_ELEMENTS); +} + +uint8_t +xcb_icccm_get_wm_hints_from_reply(xcb_icccm_wm_hints_t *hints, + xcb_get_property_reply_t *reply) +{ + if(!reply || reply->type != XCB_ATOM_WM_HINTS || reply->format != 32) + return 0; + + int length = xcb_get_property_value_length(reply); + int num_elem = length / (reply->format / 8); + + if(num_elem < XCB_ICCCM_NUM_WM_HINTS_ELEMENTS - 1) + return 0; + + if(length > sizeof(xcb_size_hints_t)) + length = sizeof(xcb_size_hints_t); + + memcpy(hints, (xcb_size_hints_t *) xcb_get_property_value(reply), length); + + if(num_elem < XCB_ICCCM_NUM_WM_HINTS_ELEMENTS) + hints->window_group = XCB_NONE; + + return 1; +} + +uint8_t +xcb_icccm_get_wm_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_wm_hints_t *hints, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + int ret = xcb_icccm_get_wm_hints_from_reply(hints, reply); + free(reply); + return ret; +} + +/* WM_PROTOCOLS */ + +xcb_void_cookie_t +xcb_icccm_set_wm_protocols_checked(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t wm_protocols, uint32_t list_len, + xcb_atom_t *list) +{ + return xcb_change_property_checked(c, XCB_PROP_MODE_REPLACE, window, + wm_protocols, XCB_ATOM_ATOM, 32, list_len, list); +} + +xcb_void_cookie_t +xcb_icccm_set_wm_protocols(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t wm_protocols, uint32_t list_len, xcb_atom_t *list) +{ + return xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, wm_protocols, + XCB_ATOM_ATOM, 32, list_len, list); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_protocols(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t wm_protocol_atom) +{ + return xcb_get_property(c, 0, window, wm_protocol_atom, XCB_ATOM_ATOM, 0, UINT_MAX); +} + +xcb_get_property_cookie_t +xcb_icccm_get_wm_protocols_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocol_atom) +{ + return xcb_get_property_unchecked(c, 0, window, wm_protocol_atom, XCB_ATOM_ATOM, 0, + UINT_MAX); +} + +uint8_t +xcb_icccm_get_wm_protocols_from_reply(xcb_get_property_reply_t *reply, xcb_icccm_get_wm_protocols_reply_t *protocols) +{ + if(!reply || reply->type != XCB_ATOM_ATOM || reply->format != 32) + return 0; + + protocols->_reply = reply; + protocols->atoms_len = xcb_get_property_value_length(protocols->_reply) / (reply->format / 8); + protocols->atoms = (xcb_atom_t *) xcb_get_property_value(protocols->_reply); + + return 1; +} + +uint8_t +xcb_icccm_get_wm_protocols_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_wm_protocols_reply_t *protocols, + xcb_generic_error_t **e) +{ + xcb_get_property_reply_t *reply = xcb_get_property_reply(c, cookie, e); + uint8_t ret = xcb_icccm_get_wm_protocols_from_reply(reply, protocols); + if(!ret) + free(reply); + return ret; +} + +void +xcb_icccm_get_wm_protocols_reply_wipe(xcb_icccm_get_wm_protocols_reply_t *protocols) +{ + free(protocols->_reply); +} diff --git a/depends/libxcb-wm/xcb/xcb_icccm.h b/depends/libxcb-wm/xcb/xcb_icccm.h new file mode 100644 index 0000000..449a5c8 --- /dev/null +++ b/depends/libxcb-wm/xcb/xcb_icccm.h @@ -0,0 +1,1049 @@ +#ifndef __XCB_ICCCM_H__ +#define __XCB_ICCCM_H__ + +/* + * Copyright (C) 2008 Arnaud Fontaine <arnau@debian.org> + * Copyright (C) 2007-2008 Vincent Torri <vtorri@univ-evry.fr> + * + * 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. + */ + +/** + * @defgroup xcb__icccm_t XCB ICCCM Functions + * + * These functions allow easy handling of the protocol described in the + * Inter-Client Communication Conventions Manual. + * + * @{ + */ + +#include <xcb/xcb.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief TextProperty reply structure. + */ +typedef struct { +/** Store reply to avoid memory allocation, should normally not be + used directly */ +xcb_get_property_reply_t *_reply; +/** Encoding used */ +xcb_atom_t encoding; +/** Length of the name field above */ +uint32_t name_len; +/** Property value */ +char *name; +/** Format, may be 8, 16 or 32 */ +uint8_t format; +} xcb_icccm_get_text_property_reply_t; + +/** + * @brief Deliver a GetProperty request to the X server. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param property Property atom to get. + * @return The request cookie. + * + * Allow to get a window property, in most case you might want to use + * above functions to get an ICCCM property for a given window. + */ +xcb_get_property_cookie_t xcb_icccm_get_text_property(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @see xcb_icccm_get_text_property() + */ +xcb_get_property_cookie_t xcb_icccm_get_text_property_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @brief Fill given structure with the property value of a window. + * @param c The connection to the X server. + * @param cookie TextProperty request cookie. + * @param prop TextProperty reply which is to be filled. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * If the function return 0 (failure), the content of prop is unmodified and + * therefore the structure must not be wiped. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_text_property_unchecked() is used. Otherwise, it stores + * the error if any. prop structure members should be freed by + * xcb_icccm_get_text_property_reply_wipe(). + */ +uint8_t xcb_icccm_get_text_property_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/** + * @brief Wipe prop structure members previously allocated by + * xcb_icccm_get_text_property_reply(). + * @param prop prop structure whose members is going to be freed. + */ +void xcb_icccm_get_text_property_reply_wipe(xcb_icccm_get_text_property_reply_t *prop); + +/* WM_NAME */ + +/** + * @brief Deliver a SetProperty request to set WM_NAME property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param encoding Encoding used for the data passed in the name parameter, the set property will also have this encoding as its type. + * @param format Encoding format. + * @param name_len Length of name value to set. + * @param name Name value to set. + */ +xcb_void_cookie_t xcb_icccm_set_wm_name_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t encoding, + uint8_t format, + uint32_t name_len, + const char *name); + +/** + * @see xcb_icccm_set_wm_name_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_name(xcb_connection_t *c, xcb_window_t window, + xcb_atom_t encoding, uint8_t format, + uint32_t name_len, const char *name); + +/** + * @brief Deliver a GetProperty request to the X server for WM_NAME. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_name(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_icccm_get_wm_name() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_name_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_NAME property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_NAME property value. + * @param e Error if any. + * @see xcb_icccm_get_text_property_reply() + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_icccm_get_wm_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/* WM_ICON_NAME */ + +/** + * @brief Deliver a SetProperty request to set WM_ICON_NAME property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param encoding Encoding used for the data passed in the name parameter, the set property will also have this encoding as its type. + * @param format Encoding format. + * @param name_len Length of name value to set. + * @param name Name value to set. + */ +xcb_void_cookie_t xcb_icccm_set_wm_icon_name_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t encoding, + uint8_t format, + uint32_t name_len, + const char *name); + +/** + * @see xcb_icccm_set_wm_icon_name_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_icon_name(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t encoding, + uint8_t format, + uint32_t name_len, + const char *name); + +/** + * @brief Send request to get WM_ICON_NAME property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_icon_name(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_icccm_get_wm_icon_name() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_icon_name_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_ICON_NAME property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_ICON_NAME property value. + * @param e Error if any. + * @see xcb_icccm_get_text_property_reply() + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_icccm_get_wm_icon_name_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/* WM_COLORMAP_WINDOWS */ + +/** + * @brief Deliver a ChangeProperty request to set WM_COLORMAP_WINDOWS property value. + * @param c The connection to the X server. + * @param wm_colormap_windows The WM_COLORMAP_WINDOWS atom + * @param window Window X identifier. + * @param list_len Windows list len. + * @param list Windows list. + * @return The request cookie. + */ +xcb_void_cookie_t xcb_icccm_set_wm_colormap_windows_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom, + uint32_t list_len, + const xcb_window_t *list); + +/** + * @see xcb_icccm_set_wm_colormap_windows_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_colormap_windows(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom, + uint32_t list_len, + const xcb_window_t *list); + +/** + * @brief WM_COLORMAP_WINDOWS structure. + */ +typedef struct { +/** Length of the windows list */ +uint32_t windows_len; +/** Windows list */ +xcb_window_t *windows; +/** Store reply to avoid memory allocation, should normally not be + used directly */ +xcb_get_property_reply_t *_reply; +} xcb_icccm_get_wm_colormap_windows_reply_t; + +/** + * @brief Send request to get WM_COLORMAP_WINDOWS property of a given window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_colormap_windows(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom); + +/** + * @see xcb_icccm_get_wm_colormap_windows() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_colormap_windows_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_colormap_windows_atom); + +/** + * @brief Fill the given structure with the WM_COLORMAP_WINDOWS property of a window. + * @param reply The reply of the GetProperty request. + * @param colormap_windows WM_COLORMAP property value. + * @return Return 1 on success, 0 otherwise. + * + * protocols structure members should be freed by + * xcb_icccm_get_wm_protocols_reply_wipe(). + */ +uint8_t xcb_icccm_get_wm_colormap_windows_from_reply(xcb_get_property_reply_t *reply, + xcb_icccm_get_wm_colormap_windows_reply_t *colormap_windows); +/** + * @brief Fill the given structure with the WM_COLORMAP_WINDOWS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param protocols WM_COLORMAP_WINDOWS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_wm_colormap_windows_unchecked() is used. Otherwise, it + * stores the error if any. protocols structure members should be + * freed by xcb_icccm_get_wm_colormap_windows_reply_wipe(). + */ +uint8_t xcb_icccm_get_wm_colormap_windows_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_wm_colormap_windows_reply_t *windows, + xcb_generic_error_t **e); + +/** + * @brief Wipe protocols structure members previously allocated by + * xcb_icccm_get_wm_colormap_windows_reply(). + * @param windows windows structure whose members is going to be freed. + */ +void xcb_icccm_get_wm_colormap_windows_reply_wipe(xcb_icccm_get_wm_colormap_windows_reply_t *windows); + +/* WM_CLIENT_MACHINE */ + +/** + * @brief Deliver a SetProperty request to set WM_CLIENT_MACHINE property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param encoding Encoding used for the data passed in the name parameter, the set property will also have this encoding as its type. + * @param format Encoding format. + * @param name_len Length of name value to set. + * @param name Name value to set. + */ +xcb_void_cookie_t xcb_icccm_set_wm_client_machine_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t encoding, + uint8_t format, + uint32_t name_len, + const char *name); + +/** + * @see xcb_icccm_set_wm_client_machine_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_client_machine(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t encoding, + uint8_t format, + uint32_t name_len, + const char *name); + +/** + * @brief Send request to get WM_CLIENT_MACHINE property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_client_machine(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_icccm_get_wm_client_machine() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_client_machine_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_CLIENT_MACHINE property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_CLIENT_MACHINE property value. + * @param e Error if any. + * @see xcb_icccm_get_text_property_reply() + * @return Return 1 on success, 0 otherwise. + */ +uint8_t xcb_icccm_get_wm_client_machine_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_text_property_reply_t *prop, + xcb_generic_error_t **e); + +/* WM_CLASS */ + +/** + * @brief WM_CLASS hint structure + */ + +/** + * @brief Deliver a SetProperty request to set WM_CLASS property value. + * + * WM_CLASS string is a concatenation of the instance and class name + * strings respectively (including null character). + * + * @param c The connection to the X server. + * @param window Window X identifier. + * @param class_len Length of WM_CLASS string. + * @param class_name WM_CLASS string. + * @return The request cookie. + */ +xcb_void_cookie_t xcb_icccm_set_wm_class_checked(xcb_connection_t *c, + xcb_window_t window, + uint32_t class_len, + const char *class_name); + +/** + * @see xcb_icccm_set_wm_class_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_class(xcb_connection_t *c, + xcb_window_t window, + uint32_t class_len, + const char *class_name); + +typedef struct { +/** Instance name */ +char *instance_name; +/** Class of application */ +char *class_name; +/** Store reply to avoid memory allocation, should normally not be + used directly */ +xcb_get_property_reply_t *_reply; +} xcb_icccm_get_wm_class_reply_t; + +/** + * @brief Deliver a GetProperty request to the X server for WM_CLASS. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_class(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_icccm_get_wm_class() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_class_unchecked(xcb_connection_t *c, + xcb_window_t window); + + +/** + * @brief Fill give structure with the WM_CLASS property of a window. + * @param prop The property structure to fill. + * @param reply The property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_icccm_get_wm_class_from_reply(xcb_icccm_get_wm_class_reply_t *prop, + xcb_get_property_reply_t *reply); + +/** + * @brief Fill given structure with the WM_CLASS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_CLASS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_wm_class_unchecked() is used. Otherwise, it stores the + * error if any. prop structure members should be freed by + * xcb_icccm_get_wm_class_reply_wipe(). + */ +uint8_t xcb_icccm_get_wm_class_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_wm_class_reply_t *prop, + xcb_generic_error_t **e); + +/** + * @brief Wipe prop structure members previously allocated by + * xcb_icccm_get_wm_class_reply(). + * @param prop prop structure whose members is going to be freed. + */ +void xcb_icccm_get_wm_class_reply_wipe(xcb_icccm_get_wm_class_reply_t *prop); + +/* WM_TRANSIENT_FOR */ + +/** + * @brief Deliver a SetProperty request to set WM_TRANSIENT_FOR property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param transient_for_window The WM_TRANSIENT_FOR window X identifier. + * @return The request cookie. + */ +xcb_void_cookie_t xcb_icccm_set_wm_transient_for_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_window_t transient_for_window); + +/** + * @see xcb_icccm_set_wm_transient_for + */ +xcb_void_cookie_t xcb_icccm_set_wm_transient_for(xcb_connection_t *c, + xcb_window_t window, + xcb_window_t transient_for_window); + +/** + * @brief Send request to get WM_TRANSIENT_FOR property of a window. + * @param c The connection to the X server + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_transient_for(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_icccm_get_wm_transient_for_unchecked() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_transient_for_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given window pointer with the WM_TRANSIENT_FOR property of a window. + * @param prop WM_TRANSIENT_FOR property value. + * @param reply The get property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_icccm_get_wm_transient_for_from_reply(xcb_window_t *prop, + xcb_get_property_reply_t *reply); +/** + * @brief Fill given structure with the WM_TRANSIENT_FOR property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param prop WM_TRANSIENT_FOR property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_wm_transient_for_unchecked() is used. Otherwise, it stores + * the error if any. + */ +uint8_t xcb_icccm_get_wm_transient_for_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_window_t *prop, + xcb_generic_error_t **e); + +/* WM_SIZE_HINTS */ + +typedef enum { +XCB_ICCCM_SIZE_HINT_US_POSITION = 1 << 0, + XCB_ICCCM_SIZE_HINT_US_SIZE = 1 << 1, + XCB_ICCCM_SIZE_HINT_P_POSITION = 1 << 2, + XCB_ICCCM_SIZE_HINT_P_SIZE = 1 << 3, + XCB_ICCCM_SIZE_HINT_P_MIN_SIZE = 1 << 4, + XCB_ICCCM_SIZE_HINT_P_MAX_SIZE = 1 << 5, + XCB_ICCCM_SIZE_HINT_P_RESIZE_INC = 1 << 6, + XCB_ICCCM_SIZE_HINT_P_ASPECT = 1 << 7, + XCB_ICCCM_SIZE_HINT_BASE_SIZE = 1 << 8, + XCB_ICCCM_SIZE_HINT_P_WIN_GRAVITY = 1 << 9 + } xcb_icccm_size_hints_flags_t; + +/** + * @brief Size hints structure. + */ +typedef struct { +/** User specified flags */ +uint32_t flags; +/** User-specified position */ +int32_t x, y; +/** User-specified size */ +int32_t width, height; +/** Program-specified minimum size */ +int32_t min_width, min_height; +/** Program-specified maximum size */ +int32_t max_width, max_height; +/** Program-specified resize increments */ +int32_t width_inc, height_inc; +/** Program-specified minimum aspect ratios */ +int32_t min_aspect_num, min_aspect_den; +/** Program-specified maximum aspect ratios */ +int32_t max_aspect_num, max_aspect_den; +/** Program-specified base size */ +int32_t base_width, base_height; +/** Program-specified window gravity */ +uint32_t win_gravity; +} xcb_size_hints_t; + +/** Number of elements in this structure */ +#define XCB_ICCCM_NUM_WM_SIZE_HINTS_ELEMENTS 18 + +/** + * @brief Set size hints to a given position. + * @param hints SIZE_HINTS structure. + * @param user_specified Is the size user-specified? + * @param x The X position. + * @param y The Y position. + */ +void xcb_icccm_size_hints_set_position(xcb_size_hints_t *hints, int user_specified, + int32_t x, int32_t y); + +/** + * @brief Set size hints to a given size. + * @param hints SIZE_HINTS structure. + * @param user_specified is the size user-specified? + * @param width The width. + * @param height The height. + */ +void xcb_icccm_size_hints_set_size(xcb_size_hints_t *hints, int user_specified, + int32_t width, int32_t height); + +/** + * @brief Set size hints to a given minimum size. + * @param hints SIZE_HINTS structure. + * @param width The minimum width. + * @param height The minimum height. + */ +void xcb_icccm_size_hints_set_min_size(xcb_size_hints_t *hints, int32_t min_width, + int32_t min_height); + +/** + * @brief Set size hints to a given maximum size. + * @param hints SIZE_HINTS structure. + * @param width The maximum width. + * @param height The maximum height. + */ +void xcb_icccm_size_hints_set_max_size(xcb_size_hints_t *hints, int32_t max_width, + int32_t max_height); + +/** + * @brief Set size hints to a given resize increments. + * @param hints SIZE_HINTS structure. + * @param width The resize increments width. + * @param height The resize increments height. + */ +void xcb_icccm_size_hints_set_resize_inc(xcb_size_hints_t *hints, int32_t width_inc, + int32_t height_inc); + +/** + * @brief Set size hints to a given aspect ratios. + * @param hints SIZE_HINTS structure. + * @param min_aspect_num The minimum aspect ratios for the width. + * @param min_aspect_den The minimum aspect ratios for the height. + * @param max_aspect_num The maximum aspect ratios for the width. + * @param max_aspect_den The maximum aspect ratios for the height. + */ +void xcb_icccm_size_hints_set_aspect(xcb_size_hints_t *hints, int32_t min_aspect_num, + int32_t min_aspect_den, int32_t max_aspect_num, + int32_t max_aspect_den); + +/** + * @brief Set size hints to a given base size. + * @param hints SIZE_HINTS structure. + * @param base_width Base width. + * @param base_height Base height. + */ +void xcb_icccm_size_hints_set_base_size(xcb_size_hints_t *hints, int32_t base_width, + int32_t base_height); + +/** + * @brief Set size hints to a given window gravity. + * @param hints SIZE_HINTS structure. + * @param win_gravity Window gravity value. + */ +void xcb_icccm_size_hints_set_win_gravity(xcb_size_hints_t *hints, + xcb_gravity_t win_gravity); + +/** + * @brief Deliver a ChangeProperty request to set a value to a given property. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param property Property to set value for. + * @param hints Hints value to set. + */ +xcb_void_cookie_t xcb_icccm_set_wm_size_hints_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property, + xcb_size_hints_t *hints); + +/** + * @see xcb_icccm_set_wm_size_hints_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_size_hints(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property, + xcb_size_hints_t *hints); + +/** + * @brief Send request to get size hints structure for the named property. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param property Specify the property name. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_size_hints(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @see xcb_icccm_get_wm_size_hints() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_size_hints_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t property); + +/** + * @brief Fill given structure with the size hints of the named property. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param hints Size hints structure. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_wm_size_hints_unchecked() is used. Otherwise, it stores + * the error if any. The returned pointer should be freed. + */ +uint8_t xcb_icccm_get_wm_size_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, + xcb_generic_error_t **e); + +/* WM_NORMAL_HINTS */ + +/** + * @brief Deliver a ChangeProperty request to set WM_NORMAL_HINTS property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param hints Hints value to set. + */ +xcb_void_cookie_t xcb_icccm_set_wm_normal_hints_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_size_hints_t *hints); + +/** + * @see xcb_icccm_set_wm_normal_hints_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_normal_hints(xcb_connection_t *c, + xcb_window_t window, + xcb_size_hints_t *hints); + +/** + * @brief Send request to get WM_NORMAL_HINTS property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_normal_hints(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_icccm_get_wm_normal_hints() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_normal_hints_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_NORMAL_HINTS property of a window. + * @param hints WM_NORMAL_HINTS property value. + * @param reply The get property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_icccm_get_wm_size_hints_from_reply(xcb_size_hints_t *hints, + xcb_get_property_reply_t *reply); + +/** + * @brief Fill given structure with the WM_NORMAL_HINTS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param hints WM_NORMAL_HINTS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_wm_normal_hints_unchecked() is used. Otherwise, it stores + * the error if any. The returned pointer should be freed. + */ +uint8_t xcb_icccm_get_wm_normal_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_size_hints_t *hints, + xcb_generic_error_t **e); + +/* WM_HINTS */ + +/** + * @brief WM hints structure (may be extended in the future). + */ +typedef struct { +/** Marks which fields in this structure are defined */ +int32_t flags; +/** Does this application rely on the window manager to get keyboard + input? */ + uint32_t input; + /** See below */ + int32_t initial_state; + /** Pixmap to be used as icon */ + xcb_pixmap_t icon_pixmap; + /** Window to be used as icon */ + xcb_window_t icon_window; + /** Initial position of icon */ + int32_t icon_x, icon_y; + /** Icon mask bitmap */ + xcb_pixmap_t icon_mask; + /* Identifier of related window group */ + xcb_window_t window_group; +} xcb_icccm_wm_hints_t; + +/** Number of elements in this structure */ +#define XCB_ICCCM_NUM_WM_HINTS_ELEMENTS 9 + +/** + * @brief WM_HINTS window states. + */ +typedef enum { + XCB_ICCCM_WM_STATE_WITHDRAWN = 0, + XCB_ICCCM_WM_STATE_NORMAL = 1, + XCB_ICCCM_WM_STATE_ICONIC = 3 +} xcb_icccm_wm_state_t; + +typedef enum { + XCB_ICCCM_WM_HINT_INPUT = (1L << 0), + XCB_ICCCM_WM_HINT_STATE = (1L << 1), + XCB_ICCCM_WM_HINT_ICON_PIXMAP = (1L << 2), + XCB_ICCCM_WM_HINT_ICON_WINDOW = (1L << 3), + XCB_ICCCM_WM_HINT_ICON_POSITION = (1L << 4), + XCB_ICCCM_WM_HINT_ICON_MASK = (1L << 5), + XCB_ICCCM_WM_HINT_WINDOW_GROUP = (1L << 6), + XCB_ICCCM_WM_HINT_X_URGENCY = (1L << 8) +} xcb_icccm_wm_t; + +#define XCB_ICCCM_WM_ALL_HINTS (XCB_ICCCM_WM_HINT_INPUT | XCB_ICCCM_WM_HINT_STATE | \ + XCB_ICCCM_WM_HINT_ICON_PIXMAP | XCB_ICCCM_WM_HINT_ICON_WINDOW | \ + XCB_ICCCM_WM_HINT_ICON_POSITION | XCB_ICCCM_WM_HINT_ICON_MASK | \ + XCB_ICCCM_WM_HINT_WINDOW_GROUP) + +/** + * @brief Get urgency hint. + * @param hints WM_HINTS structure. + * @return Urgency hint value. + */ +uint32_t xcb_icccm_wm_hints_get_urgency(xcb_icccm_wm_hints_t *hints); + +/** + * @brief Set input focus. + * @param hints WM_HINTS structure. + * @param input Input focus. + */ +void xcb_icccm_wm_hints_set_input(xcb_icccm_wm_hints_t *hints, uint8_t input); + +/** + * @brief Set hints state to 'iconic'. + * @param hints WM_HINTS structure. + */ +void xcb_icccm_wm_hints_set_iconic(xcb_icccm_wm_hints_t *hints); + +/** + * @brief Set hints state to 'normal'. + * @param hints WM_HINTS structure. + */ +void xcb_icccm_wm_hints_set_normal(xcb_icccm_wm_hints_t *hints); + +/** + * @brief Set hints state to 'withdrawn'. + * @param hints WM_HINTS structure. + */ +void xcb_icccm_wm_hints_set_withdrawn(xcb_icccm_wm_hints_t *hints); + +/** + * @brief Set hints state to none. + * @param hints WM_HINTS structure. + */ +void xcb_icccm_wm_hints_set_none(xcb_icccm_wm_hints_t *hints); + +/** + * @brief Set pixmap to be used as icon. + * @param hints WM_HINTS structure. + * @param icon_pixmap Pixmap. + */ +void xcb_icccm_wm_hints_set_icon_pixmap(xcb_icccm_wm_hints_t *hints, + xcb_pixmap_t icon_pixmap); + +/** + * @brief Set icon mask bitmap. + * @param hints WM_HINTS structure. + * @param icon_mask Pixmap. + */ +void xcb_icccm_wm_hints_set_icon_mask(xcb_icccm_wm_hints_t *hints, xcb_pixmap_t icon_mask); + +/** + * @brief Set window identifier to be used as icon. + * @param hints WM_HINTS structure. + * @param icon_window Window X identifier. + */ +void xcb_icccm_wm_hints_set_icon_window(xcb_icccm_wm_hints_t *hints, + xcb_window_t icon_window); + +/** + * @brief Set identifier of related window group. + * @param hints WM_HINTS structure. + * @param window_group Window X identifier. + */ +void xcb_icccm_wm_hints_set_window_group(xcb_icccm_wm_hints_t *hints, + xcb_window_t window_group); + +/** + * @brief Set urgency hints flag. + * @param hints WM_HINTS structure. + */ +void xcb_icccm_wm_hints_set_urgency(xcb_icccm_wm_hints_t *hints); + +/** + * @brief Deliver a SetProperty request to set WM_HINTS property value. + * @param c The connection to the X server. + * @param window Window X identifier. + * @param hints Hints value to set. + */ +xcb_void_cookie_t xcb_icccm_set_wm_hints_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_icccm_wm_hints_t *hints); + +/** + * @see xcb_icccm_set_wm_hints_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_hints(xcb_connection_t *c, + xcb_window_t window, + xcb_icccm_wm_hints_t *hints); + +/** + * @brief Send request to get WM_HINTS property of a window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_hints(xcb_connection_t *c, + xcb_window_t window); + +/** + * @see xcb_icccm_get_wm_hints() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_hints_unchecked(xcb_connection_t *c, + xcb_window_t window); + +/** + * @brief Fill given structure with the WM_HINTS property of a window. + * @param hints WM_HINTS property value. + * @param reply The get property request reply. + * @return Return 1 on success, 0 otherwise. + */ +uint8_t +xcb_icccm_get_wm_hints_from_reply(xcb_icccm_wm_hints_t *hints, + xcb_get_property_reply_t *reply); + +/** + * @brief Fill given structure with the WM_HINTS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param hints WM_HINTS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_wm_hints_unchecked() is used. Otherwise, it stores the + * error if any. The returned pointer should be freed. + */ +uint8_t xcb_icccm_get_wm_hints_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_wm_hints_t *hints, + xcb_generic_error_t **e); + +/* WM_PROTOCOLS */ + +/** + * @brief Deliver a SetProperty request to set WM_PROTOCOLS property value. + * @param c The connection to the X server. + * @param wm_protocols The WM_PROTOCOLS atom. + * @param window Window X identifier. + * @param list_len Atom list len. + * @param list Atom list. + */ +xcb_void_cookie_t xcb_icccm_set_wm_protocols_checked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocols, + uint32_t list_len, + xcb_atom_t *list); + +/** + * @see xcb_icccm_set_wm_protocols_checked() + */ +xcb_void_cookie_t xcb_icccm_set_wm_protocols(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocols, + uint32_t list_len, + xcb_atom_t *list); + +/** + * @brief WM_PROTOCOLS structure. + */ +typedef struct { + /** Length of the atoms list */ + uint32_t atoms_len; + /** Atoms list */ + xcb_atom_t *atoms; + /** Store reply to avoid memory allocation, should normally not be + used directly */ + xcb_get_property_reply_t *_reply; +} xcb_icccm_get_wm_protocols_reply_t; + +/** + * @brief Send request to get WM_PROTOCOLS property of a given window. + * @param c The connection to the X server. + * @param window Window X identifier. + * @return The request cookie. + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_protocols(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocol_atom); + +/** + * @see xcb_icccm_get_wm_protocols() + */ +xcb_get_property_cookie_t xcb_icccm_get_wm_protocols_unchecked(xcb_connection_t *c, + xcb_window_t window, + xcb_atom_t wm_protocol_atom); + +/** + * @brief Fill the given structure with the WM_PROTOCOLS property of a window. + * @param reply The reply of the GetProperty request. + * @param protocols WM_PROTOCOLS property value. + * @return Return 1 on success, 0 otherwise. + * + * protocols structure members should be freed by + * xcb_icccm_get_wm_protocols_reply_wipe(). + */ +uint8_t xcb_icccm_get_wm_protocols_from_reply(xcb_get_property_reply_t *reply, + xcb_icccm_get_wm_protocols_reply_t *protocols); +/** + * @brief Fill the given structure with the WM_PROTOCOLS property of a window. + * @param c The connection to the X server. + * @param cookie Request cookie. + * @param protocols WM_PROTOCOLS property value. + * @param e Error if any. + * @return Return 1 on success, 0 otherwise. + * + * The parameter e supplied to this function must be NULL if + * xcb_icccm_get_wm_protocols_unchecked() is used. Otherwise, it stores the + * error if any. protocols structure members should be freed by + * xcb_icccm_get_wm_protocols_reply_wipe(). + */ +uint8_t xcb_icccm_get_wm_protocols_reply(xcb_connection_t *c, + xcb_get_property_cookie_t cookie, + xcb_icccm_get_wm_protocols_reply_t *protocols, + xcb_generic_error_t **e); + +/** + * @brief Wipe protocols structure members previously allocated by + * xcb_icccm_get_wm_protocols_reply(). + * @param protocols protocols structure whose members is going to be freed. + */ +void xcb_icccm_get_wm_protocols_reply_wipe(xcb_icccm_get_wm_protocols_reply_t *protocols); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __XCB_ICCCM_H__ */ |