aboutsummaryrefslogtreecommitdiff
path: root/depends
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2023-12-13 20:17:13 +0100
committerdec05eba <dec05eba@protonmail.com>2023-12-13 20:36:41 +0100
commitbc5a4cf5fcc70e30028ff8fa91dca075896b2764 (patch)
tree24b7fe9cc18a8deb3b30ee6f1265152ba8ad628f /depends
parent4d639d934ec56b53e8f4776a7a0794f05b5451b6 (diff)
Include all libxcb utils (wm, util, image, errors, cursor)
Diffstat (limited to 'depends')
-rw-r--r--depends/libxcb-cursor/xcb/cursor.c179
-rw-r--r--depends/libxcb-cursor/xcb/cursor.h169
-rw-r--r--depends/libxcb-cursor/xcb/load_cursor.c290
-rw-r--r--depends/libxcb-cursor/xcb/parse_cursor_file.c198
-rw-r--r--depends/libxcb-cursor/xcb/xcb_cursor.h124
-rw-r--r--depends/libxcb-errors/xcb/errors.h50
-rw-r--r--depends/libxcb-errors/xcb/xcb_errors.c291
-rw-r--r--depends/libxcb-errors/xcb/xcb_errors.h157
-rw-r--r--depends/libxcb-image/config.h76
-rw-r--r--depends/libxcb-image/xcb/xcb_bitops.h212
-rw-r--r--depends/libxcb-image/xcb/xcb_image.c1013
-rw-r--r--depends/libxcb-image/xcb/xcb_image.h628
-rw-r--r--depends/libxcb-image/xcb/xcb_pixel.h171
-rw-r--r--depends/libxcb-util/config.h76
-rw-r--r--depends/libxcb-util/xcb/atoms.c87
-rw-r--r--depends/libxcb-util/xcb/event.c259
-rw-r--r--depends/libxcb-util/xcb/xcb_atom.h18
-rw-r--r--depends/libxcb-util/xcb/xcb_aux.c378
-rw-r--r--depends/libxcb-util/xcb/xcb_aux.h214
-rw-r--r--depends/libxcb-util/xcb/xcb_event.h90
-rw-r--r--depends/libxcb-util/xcb/xcb_util.h8
-rw-r--r--depends/libxcb-wm/config.h73
-rw-r--r--depends/libxcb-wm/xcb/icccm.c849
-rw-r--r--depends/libxcb-wm/xcb/xcb_icccm.h1049
24 files changed, 6659 insertions, 0 deletions
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__ */