static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) { struct userdata *u = userdata; pa_assert(c); pa_assert(u); u->client = c; switch (state) { case AVAHI_CLIENT_S_REGISTERING: case AVAHI_CLIENT_S_RUNNING: case AVAHI_CLIENT_S_COLLISION: if (!u->sink_browser) { if (!(u->sink_browser = avahi_service_browser_new( c, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, SERVICE_TYPE_SINK, NULL, 0, browser_cb, u))) { pa_log("avahi_service_browser_new() failed: %s", avahi_strerror(avahi_client_errno(c))); pa_module_unload_request(u->module, true); } } break; case AVAHI_CLIENT_FAILURE: if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) { int error; pa_log_debug("Avahi daemon disconnected."); if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) { pa_log("avahi_client_new() failed: %s", avahi_strerror(error)); pa_module_unload_request(u->module, true); } } /* Fall through */ case AVAHI_CLIENT_CONNECTING: if (u->sink_browser) { avahi_service_browser_free(u->sink_browser); u->sink_browser = NULL; } break; default: ; } }
int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; int32_t fd = -1; char x = 1; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs)) || pa_modargs_get_value_s32(ma, "fd", &fd) < 0 || fd < 0) { pa_log("Failed to parse module arguments"); goto finish; } if (pa_loop_write(fd, &x, sizeof(x), NULL) != sizeof(x)) pa_log_warn("write(%u, 1, 1) failed: %s", fd, pa_cstrerror(errno)); pa_assert_se(pa_close(fd) == 0); pa_module_unload_request(m, true); ret = 0; finish: if (ma) pa_modargs_free(ma); return ret; }
int pa__init(pa_module*m) { pa_modargs *ma = NULL; int ret = -1; uint32_t pid = 0; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs)) || pa_modargs_get_value_u32(ma, "pid", &pid) < 0 || !pid) { pa_log("Failed to parse module arguments"); goto finish; } if (kill((pid_t) pid, SIGUSR1) < 0) pa_log_warn("kill(%u) failed: %s", pid, pa_cstrerror(errno)); pa_module_unload_request(m, true); ret = 0; finish: if (ma) pa_modargs_free(ma); return ret; }
static void eof_and_unload_cb(pa_cli*c, void *userdata) { pa_module *m = userdata; pa_assert(c); pa_assert(m); pa_module_unload_request(m, true); }
void pa_module_unload_request_by_index(pa_core *c, uint32_t idx, pa_bool_t force) { pa_module *m; pa_assert(c); if (!(m = pa_idxset_get_by_index(c->modules, idx))) return; pa_module_unload_request(m, force); }
/* Called from main thread */ static void source_output_kill_cb(pa_source_output *o) { struct userdata *u; pa_source_output_assert_ref(o); pa_assert_ctl_context(); pa_assert_se(u = o->userdata); teardown(u); pa_module_unload_request(u->module, TRUE); }
/* Called from main thread */ static void sink_input_kill_cb(pa_sink_input *i) { struct userdata *u; pa_sink_input_assert_ref(i); pa_assert_ctl_context(); pa_assert_se(u = i->userdata); teardown(u); pa_module_unload_request(u->module, TRUE); }
/* Called from main context */ static void source_output_kill_cb(pa_source_output* o) { struct userdata *u; pa_source_output_assert_ref(o); pa_assert_se(u = o->userdata); pa_module_unload_request(u->module, true); pa_source_output_unlink(u->source_output); pa_source_output_unref(u->source_output); u->source_output = NULL; }
static void sink_input_kill_cb(pa_sink_input *i) { struct userdata *u; pa_sink_input_assert_ref(i); pa_assert_se(u = i->userdata); pa_sink_input_unlink(u->sink_input); pa_sink_input_unref(u->sink_input); u->sink_input = NULL; pa_module_unload_request(u->module, true); }
static void die_cb(SmcConn connection, SmPointer client_data) { struct userdata *u = client_data; pa_assert(u); pa_log_debug("Got die message from XSMP."); pa_x11_wrapper_kill(u->x11); pa_x11_wrapper_unref(u->x11); u->x11 = NULL; pa_module_unload_request(u->module, TRUE); }
static void io_callback(pa_iochannel *io, void*userdata) { struct userdata *u = userdata; pa_assert(u); if (do_read(u) < 0 || do_write(u) < 0) { if (u->io) { pa_iochannel_free(u->io); u->io = NULL; } pa_module_unload_request(u->module, TRUE); } }
int pa__init(pa_module*m) { bool just_one = false; int n = 0; pa_modargs *ma; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; } if (pa_modargs_get_value_boolean(ma, "just-one", &just_one) < 0) { pa_log("just_one= expects a boolean argument."); goto fail; } #ifdef HAVE_ALSA if ((n = detect_alsa(m->core, just_one)) <= 0) #endif #ifdef HAVE_OSS_OUTPUT if ((n = detect_oss(m->core, just_one)) <= 0) #endif #ifdef HAVE_SOLARIS if ((n = detect_solaris(m->core, just_one)) <= 0) #endif #ifdef OS_IS_WIN32 if ((n = detect_waveout(m->core, just_one)) <= 0) #endif { pa_log_warn("failed to detect any sound hardware."); goto fail; } pa_log_info("loaded %i modules.", n); /* We were successful and can unload ourselves now. */ pa_module_unload_request(m, true); pa_modargs_free(ma); return 0; fail: if (ma) pa_modargs_free(ma); return -1; }
/* Called from main context */ static void aep_sink_input_kill_cb(pa_sink_input *i) { struct userdata *u; pa_log_debug("Kill called"); pa_sink_input_assert_ref(i); pa_assert_se(u = i->userdata); /* FIXME: this is sort-of understandable with the may_move hack... we avoid abort in free() here */ u->aep_sink_input->thread_info.attached = FALSE; pa_sink_input_unlink(u->aep_sink_input); pa_sink_input_unref(u->aep_sink_input); u->aep_sink_input = NULL; pa_module_unload_request(u->module, TRUE); }
static void x11_kill_cb(pa_x11_wrapper *w, void *userdata) { struct userdata *u = userdata; pa_assert(w); pa_assert(u); pa_assert(u->x11_wrapper == w); if (u->x11_client) pa_x11_client_free(u->x11_client); if (u->x11_wrapper) pa_x11_wrapper_unref(u->x11_wrapper); u->x11_client = NULL; u->x11_wrapper = NULL; pa_module_unload_request(u->module, true); }
static void on_connection(pa_socket_client *c, pa_iochannel*io, void *userdata) { struct userdata *u = userdata; pa_socket_client_unref(u->client); u->client = NULL; if (!io) { pa_log("Connection failed: %s", pa_cstrerror(errno)); pa_module_unload_request(u->module, TRUE); return; } pa_assert(!u->io); u->io = io; pa_iochannel_set_callback(u->io, io_callback, u); pa_log_debug("Connection established, authenticating ..."); }
int pa__init(pa_module *m) { struct userdata *u = NULL; u = pa_xnew0(struct userdata, 1); m->userdata = u; u->mode_sink = pa_namereg_get(m->core, "sink.hw0", PA_NAMEREG_SINK); if (!u->mode_sink) { pa_log_error("sink.hw0 not found"); pa_xfree(u); m->userdata = NULL; return -1; } run_basic_tests(u); run_modifier_tests(u); pa_module_unload_request(m, TRUE); return 0; }
/* Called from main context */ static void sink_input_kill_cb(pa_sink_input *i) { struct userdata *u; pa_sink_input_assert_ref(i); pa_assert_se(u = i->userdata); /* The order here matters! We first kill the sink input, followed * by the sink. That means the sink callbacks must be protected * against an unconnected sink input! */ pa_sink_input_unlink(u->sink_input); pa_sink_unlink(u->sink); pa_sink_input_unref(u->sink_input); u->sink_input = NULL; pa_sink_unref(u->sink); u->sink = NULL; pa_module_unload_request(u->module, TRUE); }
/* Called from main thread */ static void source_output_kill_cb(pa_source_output *o) { struct userdata *u; pa_source_output_assert_ref(o); pa_assert_ctl_context(); pa_assert_se(u = o->userdata); /* The order here matters! We first kill the source output, followed * by the source. That means the source callbacks must be protected * against an unconnected source output! */ pa_source_output_unlink(u->source_output); pa_source_unlink(u->source); pa_source_output_unref(u->source_output); u->source_output = NULL; pa_source_unref(u->source); u->source = NULL; pa_module_unload_request(u->module, true); }
/* Called from main context */ static void sink_input_kill_cb(pa_sink_input *i) { struct userdata *u; pa_sink_input_assert_ref(i); pa_assert_se(u = i->userdata); /* The order here matters! We first kill the sink so that streams * can properly be moved away while the sink input is still connected * to the master. */ pa_sink_input_cork(u->sink_input, true); pa_sink_unlink(u->sink); pa_sink_input_unlink(u->sink_input); pa_sink_input_unref(u->sink_input); u->sink_input = NULL; pa_sink_unref(u->sink); u->sink = NULL; pa_module_unload_request(u->module, true); }
static void client_callback(AvahiClient *c, AvahiClientState state, void *userdata) { struct userdata *u = userdata; pa_assert(c); pa_assert(u); u->client = c; switch (state) { case AVAHI_CLIENT_S_RUNNING: publish_all_services(u); break; case AVAHI_CLIENT_S_COLLISION: pa_log_debug("Host name collision"); unpublish_all_services(u, FALSE); break; case AVAHI_CLIENT_FAILURE: if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) { int error; pa_log_debug("Avahi daemon disconnected."); unpublish_all_services(u, TRUE); avahi_client_free(u->client); if (!(u->client = avahi_client_new(u->avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, u, &error))) { pa_log("avahi_client_new() failed: %s", avahi_strerror(error)); pa_module_unload_request(u->module, TRUE); } } break; default: ; } }
int pa__init(pa_module*m) { pa_modargs *ma = NULL; bool restore_device = true, restore_volume = true; pa_module *n; char *t; pa_assert(m); if (!(ma = pa_modargs_new(m->argument, valid_modargs))) { pa_log("Failed to parse module arguments"); goto fail; } if (pa_modargs_get_value_boolean(ma, "restore_device", &restore_device) < 0 || pa_modargs_get_value_boolean(ma, "restore_volume", &restore_volume) < 0) { pa_log("restore_volume= and restore_device= expect boolean arguments"); goto fail; } pa_log_warn("We will now load module-stream-restore. Please make sure to remove module-volume-restore from your configuration."); t = pa_sprintf_malloc("restore_volume=%s restore_device=%s", pa_yes_no(restore_volume), pa_yes_no(restore_device)); n = pa_module_load(m->core, "module-stream-restore", t); pa_xfree(t); if (n) pa_module_unload_request(m, true); pa_modargs_free(ma); return n ? 0 : -1; fail: if (ma) pa_modargs_free(ma); return -1; }
static void on_set_debug(pa_core* c, pa_proplist* p, int debug_sink_id, const char* ext_args) { const char* device_name = pa_proplist_gets(p, PROPLIST_KEY_DEVICE); if (!device_name) { pa_log_error("device not specific!"); return; } int device_id = atoi(device_name); pa_sink* sink = NULL; pa_source* source = NULL; sink = find_sink(c, device_id); if (!sink) { source = find_source(c, device_id); } if (!sink && !source) { pa_log_error("sink/source of device id %s not found!", device_name); return; } pa_sample_spec ss; pa_channel_map map; if (sink) { ss = sink->sample_spec; map = sink->channel_map; } else { ss = source->sample_spec; map = source->channel_map; } if (debug_sink_id == EAUDIO_STREAM_DEVICE_VIRTUALOUPUT_REMOTE) { ss.rate = 8000; ss.format = PA_SAMPLE_U8; ss.channels = 1; map.channels = 1; } char sink_name[64]; GET_PLUGIN_NAME(sink_name, debug_sink_id); pa_module* link_module = NULL; const char* str_func = pa_proplist_gets(p, PROPLIST_VALUE_FUNC); bool func_on = true; if (str_func) { func_on = !strcmp(str_func, PROPLIST_VALUE_TRUE); } if (sink) { link_module = sink->module; } else if (source) { link_module = source->module; } if (func_on) { pa_pre_load_func_t f = pa_get_user_data(PA_USER_SINK_PRELOAD_FUNC); if (f) { f(sink_name, c, &ss, &map, ext_args); } pa_sink* remote_sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK); if (!remote_sink) { pa_log_error("remote-sink load failed"); return; } char args[256] = { 0 }; char loopback_name[128] = { 0 }; const char* i_name = NULL; const char* o_name = NULL; if (sink) { i_name = sink->monitor_source->name; o_name = remote_sink->name; } else if (source) { i_name = source->name; o_name = remote_sink->name; } pa_snprintf(loopback_name, sizeof(loopback_name), "Loopback(%s->%s)", i_name, o_name); pa_snprintf(args, sizeof(args), "name=%s source=%s sink=%s token=%u %s", loopback_name, i_name, o_name, MAGIC_TOKEN_ID, ext_args ? ext_args : ""); pa_log_info("load-module module-loopback args: %s", args); pa_module* m = pa_module_load(c, "module-loopback", args); if (!m) { pa_log_error("on_set_debug module load err."); return; } if (link_module) { pa_proplist_sets(link_module->proplist, PA_PROP_LINK_LOOPBACK_ID, loopback_name); } } else { pa_sink* remote_sink = find_sink(c, debug_sink_id); if (remote_sink) { pa_log_info("unloading remote_sink %d", debug_sink_id); pa_module_unload_request(remote_sink->module, true); } } }
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) { struct userdata *u = userdata; char *name = NULL, *code = NULL; pa_assert(io); pa_assert(u); if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { pa_log("Lost connection to LIRC daemon."); goto fail; } if (events & PA_IO_EVENT_INPUT) { char *c; if (lirc_nextcode(&code) != 0 || !code) { pa_log("lirc_nextcode() failed."); goto fail; } c = pa_xstrdup(code); c[strcspn(c, "\n\r")] = 0; pa_log_debug("Raw IR code '%s'", c); pa_xfree(c); while (lirc_code2char(u->config, code, &name) == 0 && name) { enum { INVALID, UP, DOWN, MUTE, RESET, MUTE_TOGGLE } volchange = INVALID; pa_log_info("Translated IR code '%s'", name); if (strcasecmp(name, "volume-up") == 0) volchange = UP; else if (strcasecmp(name, "volume-down") == 0) volchange = DOWN; else if (strcasecmp(name, "mute") == 0) volchange = MUTE; else if (strcasecmp(name, "mute-toggle") == 0) volchange = MUTE_TOGGLE; else if (strcasecmp(name, "reset") == 0) volchange = RESET; if (volchange == INVALID) pa_log_warn("Received unknown IR code '%s'", name); else { pa_sink *s; if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK))) pa_log("Failed to get sink '%s'", u->sink_name); else { pa_cvolume cv = *pa_sink_get_volume(s, FALSE); switch (volchange) { case UP: pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit); pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case DOWN: pa_cvolume_dec(&cv, u->volume_step); pa_sink_set_volume(s, &cv, TRUE, TRUE); break; case MUTE: pa_sink_set_mute(s, TRUE, TRUE); break; case RESET: pa_sink_set_mute(s, FALSE, TRUE); break; case MUTE_TOGGLE: pa_sink_set_mute(s, !pa_sink_get_mute(s, FALSE), TRUE); break; case INVALID: pa_assert_not_reached(); } } } } } pa_xfree(code); return; fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; pa_module_unload_request(u->module, TRUE); pa_xfree(code); }
static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) { struct userdata *u = PA_SINK(o)->userdata; switch (code) { case PA_SINK_MESSAGE_SET_STATE: switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) { case PA_SINK_SUSPENDED: pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state)); pa_smoother_pause(u->smoother, pa_rtclock_now()); /* Issue a FLUSH if we are connected */ if (u->fd >= 0) { pa_raop_flush(u->raop); } break; case PA_SINK_IDLE: case PA_SINK_RUNNING: if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { pa_smoother_resume(u->smoother, pa_rtclock_now(), true); /* The connection can be closed when idle, so check to see if we need to reestablish it */ if (u->fd < 0) pa_raop_connect(u->raop); else pa_raop_flush(u->raop); } break; case PA_SINK_UNLINKED: case PA_SINK_INIT: case PA_SINK_INVALID_STATE: ; } break; case PA_SINK_MESSAGE_GET_LATENCY: { pa_usec_t w, r; r = pa_smoother_get(u->smoother, pa_rtclock_now()); w = pa_bytes_to_usec((u->offset - u->encoding_overhead + (u->encoded_memchunk.length / u->encoding_ratio)), &u->sink->sample_spec); *((pa_usec_t*) data) = w > r ? w - r : 0; return 0; } case SINK_MESSAGE_PASS_SOCKET: { struct pollfd *pollfd; pa_assert(!u->rtpoll_item); u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1); pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); pollfd->fd = u->fd; pollfd->events = POLLOUT; /*pollfd->events = */pollfd->revents = 0; if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { /* Our stream has been suspended so we just flush it.... */ pa_raop_flush(u->raop); } return 0; } case SINK_MESSAGE_RIP_SOCKET: { if (u->fd >= 0) { pa_close(u->fd); u->fd = -1; } else /* FIXME */ pa_log("We should not get to this state. Cannot rip socket if not connected."); if (u->sink->thread_info.state == PA_SINK_SUSPENDED) { pa_log_debug("RTSP control connection closed, but we're suspended so let's not worry about it... we'll open it again later"); if (u->rtpoll_item) pa_rtpoll_item_free(u->rtpoll_item); u->rtpoll_item = NULL; } else { /* Question: is this valid here: or should we do some sort of: return pa_sink_process_msg(PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL); ?? */ pa_module_unload_request(u->module, true); } return 0; } } return pa_sink_process_msg(o, code, data, offset, chunk); }
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) { struct userdata *u = userdata; pa_assert(io); pa_assert(u); if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) { pa_log("Lost connection to evdev device."); goto fail; } if (events & PA_IO_EVENT_INPUT) { struct input_event ev; if (pa_loop_read(u->fd, &ev, sizeof(ev), &u->fd_type) <= 0) { pa_log("Failed to read from event device: %s", pa_cstrerror(errno)); goto fail; } if (ev.type == EV_KEY && (ev.value == 1 || ev.value == 2)) { enum { INVALID, UP, DOWN, MUTE_TOGGLE } volchange = INVALID; pa_log_debug("Key code=%u, value=%u", ev.code, ev.value); switch (ev.code) { case KEY_VOLUMEDOWN: volchange = DOWN; break; case KEY_VOLUMEUP: volchange = UP; break; case KEY_MUTE: volchange = MUTE_TOGGLE; break; } if (volchange != INVALID) { pa_sink *s; if (!(s = pa_namereg_get(u->module->core, u->sink_name, PA_NAMEREG_SINK))) pa_log("Failed to get sink '%s'", u->sink_name); else { pa_cvolume cv = *pa_sink_get_volume(s, false); switch (volchange) { case UP: pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit); pa_sink_set_volume(s, &cv, true, true); break; case DOWN: pa_cvolume_dec(&cv, u->volume_step); pa_sink_set_volume(s, &cv, true, true); break; case MUTE_TOGGLE: pa_sink_set_mute(s, !pa_sink_get_mute(s, false), true); break; case INVALID: pa_assert_not_reached(); } } } } } return; fail: u->module->core->mainloop->io_free(u->io); u->io = NULL; pa_module_unload_request(u->module, true); }