summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2011-11-02 13:52:58 +0000
committerMike Blumenkrantz <michael.blumenkrantz@gmail.com>2011-11-02 13:52:58 +0000
commit7b68bacceb144392660b0b087ad4c4112e058806 (patch)
tree1b41570a2156a7dbbd1dd69d76a962d1cbd0d767
parent7716a18de8de894e9d3dd215048ea748f907a696 (diff)
update pulse core from e
SVN revision: 64644
-rw-r--r--Pulse.h26
-rw-r--r--pa.c69
-rw-r--r--pa.h10
-rw-r--r--serial.c54
-rw-r--r--sink.c48
5 files changed, 161 insertions, 46 deletions
diff --git a/Pulse.h b/Pulse.h
index 0bc2f24..44d0d62 100644
--- a/Pulse.h
+++ b/Pulse.h
@@ -12,8 +12,15 @@ extern int PULSE_EVENT_CHANGE;
12typedef struct Pulse Pulse; 12typedef struct Pulse Pulse;
13typedef uint32_t Pulse_Tag_Id; 13typedef uint32_t Pulse_Tag_Id;
14typedef struct Pulse_Sink Pulse_Sink; 14typedef struct Pulse_Sink Pulse_Sink;
15typedef struct Pulse_Sink Pulse_Source;
15typedef void (*Pulse_Cb)(Pulse *, Pulse_Tag_Id, void *); 16typedef void (*Pulse_Cb)(Pulse *, Pulse_Tag_Id, void *);
16 17
18typedef struct Pulse_Sink_Port_Info {
19 const char *name; /**< Name of this port */
20 const char *description; /**< Description of this port */
21 uint32_t priority; /**< The higher this value is the more useful this port is as a default */
22} Pulse_Sink_Port_Info;
23
17int pulse_init(void); 24int pulse_init(void);
18void pulse_shutdown(void); 25void pulse_shutdown(void);
19 26
@@ -23,9 +30,18 @@ void pulse_free(Pulse *conn);
23void pulse_cb_set(Pulse *conn, uint32_t tagnum, Pulse_Cb cb); 30void pulse_cb_set(Pulse *conn, uint32_t tagnum, Pulse_Cb cb);
24 31
25uint32_t pulse_cards_get(Pulse *conn); 32uint32_t pulse_cards_get(Pulse *conn);
26uint32_t pulse_sinks_get(Pulse *conn); 33#define pulse_sinks_get(conn) pulse_types_get((conn), EINA_FALSE)
27uint32_t pulse_sink_get(Pulse *conn, uint32_t idx); 34#define pulse_sources_get(conn) pulse_types_get((conn), EINA_TRUE)
28uint32_t pulse_sink_mute_set(Pulse *conn, uint32_t idx, Eina_Bool mute); 35uint32_t pulse_types_get(Pulse *conn, Eina_Bool source);
36#define pulse_sink_get(conn, idx) pulse_type_get((conn), (idx), EINA_FALSE)
37#define pulse_source_get(conn, idx) pulse_type_get((conn), (idx), EINA_FALSE)
38uint32_t pulse_type_get(Pulse *conn, uint32_t idx, Eina_Bool source);
39#define pulse_sink_mute_set(conn, idx, mute) pulse_type_mute_set((conn), (idx), (mute), EINA_FALSE)
40#define pulse_source_mute_set(conn, idx, mute) pulse_type_mute_set((conn), (idx), (mute), EINA_TRUE)
41uint32_t pulse_type_mute_set(Pulse *conn, uint32_t idx, Eina_Bool mute, Eina_Bool source);
42#define pulse_sink_volume_set(conn, idx, channels, vol) pulse_type_volume_set((conn), (idx), (channels), (vol), EINA_FALSE)
43#define pulse_source_volume_set(conn, idx, channels, vol) pulse_type_volume_set((conn), (idx), (channels), (vol), EINA_TRUE)
44uint32_t pulse_type_volume_set(Pulse *conn, uint32_t sink_num, uint8_t channels, double vol, Eina_Bool source);
29 45
30void pulse_sink_free(Pulse_Sink *sink); 46void pulse_sink_free(Pulse_Sink *sink);
31const char *pulse_sink_name_get(Pulse_Sink *sink); 47const char *pulse_sink_name_get(Pulse_Sink *sink);
@@ -38,7 +54,11 @@ uint8_t pulse_sink_channels_count(Pulse_Sink *sink);
38Eina_List *pulse_sink_channel_names_get(Pulse_Sink *sink); 54Eina_List *pulse_sink_channel_names_get(Pulse_Sink *sink);
39Eina_Bool pulse_sinks_watch(Pulse *conn); 55Eina_Bool pulse_sinks_watch(Pulse *conn);
40 56
57const Eina_List *pulse_sink_ports_get(Pulse_Sink *sink);
58const char *pulse_sink_port_active_get(Pulse_Sink *sink);
59#define pulse_source_channel_volume_set pulse_sink_channel_volume_set
41uint32_t pulse_sink_channel_volume_set(Pulse *conn, Pulse_Sink *sink, uint32_t id, double vol); 60uint32_t pulse_sink_channel_volume_set(Pulse *conn, Pulse_Sink *sink, uint32_t id, double vol);
61uint32_t pulse_sink_port_set(Pulse *conn, Pulse_Sink *sink, const char *port);
42double pulse_sink_channel_volume_get(Pulse_Sink *sink, unsigned int id); 62double pulse_sink_channel_volume_get(Pulse_Sink *sink, unsigned int id);
43float pulse_sink_channel_balance_get(Pulse_Sink *sink, unsigned int id); 63float pulse_sink_channel_balance_get(Pulse_Sink *sink, unsigned int id);
44float pulse_sink_channel_depth_get(Pulse_Sink *sink, unsigned int id); 64float pulse_sink_channel_depth_get(Pulse_Sink *sink, unsigned int id);
diff --git a/pa.c b/pa.c
index 2111520..a30bab0 100644
--- a/pa.c
+++ b/pa.c
@@ -15,6 +15,7 @@ int PULSE_EVENT_CONNECTED = -1;
15int PULSE_EVENT_DISCONNECTED = -1; 15int PULSE_EVENT_DISCONNECTED = -1;
16int PULSE_EVENT_CHANGE = -1; 16int PULSE_EVENT_CHANGE = -1;
17Eina_Hash *pulse_sinks = NULL; 17Eina_Hash *pulse_sinks = NULL;
18Eina_Hash *pulse_sources = NULL;
18 19
19void 20void
20pulse_fake_free(void *d __UNUSED__, void *d2 __UNUSED__) 21pulse_fake_free(void *d __UNUSED__, void *d2 __UNUSED__)
@@ -390,11 +391,11 @@ pulse_cb_set(Pulse *conn, uint32_t tagnum, Pulse_Cb cb)
390} 391}
391 392
392uint32_t 393uint32_t
393pulse_sink_get(Pulse *conn, uint32_t sink_num) 394pulse_type_get(Pulse *conn, uint32_t idx, Eina_Bool source)
394{ 395{
395 Pulse_Tag *tag; 396 Pulse_Tag *tag;
396 int read; 397 int read;
397 uint32_t type = PA_COMMAND_GET_SINK_INFO; 398 uint32_t type = source ? PA_COMMAND_GET_SOURCE_INFO : PA_COMMAND_GET_SINK_INFO;
398 399
399 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); 400 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
400 tag = calloc(1, sizeof(Pulse_Tag)); 401 tag = calloc(1, sizeof(Pulse_Tag));
@@ -403,7 +404,7 @@ pulse_sink_get(Pulse *conn, uint32_t sink_num)
403 tag->data = malloc(tag->dsize); 404 tag->data = malloc(tag->dsize);
404 tag->tag_count = conn->tag_count; 405 tag->tag_count = conn->tag_count;
405 tag_simple_init(conn, tag, type, PA_TAG_U32); 406 tag_simple_init(conn, tag, type, PA_TAG_U32);
406 tag_uint32(tag, sink_num); 407 tag_uint32(tag, idx);
407 tag_string(tag, NULL); 408 tag_string(tag, NULL);
408 tag_finish(tag); 409 tag_finish(tag);
409 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; 410 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
@@ -414,11 +415,11 @@ pulse_sink_get(Pulse *conn, uint32_t sink_num)
414} 415}
415 416
416uint32_t 417uint32_t
417pulse_sinks_get(Pulse *conn) 418pulse_types_get(Pulse *conn, Eina_Bool source)
418{ 419{
419 Pulse_Tag *tag; 420 Pulse_Tag *tag;
420 int read; 421 int read;
421 uint32_t type = PA_COMMAND_GET_SINK_INFO_LIST; 422 uint32_t type = source ? PA_COMMAND_GET_SOURCE_INFO_LIST : PA_COMMAND_GET_SINK_INFO_LIST;
422 423
423 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); 424 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
424 tag = calloc(1, sizeof(Pulse_Tag)); 425 tag = calloc(1, sizeof(Pulse_Tag));
@@ -436,11 +437,12 @@ pulse_sinks_get(Pulse *conn)
436} 437}
437 438
438uint32_t 439uint32_t
439pulse_sink_mute_set(Pulse *conn, uint32_t sink_num, Eina_Bool mute) 440pulse_type_mute_set(Pulse *conn, uint32_t sink_num, Eina_Bool mute, Eina_Bool source)
440{ 441{
441 Pulse_Tag *tag; 442 Pulse_Tag *tag;
442 int read; 443 int read;
443 uint32_t type = PA_COMMAND_SET_SINK_MUTE; 444 uint32_t type = source ? PA_COMMAND_SET_SOURCE_MUTE : PA_COMMAND_SET_SINK_MUTE;
445 Eina_Hash *h;
444 446
445 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); 447 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
446 tag = calloc(1, sizeof(Pulse_Tag)); 448 tag = calloc(1, sizeof(Pulse_Tag));
@@ -457,22 +459,23 @@ pulse_sink_mute_set(Pulse *conn, uint32_t sink_num, Eina_Bool mute)
457 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE); 459 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
458 conn->oq = eina_list_append(conn->oq, tag); 460 conn->oq = eina_list_append(conn->oq, tag);
459 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); 461 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
460 if (pulse_sinks) 462 h = (source) ? pulse_sources : pulse_sinks;
463 if (h)
461 { 464 {
462 Pulse_Sink *sink; 465 Pulse_Sink *sink;
463 466
464 sink = eina_hash_find(pulse_sinks, &sink_num); 467 sink = eina_hash_find(h, &sink_num);
465 if (sink) sink->mute = !!mute; 468 if (sink) sink->mute = !!mute;
466 } 469 }
467 return tag->tag_count; 470 return tag->tag_count;
468} 471}
469 472
470uint32_t 473uint32_t
471pulse_sink_volume_set(Pulse *conn, uint32_t sink_num, uint8_t channels, double vol) 474pulse_type_volume_set(Pulse *conn, uint32_t sink_num, uint8_t channels, double vol, Eina_Bool source)
472{ 475{
473 Pulse_Tag *tag; 476 Pulse_Tag *tag;
474 int read; 477 int read;
475 uint32_t type = PA_COMMAND_SET_SINK_VOLUME; 478 uint32_t type = source ? PA_COMMAND_SET_SOURCE_MUTE : PA_COMMAND_SET_SINK_VOLUME;
476 479
477 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); 480 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
478 tag = calloc(1, sizeof(Pulse_Tag)); 481 tag = calloc(1, sizeof(Pulse_Tag));
@@ -497,12 +500,13 @@ pulse_sink_channel_volume_set(Pulse *conn, Pulse_Sink *sink, uint32_t id, double
497{ 500{
498 Pulse_Tag *tag; 501 Pulse_Tag *tag;
499 int read; 502 int read;
500 uint32_t type = PA_COMMAND_SET_SINK_VOLUME; 503 uint32_t type;
501 504
502 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); 505 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
503 EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, 0); 506 EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, 0);
504 tag = calloc(1, sizeof(Pulse_Tag)); 507 tag = calloc(1, sizeof(Pulse_Tag));
505 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); 508 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
509 type = sink->source ? PA_COMMAND_SET_SOURCE_VOLUME : PA_COMMAND_SET_SINK_VOLUME;
506 tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_CVOLUME + sink->channel_map.channels * sizeof(uint32_t); 510 tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_CVOLUME + sink->channel_map.channels * sizeof(uint32_t);
507 tag->data = malloc(tag->dsize); 511 tag->data = malloc(tag->dsize);
508 tag->tag_count = conn->tag_count; 512 tag->tag_count = conn->tag_count;
@@ -520,6 +524,42 @@ pulse_sink_channel_volume_set(Pulse *conn, Pulse_Sink *sink, uint32_t id, double
520 return tag->tag_count; 524 return tag->tag_count;
521} 525}
522 526
527uint32_t
528pulse_sink_port_set(Pulse *conn, Pulse_Sink *sink, const char *port)
529{
530 Pulse_Tag *tag;
531 int read;
532 uint32_t type;
533 Eina_List *l;
534 const char *p;
535 Eina_Bool match = EINA_FALSE;
536
537 EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0);
538 EINA_SAFETY_ON_NULL_RETURN_VAL(port, 0);
539 EINA_LIST_FOREACH(sink->ports, l, p)
540 {
541 match = !strcmp(p, port);
542 if (match) break;
543 }
544 EINA_SAFETY_ON_TRUE_RETURN_VAL(!match, 0);
545 tag = calloc(1, sizeof(Pulse_Tag));
546 EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0);
547 type = sink->source ? PA_COMMAND_SET_SOURCE_PORT : PA_COMMAND_SET_SINK_PORT;
548 tag->dsize = PA_TAG_SIZE_U32 + 2 * PA_TAG_SIZE_STRING + strlen(sink->name) + strlen(port);
549 tag->data = malloc(tag->dsize);
550 tag->tag_count = conn->tag_count;
551 tag_simple_init(conn, tag, type, PA_TAG_U32);
552 tag_uint32(tag, sink->index);
553 tag_string(tag, sink->name);
554 tag_string(tag, port);
555 tag_finish(tag);
556 read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ;
557 ecore_main_fd_handler_active_set(conn->fdh, read | ECORE_FD_WRITE);
558 conn->oq = eina_list_append(conn->oq, tag);
559 eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type));
560 return tag->tag_count;
561}
562
523Eina_Bool 563Eina_Bool
524pulse_sinks_watch(Pulse *conn) 564pulse_sinks_watch(Pulse *conn)
525{ 565{
@@ -563,6 +603,9 @@ pulse_shutdown(void)
563{ 603{
564 if ((!pulse_init_count) || (!--pulse_init_count)) return; 604 if ((!pulse_init_count) || (!--pulse_init_count)) return;
565 605
606 if (pulse_sinks) eina_hash_free(pulse_sinks);
607 if (pulse_sources) eina_hash_free(pulse_sources);
608 pulse_sinks = pulse_sources = NULL;
566 eina_log_domain_unregister(pa_log_dom); 609 eina_log_domain_unregister(pa_log_dom);
567 ecore_con_shutdown(); 610 ecore_con_shutdown();
568 ecore_shutdown(); 611 ecore_shutdown();
@@ -574,7 +617,7 @@ pulse_new(void)
574{ 617{
575 Pulse *conn; 618 Pulse *conn;
576 Eina_Iterator *it; 619 Eina_Iterator *it;
577 const char *dir, *prev, *buf = NULL;; 620 const char *dir, *prev = NULL, *buf = NULL;;
578 time_t time = 0; 621 time_t time = 0;
579 char *home, h[4096]; 622 char *home, h[4096];
580 623
diff --git a/pa.h b/pa.h
index fdcce31..5f726fd 100644
--- a/pa.h
+++ b/pa.h
@@ -432,12 +432,6 @@ typedef struct pa_cvolume {
432 pa_volume_t values[PA_CHANNELS_MAX]; /**< Per-channel volume */ 432 pa_volume_t values[PA_CHANNELS_MAX]; /**< Per-channel volume */
433} pa_cvolume; 433} pa_cvolume;
434 434
435typedef struct pa_sink_port_info {
436 const char *name; /**< Name of this port */
437 const char *description; /**< Description of this port */
438 uint32_t priority; /**< The higher this value is the more useful this port is as a default */
439} pa_sink_port_info;
440
441typedef struct pa_channel_map { 435typedef struct pa_channel_map {
442 uint8_t channels; 436 uint8_t channels;
443 /**< Number of channels */ 437 /**< Number of channels */
@@ -460,8 +454,11 @@ struct Pulse_Sink {
460 pa_channel_map channel_map; /**< Channel map */ 454 pa_channel_map channel_map; /**< Channel map */
461// uint32_t owner_module; /**< Index of the owning module of this sink, or PA_INVALID_INDEX */ 455// uint32_t owner_module; /**< Index of the owning module of this sink, or PA_INVALID_INDEX */
462 pa_cvolume volume; /**< Volume of the sink */ 456 pa_cvolume volume; /**< Volume of the sink */
457 Eina_List *ports; /**< output ports */
458 const char *active_port; /**< currently active port */
463 Eina_Bool mute : 1; /**< Mute switch of the sink */ 459 Eina_Bool mute : 1; /**< Mute switch of the sink */
464 Eina_Bool update : 1; 460 Eina_Bool update : 1;
461 Eina_Bool source : 1; /**< sink is actually a source */
465}; 462};
466 463
467typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX]; 464typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX];
@@ -537,5 +534,6 @@ void msg_send_creds(Pulse *conn, Pulse_Tag *tag);
537Eina_Bool msg_send(Pulse *conn, Pulse_Tag *tag); 534Eina_Bool msg_send(Pulse *conn, Pulse_Tag *tag);
538 535
539extern Eina_Hash *pulse_sinks; 536extern Eina_Hash *pulse_sinks;
537extern Eina_Hash *pulse_sources;
540 538
541#endif 539#endif
diff --git a/serial.c b/serial.c
index ad1ce27..d113afb 100644
--- a/serial.c
+++ b/serial.c
@@ -14,25 +14,34 @@ deserialize_sinks_watcher(Pulse *conn, Pulse_Tag *tag)
14 Pulse_Sink *sink; 14 Pulse_Sink *sink;
15 15
16 sink = eina_hash_find(pulse_sinks, &idx); 16 sink = eina_hash_find(pulse_sinks, &idx);
17 if (!sink) return; 17 if (sink)
18 if (pulse_sink_get(conn, idx)) 18 {
19 sink->update = EINA_TRUE; 19 if (pulse_sink_get(conn, idx))
20 sink->update = EINA_TRUE;
21 }
22 else
23 {
24 sink = eina_hash_find(pulse_sources, &idx);
25 if (!sink) return;
26 if (pulse_source_get(conn, idx))
27 sink->update = EINA_TRUE;
28 }
20 } 29 }
21} 30}
22 31
23Pulse_Sink * 32static Pulse_Sink *
24deserialize_sink(Pulse *conn __UNUSED__, Pulse_Tag *tag) 33deserialize_sink(Pulse *conn __UNUSED__, Pulse_Tag *tag, Eina_Bool source)
25{ 34{
26 Pulse_Sink *sink; 35 Pulse_Sink *sink = NULL;
27 Eina_Bool mute, exist; 36 Eina_Bool mute, exist;
28 pa_sample_spec spec; 37 pa_sample_spec spec;
29 uint32_t owner_module, monitor_source, flags, base_volume, state, n_volume_steps, card, n_ports; 38 uint32_t owner_module, monitor_source, flags, base_volume, state, n_volume_steps, card, n_ports;
30 uint64_t latency, configured_latency; 39 uint64_t latency, configured_latency;
31 const char *monitor_source_name, *driver, *active_port; 40 const char *monitor_source_name, *driver;
32 Eina_Hash *props; 41 Eina_Hash *props;
33 unsigned int x; 42 unsigned int x;
34 43
35 monitor_source_name = driver = active_port = NULL; 44 monitor_source_name = driver = NULL;
36 EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &x), error); 45 EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &x), error);
37 sink = eina_hash_find(pulse_sinks, &x); 46 sink = eina_hash_find(pulse_sinks, &x);
38 exist = !!sink; 47 exist = !!sink;
@@ -63,21 +72,26 @@ deserialize_sink(Pulse *conn __UNUSED__, Pulse_Tag *tag)
63 72
64 for (x = 0; x < n_ports; x++) 73 for (x = 0; x < n_ports; x++)
65 { 74 {
66 pa_sink_port_info pi = {NULL, NULL, 0}; 75 Pulse_Sink_Port_Info *pi;
67 76
68 EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &pi.name), error); 77 pi = calloc(1, sizeof(Pulse_Sink_Port_Info));
69 eina_stringshare_del(pi.name); 78 EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &pi->name), error);
70 EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &pi.description), error); 79 eina_stringshare_del(pi->name);
71 eina_stringshare_del(pi.description); 80 EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &pi->description), error);
72 EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &pi.priority), error); 81 eina_stringshare_del(pi->description);
82 EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &pi->priority), error);
83 sink->ports = eina_list_append(sink->ports, pi);
73 } 84 }
74 EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &active_port), error); 85 EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &sink->active_port), error);
75 if (exist) 86 if (exist)
76 ecore_event_add(PULSE_EVENT_CHANGE, sink, pulse_fake_free, NULL); 87 ecore_event_add(PULSE_EVENT_CHANGE, sink, pulse_fake_free, NULL);
77 else 88 else
78 { 89 {
79 if (!pulse_sinks) pulse_sinks = eina_hash_int32_new(NULL); 90 if (source && (!pulse_sources))
80 eina_hash_add(pulse_sinks, (uintptr_t*)&sink->index, sink); 91 pulse_sources = eina_hash_int32_new((Eina_Free_Cb)pulse_sink_free);
92 else if ((!source) && (!pulse_sinks))
93 pulse_sinks = eina_hash_int32_new((Eina_Free_Cb)pulse_sink_free);
94 eina_hash_add(source ? pulse_sources : pulse_sinks, (uintptr_t*)&sink->index, sink);
81 } 95 }
82 return sink; 96 return sink;
83error: 97error:
@@ -97,13 +111,14 @@ deserialize_tag(Pulse *conn, PA_Commands command, Pulse_Tag *tag)
97 switch (command) 111 switch (command)
98 { 112 {
99 case PA_COMMAND_GET_SINK_INFO_LIST: 113 case PA_COMMAND_GET_SINK_INFO_LIST:
114 case PA_COMMAND_GET_SOURCE_INFO_LIST:
100 if (!cb) return EINA_TRUE; 115 if (!cb) return EINA_TRUE;
101 ev = NULL; 116 ev = NULL;
102 while (tag->size < tag->dsize - PA_TAG_SIZE_STRING_NULL) 117 while (tag->size < tag->dsize - PA_TAG_SIZE_STRING_NULL)
103 { 118 {
104 Pulse_Sink *sink; 119 Pulse_Sink *sink;
105 120
106 sink = deserialize_sink(conn, tag); 121 sink = deserialize_sink(conn, tag, (command == PA_COMMAND_GET_SOURCE_INFO_LIST));
107 if (!sink) 122 if (!sink)
108 { 123 {
109 EINA_LIST_FREE(ev, sink) 124 EINA_LIST_FREE(ev, sink)
@@ -114,8 +129,9 @@ deserialize_tag(Pulse *conn, PA_Commands command, Pulse_Tag *tag)
114 } 129 }
115 break; 130 break;
116 case PA_COMMAND_GET_SINK_INFO: 131 case PA_COMMAND_GET_SINK_INFO:
132 case PA_COMMAND_GET_SOURCE_INFO:
117 if ((!cb) && (!conn->watching)) return EINA_TRUE; 133 if ((!cb) && (!conn->watching)) return EINA_TRUE;
118 ev = deserialize_sink(conn, tag); 134 ev = deserialize_sink(conn, tag, (command == PA_COMMAND_GET_SOURCE_INFO));
119 break; 135 break;
120 case 0: 136 case 0:
121 deserialize_sinks_watcher(conn, tag); 137 deserialize_sinks_watcher(conn, tag);
diff --git a/sink.c b/sink.c
index 7959e6b..b357110 100644
--- a/sink.c
+++ b/sink.c
@@ -150,16 +150,52 @@ static Eina_Bool on_rear(pa_channel_position_t p) {
150 return !!(PA_CHANNEL_POSITION_MASK(p) & PA_CHANNEL_POSITION_MASK_REAR); 150 return !!(PA_CHANNEL_POSITION_MASK(p) & PA_CHANNEL_POSITION_MASK_REAR);
151} 151}
152 152
153static void
154pulse_sink_port_info_free(Pulse_Sink_Port_Info *pi)
155{
156 if (!pi) return;
157 eina_stringshare_del(pi->name);
158 eina_stringshare_del(pi->description);
159 free(pi);
160}
161
153void 162void
154pulse_sink_free(Pulse_Sink *sink) 163pulse_sink_free(Pulse_Sink *sink)
155{ 164{
165 Pulse_Sink_Port_Info *pi;
156 if (!sink) return; 166 if (!sink) return;
167 if (sink->source)
168 {
169 if (eina_hash_del_by_key(pulse_sources, (uintptr_t*)&sink->index))
170 return;
171 }
172 else
173 {
174 if (eina_hash_del_by_key(pulse_sinks, (uintptr_t*)&sink->index))
175 return;
176 }
157 eina_stringshare_del(sink->name); 177 eina_stringshare_del(sink->name);
158 eina_stringshare_del(sink->description); 178 eina_stringshare_del(sink->description);
159 eina_hash_del_by_key(pulse_sinks, (uintptr_t*)&sink->index); 179 EINA_LIST_FREE(sink->ports, pi)
180 pulse_sink_port_info_free(pi);
181 eina_stringshare_del(sink->active_port);
160 free(sink); 182 free(sink);
161} 183}
162 184
185const Eina_List *
186pulse_sink_ports_get(Pulse_Sink *sink)
187{
188 EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL);
189 return sink->ports;
190}
191
192const char *
193pulse_sink_port_active_get(Pulse_Sink *sink)
194{
195 EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL);
196 return sink->active_port;
197}
198
163const char * 199const char *
164pulse_sink_name_get(Pulse_Sink *sink) 200pulse_sink_name_get(Pulse_Sink *sink)
165{ 201{
@@ -226,9 +262,8 @@ pulse_sink_channel_names_get(Pulse_Sink *sink)
226 unsigned int x; 262 unsigned int x;
227 263
228 EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL); 264 EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL);
229 265 for (x = 0; x < sink->volume.channels; x++)
230 for (x = 0; x < sink->channel_map.channels; x++) 266 ret = eina_list_append(ret, pulse_sink_channel_id_get_name(sink, x));
231 ret = eina_list_append(ret, eina_stringshare_add(channel_name_table[x]));
232 return ret; 267 return ret;
233} 268}
234 269
@@ -240,7 +275,10 @@ pulse_sink_channel_name_get_id(Pulse_Sink *sink, const char *name)
240 EINA_SAFETY_ON_NULL_RETURN_VAL(sink, UINT_MAX); 275 EINA_SAFETY_ON_NULL_RETURN_VAL(sink, UINT_MAX);
241 EINA_SAFETY_ON_NULL_RETURN_VAL(name, UINT_MAX); 276 EINA_SAFETY_ON_NULL_RETURN_VAL(name, UINT_MAX);
242 for (x = 0; x < sink->channel_map.channels; x++) 277 for (x = 0; x < sink->channel_map.channels; x++)
243 if (!strcmp(name, channel_name_table[sink->channel_map.map[x]])) return x; 278 {
279 if (!strcmp(name, channel_name_table[sink->channel_map.map[x]]))
280 return x;
281 }
244 return UINT_MAX; 282 return UINT_MAX;
245} 283}
246 284