summaryrefslogtreecommitdiff
path: root/pa-sink-ctl.c
blob: acd13d5bd038b5dd56b5e12bfdadea6ea3452dcb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <stdio.h>
#include <pulse/pulseaudio.h>
#include <ncurses.h>
#include <string.h>

static void context_state_callback(pa_context*, void *);
static void get_sink_input_info_callback(pa_context *, const pa_sink_input_info*, int, void *);

typedef struct _sink_input_info {
	uint32_t sink;
	char *name;
	char *pid;
	pa_volume_t vol;
} sink_input_info;

static sink_input_info** sink_input_list = 0;
int sink_input_counter;
int sink_input_max;

static pa_mainloop_api *mainloop_api = NULL;
static pa_context *context = NULL;

int main(int argc, char** argv)
{
	sink_input_counter = 0;
	sink_input_max = 1;

	sink_input_list = (sink_input_list**) calloc(sink_input_max, sizeof(sink_input_info*));

	pa_mainloop *m = NULL;
	int ret = 1;

	if(!(m = pa_mainloop_new())) {
		printf("error: pa_mainloop_new() failed.\n");
		return -1;
	}

	mainloop_api = pa_mainloop_get_api(m);

	if (!(context = pa_context_new(mainloop_api, "pa-sink-ctl"))) {
		printf("error: pa_context_new() failed.\n");
		return -1;
	}

	pa_context_set_state_callback(context, context_state_callback, NULL);
	if (pa_context_connect(context, "tcp:127.0.0.1:4713", PA_CONTEXT_NOAUTOSPAWN, NULL)) {
		printf("error: pa_context_connect() failed.\n");
	}

	if (pa_mainloop_run(m, &ret) < 0) {
		printf("error: pa_mainloop_run() failed.\n");
		return -1;
	}

	return ret;
}

static void context_state_callback(pa_context *c, void *userdata) {

	switch (pa_context_get_state(c)) {
		case PA_CONTEXT_CONNECTING:
			printf("connecting...\n");
			break;

		case PA_CONTEXT_AUTHORIZING:
			printf("authorizing...\n");
			break;

		case PA_CONTEXT_SETTING_NAME:
			printf("setting name\n");
			break;

		case PA_CONTEXT_READY:
			printf("Menue\n");

			pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL));
			break;
		default:
			printf("unknown state\n");
			break;
	}
}

static void get_sink_input_info_callback(pa_context *c, const pa_sink_input_info *i, int is_last, void *userdata) {
	char t[32], k[32], cv[PA_CVOLUME_SNPRINT_MAX];

	if (is_last < 0) {
		printf("Failed to get sink input information: %s\n", pa_strerror(pa_context_errno(c)));
		return;
	}

	if (is_last) {
//		print_sinks(sink_list);
		return;
	}

	snprintf(t, sizeof(t), "%u", i->owner_module);
	snprintf(k, sizeof(k), "%u", i->client);

	printf( "Sink Input #%u"
		"\tClient: %s"
		"\tSink: %u"
		"\tMute: %d"
		"\tVolume: %s"
		"\tname: %s"
		"\tpid: %s\n",
			i->index,
			i->client != PA_INVALID_INDEX ? k : "n/a",
			i->sink,
			i->mute,
			pa_cvolume_snprint(cv, sizeof(cv), &i->volume),
			pa_proplist_gets(i->proplist, "application.name"),
			pa_proplist_gets(i->proplist, "application.process.id"));

	++sink_input_counter;

	if (sink_input_counter >= sink_input_max) {
		sink_input_max*=2;
		sink_input_list = (sink_input_list**) realloc(sink_input_max, sizeof(sink_input_info) * sink_input_max);
	}

	sink_input_list[sink_input_counter] = (sink_input_info*) calloc(1, sizeof(sink_input_info));
	sink_input_list[sink_input_counter]->name = (char*) calloc(strlen(i->name) + 1, sizeof(char));

	sink_input_list[sink_input_counter]->sink = i->sink;
	strncpy(sink_input_list[sink_input_counter]->name, i->name, strlen(i->name));
	sink_input_list[sink_input_counter]->vol = pa_cvolume_avg(&i->volume);
}