Branch data Line data Source code
1 : : /***
2 : : This file is part of PulseAudio.
3 : :
4 : : Copyright 2004-2006 Lennart Poettering
5 : :
6 : : PulseAudio is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU Lesser General Public License as published
8 : : by the Free Software Foundation; either version 2.1 of the License,
9 : : or (at your option) any later version.
10 : :
11 : : PulseAudio is distributed in the hope that it will be useful, but
12 : : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU Lesser General Public License
17 : : along with PulseAudio; if not, write to the Free Software
18 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 : : USA.
20 : : ***/
21 : :
22 : : #ifdef HAVE_CONFIG_H
23 : : #include <config.h>
24 : : #endif
25 : :
26 : : #include <string.h>
27 : :
28 : : #include "x11prop.h"
29 : :
30 : : #include <pulsecore/macro.h>
31 : :
32 : : #include <xcb/xproto.h>
33 : :
34 : : #define PA_XCB_FORMAT 8
35 : :
36 : 0 : static xcb_screen_t *screen_of_display(xcb_connection_t *xcb, int screen) {
37 : : const xcb_setup_t *s;
38 : : xcb_screen_iterator_t iter;
39 : :
40 [ # # ]: 0 : if ((s = xcb_get_setup(xcb))) {
41 : 0 : iter = xcb_setup_roots_iterator(s);
42 [ # # ]: 0 : for (; iter.rem; --screen, xcb_screen_next(&iter))
43 [ # # ]: 0 : if (0 == screen)
44 : 0 : return iter.data;
45 : : }
46 : : return NULL;
47 : : }
48 : :
49 : 0 : void pa_x11_set_prop(xcb_connection_t *xcb, int screen, const char *name, const char *data) {
50 : : xcb_screen_t *xs;
51 : : xcb_intern_atom_reply_t *reply;
52 : :
53 [ # # ]: 0 : pa_assert(xcb);
54 [ # # ]: 0 : pa_assert(name);
55 [ # # ]: 0 : pa_assert(data);
56 : :
57 [ # # ]: 0 : if ((xs = screen_of_display(xcb, screen))) {
58 : 0 : reply = xcb_intern_atom_reply(xcb,
59 : 0 : xcb_intern_atom(xcb, 0, strlen(name), name),
60 : : NULL);
61 : :
62 [ # # ]: 0 : if (reply) {
63 : 0 : xcb_change_property(xcb, XCB_PROP_MODE_REPLACE, xs->root, reply->atom,
64 : : XCB_ATOM_STRING, PA_XCB_FORMAT,
65 : 0 : (int) strlen(data), (const void*) data);
66 : :
67 : 0 : free(reply);
68 : : }
69 : : }
70 : 0 : }
71 : :
72 : 0 : void pa_x11_del_prop(xcb_connection_t *xcb, int screen, const char *name) {
73 : : xcb_screen_t *xs;
74 : : xcb_intern_atom_reply_t *reply;
75 : :
76 [ # # ]: 0 : pa_assert(xcb);
77 [ # # ]: 0 : pa_assert(name);
78 : :
79 [ # # ]: 0 : if ((xs = screen_of_display(xcb, screen))) {
80 : 0 : reply = xcb_intern_atom_reply(xcb,
81 : 0 : xcb_intern_atom(xcb, 0, strlen(name), name),
82 : : NULL);
83 : :
84 [ # # ]: 0 : if (reply) {
85 : 0 : xcb_delete_property(xcb, xs->root, reply->atom);
86 : 0 : free(reply);
87 : : }
88 : : }
89 : 0 : }
90 : :
91 : 0 : char* pa_x11_get_prop(xcb_connection_t *xcb, int screen, const char *name, char *p, size_t l) {
92 : 0 : char *ret = NULL;
93 : : int len;
94 : : xcb_get_property_cookie_t req;
95 : 0 : xcb_get_property_reply_t* prop = NULL;
96 : : xcb_screen_t *xs;
97 : : xcb_intern_atom_reply_t *reply;
98 : :
99 [ # # ]: 0 : pa_assert(xcb);
100 [ # # ]: 0 : pa_assert(name);
101 [ # # ]: 0 : pa_assert(p);
102 : :
103 : :
104 : 0 : xs = screen_of_display(xcb, screen);
105 : : /*
106 : : * Also try and get the settings from the first screen.
107 : : * This allows for e.g. a Media Center to run on screen 1 (e.g. HDMI) and have
108 : : * different defaults (e.g. prefer the HDMI sink) than the primary screen 0
109 : : * which uses the Internal Audio sink.
110 : : */
111 [ # # ]: 0 : if (!xs && 0 != screen)
112 : 0 : xs = screen_of_display(xcb, 0);
113 : :
114 [ # # ]: 0 : if (xs) {
115 : 0 : reply = xcb_intern_atom_reply(xcb,
116 : 0 : xcb_intern_atom(xcb, 0, strlen(name), name),
117 : : NULL);
118 : :
119 [ # # ]: 0 : if (!reply)
120 : : goto finish;
121 : :
122 : 0 : req = xcb_get_property(xcb, 0, xs->root, reply->atom, XCB_ATOM_STRING, 0, (uint32_t)(l-1));
123 : 0 : free(reply);
124 : 0 : prop = xcb_get_property_reply(xcb, req, NULL);
125 : :
126 [ # # ]: 0 : if (!prop)
127 : : goto finish;
128 : :
129 [ # # ]: 0 : if (PA_XCB_FORMAT != prop->format)
130 : : goto finish;
131 : :
132 : 0 : len = xcb_get_property_value_length(prop);
133 [ # # ][ # # ]: 0 : if (len < 1 || len >= (int)l)
134 : : goto finish;
135 : :
136 : 0 : memcpy(p, xcb_get_property_value(prop), len);
137 : 0 : p[len] = 0;
138 : :
139 : 0 : ret = p;
140 : : }
141 : :
142 : : finish:
143 : :
144 [ # # ]: 0 : if (prop)
145 : 0 : free(prop);
146 : :
147 : 0 : return ret;
148 : : }
|