[Xcb-commit] xcb/util-cursor: 2 commits - cursor

Michael Stapelberg stapelberg at kemper.freedesktop.org
Thu Sep 19 21:20:20 PDT 2013


 cursor/cursor.c      |   27 +++++++++++++++++++++------
 cursor/cursor.h      |   11 +++++++++--
 cursor/load_cursor.c |    6 +++---
 3 files changed, 33 insertions(+), 11 deletions(-)

New commits:
commit 7de51b81885a3b6dbb719a63f776783c0e307ab7
Author: Uli Schlachter <psychon at znc.in>
Date:   Thu Sep 19 18:08:20 2013 +0200

    Check exact RENDER version that the server supports
    
    RENDER's CreateCursor request was added in version 0.5 and CreateAnimCursor was
    added in version 0.8. Hence, just having the RENDER extension is not enough and
    we need to check the exact version that the server provides.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/cursor/cursor.c b/cursor/cursor.c
index fd75ba9..2f56f19 100644
--- a/cursor/cursor.c
+++ b/cursor/cursor.c
@@ -126,6 +126,7 @@ int xcb_cursor_context_new(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cur
     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;
@@ -133,15 +134,17 @@ int xcb_cursor_context_new(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cur
     c = *ctx;
     c->conn = conn;
     c->root = screen->root;
+    c->render_version = RV_NONE;
 
     ext = xcb_get_extension_data(conn, &xcb_render_id);
-    c->render_present = (ext && ext->present);
 
     // 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 (c->render_present)
+    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");
 
@@ -149,7 +152,15 @@ int xcb_cursor_context_new(xcb_connection_t *conn, xcb_screen_t *screen, xcb_cur
     parse_resource_manager(c, rm_reply);
     free(rm_reply);
 
-    if (c->render_present) {
+    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);
     }
diff --git a/cursor/cursor.h b/cursor/cursor.h
index 09ab395..455dc34 100644
--- a/cursor/cursor.h
+++ b/cursor/cursor.h
@@ -29,7 +29,6 @@
 #ifndef CURSOR_H
 #define CURSOR_H
 
-#include <stdbool.h>
 #include <xcb/render.h>
 
 #include "xcb_cursor.h"
@@ -41,6 +40,14 @@ enum {
     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;
@@ -62,7 +69,7 @@ struct xcb_cursor_context_t {
     const char *home;
     const char *path;
 
-    bool render_present;
+    enum render_version render_version;
 };
 
 /*
diff --git a/cursor/load_cursor.c b/cursor/load_cursor.c
index 43cd7a5..914950a 100644
--- a/cursor/load_cursor.c
+++ b/cursor/load_cursor.c
@@ -196,7 +196,7 @@ xcb_cursor_t xcb_cursor_load_cursor(xcb_cursor_context_t *c, const char *name) {
 
     // NB: if !render_present, fd will be -1 and thus the next if statement
     // will trigger the fallback.
-    if (c->render_present) {
+    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);
 
@@ -264,8 +264,8 @@ xcb_cursor_t xcb_cursor_load_cursor(xcb_cursor_context_t *c, const char *name) {
     xcb_free_gc(c->conn, gc);
     free(images);
 
-    if (nimg == 1) {
-        /* non-animated cursor */
+    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);
commit 8f3279a2b3711b6f311c5a31d77c6a8c05c4c3ac
Author: Uli Schlachter <psychon at znc.in>
Date:   Thu Sep 19 17:47:22 2013 +0200

    Fix memleak with broken resource databases
    
    If someone e.g. defines Xcursor.theme twice in the resource information, this
    would cause c->rm[RM_XCURSOR_THEME] to be set via strdup() twice which means
    that the first pointer is leaked.
    
    Fix this by freeing the old value in this case.
    
    Signed-off-by: Uli Schlachter <psychon at znc.in>

diff --git a/cursor/cursor.c b/cursor/cursor.c
index 24999e0..fd75ba9 100644
--- a/cursor/cursor.c
+++ b/cursor/cursor.c
@@ -73,12 +73,16 @@ static void parse_resource_manager(xcb_cursor_context_t *c, const xcb_get_proper
             sep++;
         /* strdup() may return NULL, which is interpreted later as the key not
          * being available. */
-        if (strcmp(line, "Xcursor.theme") == 0)
+        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)
+        } 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)
+        } else if (strcmp(line, "Xft.dpi") == 0) {
+            free(c->rm[RM_XFT_DPI]);
             c->rm[RM_XFT_DPI] = strdup(sep);
+        }
     }
 
     free(rm);


More information about the xcb-commit mailing list