static gboolean poll_session_bus_address_file (gpointer userdata) { (void) userdata; gchar *address = NULL; if (g_file_test (SESSION_BUS_ADDRESS_FILENAME, G_FILE_TEST_EXISTS)) { N_DEBUG (LOG_CAT "session bus address file exists."); if ((address = load_session_bus_address (SESSION_BUS_ADDRESS_FILENAME)) != NULL) { stop_file_polling (); session_new_bus (address); g_free (address); setup_file_watcher (); return FALSE; } } return TRUE; }
int n_context_subscribe_value_change (NContext *context, const char *key, NContextValueChangeFunc callback, void *userdata) { NContextSubscriber *subscriber = NULL; if (!context || !callback) return FALSE; subscriber = g_slice_new0 (NContextSubscriber); subscriber->key = g_strdup (key); subscriber->callback = callback; subscriber->userdata = userdata; context->subscribers = g_list_append (context->subscribers, subscriber); N_DEBUG (LOG_CAT "subscriber added for key '%s'", key ? key : "<all keys>"); return TRUE; }
static NPlugin* n_core_load_plugin (NCore *core, const char *plugin_name) { g_assert (core != NULL); g_assert (plugin_name != NULL); NPlugin *plugin = NULL; gchar *filename = NULL; gchar *full_path = NULL; filename = g_strdup_printf ("libngfd_%s.so", plugin_name); full_path = g_build_filename (core->plugin_path, filename, NULL); if (!(plugin = n_plugin_load (full_path))) goto done; plugin->core = core; plugin->params = n_core_load_params (core, plugin_name); if (!plugin->load (plugin)) goto done; N_DEBUG (LOG_CAT "loaded plugin '%s'", plugin_name); g_free (full_path); g_free (filename); return plugin; done: N_ERROR (LOG_CAT "unable to load plugin '%s'", plugin_name); if (plugin) n_plugin_unload (plugin); g_free (full_path); g_free (filename); return NULL; }
static int canberra_sink_prepare (NSinkInterface *iface, NRequest *request) { N_DEBUG (LOG_CAT "sink prepare"); CanberraData *data = g_slice_new0 (CanberraData); NProplist *props = props = (NProplist*) n_request_get_properties (request); data->request = request; data->iface = iface; data->filename = n_proplist_get_string (props, SOUND_FILENAME_KEY); data->sound_enabled = TRUE; data->complete_cb_id = 0; n_request_store_data (request, CANBERRA_KEY, data); n_sink_interface_synchronize (iface, request); if (n_proplist_has_key (props, SOUND_VOLUME_KEY)) data->sound_enabled = n_proplist_get_int (props, SOUND_VOLUME_KEY) > 0; return TRUE; }
static void process_queued_ops () { QueueItem *queued_volume = NULL; while ((queued_volume = g_queue_pop_head (volume_queue)) != NULL) { N_DEBUG (LOG_CAT "processing queued volume for role '%s', volume %d ", queued_volume->role, queued_volume->volume); add_entry (queued_volume->role, queued_volume->volume); g_free (queued_volume->role); g_slice_free (QueueItem, queued_volume); } // listen for objects here if (queue_subscribe) { listen_for_signal (NEW_ENTRY_SIGNAL, NULL); listen_for_signal (ENTRY_REMOVED_SIGNAL, NULL); update_object_map_listen (); queue_subscribe = FALSE; } }
void n_core_register_input (NCore *core, const NInputInterfaceDecl *iface) { NInputInterface *input = NULL; g_assert (core != NULL); g_assert (iface->name != NULL); input = g_new0 (NInputInterface, 1); input->name = iface->name; input->core = core; input->funcs = *iface; core->num_inputs++; core->inputs = (NInputInterface**) g_realloc (core->inputs, sizeof (NInputInterface*) * (core->num_inputs + 1)); core->inputs[core->num_inputs-1] = input; core->inputs[core->num_inputs] = NULL; N_DEBUG (LOG_CAT "input interface '%s' registered", input->name); }
void n_core_register_sink (NCore *core, const NSinkInterfaceDecl *iface) { g_assert (core != NULL); g_assert (iface->name != NULL); g_assert (iface->play != NULL); g_assert (iface->stop != NULL); NSinkInterface *sink = NULL; sink = g_new0 (NSinkInterface, 1); sink->name = iface->name; sink->core = core; sink->funcs = *iface; core->num_sinks++; core->sinks = (NSinkInterface**) g_realloc (core->sinks, sizeof (NSinkInterface*) * (core->num_sinks + 1)); core->sinks[core->num_sinks-1] = sink; core->sinks[core->num_sinks] = NULL; N_DEBUG (LOG_CAT "sink interface '%s' registered", sink->name); }
/* * Create a Hash table of effects from a string of semicolon separated keys. * Values of keys will be initialized to -1. */ static GHashTable *ffm_new_effect_list(const char *effect_data) { GHashTable *list = NULL; gchar **effect_names; int i = 0; struct ffm_effect_data *data; if (!effect_data) { N_WARNING (LOG_CAT "NULL effect_data pointer"); return NULL; } N_DEBUG (LOG_CAT "creating effect list for %s", effect_data); effect_names = g_strsplit((const gchar*) effect_data, ";", 0); if (!effect_names[0]) { N_WARNING (LOG_CAT "Empty effect_data string"); goto ffm_effect_list_done; } list = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); for (i = 0; effect_names[i] != NULL; i++) { /* Add effect key to effect list with initial data */ data = g_new(struct ffm_effect_data, 1); data->id = -1; data->repeat = 1; g_hash_table_insert(list, strdup(effect_names[i]), data); } ffm_effect_list_done: g_strfreev(effect_names); return list; }
static void canberra_sink_shutdown (NSinkInterface *iface) { (void) iface; N_DEBUG (LOG_CAT "sink shutdown"); }
static int canberra_sink_play (NSinkInterface *iface, NRequest *request) { CanberraData *data = (CanberraData*) n_request_get_data (request, CANBERRA_KEY); (void) iface; N_DEBUG (LOG_CAT "sink play"); g_assert (data != NULL); if (!data->sound_enabled) goto complete; if (canberra_connect () == FALSE) return FALSE; static GHashTable *cached_samples = NULL; if (!cached_samples) { cached_samples = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } NProplist *props = props = (NProplist*) n_request_get_properties (request); ca_proplist *ca_props = 0; int error; ca_proplist_create (&ca_props); /* TODO: don't hardcode */ ca_proplist_sets (ca_props, CA_PROP_CANBERRA_XDG_THEME_NAME, "jolla-ambient"); ca_proplist_sets (ca_props, CA_PROP_EVENT_ID, data->filename); /* convert all properties within the request that begin with "sound.stream." prefix. */ n_proplist_foreach (props, proplist_to_structure_cb, ca_props); if (g_hash_table_lookup_extended (cached_samples, data->filename, NULL, NULL) == FALSE) { N_DEBUG (LOG_CAT "caching sample %s", data->filename); error = ca_context_cache_full (c_context, ca_props); if (error) { N_WARNING (LOG_CAT "canberra couldn't cache sample %s", data->filename); return FALSE; } g_hash_table_add (cached_samples, strdup(data->filename)); } else { N_DEBUG (LOG_CAT "sample %s is cached", data->filename); } error = ca_context_play_full (c_context, 0, ca_props, NULL, NULL); ca_proplist_destroy (ca_props); if (error) { N_WARNING (LOG_CAT "sink play had a warning: %s", ca_strerror (error)); if (error == CA_ERROR_NOTAVAILABLE || error == CA_ERROR_DISCONNECTED || error == CA_ERROR_STATE || error == CA_ERROR_DESTROYED) { ca_context_destroy (c_context); c_context = 0; } return FALSE; } complete: /* We do not know how long our samples play, but let's guess we * are done in 200ms. */ data->complete_cb_id = g_timeout_add (200, canberra_complete_cb, data); return TRUE; }
static DBusHandlerResult filter_cb (DBusConnection *connection, DBusMessage *msg, void *data) { (void) connection; (void) data; const char *obj_path; char *stream_name; GList *list, *i; SubscribeItem *item; int volume = 0; if (dbus_message_has_interface (msg, DBUS_INTERFACE_LOCAL) && dbus_message_has_path (msg, DBUS_PATH_LOCAL) && dbus_message_has_member (msg, DISCONNECTED_SIG)) { N_DEBUG (LOG_CAT "pulseaudio disconnected, reconnecting in %d seconds", RETRY_TIMEOUT); disconnect_from_pulseaudio (); // After disconnecting re-query stream restore object names. if (subscribe_map && object_map) { list = g_hash_table_get_values (subscribe_map); for (i = g_list_first (list); i; i = g_list_next (i)) { SubscribeItem *item = (SubscribeItem*) i->data; if (item->object_path) { g_free (item->object_path); item->object_path = NULL; } } g_list_free (list); queue_subscribe = TRUE; } // If PulseAudio is restarting path to runtime files may change so we'll // have to request DBus address again. if (volume_pulse_address) { g_free(volume_pulse_address); volume_pulse_address = NULL; } retry_connect(); } else if (subscribe_callback && dbus_message_has_interface (msg, STREAM_RESTORE_IF) && dbus_message_has_path (msg, STREAM_RESTORE_PATH) && dbus_message_has_member (msg, NEW_ENTRY_MEMBER)) { if (!dbus_message_get_args (msg, NULL, DBUS_TYPE_OBJECT_PATH, &obj_path, DBUS_TYPE_INVALID)) { N_WARNING (LOG_CAT "failed to get arguments for new entry"); goto end; } // If the entry is in subscribe_map but not in object_map, look up the entry // and add to object_map if (!object_map_complete && !g_hash_table_lookup (object_map, obj_path)) { if ((stream_name = get_object_name (obj_path))) { if ((item = g_hash_table_lookup (subscribe_map, stream_name))) { item->object_path = g_strdup (obj_path); N_DEBUG (LOG_CAT "stream restore entry for %s appeared (%s)", item->stream_name, item->object_path); update_object_map_listen (); } g_free (stream_name); } } } else if (subscribe_callback && dbus_message_has_interface (msg, STREAM_RESTORE_IF) && dbus_message_has_path (msg, STREAM_RESTORE_PATH) && dbus_message_has_member (msg, ENTRY_REMOVED_MEMBER)) { if (!dbus_message_get_args (msg, NULL, DBUS_TYPE_OBJECT_PATH, &obj_path, DBUS_TYPE_INVALID)) { N_WARNING (LOG_CAT "failed to get arguments for removed entry"); goto end; } if ((item = g_hash_table_lookup (object_map, obj_path))) { g_hash_table_remove (object_map, item->object_path); g_free (item->object_path); item->object_path = NULL; update_object_map_listen (); N_DEBUG (LOG_CAT "removed entry %s from object map (%s)", item->stream_name, obj_path); } } else if (subscribe_callback && dbus_message_has_interface (msg, STREAM_ENTRY_IF) && dbus_message_has_member (msg, VOLUME_UPDATED_MEMBER)) { if (!(obj_path = dbus_message_get_path (msg))) goto end; if ((item = g_hash_table_lookup (object_map, obj_path))) { N_DEBUG (LOG_CAT "volume updated for stream %s (%s)", item->stream_name, item->object_path); if (get_volume (msg, &volume)) { subscribe_callback (item->stream_name, FROM_PA_VOL(volume), item->data, subscribe_userdata); } } } end: return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; }