]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/x11prop.c
Make tests compile on FreeBSD
[pulseaudio] / src / pulsecore / x11prop.c
index 873a76e7d4ef6468663ff03094d48fd1070a3c9d..0fa30a3ffe78a2c085d4cb6c161f673985082ed0 100644 (file)
 
 #include <string.h>
 
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-
 #include "x11prop.h"
 
-void pa_x11_set_prop(Display *d, const char *name, const char *data) {
-    Atom a = XInternAtom(d, name, False);
-    XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, (int) (strlen(data)+1));
+#include <pulsecore/macro.h>
+
+#include <xcb/xproto.h>
+
+#define PA_XCB_FORMAT 8
+
+static xcb_screen_t *screen_of_display(xcb_connection_t *xcb, int screen) {
+    const xcb_setup_t *s;
+    xcb_screen_iterator_t iter;
+
+    if ((s = xcb_get_setup(xcb))) {
+        iter = xcb_setup_roots_iterator(s);
+        for (; iter.rem; --screen, xcb_screen_next(&iter))
+            if (0 == screen)
+                return iter.data;
+    }
+    return NULL;
 }
 
-void pa_x11_del_prop(Display *d, const char *name) {
-    Atom a = XInternAtom(d, name, False);
-    XDeleteProperty(d, RootWindow(d, 0), a);
+void pa_x11_set_prop(xcb_connection_t *xcb, int screen, const char *name, const char *data) {
+    xcb_screen_t *xs;
+    xcb_intern_atom_reply_t *reply;
+
+    pa_assert(xcb);
+    pa_assert(name);
+    pa_assert(data);
+
+    if ((xs = screen_of_display(xcb, screen))) {
+        reply = xcb_intern_atom_reply(xcb,
+                                      xcb_intern_atom(xcb, 0, strlen(name), name),
+                                      NULL);
+
+        if (reply) {
+            xcb_change_property(xcb, XCB_PROP_MODE_REPLACE, xs->root, reply->atom,
+                                XCB_ATOM_STRING, PA_XCB_FORMAT,
+                                (int) strlen(data), (const void*) data);
+
+            free(reply);
+        }
+    }
 }
 
-char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) {
-    Atom actual_type;
-    int actual_format;
-    unsigned long nitems;
-    unsigned long nbytes_after;
-    unsigned char *prop = NULL;
-    char *ret = NULL;
+void pa_x11_del_prop(xcb_connection_t *xcb, int screen, const char *name) {
+    xcb_screen_t *xs;
+    xcb_intern_atom_reply_t *reply;
 
-    Atom a = XInternAtom(d, name, False);
-    if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (long) ((l+2)/4), False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success)
-        goto finish;
+    pa_assert(xcb);
+    pa_assert(name);
 
-    if (actual_type != XA_STRING)
-        goto finish;
+    if ((xs = screen_of_display(xcb, screen))) {
+        reply = xcb_intern_atom_reply(xcb,
+                                      xcb_intern_atom(xcb, 0, strlen(name), name),
+                                      NULL);
 
-    memcpy(p, prop, nitems);
-    p[nitems] = 0;
+        if (reply) {
+            xcb_delete_property(xcb, xs->root, reply->atom);
+            free(reply);
+        }
+    }
+}
 
-    ret = p;
+char* pa_x11_get_prop(xcb_connection_t *xcb, int screen, const char *name, char *p, size_t l) {
+    char *ret = NULL;
+    int len;
+    xcb_get_property_cookie_t req;
+    xcb_get_property_reply_t* prop = NULL;
+    xcb_screen_t *xs;
+    xcb_intern_atom_reply_t *reply;
+
+    pa_assert(xcb);
+    pa_assert(name);
+    pa_assert(p);
+
+    xs = screen_of_display(xcb, screen);
+    /*
+     * Also try and get the settings from the first screen.
+     * This allows for e.g. a Media Center to run on screen 1 (e.g. HDMI) and have
+     * different defaults (e.g. prefer the HDMI sink) than the primary screen 0
+     * which uses the Internal Audio sink.
+     */
+    if (!xs && 0 != screen)
+        xs = screen_of_display(xcb, 0);
+
+    if (xs) {
+        reply = xcb_intern_atom_reply(xcb,
+                                      xcb_intern_atom(xcb, 0, strlen(name), name),
+                                      NULL);
+
+        if (!reply)
+            goto finish;
+
+        req = xcb_get_property(xcb, 0, xs->root, reply->atom, XCB_ATOM_STRING, 0, (uint32_t)(l-1));
+        free(reply);
+        prop = xcb_get_property_reply(xcb, req, NULL);
+
+        if (!prop)
+            goto finish;
+
+        if (PA_XCB_FORMAT != prop->format)
+            goto finish;
+
+        len = xcb_get_property_value_length(prop);
+        if (len < 1 || len >= (int)l)
+            goto finish;
+
+        memcpy(p, xcb_get_property_value(prop), len);
+        p[len] = 0;
+
+        ret = p;
+    }
 
 finish:
 
     if (prop)
-        XFree(prop);
+        free(prop);
 
     return ret;
 }