diff --git a/src/bin/e_randr2.c b/src/bin/e_randr2.c index 6c879c265..65a4bd3ac 100644 --- a/src/bin/e_randr2.c +++ b/src/bin/e_randr2.c @@ -795,6 +795,7 @@ again: mcommon = m; } } + modes = eina_list_free(modes); // no common mode with least difference found if (!mcommon) return; // we have a common mode - apply it to the base screen diff --git a/src/modules/mixer/Pulse.h b/src/modules/mixer/Pulse.h deleted file mode 100644 index 72ac3cc54..000000000 --- a/src/modules/mixer/Pulse.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef PULSE_H -#define PULSE_H - -#include -#include - -# ifdef EINTERN -# undef EINTERN -# endif -# ifdef __GNUC__ -# if __GNUC__ >= 4 -# define EINTERN __attribute__ ((visibility("hidden"))) -# else -# define EINTERN -# endif -# else -# define EINTERN -# endif - -#define PULSE_SUCCESS (void*)1 - -extern int PULSE_EVENT_CONNECTED; -extern int PULSE_EVENT_DISCONNECTED; -extern int PULSE_EVENT_CHANGE; -typedef struct Pulse Pulse; -typedef uint32_t Pulse_Tag_Id; -typedef struct Pulse_Sink Pulse_Sink; -typedef struct Pulse_Sink Pulse_Source; -typedef void (*Pulse_Cb)(Pulse *, Pulse_Tag_Id, void *); - -typedef struct Pulse_Sink_Port_Info { - const char *name; /**< Name of this port */ - const char *description; /**< Description of this port */ - uint32_t priority; /**< The higher this value is the more useful this port is as a default */ -} Pulse_Sink_Port_Info; - -typedef struct Pulse_Server_Info -{ - Pulse *conn; - const char *name; - const char *version; - const char *username; - const char *hostname; - const char *default_sink; - const char *default_source; -} Pulse_Server_Info; - -EINTERN int pulse_init(void); -EINTERN void pulse_shutdown(void); - -EINTERN Pulse *pulse_new(void); -EINTERN Eina_Bool pulse_connect(Pulse *conn); -EINTERN void pulse_disconnect(Pulse *conn); -EINTERN void pulse_free(Pulse *conn); -EINTERN void pulse_cb_set(Pulse *conn, uint32_t tagnum, Pulse_Cb cb); -EINTERN void pulse_server_info_free(Pulse_Server_Info *ev); - -EINTERN uint32_t pulse_server_info_get(Pulse *conn); -EINTERN uint32_t pulse_cards_get(Pulse *conn); -#define pulse_sinks_get(conn) pulse_types_get((conn), EINA_FALSE) -#define pulse_sources_get(conn) pulse_types_get((conn), EINA_TRUE) -EINTERN uint32_t pulse_types_get(Pulse *conn, Eina_Bool source); -#define pulse_sink_get(conn, idx) pulse_type_get((conn), (idx), EINA_FALSE) -#define pulse_source_get(conn, idx) pulse_type_get((conn), (idx), EINA_FALSE) -EINTERN uint32_t pulse_type_get(Pulse *conn, uint32_t idx, Eina_Bool source); -#define pulse_sink_mute_set(conn, idx, mute) pulse_type_mute_set((conn), (idx), (mute), EINA_FALSE) -#define pulse_source_mute_set(conn, idx, mute) pulse_type_mute_set((conn), (idx), (mute), EINA_TRUE) -EINTERN uint32_t pulse_type_mute_set(Pulse *conn, uint32_t idx, Eina_Bool mute, Eina_Bool source); -#define pulse_sink_volume_set(conn, idx, channels, vol) pulse_type_volume_set((conn), (idx), (channels), (vol), EINA_FALSE) -#define pulse_source_volume_set(conn, idx, channels, vol) pulse_type_volume_set((conn), (idx), (channels), (vol), EINA_TRUE) -EINTERN uint32_t pulse_type_volume_set(Pulse *conn, uint32_t sink_num, uint8_t channels, double vol, Eina_Bool source); - -EINTERN void pulse_sink_free(Pulse_Sink *sink); -EINTERN const char *pulse_sink_name_get(Pulse_Sink *sink); -EINTERN const char *pulse_sink_desc_get(Pulse_Sink *sink); -EINTERN uint32_t pulse_sink_idx_get(Pulse_Sink *sink); -EINTERN Eina_Bool pulse_sink_muted_get(Pulse_Sink *sink); -EINTERN double pulse_sink_avg_get_pct(Pulse_Sink *sink); -EINTERN float pulse_sink_balance_get(Pulse_Sink *sink); -EINTERN uint8_t pulse_sink_channels_count(Pulse_Sink *sink); -EINTERN Eina_List *pulse_sink_channel_names_get(Pulse_Sink *sink); -EINTERN Eina_Bool pulse_sinks_watch(Pulse *conn); - -EINTERN const Eina_List *pulse_sink_ports_get(Pulse_Sink *sink); -EINTERN const char *pulse_sink_port_active_get(Pulse_Sink *sink); -#define pulse_source_channel_volume_set pulse_sink_channel_volume_set -EINTERN uint32_t pulse_sink_channel_volume_set(Pulse *conn, Pulse_Sink *sink, uint32_t id, double vol); -EINTERN uint32_t pulse_sink_port_set(Pulse *conn, Pulse_Sink *sink, const char *port); -EINTERN double pulse_sink_channel_volume_get(Pulse_Sink *sink, unsigned int id); -EINTERN float pulse_sink_channel_balance_get(Pulse_Sink *sink, unsigned int id); -EINTERN float pulse_sink_channel_depth_get(Pulse_Sink *sink, unsigned int id); -EINTERN unsigned int pulse_sink_channel_name_get_id(Pulse_Sink *sink, const char *name); -EINTERN const char *pulse_sink_channel_id_get_name(Pulse_Sink *sink, unsigned int id); - -#endif diff --git a/src/modules/mixer/app_mixer.c b/src/modules/mixer/app_mixer.c deleted file mode 100644 index 3800ee92e..000000000 --- a/src/modules/mixer/app_mixer.c +++ /dev/null @@ -1,562 +0,0 @@ -#include "e_mod_main.h" - -extern const char _e_mixer_Name[]; - -typedef struct E_Mixer_App_Dialog_Data -{ - E_Mixer_System *sys; - const char *sys_card_name; - const char *channel_name; - int lock_sliders; - Eina_List *cards; - Eina_List *channel_infos; - E_Mixer_Channel_Info *channel_info; - E_Mixer_Channel_State state; - - struct e_mixer_app_ui - { - Evas_Object *hlayout; - struct e_mixer_app_ui_cards - { - Evas_Object *frame; - Evas_Object *list; - } cards; - struct e_mixer_app_ui_channels - { - Evas_Object *frame; - Evas_Object *list; - } channels; - struct e_mixer_app_ui_channel_editor - { - Evas_Object *frame; - Evas_Object *label_card; - Evas_Object *card; - Evas_Object *label_channel; - Evas_Object *channel; - Evas_Object *label_type; - Evas_Object *type; - Evas_Object *label_left; - Evas_Object *left; - Evas_Object *label_right; - Evas_Object *right; - Evas_Object *mute; - Evas_Object *lock_sliders; - } channel_editor; - } ui; - - struct - { - void *data; - void (*func)(E_Dialog *dialog, void *data); - } del; -} E_Mixer_App_Dialog_Data; - -static void -_cb_changed_left(void *data, Evas_Object *obj EINA_UNUSED) -{ - E_Mixer_App_Dialog_Data *app = data; - E_Mixer_Channel_State *state; - - state = &app->state; - if (app->lock_sliders && (state->left != state->right)) - { - state->right = state->left; - e_widget_slider_value_int_set(app->ui.channel_editor.right, - state->right); - } - - e_mod_mixer_volume_set(app->sys, app->channel_info, - state->left, state->right); -} - -static void -_cb_changed_right(void *data, Evas_Object *obj EINA_UNUSED) -{ - E_Mixer_App_Dialog_Data *app = data; - E_Mixer_Channel_State *state; - - state = &app->state; - if (app->lock_sliders && (state->right != state->left)) - { - state->left = state->right; - e_widget_slider_value_int_set(app->ui.channel_editor.left, - state->left); - } - - e_mod_mixer_volume_set(app->sys, app->channel_info, - state->left, state->right); -} - -static void -_cb_changed_mute(void *data, Evas_Object *obj EINA_UNUSED) -{ - E_Mixer_App_Dialog_Data *app = data; - - e_mod_mixer_mute_set(app->sys, app->channel_info, app->state.mute); -} - -static void -_cb_changed_lock_sliders(void *data, Evas_Object *obj EINA_UNUSED) -{ - E_Mixer_App_Dialog_Data *app = data; - E_Mixer_Channel_State *state; - - if (!app->lock_sliders) - return; - - state = &app->state; - if (state->left == state->right) - return; - - state->left = state->right = (state->left + state->right) / 2; - - e_widget_slider_value_int_set(app->ui.channel_editor.left, state->left); - e_widget_slider_value_int_set(app->ui.channel_editor.right, state->right); - e_mod_mixer_volume_set(app->sys, app->channel_info, - state->left, state->right); -} - -static void -_disable_channel_editor(E_Mixer_App_Dialog_Data *app) -{ - struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor; - - e_widget_entry_text_set(ui->card, ""); - e_widget_entry_text_set(ui->channel, ""); - e_widget_entry_text_set(ui->type, ""); - - e_widget_slider_value_int_set(ui->left, 0); - e_widget_slider_value_int_set(ui->right, 0); - e_widget_check_checked_set(ui->mute, 0); - e_widget_check_checked_set(ui->lock_sliders, 0); - - e_widget_disabled_set(ui->left, 1); - e_widget_disabled_set(ui->right, 1); - e_widget_disabled_set(ui->mute, 1); - e_widget_disabled_set(ui->lock_sliders, 1); -} - -static void -_update_channel_editor_state(E_Mixer_App_Dialog_Data *app, const E_Mixer_Channel_State state) -{ - struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor; - - if (!e_mod_mixer_channel_has_no_volume(app->channel_info)) - { - if (e_mod_mixer_channel_is_mono(app->channel_info)) - e_widget_slider_value_int_set(ui->left, state.left); - else - { - e_widget_slider_value_int_set(ui->left, state.left); - e_widget_slider_value_int_set(ui->right, state.right); - } - } - - if (e_mod_mixer_channel_is_mutable(app->channel_info)) - e_widget_check_checked_set(ui->mute, state.mute); -} - -static void -_populate_channel_editor(E_Mixer_App_Dialog_Data *app) -{ - struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor; - E_Mixer_Channel_State state; - - if ((!app->sys_card_name) || (!app->channel_name)) - { - _disable_channel_editor(app); - return; - } - - e_widget_entry_text_set(ui->card, app->sys_card_name); - e_widget_entry_text_set(ui->channel, app->channel_name); - - if (e_mod_mixer_channel_is_boost(app->channel_info)) - e_widget_entry_text_set(ui->type, _("Boost")); - else if (e_mod_mixer_channel_has_playback(app->channel_info)) - e_widget_entry_text_set(ui->type, _("Playback")); - else if (e_mod_mixer_channel_has_capture(app->channel_info)) - e_widget_entry_text_set(ui->type, _("Capture")); - else - e_widget_entry_text_set(ui->type, _("Switch")); - - e_mod_mixer_state_get(app->sys, app->channel_info, &state); - _update_channel_editor_state(app, state); - - if (e_mod_mixer_channel_is_mutable(app->channel_info)) - { - e_widget_disabled_set(ui->mute, 0); - } - else - { - e_widget_disabled_set(ui->mute, 1); - e_widget_check_checked_set(ui->mute, 0); - } - - if (e_mod_mixer_channel_has_no_volume(app->channel_info)) - { - app->lock_sliders = 1; - e_widget_slider_value_int_set(ui->left, 0); - e_widget_slider_value_int_set(ui->right, 0); - e_widget_disabled_set(ui->lock_sliders, 1); - e_widget_disabled_set(ui->left, 1); - e_widget_disabled_set(ui->right, 1); - } - else if (e_mod_mixer_channel_is_mono(app->channel_info)) - { - app->lock_sliders = 0; - e_widget_slider_value_int_set(ui->right, 0); - e_widget_disabled_set(ui->lock_sliders, 1); - e_widget_disabled_set(ui->left, 0); - e_widget_disabled_set(ui->right, 1); - } - else - { - app->lock_sliders = (state.left == state.right); - e_widget_disabled_set(ui->lock_sliders, 0); - e_widget_disabled_set(ui->left, 0); - e_widget_disabled_set(ui->right, 0); - } - e_widget_check_checked_set(ui->lock_sliders, app->lock_sliders); -} - -static void -_cb_channel_selected(void *data) -{ - E_Mixer_Channel_Info *info = data; - E_Mixer_App_Dialog_Data *app; - - app = info->app; - app->channel_info = info; - _populate_channel_editor(app); -} - -static int -_cb_system_update(void *data, E_Mixer_System *sys EINA_UNUSED) -{ - E_Mixer_App_Dialog_Data *app = data; - E_Mixer_Channel_State state; - - if ((!app->sys) || (!app->channel_info)) - return 1; - - e_mod_mixer_state_get(app->sys, app->channel_info, &state); - _update_channel_editor_state(app, state); - - return 1; -} - -static void -_populate_channels(E_Mixer_App_Dialog_Data *app) -{ - Eina_List *l; - Evas_Object *ilist; - int header_input; - int i, selected; - - ilist = app->ui.channels.list; - edje_freeze(); - e_widget_ilist_freeze(ilist); - e_widget_ilist_clear(ilist); - - if (app->sys) - e_mod_mixer_del(app->sys); - app->sys = e_mod_mixer_new(app->sys_card_name); - if (_mixer_using_default) - e_mixer_system_callback_set(app->sys, _cb_system_update, app); - - if (app->channel_infos) - e_mod_mixer_channel_infos_free(app->channel_infos); - app->channel_infos = e_mod_mixer_channel_infos_get(app->sys); - - i = 0; - selected = 0; - header_input = 0; - for (l = app->channel_infos; l; l = l->next, i++) - { - E_Mixer_Channel_Info *info = l->data; - - if (header_input != e_mod_mixer_channel_group_get(info)) - { - if (e_mod_mixer_channel_is_boost(info)) - e_widget_ilist_header_append(ilist, NULL, _("Boost")); - else if (e_mod_mixer_channel_has_playback(info)) - e_widget_ilist_header_append(ilist, NULL, _("Playback")); - else if (e_mod_mixer_channel_has_capture(info)) - e_widget_ilist_header_append(ilist, NULL, _("Capture")); - else - e_widget_ilist_header_append(ilist, NULL, _("Switch")); - header_input = e_mod_mixer_channel_group_get(info); - i++; - } - - info->app = app; - e_widget_ilist_append(ilist, NULL, info->name, _cb_channel_selected, - info, info->name); - if ((selected == 0) && app->channel_name && info->name && - (strcmp(app->channel_name, info->name) == 0)) - { - e_widget_ilist_selected_set(ilist, i); - app->channel_info = info; - selected = 1; - } - } - - if ((selected == 0) && (i > 0)) - e_widget_ilist_selected_set(ilist, 0); - else - app->channel_name = NULL; - - e_widget_ilist_go(ilist); - e_widget_ilist_thaw(ilist); - edje_thaw(); -} - -static void -_cb_card_selected(void *data) -{ - _populate_channels(data); -} - -static void -_create_cards(E_Dialog *dialog EINA_UNUSED, Evas *evas, E_Mixer_App_Dialog_Data *app) -{ - struct e_mixer_app_ui_cards *ui = &app->ui.cards; - const char *card; - Eina_List *l; - - app->cards = e_mod_mixer_card_names_get(); - if (eina_list_count(app->cards) < 2) - return; - - ui->list = e_widget_ilist_add(evas, 32, 32, &app->sys_card_name); - e_widget_size_min_set(ui->list, 180, 100); - e_widget_ilist_go(ui->list); - EINA_LIST_FOREACH(app->cards, l, card) - { - const char *card_name; - - card_name = e_mod_mixer_card_name_get(card); - - if (!card_name) - continue; - - e_widget_ilist_append(ui->list, NULL, card_name, _cb_card_selected, - app, card); - - eina_stringshare_del(card_name); - } - - ui->frame = e_widget_framelist_add(evas, _("Cards"), 0); - e_widget_framelist_object_append(ui->frame, ui->list); - e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 0, 0.0); -} - -static void -_create_channels(E_Dialog *dialog EINA_UNUSED, Evas *evas, E_Mixer_App_Dialog_Data *app) -{ - struct e_mixer_app_ui_channels *ui = &app->ui.channels; - ui->list = e_widget_ilist_add(evas, 24, 24, &app->channel_name); - e_widget_size_min_set(ui->list, 180, 100); - e_widget_ilist_go(ui->list); - - ui->frame = e_widget_framelist_add(evas, _("Channels"), 0); - e_widget_framelist_object_append(ui->frame, ui->list); - e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.0); -} - -static void -_create_channel_editor(E_Dialog *dialog, Evas *evas, E_Mixer_App_Dialog_Data *app) -{ - struct e_mixer_app_ui_channel_editor *ui = &app->ui.channel_editor; - - ui->label_card = e_widget_label_add(evas, _("Card:")); - ui->card = e_widget_entry_add(dialog->win, NULL, NULL, NULL, NULL); - e_widget_entry_readonly_set(ui->card, 1); - - ui->label_channel = e_widget_label_add(evas, _("Channel:")); - ui->channel = e_widget_entry_add(dialog->win, NULL, NULL, NULL, NULL); - e_widget_entry_readonly_set(ui->channel, 1); - - ui->label_type = e_widget_label_add(evas, _("Type:")); - ui->type = e_widget_entry_add(dialog->win, NULL, NULL, NULL, NULL); - e_widget_entry_readonly_set(ui->type, 1); - - ui->label_left = e_widget_label_add(evas, _("Left:")); - ui->left = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0, - NULL, &app->state.left, 150); - e_widget_on_change_hook_set(ui->left, _cb_changed_left, app); - - ui->label_right = e_widget_label_add(evas, _("Right:")); - ui->right = e_widget_slider_add(evas, 1, 0, "%3.0f", 0.0, 100.0, 10.0, 100.0, - NULL, &app->state.right, 150); - e_widget_on_change_hook_set(ui->right, _cb_changed_right, app); - - ui->mute = e_widget_check_add(evas, _("Mute"), &app->state.mute); - e_widget_on_change_hook_set(ui->mute, _cb_changed_mute, app); - - ui->lock_sliders = e_widget_check_add(evas, _("Lock Sliders"), - &app->lock_sliders); - e_widget_on_change_hook_set(ui->lock_sliders, _cb_changed_lock_sliders, app); - - ui->frame = e_widget_framelist_add(evas, _("Edit"), 0); - e_widget_framelist_object_append(ui->frame, ui->label_card); - e_widget_framelist_object_append(ui->frame, ui->card); - e_widget_framelist_object_append(ui->frame, ui->label_channel); - e_widget_framelist_object_append(ui->frame, ui->channel); - e_widget_framelist_object_append(ui->frame, ui->label_type); - e_widget_framelist_object_append(ui->frame, ui->type); - e_widget_framelist_object_append(ui->frame, ui->label_left); - e_widget_framelist_object_append(ui->frame, ui->left); - e_widget_framelist_object_append(ui->frame, ui->label_right); - e_widget_framelist_object_append(ui->frame, ui->right); - e_widget_framelist_object_append(ui->frame, ui->mute); - e_widget_framelist_object_append(ui->frame, ui->lock_sliders); - - e_widget_list_object_append(app->ui.hlayout, ui->frame, 1, 1, 0.5); -} - -static void -_create_ui(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app) -{ - struct e_mixer_app_ui *ui = &app->ui; - Evas *evas; - int mw, mh; - - evas = evas_object_evas_get(dialog->win); - - ui->hlayout = e_widget_list_add(evas, 0, 1); - _create_cards(dialog, evas, app); - _create_channels(dialog, evas, app); - _create_channel_editor(dialog, evas, app); - - e_widget_size_min_get(ui->hlayout, &mw, &mh); - if (mw < 300) - mw = 300; - if (mh < 200) - mh = 200; - e_dialog_content_set(dialog, ui->hlayout, mw, mh); -} - -static void -_mixer_app_dialog_del(E_Dialog *dialog, E_Mixer_App_Dialog_Data *app) -{ - if (!app) - return; - - if (app->del.func) - app->del.func(dialog, app->del.data); - - if ((!app->ui.cards.list) && (app->ui.channels.list)) - eina_stringshare_del(app->sys_card_name); - - if (app->cards) - e_mod_mixer_card_names_free(app->cards); - if (app->channel_infos) - e_mod_mixer_channel_infos_free(app->channel_infos); - e_mod_mixer_del(app->sys); - - e_util_defer_object_del(E_OBJECT(dialog)); - dialog->data = NULL; - E_FREE(app); -} - -static void -_cb_win_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - E_Dialog *dialog = data; - E_Mixer_App_Dialog_Data *app = dialog->data; - _mixer_app_dialog_del(dialog, app); -} - -static void -_cb_dialog_dismiss(void *data, E_Dialog *dialog) -{ - _mixer_app_dialog_del(dialog, data); -} - -E_Dialog * -e_mixer_app_dialog_new(Evas_Object *parent EINA_UNUSED, void (*func)(E_Dialog *dialog, void *data), void *data) -{ - E_Mixer_App_Dialog_Data *app; - E_Dialog *dialog; - - dialog = e_dialog_new(NULL, _e_mixer_Name, "e_mixer_app_dialog"); - if (!dialog) - return NULL; - - app = E_NEW(E_Mixer_App_Dialog_Data, 1); - if (!app) - { - e_object_del(E_OBJECT(dialog)); - return NULL; - } - - dialog->data = app; - app->del.data = data; - app->del.func = func; - - e_dialog_title_set(dialog, _(_e_mixer_Name)); - - evas_object_event_callback_add(dialog->win, EVAS_CALLBACK_DEL, _cb_win_del, dialog); - - _create_ui(dialog, app); - - e_dialog_button_add(dialog, _("Close"), NULL, _cb_dialog_dismiss, app); - e_dialog_button_focus_num(dialog, 1); - elm_win_center(dialog->win, 1, 1); - e_dialog_show(dialog); - e_dialog_border_icon_set(dialog, "preferences-desktop-mixer"); - - // FIXME: what if module unloaded while mixer_app dialog up? bad! - - return dialog; -} - -int -e_mixer_app_dialog_select(E_Dialog *dialog, const char *sys_card_name, const char *channel_name) -{ - int n, i; - Eina_List *l; - E_Mixer_App_Dialog_Data *app; - - if (!dialog) - return 0; - - if ((!sys_card_name) || (!channel_name)) - return 0; - - app = dialog->data; - if (!app) - return 0; - - n = -1; - for (i = 0, l = app->cards; l; i++, l = l->next) - { - if (strcmp(sys_card_name, l->data) == 0) - { - n = i; - break; - } - } - - if (n < 0) - { - /* FIXME device disappeared, very bad !! */ - return 0; - } - - /* app->channel_name will be overriden by selection in _populate_channels */ - app->channel_name = channel_name; - - if (app->ui.cards.list) - e_widget_ilist_selected_set(app->ui.cards.list, n); - else if (app->ui.channels.list) - { - app->sys_card_name = eina_stringshare_add(sys_card_name); - _populate_channels(app); - } - - return 1; -} - diff --git a/src/modules/mixer/conf_gadget.c b/src/modules/mixer/conf_gadget.c deleted file mode 100644 index 7f5772764..000000000 --- a/src/modules/mixer/conf_gadget.c +++ /dev/null @@ -1,392 +0,0 @@ -#include "e_mod_main.h" - -extern const char _e_mixer_Name[]; - -struct _E_Config_Dialog_Data -{ - int lock_sliders; - int show_locked; - int keybindings_popup; - int card_num; - int channel; - const char *card; - const char *channel_name; - Eina_List *cards; - Eina_List *card_names; - Eina_List *channel_names; - struct mixer_config_ui - { - Evas_Object *table; - struct mixer_config_ui_general - { - Evas_Object *frame; - Evas_Object *lock_sliders; - Evas_Object *show_locked; - Evas_Object *keybindings_popup; - } general; - struct mixer_config_ui_cards - { - Evas_Object *frame; - E_Radio_Group *radio; - } cards; - struct mixer_config_ui_channels - { - Evas_Object *frame; - Evas_Object *scroll; - Evas_Object *list; - E_Radio_Group *radio; - Eina_List *radios; - } channels; - } ui; - E_Mixer_Gadget_Config *conf; -}; - -static void -_mixer_fill_card_infos(E_Config_Dialog_Data *cfdata) -{ - const char *card; - const char *name; - Eina_List *l; - int i = 0; - - cfdata->card_num = -1; - cfdata->cards = e_mod_mixer_card_names_get(); - cfdata->card_names = NULL; - EINA_LIST_FOREACH(cfdata->cards, l, card) - { - name = e_mod_mixer_card_name_get(card); - if ((cfdata->card_num < 0) && card && cfdata->card && - (strcmp(card, cfdata->card) == 0)) - cfdata->card_num = i; - - cfdata->card_names = eina_list_append(cfdata->card_names, name); - - i++; - } - - if (cfdata->card_num < 0) - { - card = eina_list_nth(cfdata->cards, 0); - if (card) - { - cfdata->card_num = 0; - eina_stringshare_del(cfdata->card); - cfdata->card = eina_stringshare_ref(card); - } - } -} - -static void -_mixer_fill_channel_infos(E_Config_Dialog_Data *cfdata) -{ - E_Mixer_System *sys; - const char *channel; - Eina_List *l; - int i = 0; - - sys = e_mod_mixer_new(cfdata->card); - if (!sys) - return; - - cfdata->channel = 0; - cfdata->channel_name = eina_stringshare_add(cfdata->conf->channel_name); - cfdata->channel_names = e_mod_mixer_channel_names_get(sys); - EINA_LIST_FOREACH(cfdata->channel_names, l, channel) - { - if (channel && cfdata->channel_name && - (channel == cfdata->channel_name || - strcmp(channel, cfdata->channel_name) == 0)) - { - cfdata->channel = i; - break; - } - - i++; - } - e_mod_mixer_del(sys); -} - -static void * -_create_data(E_Config_Dialog *dialog) -{ - E_Config_Dialog_Data *cfdata; - E_Mixer_Gadget_Config *conf; - - cfdata = E_NEW(E_Config_Dialog_Data, 1); - if (!cfdata) - return NULL; - - conf = dialog->data; - cfdata->conf = conf; - cfdata->lock_sliders = conf->lock_sliders; - cfdata->show_locked = conf->show_locked; - cfdata->keybindings_popup = conf->keybindings_popup; - cfdata->card = eina_stringshare_add(conf->card); - _mixer_fill_card_infos(cfdata); - _mixer_fill_channel_infos(cfdata); - - return cfdata; -} - -static void -_free_data(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata) -{ - E_Mixer_Gadget_Config *conf = dialog->data; - const char *card; - - if (conf) - conf->dialog = NULL; - - if (!cfdata) - return; - - EINA_LIST_FREE(cfdata->card_names, card) - eina_stringshare_del(card); - - if (cfdata->channel_names) - e_mod_mixer_channel_names_free(cfdata->channel_names); - if (cfdata->cards) - e_mod_mixer_card_names_free(cfdata->cards); - - eina_stringshare_del(cfdata->card); - eina_stringshare_del(cfdata->channel_name); - - eina_list_free(cfdata->ui.channels.radios); - - E_FREE(cfdata); -} - -static int -_basic_apply(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata) -{ - E_Mixer_Gadget_Config *conf = dialog->data; - const char *card, *channel; - - conf->lock_sliders = cfdata->lock_sliders; - conf->show_locked = cfdata->show_locked; - conf->keybindings_popup = cfdata->keybindings_popup; - conf->using_default = EINA_FALSE; - - card = eina_list_nth(cfdata->cards, cfdata->card_num); - if (card) - { - eina_stringshare_del(conf->card); - conf->card = eina_stringshare_ref(card); - } - - channel = eina_list_nth(cfdata->channel_names, cfdata->channel); - if (channel) - { - eina_stringshare_del(conf->channel_name); - conf->channel_name = eina_stringshare_ref(channel); - } - - e_mixer_update(conf->instance); - return 1; -} - -static void -_lock_change(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Config_Dialog_Data *cfdata = data; - e_widget_disabled_set(cfdata->ui.general.show_locked, !cfdata->lock_sliders); -} - -static void -_basic_create_general(Evas *evas, E_Config_Dialog_Data *cfdata) -{ - struct mixer_config_ui_general *ui = &cfdata->ui.general; - - ui->frame = e_widget_framelist_add(evas, _("General Settings"), 0); - - ui->lock_sliders = e_widget_check_add( - evas, _("Lock Sliders"), &cfdata->lock_sliders); - evas_object_smart_callback_add( - ui->lock_sliders, "changed", _lock_change, cfdata); - e_widget_framelist_object_append(ui->frame, ui->lock_sliders); - - ui->show_locked = e_widget_check_add( - evas, _("Show both sliders when locked"), &cfdata->show_locked); - e_widget_disabled_set(ui->show_locked, !cfdata->lock_sliders); - e_widget_framelist_object_append(ui->frame, ui->show_locked); - - ui->keybindings_popup = e_widget_check_add( - evas, _("Show Popup on volume change via keybindings"), &cfdata->keybindings_popup); - e_widget_framelist_object_append(ui->frame, ui->keybindings_popup); -} - -static void -_clear_channels(E_Config_Dialog_Data *cfdata) -{ - Evas_Object *o; - - EINA_LIST_FREE(cfdata->ui.channels.radios, o) - evas_object_del(o); -} - -static void -_fill_channels(Evas *evas, E_Config_Dialog_Data *cfdata) -{ - struct mixer_config_ui_channels *ui = &cfdata->ui.channels; - Evas_Object *selected; - Evas_Coord mw, mh; - const char *name; - Eina_List *l; - int i = 0; - - ui->radio = e_widget_radio_group_new(&cfdata->channel); - EINA_LIST_FOREACH(cfdata->channel_names, l, name) - { - Evas_Object *ow; - - if (!name) continue; - - ow = e_widget_radio_add(evas, name, i, ui->radio); - ui->radios = eina_list_append(ui->radios, ow); - e_widget_list_object_append(ui->list, ow, 1, 1, 0.0); - - ++i; - } - - e_widget_size_min_get(ui->list, &mw, &mh); - evas_object_resize(ui->list, mw, mh); - - selected = eina_list_nth(ui->radios, cfdata->channel); - if (selected) - { - Evas_Coord x, y, w, h, lx, ly; - evas_object_geometry_get(selected, &x, &y, &w, &h); - evas_object_geometry_get(ui->list, &lx, &ly, NULL, NULL); - x -= lx; - y -= ly - 10; - h += 20; - e_widget_scrollframe_child_region_show(ui->scroll, x, y, w, h); - } -} - -static void -_channel_scroll_set_min_size(struct mixer_config_ui_channels *ui) -{ - Evas_Coord w, h; - int len = eina_list_count(ui->radios); - if (len < 1) - return; - - e_widget_size_min_get(ui->list, &w, &h); - h = 4 * h / len; - e_widget_size_min_set(ui->scroll, w, h); -} - -static void -_basic_create_channels(Evas *evas, E_Config_Dialog_Data *cfdata) -{ - struct mixer_config_ui_channels *ui = &cfdata->ui.channels; - - ui->list = e_widget_list_add(evas, 1, 0); - ui->scroll = e_widget_scrollframe_simple_add(evas, ui->list); - ui->frame = e_widget_framelist_add(evas, _("Channels"), 0); - - _fill_channels(evas, cfdata); - - _channel_scroll_set_min_size(ui); - e_widget_framelist_object_append(ui->frame, ui->scroll); -} - -static void -_card_change(void *data, Evas_Object *obj, void *event EINA_UNUSED) -{ - E_Config_Dialog_Data *cfdata = data; - Evas *evas; - char *card; - - eina_stringshare_del(cfdata->card); - - e_mod_mixer_channel_names_free(cfdata->channel_names); - - eina_stringshare_del(cfdata->channel_name); - - card = eina_list_nth(cfdata->cards, cfdata->card_num); - cfdata->card = eina_stringshare_add(card); - _mixer_fill_channel_infos(cfdata); - - evas = evas_object_evas_get(obj); - _clear_channels(cfdata); - _fill_channels(evas, cfdata); -} - -static void -_basic_create_cards(Evas *evas, E_Config_Dialog_Data *cfdata) -{ - struct mixer_config_ui_cards *ui = &cfdata->ui.cards; - const char *card; - Eina_List *l; - int i = 0; - - ui->frame = e_widget_framelist_add(evas, _("Sound Cards"), 0); - ui->radio = e_widget_radio_group_new(&cfdata->card_num); - EINA_LIST_FOREACH(cfdata->card_names, l, card) - { - Evas_Object *ow; - - if (!card) continue; - - ow = e_widget_radio_add(evas, card, i, ui->radio); - e_widget_framelist_object_append(ui->frame, ow); - evas_object_smart_callback_add(ow, "changed", _card_change, cfdata); - - ++i; - } -} - -static Evas_Object * -_basic_create(E_Config_Dialog *cfd EINA_UNUSED, Evas *evas, E_Config_Dialog_Data *cfdata) -{ - if (!cfdata) return NULL; - - e_dialog_resizable_set(cfd->dia, 1); - - cfdata->ui.table = e_widget_table_add(e_win_evas_win_get(evas), 0); - _basic_create_general(evas, cfdata); - _basic_create_cards(evas, cfdata); - _basic_create_channels(evas, cfdata); - - e_widget_table_object_append(cfdata->ui.table, cfdata->ui.general.frame, - 0, 0, 1, 1, 1, 1, 1, 0); - e_widget_table_object_append(cfdata->ui.table, cfdata->ui.cards.frame, - 0, 1, 1, 1, 1, 1, 1, 0); - e_widget_table_object_append(cfdata->ui.table, cfdata->ui.channels.frame, - 0, 2, 1, 1, 1, 1, 1, 1); - - return cfdata->ui.table; -} - -void -e_mixer_config_pulse_toggle(void) -{ -} - -E_Config_Dialog * -e_mixer_config_dialog_new(Evas_Object *parent EINA_UNUSED, E_Mixer_Gadget_Config *conf) -{ - E_Config_Dialog *dialog; - E_Config_Dialog_View *view; - - if (e_config_dialog_find(_e_mixer_Name, "e_mixer_config_dialog_new")) - return NULL; - - view = E_NEW(E_Config_Dialog_View, 1); - if (!view) - return NULL; - - view->create_cfdata = _create_data; - view->free_cfdata = _free_data; - view->basic.create_widgets = _basic_create; - view->basic.apply_cfdata = _basic_apply; - - dialog = e_config_dialog_new(NULL, _("Mixer Settings"), - _e_mixer_Name, "e_mixer_config_dialog_new", - e_mixer_theme_path(), 0, view, conf); - - return dialog; -} - diff --git a/src/modules/mixer/conf_module.c b/src/modules/mixer/conf_module.c deleted file mode 100644 index e838be4a1..000000000 --- a/src/modules/mixer/conf_module.c +++ /dev/null @@ -1,237 +0,0 @@ -#include "e_mod_main.h" - -extern const char _e_mixer_Name[]; - -struct _E_Config_Dialog_Data -{ - int default_instance; - struct mixer_config_ui - { - Evas_Object *list; - struct mixer_config_ui_general - { - Evas_Object *frame; - E_Radio_Group *radio; - } general; - } ui; -}; - -static int -_find_default_instance_index(E_Mixer_Module_Context *ctxt) -{ - Eina_List *l; - int i; - - for (i = 0, l = ctxt->instances; l; l = l->next, i++) - if (l->data == ctxt->default_instance) - return i; - - return 0; -} - -static void * -_create_data(E_Config_Dialog *dialog) -{ - E_Config_Dialog_Data *cfdata; - E_Mixer_Module_Context *ctxt; - - cfdata = E_NEW(E_Config_Dialog_Data, 1); - if (!cfdata) - return NULL; - - ctxt = dialog->data; - cfdata->default_instance = _find_default_instance_index(ctxt); - - return cfdata; -} - -static void -_free_data(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata) -{ - E_Mixer_Module_Context *ctxt = dialog->data; - if (ctxt) - ctxt->conf_dialog = NULL; - - E_FREE(cfdata); -} - -static int -_basic_apply(E_Config_Dialog *dialog, E_Config_Dialog_Data *cfdata) -{ - E_Mixer_Module_Context *ctxt = dialog->data; - ctxt->default_instance = eina_list_nth(ctxt->instances, - cfdata->default_instance); - if (ctxt->default_instance) - { - E_Mixer_Module_Config *conf; - const char *id; - - conf = ctxt->conf; - if (conf->default_gc_id) - eina_stringshare_del(conf->default_gc_id); - - id = ctxt->default_instance->gcc->cf->id; - conf->default_gc_id = eina_stringshare_add(id); - - conf->desktop_notification = ctxt->desktop_notification; - conf->disable_pulse = ctxt->disable_pulse; - - if ((ctxt->external_mixer_enabled) && - (!strlen(ctxt->external_mixer_command))) - return 0; - conf->external_mixer_enabled = ctxt->external_mixer_enabled; - if (conf->external_mixer_command) - eina_stringshare_del(conf->external_mixer_command); - if (ctxt->external_mixer_enabled) - conf->external_mixer_command = eina_stringshare_add(ctxt->external_mixer_command); - } - - return 1; -} - -static void -_basic_create_general(E_Config_Dialog *dialog, Evas *evas, E_Config_Dialog_Data *cfdata) -{ - struct mixer_config_ui_general *ui = &cfdata->ui.general; - E_Mixer_Module_Context *ctxt = dialog->data; - Evas_Object *label, *chk, *edit; - Eina_List *l; - int i; - - ui->frame = e_widget_framelist_add(evas, _("General Settings"), 0); - - label = e_widget_label_add(evas, _("Mixer to use for global actions:")); - e_widget_framelist_object_append(ui->frame, label); - - ui->radio = e_widget_radio_group_new(&cfdata->default_instance); - for (i = 0, l = ctxt->instances; l; l = l->next, i++) - { - E_Mixer_Instance *inst; - E_Mixer_Gadget_Config *conf; - Evas_Object *o; - char name[128]; - const char *card_name; - - inst = l->data; - conf = inst->conf; - - card_name = e_mixer_system_get_card_name(conf->card); - snprintf(name, sizeof(name), "%s: %s", card_name, conf->channel_name); - eina_stringshare_del(card_name); - - o = e_widget_radio_add(evas, name, i, ui->radio); - e_widget_framelist_object_append(ui->frame, o); - } - - e_widget_list_object_append(cfdata->ui.list, ui->frame, 1, 1, 0.5); - chk = e_widget_check_add(evas, _("Display desktop notifications on volume change"), &ctxt->desktop_notification); - e_widget_check_checked_set(chk, ctxt->desktop_notification); -#ifndef HAVE_ENOTIFY - e_widget_disabled_set(chk, EINA_TRUE); -#endif - e_widget_list_object_append(cfdata->ui.list, chk, 1, 1, 0.5); - - chk = e_widget_check_add(evas, _("Disable PulseAudio"), &ctxt->disable_pulse); - e_widget_check_checked_set(chk, ctxt->disable_pulse); - e_widget_list_object_append(cfdata->ui.list, chk, 1, 1, 0.5); - - chk = e_widget_check_add(evas, _("Enable external Mixer Command"), &ctxt->external_mixer_enabled); - e_widget_check_checked_set(chk, ctxt->external_mixer_enabled); - e_widget_list_object_append(cfdata->ui.list, chk, 1, 1, 0.5); - - edit = e_widget_entry_add(dialog->dia->win, &ctxt->external_mixer_command, NULL, NULL, NULL); - e_widget_list_object_append(cfdata->ui.list, edit, 1, 1, 0.5); -} - -static void -cb_mixer_app_del(E_Dialog *dialog EINA_UNUSED, void *data) -{ - E_Mixer_Module_Context *ctxt = data; - ctxt->mixer_dialog = NULL; -} - -static void -cb_mixer_call(void *data, void *data2 EINA_UNUSED) -{ - Eina_List *l; - E_Mixer_Module_Context *ctxt = data; - - if (ctxt->mixer_dialog) - { - e_dialog_show(ctxt->mixer_dialog); - return; - } - - if (ctxt->conf->external_mixer_enabled) - { - E_Zone *zone = e_zone_current_get(); - e_exec (zone, NULL, ctxt->conf->external_mixer_command, NULL, NULL); - return; - } - - ctxt->mixer_dialog = e_mixer_app_dialog_new(NULL, cb_mixer_app_del, ctxt); - - for (l = ctxt->instances; l; l = l->next) - { - E_Mixer_Instance *inst; - E_Mixer_Gadget_Config *conf; - - inst = l->data; - conf = inst->conf; - - if (conf) - { - e_mixer_app_dialog_select(ctxt->mixer_dialog, conf->card, conf->channel_name); - break; - } - - } -} - -static void -_basic_create_mixer_call(E_Config_Dialog *dialog, Evas *evas, E_Config_Dialog_Data *cfdata) -{ - Evas_Object *button; - - button = e_widget_button_add(evas, _("Launch mixer..."), NULL, - cb_mixer_call, dialog->data, NULL); - e_widget_list_object_append(cfdata->ui.list, button, 0, 0, 0.0); -} - -static Evas_Object * -_basic_create(E_Config_Dialog *dialog, Evas *evas, E_Config_Dialog_Data *cfdata) -{ - if (!cfdata) - return NULL; - - cfdata->ui.list = e_widget_list_add(evas, 0, 0); - _basic_create_general(dialog, evas, cfdata); - _basic_create_mixer_call(dialog, evas, cfdata); - return cfdata->ui.list; -} - -E_Config_Dialog * -e_mixer_config_module_dialog_new(Evas_Object *parent EINA_UNUSED, E_Mixer_Module_Context *ctxt) -{ - E_Config_Dialog *dialog; - E_Config_Dialog_View *view; - - if (e_config_dialog_find(_e_mixer_Name, "extensions/mixer")) - return NULL; - - view = E_NEW(E_Config_Dialog_View, 1); - if (!view) - return NULL; - - view->create_cfdata = _create_data; - view->free_cfdata = _free_data; - view->basic.create_widgets = _basic_create; - view->basic.apply_cfdata = _basic_apply; - - dialog = e_config_dialog_new(NULL, _("Mixer Module Settings"), - _e_mixer_Name, "extensions/mixer", - e_mixer_theme_path(), 0, view, ctxt); - - return dialog; -} - diff --git a/src/modules/mixer/e_mod_main.c b/src/modules/mixer/e_mod_main.c deleted file mode 100644 index 0e72f250d..000000000 --- a/src/modules/mixer/e_mod_main.c +++ /dev/null @@ -1,1472 +0,0 @@ -#include "e_mod_main.h" - -static void _mixer_popup_timer_new(E_Mixer_Instance *inst); -static Eina_Bool _mixer_popup_timer_cb(void *data); - -static E_Module *mixer_mod = NULL; -static char tmpbuf[4096]; /* general purpose buffer, just use immediately */ - -static const char _conf_domain[] = "module.mixer"; -static const char _name[] = "mixer"; -const char _e_mixer_Name[] = N_("Mixer"); - -static void _mixer_actions_unregister(E_Mixer_Module_Context *ctxt); -static void _mixer_actions_register(E_Mixer_Module_Context *ctxt); - -#ifdef HAVE_ENOTIFY -static void -_mixer_notify_cb(void *data, unsigned int id) -{ - E_Mixer_Instance *inst = data; - - inst->notification_id = id; -} -#endif - -static void -_mixer_notify(const float val, E_Mixer_Instance *inst) -{ -#ifdef HAVE_ENOTIFY - E_Notification_Notify n; - E_Mixer_Module_Context *ctxt; - char *icon, buf[56]; - int ret; - - memset(&n, 0, sizeof(E_Notification_Notify)); - if (val > 100.0 || val < 0.0) - return; - - if (!(ctxt = (E_Mixer_Module_Context *)mixer_mod->data) || !ctxt->desktop_notification) - return; - - ret = snprintf(buf, (sizeof(buf) - 1), "%s: %d%%", _("New volume"), (int)(val + 0.5)); - if ((ret < 0) || ((unsigned int)ret > sizeof(buf))) - return; - //Names are taken from FDO icon naming scheme - if (val == 0.0) - icon = "audio-volume-muted"; - else if ((val > 33.3) && (val < 66.6)) - icon = "audio-volume-medium"; - else if (val < 33.3) - icon = "audio-volume-low"; - else - icon = "audio-volume-high"; - - n.app_name = _("Mixer"); - n.replaces_id = inst->notification_id; - n.icon.icon = icon; - n.summary = _("Volume changed"); - n.body = buf; - n.timeout = 2000; - e_notification_client_send(&n, _mixer_notify_cb, inst); -#endif -} - -const char * -e_mixer_theme_path(void) -{ -#define TF "/e-module-mixer.edj" - size_t dirlen; - - dirlen = strlen(mixer_mod->dir); - if (dirlen >= sizeof(tmpbuf) - sizeof(TF)) - return NULL; - - memcpy(tmpbuf, mixer_mod->dir, dirlen); - memcpy(tmpbuf + dirlen, TF, sizeof(TF)); - - return tmpbuf; -#undef TF -} - -static int -_mixer_gadget_configuration_defaults(E_Mixer_Gadget_Config *conf) -{ - E_Mixer_System *sys; - const char *card, *channel; - - card = e_mod_mixer_card_default_get(); - if (!card) - return 0; - - sys = e_mod_mixer_new(card); - if (!sys) - { - eina_stringshare_del(card); - return 0; - } - - channel = e_mod_mixer_channel_default_name_get(sys); - e_mod_mixer_del(sys); - - if (!channel) - { - eina_stringshare_del(card); - return 0; - } - - eina_stringshare_del(conf->card); - conf->card = card; - eina_stringshare_del(conf->channel_name); - conf->channel_name = channel; - conf->lock_sliders = 1; - conf->show_locked = 0; - conf->keybindings_popup = 0; - conf->state.left = conf->state.right = conf->state.mute = -1; - - return 1; -} - -static E_Mixer_Gadget_Config * -_mixer_gadget_configuration_new(E_Mixer_Module_Config *mod_conf, const char *id) -{ - E_Mixer_Gadget_Config *conf; - - conf = E_NEW(E_Mixer_Gadget_Config, 1); - if (!conf) - return NULL; - - _mixer_gadget_configuration_defaults(conf); - conf->id = eina_stringshare_add(id); - if (!mod_conf->gadgets) - mod_conf->gadgets = eina_hash_string_superfast_new(NULL); - eina_hash_direct_add(mod_conf->gadgets, conf->id, conf); - - return conf; -} - -static inline void -_mixer_gadget_configuration_free_int(E_Mixer_Gadget_Config *conf) -{ - if (conf->dialog) - e_object_del(E_OBJECT(conf->dialog)); - - if (conf->card) - eina_stringshare_del(conf->card); - if (conf->channel_name) - eina_stringshare_del(conf->channel_name); - - eina_stringshare_del(conf->id); - free(conf); -} - -static void -_mixer_gadget_configuration_free(E_Mixer_Module_Config *mod_conf, E_Mixer_Gadget_Config *conf) -{ - if (!mod_conf) - return; - if (!conf) - return; - eina_hash_del(mod_conf->gadgets, conf->id, conf); - if (!eina_hash_population(mod_conf->gadgets)) - eina_hash_free(mod_conf->gadgets); - _mixer_gadget_configuration_free_int(conf); -} - -static Eina_Bool -_mixer_gadget_configuration_free_foreach(const Eina_Hash *hash EINA_UNUSED, const void *key EINA_UNUSED, void *hdata, void *fdata EINA_UNUSED) -{ - _mixer_gadget_configuration_free_int(hdata); - return 1; -} - -#if 0 -static Eina_Bool -_mixer_module_configuration_alert(void *data) -{ - e_util_dialog_show(_("Mixer Settings Updated"), "%s", (char *)data); - return ECORE_CALLBACK_CANCEL; -} - -#endif - -static E_Mixer_Module_Config * -_mixer_module_configuration_new(void) -{ - E_Mixer_Module_Config *conf; - - conf = E_NEW(E_Mixer_Module_Config, 1); - conf->desktop_notification = 1; - conf->disable_pulse = 0; - conf->external_mixer_enabled = 0; - conf->external_mixer_command = eina_stringshare_add(""); - - return conf; -} - -static void -_mixer_module_configuration_free(E_Mixer_Module_Config *conf) -{ - if (!conf) - return; - - if (conf->gadgets) - { - eina_hash_foreach(conf->gadgets, - _mixer_gadget_configuration_free_foreach, NULL); - eina_hash_free(conf->gadgets); - } - eina_stringshare_del(conf->default_gc_id); - - if (conf->external_mixer_command) - eina_stringshare_del(conf->external_mixer_command); - free(conf); -} - -static void -_mixer_popup_update(E_Mixer_Instance *inst) -{ - E_Mixer_Channel_State *state; - - if (!inst->popup) return; - - state = &inst->mixer_state; - - if (inst->ui.left) - e_slider_value_set(inst->ui.left, state->left); - if (inst->ui.right) - e_slider_value_set(inst->ui.right, state->right); - if (inst->ui.mute) - e_widget_check_checked_set(inst->ui.mute, state->mute); -} - -static void -_mixer_gadget_update(E_Mixer_Instance *inst) -{ - Edje_Message_Int_Set *msg; - - if (!inst) - return; - - msg = alloca(sizeof(Edje_Message_Int_Set) + (2 * sizeof(int))); - msg->count = 3; - msg->val[0] = inst->mixer_state.mute; - msg->val[1] = inst->mixer_state.left; - msg->val[2] = inst->mixer_state.right; - edje_object_message_send(inst->ui.gadget, EDJE_MESSAGE_INT_SET, 0, msg); - - edje_object_signal_emit(inst->ui.gadget, "e,action,volume,change", "e"); - - if (inst->popup) - _mixer_popup_update(inst); -} - -static void -_mixer_update_volume(E_Mixer_Instance *inst, int dl, int dr, Eina_Bool non_ui) -{ - E_Mixer_Channel_State *state; - - state = &inst->mixer_state; - if (!inst->channel) return; - e_mod_mixer_volume_get(inst->sys, inst->channel, - &state->left, &state->right); - if (state->left >= 0) - { - state->left += dl; - if (state->left < 0) - state->left = 0; - else if (state->left > 100) - state->left = 100; - } - if (state->right >= 0) - { - state->right += dr; - if (state->right < 0) - state->right = 0; - else if (state->right > 100) - state->right = 100; - } - - e_mod_mixer_volume_set(inst->sys, inst->channel, - state->left, state->right); - _mixer_gadget_update(inst); - if (non_ui) - _mixer_notify(((float)state->left + (float)state->right) / 2.0, inst); -} - -static void -_mixer_volume_change(E_Mixer_Instance *inst, Eina_Bool up, Eina_Bool non_ui) -{ - if (up) - _mixer_update_volume(inst, 5, 5, non_ui); - else - _mixer_update_volume(inst, -5, -5, non_ui); -} - -static void -_mixer_toggle_mute(E_Mixer_Instance *inst, Eina_Bool non_ui) -{ - E_Mixer_Channel_State *state; - - - if (!inst->channel) return; - if (!e_mod_mixer_channel_is_mutable(inst->channel)) - return; - - state = &inst->mixer_state; - e_mod_mixer_mute_get(inst->sys, inst->channel, &state->mute); - state->mute = !state->mute; - e_mod_mixer_mute_set(inst->sys, inst->channel, state->mute); - if (!state->mute) e_mod_mixer_volume_set(inst->sys, inst->channel, state->left, state->right); - _mixer_gadget_update(inst); - if (non_ui) - { - if (state->mute) - _mixer_notify(0.0, inst); - else - _mixer_notify(((float)state->left + (float)state->right) / 2.0, inst); - } -} - -static void -_mixer_popup_cb_volume_left_change(void *data, Evas_Object *obj, void *event EINA_UNUSED) -{ - E_Mixer_Instance *inst = data; - E_Mixer_Channel_State *state = &inst->mixer_state; - - if (!inst->channel) return; - e_mod_mixer_volume_get(inst->sys, inst->channel, - &state->left, &state->right); - - state->left = (int)e_slider_value_get(obj); - if (inst->conf->lock_sliders) - { - state->right = state->left; - e_slider_value_set(inst->ui.right, state->right); - } - - e_mod_mixer_volume_set(inst->sys, inst->channel, - state->left, state->right); - if (!_mixer_using_default) _mixer_gadget_update(inst); -} - -static void -_mixer_popup_cb_volume_right_change(void *data, Evas_Object *obj, void *event EINA_UNUSED) -{ - E_Mixer_Instance *inst = data; - E_Mixer_Channel_State *state = &inst->mixer_state; - - if (!inst->channel) return; - e_mod_mixer_volume_get(inst->sys, inst->channel, - &state->left, &state->right); - - state->right = (int)e_slider_value_get(obj); - if (inst->conf->lock_sliders) - { - state->left = state->right; - e_slider_value_set(inst->ui.left, state->left); - } - - e_mod_mixer_volume_set(inst->sys, inst->channel, - state->left, state->right); - if (!_mixer_using_default) _mixer_gadget_update(inst); -} - -static void -_mixer_popup_cb_mute_change(void *data, Evas_Object *obj, void *event EINA_UNUSED) -{ - E_Mixer_Instance *inst = data; - E_Mixer_Channel_State *state = &inst->mixer_state; - - if (!inst->channel) return; - state->mute = e_widget_check_checked_get(obj); - e_mod_mixer_mute_set(inst->sys, inst->channel, state->mute); - - if (!_mixer_using_default) _mixer_gadget_update(inst); -} - -static Evas_Object * -_mixer_popup_add_slider(E_Mixer_Instance *inst, int value, void (*cb)(void *data, Evas_Object *obj, void *event_info)) -{ - Evas_Object *slider = e_slider_add(e_comp->evas); - evas_object_show(slider); - e_slider_orientation_set(slider, 0); - e_slider_value_set(slider, value); - e_slider_value_range_set(slider, 0.0, 100.0); - e_slider_value_format_display_set(slider, NULL); - evas_object_smart_callback_add(slider, "changed", cb, inst); - - return slider; -} - -static void -_mixer_app_cb_del(E_Dialog *dialog EINA_UNUSED, void *data) -{ - E_Mixer_Module_Context *ctxt = data; - ctxt->mixer_dialog = NULL; -} - -static void _mixer_popup_del(E_Mixer_Instance *inst); - -static Eina_Bool -_mixer_popup_key_down_cb(void *data, Ecore_Event_Key *ev) -{ - E_Mixer_Instance *inst = data; - const char *keysym; - - if (!inst) return ECORE_CALLBACK_PASS_ON; - keysym = ev->key; - if (strcmp(keysym, "Escape") == 0) - _mixer_popup_del(inst); - else if (strcmp(keysym, "Up") == 0) - _mixer_volume_change(inst, EINA_TRUE, EINA_FALSE); - else if (strcmp(keysym, "Down") == 0) - _mixer_volume_change(inst, EINA_FALSE, EINA_FALSE); - else if ((strcmp(keysym, "Return") == 0) || - (strcmp(keysym, "KP_Enter") == 0)) - _mixer_toggle_mute(inst, EINA_FALSE); - else - { - E_Action *act; - Eina_List *l; - E_Config_Binding_Key *binding; - E_Binding_Modifier mod; - Eina_Bool handled = EINA_FALSE; - - EINA_LIST_FOREACH(e_bindings->key_bindings, l, binding) - { - if (binding->action && - (strcmp(binding->action, "volume_increase") && - strcmp(binding->action, "volume_decrease") && - strcmp(binding->action, "volume_mute"))) - continue; - - mod = 0; - - if (ev->modifiers & ECORE_EVENT_MODIFIER_SHIFT) - mod |= E_BINDING_MODIFIER_SHIFT; - if (ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) - mod |= E_BINDING_MODIFIER_CTRL; - if (ev->modifiers & ECORE_EVENT_MODIFIER_ALT) - mod |= E_BINDING_MODIFIER_ALT; - if (ev->modifiers & ECORE_EVENT_MODIFIER_WIN) - mod |= E_BINDING_MODIFIER_WIN; - - if (binding->key && (!strcmp(binding->key, ev->key)) && - ((binding->modifiers == mod) || (binding->any_mod))) - { - if (!(act = e_action_find(binding->action))) continue; - if (act->func.go_key) - act->func.go_key(E_OBJECT(inst->gcc->gadcon->zone), binding->params, ev); - else if (act->func.go) - act->func.go(E_OBJECT(inst->gcc->gadcon->zone), binding->params); - handled = EINA_TRUE; - } - } - if (!handled) _mixer_popup_del(inst); - } - - return ECORE_CALLBACK_PASS_ON; -} - -static void -_mixer_popup_del(E_Mixer_Instance *inst) -{ - inst->ui.label = NULL; - inst->ui.left = NULL; - inst->ui.right = NULL; - inst->ui.mute = NULL; - inst->ui.table = NULL; - inst->ui.button = NULL; - E_FREE_FUNC(inst->popup, e_object_del); - E_FREE_FUNC(inst->popup_timer, ecore_timer_del); -} - -static void -_mixer_popup_del_cb(void *obj) -{ - _mixer_popup_del(e_object_data_get(obj)); -} - -static void -_mixer_popup_comp_del_cb(void *data, Evas_Object *obj EINA_UNUSED) -{ - E_Mixer_Instance *inst = data; - - E_FREE_FUNC(inst->popup, e_object_del); -} - -static void -_mixer_app_select_current(E_Dialog *dialog, E_Mixer_Instance *inst) -{ - E_Mixer_Gadget_Config *conf = inst->conf; - - e_mixer_app_dialog_select(dialog, conf->card, conf->channel_name); -} - -static void -_mixer_popup_cb_mixer(void *data, void *data2 EINA_UNUSED) -{ - E_Mixer_Instance *inst = data; - E_Mixer_Module_Context *ctxt; - - _mixer_popup_del(inst); - - ctxt = mixer_mod->data; - if (ctxt->mixer_dialog) - { - /* maybe not update mixer dialog current selection */ - /* _mixer_app_select_current(ctxt->mixer_dialog, inst); */ - e_dialog_show(ctxt->mixer_dialog); - return; - } - - if (ctxt->conf->external_mixer_enabled) - { - E_Zone *zone = e_zone_current_get(); - e_exec (zone, NULL, ctxt->conf->external_mixer_command, NULL, NULL); - return; - } - - ctxt->mixer_dialog = e_mixer_app_dialog_new(NULL, _mixer_app_cb_del, ctxt); - - _mixer_app_select_current(ctxt->mixer_dialog, inst); -} - -static void -_mixer_popup_new(E_Mixer_Instance *inst) -{ - E_Mixer_Channel_State *state; - Evas *evas; - Evas_Coord mw, mh; - int colspan; - - if (inst->conf->dialog) - return; - - state = &inst->mixer_state; - e_mod_mixer_state_get(inst->sys, inst->channel, state); - - if ((inst->channel) && - (e_mod_mixer_channel_has_no_volume(inst->channel) || - e_mod_mixer_channel_is_mono(inst->channel) || - (inst->conf->lock_sliders && !inst->conf->show_locked))) - colspan = 1; - else - colspan = 2; - - inst->popup = e_gadcon_popup_new(inst->gcc, 0); - evas = e_comp->evas; - - inst->ui.table = e_widget_table_add(e_win_evas_win_get(evas), 0); - - inst->ui.label = e_widget_label_add(evas, inst->conf->channel_name); - e_widget_table_object_append(inst->ui.table, inst->ui.label, - 0, 0, colspan, 1, 0, 0, 0, 0); - - if (colspan==2) - { - inst->ui.left = _mixer_popup_add_slider(inst, state->left, - _mixer_popup_cb_volume_left_change); - e_widget_table_object_append(inst->ui.table, inst->ui.left, - 0, 1, 1, 1, 1, 1, 1, 1); - - inst->ui.right = _mixer_popup_add_slider(inst, state->right, - _mixer_popup_cb_volume_right_change); - e_widget_table_object_append(inst->ui.table, inst->ui.right, - 1, 1, 1, 1, 1, 1, 1, 1); - } - else - { - if ((inst->channel) && - (e_mod_mixer_channel_has_no_volume(inst->channel))) - { - inst->ui.left = _mixer_popup_add_slider(inst, 0, NULL); - e_widget_table_object_append(inst->ui.table, inst->ui.left, - 0, 1, 1, 1, 1, 1, 1, 1); - e_slider_disabled_set(inst->ui.left, 1); - } - else - { - inst->ui.left = _mixer_popup_add_slider(inst, state->left, - _mixer_popup_cb_volume_left_change); - e_widget_table_object_append(inst->ui.table, inst->ui.left, - 0, 1, 1, 1, 1, 1, 1, 1); - } - inst->ui.right = NULL; - } - - if ((inst->channel) && (e_mod_mixer_channel_is_mutable(inst->channel))) - { - inst->ui.mute = e_widget_check_add(evas, _("Mute"), &state->mute); - evas_object_show(inst->ui.mute); - e_widget_table_object_append(inst->ui.table, inst->ui.mute, - 0, 2, colspan, 1, 1, 1, 1, 0); - evas_object_smart_callback_add(inst->ui.mute, "changed", - _mixer_popup_cb_mute_change, inst); - } - else - inst->ui.mute = NULL; - - inst->ui.button = e_widget_button_add(evas, NULL, "preferences-system", - _mixer_popup_cb_mixer, inst, NULL); - e_widget_table_object_append(inst->ui.table, inst->ui.button, - 0, 7, colspan, 1, 1, 1, 1, 0); - - e_widget_size_min_get(inst->ui.table, &mw, &mh); - if (mh < 208) mh = 208; - e_widget_size_min_set(inst->ui.table, mw, mh); - - e_gadcon_popup_content_set(inst->popup, inst->ui.table); - e_comp_object_util_autoclose(inst->popup->comp_object, - _mixer_popup_comp_del_cb, _mixer_popup_key_down_cb, inst); - e_gadcon_popup_show(inst->popup); - e_object_data_set(E_OBJECT(inst->popup), inst); - E_OBJECT_DEL_SET(inst->popup, _mixer_popup_del_cb); -} - -static void -_mixer_popup_timer_new(E_Mixer_Instance *inst) -{ - if (inst->popup) - { - if (inst->popup_timer) - { - ecore_timer_del(inst->popup_timer); - inst->popup_timer = ecore_timer_add(1.0, _mixer_popup_timer_cb, inst); - } - } - else - { - _mixer_popup_new(inst); - inst->popup_timer = ecore_timer_add(1.0, _mixer_popup_timer_cb, inst); - } -} - -static Eina_Bool -_mixer_popup_timer_cb(void *data) -{ - E_Mixer_Instance *inst; - inst = data; - - if (inst->popup) - _mixer_popup_del(inst); - inst->popup_timer = NULL; - - return ECORE_CALLBACK_CANCEL; -} - -static void -_mixer_menu_cb_cfg(void *data, E_Menu *menu EINA_UNUSED, E_Menu_Item *mi EINA_UNUSED) -{ - E_Mixer_Instance *inst = data; - - if (inst->popup) - _mixer_popup_del(inst); - inst->conf->dialog = e_mixer_config_dialog_new(NULL, inst->conf); -} - -static void -_mixer_menu_new(E_Mixer_Instance *inst, Evas_Event_Mouse_Down *ev) -{ - E_Zone *zone; - E_Menu *m; - E_Menu_Item *mi; - int x, y; - - zone = e_zone_current_get(); - - m = e_menu_new(); - - mi = e_menu_item_new(m); - e_menu_item_label_set(mi, _("Settings")); - e_util_menu_item_theme_icon_set(mi, "configure"); - e_menu_item_callback_set(mi, _mixer_menu_cb_cfg, inst); - - m = e_gadcon_client_util_menu_items_append(inst->gcc, m, 0); - e_gadcon_canvas_zone_geometry_get(inst->gcc->gadcon, &x, &y, NULL, NULL); - e_menu_activate_mouse(m, zone, x + ev->output.x, y + ev->output.y, - 1, 1, E_MENU_POP_DIRECTION_AUTO, ev->timestamp); - evas_event_feed_mouse_up(inst->gcc->gadcon->evas, ev->button, - EVAS_BUTTON_NONE, ev->timestamp, NULL); -} - -static void -_mixer_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Mixer_Instance *inst = data; - Evas_Event_Mouse_Down *ev = event; - - if (ev->button == 1) - { - if (!inst->popup) - _mixer_popup_new(inst); - } - else if (ev->button == 2) - _mixer_toggle_mute(inst, EINA_FALSE); - else if (ev->button == 3) - _mixer_menu_new(inst, ev); -} - -static void -_mixer_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Mixer_Instance *inst = data; - Evas_Event_Mouse_Wheel *ev = event; - - if (ev->direction == 0) - { - if (ev->z > 0) - _mixer_volume_change(inst, EINA_FALSE, EINA_FALSE); - else if (ev->z < 0) - _mixer_volume_change(inst, EINA_TRUE, EINA_FALSE); - } - else if (_mixer_using_default && (ev->direction == 1)) /* invalid with pulse */ - { - if (ev->z > 0) - _mixer_update_volume(inst, -5, 5, EINA_FALSE); - else if (ev->z < 0) - _mixer_update_volume(inst, 5, -5, EINA_FALSE); - } -} - -static int -_mixer_sys_setup(E_Mixer_Instance *inst) -{ - E_Mixer_Gadget_Config *conf; - - conf = inst->conf; - if ((!_mixer_using_default) && (!e_mixer_pulse_ready())) return 1; - - if (!conf->card) - { - ERR("conf->card in mixer sys setup is NULL"); - /* return 1; */ - } - - if (inst->sys) - e_mod_mixer_del(inst->sys); - - inst->sys = e_mod_mixer_new(conf->card); - if (!inst->sys) - { - inst->channel = NULL; - return 0; - } - - inst->channel = e_mod_mixer_channel_info_get_by_name(inst->sys, conf->channel_name); - return !!inst->channel; -} - -static int -_mixer_system_cb_update(void *data, E_Mixer_System *sys EINA_UNUSED) -{ - E_Mixer_Instance *inst = data; - e_mod_mixer_state_get(inst->sys, inst->channel, &inst->mixer_state); - _mixer_gadget_update(inst); - - return 1; -} - -int -e_mixer_update(E_Mixer_Instance *inst) -{ - int r; - - e_modapi_save(mixer_mod); - if ((!inst) || (!inst->conf)) - return 0; - - r = _mixer_sys_setup(inst); - if (r && _mixer_using_default) - e_mixer_system_callback_set(inst->sys, _mixer_system_cb_update, inst); - - return r; -} - -static int -_mixer_sys_setup_default_card(E_Mixer_Instance *inst) -{ - E_Mixer_Gadget_Config *conf; - const char *card; - - conf = inst->conf; - conf->using_default = EINA_TRUE; - eina_stringshare_del(conf->card); - - card = e_mod_mixer_card_default_get(); - if (!card) - goto error; - - if (inst->sys) - e_mod_mixer_del(inst->sys); - inst->sys = e_mod_mixer_new(card); - if (!inst->sys) - goto system_error; - - conf->card = card; - return 1; - -system_error: - eina_stringshare_del(card); -error: - conf->card = NULL; - return 0; -} - -static int -_mixer_sys_setup_default_channel(E_Mixer_Instance *inst) -{ - E_Mixer_Gadget_Config *conf; - const char *channel_name; - - conf = inst->conf; - if (conf->channel_name) - eina_stringshare_del(conf->channel_name); - - channel_name = e_mod_mixer_channel_default_name_get(inst->sys); - if (!channel_name) - goto error; - - inst->channel = e_mod_mixer_channel_info_get_by_name(inst->sys, channel_name); - if (!inst->channel) - goto system_error; - - conf->channel_name = channel_name; - return 1; - -system_error: - eina_stringshare_del(channel_name); -error: - conf->channel_name = NULL; - return 0; -} - -static int -_mixer_sys_setup_defaults(E_Mixer_Instance *inst) -{ - if ((!_mixer_using_default) && (!e_mixer_pulse_ready())) return 1; - if ((!inst->sys) && (!_mixer_sys_setup_default_card(inst))) - return 0; - - return _mixer_sys_setup_default_channel(inst); -} - -static void -_mixer_pulse_setup(void) -{ - E_Mixer_Instance *inst; - E_Mixer_Module_Context *ctxt; - Eina_List *l; - - e_mixer_pulse_setup(); - - if (!mixer_mod) return; - - ctxt = mixer_mod->data; - EINA_LIST_FOREACH(ctxt->instances, l, inst) - { - if (!inst->conf->card) - _mixer_gadget_configuration_defaults(inst->conf); - } -} - -void -e_mod_mixer_pulse_ready(Eina_Bool ready) -{ - E_Mixer_Instance *inst; - E_Mixer_Module_Context *ctxt; - Eina_List *l; - Eina_Bool pulse = !_mixer_using_default; - static Eina_Bool called = EINA_FALSE; - - if (!mixer_mod) return; - - if (called && (ready != _mixer_using_default)) return; // prevent multiple calls - ctxt = mixer_mod->data; - if (pulse != _mixer_using_default) - { - EINA_LIST_FOREACH(ctxt->instances, l, inst) - { - e_mod_mixer_channel_info_free(inst->channel); - e_mod_mixer_del(inst->sys); - inst->channel = NULL; - inst->sys = NULL; - } - } - if (ready) _mixer_pulse_setup(); - else e_mixer_default_setup(); - - EINA_LIST_FOREACH(ctxt->instances, l, inst) - { - if (pulse != _mixer_using_default) - _mixer_gadget_configuration_defaults(inst->conf); - if ((!_mixer_sys_setup(inst)) && (!_mixer_sys_setup_defaults(inst))) - { - if (inst->sys) - e_mod_mixer_del(inst->sys); - inst->sys = NULL; - return; - } - if (_mixer_using_default) e_mixer_system_callback_set(inst->sys, _mixer_system_cb_update, inst); - else e_mixer_system_callback_set(inst->sys, NULL, NULL); - if ((inst->mixer_state.left > -1) && (inst->mixer_state.right > -1) && (inst->mixer_state.mute > -1)) - e_mod_mixer_volume_set(inst->sys, inst->channel, - inst->mixer_state.left, inst->mixer_state.right); - else - e_mod_mixer_state_get(inst->sys, inst->channel, &inst->mixer_state); - _mixer_gadget_update(inst); - } - called = EINA_TRUE; -} - -void -e_mod_mixer_pulse_update(void) -{ - E_Mixer_Instance *inst; - E_Mixer_Module_Context *ctxt; - Eina_List *l; - - if (!mixer_mod) return; - - ctxt = mixer_mod->data; - EINA_LIST_FOREACH(ctxt->instances, l, inst) - { - if (inst->conf->using_default) - _mixer_sys_setup_default_card(inst); - e_mod_mixer_state_get(inst->sys, inst->channel, &inst->mixer_state); - _mixer_gadget_update(inst); - } -} - -/* Gadcon Api Functions */ -static void _mixer_module_configuration_setup(E_Mixer_Module_Context *ctxt); - -static E_Gadcon_Client * -_gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style) -{ - E_Mixer_Instance *inst; - E_Mixer_Module_Context *ctxt; - E_Mixer_Gadget_Config *conf; - - if (!mixer_mod) - return NULL; - - ctxt = mixer_mod->data; - _mixer_actions_register(ctxt); - if (!ctxt->conf) - { - _mixer_module_configuration_setup(ctxt); - if (!ctxt->conf) - return NULL; - } - - conf = eina_hash_find(ctxt->conf->gadgets, id); - if (!conf) - { - conf = _mixer_gadget_configuration_new(ctxt->conf, id); - if (!conf) - return NULL; - } - - inst = E_NEW(E_Mixer_Instance, 1); - inst->conf = conf; - inst->mixer_state.right = inst->conf->state.right; - inst->mixer_state.left = inst->conf->state.left; - inst->mixer_state.mute = inst->conf->state.mute; -#ifdef HAVE_ENOTIFY - inst->notification_id = 0; -#endif - conf->instance = inst; - if ((!_mixer_sys_setup(inst)) && (!_mixer_sys_setup_defaults(inst))) - { - if (inst->sys) - e_mod_mixer_del(inst->sys); - _mixer_gadget_configuration_free(ctxt->conf, conf); - E_FREE(inst); - return NULL; - } - - if (_mixer_using_default) e_mixer_system_callback_set(inst->sys, _mixer_system_cb_update, inst); - - inst->ui.gadget = edje_object_add(gc->evas); - e_theme_edje_object_set(inst->ui.gadget, "base/theme/modules/mixer", - "e/modules/mixer/main"); - - inst->gcc = e_gadcon_client_new(gc, name, id, style, inst->ui.gadget); - inst->gcc->data = inst; - - evas_object_event_callback_add(inst->ui.gadget, EVAS_CALLBACK_MOUSE_DOWN, - _mixer_cb_mouse_down, inst); - evas_object_event_callback_add(inst->ui.gadget, EVAS_CALLBACK_MOUSE_WHEEL, - _mixer_cb_mouse_wheel, inst); - - if (inst->sys) - { - if (_mixer_using_default && - ((inst->mixer_state.left > -1) && (inst->mixer_state.right > -1) && (inst->mixer_state.mute > -1))) - e_mod_mixer_volume_set(inst->sys, inst->channel, - inst->mixer_state.left, inst->mixer_state.right); - else - e_mod_mixer_state_get(inst->sys, inst->channel, &inst->mixer_state); - _mixer_gadget_update(inst); - } - - if (!ctxt->conf->default_gc_id) - { - ctxt->conf->default_gc_id = eina_stringshare_add(id); - ctxt->default_instance = inst; - } - else if ((!ctxt->default_instance) || - (strcmp(id, ctxt->conf->default_gc_id) == 0)) - ctxt->default_instance = inst; - - ctxt->instances = eina_list_append(ctxt->instances, inst); - - return inst->gcc; -} - -static void -_gc_shutdown(E_Gadcon_Client *gcc) -{ - E_Mixer_Module_Context *ctxt; - E_Mixer_Instance *inst; - - if (!mixer_mod) - return; - - ctxt = mixer_mod->data; - if (!ctxt) - return; - - inst = gcc->data; - if (!inst) - return; - - inst->conf->state.mute = inst->mixer_state.mute; - inst->conf->state.left = inst->mixer_state.left; - inst->conf->state.right = inst->mixer_state.right; - evas_object_del(inst->ui.gadget); - e_mod_mixer_channel_info_free(inst->channel); - e_mod_mixer_del(inst->sys); - - inst->conf->instance = NULL; - ctxt->instances = eina_list_remove(ctxt->instances, inst); - - if (ctxt->default_instance == inst) - { - ctxt->default_instance = NULL; - _mixer_actions_unregister(ctxt); - } - - E_FREE(inst); -} - -static void -_gc_orient(E_Gadcon_Client *gcc, E_Gadcon_Orient orient EINA_UNUSED) -{ - e_gadcon_client_aspect_set(gcc, 16, 16); - e_gadcon_client_min_size_set(gcc, 16, 16); -} - -static const char * -_gc_label(const E_Gadcon_Client_Class *client_class EINA_UNUSED) -{ - return (char *)_(_e_mixer_Name); -} - -static Evas_Object * -_gc_icon(const E_Gadcon_Client_Class *client_class EINA_UNUSED, Evas *evas) -{ - Evas_Object *o = edje_object_add(evas); - edje_object_file_set(o, e_mixer_theme_path(), "icon"); - return o; -} - -static const char * -_gc_id_new(const E_Gadcon_Client_Class *client_class EINA_UNUSED) -{ - E_Mixer_Module_Context *ctxt; - Eina_List *instances; - - if (!mixer_mod) - return NULL; - - ctxt = mixer_mod->data; - if (!ctxt) - return NULL; - - instances = ctxt->instances; - snprintf(tmpbuf, sizeof(tmpbuf), "mixer.%d", eina_list_count(instances)); - return tmpbuf; -} - -static const E_Gadcon_Client_Class _gc_class = -{ - GADCON_CLIENT_CLASS_VERSION, _name, - { - _gc_init, _gc_shutdown, _gc_orient, _gc_label, _gc_icon, _gc_id_new, NULL, - e_gadcon_site_is_not_toolbar - }, - E_GADCON_CLIENT_STYLE_PLAIN -}; - -E_API E_Module_Api e_modapi = {E_MODULE_API_VERSION, _e_mixer_Name}; - -static void -_mixer_cb_volume_modify(Eina_Bool up) -{ - E_Mixer_Module_Context *ctxt; - - if (!mixer_mod) - return; - - ctxt = mixer_mod->data; - if (!ctxt->conf) - return; - - if (!ctxt->default_instance) - return; - - if ((ecore_loop_time_get() - ctxt->last_act_time) < 0.04) - return; - - ctxt->last_act_time = ecore_loop_time_get(); - - if (ctxt->default_instance->conf->keybindings_popup && (!e_comp->nocomp)) - _mixer_popup_timer_new(ctxt->default_instance); - _mixer_volume_change(ctxt->default_instance, up, EINA_TRUE); -} - -static void -_mixer_cb_volume_increase(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED) -{ - _mixer_cb_volume_modify(EINA_TRUE); -} - -static void -_mixer_cb_volume_decrease(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED) -{ - _mixer_cb_volume_modify(EINA_FALSE); -} - -static void -_mixer_cb_volume_mute(E_Object *obj EINA_UNUSED, const char *params EINA_UNUSED) -{ - E_Mixer_Module_Context *ctxt; - - if (!mixer_mod) - return; - - ctxt = mixer_mod->data; - if (!ctxt->conf) - return; - - if (!ctxt->default_instance) - return; - - if ((ecore_loop_time_get() - ctxt->last_act_time) < 0.1) - return; - - ctxt->last_act_time = ecore_loop_time_get(); - - if (ctxt->default_instance->conf->keybindings_popup && (!e_comp->nocomp)) - _mixer_popup_timer_new(ctxt->default_instance); - _mixer_toggle_mute(ctxt->default_instance, EINA_TRUE); -} - -static E_Config_Dialog * -_mixer_module_config(Evas_Object *parent EINA_UNUSED, const char *params EINA_UNUSED) -{ - E_Mixer_Module_Context *ctxt; - - if (!mixer_mod) - return NULL; - - ctxt = mixer_mod->data; - if (!ctxt) - return NULL; - - if (ctxt->conf_dialog) - return NULL; - - if (!ctxt->conf) - { - _mixer_module_configuration_setup(ctxt); - if (!ctxt->conf) - return NULL; - } - - ctxt->conf_dialog = e_mixer_config_module_dialog_new(NULL, ctxt); - return ctxt->conf_dialog; -} - -static const char _reg_cat[] = "extensions"; -static const char _reg_item[] = "extensions/mixer"; - -static void -_mixer_configure_registry_register(void) -{ - e_configure_registry_category_add(_reg_cat, 90, _("Extensions"), NULL, - "preferences-extensions"); - e_configure_registry_item_add(_reg_item, 30, _(_e_mixer_Name), NULL, - "preferences-desktop-mixer", - _mixer_module_config); -} - -static void -_mixer_configure_registry_unregister(void) -{ - e_configure_registry_item_del(_reg_item); - e_configure_registry_category_del(_reg_cat); -} - -static E_Config_DD * -_mixer_module_configuration_descriptor_new(E_Config_DD *gadget_conf_edd) -{ - E_Config_DD *conf_edd; - - conf_edd = E_CONFIG_DD_NEW("Mixer_Module_Config", E_Mixer_Module_Config); - if (!conf_edd) - return NULL; - E_CONFIG_VAL(conf_edd, E_Mixer_Module_Config, version, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Module_Config, default_gc_id, STR); - E_CONFIG_HASH(conf_edd, E_Mixer_Module_Config, gadgets, gadget_conf_edd); - E_CONFIG_VAL(conf_edd, E_Mixer_Module_Config, desktop_notification, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Module_Config, disable_pulse, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Module_Config, external_mixer_enabled, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Module_Config, external_mixer_command, STR); - - return conf_edd; -} - -static inline void -_mixer_module_configuration_descriptor_free(E_Config_DD *conf_edd) -{ - if (!conf_edd) - return; - E_CONFIG_DD_FREE(conf_edd); -} - -static E_Config_DD * -_mixer_gadget_configuration_descriptor_new(void) -{ - E_Config_DD *conf_edd; - - conf_edd = E_CONFIG_DD_NEW("Mixer_Gadget_Config", E_Mixer_Gadget_Config); - if (!conf_edd) - return NULL; - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, lock_sliders, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, show_locked, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, keybindings_popup, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, card, STR); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, channel_name, STR); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, using_default, UCHAR); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, state.mute, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, state.left, INT); - E_CONFIG_VAL(conf_edd, E_Mixer_Gadget_Config, state.right, INT); - - return conf_edd; -} - -static inline void -_mixer_gadget_configuration_descriptor_free(E_Config_DD *conf_edd) -{ - if (!conf_edd) - return; - E_CONFIG_DD_FREE(conf_edd); -} - -static E_Mixer_Module_Config * -_mixer_module_configuration_load(E_Config_DD *module_conf_edd) -{ - E_Mixer_Module_Config *conf; - - conf = e_config_domain_load(_conf_domain, module_conf_edd); - - if (!conf) - return _mixer_module_configuration_new(); - - if (conf && !e_util_module_config_check(_("Mixer Module"), conf->version, - MOD_CONFIG_FILE_VERSION)) - { - _mixer_module_configuration_free(conf); - return _mixer_module_configuration_new(); - } - - return conf; -} - -static void -_mixer_module_configuration_setup(E_Mixer_Module_Context *ctxt) -{ - E_Config_DD *module_edd, *gadget_edd; - - gadget_edd = _mixer_gadget_configuration_descriptor_new(); - module_edd = _mixer_module_configuration_descriptor_new(gadget_edd); - ctxt->gadget_conf_edd = gadget_edd; - ctxt->module_conf_edd = module_edd; - ctxt->conf = _mixer_module_configuration_load(module_edd); - - ctxt->conf->version = MOD_CONFIG_FILE_VERSION; - ctxt->desktop_notification = ctxt->conf->desktop_notification; - ctxt->disable_pulse = ctxt->conf->disable_pulse; - ctxt->external_mixer_enabled = ctxt->conf->external_mixer_enabled; - if (ctxt->conf->external_mixer_command) - ctxt->external_mixer_command = strdup(ctxt->conf->external_mixer_command); - else - ctxt->external_mixer_command = strdup(""); -} - -static const char _act_increase[] = "volume_increase"; -static const char _act_decrease[] = "volume_decrease"; -static const char _act_mute[] = "volume_mute"; -static const char _lbl_increase[] = N_("Increase Volume"); -static const char _lbl_decrease[] = N_("Decrease Volume"); -static const char _lbl_mute[] = N_("Mute Volume"); - -static void -_mixer_actions_register(E_Mixer_Module_Context *ctxt) -{ - if (!ctxt->actions.incr) - { - ctxt->actions.incr = e_action_add(_act_increase); - if (ctxt->actions.incr) - { - ctxt->actions.incr->func.go = _mixer_cb_volume_increase; - e_action_predef_name_set(_e_mixer_Name, _lbl_increase, - _act_increase, NULL, NULL, 0); - } - } - - if (!ctxt->actions.decr) - { - ctxt->actions.decr = e_action_add(_act_decrease); - if (ctxt->actions.decr) - { - ctxt->actions.decr->func.go = _mixer_cb_volume_decrease; - e_action_predef_name_set(_e_mixer_Name, _lbl_decrease, - _act_decrease, NULL, NULL, 0); - } - } - - if (!ctxt->actions.mute) - { - ctxt->actions.mute = e_action_add(_act_mute); - if (ctxt->actions.mute) - { - ctxt->actions.mute->func.go = _mixer_cb_volume_mute; - e_action_predef_name_set(_e_mixer_Name, _lbl_mute, _act_mute, - NULL, NULL, 0); - e_comp_canvas_keys_ungrab(); - e_comp_canvas_keys_grab(); - } - } -} - -static void -_mixer_actions_unregister(E_Mixer_Module_Context *ctxt) -{ - if (ctxt->actions.incr) - { - e_action_predef_name_del(_e_mixer_Name, _lbl_increase); - e_action_del(_act_increase); - ctxt->actions.incr = NULL; - } - - if (ctxt->actions.decr) - { - e_action_predef_name_del(_e_mixer_Name, _lbl_decrease); - e_action_del(_act_decrease); - ctxt->actions.decr = NULL; - } - - if (ctxt->actions.mute) - { - e_action_predef_name_del(_e_mixer_Name, _lbl_mute); - e_action_del(_act_mute); - e_comp_canvas_keys_ungrab(); - e_comp_canvas_keys_grab(); - ctxt->actions.mute = NULL; - } -} - -E_API void * -e_modapi_init(E_Module *m) -{ - E_Mixer_Module_Context *ctxt; - - ctxt = E_NEW(E_Mixer_Module_Context, 1); - if (!ctxt) - return NULL; - - _mixer_module_configuration_setup(ctxt); - if (!ctxt->conf) - { - free(ctxt); - return NULL; - } - - _mixer_configure_registry_register(); - e_gadcon_provider_register(&_gc_class); - if (!ctxt->disable_pulse) - { - if (!e_mixer_pulse_init()) e_mixer_default_setup(); - else _mixer_pulse_setup(); - } - else - e_mixer_default_setup(); - - mixer_mod = m; - return ctxt; -} - -static void -_mixer_instances_free(E_Mixer_Module_Context *ctxt) -{ - while (ctxt->instances) - { - E_Mixer_Instance *inst = ctxt->instances->data; - e_object_del(E_OBJECT(inst->gcc)); - } -} - -E_API int -e_modapi_shutdown(E_Module *m) -{ - E_Mixer_Module_Context *ctxt; - - ctxt = m->data; - if (!ctxt) - return 0; - - _mixer_instances_free(ctxt); - - if (ctxt->conf_dialog) - e_object_del(E_OBJECT(ctxt->conf_dialog)); - - if (ctxt->mixer_dialog) - e_object_del(E_OBJECT(ctxt->mixer_dialog)); - - _mixer_configure_registry_unregister(); - _mixer_actions_unregister(ctxt); - e_gadcon_provider_unregister(&_gc_class); - - if (ctxt->conf) - { - _mixer_module_configuration_free(ctxt->conf); - _mixer_gadget_configuration_descriptor_free(ctxt->gadget_conf_edd); - _mixer_module_configuration_descriptor_free(ctxt->module_conf_edd); - } - - e_mixer_pulse_shutdown(); - - E_FREE(ctxt); - mixer_mod = NULL; - return 1; -} - -E_API int -e_modapi_save(E_Module *m) -{ - E_Mixer_Module_Context *ctxt; - - ctxt = m->data; - if (!ctxt) - return 0; - if (!ctxt->conf) - return 1; - - return e_config_domain_save(_conf_domain, ctxt->module_conf_edd, ctxt->conf); -} - diff --git a/src/modules/mixer/e_mod_main.h b/src/modules/mixer/e_mod_main.h deleted file mode 100644 index f786fbc58..000000000 --- a/src/modules/mixer/e_mod_main.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef E_MOD_MAIN_H -#define E_MOD_MAIN_H - -#include "e.h" -#include "e_mod_mixer.h" - -/* Increment for Major Changes */ -#define MOD_CONFIG_FILE_EPOCH 1 -/* Increment for Minor Changes (ie: user doesn't need a new config) */ -#define MOD_CONFIG_FILE_GENERATION 1 -#define MOD_CONFIG_FILE_VERSION ((MOD_CONFIG_FILE_EPOCH * 1000000) + MOD_CONFIG_FILE_GENERATION) - -typedef struct E_Mixer_Gadget_Config -{ - int lock_sliders; - int show_locked; - int keybindings_popup; - const char *card; - const char *channel_name; - const char *id; - E_Mixer_Channel_State state; - Eina_Bool using_default; - E_Config_Dialog *dialog; - struct E_Mixer_Instance *instance; -} E_Mixer_Gadget_Config; - -typedef struct E_Mixer_Module_Config -{ - int version; - const char *default_gc_id; - Eina_Hash *gadgets; - int desktop_notification; - int disable_pulse; - int external_mixer_enabled; - const char *external_mixer_command; -} E_Mixer_Module_Config; - -typedef struct E_Mixer_Instance -{ - E_Gadcon_Client *gcc; - E_Gadcon_Popup *popup; - Ecore_Timer *popup_timer; - - struct - { - Evas_Object *gadget; - Evas_Object *label; - Evas_Object *left; - Evas_Object *right; - Evas_Object *mute; - Evas_Object *table; - Evas_Object *button; - } ui; - - E_Mixer_System *sys; - E_Mixer_Channel_Info *channel; - E_Mixer_Channel_State mixer_state; - E_Mixer_Gadget_Config *conf; - -#ifdef HAVE_ENOTIFY - unsigned int notification_id; -#endif -} E_Mixer_Instance; - -typedef struct E_Mixer_Module_Context -{ - E_Config_DD *module_conf_edd; - E_Config_DD *gadget_conf_edd; - E_Mixer_Module_Config *conf; - E_Config_Dialog *conf_dialog; - E_Mixer_Instance *default_instance; - Eina_List *instances; - E_Dialog *mixer_dialog; - double last_act_time; - struct st_mixer_actions - { - E_Action *incr; - E_Action *decr; - E_Action *mute; - } actions; - int desktop_notification; - int disable_pulse; - int external_mixer_enabled; - char *external_mixer_command; -} E_Mixer_Module_Context; - -E_API extern E_Module_Api e_modapi; -E_API void *e_modapi_init(E_Module *m); -E_API int e_modapi_shutdown(E_Module *m); -E_API int e_modapi_save(E_Module *m); - -E_Config_Dialog *e_mixer_config_module_dialog_new(Evas_Object *parent, E_Mixer_Module_Context *ctxt); -E_Config_Dialog *e_mixer_config_dialog_new(Evas_Object *parent, E_Mixer_Gadget_Config *conf); -E_Dialog *e_mixer_app_dialog_new(Evas_Object *parent, void (*func)(E_Dialog *dialog, void *data), void *data); -int e_mixer_app_dialog_select(E_Dialog *dialog, const char *card_name, const char *channel_name); - -int e_mixer_update(E_Mixer_Instance *inst); -const char *e_mixer_theme_path(void); - -void e_mod_mixer_pulse_ready(Eina_Bool); -void e_mod_mixer_pulse_update(void); - -#endif diff --git a/src/modules/mixer/e_mod_mixer.c b/src/modules/mixer/e_mod_mixer.c deleted file mode 100644 index a03da17a7..000000000 --- a/src/modules/mixer/e_mod_mixer.c +++ /dev/null @@ -1,114 +0,0 @@ -#include "e_mod_mixer.h" - -Eina_Bool _mixer_using_default = EINA_FALSE; -E_Mixer_Volume_Get_Cb e_mod_mixer_volume_get; -E_Mixer_Volume_Set_Cb e_mod_mixer_volume_set; -E_Mixer_Mute_Get_Cb e_mod_mixer_mute_get; -E_Mixer_Mute_Set_Cb e_mod_mixer_mute_set; -E_Mixer_State_Get_Cb e_mod_mixer_state_get; -E_Mixer_Cb e_mod_mixer_new; -E_Mixer_Cb e_mod_mixer_del; -E_Mixer_Cb e_mod_mixer_channel_default_name_get; -E_Mixer_Cb e_mod_mixer_channel_info_get_by_name; -E_Mixer_Cb e_mod_mixer_channels_get; -E_Mixer_Cb e_mod_mixer_channel_names_get; -E_Mixer_Cb e_mod_mixer_card_name_get; -E_Mixer_Cb e_mod_mixer_card_names_get; -E_Mixer_Cb e_mod_mixer_card_default_get; - -void -e_mixer_default_setup(void) -{ - e_mod_mixer_volume_get = (void *)e_mixer_system_get_volume; - e_mod_mixer_volume_set = (void *)e_mixer_system_set_volume; - e_mod_mixer_mute_get = (void *)e_mixer_system_get_mute; - e_mod_mixer_mute_set = (void *)e_mixer_system_set_mute; - e_mod_mixer_state_get = (void *)e_mixer_system_get_state; - e_mod_mixer_new = (void *)e_mixer_system_new; - e_mod_mixer_del = (void *)e_mixer_system_del; - e_mod_mixer_channel_default_name_get = (void *)e_mixer_system_get_default_channel_name; - e_mod_mixer_channel_info_get_by_name = (void *)e_mixer_system_get_channel_by_name; - e_mod_mixer_channels_get = (void *)e_mixer_system_get_channels; - e_mod_mixer_channel_names_get = (void *)e_mixer_system_get_channel_names; - e_mod_mixer_card_name_get = (void *)e_mixer_system_get_card_name; - e_mod_mixer_card_names_get = (void *)e_mixer_system_get_cards; - e_mod_mixer_card_default_get = (void *)e_mixer_system_get_default_card; - _mixer_using_default = EINA_TRUE; -} - -void -e_mixer_pulse_setup() -{ - e_mod_mixer_volume_get = (void *)e_mixer_pulse_get_volume; - e_mod_mixer_volume_set = (void *)e_mixer_pulse_set_volume; - e_mod_mixer_mute_get = (void *)e_mixer_pulse_get_mute; - e_mod_mixer_mute_set = (void *)e_mixer_pulse_set_mute; - e_mod_mixer_state_get = (void *)e_mixer_pulse_get_state; - e_mod_mixer_new = (void *)e_mixer_pulse_new; - e_mod_mixer_del = (void *)e_mixer_pulse_del; - e_mod_mixer_channel_default_name_get = (void *)e_mixer_pulse_get_default_channel_name; - e_mod_mixer_channel_info_get_by_name = (void *)e_mixer_pulse_get_channel_by_name; - e_mod_mixer_channels_get = (void *)e_mixer_pulse_get_channels; - e_mod_mixer_channel_names_get = (void *)e_mixer_pulse_get_channel_names; - e_mod_mixer_card_name_get = (void *)e_mixer_pulse_get_card_name; - e_mod_mixer_card_names_get = (void *)e_mixer_pulse_get_cards; - e_mod_mixer_card_default_get = (void *)e_mixer_pulse_get_default_card; - _mixer_using_default = EINA_FALSE; -} - -static int -_channel_info_cmp(const void *data_a, const void *data_b) -{ - const E_Mixer_Channel_Info *a = data_a, *b = data_b; - - if (e_mod_mixer_channel_group_get(a) == e_mod_mixer_channel_group_get(b)) - return strcmp(a->name, b->name); - if (e_mod_mixer_channel_is_boost(a)) - return 1; - if (e_mod_mixer_channel_is_boost(b)) - return -1; - if (e_mod_mixer_channel_group_get(a) < e_mod_mixer_channel_group_get(b)) - return 1; - return -1; -} - -void e_mod_mixer_channel_info_free(E_Mixer_Channel_Info* info) -{ - if (!info) return; - eina_stringshare_del(info->name); - free(info); -} - -Eina_List * -e_mod_mixer_channel_infos_get(const E_Mixer_System *sys) -{ - return eina_list_sort(e_mod_mixer_channels_get(sys), -1, _channel_info_cmp); -} - -void -e_mod_mixer_channel_infos_free(Eina_List *list) -{ - E_Mixer_Channel_Info *info; - - EINA_LIST_FREE(list, info) - { - eina_stringshare_del(info->name); - free(info); - } -} - -void -e_mod_mixer_channel_names_free(Eina_List *list) -{ - const char *str; - EINA_LIST_FREE(list, str) - eina_stringshare_del(str); -} - -void -e_mod_mixer_card_names_free(Eina_List *list) -{ - const char *str; - EINA_LIST_FREE(list, str) - eina_stringshare_del(str); -} diff --git a/src/modules/mixer/e_mod_mixer.h b/src/modules/mixer/e_mod_mixer.h deleted file mode 100644 index f9800cede..000000000 --- a/src/modules/mixer/e_mod_mixer.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef E_MOD_MIXER_H -#define E_MOD_MIXER_H - -#include "e.h" - -typedef void E_Mixer_App; -typedef void E_Mixer_System; -typedef void E_Mixer_Channel; - -typedef struct _E_Mixer_Channel_State -{ - int mute; - int left; - int right; -} E_Mixer_Channel_State; - -#define E_MIXER_CHANNEL_CAN_MUTE 0x01 -#define E_MIXER_CHANNEL_IS_MONO 0x02 -#define E_MIXER_CHANNEL_HAS_CAPTURE 0x04 -#define E_MIXER_CHANNEL_HAS_PLAYBACK 0x08 -#define E_MIXER_CHANNEL_GROUP_MASK 0xFC -#define E_MIXER_CHANNEL_USABLE_MASK 0xFD - -#define e_mod_mixer_channel_is_mutable(_ch) \ - ( ((_ch)->capabilities & E_MIXER_CHANNEL_CAN_MUTE )!=0 ) -#define e_mod_mixer_channel_is_mono(_ch) \ - ( ((_ch)->capabilities & E_MIXER_CHANNEL_IS_MONO )!=0 ) -#define e_mod_mixer_channel_has_capture(_ch) \ - ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_CAPTURE )!=0 ) -#define e_mod_mixer_channel_has_playback(_ch) \ - ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_PLAYBACK )!=0 ) -#define e_mod_mixer_channel_is_boost(_ch) \ - ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_PLAYBACK )!=0 && \ - ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_CAPTURE )!=0 ) -#define e_mod_mixer_channel_has_no_volume(_ch) \ - ( ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_PLAYBACK )==0 && \ - ((_ch)->capabilities & E_MIXER_CHANNEL_HAS_CAPTURE )==0 ) -#define e_mod_mixer_channel_group_get(_ch) \ - ( (_ch)->capabilities & E_MIXER_CHANNEL_GROUP_MASK ) -#define e_mod_mixer_capabilities_usable(_capa) \ - ( ((_capa) & E_MIXER_CHANNEL_USABLE_MASK)!=0 ) - -typedef struct _E_Mixer_Channel_Info -{ - int capabilities; - const char *name; - E_Mixer_Channel *id; - E_Mixer_App *app; -} E_Mixer_Channel_Info; - -typedef int (*E_Mixer_Volume_Set_Cb)(const E_Mixer_System *, const E_Mixer_Channel_Info *, int, int); -typedef int (*E_Mixer_Volume_Get_Cb)(const E_Mixer_System *, const E_Mixer_Channel_Info *, int *, int *); -typedef int (*E_Mixer_Mute_Get_Cb)(const E_Mixer_System *, const E_Mixer_Channel_Info *, int *); -typedef int (*E_Mixer_Mute_Set_Cb)(const E_Mixer_System *, const E_Mixer_Channel_Info *, int); -typedef int (*E_Mixer_State_Get_Cb)(const E_Mixer_System *, const E_Mixer_Channel_Info *, E_Mixer_Channel_State *); -typedef int (*E_Mixer_Capture_Cb)(const E_Mixer_System *, const E_Mixer_Channel_Info *); -typedef void *(*E_Mixer_Cb)(); - -extern Eina_Bool _mixer_using_default; -extern E_Mixer_Volume_Get_Cb e_mod_mixer_volume_get; -extern E_Mixer_Volume_Set_Cb e_mod_mixer_volume_set; -extern E_Mixer_Mute_Get_Cb e_mod_mixer_mute_get; -extern E_Mixer_Mute_Set_Cb e_mod_mixer_mute_set; -extern E_Mixer_State_Get_Cb e_mod_mixer_state_get; -extern E_Mixer_Cb e_mod_mixer_new; -extern E_Mixer_Cb e_mod_mixer_del; -extern E_Mixer_Cb e_mod_mixer_channel_default_name_get; -extern E_Mixer_Cb e_mod_mixer_channel_info_get_by_name; -extern E_Mixer_Cb e_mod_mixer_channel_names_get; -extern E_Mixer_Cb e_mod_mixer_card_name_get; -extern E_Mixer_Cb e_mod_mixer_card_names_get; -extern E_Mixer_Cb e_mod_mixer_card_default_get; - -void e_mod_mixer_channel_info_free(E_Mixer_Channel_Info*); -Eina_List *e_mod_mixer_channel_infos_get(const E_Mixer_System *sys); -void e_mod_mixer_channel_infos_free(Eina_List*); -void e_mod_mixer_channel_names_free(Eina_List*); -void e_mod_mixer_card_names_free(Eina_List*); - -void e_mixer_default_setup(void); -void e_mixer_pulse_setup(); - -/* ALSA | DUMMY */ -int e_mixer_system_callback_set(const E_Mixer_System *self, int (*func)(void *data, E_Mixer_System *self), void *data); - -E_Mixer_System *e_mixer_system_new(const char *card); -void e_mixer_system_del(E_Mixer_System *self); - -Eina_List *e_mixer_system_get_cards(void); -const char *e_mixer_system_get_default_card(void); -const char *e_mixer_system_get_card_name(const char *card); - -Eina_List *e_mixer_system_get_channels(const E_Mixer_System *self); -Eina_List *e_mixer_system_get_channel_names(const E_Mixer_System *self); - -const char *e_mixer_system_get_default_channel_name(const E_Mixer_System *self); -E_Mixer_Channel_Info *e_mixer_system_get_channel_by_name(const E_Mixer_System *self, const char *name); - -int e_mixer_system_get_volume(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int *left, int *right); -int e_mixer_system_set_volume(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int left, int right); -int e_mixer_system_get_mute(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int *mute); -int e_mixer_system_set_mute(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int mute); -int e_mixer_system_get_state(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, E_Mixer_Channel_State *state); - -/* PULSE */ -int pulse_init(void); -Eina_Bool e_mixer_pulse_ready(void); -Eina_Bool e_mixer_pulse_init(void); -void e_mixer_pulse_shutdown(void); - -E_Mixer_System *e_mixer_pulse_new(const char *name); -void e_mixer_pulse_del(E_Mixer_System *self); - -Eina_List *e_mixer_pulse_get_cards(void); -const char *e_mixer_pulse_get_default_card(void); -const char *e_mixer_pulse_get_card_name(const char *card); - -Eina_List *e_mixer_pulse_get_channels(const E_Mixer_System *self); -Eina_List *e_mixer_pulse_get_channel_names(const E_Mixer_System *self); - -const char *e_mixer_pulse_get_default_channel_name(const E_Mixer_System *self); -E_Mixer_Channel_Info *e_mixer_pulse_get_channel_by_name(const E_Mixer_System *self, const char *name); - -int e_mixer_pulse_get_volume(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int *left, int *right); -int e_mixer_pulse_set_volume(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int left, int right); -int e_mixer_pulse_get_mute(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int *mute); -int e_mixer_pulse_set_mute(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, int mute); -int e_mixer_pulse_get_state(const E_Mixer_System *self, const E_Mixer_Channel_Info *channel, E_Mixer_Channel_State *state); - -/** - * @addtogroup Optional_Devices - * @{ - * - * @defgroup Module_Mixer Audio Mixer (Volume Control) - * - * Controls the audio volume and mute status for both playback - * (output) and record (input) devices. - * - * Can work with ALSA (http://www.alsa-project.org/) or PulseAudio - * (http://www.pulseaudio.org/). - * - * @} - */ -#endif /* E_MOD_SYSTEM_H */ diff --git a/src/modules/mixer/msg.c b/src/modules/mixer/msg.c deleted file mode 100644 index 5bb091c9c..000000000 --- a/src/modules/mixer/msg.c +++ /dev/null @@ -1,207 +0,0 @@ -#include "pa.h" -#include -#include -#include - -void -msg_recv_creds(Pulse *conn, Pulse_Tag *tag) -{ -#ifdef __linux__ - int r; - struct msghdr mh; - struct iovec iov; - union { - struct cmsghdr hdr; - uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; - } cmsg; - - memset(&iov, 0, sizeof(iov)); - iov.iov_base = &tag->header[tag->pos]; - iov.iov_len = sizeof(tag->header) - tag->pos; - - memset(&cmsg, 0, sizeof(cmsg)); - memset(&mh, 0, sizeof(mh)); - mh.msg_iov = &iov; - mh.msg_iovlen = 1; - mh.msg_control = &cmsg; - mh.msg_controllen = sizeof(cmsg); - - r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0); - if ((!r) || (r == sizeof(tag->header))) tag->auth = EINA_TRUE; - else if (r < 0) - { - if (errno != EAGAIN) - { - ERR("%d: %s", errno, strerror(errno)); - pulse_disconnect(conn); - } - } - else - { - DBG("%zu bytes left", sizeof(tag->header) - r); - tag->pos += r; - } -#else - conn = NULL; - tag = NULL; -#endif -} - -Eina_Bool -msg_recv(Pulse *conn, Pulse_Tag *tag) -{ -#ifdef __linux__ - long r; - struct msghdr mh; - struct iovec iov; - union { - struct cmsghdr hdr; - uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; - } cmsg; - - memset(&iov, 0, sizeof(iov)); - iov.iov_base = tag->data + tag->pos; - iov.iov_len = tag->dsize - tag->pos; - - memset(&cmsg, 0, sizeof(cmsg)); - memset(&mh, 0, sizeof(mh)); - mh.msg_iov = &iov; - mh.msg_iovlen = 1; - mh.msg_control = &cmsg; - mh.msg_controllen = sizeof(cmsg); - - r = recvmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, 0); - DBG("recv %li bytes", r); - /* things we don't really care about: credentials */ - if ((!r) || ((unsigned int)r == tag->dsize)) - { - conn->iq = eina_list_remove(conn->iq, tag); - return EINA_TRUE; - } - else if (r < 0) - { - if (errno != EAGAIN) - { - ERR("%d: %s", errno, strerror(errno)); - pulse_disconnect(conn); - } - } - else - tag->pos += r; -#else - conn = NULL; - tag = NULL; -#endif - return EINA_FALSE; -} - -void -msg_sendmsg_creds(Pulse *conn, Pulse_Tag *tag) -{ -#ifdef __linux__ - int r; - struct msghdr mh; - struct iovec iov; - union { - struct cmsghdr hdr; - uint8_t data[CMSG_SPACE(sizeof(struct ucred))]; - } cmsg; - struct ucred *u; - - memset(&iov, 0, sizeof(iov)); - iov.iov_base = (void*) &tag->header[tag->pos]; - iov.iov_len = sizeof(tag->header) - tag->pos; - - memset(&cmsg, 0, sizeof(cmsg)); - cmsg.hdr.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - cmsg.hdr.cmsg_level = SOL_SOCKET; - cmsg.hdr.cmsg_type = SCM_CREDENTIALS; - - u = (struct ucred*) CMSG_DATA(&cmsg.hdr); - - u->pid = getpid(); - u->uid = getuid(); - u->gid = getgid(); - - memset(&mh, 0, sizeof(mh)); - mh.msg_iov = &iov; - mh.msg_iovlen = 1; - mh.msg_control = &cmsg; - mh.msg_controllen = sizeof(cmsg); - - r = sendmsg(ecore_main_fd_handler_fd_get(conn->fdh), &mh, MSG_NOSIGNAL); - if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE; - else if (r < 0) - { - if (errno != EAGAIN) - { - ERR("%d: %s", errno, strerror(errno)); - pulse_disconnect(conn); - } - } - else - tag->pos += r; -#else - conn = NULL; - tag = NULL; -#endif -} - -void -msg_send_creds(Pulse *conn, Pulse_Tag *tag) -{ -#ifdef __linux__ - int r; - - INF("trying to send 20 byte auth header"); - r = send(ecore_main_fd_handler_fd_get(conn->fdh), &tag->header[tag->pos], sizeof(tag->header) - (tag->pos * sizeof(tag->header[0])), MSG_NOSIGNAL); - INF("%i bytes sent!", r); - if ((!r) || (r == (int)sizeof(tag->header))) tag->auth = EINA_TRUE; - else if (r < 0) - { - if (errno != EAGAIN) - { - ERR("%d: %s", errno, strerror(errno)); - pulse_disconnect(conn); - } - } - else - tag->pos += r; -#else - conn = NULL; - tag = NULL; -#endif -} - -Eina_Bool -msg_send(Pulse *conn, Pulse_Tag *tag) -{ -#ifdef __linux__ - int r; - - INF("trying to send %zu bytes", tag->dsize - tag->pos); - r = send(ecore_main_fd_handler_fd_get(conn->fdh), tag->data + tag->pos, tag->dsize - tag->pos, MSG_NOSIGNAL); - INF("%i bytes sent!", r); - if ((!r) || ((unsigned int)r == tag->dsize - tag->pos)) - { - DBG("Send complete! Deleting tag..."); - conn->oq = eina_list_remove(conn->oq, tag); - pulse_tag_free(tag); - return EINA_TRUE; - } - if (r < 0) - { - if (errno != EAGAIN) - { - ERR("%d: %s", errno, strerror(errno)); - pulse_disconnect(conn); - } - } - else - tag->pos += r; -#else - conn = NULL; - tag = NULL; -#endif - return EINA_FALSE; -} diff --git a/src/modules/mixer/pa.c b/src/modules/mixer/pa.c deleted file mode 100644 index 03ec610e9..000000000 --- a/src/modules/mixer/pa.c +++ /dev/null @@ -1,830 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pa.h" - -static int pulse_init_count = 0; -int pa_log_dom = -1; -int PULSE_EVENT_CONNECTED = -1; -int PULSE_EVENT_DISCONNECTED = -1; -int PULSE_EVENT_CHANGE = -1; -Eina_Hash *pulse_sinks = NULL; -Eina_Hash *pulse_sources = NULL; - -void -pulse_fake_free(void *d EINA_UNUSED, void *d2 EINA_UNUSED) -{} - -static void -proplist_init(Pulse_Tag *tag) -{ - Eina_File *file; - size_t size; - const char *str; - int argc; - char **argv; - char pid[32]; - tag->props = eina_hash_string_superfast_new((void*)eina_stringshare_del); -/* - "L\0\0\0\tL\0\0\0\1" - "P" - "tapplication.process.id\0" - "L\0\0\0\5x\0\0\0\0052742\0" - "tapplication.process.user\0" - "L\0\0\0\5x\0\0\0\5root\0" - "tapplication.process.host\0" - "L\0\0\0\fx\0\0\0\fdarc.ath.cx\0" - "tapplication.process.binary\0" - "L\0\0\0\6x\0\0\0\6pactl\0" - "tapplication.name\0" - "L\0\0\0\6x\0\0\0\6pactl\0" - "tapplication.language\0" - "L\0\0\0\vx\0\0\0\ven_US.utf8\0" - "twindow.x11.display\0" - "L\0\0\0\5x\0\0\0\5:0.0\0" - "tapplication.process.machine_id\0" - "L\0\0\0!x\0\0\0!16ebb73850fbfdfff2b0079400000030\0" - "N" -*/ - tag->dsize += PA_TAG_SIZE_PROPLIST; - snprintf(pid, sizeof(pid), "%"PRIu32, getpid()); - eina_hash_add(tag->props, "application.process.id", eina_stringshare_add(pid)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.id") + strlen(pid) + 2 + PA_TAG_SIZE_U32; - - str = getenv("USER"); - eina_hash_add(tag->props, "application.process.user", eina_stringshare_add(str)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.user") + strlen(str) + 2 + PA_TAG_SIZE_U32; - - file = eina_file_open("/etc/hostname", EINA_FALSE); - if (file) - { - size = eina_file_size_get(file); - str = (const char*)eina_file_map_all(file, EINA_FILE_POPULATE); - eina_hash_add(tag->props, "application.process.host", eina_stringshare_add_length(str, size - 1)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.host") + size + 1 + PA_TAG_SIZE_U32; - eina_file_map_free(file, (void*)str); - eina_file_close(file); - } - else - { - eina_hash_add(tag->props, "application.process.host", eina_stringshare_add("")); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.host") + 2 + PA_TAG_SIZE_U32; - } - - ecore_app_args_get(&argc, &argv); - str = strrchr(argv[0], '/'); - str = (str) ? str + 1 : argv[0]; - eina_hash_add(tag->props, "application.process.binary", eina_stringshare_add(str)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.binary") + strlen(str) + 2 + PA_TAG_SIZE_U32; - eina_hash_add(tag->props, "application.name", eina_stringshare_add(str)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.name") + strlen(str) + 2 + PA_TAG_SIZE_U32; - - str = getenv("LANG"); - if (str) - { - eina_hash_add(tag->props, "application.language", eina_stringshare_add(str)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.language") + strlen(str) + 2 + PA_TAG_SIZE_U32; - } - - str = getenv("DISPLAY"); - if (str) - { - eina_hash_add(tag->props, "window.x11.display", eina_stringshare_add(str)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("window.x11.display") + strlen(str) + 2 + PA_TAG_SIZE_U32; - } - - file = eina_file_open(PA_MACHINE_ID, EINA_FALSE); - if (file) - { - size = eina_file_size_get(file); - str = (const char*)eina_file_map_all(file, EINA_FILE_POPULATE); - eina_hash_add(tag->props, "application.process.machine_id", eina_stringshare_add_length(str, size - 1)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.machine_id") + size + 1 + PA_TAG_SIZE_U32; - eina_file_map_free(file, (void*)str); - eina_file_close(file); - return; - } - { - char buf[256]; - - errno = 0; - gethostname(buf, sizeof(buf)); - if (!errno) - { - eina_hash_add(tag->props, "application.process.machine_id", eina_stringshare_add(buf)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.machine_id") + strlen(buf) + 2 + PA_TAG_SIZE_U32; - return; - } - snprintf(buf, sizeof(buf), "%08lx", (unsigned long)gethostid()); - eina_hash_add(tag->props, "application.process.machine_id", eina_stringshare_add(buf)); - tag->dsize += PA_TAG_SIZE_ARBITRARY + sizeof("application.process.machine_id") + strlen(buf) + 2 + PA_TAG_SIZE_U32; - } -} - -static void -cookie_file(uint8_t *cookie) -{ - char buf[4096]; - Eina_File *file; - size_t size; - void *cookie_data; - - snprintf(buf, sizeof(buf), "%s/.pulse-cookie", getenv("HOME")); - file = eina_file_open(buf, EINA_FALSE); - size = eina_file_size_get(file); - cookie_data = eina_file_map_all(file, EINA_FILE_WILLNEED); - memcpy(cookie, cookie_data, size); - eina_file_map_free(file, cookie_data); - eina_file_close(file); -} - -static Pulse_Tag * -login_setup(Pulse *conn) -{ - Pulse_Tag *tag; - uint32_t x; - uint8_t cookie[PA_NATIVE_COOKIE_LENGTH]; - - tag = calloc(1, sizeof(Pulse_Tag)); - tag->dsize = 4 * PA_TAG_SIZE_U32 + sizeof(cookie); - tag->data = calloc(1, tag->dsize); - tag_simple_init(conn, tag, PA_COMMAND_AUTH, PA_TAG_U32); - DBG("%zu bytes", tag->dsize); - - if (!getuid()) - x = PA_PROTOCOL_VERSION; - else - x = PA_PROTOCOL_VERSION | 0x80000000U; - tag_uint32(tag, x); - DBG("%zu bytes", tag->dsize); - - cookie_file(cookie); - tag_arbitrary(tag, cookie, sizeof(cookie)); - DBG("%zu bytes", tag->dsize); - - tag_finish(tag); - - return tag; -} - -static Eina_Bool -pulse_recv(Pulse *conn, Ecore_Fd_Handler *fdh, Pulse_Tag **ret_tag) -{ - Pulse_Tag *tag; - uint32_t x; - - if (ret_tag) *ret_tag = NULL; - tag = eina_list_data_get(conn->iq); - if (!tag) - { - tag = calloc(1, sizeof(Pulse_Tag)); - conn->iq = eina_list_append(conn->iq, tag); - } - if (!tag->auth) - { - msg_recv_creds(conn, tag); - if (!tag->auth) return EINA_FALSE; - } - if (!tag->data) - { - tag->dsize = ntohl(tag->header[PA_PSTREAM_DESCRIPTOR_LENGTH]); - if (!tag->dsize) - { - ERR("Kicked!"); - pulse_disconnect(conn); - return EINA_FALSE; - } - tag->data = malloc(tag->dsize); - } - if (tag->pos < tag->dsize) - { - if (!msg_recv(conn, tag)) - return EINA_FALSE; - } - untag_uint32(tag, &x); - EINA_SAFETY_ON_TRUE_GOTO((x != PA_COMMAND_REPLY) && (x != PA_COMMAND_SUBSCRIBE_EVENT), error); - tag->command = x; - if (x == PA_COMMAND_REPLY) - untag_uint32(tag, &tag->tag_count); - else - tag->size += PA_TAG_SIZE_U32; - if (conn->state != PA_STATE_CONNECTED) - { - ecore_main_fd_handler_active_set(fdh, ECORE_FD_WRITE); - pulse_tag_free(tag); - } - else if (ret_tag) - *ret_tag = tag; - return EINA_TRUE; -error: - ERR("Received error command %"PRIu32"!", x); - pulse_tag_free(tag); - return EINA_FALSE; -} - -static void -login_finish(Pulse *conn, Ecore_Fd_Handler *fdh) -{ - Pulse_Tag *tag; - - tag = calloc(1, sizeof(Pulse_Tag)); - tag->dsize = 2 * PA_TAG_SIZE_U32; /* tag_simple_init */ - proplist_init(tag); - DBG("prep %zu bytes", tag->dsize); - tag->data = malloc(tag->dsize); - tag_simple_init(conn, tag, PA_COMMAND_SET_CLIENT_NAME, PA_TAG_U32); - tag_proplist(tag); - tag_finish(tag); - msg_send_creds(conn, tag); - conn->state++; - if (msg_send(conn, tag)) - ecore_main_fd_handler_active_set(fdh, ECORE_FD_READ); - else - conn->oq = eina_list_append(conn->oq, tag); -} - -static Eina_Bool -fdh_func(Pulse *conn, Ecore_Fd_Handler *fdh) -{ - Pulse_Tag *rprev, *wprev; - int pa_read, pa_write; - - if (conn->watching) pa_read = ECORE_FD_READ; - else - pa_read = !!ecore_main_fd_handler_active_get(fdh, ECORE_FD_READ) * ECORE_FD_READ; - pa_write = !!ecore_main_fd_handler_active_get(fdh, ECORE_FD_WRITE) * ECORE_FD_WRITE; - rprev = eina_list_data_get(conn->iq); - wprev = eina_list_data_get(conn->oq); - - switch (conn->state) - { - case PA_STATE_INIT: - if (!wprev) - { - wprev = login_setup(conn); - conn->oq = eina_list_append(conn->oq, wprev); - } - - if (!wprev->auth) - msg_sendmsg_creds(conn, wprev); - - - if (wprev->auth && msg_send(conn, wprev)) - { - conn->state++; - ecore_main_fd_handler_active_set(fdh, ECORE_FD_READ); - } - break; - case PA_STATE_AUTH: - if (pulse_recv(conn, fdh, NULL)) - login_finish(conn, fdh); - break; - case PA_STATE_MOREAUTH: - if (pa_write) - { - if (msg_send(conn, wprev)) - ecore_main_fd_handler_active_set(fdh, ECORE_FD_READ); - break; - } - if (pulse_recv(conn, fdh, NULL)) - { - conn->state++; - INF("Login complete!"); - ecore_main_fd_handler_active_set(fdh, 0); - ecore_event_add(PULSE_EVENT_CONNECTED, conn, pulse_fake_free, NULL); - } - break; - case PA_STATE_CONNECTED: - if (pa_write) - { - if (wprev) - { - DBG("write"); - if (!wprev->auth) - msg_send_creds(conn, wprev); - if (wprev->auth) - { - if (msg_send(conn, wprev)) - ecore_main_fd_handler_active_set(conn->fdh, ECORE_FD_READ | (!!conn->oq * ECORE_FD_WRITE)); - } - } - else - ecore_main_fd_handler_active_set(conn->fdh, ECORE_FD_READ); - } - if (pa_read) - { - DBG("read"); - if ((!rprev) || (!rprev->auth) || (rprev->pos < rprev->dsize)) - { - Pulse_Tag *tag; - PA_Commands command; - if (!pulse_recv(conn, fdh, &tag)) break; - - command = (uintptr_t)eina_hash_find(conn->tag_handlers, &tag->tag_count); - eina_hash_del_by_key(conn->tag_handlers, &tag->tag_count); - deserialize_tag(conn, command, tag); - if (!eina_list_count(conn->oq)) - ecore_main_fd_handler_active_set(conn->fdh, pa_write | conn->watching * ECORE_FD_READ); - pulse_tag_free(tag); - } - } - default: - break; - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -con(Pulse *conn, int type EINA_UNUSED, Ecore_Con_Event_Server_Add *ev) -{ - int on = 1; - int fd; - int flags; - - if (conn != ecore_con_server_data_get(ev->server)) return ECORE_CALLBACK_PASS_ON; - INF("connected to %s", ecore_con_server_name_get(ev->server)); - - fd = ecore_con_server_fd_get(ev->server); - if (fd >= -1) - conn->fd = dup(fd); - if (fd == -1) - { - pulse_disconnect(conn); - return ECORE_CALLBACK_RENEW; - } - -#ifdef SO_PASSCRED - if (setsockopt(conn->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) - { - pulse_disconnect(conn); - return ECORE_CALLBACK_RENEW; - } -#endif - if ((setsockopt(conn->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) || - (fcntl(conn->fd, F_SETFL, O_NONBLOCK) < 0)) - { - pulse_disconnect(conn); - return ECORE_CALLBACK_RENEW; - } - - flags = fcntl(conn->fd, F_GETFD); - flags |= FD_CLOEXEC; - if (fcntl(conn->fd, F_SETFD, flags) < 0) { ERR("Cannot set CLOEXEC on fd"); } - - conn->fdh = ecore_main_fd_handler_add(conn->fd, ECORE_FD_WRITE, (Ecore_Fd_Cb)fdh_func, conn, NULL, NULL); - ecore_con_server_del(conn->svr); - conn->svr = NULL; - return ECORE_CALLBACK_RENEW; -} - -uint32_t -pulse_cards_get(Pulse *conn) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type = PA_COMMAND_GET_CARD_INFO_LIST; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - tag->dsize = 2 * PA_TAG_SIZE_U32; - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return tag->tag_count; -} - -void -pulse_cb_set(Pulse *conn, uint32_t tagnum, Pulse_Cb cb) -{ - EINA_SAFETY_ON_NULL_RETURN(conn); - - if (cb) eina_hash_set(conn->tag_cbs, &tagnum, cb); - else eina_hash_del_by_key(conn->tag_cbs, &tagnum); -} - -uint32_t -pulse_type_get(Pulse *conn, uint32_t idx, Eina_Bool source) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type = source ? PA_COMMAND_GET_SOURCE_INFO : PA_COMMAND_GET_SINK_INFO; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL; - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_uint32(tag, idx); - tag_string(tag, NULL); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return tag->tag_count; -} - -uint32_t -pulse_types_get(Pulse *conn, Eina_Bool source) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type = source ? PA_COMMAND_GET_SOURCE_INFO_LIST : PA_COMMAND_GET_SINK_INFO_LIST; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - tag->dsize = 2 * PA_TAG_SIZE_U32; - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return tag->tag_count; -} - -uint32_t -pulse_type_mute_set(Pulse *conn, uint32_t sink_num, Eina_Bool mute, Eina_Bool source) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type = source ? PA_COMMAND_SET_SOURCE_MUTE : PA_COMMAND_SET_SINK_MUTE; - Eina_Hash *h; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_BOOLEAN; - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_uint32(tag, sink_num); - tag_string(tag, NULL); - tag_bool(tag, !!mute); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - h = (source) ? pulse_sources : pulse_sinks; - if (h) - { - Pulse_Sink *sink; - - sink = eina_hash_find(h, &sink_num); - if (sink) sink->mute = !!mute; - } - return tag->tag_count; -} - -uint32_t -pulse_type_volume_set(Pulse *conn, uint32_t sink_num, uint8_t channels, double vol, Eina_Bool source) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type = source ? PA_COMMAND_SET_SOURCE_MUTE : PA_COMMAND_SET_SINK_VOLUME; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_CVOLUME + channels * sizeof(uint32_t); - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_uint32(tag, sink_num); - tag_string(tag, NULL); - tag_volume(tag, channels, vol); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return tag->tag_count; -} - -uint32_t -pulse_server_info_get(Pulse *conn) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type = PA_COMMAND_GET_SERVER_INFO; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - tag->dsize = 2 * PA_TAG_SIZE_U32; - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return tag->tag_count; -} - -uint32_t -pulse_sink_channel_volume_set(Pulse *conn, Pulse_Sink *sink, uint32_t id, double vol) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - type = sink->source ? PA_COMMAND_SET_SOURCE_VOLUME : PA_COMMAND_SET_SINK_VOLUME; - tag->dsize = 3 * PA_TAG_SIZE_U32 + PA_TAG_SIZE_STRING_NULL + PA_TAG_SIZE_CVOLUME + sink->channel_map.channels * sizeof(uint32_t); - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - if (vol <= 0.0) sink->volume.values[id] = PA_VOLUME_MUTED; - else sink->volume.values[id] = (vol * PA_VOLUME_NORM) / 100; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_uint32(tag, sink->index); - tag_string(tag, NULL); - tag_cvol(tag, &sink->volume); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return tag->tag_count; -} - -uint32_t -pulse_sink_port_set(Pulse *conn, Pulse_Sink *sink, const char *port) -{ - Pulse_Tag *tag; - int pa_read; - uint32_t type; - Eina_List *l; - const char *p; - Eina_Bool match = EINA_FALSE; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, 0); - EINA_SAFETY_ON_NULL_RETURN_VAL(port, 0); - EINA_LIST_FOREACH(sink->ports, l, p) - { - match = !strcmp(p, port); - if (match) break; - } - EINA_SAFETY_ON_TRUE_RETURN_VAL(!match, 0); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, 0); - type = sink->source ? PA_COMMAND_SET_SOURCE_PORT : PA_COMMAND_SET_SINK_PORT; - tag->dsize = PA_TAG_SIZE_U32 + 2 * PA_TAG_SIZE_STRING + strlen(sink->name) + strlen(port); - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_uint32(tag, sink->index); - tag_string(tag, sink->name); - tag_string(tag, port); - tag_finish(tag); - pa_read = !!ecore_main_fd_handler_active_get(conn->fdh, ECORE_FD_READ) * ECORE_FD_READ; - ecore_main_fd_handler_active_set(conn->fdh, pa_read | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return tag->tag_count; -} - -Eina_Bool -pulse_sinks_watch(Pulse *conn) -{ - Pulse_Tag *tag; - uint32_t type = PA_COMMAND_SUBSCRIBE; - - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, EINA_FALSE); - tag = calloc(1, sizeof(Pulse_Tag)); - EINA_SAFETY_ON_NULL_RETURN_VAL(tag, EINA_FALSE); - tag->dsize = 3 * PA_TAG_SIZE_U32; - tag->data = malloc(tag->dsize); - tag->tag_count = conn->tag_count; - tag_simple_init(conn, tag, type, PA_TAG_U32); - tag_uint32(tag, PA_SUBSCRIPTION_MASK_ALL); - tag_finish(tag); - ecore_main_fd_handler_active_set(conn->fdh, ECORE_FD_READ | ECORE_FD_WRITE); - conn->oq = eina_list_append(conn->oq, tag); - eina_hash_add(conn->tag_handlers, &tag->tag_count, (uintptr_t*)((uintptr_t)type)); - return EINA_TRUE; -} - -int -pulse_init(void) -{ - if (pulse_init_count++) return pulse_init_count; - - eina_init(); - ecore_init(); - ecore_con_init(); - pa_log_dom = eina_log_domain_register("pulse", EINA_COLOR_HIGH EINA_COLOR_BLUE); - - PULSE_EVENT_CONNECTED = ecore_event_type_new(); - PULSE_EVENT_DISCONNECTED = ecore_event_type_new(); - PULSE_EVENT_CHANGE = ecore_event_type_new(); - - return pulse_init_count; -} - -void -pulse_shutdown(void) -{ - if ((!pulse_init_count) || (!--pulse_init_count)) return; - - if (pulse_sinks) eina_hash_free(pulse_sinks); - if (pulse_sources) eina_hash_free(pulse_sources); - pulse_sinks = pulse_sources = NULL; - eina_log_domain_unregister(pa_log_dom); - ecore_con_shutdown(); - ecore_shutdown(); - eina_shutdown(); -} - -Pulse * -pulse_new(void) -{ - Pulse *conn; - Eina_Iterator *it; - const char *prev = NULL, *buf = NULL; - time_t t = 0; - char *home, h[4096]; - const Eina_File_Direct_Info *info; - - conn = calloc(1, sizeof(Pulse)); - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, NULL); - home = getenv("PULSE_RUNTIME_PATH"); - - if (!home) - { - home = getenv("HOME"); - snprintf(h, sizeof(h), "%s/.pulse", home); - home = h; - } - - it = eina_file_direct_ls(home); - EINA_ITERATOR_FOREACH(it, info) - { - const char *rt = NULL; - - rt = strrchr(info->path + info->name_start, '-'); - if (rt) - { - if (!strcmp(rt + 1, "runtime")) - { - struct stat st; - buf = eina_stringshare_printf("%s/native", info->path); - if (stat(buf, &st)) - { - eina_stringshare_del(buf); - buf = NULL; - continue; - } - if (!t) - { - t = st.st_atime; - prev = buf; - buf = NULL; - continue; - } - if (t > st.st_atime) - { - eina_stringshare_del(buf); - buf = NULL; - continue; - } - eina_stringshare_del(prev); - prev = buf; - t = st.st_atime; - buf = NULL; - } - } - } - eina_iterator_free(it); - if (!prev) - { - struct stat st; - char *s; - - s = getenv("XDG_RUNTIME_DIR"); - if (s) snprintf(h, sizeof(h), "%s/pulse/native", s); - buf = eina_stringshare_add(h); - if ((!s) || (stat(h, &st))) - { - snprintf(h, sizeof(h), "/run/user/%i/pulse/native", - (int)getuid()); - if (stat(h, &st)) - { - snprintf(h, sizeof(h), "%s/run/user/%i/pulse/native", - STATEDIR, (int)getuid()); - if (stat(h, &st)) - { - buf = eina_stringshare_add(STATEDIR "/run/pulse/native"); - if (stat(buf, &st)) - { - INF("could not locate local socket '%s'!", buf); - eina_stringshare_del(buf); - free(conn); - return NULL; - } - } - else - buf = eina_stringshare_add(h); - } - else - buf = eina_stringshare_add(h); - } - else - buf = eina_stringshare_add(h); - conn->socket = buf; - } - else conn->socket = prev; - conn->con = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb)con, conn); - conn->tag_handlers = eina_hash_int32_new(NULL); - conn->tag_cbs = eina_hash_int32_new(NULL); - return conn; -} - -void -pulse_free(Pulse *conn) -{ - Pulse_Tag *tag; - if (!conn) return; - if (conn->fdh) ecore_main_fd_handler_del(conn->fdh); - else if (conn->svr) ecore_con_server_del(conn->svr); - if (conn->con) ecore_event_handler_del(conn->con); - eina_stringshare_del(conn->socket); - EINA_LIST_FREE(conn->oq, tag) - pulse_tag_free(tag); - EINA_LIST_FREE(conn->iq, tag) - pulse_tag_free(tag); - eina_hash_free(conn->tag_handlers); - eina_hash_free(conn->tag_cbs); - free(conn); -} - -Eina_Bool -pulse_connect(Pulse *conn) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(conn, EINA_FALSE); - conn->svr = ecore_con_server_connect(ECORE_CON_LOCAL_SYSTEM, conn->socket, -1, conn); - return !!conn->svr; -} - -void -pulse_disconnect(Pulse *conn) -{ - Eina_Bool event = EINA_FALSE; - EINA_SAFETY_ON_NULL_RETURN(conn); - - conn->state = PA_STATE_INIT; - if (conn->fdh) - { - ecore_main_fd_handler_del(conn->fdh); - conn->fdh = NULL; - close(conn->fd); - conn->fd = -1; - event = EINA_TRUE; - } - else if (conn->svr) - { - ecore_con_server_del(conn->svr); - conn->svr = NULL; - event = EINA_TRUE; - } - if (event) - ecore_event_add(PULSE_EVENT_DISCONNECTED, conn, pulse_fake_free, NULL); -} - -void -pulse_server_info_free(Pulse_Server_Info *ev) -{ - if (!ev) return; - - eina_stringshare_del(ev->name); - eina_stringshare_del(ev->version); - eina_stringshare_del(ev->username); - eina_stringshare_del(ev->hostname); - eina_stringshare_del(ev->default_sink); - eina_stringshare_del(ev->default_source); - free(ev); -} diff --git a/src/modules/mixer/pa.h b/src/modules/mixer/pa.h deleted file mode 100644 index c43c06f8c..000000000 --- a/src/modules/mixer/pa.h +++ /dev/null @@ -1,572 +0,0 @@ -#ifndef PA_HACKS_H -#define PA_HACKS_H - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_ARPA_INET_H -# include -#endif - -#ifdef HAVE_NETINET_IN_H -# include -#endif - -#include -#include -#include -#include "Pulse.h" -#include - -#ifndef STATEDIR -# define STATEDIR "/var" -#endif - -#ifndef EINA_UNUSED -# define EINA_UNUSED __attribute__((unused)) -#endif - -# ifdef EINTERN -# undef EINTERN -# endif -# ifdef __GNUC__ -# if __GNUC__ >= 4 -# define EINTERN __attribute__ ((visibility("hidden"))) -# else -# define EINTERN -# endif -# else -# define EINTERN -# endif - -#define PA_PROTOCOL_VERSION 16 -#define PA_NATIVE_COOKIE_LENGTH 256 -#ifndef PA_MACHINE_ID -# define PA_MACHINE_ID "/var/lib/dbus/machine-id" -#endif - -#ifndef _ -# define _(X) (X) -#endif - -#undef DBG -#undef INF -#undef WRN -#undef ERR -#undef CRI - -//#define DBG(...) EINA_LOG_DOM_DBG(pa_log_dom, __VA_ARGS__) -//#define INF(...) EINA_LOG_DOM_INFO(pa_log_dom, __VA_ARGS__) -//#define WRN(...) EINA_LOG_DOM_WARN(pa_log_dom, __VA_ARGS__) -//#define ERR(...) EINA_LOG_DOM_ERR(pa_log_dom, __VA_ARGS__) -//#define CRI(...) EINA_LOG_DOM_CRIT(pa_log_dom, __VA_ARGS__) -#define DBG(...) -#define INF(...) -#define WRN(...) -#define ERR(...) -#define CRI(...) - - -typedef enum -{ - PA_COMMAND_ERROR, - PA_COMMAND_TIMEOUT, /* pseudo command */ - PA_COMMAND_REPLY, - PA_COMMAND_CREATE_PLAYBACK_STREAM, /* Payload changed in v9, v12 (0.9.0, 0.9.8) */ - PA_COMMAND_DELETE_PLAYBACK_STREAM, - PA_COMMAND_CREATE_RECORD_STREAM, /* Payload changed in v9, v12 (0.9.0, 0.9.8) */ - PA_COMMAND_DELETE_RECORD_STREAM, - PA_COMMAND_EXIT, - PA_COMMAND_AUTH, - PA_COMMAND_SET_CLIENT_NAME, - PA_COMMAND_LOOKUP_SINK, - PA_COMMAND_LOOKUP_SOURCE, - PA_COMMAND_DRAIN_PLAYBACK_STREAM, - PA_COMMAND_STAT, - PA_COMMAND_GET_PLAYBACK_LATENCY, - PA_COMMAND_CREATE_UPLOAD_STREAM, - PA_COMMAND_DELETE_UPLOAD_STREAM, - PA_COMMAND_FINISH_UPLOAD_STREAM, - PA_COMMAND_PLAY_SAMPLE, - PA_COMMAND_REMOVE_SAMPLE, - PA_COMMAND_GET_SERVER_INFO, - PA_COMMAND_GET_SINK_INFO, - PA_COMMAND_GET_SINK_INFO_LIST, - PA_COMMAND_GET_SOURCE_INFO, - PA_COMMAND_GET_SOURCE_INFO_LIST, - PA_COMMAND_GET_MODULE_INFO, - PA_COMMAND_GET_MODULE_INFO_LIST, - PA_COMMAND_GET_CLIENT_INFO, - PA_COMMAND_GET_CLIENT_INFO_LIST, - PA_COMMAND_GET_SINK_INPUT_INFO, /* Payload changed in v11 (0.9.7) */ - PA_COMMAND_GET_SINK_INPUT_INFO_LIST, /* Payload changed in v11 (0.9.7) */ - PA_COMMAND_GET_SOURCE_OUTPUT_INFO, - PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, - PA_COMMAND_GET_SAMPLE_INFO, - PA_COMMAND_GET_SAMPLE_INFO_LIST, - PA_COMMAND_SUBSCRIBE, - PA_COMMAND_SET_SINK_VOLUME, - PA_COMMAND_SET_SINK_INPUT_VOLUME, - PA_COMMAND_SET_SOURCE_VOLUME, - PA_COMMAND_SET_SINK_MUTE, - PA_COMMAND_SET_SOURCE_MUTE, - PA_COMMAND_CORK_PLAYBACK_STREAM, - PA_COMMAND_FLUSH_PLAYBACK_STREAM, - PA_COMMAND_TRIGGER_PLAYBACK_STREAM, - PA_COMMAND_SET_DEFAULT_SINK, - PA_COMMAND_SET_DEFAULT_SOURCE, - PA_COMMAND_SET_PLAYBACK_STREAM_NAME, - PA_COMMAND_SET_RECORD_STREAM_NAME, - PA_COMMAND_KILL_CLIENT, - PA_COMMAND_KILL_SINK_INPUT, - PA_COMMAND_KILL_SOURCE_OUTPUT, - PA_COMMAND_LOAD_MODULE, - PA_COMMAND_UNLOAD_MODULE, - PA_COMMAND_ADD_AUTOLOAD___OBSOLETE, - PA_COMMAND_REMOVE_AUTOLOAD___OBSOLETE, - PA_COMMAND_GET_AUTOLOAD_INFO___OBSOLETE, - PA_COMMAND_GET_AUTOLOAD_INFO_LIST___OBSOLETE, - PA_COMMAND_GET_RECORD_LATENCY, - PA_COMMAND_CORK_RECORD_STREAM, - PA_COMMAND_FLUSH_RECORD_STREAM, - PA_COMMAND_PREBUF_PLAYBACK_STREAM, - PA_COMMAND_REQUEST, - PA_COMMAND_OVERFLOW, - PA_COMMAND_UNDERFLOW, - PA_COMMAND_PLAYBACK_STREAM_KILLED, - PA_COMMAND_RECORD_STREAM_KILLED, - PA_COMMAND_SUBSCRIBE_EVENT, - PA_COMMAND_MOVE_SINK_INPUT, - PA_COMMAND_MOVE_SOURCE_OUTPUT, - PA_COMMAND_SET_SINK_INPUT_MUTE, - PA_COMMAND_SUSPEND_SINK, - PA_COMMAND_SUSPEND_SOURCE, - PA_COMMAND_SET_PLAYBACK_STREAM_BUFFER_ATTR, - PA_COMMAND_SET_RECORD_STREAM_BUFFER_ATTR, - PA_COMMAND_UPDATE_PLAYBACK_STREAM_SAMPLE_RATE, - PA_COMMAND_UPDATE_RECORD_STREAM_SAMPLE_RATE, - PA_COMMAND_PLAYBACK_STREAM_SUSPENDED, - PA_COMMAND_RECORD_STREAM_SUSPENDED, - PA_COMMAND_PLAYBACK_STREAM_MOVED, - PA_COMMAND_RECORD_STREAM_MOVED, - PA_COMMAND_UPDATE_RECORD_STREAM_PROPLIST, - PA_COMMAND_UPDATE_PLAYBACK_STREAM_PROPLIST, - PA_COMMAND_UPDATE_CLIENT_PROPLIST, - PA_COMMAND_REMOVE_RECORD_STREAM_PROPLIST, - PA_COMMAND_REMOVE_PLAYBACK_STREAM_PROPLIST, - PA_COMMAND_REMOVE_CLIENT_PROPLIST, - PA_COMMAND_STARTED, - PA_COMMAND_EXTENSION, - PA_COMMAND_GET_CARD_INFO, - PA_COMMAND_GET_CARD_INFO_LIST, - PA_COMMAND_SET_CARD_PROFILE, - PA_COMMAND_CLIENT_EVENT, - PA_COMMAND_PLAYBACK_STREAM_EVENT, - PA_COMMAND_RECORD_STREAM_EVENT, - PA_COMMAND_PLAYBACK_BUFFER_ATTR_CHANGED, - PA_COMMAND_RECORD_BUFFER_ATTR_CHANGED, - PA_COMMAND_SET_SINK_PORT, - PA_COMMAND_SET_SOURCE_PORT, - PA_COMMAND_MAX -} PA_Commands; - -typedef enum pa_subscription_event_type { - PA_SUBSCRIPTION_EVENT_SINK = 0x0000U, - PA_SUBSCRIPTION_EVENT_SOURCE = 0x0001U, - PA_SUBSCRIPTION_EVENT_SINK_INPUT = 0x0002U, - PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 0x0003U, - PA_SUBSCRIPTION_EVENT_MODULE = 0x0004U, - PA_SUBSCRIPTION_EVENT_CLIENT = 0x0005U, - PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE = 0x0006U, - PA_SUBSCRIPTION_EVENT_SERVER = 0x0007U, - PA_SUBSCRIPTION_EVENT_AUTOLOAD = 0x0008U, - PA_SUBSCRIPTION_EVENT_CARD = 0x0009U, - PA_SUBSCRIPTION_EVENT_FACILITY_MASK = 0x000FU, - PA_SUBSCRIPTION_EVENT_NEW = 0x0000U, - PA_SUBSCRIPTION_EVENT_CHANGE = 0x0010U, - PA_SUBSCRIPTION_EVENT_REMOVE = 0x0020U, - PA_SUBSCRIPTION_EVENT_TYPE_MASK = 0x0030U -} pa_subscription_event_type_t; - -/** Subscription event mask, as used by pa_context_subscribe() */ -typedef enum pa_subscription_mask { - PA_SUBSCRIPTION_MASK_NULL = 0x0000U, - PA_SUBSCRIPTION_MASK_SINK = 0x0001U, - PA_SUBSCRIPTION_MASK_SOURCE = 0x0002U, - PA_SUBSCRIPTION_MASK_SINK_INPUT = 0x0004U, - PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT = 0x0008U, - PA_SUBSCRIPTION_MASK_MODULE = 0x0010U, - PA_SUBSCRIPTION_MASK_CLIENT = 0x0020U, - PA_SUBSCRIPTION_MASK_SAMPLE_CACHE = 0x0040U, - PA_SUBSCRIPTION_MASK_SERVER = 0x0080U, - PA_SUBSCRIPTION_MASK_AUTOLOAD = 0x0100U, - PA_SUBSCRIPTION_MASK_CARD = 0x0200U, - PA_SUBSCRIPTION_MASK_ALL = 0x02ffU -} pa_subscription_mask_t; - -/* The sequence descriptor header consists of 5 32bit integers: */ -typedef enum { - PA_PSTREAM_DESCRIPTOR_LENGTH, - PA_PSTREAM_DESCRIPTOR_CHANNEL, - PA_PSTREAM_DESCRIPTOR_OFFSET_HI, - PA_PSTREAM_DESCRIPTOR_OFFSET_LO, - PA_PSTREAM_DESCRIPTOR_FLAGS, - PA_PSTREAM_DESCRIPTOR_MAX -} PA_Header; - -/* Due to a stupid design flaw, proplists may only be at the END of a - * packet or not before a STRING! Don't forget that! We can't really - * fix this without breaking compat. */ - -typedef enum { - PA_TAG_INVALID = 0, - PA_TAG_STRING = 't', - PA_TAG_STRING_NULL = 'N', - PA_TAG_U32 = 'L', - PA_TAG_U8 = 'B', - PA_TAG_U64 = 'R', - PA_TAG_S64 = 'r', - PA_TAG_SAMPLE_SPEC = 'a', - PA_TAG_ARBITRARY = 'x', - PA_TAG_BOOLEAN_TRUE = '1', - PA_TAG_BOOLEAN_FALSE = '0', - PA_TAG_BOOLEAN = PA_TAG_BOOLEAN_TRUE, - PA_TAG_TIMEVAL = 'T', - PA_TAG_USEC = 'U' /* 64bit unsigned */, - PA_TAG_CHANNEL_MAP = 'm', - PA_TAG_CVOLUME = 'v', - PA_TAG_PROPLIST = 'P', - PA_TAG_VOLUME = 'V' -} PA_Tag; - -typedef enum -{ - PA_TAG_SIZE_INVALID = 0, - PA_TAG_SIZE_STRING = 2, - PA_TAG_SIZE_STRING_NULL = 1, - PA_TAG_SIZE_U32 = 5, - PA_TAG_SIZE_U8 = 'B', - PA_TAG_SIZE_U64 = 'R', - PA_TAG_SIZE_S64 = 'r', - PA_TAG_SIZE_SAMPLE_SPEC = 7, - PA_TAG_SIZE_ARBITRARY = PA_TAG_SIZE_U32, - PA_TAG_SIZE_BOOLEAN = 1, - PA_TAG_SIZE_TIMEVAL = 'T', - PA_TAG_SIZE_USEC = 9 /* 64bit unsigned */, - PA_TAG_SIZE_CHANNEL_MAP = 2, - PA_TAG_SIZE_CVOLUME = 2, - PA_TAG_SIZE_PROPLIST = 1 + PA_TAG_SIZE_STRING_NULL, - PA_TAG_SIZE_VOLUME = 2 -} PA_Tag_Size; - -/** Volume specification: - * PA_VOLUME_MUTED: silence; - * < PA_VOLUME_NORM: decreased volume; - * PA_VOLUME_NORM: normal volume; - * > PA_VOLUME_NORM: increased volume */ -typedef uint32_t pa_volume_t; - -/** Normal volume (100%, 0 dB) */ -#define PA_VOLUME_NORM ((pa_volume_t) 0x10000U) - -/** Muted (minimal valid) volume (0%, -inf dB) */ -#define PA_VOLUME_MUTED ((pa_volume_t) 0U) - -/** Maximum valid volume we can store. \since 0.9.15 */ -#define PA_VOLUME_MAX ((pa_volume_t) UINT32_MAX-1) - -/** Special 'invalid' volume. \since 0.9.16 */ -#define PA_VOLUME_INVALID ((pa_volume_t) UINT32_MAX) -#define PA_CHANNELS_MAX 32U - - -/** Maximum allowed sample rate */ -#define PA_RATE_MAX (48000U*4U) - -/** Sample format */ -typedef enum pa_sample_format { - PA_SAMPLE_U8, - /**< Unsigned 8 Bit PCM */ - - PA_SAMPLE_ALAW, - /**< 8 Bit a-Law */ - - PA_SAMPLE_ULAW, - /**< 8 Bit mu-Law */ - - PA_SAMPLE_S16LE, - /**< Signed 16 Bit PCM, little endian (PC) */ - - PA_SAMPLE_S16BE, - /**< Signed 16 Bit PCM, big endian */ - - PA_SAMPLE_FLOAT32LE, - /**< 32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0 */ - - PA_SAMPLE_FLOAT32BE, - /**< 32 Bit IEEE floating point, big endian, range -1.0 to 1.0 */ - - PA_SAMPLE_S32LE, - /**< Signed 32 Bit PCM, little endian (PC) */ - - PA_SAMPLE_S32BE, - /**< Signed 32 Bit PCM, big endian */ - - PA_SAMPLE_S24LE, - /**< Signed 24 Bit PCM packed, little endian (PC). \since 0.9.15 */ - - PA_SAMPLE_S24BE, - /**< Signed 24 Bit PCM packed, big endian. \since 0.9.15 */ - - PA_SAMPLE_S24_32LE, - /**< Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC). \since 0.9.15 */ - - PA_SAMPLE_S24_32BE, - /**< Signed 24 Bit PCM in LSB of 32 Bit words, big endian. \since 0.9.15 */ - - PA_SAMPLE_MAX, - /**< Upper limit of valid sample types */ - - PA_SAMPLE_INVALID = -1 - /**< An invalid value */ -} pa_sample_format_t; - -/** A list of channel labels */ -typedef enum pa_channel_position { - PA_CHANNEL_POSITION_INVALID = -1, - PA_CHANNEL_POSITION_MONO = 0, - - PA_CHANNEL_POSITION_FRONT_LEFT, /* Apple, Dolby call this 'Left' */ - PA_CHANNEL_POSITION_FRONT_RIGHT, /* Apple, Dolby call this 'Right' */ - PA_CHANNEL_POSITION_FRONT_CENTER, /* Apple, Dolby call this 'Center' */ - -/** \cond fulldocs */ - PA_CHANNEL_POSITION_LEFT = PA_CHANNEL_POSITION_FRONT_LEFT, - PA_CHANNEL_POSITION_RIGHT = PA_CHANNEL_POSITION_FRONT_RIGHT, - PA_CHANNEL_POSITION_CENTER = PA_CHANNEL_POSITION_FRONT_CENTER, -/** \endcond */ - - PA_CHANNEL_POSITION_REAR_CENTER, /* Microsoft calls this 'Back Center', Apple calls this 'Center Surround', Dolby calls this 'Surround Rear Center' */ - PA_CHANNEL_POSITION_REAR_LEFT, /* Microsoft calls this 'Back Left', Apple calls this 'Left Surround' (!), Dolby calls this 'Surround Rear Left' */ - PA_CHANNEL_POSITION_REAR_RIGHT, /* Microsoft calls this 'Back Right', Apple calls this 'Right Surround' (!), Dolby calls this 'Surround Rear Right' */ - - PA_CHANNEL_POSITION_LFE, /* Microsoft calls this 'Low Frequency', Apple calls this 'LFEScreen' */ -/** \cond fulldocs */ - PA_CHANNEL_POSITION_SUBWOOFER = PA_CHANNEL_POSITION_LFE, -/** \endcond */ - - PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, /* Apple, Dolby call this 'Left Center' */ - PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, /* Apple, Dolby call this 'Right Center */ - - PA_CHANNEL_POSITION_SIDE_LEFT, /* Apple calls this 'Left Surround Direct', Dolby calls this 'Surround Left' (!) */ - PA_CHANNEL_POSITION_SIDE_RIGHT, /* Apple calls this 'Right Surround Direct', Dolby calls this 'Surround Right' (!) */ - - PA_CHANNEL_POSITION_AUX0, - PA_CHANNEL_POSITION_AUX1, - PA_CHANNEL_POSITION_AUX2, - PA_CHANNEL_POSITION_AUX3, - PA_CHANNEL_POSITION_AUX4, - PA_CHANNEL_POSITION_AUX5, - PA_CHANNEL_POSITION_AUX6, - PA_CHANNEL_POSITION_AUX7, - PA_CHANNEL_POSITION_AUX8, - PA_CHANNEL_POSITION_AUX9, - PA_CHANNEL_POSITION_AUX10, - PA_CHANNEL_POSITION_AUX11, - PA_CHANNEL_POSITION_AUX12, - PA_CHANNEL_POSITION_AUX13, - PA_CHANNEL_POSITION_AUX14, - PA_CHANNEL_POSITION_AUX15, - PA_CHANNEL_POSITION_AUX16, - PA_CHANNEL_POSITION_AUX17, - PA_CHANNEL_POSITION_AUX18, - PA_CHANNEL_POSITION_AUX19, - PA_CHANNEL_POSITION_AUX20, - PA_CHANNEL_POSITION_AUX21, - PA_CHANNEL_POSITION_AUX22, - PA_CHANNEL_POSITION_AUX23, - PA_CHANNEL_POSITION_AUX24, - PA_CHANNEL_POSITION_AUX25, - PA_CHANNEL_POSITION_AUX26, - PA_CHANNEL_POSITION_AUX27, - PA_CHANNEL_POSITION_AUX28, - PA_CHANNEL_POSITION_AUX29, - PA_CHANNEL_POSITION_AUX30, - PA_CHANNEL_POSITION_AUX31, - - PA_CHANNEL_POSITION_TOP_CENTER, /* Apple calls this 'Top Center Surround' */ - - PA_CHANNEL_POSITION_TOP_FRONT_LEFT, /* Apple calls this 'Vertical Height Left' */ - PA_CHANNEL_POSITION_TOP_FRONT_RIGHT, /* Apple calls this 'Vertical Height Right' */ - PA_CHANNEL_POSITION_TOP_FRONT_CENTER, /* Apple calls this 'Vertical Height Center' */ - - PA_CHANNEL_POSITION_TOP_REAR_LEFT, /* Microsoft and Apple call this 'Top Back Left' */ - PA_CHANNEL_POSITION_TOP_REAR_RIGHT, /* Microsoft and Apple call this 'Top Back Right' */ - PA_CHANNEL_POSITION_TOP_REAR_CENTER, /* Microsoft and Apple call this 'Top Back Center' */ - - PA_CHANNEL_POSITION_MAX -} pa_channel_position_t; - -/** A mask of channel positions. \since 0.9.16 */ -typedef uint64_t pa_channel_position_mask_t; - -/** Makes a bit mask from a channel position. \since 0.9.16 */ -#define PA_CHANNEL_POSITION_MASK(f) ((pa_channel_position_mask_t) (1ULL << (f))) - -/** A list of channel mapping definitions for pa_channel_map_init_auto() */ -typedef enum pa_channel_map_def { - PA_CHANNEL_MAP_AIFF, - /**< The mapping from RFC3551, which is based on AIFF-C */ - -/** \cond fulldocs */ - PA_CHANNEL_MAP_ALSA, - /**< The default mapping used by ALSA. This mapping is probably - * not too useful since ALSA's default channel mapping depends on - * the device string used. */ -/** \endcond */ - - PA_CHANNEL_MAP_AUX, - /**< Only aux channels */ - - PA_CHANNEL_MAP_WAVEEX, - /**< Microsoft's WAVEFORMATEXTENSIBLE mapping. This mapping works - * as if all LSBs of dwChannelMask are set. */ - -/** \cond fulldocs */ - PA_CHANNEL_MAP_OSS, - /**< The default channel mapping used by OSS as defined in the OSS - * 4.0 API specs. This mapping is probably not too useful since - * the OSS API has changed in this respect and no longer knows a - * default channel mapping based on the number of channels. */ -/** \endcond */ - - /**< Upper limit of valid channel mapping definitions */ - PA_CHANNEL_MAP_DEF_MAX, - - PA_CHANNEL_MAP_DEFAULT = PA_CHANNEL_MAP_AIFF - /**< The default channel map */ -} pa_channel_map_def_t; - -typedef struct pa_sample_spec { - pa_sample_format_t format; - /**< The sample format */ - - uint32_t rate; - /**< The sample rate. (e.g. 44100) */ - - uint8_t channels; - /**< Audio channels. (1 for mono, 2 for stereo, ...) */ -} pa_sample_spec; -/** A structure encapsulating a per-channel volume */ -typedef struct pa_cvolume { - uint8_t channels; /**< Number of channels */ - pa_volume_t values[PA_CHANNELS_MAX]; /**< Per-channel volume */ -} pa_cvolume; - -typedef struct pa_channel_map { - uint8_t channels; - /**< Number of channels */ - - pa_channel_position_t map[PA_CHANNELS_MAX]; - /**< Channel labels */ -} pa_channel_map; - -/** Type for usec specifications (unsigned). Always 64 bit. */ -typedef uint64_t pa_usec_t; - -/** Stores information about sinks. Please note that this structure - * can be extended as part of evolutionary API updates at any time in - * any new release. */ -struct Pulse_Sink { - const char *name; /**< Name of the sink */ - uint32_t index; /**< Index of the sink */ - const char *description; /**< Description of this sink */ -// pa_sample_spec sample_spec; /**< Sample spec of this sink */ - pa_channel_map channel_map; /**< Channel map */ -// uint32_t owner_module; /**< Index of the owning module of this sink, or PA_INVALID_INDEX */ - pa_cvolume volume; /**< Volume of the sink */ - Eina_List *ports; /**< output ports */ - const char *active_port; /**< currently active port */ - Eina_Bool mute : 1; /**< Mute switch of the sink */ - Eina_Bool update : 1; - Eina_Bool source : 1; /**< sink is actually a source */ - Eina_Bool deleted : 1; /**< sink has been deleted */ -}; - -typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX]; - -typedef struct -{ - pa_pstream_descriptor header; - uint8_t *data; - - size_t dsize; - size_t size; - size_t pos; - PA_Commands command; - uint32_t tag_count; - Eina_Bool auth : 1; - Eina_Hash *props; -} Pulse_Tag; - -typedef enum -{ - PA_STATE_INIT, - PA_STATE_AUTH, - PA_STATE_MOREAUTH, - PA_STATE_CONNECTED, -} PA_State; - -struct Pulse -{ - PA_State state; - int fd; - Ecore_Fd_Handler *fdh; - Ecore_Con_Server *svr; - Ecore_Event_Handler *con; - const char *socket; - Eina_List *oq; - Eina_List *iq; - Eina_Hash *tag_handlers; - Eina_Hash *tag_cbs; - uint32_t tag_count; - Eina_Bool watching : 1; -}; - -extern int pa_log_dom; - -uint8_t *tag_bool(Pulse_Tag *tag, Eina_Bool val); -uint8_t *untag_bool(Pulse_Tag *tag, Eina_Bool *val); -uint8_t *tag_uint32(Pulse_Tag *tag, uint32_t val); -uint8_t *untag_uint32(Pulse_Tag *tag, uint32_t *val); -uint8_t *tag_string(Pulse_Tag *tag, const char *val); -uint8_t *untag_string(Pulse_Tag *tag, const char **val); -uint8_t *tag_arbitrary(Pulse_Tag *tag, const void *val, uint32_t size); -uint8_t *untag_arbitrary(Pulse_Tag *tag, Eina_Binbuf **val); -uint8_t *untag_sample(Pulse_Tag *tag, pa_sample_spec *spec); -uint8_t *untag_channel_map(Pulse_Tag *tag, pa_channel_map *map); -uint8_t *untag_cvol(Pulse_Tag *tag, pa_cvolume *cvol); -uint8_t *untag_usec(Pulse_Tag *tag, uint64_t *val); -uint8_t *untag_proplist(Pulse_Tag *tag, Eina_Hash **props); -uint8_t *tag_simple_init(Pulse *conn, Pulse_Tag *tag, uint32_t val, PA_Tag type); -uint8_t *tag_proplist(Pulse_Tag *tag); -uint8_t *tag_volume(Pulse_Tag *tag, uint8_t channels, double vol); -uint8_t *tag_cvol(Pulse_Tag *tag, pa_cvolume *c); -void tag_finish(Pulse_Tag *tag); - -Eina_Bool deserialize_tag(Pulse *conn, PA_Commands command, Pulse_Tag *tag); - -void pulse_fake_free(void *d EINA_UNUSED, void *d2 EINA_UNUSED); -void pulse_tag_free(Pulse_Tag *tag); - -void msg_recv_creds(Pulse *conn, Pulse_Tag *tag); -Eina_Bool msg_recv(Pulse *conn, Pulse_Tag *tag); -void msg_sendmsg_creds(Pulse *conn, Pulse_Tag *tag); -void msg_send_creds(Pulse *conn, Pulse_Tag *tag); -Eina_Bool msg_send(Pulse *conn, Pulse_Tag *tag); - -extern Eina_Hash *pulse_sinks; -extern Eina_Hash *pulse_sources; - -#endif diff --git a/src/modules/mixer/serial.c b/src/modules/mixer/serial.c deleted file mode 100644 index 20c04548d..000000000 --- a/src/modules/mixer/serial.c +++ /dev/null @@ -1,184 +0,0 @@ -#include "pa.h" - -static Pulse_Server_Info * -deserialize_server_info(Pulse *conn, Pulse_Tag *tag) -{ - Pulse_Server_Info *ev; - pa_sample_spec spec; - - ev = calloc(1, sizeof(Pulse_Server_Info)); - ev->conn = conn; - EINA_SAFETY_ON_NULL_RETURN_VAL(ev, NULL); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &ev->name), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &ev->version), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &ev->username), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &ev->hostname), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_sample(tag, &spec), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &ev->default_sink), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &ev->default_source), error); - - return ev; -error: - pulse_server_info_free(ev); - return NULL; -} - -static void -deserialize_sinks_watcher(Pulse *conn, Pulse_Tag *tag) -{ - pa_subscription_event_type_t e; - uint32_t idx; - - EINA_SAFETY_ON_FALSE_RETURN(untag_uint32(tag, &e)); - EINA_SAFETY_ON_FALSE_RETURN(untag_uint32(tag, &idx)); - - if (e & PA_SUBSCRIPTION_EVENT_CHANGE) - { - Pulse_Sink *sink; - - sink = eina_hash_find(pulse_sinks, &idx); - if (sink) - { - if (pulse_sink_get(conn, idx)) - sink->update = EINA_TRUE; - } - else - { - sink = eina_hash_find(pulse_sources, &idx); - if (!sink) return; - if (pulse_source_get(conn, idx)) - sink->update = EINA_TRUE; - } - } -} - -static Pulse_Sink * -deserialize_sink(Pulse *conn EINA_UNUSED, Pulse_Tag *tag, Eina_Bool source) -{ - Pulse_Sink *sink = NULL; - Eina_Bool mute, exist; - pa_sample_spec spec; - uint32_t owner_module, monitor_source, flags, base_volume, state, n_volume_steps, card, n_ports; - uint64_t latency, configured_latency; - const char *monitor_source_name, *driver; - Eina_Hash *props = NULL; - unsigned int x; - Pulse_Sink_Port_Info *pi = NULL; - - monitor_source_name = driver = NULL; - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &x), error); - if (source && pulse_sources) - sink = eina_hash_find(pulse_sources, &x); - else if ((!source) && pulse_sinks) - sink = eina_hash_find(pulse_sinks, &x); - exist = !!sink; - if (!sink) sink = calloc(1, sizeof(Pulse_Sink)); - sink->index = x; - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &sink->name), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &sink->description), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_sample(tag, &spec), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_channel_map(tag, &sink->channel_map), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &owner_module), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_cvol(tag, &sink->volume), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_bool(tag, &mute), error); - sink->mute = !!mute; - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &monitor_source), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &monitor_source_name), error); - eina_stringshare_del(monitor_source_name); - EINA_SAFETY_ON_FALSE_GOTO(untag_usec(tag, &latency), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &driver), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &flags), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_proplist(tag, &props), error); - eina_hash_free(props); - EINA_SAFETY_ON_FALSE_GOTO(untag_usec(tag, &configured_latency), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &base_volume), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &state), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &n_volume_steps), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &card), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &n_ports), error); - - for (x = 0; x < n_ports; x++) - { - pi = calloc(1, sizeof(Pulse_Sink_Port_Info)); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &pi->name), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &pi->description), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_uint32(tag, &pi->priority), error); - sink->ports = eina_list_append(sink->ports, pi); - pi = NULL; - } - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &sink->active_port), error); - if (exist) - ecore_event_add(PULSE_EVENT_CHANGE, sink, pulse_fake_free, NULL); - else - { - if (source && (!pulse_sources)) - pulse_sources = eina_hash_int32_new((Eina_Free_Cb)pulse_sink_free); - else if ((!source) && (!pulse_sinks)) - pulse_sinks = eina_hash_int32_new((Eina_Free_Cb)pulse_sink_free); - eina_hash_add(source ? pulse_sources : pulse_sinks, (uintptr_t*)&sink->index, sink); - } - return sink; -error: - if (pi) - { - if (pi->name) eina_stringshare_del(pi->name); - if (pi->description) eina_stringshare_del(pi->description); - free(pi); - pi = NULL; - } - pulse_sink_free(sink); - eina_hash_free(props); - return NULL; -} - -Eina_Bool -deserialize_tag(Pulse *conn, PA_Commands command, Pulse_Tag *tag) -{ - Pulse_Cb cb; - void *ev = (!command) ? NULL : PULSE_SUCCESS; - - cb = eina_hash_find(conn->tag_cbs, &tag->tag_count); - if (command == PA_COMMAND_SUBSCRIBE) - conn->watching = EINA_TRUE; - switch (command) - { - case PA_COMMAND_GET_SERVER_INFO: - if (!cb) return EINA_TRUE; - ev = NULL; - ev = deserialize_server_info(conn, tag); - break; - case PA_COMMAND_GET_SINK_INFO_LIST: - case PA_COMMAND_GET_SOURCE_INFO_LIST: - if (!cb) return EINA_TRUE; - ev = NULL; - while (tag->size < tag->dsize - PA_TAG_SIZE_STRING_NULL) - { - Pulse_Sink *sink; - - sink = deserialize_sink(conn, tag, (command == PA_COMMAND_GET_SOURCE_INFO_LIST)); - if (!sink) - { - EINA_LIST_FREE(ev, sink) - pulse_sink_free(sink); - break; - } - if (cb) ev = eina_list_append(ev, sink); - } - break; - case PA_COMMAND_GET_SINK_INFO: - case PA_COMMAND_GET_SOURCE_INFO: - if ((!cb) && (!conn->watching)) return EINA_TRUE; - ev = deserialize_sink(conn, tag, (command == PA_COMMAND_GET_SOURCE_INFO)); - break; - case 0: - deserialize_sinks_watcher(conn, tag); - return EINA_TRUE; - default: - break; - } - if (!cb) return EINA_TRUE; - eina_hash_del_by_key(conn->tag_cbs, &tag->tag_count); - cb(conn, tag->tag_count, ev); - - return EINA_TRUE; -} diff --git a/src/modules/mixer/sink.c b/src/modules/mixer/sink.c deleted file mode 100644 index c5134ca3f..000000000 --- a/src/modules/mixer/sink.c +++ /dev/null @@ -1,357 +0,0 @@ -#include "pa.h" - - -/** Makes a bit mask from a channel position. \since 0.9.16 */ -#define PA_CHANNEL_POSITION_MASK(f) ((pa_channel_position_mask_t) (1ULL << (f))) - - -#define PA_CHANNEL_POSITION_MASK_LEFT \ - (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_LEFT)) \ - -#define PA_CHANNEL_POSITION_MASK_RIGHT \ - (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_RIGHT)) - -#define PA_CHANNEL_POSITION_MASK_CENTER \ - (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_CENTER)) - -#define PA_CHANNEL_POSITION_MASK_FRONT \ - (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_CENTER)) - -#define PA_CHANNEL_POSITION_MASK_REAR \ - (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_REAR_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_CENTER)) - -#define PA_CHANNEL_POSITION_MASK_SIDE_OR_TOP_CENTER \ - (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_SIDE_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_CENTER)) - -#define PA_CHANNEL_POSITION_MASK_TOP \ - (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_FRONT_CENTER) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_LEFT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_RIGHT) \ - | PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_TOP_REAR_CENTER)) - -#define PA_CHANNEL_POSITION_MASK_ALL \ - ((pa_channel_position_mask_t) (PA_CHANNEL_POSITION_MASK(PA_CHANNEL_POSITION_MAX)-1)) - -const char *const channel_name_table[PA_CHANNEL_POSITION_MAX] = { - [PA_CHANNEL_POSITION_MONO] = _("Mono"), - - [PA_CHANNEL_POSITION_FRONT_CENTER] = _("Front Center"), - [PA_CHANNEL_POSITION_FRONT_LEFT] = _("Front Left"), - [PA_CHANNEL_POSITION_FRONT_RIGHT] = _("Front Right"), - - [PA_CHANNEL_POSITION_REAR_CENTER] = _("Rear Center"), - [PA_CHANNEL_POSITION_REAR_LEFT] = _("Rear Left"), - [PA_CHANNEL_POSITION_REAR_RIGHT] = _("Rear Right"), - - [PA_CHANNEL_POSITION_LFE] = _("Subwoofer"), - - [PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER] = _("Front Left-of-center"), - [PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER] = _("Front Right-of-center"), - - [PA_CHANNEL_POSITION_SIDE_LEFT] = _("Side Left"), - [PA_CHANNEL_POSITION_SIDE_RIGHT] = _("Side Right"), - - [PA_CHANNEL_POSITION_AUX0] = _("Auxiliary 0"), - [PA_CHANNEL_POSITION_AUX1] = _("Auxiliary 1"), - [PA_CHANNEL_POSITION_AUX2] = _("Auxiliary 2"), - [PA_CHANNEL_POSITION_AUX3] = _("Auxiliary 3"), - [PA_CHANNEL_POSITION_AUX4] = _("Auxiliary 4"), - [PA_CHANNEL_POSITION_AUX5] = _("Auxiliary 5"), - [PA_CHANNEL_POSITION_AUX6] = _("Auxiliary 6"), - [PA_CHANNEL_POSITION_AUX7] = _("Auxiliary 7"), - [PA_CHANNEL_POSITION_AUX8] = _("Auxiliary 8"), - [PA_CHANNEL_POSITION_AUX9] = _("Auxiliary 9"), - [PA_CHANNEL_POSITION_AUX10] = _("Auxiliary 10"), - [PA_CHANNEL_POSITION_AUX11] = _("Auxiliary 11"), - [PA_CHANNEL_POSITION_AUX12] = _("Auxiliary 12"), - [PA_CHANNEL_POSITION_AUX13] = _("Auxiliary 13"), - [PA_CHANNEL_POSITION_AUX14] = _("Auxiliary 14"), - [PA_CHANNEL_POSITION_AUX15] = _("Auxiliary 15"), - [PA_CHANNEL_POSITION_AUX16] = _("Auxiliary 16"), - [PA_CHANNEL_POSITION_AUX17] = _("Auxiliary 17"), - [PA_CHANNEL_POSITION_AUX18] = _("Auxiliary 18"), - [PA_CHANNEL_POSITION_AUX19] = _("Auxiliary 19"), - [PA_CHANNEL_POSITION_AUX20] = _("Auxiliary 20"), - [PA_CHANNEL_POSITION_AUX21] = _("Auxiliary 21"), - [PA_CHANNEL_POSITION_AUX22] = _("Auxiliary 22"), - [PA_CHANNEL_POSITION_AUX23] = _("Auxiliary 23"), - [PA_CHANNEL_POSITION_AUX24] = _("Auxiliary 24"), - [PA_CHANNEL_POSITION_AUX25] = _("Auxiliary 25"), - [PA_CHANNEL_POSITION_AUX26] = _("Auxiliary 26"), - [PA_CHANNEL_POSITION_AUX27] = _("Auxiliary 27"), - [PA_CHANNEL_POSITION_AUX28] = _("Auxiliary 28"), - [PA_CHANNEL_POSITION_AUX29] = _("Auxiliary 29"), - [PA_CHANNEL_POSITION_AUX30] = _("Auxiliary 30"), - [PA_CHANNEL_POSITION_AUX31] = _("Auxiliary 31"), - - [PA_CHANNEL_POSITION_TOP_CENTER] = _("Top Center"), - - [PA_CHANNEL_POSITION_TOP_FRONT_CENTER] = _("Top Front Center"), - [PA_CHANNEL_POSITION_TOP_FRONT_LEFT] = _("Top Front Left"), - [PA_CHANNEL_POSITION_TOP_FRONT_RIGHT] = _("Top Front Right"), - - [PA_CHANNEL_POSITION_TOP_REAR_CENTER] = _("Top Rear Center"), - [PA_CHANNEL_POSITION_TOP_REAR_LEFT] = _("Top Rear Left"), - [PA_CHANNEL_POSITION_TOP_REAR_RIGHT] = _("Top Rear Right") -}; - -static Eina_Bool on_left(pa_channel_position_t p) { - return !!(PA_CHANNEL_POSITION_MASK(p) & PA_CHANNEL_POSITION_MASK_LEFT); -} - -static Eina_Bool on_right(pa_channel_position_t p) { - return !!(PA_CHANNEL_POSITION_MASK(p) & PA_CHANNEL_POSITION_MASK_RIGHT); -} -#if 0 -static Eina_Bool on_center(pa_channel_position_t p) { - return !!(PA_CHANNEL_POSITION_MASK(p) & PA_CHANNEL_POSITION_MASK_CENTER); -} - -static Eina_Bool on_lfe(pa_channel_position_t p) { - return p == PA_CHANNEL_POSITION_LFE; -} -#endif -static Eina_Bool on_front(pa_channel_position_t p) { - return !!(PA_CHANNEL_POSITION_MASK(p) & PA_CHANNEL_POSITION_MASK_FRONT); -} - -static Eina_Bool on_rear(pa_channel_position_t p) { - return !!(PA_CHANNEL_POSITION_MASK(p) & PA_CHANNEL_POSITION_MASK_REAR); -} - -static void -pulse_sink_port_info_free(Pulse_Sink_Port_Info *pi) -{ - if (!pi) return; - eina_stringshare_del(pi->name); - eina_stringshare_del(pi->description); - free(pi); -} - -void -pulse_sink_free(Pulse_Sink *sink) -{ - Pulse_Sink_Port_Info *pi; - if (!sink) return; - if (!sink->deleted) - { - sink->deleted = EINA_TRUE; - if (sink->source) - { - eina_hash_del_by_key(pulse_sources, (uintptr_t*)&sink->index); - return; - } - else - { - eina_hash_del_by_key(pulse_sinks, (uintptr_t*)&sink->index); - return; - } - } - eina_stringshare_del(sink->name); - eina_stringshare_del(sink->description); - EINA_LIST_FREE(sink->ports, pi) - pulse_sink_port_info_free(pi); - eina_stringshare_del(sink->active_port); - free(sink); -} - -const Eina_List * -pulse_sink_ports_get(Pulse_Sink *sink) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL); - return sink->ports; -} - -const char * -pulse_sink_port_active_get(Pulse_Sink *sink) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL); - return sink->active_port; -} - -const char * -pulse_sink_name_get(Pulse_Sink *sink) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL); - - return sink->name; -} - -const char * -pulse_sink_desc_get(Pulse_Sink *sink) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL); - - return sink->description; -} - -uint32_t -pulse_sink_idx_get(Pulse_Sink *sink) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, 0); - - return sink->index; -} - -Eina_Bool -pulse_sink_muted_get(Pulse_Sink *sink) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, EINA_FALSE); - - return sink->mute; -} - -uint8_t -pulse_sink_channels_count(Pulse_Sink *sink) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, 0); - - return sink->volume.channels; -} - -double -pulse_sink_avg_get_pct(Pulse_Sink *sink) -{ - double avg; - int x; - - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, -1.0); - - for (avg = 0, x = 0; x < sink->volume.channels; x++) - avg += sink->volume.values[x]; - avg /= sink->volume.channels; - - if (avg <= PA_VOLUME_MUTED) return 0.0; - - if (avg == PA_VOLUME_NORM) return 100.0; - - return (avg * 100 + PA_VOLUME_NORM / 2) / PA_VOLUME_NORM; -} - -Eina_List * -pulse_sink_channel_names_get(Pulse_Sink *sink) -{ - Eina_List *ret = NULL; - unsigned int x; - - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL); - for (x = 0; x < sink->volume.channels; x++) - ret = eina_list_append(ret, pulse_sink_channel_id_get_name(sink, x)); - return ret; -} - -unsigned int -pulse_sink_channel_name_get_id(Pulse_Sink *sink, const char *name) -{ - unsigned int x; - - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, UINT_MAX); - EINA_SAFETY_ON_NULL_RETURN_VAL(name, UINT_MAX); - for (x = 0; x < sink->channel_map.channels; x++) - { - if (!strcmp(name, channel_name_table[sink->channel_map.map[x]])) - return x; - } - return UINT_MAX; -} - -const char * -pulse_sink_channel_id_get_name(Pulse_Sink *sink, unsigned int id) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, NULL); - EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, NULL); - return eina_stringshare_add(channel_name_table[sink->channel_map.map[id]]); -} - -double -pulse_sink_channel_volume_get(Pulse_Sink *sink, unsigned int id) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, -1); - EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, -1); - return (sink->volume.values[id] * 100 + PA_VOLUME_NORM / 2) / PA_VOLUME_NORM; -} - -float -pulse_sink_channel_balance_get(Pulse_Sink *sink, unsigned int id) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, -1.0); - EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, -1.0); - - if (on_left(sink->channel_map.map[id])) return 0.0; - if (on_right(sink->channel_map.map[id])) return 1.0; - return 0.5; -} - -float -pulse_sink_channel_depth_get(Pulse_Sink *sink, unsigned int id) -{ - EINA_SAFETY_ON_NULL_RETURN_VAL(sink, -1.0); - EINA_SAFETY_ON_TRUE_RETURN_VAL(id >= sink->channel_map.channels, -1.0); - - if (on_rear(sink->channel_map.map[id])) return 0.0; - if (on_front(sink->channel_map.map[id])) return 1.0; - return 0.5; -} - -float -pulse_sink_balance_get(Pulse_Sink *sink) -{ - int c; - float l, r; - pa_volume_t left = 0, right = 0; - unsigned n_left = 0, n_right = 0; - - for (c = 0; c < sink->channel_map.channels; c++) { - if (on_left(sink->channel_map.map[c])) { - left += sink->volume.values[c]; - n_left++; - } else if (on_right(sink->channel_map.map[c])) { - right += sink->volume.values[c]; - n_right++; - } - } - - if (n_left <= 0) - l = PA_VOLUME_NORM; - else - l = left / n_left; - - if (n_right <= 0) - r = PA_VOLUME_NORM; - else - r = right / n_right; - l /= (float)PA_VOLUME_NORM; - r /= (float)PA_VOLUME_NORM; - return r - l; -} diff --git a/src/modules/mixer/sys_alsa.c b/src/modules/mixer/sys_alsa.c deleted file mode 100644 index 7afc75f8f..000000000 --- a/src/modules/mixer/sys_alsa.c +++ /dev/null @@ -1,625 +0,0 @@ -#include "e_mod_mixer.h" -#include -#include - -struct e_mixer_callback_desc -{ - int (*func)(void *data, - E_Mixer_System *self); - void *data; - E_Mixer_System *self; - Ecore_Idler *idler; - Eina_List *handlers; -}; - -static int _mixer_callback_add(const E_Mixer_System *self, - int (*func)(void *data, E_Mixer_System *self), - void *data); -static int _mixer_callback_del(const E_Mixer_System *self, - struct e_mixer_callback_desc *desc); - -static Eina_Bool -_cb_dispatch(void *data) -{ - struct e_mixer_callback_desc *desc; - int r; - - desc = data; - snd_mixer_handle_events(desc->self); - r = desc->func(desc->data, desc->self); - desc->idler = NULL; - - if (!r) - _mixer_callback_del(desc->self, desc); /* desc is invalid then. */ - - return ECORE_CALLBACK_CANCEL; -} - -static Eina_Bool -_cb_fd_handler(void *data, - Ecore_Fd_Handler *fd_handler) -{ - struct e_mixer_callback_desc *desc; - - desc = data; - - if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR)) - { - desc->handlers = eina_list_remove(desc->handlers, fd_handler); - if (!desc->handlers) - { - E_Mixer_System *s; - int (*f)(void *, - E_Mixer_System *); - void *d; - - s = desc->self; - f = desc->func; - d = desc->data; - _mixer_callback_del(s, desc); - _mixer_callback_add(s, f, d); - } - return ECORE_CALLBACK_CANCEL; - } - - if (!desc->idler) - desc->idler = ecore_idler_add(_cb_dispatch, desc); - return ECORE_CALLBACK_RENEW; -} - -static int -_mixer_callback_add(const E_Mixer_System *self, - int (*func)(void *data, E_Mixer_System *self), - void *data) -{ - struct e_mixer_callback_desc *desc; - struct pollfd *pfds; - int len; - - len = snd_mixer_poll_descriptors_count((snd_mixer_t *)self); - if (len <= 0) - return 0; - - desc = malloc(sizeof(struct e_mixer_callback_desc)); - if (!desc) - return 0; - - desc->func = func; - desc->data = data; - desc->self = (E_Mixer_System *)self; - desc->idler = NULL; - desc->handlers = NULL; - - pfds = alloca(len * sizeof(struct pollfd)); - len = snd_mixer_poll_descriptors((snd_mixer_t *)self, pfds, len); - if (len <= 0) - { - free(desc); - return 0; - } - - while (len > 0) - { - Ecore_Fd_Handler *fd_handler; - - len--; - fd_handler = ecore_main_fd_handler_add( - pfds[len].fd, ECORE_FD_READ, _cb_fd_handler, desc, NULL, NULL); - desc->handlers = eina_list_prepend(desc->handlers, fd_handler); - } - - snd_mixer_set_callback_private((snd_mixer_t *)self, desc); - - return 1; -} - -static int -_mixer_callback_del(const E_Mixer_System *self, - struct e_mixer_callback_desc *desc) -{ - Ecore_Fd_Handler *handler; - - EINA_LIST_FREE(desc->handlers, handler) - ecore_main_fd_handler_del(handler); - - snd_mixer_set_callback_private((snd_mixer_t *)self, NULL); - - memset(desc, 0, sizeof(*desc)); - free(desc); - - return 1; -} - -static int -_mixer_callback_replace(const E_Mixer_System *self EINA_UNUSED, - struct e_mixer_callback_desc *desc, - int (*func)(void *data, E_Mixer_System *self), - void *data) -{ - desc->func = func; - desc->data = data; - - return 1; -} - -E_Mixer_System * -e_mixer_system_new(const char *name) -{ - snd_mixer_t *handle; - int err; - - if (!name) - return NULL; - - err = snd_mixer_open(&handle, 0); - if (err < 0) - goto error_open; - - err = snd_mixer_attach(handle, name); - if (err < 0) - goto error_load; - - err = snd_mixer_selem_register(handle, NULL, NULL); - if (err < 0) - goto error_load; - - err = snd_mixer_load(handle); - if (err < 0) - goto error_load; - - return handle; - -error_load: - snd_mixer_close(handle); -error_open: - fprintf(stderr, "MIXER: Cannot get hardware info: %s\n", snd_strerror(err)); - return NULL; -} - -void -e_mixer_system_del(E_Mixer_System *self) -{ - struct e_mixer_callback_desc *desc; - - if (!self) - return; - - desc = snd_mixer_get_callback_private(self); - if (desc) - _mixer_callback_del(self, desc); - - snd_mixer_close(self); -} - -int -e_mixer_system_callback_set(const E_Mixer_System *self, - int (*func)(void *data, E_Mixer_System *self), - void *data) -{ - struct e_mixer_callback_desc *desc; - - if (!self) - return 0; - - desc = snd_mixer_get_callback_private(self); - if (!desc) - { - if (func) - return _mixer_callback_add(self, func, data); - return 1; - } - else - { - if (func) - return _mixer_callback_replace(self, desc, func, data); - else - return _mixer_callback_del(self, desc); - } -} - -Eina_List * -e_mixer_system_get_cards(void) -{ - int err, card_num; - Eina_List *cards; - - cards = NULL; - card_num = -1; - while (((err = snd_card_next(&card_num)) == 0) && (card_num >= 0)) - { - snd_ctl_t *control; - char buf[256]; - - snprintf(buf, sizeof(buf), "hw:%d", card_num); - - if (snd_ctl_open(&control, buf, 0) < 0) - break; - snd_ctl_close(control); - cards = eina_list_append(cards, eina_stringshare_add(buf)); - } - - if (err < 0) - fprintf(stderr, "MIXER: Cannot get available card number: %s\n", - snd_strerror(err)); - - return cards; -} - -const char * -e_mixer_system_get_default_card(void) -{ - static const char buf[] = "hw:0"; - snd_ctl_t *control; - - if (snd_ctl_open(&control, buf, 0) < 0) - return NULL; - snd_ctl_close(control); - return eina_stringshare_add(buf); -} - -const char * -e_mixer_system_get_card_name(const char *card) -{ - snd_ctl_card_info_t *hw_info; - const char *name; - snd_ctl_t *control; - int err; - - if (!card) - return NULL; - - snd_ctl_card_info_alloca(&hw_info); - - err = snd_ctl_open(&control, card, 0); - if (err < 0) - return NULL; - - err = snd_ctl_card_info(control, hw_info); - if (err < 0) - { - fprintf(stderr, "MIXER: Cannot get hardware info: %s: %s\n", card, - snd_strerror(err)); - snd_ctl_close(control); - return NULL; - } - - snd_ctl_close(control); - name = snd_ctl_card_info_get_name(hw_info); - if (!name) - { - fprintf(stderr, "MIXER: Cannot get hardware name: %s\n", card); - return NULL; - } - - return eina_stringshare_add(name); -} - -static int -_mixer_channel_has_capabilities(snd_mixer_elem_t *elem) -{ - if (!snd_mixer_selem_is_active(elem)) return 0; - if (snd_mixer_selem_has_playback_volume(elem)) return 1; - if (snd_mixer_selem_has_capture_volume(elem)) return 1; - if (snd_mixer_selem_has_playback_switch(elem)) return 1; - if (snd_mixer_selem_has_capture_switch(elem)) return 1; - - return 0; -} - -static int -_mixer_channel_capabilities(snd_mixer_elem_t *elem) -{ - int capabilities = 0; - - /* - * never vol_joined if not mono - * -> mono is enough - * never switch_joined if not switch - * -> switch is enough - * never common_vol if not (playback_vol && capture vol) - * -> palyback_vol & capture_vol is enough - */ - if (!snd_mixer_selem_is_active(elem)) - return 0; - - if (snd_mixer_selem_has_capture_volume(elem)) - capabilities |= E_MIXER_CHANNEL_HAS_CAPTURE; - if (snd_mixer_selem_has_playback_volume(elem)) - capabilities |= E_MIXER_CHANNEL_HAS_PLAYBACK; - if (snd_mixer_selem_has_playback_switch(elem) || - snd_mixer_selem_has_capture_switch(elem)) - capabilities |= E_MIXER_CHANNEL_CAN_MUTE; - if (snd_mixer_selem_is_playback_mono(elem)==1 || - snd_mixer_selem_is_capture_mono(elem)==1) - capabilities |= E_MIXER_CHANNEL_IS_MONO; - - return capabilities; -} - -Eina_List * -e_mixer_system_get_channels(const E_Mixer_System *self) -{ - int capabilities; - Eina_List *channels; - snd_mixer_elem_t *elem; - E_Mixer_Channel_Info *ch_info; - - if (!self) - return NULL; - - channels = NULL; - - elem = snd_mixer_first_elem((snd_mixer_t *)self); - for (; elem; elem = snd_mixer_elem_next(elem)) - { - capabilities = _mixer_channel_capabilities(elem); - if (!e_mod_mixer_capabilities_usable(capabilities)) - continue; - - ch_info = malloc(sizeof(*ch_info)); - ch_info->id = elem; - ch_info->name = eina_stringshare_add(snd_mixer_selem_get_name(elem)); - ch_info->capabilities = capabilities; - - channels = eina_list_append(channels, ch_info); - } - - return channels; -} - -Eina_List * -e_mixer_system_get_channel_names(const E_Mixer_System *self) -{ - Eina_List *channels; - snd_mixer_elem_t *elem; - snd_mixer_selem_id_t *sid; - - if (!self) - return NULL; - - channels = NULL; - snd_mixer_selem_id_alloca(&sid); - - elem = snd_mixer_first_elem((snd_mixer_t *)self); - for (; elem; elem = snd_mixer_elem_next(elem)) - { - const char *name; - if (!_mixer_channel_has_capabilities(elem)) - continue; - - snd_mixer_selem_get_id(elem, sid); - name = snd_mixer_selem_id_get_name(sid); - if (name) - channels = eina_list_append(channels, eina_stringshare_add(name)); - } - - return channels; -} - -const char * -e_mixer_system_get_default_channel_name(const E_Mixer_System *self) -{ - snd_mixer_elem_t *elem; - snd_mixer_selem_id_t *sid; - - if (!self) - return NULL; - - snd_mixer_selem_id_alloca(&sid); - - elem = snd_mixer_first_elem((snd_mixer_t *)self); - for (; elem; elem = snd_mixer_elem_next(elem)) - { - const char *name; - if (!_mixer_channel_has_capabilities(elem)) - continue; - - snd_mixer_selem_get_id(elem, sid); - name = snd_mixer_selem_id_get_name(sid); - if (name) - return eina_stringshare_add(name); - } - - return NULL; -} - -E_Mixer_Channel_Info * -e_mixer_system_get_channel_by_name(const E_Mixer_System *self, - const char *name) -{ - int capabilities; - snd_mixer_elem_t *elem; - snd_mixer_selem_id_t *sid; - E_Mixer_Channel_Info *ch_info; - - if ((!self) || (!name)) - return NULL; - - snd_mixer_selem_id_alloca(&sid); - - elem = snd_mixer_first_elem((snd_mixer_t *)self); - for (; elem; elem = snd_mixer_elem_next(elem)) - { - const char *n; - capabilities = _mixer_channel_capabilities(elem); - if (!e_mod_mixer_capabilities_usable(capabilities)) - continue; - - snd_mixer_selem_get_id(elem, sid); - n = snd_mixer_selem_id_get_name(sid); - if (n && (strcmp(n, name) == 0)) - { - ch_info = malloc(sizeof(*ch_info)); - ch_info->id = elem; - ch_info->name = eina_stringshare_add(n); - ch_info->capabilities = capabilities; - - return ch_info; - } - } - - return NULL; -} - -int -e_mixer_system_get_volume(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, - int *left, - int *right) -{ - long lvol, rvol, range, min, max; - - if ((!self) || (!channel) || (!channel->id) || (!left) || (!right)) - return 0; - - snd_mixer_handle_events((snd_mixer_t *)self); - if (e_mod_mixer_channel_has_playback(channel)) - snd_mixer_selem_get_playback_volume_range(channel->id, &min, &max); - else if (e_mod_mixer_channel_has_capture(channel)) - snd_mixer_selem_get_capture_volume_range(channel->id, &min, &max); - else - return 0; - - range = max - min; - if (range < 1) - return 0; - - if (e_mod_mixer_channel_has_playback(channel)) - { - snd_mixer_selem_get_playback_volume(channel->id, 0, &lvol); - if (!e_mod_mixer_channel_is_mono(channel)) - snd_mixer_selem_get_playback_volume(channel->id, 1, &rvol); - else - rvol = lvol; - } - else - { - snd_mixer_selem_get_capture_volume(channel->id, 0, &lvol); - if (!e_mod_mixer_channel_is_mono(channel)) - snd_mixer_selem_get_capture_volume(channel->id, 1, &rvol); - else - rvol = lvol; - } - - *left = rint((double)(lvol - min) * 100 / (double)range); - *right = rint((double)(rvol - min) * 100 / (double)range); - - return 1; -} - -int -e_mixer_system_set_volume(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, - int left, - int right) -{ - long range, min, max, divide; - int mode; - - if ((!self) || (!channel) || (!channel->id)) - return 0; - - snd_mixer_handle_events((snd_mixer_t *)self); - snd_mixer_selem_get_playback_volume_range(channel->id, &min, &max); - divide = 100 + min; - if (divide == 0) - { - divide = 1; /* no zero-division */ - min++; - } - - range = max - min; - if (range < 1) - return 0; - - mode = 0; - if (left >= 0) - { - left = (((range * left) + (range / 2)) / divide) - min; - mode |= 1; - } - - if (!e_mod_mixer_channel_is_mono(channel) && (right >= 0)) - { - right = (((range * right) + (range / 2)) / divide) - min; - mode |= 2; - } - - if (mode & 1) - { - if (e_mod_mixer_channel_has_playback(channel)) - snd_mixer_selem_set_playback_volume(channel->id, 0, left); - else - snd_mixer_selem_set_capture_volume(channel->id, 0, left); - } - if (mode & 2) - { - if (e_mod_mixer_channel_has_playback(channel)) - snd_mixer_selem_set_playback_volume(channel->id, 1, right); - else - snd_mixer_selem_set_capture_volume(channel->id, 1, right); - } - - return 1; -} - -int -e_mixer_system_get_mute(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, - int *mute) -{ - if ((!self) || (!channel) || (!channel->id) || (!mute)) - return 0; - - snd_mixer_handle_events((snd_mixer_t *)self); - - if (e_mod_mixer_channel_is_mutable(channel)) - { - int m; - - /* XXX: not checking for return, always returns 0 even if it worked. - * alsamixer also don't check it. Bug? - */ - if (e_mod_mixer_channel_has_capture(channel)) - snd_mixer_selem_get_capture_switch(channel->id, 0, &m); - else - snd_mixer_selem_get_playback_switch(channel->id, 0, &m); - *mute = !m; - } - else - *mute = 0; - - return 1; -} - -int -e_mixer_system_set_mute(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, - int mute) -{ - if ((!self) || (!channel) || (!channel->id)) - return 0; - - if (!e_mod_mixer_channel_is_mutable(channel)) - return 0; - - if (e_mod_mixer_channel_has_capture(channel)) - return snd_mixer_selem_set_capture_switch_all(channel->id, !mute); - else - return snd_mixer_selem_set_playback_switch_all(channel->id, !mute); -} - -int -e_mixer_system_get_state(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, - E_Mixer_Channel_State *state) -{ - int r; - - if (!state) - return 0; - - r = e_mixer_system_get_mute(self, channel, &state->mute); - r &= e_mixer_system_get_volume(self, channel, &state->left, &state->right); - return r; -} diff --git a/src/modules/mixer/sys_dummy.c b/src/modules/mixer/sys_dummy.c deleted file mode 100644 index 9d9f50914..000000000 --- a/src/modules/mixer/sys_dummy.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "e_mod_mixer.h" - -static const char *_name = NULL; - -static void -_e_mixer_dummy_set(void) -{ - if (!_name) _name = eina_stringshare_add("No ALSA mixer found!"); -} - -E_Mixer_System * -e_mixer_system_new(const char *name) -{ - _e_mixer_dummy_set(); - - if (!name) return NULL; - - if (name == _name || strcmp(name, _name) == 0) - return (E_Mixer_System *)-1; - else - return NULL; -} - -void -e_mixer_system_del(E_Mixer_System *self EINA_UNUSED) -{ -} - -int -e_mixer_system_callback_set(const E_Mixer_System *self EINA_UNUSED, int (*func)(void *data, E_Mixer_System *self) EINA_UNUSED, void *data EINA_UNUSED) -{ - return 0; -} - -Eina_List * -e_mixer_system_get_cards(void) -{ - _e_mixer_dummy_set(); - - return eina_list_append(NULL, eina_stringshare_ref(_name)); -} - -const char * -e_mixer_system_get_default_card(void) -{ - _e_mixer_dummy_set(); - - return eina_stringshare_ref(_name); -} - -const char * -e_mixer_system_get_card_name(const char *card) -{ - _e_mixer_dummy_set(); - - if (card == _name || strcmp(card, _name) == 0) - return eina_stringshare_ref(_name); - else - return NULL; -} - -Eina_List * -e_mixer_system_get_channels(const E_Mixer_System *self EINA_UNUSED) -{ - E_Mixer_Channel_Info *ch_info; - - _e_mixer_dummy_set(); - - ch_info = malloc(sizeof(*ch_info)); - ch_info->id = (void*)-2; - ch_info->name = eina_stringshare_ref(_name); - ch_info->capabilities = E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; - - return eina_list_append(NULL, ch_info); -} - -Eina_List * -e_mixer_system_get_channel_names(const E_Mixer_System *self EINA_UNUSED) -{ - _e_mixer_dummy_set(); - - return eina_list_append(NULL, eina_stringshare_ref(_name)); -} - -const char * -e_mixer_system_get_default_channel_name(const E_Mixer_System *self EINA_UNUSED) -{ - _e_mixer_dummy_set(); - - return eina_stringshare_ref(_name); -} - -E_Mixer_Channel_Info * -e_mixer_system_get_channel_by_name(const E_Mixer_System *self EINA_UNUSED, const char *name) -{ - E_Mixer_Channel_Info *ch_info; - - _e_mixer_dummy_set(); - - if (name == _name || strcmp(name, _name) == 0) - { - ch_info = malloc(sizeof(*ch_info)); - ch_info->id = (void*)-2; - ch_info->name = eina_stringshare_ref(_name); - ch_info->capabilities = E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; - - return ch_info; - } - else - return NULL; -} - -int -e_mixer_system_get_volume(const E_Mixer_System *self EINA_UNUSED, - const E_Mixer_Channel_Info *channel EINA_UNUSED, - int *left, int *right) -{ - if (left) - *left = 0; - if (right) - *right = 0; - - return 1; -} - -int -e_mixer_system_set_volume(const E_Mixer_System *self EINA_UNUSED, - const E_Mixer_Channel_Info *channel EINA_UNUSED, - int left EINA_UNUSED, int right EINA_UNUSED) -{ - return 0; -} - -int -e_mixer_system_get_mute(const E_Mixer_System *self EINA_UNUSED, - const E_Mixer_Channel_Info *channel EINA_UNUSED, - int *mute) -{ - if (mute) - *mute = 1; - - return 1; -} - -int -e_mixer_system_set_mute(const E_Mixer_System *self EINA_UNUSED, - const E_Mixer_Channel_Info *channel EINA_UNUSED, - int mute EINA_UNUSED) -{ - return 0; -} - -int -e_mixer_system_get_state(const E_Mixer_System *self EINA_UNUSED, - const E_Mixer_Channel_Info *channel EINA_UNUSED, - E_Mixer_Channel_State *state) -{ - const E_Mixer_Channel_State def = {1, 0, 0}; - - if (state) - *state = def; - - return 1; -} diff --git a/src/modules/mixer/sys_pulse.c b/src/modules/mixer/sys_pulse.c deleted file mode 100644 index 61e1adee3..000000000 --- a/src/modules/mixer/sys_pulse.c +++ /dev/null @@ -1,550 +0,0 @@ -#include "e_mod_main.h" -#include "e_mod_mixer.h" -#include "Pulse.h" - -static Ecore_Exe *pulse_inst = NULL; -static Eina_Bool pa_started = EINA_FALSE; - -static Pulse *conn = NULL; -static Pulse_Server_Info *info = NULL; -static Pulse_Sink *default_sink = NULL; -static Eina_List *handlers = NULL; -static Eina_List *sinks = NULL; -static Eina_List *sources = NULL; -static Eina_Hash *queue_states = NULL; -static const char *_name = NULL; - -static Ecore_Timer *disc_timer = NULL; - -static unsigned int disc_count = 0; -static unsigned int update_count = 0; -static Ecore_Timer *update_timer = NULL; - -static Eina_Bool -_pulse_start(void *d EINA_UNUSED) -{ - update_timer = NULL; - e_mixer_pulse_init(); - return EINA_FALSE; -} - -static Eina_Bool -_pulse_started(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Exe_Event_Add *ev) -{ - if (ev->exe != pulse_inst) return ECORE_CALLBACK_RENEW; - if (!update_timer) - update_timer = ecore_timer_add(2.0, _pulse_start, NULL); - pa_started = EINA_TRUE; - pulse_inst = NULL; - E_FREE_LIST(handlers, ecore_event_handler_del); - return ECORE_CALLBACK_DONE; -} - -static Eina_Bool -_pulse_not_started(void *data EINA_UNUSED, int type EINA_UNUSED, Ecore_Exe_Event_Del *ev) -{ - if (ev->exe != pulse_inst) return ECORE_CALLBACK_RENEW; - if (!pa_started) - { - E_FREE_LIST(handlers, ecore_event_handler_del); - e_mod_mixer_pulse_ready(EINA_FALSE); - } - return ECORE_CALLBACK_DONE; -} - -static void -_pulse_info_get(Pulse *d EINA_UNUSED, int type EINA_UNUSED, Pulse_Server_Info *ev) -{ - Eina_List *l; - Pulse_Sink *sink; - - pulse_server_info_free(info); - info = ev; - EINA_LIST_FOREACH(sinks, l, sink) - if (ev->default_sink == pulse_sink_name_get(sink)) - { - if (default_sink == sink) return; - default_sink = sink; - if (!_mixer_using_default) e_mod_mixer_pulse_update(); - break; - } - e_mod_mixer_pulse_ready(EINA_TRUE); -} - -static Eina_Bool -_pulse_update_timer(void *d EINA_UNUSED) -{ - e_mod_mixer_pulse_update(); - update_timer = NULL; - return EINA_FALSE; -} - -static Eina_Bool -_pulse_update(Pulse *d EINA_UNUSED, int type EINA_UNUSED, Pulse_Sink *ev EINA_UNUSED) -{ - Pulse_Tag_Id id; - - id = pulse_server_info_get(conn); - if (id) - pulse_cb_set(conn, id, (Pulse_Cb)_pulse_info_get); - if (update_timer) ecore_timer_reset(update_timer); - else update_timer = ecore_timer_add(0.2, _pulse_update_timer, NULL); - return EINA_TRUE; -} - -static void -_pulse_sinks_get(Pulse *p EINA_UNUSED, Pulse_Tag_Id id EINA_UNUSED, Eina_List *ev) -{ - Eina_List *l; - Pulse_Sink *sink; - - E_FREE_LIST(sinks, pulse_sink_free); - - EINA_LIST_FOREACH(ev, l, sink) - { -/* - printf("Sink:\n"); - printf("\tname: %s\n", pulse_sink_name_get(sink)); - printf("\tidx: %"PRIu32"\n", pulse_sink_idx_get(sink)); - printf("\tdesc: %s\n", pulse_sink_desc_get(sink)); - printf("\tchannels: %u\n", pulse_sink_channels_count(sink)); - printf("\tmuted: %s\n", pulse_sink_muted_get(sink) ? "yes" : "no"); - printf("\tavg: %g\n", pulse_sink_avg_get_pct(sink)); - printf("\tbalance: %f\n", pulse_sink_balance_get(sink)); -*/ - if (info && (!default_sink)) - { - if (info->default_sink == pulse_sink_name_get(sink)) - { - default_sink = sink; - break; - } - } - } - - sinks = ev; - pulse_sinks_watch(conn); - if (default_sink) e_mod_mixer_pulse_ready(EINA_TRUE); -} - -static void -_pulse_sources_get(Pulse *p EINA_UNUSED, Pulse_Tag_Id id EINA_UNUSED, Eina_List *ev) -{ - eina_list_free(sources); - sources = ev; -/* - Eina_List *l; - Pulse_Sink *sink; - sources = ev; - - EINA_LIST_FOREACH(ev, l, sink) - { - printf("Sources:\n"); - printf("\tname: %s\n", pulse_sink_name_get(sink)); - printf("\tidx: %"PRIu32"\n", pulse_sink_idx_get(sink)); - printf("\tdesc: %s\n", pulse_sink_desc_get(sink)); - printf("\tchannels: %u\n", pulse_sink_channels_count(sink)); - printf("\tmuted: %s\n", pulse_sink_muted_get(sink) ? "yes" : "no"); - printf("\tavg: %g\n", pulse_sink_avg_get_pct(sink)); - printf("\tbalance: %f\n", pulse_sink_balance_get(sink)); - } - */ -} - -static Eina_Bool -_pulse_connected(Pulse *d, int type EINA_UNUSED, Pulse *ev) -{ - Pulse_Tag_Id id; - if (d != ev) return ECORE_CALLBACK_PASS_ON; - id = pulse_sinks_get(conn); - if (!id) - { - e_mixer_pulse_shutdown(); - e_mixer_default_setup(); - return ECORE_CALLBACK_RENEW; - } - if (!queue_states) - queue_states = eina_hash_stringshared_new(free); - pulse_cb_set(conn, id, (Pulse_Cb)_pulse_sinks_get); - id = pulse_sources_get(conn); - if (id) - pulse_cb_set(conn, id, (Pulse_Cb)_pulse_sources_get); - id = pulse_server_info_get(conn); - if (id) - pulse_cb_set(conn, id, (Pulse_Cb)_pulse_info_get); - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_pulse_disc_timer(void *d EINA_UNUSED) -{ - disc_timer = NULL; - if (disc_count < 5) - { - if (pulse_connect(conn)) return EINA_FALSE; - } - e_mod_mixer_pulse_ready(EINA_FALSE); - e_mixer_pulse_shutdown(); - e_mixer_pulse_init(); - disc_count = 0; - return EINA_FALSE; -} - -static Eina_Bool -_pulse_disconnected(Pulse *d, int type EINA_UNUSED, Pulse *ev) -{ - Pulse_Sink *sink; - - if (d != ev) return ECORE_CALLBACK_PASS_ON; - - EINA_LIST_FREE(sinks, sink) - pulse_sink_free(sink); - EINA_LIST_FREE(sources, sink) - pulse_sink_free(sink); - pulse_server_info_free(info); - if (queue_states) eina_hash_free(queue_states); - queue_states = NULL; - info = NULL; - default_sink = NULL; - if (update_timer) ecore_timer_del(update_timer); - update_timer = NULL; - -// printf("PULSEAUDIO: disconnected at %g\n", ecore_time_unix_get()); - - disc_count++; - if (disc_timer) return ECORE_CALLBACK_RENEW; - disc_timer = ecore_timer_add(1.5, _pulse_disc_timer, NULL); - return ECORE_CALLBACK_RENEW; -} - -static void -_pulse_state_queue(Pulse_Sink *sink, int left, int right, int mute) -{ - E_Mixer_Channel_State *state = NULL; - - if (queue_states) - state = eina_hash_find(queue_states, pulse_sink_name_get(sink)); - else - queue_states = eina_hash_stringshared_new(free); - if (!state) - { - state = E_NEW(E_Mixer_Channel_State, 1); - eina_hash_direct_add(queue_states, pulse_sink_name_get(sink), state); - state->left = state->right = state->mute = -1; - } - if (left >= 0) - state->left = left; - if (right >= 0) - state->right = right; - if (mute >= 0) - state->mute = mute; -} - -static Pulse_Sink * -_pulse_sink_find(const char *name) -{ - Eina_List *l; - Pulse_Sink *sink; - EINA_LIST_FOREACH(sinks, l, sink) - { - const char *sink_name; - - sink_name = pulse_sink_name_get(sink); - if ((sink_name == name) || (!e_util_strcmp(sink_name, name))) - return sink; - } - EINA_LIST_FOREACH(sources, l, sink) - { - const char *sink_name; - - sink_name = pulse_sink_name_get(sink); - if ((sink_name == name) || (!e_util_strcmp(sink_name, name))) - return sink; - } - return NULL; -} - -static Eina_Bool -_pulse_queue_process(const Eina_Hash *h EINA_UNUSED, const char *key, - E_Mixer_Channel_State *state, void *d EINA_UNUSED) -{ - Eina_List *l, *list[2] = {sinks, sources}; - E_Mixer_Channel_Info ch; - void *s; - int x; - - if ((state->mute == -1) && (state->left == -1) && (state->right == -1)) return EINA_TRUE; - ch.id = (void*)1; - for (x = 0; x < 2; x++) - EINA_LIST_FOREACH(list[x], l, s) - { - if (key != pulse_sink_name_get(s)) continue; - if ((state->left >= 0) || (state->right >= 0)) - e_mixer_pulse_set_volume(s, &ch, state->left, state->right); - if (state->mute >= 0) - e_mixer_pulse_set_mute(s, &ch, state->mute); - state->left = state->right = state->mute = -1; - return EINA_FALSE; - } - return EINA_TRUE; -} - -static void -_pulse_result_cb(Pulse *p EINA_UNUSED, Pulse_Tag_Id id, void *ev) -{ - if (!ev) fprintf(stderr, "Command %u failed!\n", id); - if (!update_count) return; - if (--update_count) return; - if (!queue_states) return; - eina_hash_foreach(queue_states, (Eina_Hash_Foreach)_pulse_queue_process, NULL); -} - -Eina_Bool -e_mixer_pulse_ready(void) -{ - return !!sinks; -} - -Eina_Bool -e_mixer_pulse_init(void) -{ - pulse_init(); - conn = pulse_new(); - if ((!conn) || (!pulse_connect(conn))) - { - pulse_free(conn); - conn = NULL; - pulse_shutdown(); - - if (pa_started) - { - e_mod_mixer_pulse_ready(EINA_FALSE); - return EINA_FALSE; - } - - pulse_inst = ecore_exe_run("start-pulseaudio-x11", NULL); - if (!pulse_inst) return EINA_FALSE; - - E_LIST_HANDLER_APPEND(handlers, ECORE_EXE_EVENT_ADD, (Ecore_Event_Handler_Cb)_pulse_started, NULL); - E_LIST_HANDLER_APPEND(handlers, ECORE_EXE_EVENT_DEL, (Ecore_Event_Handler_Cb)_pulse_not_started, NULL); - - return EINA_TRUE; - } - E_LIST_HANDLER_APPEND(handlers, PULSE_EVENT_CONNECTED, (Ecore_Event_Handler_Cb)_pulse_connected, conn); - E_LIST_HANDLER_APPEND(handlers, PULSE_EVENT_CHANGE, (Ecore_Event_Handler_Cb)_pulse_update, conn); - E_LIST_HANDLER_APPEND(handlers, PULSE_EVENT_DISCONNECTED, (Ecore_Event_Handler_Cb)_pulse_disconnected, conn); - if (!_name) _name = eina_stringshare_add("Output"); - return EINA_TRUE; -} - -void -e_mixer_pulse_shutdown(void) -{ - Pulse_Sink *sink; - EINA_LIST_FREE(sinks, sink) - pulse_sink_free(sink); - EINA_LIST_FREE(sources, sink) - pulse_sink_free(sink); - pulse_server_info_free(info); - info = NULL; - default_sink = NULL; - update_count = 0; - if (update_timer) ecore_timer_del(update_timer); - update_timer = NULL; - - pulse_free(conn); - conn = NULL; - E_FREE_LIST(handlers, ecore_event_handler_del); - if (queue_states) eina_hash_free(queue_states); - queue_states = NULL; - pulse_shutdown(); - if (_name) eina_stringshare_del(_name); - _name = NULL; -} - -E_Mixer_System * -e_mixer_pulse_new(const char *name) -{ - return (E_Mixer_System *)_pulse_sink_find(name); -} - -void -e_mixer_pulse_del(E_Mixer_System *self EINA_UNUSED) -{ -} - -Eina_List * -e_mixer_pulse_get_cards(void) -{ - Eina_List *l, *ret = NULL; - Pulse_Sink *sink; - - EINA_LIST_FOREACH(sinks, l, sink) - ret = eina_list_append(ret, eina_stringshare_ref(pulse_sink_name_get(sink))); - EINA_LIST_FOREACH(sources, l, sink) - ret = eina_list_append(ret, eina_stringshare_ref(pulse_sink_name_get(sink))); - return ret; -} - -const char * -e_mixer_pulse_get_default_card(void) -{ - if (default_sink) - return eina_stringshare_ref(pulse_sink_name_get(default_sink)); - return NULL; -} - -const char * -e_mixer_pulse_get_card_name(const char *card) -{ - Pulse_Sink *sink; - const char *s; - - sink = _pulse_sink_find(card); - s = pulse_sink_desc_get(sink); - if ((!s) || (!s[0])) s = pulse_sink_name_get(sink); - return eina_stringshare_ref(s); -} - -Eina_List * -e_mixer_pulse_get_channels(const E_Mixer_System *self EINA_UNUSED) -{ - E_Mixer_Channel_Info *ch_info; - - ch_info = malloc(sizeof(*ch_info)); - ch_info->id = (void*)1; - ch_info->name = eina_stringshare_ref(_name); - ch_info->capabilities= E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; - - return eina_list_append(NULL, ch_info); -} - -Eina_List * -e_mixer_pulse_get_channel_names(const E_Mixer_System *self EINA_UNUSED) -{ - return eina_list_append(NULL, eina_stringshare_ref(_name)); -} - -const char * -e_mixer_pulse_get_default_channel_name(const E_Mixer_System *self EINA_UNUSED) -{ - return eina_stringshare_ref(_name); -} - -E_Mixer_Channel_Info * -e_mixer_pulse_get_channel_by_name(const E_Mixer_System *self EINA_UNUSED, - const char *name EINA_UNUSED) -{ - E_Mixer_Channel_Info *ch_info; - - ch_info = malloc(sizeof(*ch_info)); - ch_info->id = (void*)1; - ch_info->name = eina_stringshare_ref(_name); - ch_info->capabilities= E_MIXER_CHANNEL_CAN_MUTE|E_MIXER_CHANNEL_HAS_PLAYBACK; - - return ch_info; -} - -int -e_mixer_pulse_get_volume(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, int *left, int *right) -{ - double volume; - int x, n; - - if (!channel) return 0; - n = pulse_sink_channels_count((void *)self); - for (x = 0; x < n; x++) - { - volume = pulse_sink_channel_volume_get((void *)self, - ((uintptr_t)x)); - if (x == 0) - { - if (left) *left = (int)volume; - } - else if (x == 1) - { - if (right) *right = (int)volume; - } - } - return 1; -} - -int -e_mixer_pulse_set_volume(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, int left, int right) -{ - uint32_t id = 0; - int x, n; - - if (!channel) return 0; - if (update_count > 1) - { - _pulse_state_queue((void*)self, left, right, -1); - return 1; - } - n = pulse_sink_channels_count((void *)self); - for (x = 0; x < n; x++, id = 0) - { - double vol; - - vol = lround(pulse_sink_channel_volume_get((void *)self, x)); - if (x == 0) - { - if (vol != left) - id = pulse_sink_channel_volume_set(conn, (void *)self, x, left); - } - else if (x == 1) - { - if (vol != right) - id = pulse_sink_channel_volume_set(conn, (void *)self, x, right); - } - if (id) - { - pulse_cb_set(conn, id, (Pulse_Cb)_pulse_result_cb); - update_count++; - } - } - return 1; -} - -int -e_mixer_pulse_get_mute(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel EINA_UNUSED, int *mute) -{ - if (mute) *mute = pulse_sink_muted_get((void *)self); - return 1; -} - -int -e_mixer_pulse_set_mute(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel EINA_UNUSED, int mute) -{ - uint32_t id; - Eina_Bool source = EINA_FALSE; - - if (update_count > 2) - { - _pulse_state_queue((void*)self, -1, -1, mute); - return 1; - } - source = !!eina_list_data_find(sources, self); - id = pulse_type_mute_set(conn, pulse_sink_idx_get((void *)self), mute, source); - if (!id) return 0; - update_count++; - pulse_cb_set(conn, id, (Pulse_Cb)_pulse_result_cb); - return 1; -} - -int -e_mixer_pulse_get_state(const E_Mixer_System *self, - const E_Mixer_Channel_Info *channel, - E_Mixer_Channel_State *state) -{ - if (!state) return 0; - if (!channel) return 0; - e_mixer_pulse_get_mute(self, channel, &(state->mute)); - e_mixer_pulse_get_volume(self, channel, &(state->left), &(state->right)); - return 1; -} - diff --git a/src/modules/mixer/tag.c b/src/modules/mixer/tag.c deleted file mode 100644 index 5bd424025..000000000 --- a/src/modules/mixer/tag.c +++ /dev/null @@ -1,326 +0,0 @@ -#include "pa.h" - -uint8_t * -tag_uint32(Pulse_Tag *tag, uint32_t val) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - *ret = PA_TAG_U32; - val = htonl(val); - memcpy(ret + 1, &val, sizeof(val)); - ret += PA_TAG_SIZE_U32; - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -untag_uint32(Pulse_Tag *tag, uint32_t *val) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - if ((*ret != PA_TAG_U32) && (*ret != PA_TAG_VOLUME)) return 0; - memcpy(val, ret + 1, sizeof(uint32_t)); - *val = ntohl(*val); - ret += PA_TAG_SIZE_U32; - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -tag_bool(Pulse_Tag *tag, Eina_Bool val) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - *ret = (uint8_t)(val ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE); - ret += PA_TAG_SIZE_BOOLEAN; - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -untag_bool(Pulse_Tag *tag, Eina_Bool *val) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - if ((*ret != PA_TAG_BOOLEAN_TRUE) && (*ret != PA_TAG_BOOLEAN_FALSE)) return 0; - *val = !!(*ret == PA_TAG_BOOLEAN_TRUE) ? EINA_TRUE : EINA_FALSE; - ret += PA_TAG_SIZE_BOOLEAN; - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -tag_string(Pulse_Tag *tag, const char *val) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - if (val) - { - *ret = PA_TAG_STRING; - strcpy((char*)ret + 1, val); - ret += PA_TAG_SIZE_STRING + strlen(val); - tag->size = ret - tag->data; - } - else - *ret = PA_TAG_STRING_NULL, tag->size++; - return ret; -} - -uint8_t * -untag_string(Pulse_Tag *tag, const char **val) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - switch (*ret) - { - case PA_TAG_STRING: - eina_stringshare_replace(val, (char*)ret + 1); - ret += PA_TAG_SIZE_STRING + strlen(*val); - break; - case PA_TAG_STRING_NULL: - *val = NULL; - ret += PA_TAG_SIZE_STRING_NULL; - break; - default: - return 0; - } - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -untag_sample(Pulse_Tag *tag, pa_sample_spec *spec) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - if (*ret != PA_TAG_SAMPLE_SPEC) return 0; - - spec->format = ret[1]; - spec->channels = ret[2]; - memcpy(&spec->rate, ret + 3, sizeof(spec->rate)); - spec->rate = ntohl(spec->rate); - ret += PA_TAG_SIZE_SAMPLE_SPEC, tag->size += PA_TAG_SIZE_SAMPLE_SPEC; - return ret; -} - -uint8_t * -untag_channel_map(Pulse_Tag *tag, pa_channel_map *map) -{ - uint8_t *ret; - unsigned int x; - - ret = tag->data + tag->size; - if (*ret != PA_TAG_CHANNEL_MAP) return 0; - - map->channels = ret[1]; - if (map->channels > PA_CHANNELS_MAX) return 0; - if (map->channels + 2 + tag->size > tag->dsize) return 0; - - for (ret += 2, x = 0; x < map->channels; ret++, x++) - map->map[x] = (int8_t)*ret; - - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -untag_usec(Pulse_Tag *tag, uint64_t *val) -{ - uint8_t *ret; - uint32_t tmp; - - ret = tag->data + tag->size; - if (*ret != PA_TAG_USEC) return 0; - - memcpy(&tmp, ret + 1, 4); - *val = (uint64_t)ntohl(tmp) << 32; - memcpy(&tmp, ret + 5, 4); - *val |= (uint64_t)ntohl(tmp); - ret += PA_TAG_SIZE_USEC; - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -tag_arbitrary(Pulse_Tag *tag, const void *val, uint32_t size) -{ - uint8_t *ret; - uint32_t tmp; - - ret = tag->data + tag->size; - *ret = PA_TAG_ARBITRARY; - tmp = htonl(size); - memcpy(ret + 1, &tmp, sizeof(uint32_t)); - memcpy(ret + PA_TAG_SIZE_U32, val, size); - ret += PA_TAG_SIZE_ARBITRARY + size; - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -untag_arbitrary(Pulse_Tag *tag, Eina_Binbuf **val) -{ - uint8_t *ret; - uint32_t len; - - if (!untag_uint32(tag, &len)) return 0; - ret = tag->data + tag->size; - if (*ret != PA_TAG_ARBITRARY) return 0; - ret += PA_TAG_SIZE_ARBITRARY; - - *val = eina_binbuf_new(); - eina_binbuf_append_length(*val, ret, len); - ret += len; - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -tag_simple_init(Pulse *conn, Pulse_Tag *tag, uint32_t val, PA_Tag type) -{ - switch (type) - { - case PA_TAG_U32: - tag_uint32(tag, val); - return tag_uint32(tag, conn->tag_count++); - default: - break; - } - return NULL; -} - -static Eina_Bool -tag_proplist_foreach(const Eina_Hash *h EINA_UNUSED, const char *key, const char *val, Pulse_Tag *tag) -{ - size_t size; - - tag_string(tag, key); - size = strlen(val) + 1; - tag_uint32(tag, size); - tag_arbitrary(tag, val, size); - return EINA_TRUE; -} - -uint8_t * -tag_proplist(Pulse_Tag *tag) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - *ret = PA_TAG_PROPLIST, tag->size++; - - eina_hash_foreach(tag->props, (Eina_Hash_Foreach)tag_proplist_foreach, tag); - return tag_string(tag, NULL); -} - -uint8_t * -untag_proplist(Pulse_Tag *tag, Eina_Hash **props) -{ - uint8_t *ret; - - ret = tag->data + tag->size; - if (*ret != PA_TAG_PROPLIST) return 0; - - *props = eina_hash_string_superfast_new((Eina_Free_Cb)eina_binbuf_free); - for (++tag->size; *ret != PA_TAG_STRING_NULL && tag->size < tag->dsize - 1;) - { - const char *key = NULL; - Eina_Binbuf *val; - EINA_SAFETY_ON_FALSE_GOTO(untag_string(tag, &key), error); - EINA_SAFETY_ON_FALSE_GOTO(untag_arbitrary(tag, &val), error); -#if 0 - { - char buf[128]; - snprintf(buf, sizeof(buf), "key='%%s', val='%%.%zus'", eina_binbuf_length_get(val)); - DBG(buf, key, eina_binbuf_string_get(val)); - } -#endif - eina_hash_add(*props, key, val); - eina_stringshare_del(key); - ret = tag->data + tag->size; - } - tag->size++; - return ++ret; -error: - eina_hash_free(*props); - return 0; -} - -uint8_t * -tag_volume(Pulse_Tag *tag, uint8_t channels, double vol) -{ - uint32_t pa_vol; - uint8_t *ret, x; - - if (vol <= 0.0) pa_vol = PA_VOLUME_MUTED; - else pa_vol = ((vol * PA_VOLUME_NORM) - (PA_VOLUME_NORM / 2)) / 100; - pa_vol = htonl(pa_vol); - ret = tag->data + tag->size; - *ret++ = PA_TAG_CVOLUME; - *ret++ = channels; - for (x = 0; x < channels; x++, ret += sizeof(pa_vol)) - memcpy(ret, &pa_vol, sizeof(pa_vol)); - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -tag_cvol(Pulse_Tag *tag, pa_cvolume *c) -{ - uint8_t *ret, x; - uint32_t pa_vol; - - ret = tag->data + tag->size; - *ret++ = PA_TAG_CVOLUME; - *ret++ = c->channels; - for (x = 0; x < c->channels; x++, ret += sizeof(pa_vol)) - { - pa_vol = htonl(c->values[x]); - memcpy(ret, &pa_vol, sizeof(pa_vol)); - } - tag->size = ret - tag->data; - return ret; -} - -uint8_t * -untag_cvol(Pulse_Tag *tag, pa_cvolume *cvol) -{ - uint32_t pa_vol; - uint8_t *ret, x; - - ret = tag->data + tag->size; - if (*ret != PA_TAG_CVOLUME) return 0; - cvol->channels = ret[1]; - for (x = 0, ret += 2; x < cvol->channels; x++, ret += sizeof(pa_vol)) - { - memcpy(&pa_vol, ret, sizeof(pa_vol)); - cvol->values[x] = ntohl(pa_vol); - } - - tag->size = ret - tag->data; - return ret; -} - -void -tag_finish(Pulse_Tag *tag) -{ - EINA_SAFETY_ON_NULL_RETURN(tag); - tag->header[PA_PSTREAM_DESCRIPTOR_CHANNEL] = htonl((uint32_t) -1); - tag->header[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(tag->dsize); -} - -void -pulse_tag_free(Pulse_Tag *tag) -{ - if (!tag) return; - free(tag->data); - if (tag->props) eina_hash_free(tag->props); - free(tag); -}