├── .gitignore
├── Makefile
├── README.md
├── demo.png
├── libpulse.deps
├── libpulse.vapi
├── meson.build
├── src
├── App.vala
├── Nodes.vala
└── Pulse.vala
└── subprojects
├── .gitignore
└── libgtkflow.wrap
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | .gdb_history
3 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | run: build
2 | G_DEBUG=fatal-criticals gdb -ex run --args build/pulse-flow
3 |
4 | build: configure
5 | ninja -C build
6 |
7 | configure:
8 | [ -f build/build.ninja ] || meson ./build
9 |
10 | clean:
11 | ninja -C build clean
12 |
13 | .PHONY: run build configure clean
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # pulse-flow
2 |
3 | A pulseaudio configuration tool
4 |
5 | 
6 |
7 | ### Dependencies
8 | - [meson (build)](http://mesonbuild.com)
9 |
10 | ### Run
11 | ```
12 | $ git clone https://github.com/benwaffle/pulse-flow.git
13 | $ cd pulse-flow
14 | $ meson build
15 | $ ninja -C build
16 | $ build/pulse-flow
17 | ```
18 |
--------------------------------------------------------------------------------
/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/benwaffle/pulse-flow/3588c5859de016ae776a3beb8d0eda9492aea432/demo.png
--------------------------------------------------------------------------------
/libpulse.deps:
--------------------------------------------------------------------------------
1 | posix
2 |
--------------------------------------------------------------------------------
/libpulse.vapi:
--------------------------------------------------------------------------------
1 | /***
2 | This file is part of PulseAudio.
3 |
4 | Copyright 2009 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, see .
18 | ***/
19 |
20 | using GLib;
21 | using Posix;
22 |
23 | [CCode (cheader_filename="pulse/pulseaudio.h")]
24 | namespace PulseAudio {
25 |
26 | [CCode (cname="pa_get_library_version")]
27 | public unowned string get_library_version();
28 |
29 | [CCode (cname="PA_API_VERSION")]
30 | public const int API_VERSION;
31 |
32 | [CCode (cname="PA_PROTOCOL_VERSION")]
33 | public const int PROTOCOL_VERSION;
34 |
35 | [CCode (cname="PA_MAJOR")]
36 | public const int MAJOR;
37 |
38 | [CCode (cname="PA_MINOR")]
39 | public const int MINOR;
40 |
41 | [CCode (cname="PA_MICRO")]
42 | public const int MICRO;
43 |
44 | [CCode (cname="PA_CHECK_VERSION")]
45 | public bool CHECK_VERSION(int major, int minor, int micro);
46 |
47 | [CCode (cname="PA_INVALID_INDEX")]
48 | public const uint32 INVALID_INDEX;
49 |
50 | [CCode (cname="pa_free_cb_t", has_target=false)]
51 | public delegate void FreeCb(void *p);
52 |
53 | [CCode (cname="pa_sample_format_t", cprefix="PA_SAMPLE_", has_type_id=false)]
54 | public enum SampleFormat {
55 | U8,
56 | ALAW,
57 | ULAW,
58 | S16LE,
59 | S16BE,
60 | FLOAT32LE,
61 | FLOAT32BE,
62 | S32LE,
63 | S32BE,
64 | S24LE,
65 | S24BE,
66 | S24_32LE,
67 | S24_32BE,
68 | MAX,
69 | S16NE,
70 | S16RE,
71 | FLOAT32NE,
72 | FLOAT32RE,
73 | S32NE,
74 | S32RE,
75 | S24NE,
76 | S24RE,
77 | S24_32NE,
78 | S24_32RE;
79 |
80 | [CCode (cname="pa_sample_size_of_format")]
81 | public size_t size();
82 |
83 | [CCode (cname="pa_sample_format_to_string")]
84 | public unowned string? to_string();
85 |
86 | [CCode (cname="pa_sample_format_is_le")]
87 | public int is_le();
88 |
89 | [CCode (cname="pa_sample_format_is_be")]
90 | public int is_be();
91 |
92 | [CCode (cname="pa_sample_format_is_ne")]
93 | public int is_ne();
94 |
95 | [CCode (cname="pa_sample_format_is_re")]
96 | public int is_re();
97 |
98 | [CCode (cname="pa_parse_sample_format")]
99 | public static SampleFormat parse(string b);
100 | }
101 |
102 | [CCode (cname="pa_usec_t")]
103 | public struct usec : uint64 {
104 | }
105 |
106 | [CCode (cname="pa_sample_spec", has_type_id=false)]
107 | public struct SampleSpec {
108 | public SampleFormat format;
109 | public uint32 rate;
110 | public uint8 channels;
111 |
112 | [CCode (cname="PA_SAMPLE_SPEC_SNPRINT_MAX")]
113 | public const size_t SNPRINT_MAX;
114 |
115 | [CCode (cname="pa_bytes_per_second")]
116 | public size_t bytes_per_second();
117 |
118 | [CCode (cname="pa_frame_size")]
119 | public size_t frame_size();
120 |
121 | [CCode (cname="pa_sample_size")]
122 | public size_t sample_size();
123 |
124 | [CCode (cname="pa_bytes_to_usec", instance_pos=1.1)]
125 | public usec bytes_to_usec(size_t size);
126 |
127 | [CCode (cname="pa_usec_to_bytes", instance_pos=1.1)]
128 | public size_t usec_to_bytes(usec u);
129 |
130 | [CCode (cname="pa_sample_spec_init")]
131 | public unowned SampleSpec? init();
132 |
133 | [CCode (cname="pa_sample_spec_valid")]
134 | public bool valid();
135 |
136 | [CCode (cname="pa_sample_spec_equal")]
137 | public bool equal(SampleSpec other);
138 |
139 | [CCode (cname="pa_sample_spec_snprint", instance_pos=3.1)]
140 | public unowned string snprint(char[] buf);
141 |
142 | public string sprint() {
143 | var buffer = new char[SNPRINT_MAX];
144 | this.snprint(buffer);
145 | return (string) buffer;
146 | }
147 |
148 | public string to_string() {
149 | return sprint();
150 | }
151 |
152 | [CCode (cname="pa_sample_spec_init")]
153 | public SampleSpec();
154 | }
155 |
156 | // [CCode (cname="PA_BYTES_SNPRINT_MAX")]
157 | [CCode (cname="PA_SAMPLE_SPEC_SNPRINT_MAX")]
158 | public const size_t BYTES_SNPRINT_MAX;
159 |
160 | [CCode (cname="pa_bytes_snprint")]
161 | public unowned string bytes_snprint(char[] buf, uint bytes);
162 |
163 | public string bytes_sprint(uint bytes) {
164 | var buffer = new char[BYTES_SNPRINT_MAX];
165 | bytes_snprint(buffer, bytes);
166 | return (string) buffer;
167 | }
168 |
169 | [CCode (cname="pa_volume_t", has_type_id=false)]
170 | [SimpleType]
171 | public struct Volume : uint32 {
172 |
173 | [CCode (cname="PA_SW_VOLUME_SNPRINT_DB_MAX")]
174 | public const size_t SW_SNPRINT_DB_MAX;
175 |
176 | [CCode (cname="PA_VOLUME_SNPRINT_MAX")]
177 | public const size_t SNPRINT_MAX;
178 |
179 | [CCode (cname="PA_VOLUME_NORM")]
180 | public const Volume NORM;
181 |
182 | [CCode (cname="PA_VOLUME_MUTED")]
183 | public const Volume MUTED;
184 |
185 | [CCode (cname="PA_VOLUME_MAX")]
186 | public const Volume MAX;
187 |
188 | [CCode (cname="PA_VOLUME_UI_MAX")]
189 | public const Volume UI_MAX;
190 |
191 | [CCode (cname="PA_VOLUME_INVALID")]
192 | public const Volume INVALID;
193 |
194 | [CCode (cname="pa_volume_snprint", instance_pos = 3.1)]
195 | public unowned string snprint(char[] s);
196 |
197 | public string sprint() {
198 | var buffer = new char[SNPRINT_MAX];
199 | this.snprint(buffer);
200 | return (string) buffer;
201 | }
202 |
203 | public string to_string() {
204 | return sprint();
205 | }
206 |
207 | [CCode (cname="pa_sw_volume_snprint_dB", instance_pos = 3.1)]
208 | public unowned string sw_snprint_dB(char[] s);
209 |
210 | public string sw_sprint_dB() {
211 | var buffer = new char[SW_SNPRINT_DB_MAX];
212 | this.sw_snprint_dB(buffer);
213 | return (string) buffer;
214 | }
215 |
216 | [CCode (cname="pa_sw_volume_multiply")]
217 | public Volume sw_multiply(Volume other);
218 |
219 | [CCode (cname="pa_sw_volume_divide")]
220 | public Volume sw_divide(Volume other);
221 |
222 | [CCode (cname="pa_sw_volume_from_dB")]
223 | public static Volume sw_from_dB(double f);
224 |
225 | [CCode (cname="pa_sw_volume_to_dB")]
226 | public double sw_to_dB();
227 |
228 | [CCode (cname="pa_sw_volume_from_linear")]
229 | public static Volume sw_from_linear(double f);
230 |
231 | [CCode (cname="pa_sw_volume_to_linear")]
232 | public double sw_to_linear();
233 | }
234 |
235 | [CCode (cname="PA_DECIBEL_MININFTY")]
236 | public const double DECIBEL_MININFTY;
237 |
238 | [CCode (cname="PA_CHANNELS_MAX")]
239 | public const int CHANNELS_MAX;
240 |
241 | [CCode (cname="PA_RATE_MAX")]
242 | public const int RATE_MAX;
243 |
244 | [CCode (cname="pa_cvolume", has_copy_function=false, has_destroy_function=false, has_type_id=false)]
245 | public struct CVolume {
246 | public uint8 channels;
247 |
248 | public Volume values[CHANNELS_MAX];
249 |
250 | [CCode (cname="PA_SW_CVOLUME_SNPRINT_DB_MAX")]
251 | public const size_t SW_SNPRINT_DB_MAX;
252 |
253 | [CCode (cname="PA_CVOLUME_SNPRINT_MAX")]
254 | public const size_t SNPRINT_MAX;
255 |
256 | [CCode (cname="pa_cvolume_equal")]
257 | public bool equal(CVolume other);
258 |
259 | [CCode (cname="pa_cvolume_init")]
260 | public unowned CVolume? init();
261 |
262 | [CCode (cname="pa_cvolume_reset")]
263 | public unowned CVolume? reset(uint8 channels);
264 |
265 | [CCode (cname="pa_cvolume_mute")]
266 | public unowned CVolume? mute(uint8 channels);
267 |
268 | [CCode (cname="pa_cvolume_snprint", instance_pos = 3.1)]
269 | public unowned string snprint(char[] s);
270 |
271 | public string sprint() {
272 | var buffer = new char[SNPRINT_MAX];
273 | this.snprint(buffer);
274 | return (string) buffer;
275 | }
276 |
277 | public string to_string() {
278 | return sprint();
279 | }
280 |
281 | [CCode (cname="pa_sw_cvolume_snprint_dB", instance_pos = 3.1)]
282 | public unowned string sw_snprint_dB(char [] s);
283 |
284 | public string sw_sprint_dB() {
285 | var buffer = new char[SW_SNPRINT_DB_MAX];
286 | this.sw_snprint_dB(buffer);
287 | return (string) buffer;
288 | }
289 |
290 | [CCode (cname="pa_cvolume_init")]
291 | public CVolume();
292 |
293 | [CCode (cname="pa_cvolume_avg")]
294 | public Volume avg();
295 |
296 | [CCode (cname="pa_cvolume_max")]
297 | public Volume max();
298 |
299 | [CCode (cname="pa_cvolume_min")]
300 | public Volume min();
301 |
302 | [CCode (cname="pa_cvolume_avg_mask")]
303 | public Volume avg_mask(ChannelMap map, ChannelPositionMask mask);
304 |
305 | [CCode (cname="pa_cvolume_max_mask")]
306 | public Volume max_mask(ChannelMap map, ChannelPositionMask mask);
307 |
308 | [CCode (cname="pa_cvolume_min_mask")]
309 | public Volume min_mask(ChannelMap map, ChannelPositionMask mask);
310 |
311 | [CCode (cname="pa_cvolume_valid")]
312 | public bool valid();
313 |
314 | [CCode (cname="pa_cvolume_channels_equal_to")]
315 | public bool channels_equal_to(Volume other);
316 |
317 | [CCode (cname="pa_cvolume_is_muted")]
318 | public bool is_muted();
319 |
320 | [CCode (cname="pa_cvolume_is_norm")]
321 | public bool is_norm();
322 |
323 | [CCode (cname="pa_sw_cvolume_multiply")]
324 | public unowned CVolume? multiply(CVolume other);
325 |
326 | [CCode (cname="pa_sw_cvolume_divide")]
327 | public unowned CVolume? divide(CVolume other);
328 |
329 | [CCode (cname="pa_sw_cvolume_multiply_scalar")]
330 | public unowned CVolume? multiply_scalar(Volume other);
331 |
332 | [CCode (cname="pa_sw_cvolume_divide_scalar")]
333 | public unowned CVolume? divide_scalar(Volume other);
334 |
335 | [CCode (cname="pa_cvolume_remap")]
336 | public unowned CVolume? remap(ChannelMap from, ChannelMap to);
337 |
338 | [CCode (cname="pa_cvolume_compatible")]
339 | public bool compatible(SampleSpec ss);
340 |
341 | [CCode (cname="pa_cvolume_compatible_with_channel_map")]
342 | public bool compatible_with_channel_map(ChannelMap cm);
343 |
344 | [CCode (cname="pa_cvolume_set")]
345 | public unowned CVolume? set(uint8 channels, Volume v);
346 |
347 | [CCode (cname="pa_cvolume_get_balance")]
348 | public float get_balance(ChannelMap map);
349 |
350 | [CCode (cname="pa_cvolume_set_balance")]
351 | public unowned CVolume? set_balance(ChannelMap map, float b);
352 |
353 | [CCode (cname="pa_cvolume_get_fade")]
354 | public float get_fade(ChannelMap map);
355 |
356 | [CCode (cname="pa_cvolume_set_fade")]
357 | public unowned CVolume? set_fade(ChannelMap map, float f);
358 |
359 | [CCode (cname="pa_cvolume_scale")]
360 | public unowned CVolume? scale(Volume max);
361 |
362 | [CCode (cname="pa_cvolume_scale_mask")]
363 | public unowned CVolume? scale_mask(Volume max, ChannelMap map, ChannelPositionMask mask);
364 |
365 | [CCode (cname="pa_cvolume_set_position")]
366 | public unowned CVolume? set_position(ChannelMap map, ChannelPosition p, Volume v);
367 |
368 | [CCode (cname="pa_cvolume_get_position")]
369 | public Volume get_position(ChannelMap map, ChannelPosition p);
370 |
371 | [CCode (cname="pa_cvolume_merge")]
372 | public unowned CVolume? merge(CVolume other);
373 |
374 | [CCode (cname="pa_cvolume_inc")]
375 | public unowned CVolume? inc(Volume plus = 1);
376 |
377 | [CCode (cname="pa_cvolume_dec")]
378 | public unowned CVolume? dec(Volume minus = 1);
379 | }
380 |
381 | [CCode (cname="pa_channel_map", has_type_id=false)]
382 | public struct ChannelMap {
383 | public uint8 channels;
384 | // TODO: Replace array length with CHANNELS_MAX once vala's bug #647788 is fixed
385 | public ChannelPosition map[32];
386 |
387 | [CCode (cname="PA_CHANNEL_MAP_SNPRINT_MAX")]
388 | public const size_t SNPRINT_MAX;
389 |
390 | [CCode (cname="pa_channel_map_init")]
391 | public ChannelMap();
392 |
393 | [CCode (cname="pa_channel_map_init")]
394 | public unowned ChannelMap? init();
395 |
396 | [CCode (cname="pa_channel_map_init_mono")]
397 | public unowned ChannelMap? init_mono();
398 |
399 | [CCode (cname="pa_channel_map_init_stereo")]
400 | public unowned ChannelMap? init_stereo();
401 |
402 | [CCode (cname="pa_channel_map_init_auto")]
403 | public unowned ChannelMap? init_auto(uint8 channels, ChannelMapDef def = ChannelMapDef.DEFAULT);
404 |
405 | [CCode (cname="pa_channel_map_init_extend")]
406 | public unowned ChannelMap? init_extend(uint8 channels, ChannelMapDef def = ChannelMapDef.DEFAULT);
407 |
408 | [CCode (cname="pa_channel_map_snprint", instance_pos = 3.1)]
409 | public unowned string snprint(char[] s);
410 |
411 | public string sprint() {
412 | var buffer = new char[SNPRINT_MAX];
413 | this.snprint(buffer);
414 | return (string) buffer;
415 | }
416 |
417 | public string to_string() {
418 | return sprint();
419 | }
420 |
421 | [CCode (cname="pa_channel_map_parse")]
422 | public unowned ChannelMap? parse(string s);
423 |
424 | [CCode (cname="pa_channel_map_equal")]
425 | public bool equal(ChannelMap other);
426 |
427 | [CCode (cname="pa_channel_map_superset")]
428 | public bool superset(ChannelMap other);
429 |
430 | [CCode (cname="pa_channel_map_valid")]
431 | public bool valid();
432 |
433 | [CCode (cname="pa_channel_map_compatible")]
434 | public bool compatible(SampleSpec ss);
435 |
436 | [CCode (cname="pa_channel_map_can_balance")]
437 | public bool can_balance();
438 |
439 | [CCode (cname="pa_channel_map_can_fade")]
440 | public bool can_fade();
441 |
442 | [CCode (cname="pa_channel_map_to_name")]
443 | public unowned string? to_name();
444 |
445 | [CCode (cname="pa_channel_map_to_pretty_name")]
446 | public unowned string? to_pretty_name();
447 |
448 | [CCode (cname="pa_channel_map_has_position")]
449 | public bool has_position(ChannelPosition p);
450 |
451 | [CCode (cname="pa_channel_map_mask")]
452 | public ChannelPositionMask mask();
453 | }
454 |
455 | [CCode (cname="pa_channel_position_mask_t", has_type_id=false)]
456 | public struct ChannelPositionMask : uint64 {
457 | }
458 |
459 | [CCode (cname="pa_channel_position_t", cprefix="PA_CHANNEL_POSITION_", has_type_id=false)]
460 | public enum ChannelPosition {
461 | INVALID,
462 | MONO,
463 | FRONT_LEFT,
464 | FRONT_RIGHT,
465 | FRONT_CENTER,
466 | REAR_CENTER,
467 | REAR_LEFT,
468 | REAR_RIGHT,
469 | LFE,
470 | FRONT_LEFT_OF_CENTER,
471 | FRONT_RIGHT_OF_CENTER,
472 | SIDE_LEFT,
473 | SIDE_RIGHT,
474 | TOP_CENTER,
475 | AUX0,
476 | AUX1,
477 | AUX2,
478 | AUX3,
479 | AUX4,
480 | AUX5,
481 | AUX6,
482 | AUX7,
483 | AUX8,
484 | AUX9,
485 | AUX10,
486 | AUX11,
487 | AUX12,
488 | AUX13,
489 | AUX14,
490 | AUX15,
491 | AUX16,
492 | AUX17,
493 | AUX18,
494 | AUX19,
495 | AUX20,
496 | AUX21,
497 | AUX22,
498 | AUX23,
499 | AUX24,
500 | AUX25,
501 | AUX26,
502 | AUX27,
503 | AUX28,
504 | AUX29,
505 | AUX30,
506 | AUX31,
507 | MAX;
508 |
509 | [CCode (cname="PA_CHANNEL_POSITION_MASK")]
510 | public ChannelPositionMask mask();
511 |
512 | [CCode (cname="pa_channel_position_to_string")]
513 | public unowned string? to_string();
514 |
515 | [CCode (cname="pa_channel_position_to_pretty_string")]
516 | public unowned string? to_pretty_string();
517 |
518 | [CCode (cname="pa_channel_position_from_string")]
519 | public static ChannelPosition from_string(string s);
520 | }
521 |
522 | [CCode (cname="pa_channel_map_def_t", cprefix="PA_CHANNEL_MAP_", has_type_id=false)]
523 | public enum ChannelMapDef {
524 | AIFF,
525 | WAVEEX,
526 | AUX,
527 | DEFAULT,
528 |
529 | [CCode (cname="PA_CHANNEL_MAP_DEF_MAX")]
530 | MAX
531 | }
532 |
533 | [Compact]
534 | [CCode (cname="pa_proplist", cprefix="pa_proplist_", free_function="pa_proplist_free", has_type_id=false)]
535 | public class Proplist {
536 |
537 | [CCode (cname="PA_PROP_MEDIA_NAME")]
538 | public const string PROP_MEDIA_NAME;
539 | [CCode (cname="PA_PROP_MEDIA_TITLE")]
540 | public const string PROP_MEDIA_TITLE;
541 | [CCode (cname="PA_PROP_MEDIA_ARTIST")]
542 | public const string PROP_MEDIA_ARTIST;
543 | [CCode (cname="PA_PROP_MEDIA_COPYRIGHT")]
544 | public const string PROP_MEDIA_COPYRIGHT;
545 | [CCode (cname="PA_PROP_MEDIA_SOFTWARE")]
546 | public const string PROP_MEDIA_SOFTWARE;
547 | [CCode (cname="PA_PROP_MEDIA_LANGUAGE")]
548 | public const string PROP_MEDIA_LANGUAGE;
549 | [CCode (cname="PA_PROP_MEDIA_FILENAME")]
550 | public const string PROP_MEDIA_FILENAME;
551 | [CCode (cname="PA_PROP_MEDIA_ICON_NAME")]
552 | public const string PROP_MEDIA_ICON_NAME;
553 | [CCode (cname="PA_PROP_MEDIA_ROLE")]
554 | public const string PROP_MEDIA_ROLE;
555 | [CCode (cname="PA_PROP_EVENT_ID")]
556 | public const string PROP_EVENT_ID;
557 | [CCode (cname="PA_PROP_EVENT_DESCRIPTION")]
558 | public const string PROP_EVENT_DESCRIPTION;
559 | [CCode (cname="PA_PROP_EVENT_MOUSE_X")]
560 | public const string PROP_EVENT_MOUSE_X;
561 | [CCode (cname="PA_PROP_EVENT_MOUSE_Y")]
562 | public const string PROP_EVENT_MOUSE_Y;
563 | [CCode (cname="PA_PROP_EVENT_MOUSE_HPOS")]
564 | public const string PROP_EVENT_MOUSE_HPOS;
565 | [CCode (cname="PA_PROP_EVENT_MOUSE_VPOS")]
566 | public const string PROP_EVENT_MOUSE_VPOS;
567 | [CCode (cname="PA_PROP_EVENT_MOUSE_BUTTON")]
568 | public const string PROP_EVENT_MOUSE_BUTTON;
569 | [CCode (cname="PA_PROP_WINDOW_NAME")]
570 | public const string PROP_WINDOW_NAME;
571 | [CCode (cname="PA_PROP_WINDOW_ID")]
572 | public const string PROP_WINDOW_ID;
573 | [CCode (cname="PA_PROP_WINDOW_ICON_NAME")]
574 | public const string PROP_WINDOW_ICON_NAME;
575 | [CCode (cname="PA_PROP_WINDOW_X11_DISPLAY")]
576 | public const string PROP_WINDOW_X11_DISPLAY;
577 | [CCode (cname="PA_PROP_WINDOW_X11_SCREEN")]
578 | public const string PROP_WINDOW_X11_SCREEN;
579 | [CCode (cname="PA_PROP_WINDOW_X11_MONITOR")]
580 | public const string PROP_WINDOW_X11_MONITOR;
581 | [CCode (cname="PA_PROP_WINDOW_X11_XID")]
582 | public const string PROP_WINDOW_X11_XID;
583 | [CCode (cname="PA_PROP_APPLICATION_NAME")]
584 | public const string PROP_APPLICATION_NAME;
585 | [CCode (cname="PA_PROP_APPLICATION_ID")]
586 | public const string PROP_APPLICATION_ID;
587 | [CCode (cname="PA_PROP_APPLICATION_VERSION")]
588 | public const string PROP_APPLICATION_VERSION;
589 | [CCode (cname="PA_PROP_APPLICATION_ICON_NAME")]
590 | public const string PROP_APPLICATION_ICON_NAME;
591 | [CCode (cname="PA_PROP_APPLICATION_LANGUAGE")]
592 | public const string PROP_APPLICATION_LANGUAGE;
593 | [CCode (cname="PA_PROP_APPLICATION_PROCESS_ID")]
594 | public const string PROP_APPLICATION_PROCESS_ID;
595 | [CCode (cname="PA_PROP_APPLICATION_PROCESS_BINARY")]
596 | public const string PROP_APPLICATION_PROCESS_BINARY;
597 | [CCode (cname="PA_PROP_APPLICATION_PROCESS_USER")]
598 | public const string PROP_APPLICATION_PROCESS_USER;
599 | [CCode (cname="PA_PROP_APPLICATION_PROCESS_HOST")]
600 | public const string PROP_APPLICATION_PROCESS_HOST;
601 | [CCode (cname="PA_PROP_APPLICATION_PROCESS_MACHINE_ID")]
602 | public const string PROP_APPLICATION_PROCESS_MACHINE_ID;
603 | [CCode (cname="PA_PROP_APPLICATION_PROCESS_SESSION_ID")]
604 | public const string PROP_APPLICATION_PROCESS_SESSION_ID;
605 | [CCode (cname="PA_PROP_DEVICE_STRING")]
606 | public const string PROP_DEVICE_STRING;
607 | [CCode (cname="PA_PROP_DEVICE_API")]
608 | public const string PROP_DEVICE_API;
609 | [CCode (cname="PA_PROP_DEVICE_DESCRIPTION")]
610 | public const string PROP_DEVICE_DESCRIPTION;
611 | [CCode (cname="PA_PROP_DEVICE_BUS_PATH")]
612 | public const string PROP_DEVICE_BUS_PATH;
613 | [CCode (cname="PA_PROP_DEVICE_SERIAL")]
614 | public const string PROP_DEVICE_SERIAL;
615 | [CCode (cname="PA_PROP_DEVICE_VENDOR_ID")]
616 | public const string PROP_DEVICE_VENDOR_ID;
617 | [CCode (cname="PA_PROP_DEVICE_VENDOR_NAME")]
618 | public const string PROP_DEVICE_VENDOR_NAME;
619 | [CCode (cname="PA_PROP_DEVICE_PRODUCT_ID")]
620 | public const string PROP_DEVICE_PRODUCT_ID;
621 | [CCode (cname="PA_PROP_DEVICE_PRODUCT_NAME")]
622 | public const string PROP_DEVICE_PRODUCT_NAME;
623 | [CCode (cname="PA_PROP_DEVICE_CLASS")]
624 | public const string PROP_DEVICE_CLASS;
625 | [CCode (cname="PA_PROP_DEVICE_FORM_FACTOR")]
626 | public const string PROP_DEVICE_FORM_FACTOR;
627 | [CCode (cname="PA_PROP_DEVICE_BUS")]
628 | public const string PROP_DEVICE_BUS;
629 | [CCode (cname="PA_PROP_DEVICE_ICON_NAME")]
630 | public const string PROP_DEVICE_ICON_NAME;
631 | [CCode (cname="PA_PROP_DEVICE_ACCESS_MODE")]
632 | public const string PROP_DEVICE_ACCESS_MODE;
633 | [CCode (cname="PA_PROP_DEVICE_MASTER_DEVICE")]
634 | public const string PROP_DEVICE_MASTER_DEVICE;
635 | [CCode (cname="PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE")]
636 | public const string PROP_DEVICE_BUFFERING_BUFFER_SIZE;
637 | [CCode (cname="PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE")]
638 | public const string PROP_DEVICE_BUFFERING_FRAGMENT_SIZE;
639 | [CCode (cname="PA_PROP_DEVICE_PROFILE_NAME")]
640 | public const string PROP_DEVICE_PROFILE_NAME;
641 | [CCode (cname="PA_PROP_DEVICE_INTENDED_ROLES")]
642 | public const string PROP_DEVICE_INTENDED_ROLES;
643 | [CCode (cname="PA_PROP_DEVICE_PROFILE_DESCRIPTION")]
644 | public const string PROP_DEVICE_PROFILE_DESCRIPTION;
645 | [CCode (cname="PA_PROP_MODULE_AUTHOR")]
646 | public const string PROP_MODULE_AUTHOR;
647 | [CCode (cname="PA_PROP_MODULE_DESCRIPTION")]
648 | public const string PROP_MODULE_DESCRIPTION;
649 | [CCode (cname="PA_PROP_MODULE_USAGE")]
650 | public const string PROP_MODULE_USAGE;
651 | [CCode (cname="PA_PROP_MODULE_VERSION")]
652 | public const string PROP_MODULE_VERSION;
653 |
654 | [CCode (cname="pa_proplist_new")]
655 | public Proplist();
656 |
657 | public int sets(string key, string value);
658 | public int setp(string pair);
659 |
660 | [PrintfFormat]
661 | public int setf(string key, string format, ...);
662 |
663 | public int set(string key, void* data, size_t size);
664 |
665 | public unowned string? gets(string key);
666 |
667 | public int get(string key, out void* data, out size_t size);
668 |
669 | public void update(UpdateMode mode, Proplist other);
670 |
671 | public void unset(string key);
672 |
673 | [CCode (array_length = false)]
674 | public void unset_many(string[] key);
675 |
676 | public unowned string? iterate(ref void* state);
677 |
678 | public string to_string();
679 |
680 | public string to_string_sep(string sep);
681 |
682 | public static Proplist? from_string(string s);
683 |
684 | public bool contains(string key);
685 |
686 | public void clear();
687 |
688 | public Proplist copy();
689 |
690 | public uint size();
691 |
692 | public bool is_empty();
693 | }
694 |
695 | [CCode (cname="pa_update_mode_t", cprefix="PA_UPDATE_", has_type_id=false)]
696 | public enum UpdateMode {
697 | SET,
698 | MERGE,
699 | REPLACE
700 | }
701 |
702 | [CCode (cname="PA_OK")]
703 | public const int OK;
704 |
705 | [CCode (cname="int", cprefix="PA_ERR_", has_type_id=false)]
706 | public enum Error {
707 | ACCESS,
708 | COMMAND,
709 | INVALID,
710 | EXIST,
711 | NOENTITY,
712 | CONNECTIONREFUSED,
713 | PROTOCOL,
714 | TIMEOUT,
715 | AUTHKEY,
716 | INTERNAL,
717 | CONNECTIONTERMINATED,
718 | KILLED,
719 | INVALIDSERVER,
720 | MODINITFAILED,
721 | BADSTATE,
722 | NODATA,
723 | VERSION,
724 | TOOLARGE,
725 | NOTSUPPORTED,
726 | UNKNOWN,
727 | NOEXTENSION,
728 | OBSOLETE,
729 | NOTIMPLEMENTED,
730 | FORKED,
731 | IO,
732 | MAX
733 | }
734 |
735 | [CCode (cname="pa_strerror")]
736 | public unowned string? strerror(Error e);
737 |
738 | public delegate void VoidFunc();
739 |
740 | [CCode (cname="pa_spawn_api", has_type_id=false)]
741 | public struct SpawnApi {
742 | VoidFunc? prefork;
743 | VoidFunc? postfork;
744 | VoidFunc? atfork;
745 | }
746 |
747 | [CCode (cname="pa_io_event_flags_t", cprefix="PA_IO_EVENT_", has_type_id=false)]
748 | public enum IoEventFlags {
749 | NULL,
750 | INPUT,
751 | OUTPUT,
752 | HANGUP,
753 | ERROR
754 | }
755 |
756 | [Compact]
757 | [CCode (cname="pa_io_event", unref_function="", ref_function="", has_type_id=false)]
758 | public struct IoEvent {
759 | }
760 |
761 | [Compact]
762 | [CCode (cname="pa_time_event", unref_function="", ref_function="", has_type_id=false)]
763 | public struct TimeEvent {
764 | }
765 |
766 | [Compact]
767 | [CCode (cname="pa_defer_event", unref_function="", ref_function="", has_type_id=false)]
768 | public struct DeferEvent {
769 | }
770 |
771 | [Compact]
772 | [CCode (cname="pa_signal_event", cprefix="pa_signal_", free_function="pa_signal_free", has_type_id=false)]
773 | public struct SignalEvent {
774 |
775 | [CCode (cname="pa_signal_new")]
776 | public SignalEvent(int sig, MainLoopApi.SignalEventCb cb);
777 |
778 | public void set_destroy(MainLoopApi.SignalEventDestroyCb cb);
779 | }
780 |
781 | [Compact]
782 | [CCode (cname="pa_mainloop_api", unref_function="", ref_function="", has_type_id=false)]
783 | public class MainLoopApi {
784 | public void* userdata;
785 |
786 | /* Callbacks for the consumer to implement*/
787 | public delegate void IoEventCb(MainLoopApi a, IoEvent e, int fd, IoEventFlags flags);
788 | public delegate void IoEventDestroyCb(MainLoopApi a, IoEvent e);
789 |
790 | public delegate void TimeEventCb(MainLoopApi a, TimeEvent e, ref timeval t);
791 | public delegate void TimeEventDestroyCb(MainLoopApi a, TimeEvent e);
792 |
793 | public delegate void DeferEventCb(MainLoopApi a, DeferEvent e);
794 | public delegate void DeferEventDestroyCb(MainLoopApi a, DeferEvent e);
795 |
796 | public delegate void SignalEventCb(MainLoopApi a, SignalEvent e);
797 | public delegate void SignalEventDestroyCb(MainLoopApi a, SignalEvent e);
798 |
799 | /* Callbacks for the provider to implement */
800 | public delegate IoEvent IoNewCb(MainLoopApi a, int fd, IoEventFlags flags, IoEventCb cb);
801 | public delegate void IoEnableCb(MainLoopApi a, IoEvent e, IoEventFlags flags);
802 | public delegate void IoFreeCb(MainLoopApi a, IoEvent e);
803 | public delegate void IoSetDestroyCb(MainLoopApi a, IoEvent e, IoEventDestroyCb? cb);
804 |
805 | public delegate TimeEvent TimeNewCb(MainLoopApi a, timeval? t, TimeEventCb cb);
806 | public delegate void TimeRestartCb(MainLoopApi a, TimeEvent e, timeval? t);
807 | public delegate void TimeFreeCb(MainLoopApi a, TimeEvent e);
808 | public delegate void TimeSetDestroyCb(MainLoopApi a, TimeEvent e, TimeEventDestroyCb? cb);
809 |
810 | public delegate DeferEvent DeferNewCb(MainLoopApi a, DeferEventCb cb);
811 | public delegate void DeferEnableCb(MainLoopApi a, DeferEvent e, bool b);
812 | public delegate void DeferFreeCb(MainLoopApi a, DeferEvent e);
813 | public delegate void DeferSetDestroyCb(MainLoopApi a, DeferEvent e, DeferEventDestroyCb? cb);
814 |
815 | public delegate void QuitCb(MainLoopApi a, int retval);
816 |
817 | public delegate void OnceCb(MainLoopApi a);
818 |
819 | public IoNewCb io_new;
820 | public IoEnableCb io_enable;
821 | public IoFreeCb io_free;
822 | public IoSetDestroyCb io_set_destroy;
823 |
824 | public TimeNewCb time_new;
825 | public TimeRestartCb time_restart;
826 | public TimeFreeCb time_free;
827 | public TimeSetDestroyCb time_set_destroy;
828 |
829 | public DeferNewCb defer_new;
830 | public DeferEnableCb defer_enable;
831 | public DeferFreeCb defer_free;
832 | public DeferSetDestroyCb defer_set_destroy;
833 |
834 | public QuitCb quit;
835 |
836 | [CCode (cname="pa_mainloop_api_once")]
837 | public void once(OnceCb cb);
838 | }
839 |
840 | [CCode (cname="pa_signal_init")]
841 | public void signal_init(MainLoopApi api);
842 |
843 | [CCode (cname="pa_signal_done")]
844 | public void signal_done();
845 |
846 | [CCode (cname="pa_poll_func")]
847 | public delegate int PollFunc(pollfd[] ufds, int timeout);
848 |
849 | [Compact]
850 | [CCode (cname="pa_mainloop", cprefix="pa_mainloop_", free_function="pa_mainloop_free", has_type_id=false)]
851 | public class MainLoop {
852 |
853 | [CCode (cname="pa_mainloop_new")]
854 | public MainLoop();
855 |
856 | public int prepare(int timeout = -1);
857 | public int poll();
858 | public int dispatch();
859 | public int get_retval();
860 | public int iterate(bool block = true, out int retval = null);
861 | public int run(out int retval = null);
862 | public unowned MainLoopApi get_api();
863 | public void quit(int retval);
864 | public void wakeup();
865 | public void set_poll_func(PollFunc poll_func);
866 | }
867 |
868 | [Compact]
869 | [CCode (cname="pa_threaded_mainloop", cprefix="pa_threaded_mainloop_", free_function="pa_threaded_mainloop_free")]
870 | public class ThreadedMainLoop {
871 |
872 | [CCode (cname="pa_threaded_mainloop_new")]
873 | public ThreadedMainLoop();
874 |
875 | public int start();
876 | public void stop();
877 | public void lock();
878 | public void unlock();
879 | public void wait();
880 | public void signal(bool WaitForAccept = false);
881 | public void accept();
882 | public int get_retval();
883 | public unowned MainLoopApi get_api();
884 | public bool in_thread();
885 | }
886 |
887 | [Compact]
888 | [CCode (cname="pa_operation", cprefix="pa_operation_", unref_function="pa_operation_unref", ref_function="pa_operation_ref", has_type_id=false)]
889 | public class Operation {
890 |
891 | [CCode (cname="pa_operation_state_t", cprefix="PA_OPERATION_", has_type_id=false)]
892 | public enum State {
893 | RUNNING,
894 | DONE,
895 | CANCELED
896 | }
897 |
898 | public void cancel();
899 | public State get_state();
900 | }
901 |
902 | [Compact]
903 | [CCode (cname="pa_context", cprefix="pa_context_", unref_function="pa_context_unref", ref_function="pa_context_ref", has_type_id=false)]
904 | public class Context {
905 |
906 | [CCode (cname="pa_context_flags_t", cprefix="PA_CONTEXT_", has_type_id=false)]
907 | public enum Flags {
908 | NOAUTOSPAWN,
909 | NOFAIL
910 | }
911 |
912 | [CCode (cname="pa_context_state_t", cprefix="PA_CONTEXT_", has_type_id=false)]
913 | public enum State {
914 | UNCONNECTED,
915 | CONNECTING,
916 | AUTHORIZING,
917 | SETTING_NAME,
918 | READY,
919 | FAILED,
920 | TERMINATED;
921 |
922 | [CCode (cname="PA_CONTEXT_IS_GOOD", has_type_id=false)]
923 | public bool IS_GOOD();
924 | }
925 |
926 | [CCode (cname="pa_subscription_mask_t", cprefix="PA_SUBSCRIPTION_MASK_", has_type_id=false)]
927 | public enum SubscriptionMask {
928 | NULL,
929 | SINK,
930 | SOURCE,
931 | SINK_INPUT,
932 | SOURCE_OUTPUT,
933 | MODULE,
934 | CLIENT,
935 | SAMPLE_CACHE,
936 | SERVER,
937 | CARD,
938 | ALL;
939 |
940 | [CCode (cname="pa_subscription_match_flags")]
941 | public bool match_flags(SubscriptionEventType t);
942 | }
943 |
944 | [CCode (cname="pa_subscription_event_type_t", cprefix="PA_SUBSCRIPTION_EVENT_", has_type_id=false)]
945 | public enum SubscriptionEventType {
946 | SINK,
947 | SOURCE,
948 | SINK_INPUT,
949 | SOURCE_OUTPUT,
950 | MODULE,
951 | CLIENT,
952 | SAMPLE_CACHE,
953 | SERVER,
954 | [Version (deprecated=true)]
955 | AUTOLOAD,
956 | CARD,
957 | FACILITY_MASK,
958 | NEW,
959 | CHANGE,
960 | REMOVE,
961 | TYPE_MASK;
962 |
963 | public string to_string() {
964 | string type = "unknown";
965 | if ((this & TYPE_MASK) == NEW) type = "new";
966 | if ((this & TYPE_MASK) == CHANGE) type = "change";
967 | if ((this & TYPE_MASK) == REMOVE) type = "remove";
968 |
969 | string facility = "unknown";
970 | if ((this & FACILITY_MASK) == SINK) facility = "sink";
971 | if ((this & FACILITY_MASK) == SOURCE) facility = "source";
972 | if ((this & FACILITY_MASK) == SINK_INPUT) facility = "sink-input";
973 | if ((this & FACILITY_MASK) == SOURCE_OUTPUT) facility = "source-output";
974 | if ((this & FACILITY_MASK) == MODULE) facility = "module";
975 | if ((this & FACILITY_MASK) == CLIENT) facility = "client";
976 | if ((this & FACILITY_MASK) == SAMPLE_CACHE) facility = "sample-cache";
977 | if ((this & FACILITY_MASK) == SERVER) facility = "server";
978 | if ((this & FACILITY_MASK) == AUTOLOAD) facility = "autoload";
979 | if ((this & FACILITY_MASK) == CARD) facility = "card";
980 |
981 | return "Event '%s' on %s".printf (type, facility);
982 | }
983 | }
984 |
985 | [CCode (cname = "pa_context_notify_cb_t")]
986 | public delegate void NotifyCb(Context c);
987 | [CCode (cname = "pa_context_success_cb_t")]
988 | public delegate void SuccessCb(Context c, int success);
989 | [CCode (cname = "pa_context_event_cb_t")]
990 | public delegate void EventCb(Context c, string name, Proplist? proplist);
991 | [CCode (cname = "pa_context_subscribe_cb_t")]
992 | public delegate void SubscribeCb(Context c, SubscriptionEventType t, uint32 idx);
993 | [CCode (cname = "pa_sink_info_cb_t")]
994 | public delegate void SinkInfoCb(Context c, SinkInfo? i, int eol);
995 | [CCode (cname = "pa_source_info_cb_t")]
996 | public delegate void SourceInfoCb(Context c, SourceInfo? i, int eol);
997 | [CCode (cname = "pa_card_info_cb_t")]
998 | public delegate void CardInfoCb(Context c, CardInfo? i, int eol);
999 | [CCode (cname = "pa_sink_input_info_cb_t")]
1000 | public delegate void SinkInputInfoCb(Context c, SinkInputInfo? i, int eol);
1001 | [CCode (cname = "pa_source_output_info_cb_t")]
1002 | public delegate void SourceOutputInfoCb(Context c, SourceOutputInfo? i, int eol);
1003 | [CCode (cname = "pa_server_info_cb_t")]
1004 | public delegate void ServerInfoCb(Context c, ServerInfo? i);
1005 | [CCode (cname = "pa_stat_info_cb_t")]
1006 | public delegate void StatInfoCb(Context c, ServerInfo? i);
1007 | [CCode (cname = "pa_module_info_cb_t")]
1008 | public delegate void ModuleInfoCb(Context c, ModuleInfo? i, int eol);
1009 | [CCode (cname = "pa_client_info_cb_t")]
1010 | public delegate void ClientInfoCb(Context c, ClientInfo? i, int eol);
1011 | [CCode (cname = "pa_sample_info_cb_t")]
1012 | public delegate void SampleInfoCb(Context c, SampleInfo? i, int eol);
1013 | [CCode (cname = "pa_context_index_cb_t")]
1014 | public delegate void IndexCb(Context c, uint32 idx);
1015 |
1016 | [CCode (cname="pa_context_new_with_proplist")]
1017 | public Context(MainLoopApi api, string? name, Proplist? proplist = null);
1018 |
1019 | public void set_state_callback(NotifyCb? cb = null);
1020 | public void set_event_callback(EventCb? cb = null);
1021 | public void set_subscribe_callback(SubscribeCb? cb = null);
1022 |
1023 | public Error errno();
1024 |
1025 | public int is_pending();
1026 | public State get_state();
1027 | public int is_local();
1028 | public unowned string? get_server();
1029 | public uint32 get_protocol_version();
1030 | public uint32 get_server_protocol_version();
1031 | public uint32 get_index();
1032 |
1033 | public int connect(string? server = null, Flags flags = 0, SpawnApi? api = null);
1034 | public void disconnect();
1035 |
1036 | public Operation? drain(NotifyCb? cb = null);
1037 | public Operation? exit_daemon(SuccessCb? cb = null);
1038 | public Operation? set_default_sink(string name, SuccessCb? cb = null);
1039 | public Operation? set_default_source(string name, SuccessCb? cb = null);
1040 | public Operation? set_name(string name, SuccessCb? cb = null);
1041 |
1042 | [CCode (array_length = false)]
1043 | public Operation? proplist_remove(string[] keys, SuccessCb? cb = null);
1044 | public Operation? proplist_update(UpdateMode mode, Proplist pl, SuccessCb? cb = null);
1045 |
1046 | public Operation? subscribe(SubscriptionMask mask, SuccessCb? cb = null);
1047 |
1048 | public Operation? get_sink_info_by_name(string name, SinkInfoCb cb);
1049 | public Operation? get_sink_info_by_index(uint32 idx, SinkInfoCb cb);
1050 | public Operation? get_sink_info_list(SinkInfoCb cb);
1051 |
1052 | public Operation? set_sink_volume_by_name(string name, CVolume volume, SuccessCb? cb = null);
1053 | public Operation? set_sink_volume_by_index(uint32 idx, CVolume volume, SuccessCb? cb = null);
1054 | public Operation? set_sink_mute_by_name(string name, bool mute, SuccessCb? cb = null);
1055 | public Operation? set_sink_mute_by_index(uint32 idx, bool mute, SuccessCb? cb = null);
1056 |
1057 | public Operation? suspend_sink_by_name(string name, bool suspend, SuccessCb? cb = null);
1058 | public Operation? suspend_sink_by_index(uint32 idx, bool suspend, SuccessCb? cb = null);
1059 |
1060 | public Operation? set_sink_port_by_name(string name, string port, SuccessCb? cb = null);
1061 | public Operation? set_sink_port_by_index(uint32 idx, string port, SuccessCb? cb = null);
1062 |
1063 | public Operation? get_source_info_by_name(string name, SourceInfoCb cb);
1064 | public Operation? get_source_info_by_index(uint32 idx, SourceInfoCb cb);
1065 | public Operation? get_source_info_list(SourceInfoCb cb);
1066 |
1067 | public Operation? set_source_volume_by_name(string name, CVolume volume, SuccessCb? cb = null);
1068 | public Operation? set_source_volume_by_index(uint32 idx, CVolume volume, SuccessCb? cb = null);
1069 | public Operation? set_source_mute_by_name(string name, bool mute, SuccessCb? cb = null);
1070 | public Operation? set_source_mute_by_index(uint32 idx, bool mute, SuccessCb? cb = null);
1071 |
1072 | public Operation? suspend_source_by_name(string name, bool suspend, SuccessCb? cb = null);
1073 | public Operation? suspend_source_by_index(uint32 idx, bool suspend, SuccessCb? cb = null);
1074 |
1075 | public Operation? set_source_port_by_name(string name, string port, SuccessCb? cb = null);
1076 | public Operation? set_source_port_by_index(uint32 idx, string port, SuccessCb? cb = null);
1077 |
1078 | public Operation? get_server_info(ServerInfoCb cb);
1079 |
1080 | public Operation? get_module_info(uint32 idx, ModuleInfoCb cb);
1081 | public Operation? get_module_info_list(ModuleInfoCb cb);
1082 |
1083 | public Operation? load_module(string name, string? argument, IndexCb? cb = null);
1084 | public Operation? unload_module(uint32 idx, SuccessCb? cb = null);
1085 |
1086 | public Operation? get_client_info(uint32 idx, ClientInfoCb cb);
1087 | public Operation? get_client_info_list(ClientInfoCb cb);
1088 |
1089 | public Operation? kill_client(uint32 idx, SuccessCb? cb = null);
1090 |
1091 | public Operation? get_card_info_by_name(string name, CardInfoCb cb);
1092 | public Operation? get_card_info_by_index(uint32 idx, CardInfoCb cb);
1093 | public Operation? get_card_info_list(CardInfoCb cb);
1094 |
1095 | public Operation? set_card_profile_by_index(uint32 idx, string profile, SuccessCb? cb = null);
1096 | public Operation? set_card_profile_by_name(string name, string profile, SuccessCb? cb = null);
1097 |
1098 | public Operation? get_sink_input_info(uint32 idx, SinkInputInfoCb cb);
1099 | public Operation? get_sink_input_info_list(SinkInputInfoCb cb);
1100 |
1101 | public Operation? move_sink_input_by_index(uint32 idx, uint32 sink_idx, SuccessCb? cb = null);
1102 | public Operation? move_sink_input_by_name(uint32 idx, string sink_name, SuccessCb? cb = null);
1103 |
1104 | public Operation? set_sink_input_volume(uint32 idx, CVolume volume, SuccessCb? cb = null);
1105 | public Operation? set_sink_input_mute(uint32 idx, bool mute, SuccessCb? cb = null);
1106 |
1107 | public Operation? kill_sink_input(uint32 idx, SuccessCb? cb = null);
1108 |
1109 | public Operation? get_source_output_info(uint32 idx, SourceOutputInfoCb cb);
1110 | public Operation? get_source_output_info_list(SourceOutputInfoCb cb);
1111 |
1112 | public Operation? move_source_output_by_index(uint32 idx, uint32 source_idx, SuccessCb? cb = null);
1113 | public Operation? move_source_output_by_name(uint32 idx, string source_name, SuccessCb? cb = null);
1114 |
1115 | public Operation? kill_source_output(uint32 idx, SuccessCb? cb = null);
1116 |
1117 | public Operation? stat(StatInfoCb cb);
1118 |
1119 | public Operation? get_sample_info_by_name(string name, SampleInfoCb cb);
1120 | public Operation? get_sample_info_by_index(uint32 idx, SampleInfoCb cb);
1121 | public Operation? get_sample_info_list(SampleInfoCb cb);
1122 |
1123 | public Operation? remove_sample(string name, SuccessCb? cb = null);
1124 |
1125 | public Operation? play_sample(string name, string? device = null, Volume volume = Volume.INVALID, SuccessCb? cb = null);
1126 | public Operation? play_sample_with_proplist(string name, string? device = null, Volume volume = Volume.INVALID, Proplist? p = null, IndexCb? cb = null);
1127 | }
1128 |
1129 | [Compact]
1130 | [CCode (cname="pa_stream", cprefix="pa_stream_", unref_function="pa_stream_unref", ref_function="pa_stream_ref", has_type_id=false)]
1131 | public class Stream {
1132 |
1133 | [CCode (cname="pa_stream_flags_t", cprefix="PA_STREAM_", has_type_id=false)]
1134 | public enum Flags {
1135 | START_CORKED,
1136 | INTERPOLATE_TIMING,
1137 | NOT_MONOTONIC,
1138 | AUTO_TIMING_UPDATE,
1139 | NO_REMAP_CHANNELS,
1140 | NO_REMIX_CHANNELS,
1141 | FIX_FORMAT,
1142 | FIX_RATE,
1143 | FIX_CHANNELS,
1144 | DONT_MOVE,
1145 | VARIABLE_RATE,
1146 | PEAK_DETECT,
1147 | START_MUTED,
1148 | ADJUST_LATENCY,
1149 | EARLY_REQUESTS,
1150 | DONT_INHIBIT_AUTO_SUSPEND,
1151 | START_UNMUTED,
1152 | FAIL_ON_SUSPEND
1153 | }
1154 |
1155 | [CCode (cname="pa_stream_state_t", cprefix="PA_STREAM_", has_type_id=false)]
1156 | public enum State {
1157 | UNCONNECTED,
1158 | CREATING,
1159 | READY,
1160 | FAILED,
1161 | TERMINATED;
1162 |
1163 | [CCode (cname="PA_STREAM_IS_GOOD")]
1164 | public bool IS_GOOD();
1165 | }
1166 |
1167 | [CCode (cname="pa_stream_direction_t", cprefix="PA_STREAM_", has_type_id=false)]
1168 | public enum Direction {
1169 | NODIRECTION,
1170 | PLAYBACK,
1171 | RECORD,
1172 | UPLOAD
1173 | }
1174 |
1175 | [CCode (cname="pa_seek_mode_t", cprefix="PA_SEEK_", has_type_id=false)]
1176 | public enum SeekMode {
1177 | RELATIVE,
1178 | ABSOLUTE,
1179 | RELATIVE_ON_READ,
1180 | RELATIVE_END
1181 | }
1182 |
1183 | [CCode (cname="pa_buffer_attr", has_type_id=false)]
1184 | public struct BufferAttr {
1185 | uint32 maxlength;
1186 | uint32 tlength;
1187 | uint32 prebuf;
1188 | uint32 minreq;
1189 | uint32 fragsize;
1190 | }
1191 |
1192 | [CCode (cname="pa_timing_info", has_type_id=false)]
1193 | public struct TimingInfo {
1194 | timeval timestamp;
1195 | int synchronized_clocks;
1196 | usec sink_usec;
1197 | usec source_usec;
1198 | usec transport_usec;
1199 | int playing;
1200 | int write_index_corrupt;
1201 | int64 write_index;
1202 | int read_index_corrupt;
1203 | int64 read_index;
1204 | usec configured_sink_usec;
1205 | usec configured_source_usec;
1206 | int64 since_underrun;
1207 | }
1208 |
1209 | [CCode (cname="PA_STREAM_EVENT_REQUEST_CORK")]
1210 | public const string EVENT_REQUEST_CORK;
1211 |
1212 | [CCode (cname="PA_STREAM_EVENT_REQUEST_UNCORK")]
1213 | public const string EVENT_REQUEST_UNCORK;
1214 |
1215 | public delegate void SuccessCb(Stream s, int success);
1216 | public delegate void RequestCb(Stream s, size_t nbytes);
1217 | public delegate void NotifyCb(Stream s);
1218 | public delegate void EventCb(Stream s, string name, Proplist proplist);
1219 |
1220 | [CCode (cname="pa_stream_new_with_proplist")]
1221 | public Stream(Context c, string name, SampleSpec ss, ChannelMap? map = null, Proplist? proplist = null);
1222 |
1223 | public State get_state();
1224 | public Context get_context();
1225 | public uint32 get_index();
1226 | public uint32 get_device_index();
1227 | public unowned string? get_device_name();
1228 | public int is_suspended();
1229 | public int is_corked();
1230 |
1231 | public int connect_playback(string? dev = null, BufferAttr? a = null, Flags flags = 0, CVolume? volume = null, Stream? sync_stream = null);
1232 | public int connect_record(string? dev = null, BufferAttr? a = null, Flags flags = 0);
1233 | public int connect_upload(size_t length);
1234 | public int disconnect();
1235 | public int finish_upload();
1236 |
1237 | public int begin_write(out void* data, out size_t nbytes);
1238 | public int cancel_write();
1239 | public int write(void *data, size_t bytes, FreeCb? free_cb = null, int64 offset = 0, SeekMode mode = SeekMode.RELATIVE);
1240 | public int peek(out void *data, out size_t nbytes);
1241 | public int drop();
1242 | public size_t writable_size();
1243 | public size_t readable_size();
1244 |
1245 | public void set_state_callback(NotifyCb? cb = null);
1246 | public void set_write_callback(RequestCb? cb = null);
1247 | public void set_read_callback(RequestCb? cb = null);
1248 | public void set_overflow_callback(NotifyCb? cb = null);
1249 | public void set_underflow_callback(NotifyCb? cb = null);
1250 | public void set_started_callback(NotifyCb? cb = null);
1251 | public void set_latency_update_callback(NotifyCb? cb = null);
1252 | public void set_moved_callback(NotifyCb? cb = null);
1253 | public void set_suspended_callback(NotifyCb? cb = null);
1254 | public void set_event_callback(EventCb? cb = null);
1255 | public void set_buffer_attr_callback(NotifyCb? cb = null);
1256 |
1257 | public Operation? drain(SuccessCb? cb = null);
1258 | public Operation? update_timing_info(SuccessCb? cb = null);
1259 |
1260 | public Operation? cork(bool b, SuccessCb? cb = null);
1261 | public Operation? flush(SuccessCb? cb = null);
1262 | public Operation? prebuf(SuccessCb? cb = null);
1263 | public Operation? trigger(SuccessCb? cb = null);
1264 |
1265 | public Operation? set_name(string name, SuccessCb? cb = null);
1266 | public Operation? set_buffer_attr(BufferAttr attr, SuccessCb? cb = null);
1267 | public Operation? update_sample_rate(uint32 rate, SuccessCb? cb = null);
1268 |
1269 | [CCode (array_length = false)]
1270 | public Operation? proplist_remove(string[] keys, SuccessCb? cb = null);
1271 | public Operation? proplist_update(UpdateMode mode, Proplist pl, SuccessCb? cb = null);
1272 |
1273 | public unowned TimingInfo? get_timing_info();
1274 | public int get_time(out usec u);
1275 | public int get_latency(out usec u, out bool negative = null);
1276 |
1277 | public unowned SampleSpec? get_sample_spec();
1278 | public unowned ChannelMap? get_channel_map();
1279 | public unowned BufferAttr? get_buffer_attr();
1280 |
1281 | public int set_monitor_stream(uint32 sink_input);
1282 | public uint32 get_monitor_stream();
1283 | }
1284 |
1285 | [CCode (cname="pa_sink_port_info", has_type_id=false)]
1286 | public struct SinkPortInfo {
1287 | public string name;
1288 | public string description;
1289 | public uint32 priority;
1290 | }
1291 |
1292 | [CCode (cname="pa_sink_info", has_type_id=false)]
1293 | public struct SinkInfo {
1294 | public string name;
1295 | public uint32 index;
1296 | public string description;
1297 | public SampleSpec sample_spec;
1298 | public ChannelMap channel_map;
1299 | public uint32 owner_module;
1300 | public CVolume volume;
1301 | public int mute;
1302 | public uint32 monitor_source;
1303 | public string monitor_source_name;
1304 | public usec latency;
1305 | public string driver;
1306 | public SinkFlags flags;
1307 | public Proplist proplist;
1308 | public usec configured_latency;
1309 | public Volume base_volume;
1310 | public SinkState state;
1311 | public uint32 n_volume_steps;
1312 | public uint32 card;
1313 | public uint32 n_ports;
1314 | [CCode (array_length_cname = "n_ports", array_length_type = "uint32")]
1315 | public SinkPortInfo*[] ports;
1316 | public SinkPortInfo* active_port;
1317 | }
1318 |
1319 | [CCode (cname="pa_source_port_info", has_type_id=false)]
1320 | public struct SourcePortInfo {
1321 | public string name;
1322 | public string description;
1323 | public uint32 priority;
1324 | }
1325 |
1326 | [CCode (cname="pa_source_info", has_type_id=false)]
1327 | public struct SourceInfo {
1328 | public string name;
1329 | public uint32 index;
1330 | public string description;
1331 | public SampleSpec sample_spec;
1332 | public ChannelMap channel_map;
1333 | public uint32 owner_module;
1334 | public CVolume volume;
1335 | public int mute;
1336 | public uint32 monitor_of_sink;
1337 | public string monitor_of_sink_name;
1338 | public usec latency;
1339 | public string driver;
1340 | public SourceFlags flags;
1341 | public Proplist proplist;
1342 | public usec configured_latency;
1343 | public Volume base_volume;
1344 | public SourceState state;
1345 | public uint32 n_volume_steps;
1346 | public uint32 card;
1347 | public uint32 n_ports;
1348 | [CCode (array_length_cname = "n_ports", array_length_type = "uint32")]
1349 | public SourcePortInfo*[] ports;
1350 | public SourcePortInfo* active_port;
1351 | }
1352 |
1353 | [CCode (cname="pa_server_info", has_type_id=false)]
1354 | public struct ServerInfo {
1355 | public string user_name;
1356 | public string host_name;
1357 | public string server_version;
1358 | public string server_name;
1359 | public SampleSpec sample_spec;
1360 | public string default_sink_name;
1361 | public string default_source_name;
1362 | public ChannelMap channel_map;
1363 | }
1364 |
1365 | [CCode (cname="pa_module_info", has_type_id=false)]
1366 | public struct ModuleInfo {
1367 | public uint32 index;
1368 | public string name;
1369 | public string argument;
1370 | public uint32 n_used;
1371 | public Proplist proplist;
1372 | }
1373 |
1374 | [CCode (cname="pa_client_info", has_type_id=false)]
1375 | public struct ClientInfo {
1376 | public uint32 index;
1377 | public string name;
1378 | public uint32 owner_module;
1379 | public string driver;
1380 | public Proplist proplist;
1381 | }
1382 |
1383 | [CCode (cname="pa_card_profile_info", has_type_id=false)]
1384 | public struct CardProfileInfo {
1385 | public string name;
1386 | public string description;
1387 | public uint32 n_sinks;
1388 | public uint32 n_sources;
1389 | public uint32 priority;
1390 | }
1391 |
1392 | [CCode (cname="pa_card_info", has_type_id=false)]
1393 | public struct CardInfo {
1394 | public uint32 index;
1395 | public string name;
1396 | public uint32 owner_module;
1397 | public string driver;
1398 | public uint32 n_profiles;
1399 | public CardProfileInfo[] profiles;
1400 | public CardProfileInfo *active_profile;
1401 | public Proplist proplist;
1402 | }
1403 |
1404 | [CCode (cname="pa_sink_input_info", has_type_id=false)]
1405 | public struct SinkInputInfo {
1406 | public uint32 index;
1407 | public string name;
1408 | public uint32 owner_module;
1409 | public uint32 client;
1410 | public uint32 sink;
1411 | public SampleSpec sample_spec;
1412 | public ChannelMap channel_map;
1413 | public CVolume volume;
1414 | public uint32 buffer_usec;
1415 | public uint32 sink_usec;
1416 | public string resample_method;
1417 | public string driver;
1418 | public int mute;
1419 | public Proplist proplist;
1420 | public int corked;
1421 | public int has_volume;
1422 | public int volume_writable;
1423 | }
1424 |
1425 | [CCode (cname="pa_source_output_info", has_type_id=false)]
1426 | public struct SourceOutputInfo {
1427 | public uint32 index;
1428 | public string name;
1429 | public uint32 owner_module;
1430 | public uint32 client;
1431 | public uint32 source;
1432 | public SampleSpec sample_spec;
1433 | public ChannelMap channel_map;
1434 | public uint32 buffer_usec;
1435 | public uint32 sink_usec;
1436 | public string resample_method;
1437 | public string driver;
1438 | public Proplist proplist;
1439 | public int corked;
1440 | public CVolume volume;
1441 | public int mute;
1442 | public int has_volume;
1443 | public int volume_writable;
1444 | }
1445 |
1446 | [CCode (cname="pa_stat_info", has_type_id=false)]
1447 | public struct StatInfo {
1448 | public uint32 memblock_total;
1449 | public uint32 memblock_total_size;
1450 | public uint32 memblock_allocated;
1451 | public uint32 memblock_allocated_size;
1452 | public uint32 scache_size;
1453 | }
1454 |
1455 | [CCode (cname="pa_sample_info", has_type_id=false)]
1456 | public struct SampleInfo {
1457 | public uint32 index;
1458 | public string name;
1459 | public CVolume volume;
1460 | public SampleSpec sample_spec;
1461 | public ChannelMap channel_map;
1462 | public usec duration;
1463 | public uint32 bytes;
1464 | public bool lazy;
1465 | public string filename;
1466 | public Proplist proplist;
1467 | }
1468 |
1469 | [CCode (cname="pa_sink_flags_t", cprefix="PA_SINK_", has_type_id=false)]
1470 | public enum SinkFlags {
1471 | HW_VOLUME_CTRL,
1472 | LATENCY,
1473 | HARDWARE,
1474 | NETWORK,
1475 | HW_MUTE_CTRL,
1476 | DECIBEL_VOLUME,
1477 | FLAT_VOLUME,
1478 | DYNAMIC_LATENCY
1479 | }
1480 |
1481 | [CCode (cname="pa_source_flags_t", cprefix="PA_SOURCE_", has_type_id=false)]
1482 | public enum SourceFlags {
1483 | HW_VOLUME_CTRL,
1484 | LATENCY,
1485 | HARDWARE,
1486 | NETWORK,
1487 | HW_MUTE_CTRL,
1488 | DECIBEL_VOLUME,
1489 | DYNAMIC_LATENCY
1490 | }
1491 |
1492 | [CCode (cname="pa_sink_state_t", cprefix="PA_SINK_", has_type_id=false)]
1493 | public enum SinkState {
1494 | INVALID_STATE,
1495 | RUNNING,
1496 | IDLE,
1497 | SUSPENDED;
1498 |
1499 | [CCode (cname="PA_SINK_IS_OPENED")]
1500 | public bool IS_OPENED();
1501 | }
1502 |
1503 | [CCode (cname="pa_source_state_t", cprefix="PA_SOURCE_", has_type_id=false)]
1504 | public enum SourceState {
1505 | INVALID_STATE,
1506 | RUNNING,
1507 | IDLE,
1508 | SUSPENDED;
1509 |
1510 | [CCode (cname="PA_SOURCE_IS_OPENED")]
1511 | public bool IS_OPENED();
1512 | }
1513 |
1514 | [CCode (cname="pa_gettimeofday")]
1515 | public unowned timeval gettimeofday(out timeval tv);
1516 |
1517 | [CCode (cname="pa_timeval_diff")]
1518 | public usec timeval_diff(ref timeval a, ref timeval b);
1519 |
1520 | [CCode (cname="pa_timeval_cmp")]
1521 | public int timeval_cmp(ref timeval a, ref timeval b);
1522 |
1523 | [CCode (cname="pa_timeval_age")]
1524 | public usec timeval_age(ref timeval a);
1525 |
1526 | [CCode (cname="pa_timeval_add")]
1527 | public unowned timeval timeval_add(ref timeval tv, usec x);
1528 |
1529 | [CCode (cname="pa_timeval_sub")]
1530 | public unowned timeval timeval_sub(ref timeval tv, usec x);
1531 |
1532 | [CCode (cname="pa_timeval_store")]
1533 | public unowned timeval timeval_store(out timeval tv, usec c);
1534 |
1535 | [CCode (cname="pa_timeval_load")]
1536 | public usec timeval_load(timeval tv);
1537 |
1538 | [CCode (cname="PA_USEC_MAX")]
1539 | public const usec USEC_MAX;
1540 |
1541 | [CCode (cname="PA_USEC_INVALID")]
1542 | public const usec USEC_INVALID;
1543 |
1544 | [CCode (cname="PA_MSEC_PER_SEC")]
1545 | public const usec MSEC_PER_SEC;
1546 |
1547 | [CCode (cname="PA_USEC_PER_SEC")]
1548 | public const usec USEC_PER_SEC;
1549 |
1550 | [CCode (cname="PA_NSEC_PER_SEC")]
1551 | public const uint64 NSEC_PER_SEC;
1552 |
1553 |
1554 | [CCode (cname="PA_USEC_PER_MSEC")]
1555 | public const usec USEC_PER_MSEC;
1556 |
1557 | [CCode (cname="PA_NSEC_PER_MSEC")]
1558 | public const uint64 NSEC_PER_MSEC;
1559 |
1560 |
1561 | [CCode (cname="PA_NSEC_PER_USEC")]
1562 | public const uint64 NSEC_PER_USEC;
1563 | }
1564 |
--------------------------------------------------------------------------------
/meson.build:
--------------------------------------------------------------------------------
1 | project('pulse-flow', 'vala', 'c',
2 | default_options: ['default_library=static']) # link to gtkflow statically
3 |
4 | flow = subproject('libgtkflow', default_options: ['enable_valadoc=false'])
5 |
6 | deps = [
7 | dependency('glib-2.0'),
8 | dependency('gobject-2.0'),
9 | dependency('gtk+-3.0'),
10 |
11 | dependency('libpulse'),
12 | dependency('libpulse-mainloop-glib'),
13 | ]
14 |
15 | src = files([
16 | 'src/Pulse.vala',
17 | 'src/Nodes.vala',
18 | 'src/App.vala'
19 | ])
20 |
21 | executable('pulse-flow',
22 | src,
23 | dependencies: deps,
24 | include_directories: [
25 | flow.get_variable('gflow_inc'),
26 | flow.get_variable('gtkflow_inc')
27 | ],
28 | link_with: [
29 | flow.get_variable('gflow'),
30 | flow.get_variable('gtkflow')
31 | ],
32 | vala_args: ['--vapidir=' + meson.current_source_dir()],
33 | install: true)
34 |
--------------------------------------------------------------------------------
/src/App.vala:
--------------------------------------------------------------------------------
1 | class App : Gtk.Application {
2 | Pulse pa;
3 | GtkFlow.NodeView nodeview;
4 |
5 | public App () {
6 | Object (application_id: "me.iofel.pulse-flow",
7 | flags: ApplicationFlags.FLAGS_NONE);
8 | }
9 |
10 | public override void activate () {
11 | var win = new Gtk.ApplicationWindow (this);
12 | var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
13 | var sw = new Gtk.ScrolledWindow (null, null);
14 | nodeview = new GtkFlow.NodeView ();
15 | sw.add (nodeview);
16 | box.pack_end (sw, true, true);
17 | win.add (box);
18 |
19 | win.set_default_size (1000, 600);
20 | win.show_all ();
21 |
22 | pa = new Pulse ();
23 | pa.new_node.connect (this.add);
24 | pa.delete_node.connect (this.delete);
25 | }
26 |
27 | // positioning
28 | int srcx = 20;
29 | int sinkx = 500;
30 | int srcy = 20;
31 | int sinky = 20;
32 |
33 | private void add (PANode node) {
34 | nodeview.add_with_child (node, node.child);
35 |
36 | // position the nodes
37 | int x, y;
38 | if (node is PASource || node is PASinkInput) {
39 | x = srcx;
40 | y = srcy;
41 | srcy += 150;
42 | } else {
43 | x = sinkx;
44 | y = sinky;
45 | sinky += 150;
46 | }
47 |
48 | nodeview.set_node_position (node, x, y);
49 | }
50 |
51 | private void delete (PANode node) {
52 | if (node is PASource || node is PASinkInput) {
53 | srcy -= 150;
54 | } else {
55 | sinky -= 150;
56 | }
57 | nodeview.remove_node (node);
58 | }
59 | }
60 |
61 | int main (string[] args) {
62 | return new App ().run (args);
63 | }
64 |
--------------------------------------------------------------------------------
/src/Nodes.vala:
--------------------------------------------------------------------------------
1 | using PulseAudio;
2 |
3 | /**
4 | * A class to represent a node in our app
5 | */
6 | abstract class PANode : GFlow.SimpleNode {
7 | public Pulse pa;
8 | public Gtk.Box child = new Gtk.Box (Gtk.Orientation.VERTICAL, 6);
9 | public uint32 index = PulseAudio.INVALID_INDEX;
10 |
11 | construct {
12 | this.deletable = false;
13 | this.resizable = false;
14 | }
15 | }
16 |
17 | class PASource : PANode {
18 | public GFlow.Source src;
19 |
20 | public PASource (Pulse pa) {
21 | this.pa = pa;
22 | src = new GFlow.SimpleSource (0);
23 | src.name = "output";
24 | add_source (src);
25 | }
26 |
27 | public void update (SourceInfo info) {
28 | index = info.index;
29 | name = "(Source #%u) %s".printf (index, info.description);
30 | }
31 | }
32 |
33 | class PASink : PANode {
34 | uint32 monitor = PulseAudio.INVALID_INDEX;
35 | public GFlow.Sink sink;
36 | Gtk.Scale volumescale;
37 | Gtk.Label volumelabel = new Gtk.Label ("100% (0.00dB)");
38 | CVolume vols;
39 |
40 | public PASink (Pulse pa) {
41 | this.pa = pa;
42 | sink = new GFlow.SimpleSink (0);
43 | sink.name = "input";
44 | (sink as GFlow.SimpleSink).max_sources = -1U;
45 | add_sink (sink);
46 |
47 | volumescale = new Gtk.Scale.with_range (Gtk.Orientation.HORIZONTAL,
48 | PulseAudio.Volume.MUTED, PulseAudio.Volume.UI_MAX, PulseAudio.Volume.NORM/100.0);
49 | volumescale.set_value (PulseAudio.Volume.NORM);
50 | volumescale.draw_value = false;
51 | volumescale.add_mark (PulseAudio.Volume.NORM, Gtk.PositionType.BOTTOM, "100% (0dB)");
52 | volumescale.value_changed.connect (() => {
53 | for (var i=0; i {
74 | if (i == null)
75 | return;
76 | var src = new GFlow.SimpleSource (0);
77 | src.name = "monitor";
78 | add_source (src);
79 | });
80 | } else {
81 | // delete monitor
82 | }
83 | }
84 |
85 | // TODO handle multiple channels
86 | var volume = info.volume.values[0];
87 | volumelabel.label = "%s (%s)".printf (volume.sprint (), volume.sw_sprint_dB ());
88 | volumescale.set_value (volume);
89 | }
90 | }
91 |
92 | class PASinkInput : PANode {
93 | GFlow.Source src;
94 | Gtk.Image img;
95 |
96 | public PASinkInput (Pulse pa) {
97 | this.pa = pa;
98 | img = new Gtk.Image.from_icon_name ("dialog-question", Gtk.IconSize.BUTTON);
99 | child.pack_start (img, false, false);
100 | src = new GFlow.SimpleSource (0);
101 | src.name = "output";
102 | add_source (src);
103 | }
104 |
105 | public void update (SinkInputInfo info) {
106 | index = info.index;
107 | name = "(Sink Input #%u) %s".printf (index, info.name);
108 |
109 | if (Proplist.PROP_APPLICATION_ICON_NAME in info.proplist) {
110 | img.set_from_icon_name (info.proplist.gets (Proplist.PROP_APPLICATION_ICON_NAME), Gtk.IconSize.BUTTON);
111 | }
112 |
113 | var sink = pa.sinks[info.sink];
114 | src.unlink_all ();
115 | src.link (sink.sink);
116 | }
117 | }
118 |
119 | class PASourceOutput : PANode {
120 | GFlow.Sink sink;
121 |
122 | public PASourceOutput (Pulse pa) {
123 | this.pa = pa;
124 | sink = new GFlow.SimpleSink (0);
125 | sink.name = "input";
126 | (sink as GFlow.SimpleSink).max_sources = -1U;
127 | add_sink (sink);
128 | }
129 |
130 | public void update (SourceOutputInfo info) {
131 | index = info.index;
132 | name = "(Source Output #%u) %s".printf (index, info.name);
133 |
134 | var src = pa.sources[info.source];
135 | src.unlink_all ();
136 | sink.link (src.src);
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/Pulse.vala:
--------------------------------------------------------------------------------
1 | using PulseAudio;
2 |
3 | /**
4 | * A class to handle connections to pulseaudio and updates to info
5 | */
6 | class Pulse : Object {
7 | public PulseAudio.Context ctx;
8 | private PulseAudio.GLibMainLoop loop;
9 | public HashTable sinks = new HashTable (direct_hash, direct_equal);
10 | public HashTable sources = new HashTable (direct_hash, direct_equal);
11 | public HashTable sinkinputs = new HashTable (direct_hash, direct_equal);
12 | public HashTable sourceoutputs = new HashTable (direct_hash, direct_equal);
13 |
14 | public signal void ready (Context ctx);
15 | public signal void new_node (PANode node);
16 | public signal void delete_node (PANode node);
17 |
18 | public Pulse () {
19 | loop = new PulseAudio.GLibMainLoop ();
20 | ctx = new PulseAudio.Context (loop.get_api (), "me.iofel.pulse-flow");
21 | ctx.set_state_callback (this.state_cb);
22 | ctx.set_subscribe_callback (this.subscribe_cb);
23 |
24 | if (ctx.connect (null, PulseAudio.Context.Flags.NOFAIL) < 0) {
25 | print ("pa_context_connect() failed: %s\n", PulseAudio.strerror (ctx.errno ()));
26 | }
27 | }
28 |
29 | ~Pulse () {
30 | ctx.disconnect ();
31 | }
32 |
33 | /**
34 | * Handle pulseaudio state changes
35 | */
36 | void state_cb (Context ctx) {
37 | Context.State state = ctx.get_state ();
38 | info (@"pa state = $state\n");
39 |
40 | if (ctx.get_state () == Context.State.READY) {
41 | ready (ctx);
42 | ctx.subscribe (Context.SubscriptionMask.ALL, null);
43 | ctx.get_sink_info_list (this.sink_cb);
44 | ctx.get_source_info_list (this.source_cb);
45 | ctx.get_sink_input_info_list (this.sink_input_cb);
46 | ctx.get_source_output_info_list (this.source_output_cb);
47 | }
48 | }
49 |
50 | /**
51 | * Handle any changes from pulseaudio
52 | */
53 | void subscribe_cb (Context ctx, Context.SubscriptionEventType ev, uint32 idx) {
54 | print (@"$ev $idx\n");
55 |
56 | var type = ev & Context.SubscriptionEventType.TYPE_MASK; // type (new, change, remove)
57 | var facility = ev & Context.SubscriptionEventType.FACILITY_MASK; // facility (sink, source, ...)
58 |
59 | if (type == Context.SubscriptionEventType.NEW || type == Context.SubscriptionEventType.CHANGE) {
60 | if (facility == Context.SubscriptionEventType.SINK)
61 | ctx.get_sink_info_by_index (idx, this.sink_cb);
62 | if (facility == Context.SubscriptionEventType.SOURCE)
63 | ctx.get_source_info_by_index (idx, this.source_cb);
64 | if (facility == Context.SubscriptionEventType.SINK_INPUT)
65 | ctx.get_sink_input_info (idx, this.sink_input_cb);
66 | if (facility == Context.SubscriptionEventType.SOURCE_OUTPUT)
67 | ctx.get_source_output_info (idx, this.source_output_cb);
68 | } else if (type == Context.SubscriptionEventType.REMOVE) {
69 | PANode? node = null;
70 | if (facility == Context.SubscriptionEventType.SINK) {
71 | node = this.sinks[idx];
72 | this.sinks.remove (idx);
73 | }
74 | if (facility == Context.SubscriptionEventType.SOURCE) {
75 | node = this.sources[idx];
76 | this.sources.remove (idx);
77 | }
78 | if (facility == Context.SubscriptionEventType.SINK_INPUT) {
79 | node = this.sinkinputs[idx];
80 | this.sinkinputs.remove (idx);
81 | }
82 | if (facility == Context.SubscriptionEventType.SOURCE_OUTPUT) {
83 | node = this.sourceoutputs[idx];
84 | this.sourceoutputs.remove (idx);
85 | }
86 |
87 | if (node != null) {
88 | node.index = PulseAudio.INVALID_INDEX;
89 | node.unlink_all ();
90 | delete_node (node);
91 | }
92 | }
93 | }
94 |
95 | void sink_cb (Context ctx, SinkInfo? info, int eol) {
96 | if (eol < 0) error (PulseAudio.strerror (ctx.errno ()));
97 | if (eol > 0) return;
98 |
99 | var sink = sinks[info.index];
100 | if (sink == null) {
101 | sink = new PASink (this);
102 | sinks[info.index] = sink;
103 | new_node (sink);
104 | }
105 |
106 | sink.update (info);
107 | }
108 |
109 | void source_cb (Context ctx, SourceInfo? info, int eol) {
110 | if (eol < 0) error (PulseAudio.strerror (ctx.errno ()));
111 | if (eol > 0) return;
112 |
113 | // monitors should not be their own nodes
114 | if (info.monitor_of_sink != PulseAudio.INVALID_INDEX)
115 | return;
116 |
117 | PASource source = sources[info.index];
118 | if (source == null) {
119 | source = new PASource (this);
120 | sources[info.index] = source;
121 | new_node (source);
122 | }
123 |
124 | source.update (info);
125 | }
126 |
127 | void sink_input_cb (Context ctx, SinkInputInfo? info, int eol) {
128 | if (eol < 0) error (PulseAudio.strerror (ctx.errno ()));
129 | if (eol > 0) return;
130 |
131 | // don't show nodes that play the volume changed sound
132 | if (info.name == "audio-volume-change")
133 | return;
134 |
135 | PASinkInput sinkinput = sinkinputs[info.index];
136 | if (sinkinput == null) {
137 | sinkinput = new PASinkInput (this);
138 | sinkinputs[info.index] = sinkinput;
139 | new_node (sinkinput);
140 | }
141 |
142 | sinkinput.update (info);
143 | }
144 |
145 | void source_output_cb (Context ctx, SourceOutputInfo? info, int eol) {
146 | if (eol < 0) error (PulseAudio.strerror (ctx.errno ()));
147 | if (eol > 0) return;
148 |
149 | // don't show pavucontrol's peak detect nodes
150 | if (Proplist.PROP_MEDIA_NAME in info.proplist &&
151 | info.proplist.gets (Proplist.PROP_MEDIA_NAME) == "Peak detect")
152 | return;
153 |
154 | PASourceOutput sourceoutput = sourceoutputs[info.index];
155 | if (sourceoutput == null) {
156 | sourceoutput = new PASourceOutput (this);
157 | sourceoutputs[info.index] = sourceoutput;
158 | new_node (sourceoutput);
159 | }
160 |
161 | sourceoutput.update (info);
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/subprojects/.gitignore:
--------------------------------------------------------------------------------
1 | libgtkflow
2 |
--------------------------------------------------------------------------------
/subprojects/libgtkflow.wrap:
--------------------------------------------------------------------------------
1 | [wrap-git]
2 | directory = libgtkflow
3 | url = https://notabug.org/grindhold/libgtkflow.git
4 | revision = 0.6.0
5 |
--------------------------------------------------------------------------------