tAdd functions to deal with window properties (atoms) - libwm - X windows manipulation library
 (HTM) git clone git://z3bra.org/libwm
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit d9e5eeb099b33941fec3c257e5051cd5ce03da53
 (DIR) parent ead66d8b2d01d853ac9b27fa4bb6f6120433b71d
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Mon, 28 Oct 2019 18:44:30 +0100
       
       Add functions to deal with window properties (atoms)
       
       Diffstat:
         M libwm.c                             |      77 +++++++++++++++++++++++--------
         M wm.h                                |      18 ++++++++++++++----
       
       2 files changed, 72 insertions(+), 23 deletions(-)
       ---
 (DIR) diff --git a/libwm.c b/libwm.c
       t@@ -176,34 +176,67 @@ wm_get_attribute(xcb_window_t wid, int attr)
                return attr;
        }
        
       -int
       -wm_get_atom_string(xcb_window_t wid, xcb_atom_t atom, char **value)
       +xcb_atom_t
       +wm_add_atom(xcb_atom_t type, char *name, size_t len)
        {
       -        int len;
       -        xcb_get_property_cookie_t cookie;
       -        xcb_get_property_reply_t *reply;
       +        xcb_atom_t atom;
       +        xcb_intern_atom_cookie_t c;
       +        xcb_intern_atom_reply_t *r;
        
       -        cookie = xcb_get_property(conn, 0, wid, atom, XCB_ATOM_STRING, 0, 0);
       -        reply = xcb_get_property_reply(conn, cookie, NULL);
       +        c = xcb_intern_atom(conn, 0, len, name);
       +        r = xcb_intern_atom_reply(conn, c, NULL);
       +        if (!r)
       +                return 0;
        
       -        if (reply == NULL) {
       -                free(reply);
       -                *value = NULL;
       -                return -1;
       -        }
       +        atom = r->atom;
       +        free(r);
        
       -        len = xcb_get_property_value_length(reply);
       -        *value = realloc(value, len);
       +        return atom;
       +}
       +
       +int
       +wm_set_atom(xcb_window_t wid, xcb_atom_t atom, xcb_atom_t type, size_t len, void *data)
       +{
       +        xcb_void_cookie_t c;
       +        xcb_generic_error_t *e;
        
       -        if (value == NULL)
       +        c = xcb_change_property_checked(conn, XCB_PROP_MODE_REPLACE,
       +                wid, atom, type, 32, len, data);
       +        e = xcb_request_check(conn, c);
       +        if (!e)
                        return -1;
        
       -        *value = (char*)xcb_get_property_value(reply);
       -        free(reply);
       +        free(e);
        
                return 0;
        }
        
       +void *
       +wm_get_atom(xcb_window_t wid, xcb_atom_t atom, xcb_atom_t type, size_t *len)
       +{
       +        void *d;
       +        size_t n;
       +        xcb_get_property_cookie_t c;
       +        xcb_get_property_reply_t *r;
       +
       +        c = xcb_get_property(conn, 0, wid, atom, type, 0, 1);
       +        r = xcb_get_property_reply(conn, c, NULL);
       +        if (!r)
       +                return NULL;
       +
       +        if (!(n = xcb_get_property_value_length(r))) {
       +                free(r);
       +                return NULL;
       +        }
       +
       +        if (len)
       +                *len = n;
       +
       +        d = xcb_get_property_value(r);
       +
       +        return d;
       +}
       +
        int
        wm_get_cursor(int mode, uint32_t wid, int *x, int *y)
        {
       t@@ -384,9 +417,15 @@ wm_resize(xcb_window_t wid, int mode, int w, int h)
        }
        
        int
       -wm_restack(xcb_window_t wid, uint32_t mode)
       +wm_restack(xcb_window_t wid, uint32_t mode, xcb_window_t sibling)
        {
       -        uint32_t values[1] = { mode };
       +        uint32_t r = 0, mask = 0, values[2];
       +        if (sibling) {
       +                mask |= XCB_CONFIG_WINDOW_SIBLING;
       +                values[r++] = sibling;
       +        }
       +        mask |= XCB_CONFIG_WINDOW_STACK_MODE;
       +        values[r++] = mode;
                xcb_configure_window(conn, wid, XCB_CONFIG_WINDOW_STACK_MODE, values);
                return 0;
        }
 (DIR) diff --git a/wm.h b/wm.h
       t@@ -92,10 +92,20 @@ int wm_is_listable(xcb_window_t wid, int mask);
        int wm_is_mapped(xcb_window_t wid);
        
        /*
       - * Fills the given pointer with the value of the atom for the given window
       - * Returns -1 if a value can't be retrieved
       + * Request the X server to add a new atom, and return this new atom ID
         */
       -int wm_get_atom_string(xcb_window_t wid, xcb_atom_t atom, char **value);
       +xcb_atom_t wm_add_atom(xcb_atom_t type, char *name, size_t len);
       +
       +/*
       + * Change the value of the specified atom
       + */
       +int wm_set_atom(xcb_window_t wid, xcb_atom_t atom, xcb_atom_t type, size_t len, void *data);
       +
       +/*
       + * Retrieve the value of the given atom. The value length is set in the
       + * `len` pointer if specified
       + */
       +void *wm_get_atom(xcb_window_t wid, xcb_atom_t atom, xcb_atom_t type, size_t *len);
        
        /*
         * Get the first screen, and set the `scrn` global variable accordingly.
       t@@ -201,7 +211,7 @@ int wm_remap(xcb_window_t wid, int mode);
         *         XCB_STACK_MODE_BELOW
         *         XCB_STACK_MODE_OPPOSITE
         */
       -int wm_restack(xcb_window_t wid, uint32_t mode);
       +int wm_restack(xcb_window_t wid, uint32_t mode, xcb_window_t sibling);
        
        /*
         * Register the given event(s) on the window.