From 56c5f9340057766c66a7814ab71c111eb0d83cdb Mon Sep 17 00:00:00 2001 From: ben Date: Mon, 12 Jul 2010 11:24:25 +0200 Subject: move sources to src/ --- .gitignore | 2 +- Makefile.am | 8 +-- configure.ac | 4 +- interface.c | 147 ---------------------------------------- interface.h | 17 ----- pa-sink-ctl.c | 195 ------------------------------------------------------ pa-sink-ctl.h | 25 ------- sink.c | 93 -------------------------- sink.h | 35 ---------- sink_input.c | 78 ---------------------- sink_input.h | 25 ------- src/Makefile.am | 7 ++ src/interface.c | 147 ++++++++++++++++++++++++++++++++++++++++ src/interface.h | 17 +++++ src/pa-sink-ctl.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/pa-sink-ctl.h | 25 +++++++ src/sink.c | 93 ++++++++++++++++++++++++++ src/sink.h | 35 ++++++++++ src/sink_input.c | 78 ++++++++++++++++++++++ src/sink_input.h | 25 +++++++ 20 files changed, 626 insertions(+), 625 deletions(-) delete mode 100644 interface.c delete mode 100644 interface.h delete mode 100644 pa-sink-ctl.c delete mode 100644 pa-sink-ctl.h delete mode 100644 sink.c delete mode 100644 sink.h delete mode 100644 sink_input.c delete mode 100644 sink_input.h create mode 100644 src/Makefile.am create mode 100644 src/interface.c create mode 100644 src/interface.h create mode 100644 src/pa-sink-ctl.c create mode 100644 src/pa-sink-ctl.h create mode 100644 src/sink.c create mode 100644 src/sink.h create mode 100644 src/sink_input.c create mode 100644 src/sink_input.h diff --git a/.gitignore b/.gitignore index f14c694..8bba070 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,4 @@ depcomp autom4te.cache/* # Dependency tree -.deps/* +src/.deps/* diff --git a/Makefile.am b/Makefile.am index 8b4e688..af437a6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1 @@ -bin_PROGRAMS = pa_sink_ctl -pa_sink_ctl_SOURCES =interface.c pa-sink-ctl.c sink.c sink_input.c - -AM_CFLAGS =-std=c99 -pedantic -Wall -Werror @PULSE_CFLAGS@ -pa_sink_ctl_LDADD =@PULSE_LIBS@ @CURSES_LIBS@ - -noinst_HEADERS = interface.h pa-sink-ctl.h sink.h sink_input.h +SUBDIRS = src diff --git a/configure.ac b/configure.ac index e6a7615..34d004b 100644 --- a/configure.ac +++ b/configure.ac @@ -2,9 +2,9 @@ AC_INIT([pa-sink-ctl], [0.1], [web2p10@wemelug.de]) AM_INIT_AUTOMAKE -AC_CONFIG_SRCDIR([pa-sink-ctl.c]) +AC_CONFIG_SRCDIR([src/pa-sink-ctl.c]) AC_CONFIG_HEADERS([config.h]) -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([Makefile src/Makefile]) # Checks for programs. AC_PROG_CC diff --git a/interface.c b/interface.c deleted file mode 100644 index c48b953..0000000 --- a/interface.c +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include -#include -#include -#include - -#include "interface.h" -#include "sink.h" -#include "pa-sink-ctl.h" - -#define VOLUME_MAX UINT16_MAX -#define VOLUME_BAR_LEN 50 -#define WIDTH 80 -#define HEIGHT 10 - -// ncurses -WINDOW *menu_win; -int chooser; -int startx; -int starty; - -extern int sink_counter; -extern int sink_max; -extern sink_info** sink_list; - -extern pa_context* context; - -void interface_init(void) -{ - // ncurses - chooser = 0; - - initscr(); - clear(); - noecho(); - cbreak(); /* Line buffering disabled. pass on everything */ - startx = (80 - WIDTH) / 2; - starty = (24 - HEIGHT) / 2; - menu_win = newwin(HEIGHT, WIDTH, starty, startx); - keypad(menu_win, TRUE); - mvprintw(0, 0, "Use arrow keys to go up and down, Press enter to select a choice"); - refresh(); -} - -void print_sinks(void) { - int x, y, i; - x = 2; - y = 2; - - box(menu_win, 0, 0); - -// printf("print sinks: %d\n", sink_input_counter); - -// qsort(sink_input_list, sink_input_counter, sizeof(sink_input_info*), cmp_sink_input_list); - - for (i = 0; i < sink_counter; ++i) { - mvwprintw(menu_win, y+i, x, "%d\t%s\t", - sink_list[i]->index, - sink_list[i]->name); - } - y += i; -/* for (i = 0; i < sink_input_counter; ++i) { - if (i == chooser) - wattron(menu_win, A_REVERSE); - - mvwprintw(menu_win, y+i, x, "%d\t%s\t", - sink_input_list[i]->sink, - sink_input_list[i]->name); - - if (i == chooser) - wattroff(menu_win, A_REVERSE); - - print_volume(sink_input_list[i]->vol, y+i); - }*/ -} - -void print_volume(pa_volume_t volume, int y) { - - int x = 20; - - unsigned int vol = (unsigned int) ( (((double)volume) / ((double)VOLUME_MAX)) * VOLUME_BAR_LEN ); - mvwprintw(menu_win, y, x - 1 , "["); - for (int i = 0; i < vol; ++i) - mvwprintw(menu_win, y, x + i, "="); - for (int i = vol; i < VOLUME_BAR_LEN; ++i) - mvwprintw(menu_win, y, x + i, " "); - - mvwprintw(menu_win, y, x + VOLUME_BAR_LEN, "]"); -} - -void get_input(void) -{ - int c; -// uint32_t sink; - c = wgetch(menu_win); - switch (c) { - case KEY_UP: - if (chooser > 0) - --chooser; - break; - - case KEY_DOWN: -// if (chooser < sink_input_counter - 1) -// ++chooser; - break; - - case KEY_LEFT: - break; - - case KEY_RIGHT: - break; - - case 32: - -/* if (sink_input_list[chooser]->sink < sink_max) - sink = sink_input_list[chooser]->sink + 1; - else - sink = 0; - - pa_operation_unref( - pa_context_move_sink_input_by_index( - context, - sink_input_list[chooser]->index, - sink, - change_callback, - NULL)); - return;*/ - break; - - default: - printf("key: %d\n", c); - quit(); - break; - } - - pa_operation_unref(pa_context_get_sink_info_list(context, get_sink_info_callback, NULL)); -// sink_input_counter = 0; -// pa_operation_unref(pa_context_get_sink_input_info_list(context, get_sink_input_info_callback, NULL)); -} - -void interface_clear(void) -{ - clrtoeol(); - refresh(); - endwin(); - exit(0); -} diff --git a/interface.h b/interface.h deleted file mode 100644 index d152c7d..0000000 --- a/interface.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef INTERFACE_H -#define INTERFACE_H - -#include - -#define VOLUME_MAX UINT16_MAX -#define VOLUME_BAR_LEN 50 -#define WIDTH 80 -#define HEIGHT 10 - -void print_sinks(void); -void print_volume(pa_volume_t, int); -void get_input(void); -void interface_init(void); -void interface_clear(void); - -#endif diff --git a/pa-sink-ctl.c b/pa-sink-ctl.c deleted file mode 100644 index 5fe67c1..0000000 --- a/pa-sink-ctl.c +++ /dev/null @@ -1,195 +0,0 @@ -#define _XOPEN_SOURCE 500 -#include -#include -#include -#include -#include - -#include "sink_input.h" -#include "sink.h" -#include "interface.h" -#include "pa-sink-ctl.h" - -#define VOLUME_MAX UINT16_MAX -#define VOLUME_BAR_LEN 50 -#define WIDTH 80 -#define HEIGHT 10 - -sink_info** sink_list = NULL; -uint32_t sink_counter; -uint32_t sink_max; - -pa_mainloop_api *mainloop_api = NULL; -pa_context *context = NULL; - -// ncurses -WINDOW *menu_win; -int chooser; -int startx; -int starty; - -int main(int argc, char** argv) -{ - sink_counter = 0; - sink_max = 1; - sink_list = sink_list_init(sink_max); - - interface_init(); - 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; - } - - // define callback for connection init - pa_context_set_state_callback(context, context_state_callback, NULL); - if (pa_context_connect(context, "tcp:127.0.0.1:4712", 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; -} -/* - * is called after connection - */ -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_info_list(c, get_sink_info_callback, NULL)); -// pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL)); - break; - default: - printf("unknown state\n"); - break; - } -} - -/* - * the begin of the callback loops - */ -void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata) { - - if (is_last < 0) { - printf("Failed to get sink information: %s", pa_strerror(pa_context_errno(c))); - quit(); - } - - if (is_last) { - pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL)); - return; - } - - sink_list_check(sink_list, &sink_max, sink_counter); - - sink_list[sink_counter] = (sink_info*) calloc(1, sizeof(sink_info)); - sink_list[sink_counter]->index = i->index; - sink_list[sink_counter]->mute = i->mute; - - sink_list[sink_counter]->name = strdup(i->name); - ++sink_counter; -} - -/* - * is called after sink-input - */ -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(); - get_input(); - return; - } - - if (!(i->client != PA_INVALID_INDEX)) 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")); -*/ - -// const char *name = pa_proplist_gets(i->proplist, "application.name"); - - int sink_num = i->sink; - int counter = sink_list[sink_num]->input_counter; - - // check the length of the list - sink_check_input_list(sink_list[sink_num]); - // check the current element of the list - sink_input_check(&(sink_list[ sink_num ]->input_list[ counter ])); - sink_input_info* input = sink_list[sink_num]->input_list[counter]; - - input->name = strdup(pa_proplist_gets(i->proplist, "application.name")); - input->index = i->index; - input->vol = pa_cvolume_avg(&i->volume); - - ++sink_list[sink_num]->input_counter; -} - -void quit(void) { - sink_list_clear(sink_list, &sink_max, &sink_counter); - interface_clear(); - exit(0); -} - -/* - * is called, after user input - */ -void change_callback(pa_context* c, int success, void* userdate) { - - - // get information about sinks - pa_operation_unref(pa_context_get_sink_input_info_list(context, get_sink_input_info_callback, NULL)); -} - -void collect_all_infomation(void) { - sink_list_reset(sink_list, &sink_counter); - -} diff --git a/pa-sink-ctl.h b/pa-sink-ctl.h deleted file mode 100644 index eb14ad2..0000000 --- a/pa-sink-ctl.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef PA_SINK_CTL_H -#define PA_SINK_CTL_H - -#include -#include -#include -#include -#include - -#include "sink_input.h" -#include "sink.h" -#include "interface.h" - -#define VOLUME_MAX UINT16_MAX -#define VOLUME_BAR_LEN 50 -#define WIDTH 80 -#define HEIGHT 10 - -void context_state_callback(pa_context*, void *); -void get_sink_info_callback(pa_context *, const pa_sink_info *, int, void *); -void get_sink_input_info_callback(pa_context *, const pa_sink_input_info*, int, void *); -void change_callback(pa_context* c, int success, void* userdate); -void quit(void); - -#endif diff --git a/sink.c b/sink.c deleted file mode 100644 index 5abff14..0000000 --- a/sink.c +++ /dev/null @@ -1,93 +0,0 @@ -#include -#include -#include -#include -#include - -#include "sink_input.h" -#include "sink.h" - -/* - * return an initilized sink - */ -sink_info* sink_init(void) { - - sink_info* sink = (sink_info*) calloc(1, sizeof(sink_info)); - - sink->name = NULL; - sink->input_counter = 0; - sink->input_max = 1; - sink->input_list = NULL; - - sink->input_list = sink_input_list_init(sink->input_max); - - return sink; -} - -/* - * frees all components of a sink - */ -void sink_clear(sink_info* sink) { - - if (sink->name != NULL) - free(sink->name); - - sink_input_list_clear(sink->input_list, &sink->input_max); - - free(sink); - sink = NULL; -} - -void sink_check(sink_info** sink) { - - if ((*sink) == NULL) - (*sink) = (sink_info*) calloc(1, sizeof(sink_input_info)); -} -/* - * check the list length and resize the list, if current position = max - */ -void sink_list_check(sink_info** sink_list, uint32_t* max, uint32_t counter) { - if (counter >= (*max)) { - (*max) *= 2; - sink_list = (sink_info**) realloc(sink_list, (*max) * sizeof(sink_info*)); - for (int i = counter; i < (*max); ++i) - sink_list[i] = NULL; - } -} - -void sink_check_input_list(sink_info* sink) { - - if (sink->input_counter >= sink->input_max) - sink_input_list_enlarge(sink->input_list, &sink->input_max, sink->input_counter); -} - -sink_info** sink_list_init(uint32_t max) { - - sink_info** sink_list = (sink_info**) calloc(max, sizeof(sink_info*)); - - for (int i = 0; i < max; ++i) - sink_list[i] = NULL; - - return sink_list; -} - -void sink_list_reset(sink_info** sink_list, uint32_t* counter) { - - for (int i = 0; i < (*counter); ++i) - sink_list[i]->input_counter = 0; - - (*counter) = 0; -} - -void sink_list_clear(sink_info** sink_list, uint32_t* max, uint32_t* counter) { - - for (int i = 0; i < (*max); ++i) - if (sink_list[i] != NULL) - sink_clear(sink_list[i]); - - (*max) = 0; - (*counter) = 0; - - free(sink_list); - sink_list = NULL; -} diff --git a/sink.h b/sink.h deleted file mode 100644 index 78f5837..0000000 --- a/sink.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef SINK_H -#define SINK_H - -#include -#include -#include -#include -#include - -#include "sink_input.h" - -typedef struct _sink_info { - uint32_t index; - char* name; - int mute; - pa_volume_t vol; - - // input list - int input_counter; - int input_max; - sink_input_info** input_list; -} sink_info; - -sink_info* sink_init(void); -void sink_clear(sink_info*); - -void sink_check(sink_info**); -void sink_list_check(sink_info**, uint32_t*, uint32_t); -void sink_check_input_list(sink_info*); - -sink_info** sink_list_init(uint32_t); -void sink_list_reset(sink_info**, uint32_t*); -void sink_list_clear(sink_info**, uint32_t*, uint32_t*); - -#endif diff --git a/sink_input.c b/sink_input.c deleted file mode 100644 index 54f7c04..0000000 --- a/sink_input.c +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include -#include - -#include "sink_input.h" - -sink_input_info* sink_input_init() { - - sink_input_info* sink_input = (sink_input_info*) calloc(1, sizeof(sink_input_info)); - sink_input->name = NULL; - sink_input->pid = NULL; - - return sink_input; -} - -void sink_input_clear(sink_input_info* sink_input) { - - if (sink_input->name != NULL) - free(sink_input->name); - - if (sink_input->pid != NULL) - free(sink_input->pid); - - free(sink_input); - sink_input = NULL; -} - -sink_input_info** sink_input_list_init(int max) { - - sink_input_info** sink_input_list = (sink_input_info**) calloc(max, sizeof(sink_input_info*)); - - for (int i = 0; i < max; ++i) - sink_input_list = NULL; - - return sink_input_list; -} - -void sink_input_list_enlarge(sink_input_info** sink_input_list, int* max, int counter) { - - (*max) *= 2; - sink_input_list = (sink_input_info**) realloc(sink_input_list, (*max) * sizeof(sink_input_info*)); - - for (int i = counter; i < (*max); ++i) - sink_input_list[i] = NULL; -} - -void sink_input_list_clear(sink_input_info** sink_input_list, int *max) { - - for (int i = 0; i < (*max); ++i) - sink_input_clear(sink_input_list[i]); - - (*max) = 0; - - free(sink_input_list); - sink_input_list = NULL; -} - -void sink_input_check(sink_input_info** sink_input) { - - if ((*sink_input) == NULL) - (*sink_input) = (sink_input_info*) calloc(1, sizeof(sink_input_info)); -} - -int cmp_sink_input_list(const void *a, const void *b) { - - sink_input_info* sinka = *((sink_input_info**) a); - sink_input_info* sinkb = *((sink_input_info**) b); - - if (sinka->sink < sinkb->sink) - return -1; - else if (sinka->sink > sinkb->sink) - return 1; - else - return 0; -} - diff --git a/sink_input.h b/sink_input.h deleted file mode 100644 index d16924c..0000000 --- a/sink_input.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef SINK_INPUT_H -#define SINK_INPUT_H - -#include -// TODO: change this with the given define from pulselib -#define VOLUME_MAX UINT16_MAX - -typedef struct _sink_input_info { - uint32_t index; - uint32_t sink; - char *name; - char *pid; // maybe useless?!!? - pa_volume_t vol; // TOTO: exchange with the channel-list -} sink_input_info; - -sink_input_info* sink_input_init(); -void sink_input_clear(sink_input_info*); - -sink_input_info** sink_input_list_init(int); -void sink_input_list_enlarge(sink_input_info**, int*, int); -void sink_input_list_clear(sink_input_info**, int*); -void sink_input_check(sink_input_info**); -int cmp_sink_input_list(const void *, const void *); - -#endif diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..8b4e688 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,7 @@ +bin_PROGRAMS = pa_sink_ctl +pa_sink_ctl_SOURCES =interface.c pa-sink-ctl.c sink.c sink_input.c + +AM_CFLAGS =-std=c99 -pedantic -Wall -Werror @PULSE_CFLAGS@ +pa_sink_ctl_LDADD =@PULSE_LIBS@ @CURSES_LIBS@ + +noinst_HEADERS = interface.h pa-sink-ctl.h sink.h sink_input.h diff --git a/src/interface.c b/src/interface.c new file mode 100644 index 0000000..c48b953 --- /dev/null +++ b/src/interface.c @@ -0,0 +1,147 @@ +#include +#include +#include +#include +#include + +#include "interface.h" +#include "sink.h" +#include "pa-sink-ctl.h" + +#define VOLUME_MAX UINT16_MAX +#define VOLUME_BAR_LEN 50 +#define WIDTH 80 +#define HEIGHT 10 + +// ncurses +WINDOW *menu_win; +int chooser; +int startx; +int starty; + +extern int sink_counter; +extern int sink_max; +extern sink_info** sink_list; + +extern pa_context* context; + +void interface_init(void) +{ + // ncurses + chooser = 0; + + initscr(); + clear(); + noecho(); + cbreak(); /* Line buffering disabled. pass on everything */ + startx = (80 - WIDTH) / 2; + starty = (24 - HEIGHT) / 2; + menu_win = newwin(HEIGHT, WIDTH, starty, startx); + keypad(menu_win, TRUE); + mvprintw(0, 0, "Use arrow keys to go up and down, Press enter to select a choice"); + refresh(); +} + +void print_sinks(void) { + int x, y, i; + x = 2; + y = 2; + + box(menu_win, 0, 0); + +// printf("print sinks: %d\n", sink_input_counter); + +// qsort(sink_input_list, sink_input_counter, sizeof(sink_input_info*), cmp_sink_input_list); + + for (i = 0; i < sink_counter; ++i) { + mvwprintw(menu_win, y+i, x, "%d\t%s\t", + sink_list[i]->index, + sink_list[i]->name); + } + y += i; +/* for (i = 0; i < sink_input_counter; ++i) { + if (i == chooser) + wattron(menu_win, A_REVERSE); + + mvwprintw(menu_win, y+i, x, "%d\t%s\t", + sink_input_list[i]->sink, + sink_input_list[i]->name); + + if (i == chooser) + wattroff(menu_win, A_REVERSE); + + print_volume(sink_input_list[i]->vol, y+i); + }*/ +} + +void print_volume(pa_volume_t volume, int y) { + + int x = 20; + + unsigned int vol = (unsigned int) ( (((double)volume) / ((double)VOLUME_MAX)) * VOLUME_BAR_LEN ); + mvwprintw(menu_win, y, x - 1 , "["); + for (int i = 0; i < vol; ++i) + mvwprintw(menu_win, y, x + i, "="); + for (int i = vol; i < VOLUME_BAR_LEN; ++i) + mvwprintw(menu_win, y, x + i, " "); + + mvwprintw(menu_win, y, x + VOLUME_BAR_LEN, "]"); +} + +void get_input(void) +{ + int c; +// uint32_t sink; + c = wgetch(menu_win); + switch (c) { + case KEY_UP: + if (chooser > 0) + --chooser; + break; + + case KEY_DOWN: +// if (chooser < sink_input_counter - 1) +// ++chooser; + break; + + case KEY_LEFT: + break; + + case KEY_RIGHT: + break; + + case 32: + +/* if (sink_input_list[chooser]->sink < sink_max) + sink = sink_input_list[chooser]->sink + 1; + else + sink = 0; + + pa_operation_unref( + pa_context_move_sink_input_by_index( + context, + sink_input_list[chooser]->index, + sink, + change_callback, + NULL)); + return;*/ + break; + + default: + printf("key: %d\n", c); + quit(); + break; + } + + pa_operation_unref(pa_context_get_sink_info_list(context, get_sink_info_callback, NULL)); +// sink_input_counter = 0; +// pa_operation_unref(pa_context_get_sink_input_info_list(context, get_sink_input_info_callback, NULL)); +} + +void interface_clear(void) +{ + clrtoeol(); + refresh(); + endwin(); + exit(0); +} diff --git a/src/interface.h b/src/interface.h new file mode 100644 index 0000000..d152c7d --- /dev/null +++ b/src/interface.h @@ -0,0 +1,17 @@ +#ifndef INTERFACE_H +#define INTERFACE_H + +#include + +#define VOLUME_MAX UINT16_MAX +#define VOLUME_BAR_LEN 50 +#define WIDTH 80 +#define HEIGHT 10 + +void print_sinks(void); +void print_volume(pa_volume_t, int); +void get_input(void); +void interface_init(void); +void interface_clear(void); + +#endif diff --git a/src/pa-sink-ctl.c b/src/pa-sink-ctl.c new file mode 100644 index 0000000..5fe67c1 --- /dev/null +++ b/src/pa-sink-ctl.c @@ -0,0 +1,195 @@ +#define _XOPEN_SOURCE 500 +#include +#include +#include +#include +#include + +#include "sink_input.h" +#include "sink.h" +#include "interface.h" +#include "pa-sink-ctl.h" + +#define VOLUME_MAX UINT16_MAX +#define VOLUME_BAR_LEN 50 +#define WIDTH 80 +#define HEIGHT 10 + +sink_info** sink_list = NULL; +uint32_t sink_counter; +uint32_t sink_max; + +pa_mainloop_api *mainloop_api = NULL; +pa_context *context = NULL; + +// ncurses +WINDOW *menu_win; +int chooser; +int startx; +int starty; + +int main(int argc, char** argv) +{ + sink_counter = 0; + sink_max = 1; + sink_list = sink_list_init(sink_max); + + interface_init(); + 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; + } + + // define callback for connection init + pa_context_set_state_callback(context, context_state_callback, NULL); + if (pa_context_connect(context, "tcp:127.0.0.1:4712", 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; +} +/* + * is called after connection + */ +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_info_list(c, get_sink_info_callback, NULL)); +// pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL)); + break; + default: + printf("unknown state\n"); + break; + } +} + +/* + * the begin of the callback loops + */ +void get_sink_info_callback(pa_context *c, const pa_sink_info *i, int is_last, void *userdata) { + + if (is_last < 0) { + printf("Failed to get sink information: %s", pa_strerror(pa_context_errno(c))); + quit(); + } + + if (is_last) { + pa_operation_unref(pa_context_get_sink_input_info_list(c, get_sink_input_info_callback, NULL)); + return; + } + + sink_list_check(sink_list, &sink_max, sink_counter); + + sink_list[sink_counter] = (sink_info*) calloc(1, sizeof(sink_info)); + sink_list[sink_counter]->index = i->index; + sink_list[sink_counter]->mute = i->mute; + + sink_list[sink_counter]->name = strdup(i->name); + ++sink_counter; +} + +/* + * is called after sink-input + */ +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(); + get_input(); + return; + } + + if (!(i->client != PA_INVALID_INDEX)) 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")); +*/ + +// const char *name = pa_proplist_gets(i->proplist, "application.name"); + + int sink_num = i->sink; + int counter = sink_list[sink_num]->input_counter; + + // check the length of the list + sink_check_input_list(sink_list[sink_num]); + // check the current element of the list + sink_input_check(&(sink_list[ sink_num ]->input_list[ counter ])); + sink_input_info* input = sink_list[sink_num]->input_list[counter]; + + input->name = strdup(pa_proplist_gets(i->proplist, "application.name")); + input->index = i->index; + input->vol = pa_cvolume_avg(&i->volume); + + ++sink_list[sink_num]->input_counter; +} + +void quit(void) { + sink_list_clear(sink_list, &sink_max, &sink_counter); + interface_clear(); + exit(0); +} + +/* + * is called, after user input + */ +void change_callback(pa_context* c, int success, void* userdate) { + + + // get information about sinks + pa_operation_unref(pa_context_get_sink_input_info_list(context, get_sink_input_info_callback, NULL)); +} + +void collect_all_infomation(void) { + sink_list_reset(sink_list, &sink_counter); + +} diff --git a/src/pa-sink-ctl.h b/src/pa-sink-ctl.h new file mode 100644 index 0000000..eb14ad2 --- /dev/null +++ b/src/pa-sink-ctl.h @@ -0,0 +1,25 @@ +#ifndef PA_SINK_CTL_H +#define PA_SINK_CTL_H + +#include +#include +#include +#include +#include + +#include "sink_input.h" +#include "sink.h" +#include "interface.h" + +#define VOLUME_MAX UINT16_MAX +#define VOLUME_BAR_LEN 50 +#define WIDTH 80 +#define HEIGHT 10 + +void context_state_callback(pa_context*, void *); +void get_sink_info_callback(pa_context *, const pa_sink_info *, int, void *); +void get_sink_input_info_callback(pa_context *, const pa_sink_input_info*, int, void *); +void change_callback(pa_context* c, int success, void* userdate); +void quit(void); + +#endif diff --git a/src/sink.c b/src/sink.c new file mode 100644 index 0000000..5abff14 --- /dev/null +++ b/src/sink.c @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +#include "sink_input.h" +#include "sink.h" + +/* + * return an initilized sink + */ +sink_info* sink_init(void) { + + sink_info* sink = (sink_info*) calloc(1, sizeof(sink_info)); + + sink->name = NULL; + sink->input_counter = 0; + sink->input_max = 1; + sink->input_list = NULL; + + sink->input_list = sink_input_list_init(sink->input_max); + + return sink; +} + +/* + * frees all components of a sink + */ +void sink_clear(sink_info* sink) { + + if (sink->name != NULL) + free(sink->name); + + sink_input_list_clear(sink->input_list, &sink->input_max); + + free(sink); + sink = NULL; +} + +void sink_check(sink_info** sink) { + + if ((*sink) == NULL) + (*sink) = (sink_info*) calloc(1, sizeof(sink_input_info)); +} +/* + * check the list length and resize the list, if current position = max + */ +void sink_list_check(sink_info** sink_list, uint32_t* max, uint32_t counter) { + if (counter >= (*max)) { + (*max) *= 2; + sink_list = (sink_info**) realloc(sink_list, (*max) * sizeof(sink_info*)); + for (int i = counter; i < (*max); ++i) + sink_list[i] = NULL; + } +} + +void sink_check_input_list(sink_info* sink) { + + if (sink->input_counter >= sink->input_max) + sink_input_list_enlarge(sink->input_list, &sink->input_max, sink->input_counter); +} + +sink_info** sink_list_init(uint32_t max) { + + sink_info** sink_list = (sink_info**) calloc(max, sizeof(sink_info*)); + + for (int i = 0; i < max; ++i) + sink_list[i] = NULL; + + return sink_list; +} + +void sink_list_reset(sink_info** sink_list, uint32_t* counter) { + + for (int i = 0; i < (*counter); ++i) + sink_list[i]->input_counter = 0; + + (*counter) = 0; +} + +void sink_list_clear(sink_info** sink_list, uint32_t* max, uint32_t* counter) { + + for (int i = 0; i < (*max); ++i) + if (sink_list[i] != NULL) + sink_clear(sink_list[i]); + + (*max) = 0; + (*counter) = 0; + + free(sink_list); + sink_list = NULL; +} diff --git a/src/sink.h b/src/sink.h new file mode 100644 index 0000000..78f5837 --- /dev/null +++ b/src/sink.h @@ -0,0 +1,35 @@ +#ifndef SINK_H +#define SINK_H + +#include +#include +#include +#include +#include + +#include "sink_input.h" + +typedef struct _sink_info { + uint32_t index; + char* name; + int mute; + pa_volume_t vol; + + // input list + int input_counter; + int input_max; + sink_input_info** input_list; +} sink_info; + +sink_info* sink_init(void); +void sink_clear(sink_info*); + +void sink_check(sink_info**); +void sink_list_check(sink_info**, uint32_t*, uint32_t); +void sink_check_input_list(sink_info*); + +sink_info** sink_list_init(uint32_t); +void sink_list_reset(sink_info**, uint32_t*); +void sink_list_clear(sink_info**, uint32_t*, uint32_t*); + +#endif diff --git a/src/sink_input.c b/src/sink_input.c new file mode 100644 index 0000000..54f7c04 --- /dev/null +++ b/src/sink_input.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include + +#include "sink_input.h" + +sink_input_info* sink_input_init() { + + sink_input_info* sink_input = (sink_input_info*) calloc(1, sizeof(sink_input_info)); + sink_input->name = NULL; + sink_input->pid = NULL; + + return sink_input; +} + +void sink_input_clear(sink_input_info* sink_input) { + + if (sink_input->name != NULL) + free(sink_input->name); + + if (sink_input->pid != NULL) + free(sink_input->pid); + + free(sink_input); + sink_input = NULL; +} + +sink_input_info** sink_input_list_init(int max) { + + sink_input_info** sink_input_list = (sink_input_info**) calloc(max, sizeof(sink_input_info*)); + + for (int i = 0; i < max; ++i) + sink_input_list = NULL; + + return sink_input_list; +} + +void sink_input_list_enlarge(sink_input_info** sink_input_list, int* max, int counter) { + + (*max) *= 2; + sink_input_list = (sink_input_info**) realloc(sink_input_list, (*max) * sizeof(sink_input_info*)); + + for (int i = counter; i < (*max); ++i) + sink_input_list[i] = NULL; +} + +void sink_input_list_clear(sink_input_info** sink_input_list, int *max) { + + for (int i = 0; i < (*max); ++i) + sink_input_clear(sink_input_list[i]); + + (*max) = 0; + + free(sink_input_list); + sink_input_list = NULL; +} + +void sink_input_check(sink_input_info** sink_input) { + + if ((*sink_input) == NULL) + (*sink_input) = (sink_input_info*) calloc(1, sizeof(sink_input_info)); +} + +int cmp_sink_input_list(const void *a, const void *b) { + + sink_input_info* sinka = *((sink_input_info**) a); + sink_input_info* sinkb = *((sink_input_info**) b); + + if (sinka->sink < sinkb->sink) + return -1; + else if (sinka->sink > sinkb->sink) + return 1; + else + return 0; +} + diff --git a/src/sink_input.h b/src/sink_input.h new file mode 100644 index 0000000..d16924c --- /dev/null +++ b/src/sink_input.h @@ -0,0 +1,25 @@ +#ifndef SINK_INPUT_H +#define SINK_INPUT_H + +#include +// TODO: change this with the given define from pulselib +#define VOLUME_MAX UINT16_MAX + +typedef struct _sink_input_info { + uint32_t index; + uint32_t sink; + char *name; + char *pid; // maybe useless?!!? + pa_volume_t vol; // TOTO: exchange with the channel-list +} sink_input_info; + +sink_input_info* sink_input_init(); +void sink_input_clear(sink_input_info*); + +sink_input_info** sink_input_list_init(int); +void sink_input_list_enlarge(sink_input_info**, int*, int); +void sink_input_list_clear(sink_input_info**, int*); +void sink_input_check(sink_input_info**); +int cmp_sink_input_list(const void *, const void *); + +#endif -- cgit