summaryrefslogtreecommitdiffstats
path: root/src/modules/module-rescue-streams.c
blob: 0e3946b1f72b43e28d595154f95e45cfdc465f37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/* $Id$ */

/***
  This file is part of PulseAudio.
 
  PulseAudio is free software; you can redistribute it and/or modify
  it under the terms of the GNU Lesser General Public License as published
  by the Free Software Foundation; either version 2 of the License,
  or (at your option) any later version.
 
  PulseAudio is distributed in the hope that it will be useful, but
  WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  General Public License for more details.
 
  You should have received a copy of the GNU Lesser General Public License
  along with PulseAudio; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA.
***/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <pulse/xmalloc.h>

#include <pulsecore/core.h>
#include <pulsecore/modargs.h>
#include <pulsecore/log.h>
#include <pulsecore/namereg.h>

#include "module-rescue-streams-symdef.h"

PA_MODULE_AUTHOR("Lennart Poettering")
PA_MODULE_DESCRIPTION("When a sink/source is removed, try to move their streams to the default sink/source")
PA_MODULE_VERSION(PACKAGE_VERSION)

static const char* const valid_modargs[] = {
    NULL,
};

static pa_hook_result_t hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
    pa_sink_input *i;
    pa_sink *target;
    
    assert(c);
    assert(sink);

    if (!pa_idxset_size(sink->inputs)) {
        pa_log_debug(__FILE__": No sink inputs to move away.");
        return PA_HOOK_OK;
    }
    
    if (!(target = pa_namereg_get(c, NULL, PA_NAMEREG_SINK, 0))) {
        pa_log_info(__FILE__": No evacuation sink found.");
        return PA_HOOK_OK;
    }

    assert(target != sink);

    while ((i = pa_idxset_first(sink->inputs, NULL))) {
        if (pa_sink_input_move_to(i, target, 1) < 0) {
            pa_log_warn(__FILE__": Failed to move sink input %u \"%s\" to %s.", i->index, i->name, target->name);
            return PA_HOOK_OK;
        }

        pa_log_info(__FILE__": Sucessfully moved sink input %u \"%s\" to %s.", i->index, i->name, target->name);
    }

    
    return PA_HOOK_OK;
}

int pa__init(pa_core *c, pa_module*m) {
    pa_modargs *ma = NULL;
    
    assert(c);
    assert(m);

    if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
        pa_log(__FILE__": Failed to parse module arguments");
        return -1;
    }

    m->userdata = pa_hook_connect(&c->hook_sink_disconnect, (pa_hook_cb_t) hook_callback, NULL);

    pa_modargs_free(ma);
    return 0;
}

void pa__done(pa_core *c, pa_module*m) {
    assert(c);
    assert(m);

    if (m->userdata)
        pa_hook_slot_free((pa_hook_slot*) m->userdata);
}