~schnouki/pustule

ref: 2e90522e70214bb6d1bb88aef6f7d8c06152a99f pustule/main.c -rw-r--r-- 3.8 KiB
2e90522e — Thomas Jost Expose log functions in Lua 10 months ago
                                                                                
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
 * pustule
 * Copyright 2014-2020 Thomas Jost <schnouki@schnouki.net>
 *
 * This file is part of pustule.
 *
 * pustule is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * pustule 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 General Public License along with
 * pustule. If not, see <http://www.gnu.org/licenses/>.
 */

#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include <pulse/pulseaudio.h>

#include "argparse/argparse.h"
#include "log.h"
#include "pustule.h"

static const char* const usage[] = {
    "pustule [options]",
    NULL
};


/* Get the name of the default configuration file, using environment
   variables */
static char* get_default_config_file() {
    char* config_dir;
    char* config_file;
    char* default_dir = getenv("XDG_CONFIG_HOME");
    if (default_dir) {
        config_dir = strdup(default_dir);
    }
    else {
        char* home_dir = getenv("HOME");
        home_dir = getenv("HOME");
        if (!home_dir)
            return NULL;
        if (asprintf(&config_dir, "%s/.config", home_dir) < 0) {
            log_fatal("Can't allocate memory for the path to the config directory");
            exit(1);
        }
    }
    if (asprintf(&config_file, "%s/pustule.lua", config_dir) < 0) {
        log_fatal("Can't allocate memory for the path of the config directory");
        exit(1);
    }
    free(config_dir);
    return config_file;
}


/* Initialization */
int main(int argc, const char** argv) {
    /* Parse command-line arguments */
    const char* config_path = get_default_config_file();
    int debug = 0;

    struct argparse_option options[] = {
        OPT_HELP(),
        OPT_STRING('c', "config", &config_path, "path to the configuration file; defaults to $XDG_CONFIG_HOME/pustule.lua"),
        OPT_BOOLEAN('d', "debug", &debug, "enable debug mode"),
        OPT_END(),
    };

    struct argparse argparse;
    argparse_init(&argparse, options, usage, 0);
    argparse_describe(&argparse, "Rule-based volume control for PulseAudio.", NULL);
    argc = argparse_parse(&argparse, argc, argv);

    log_set_level(debug ? LOG_DEBUG : LOG_INFO);

    /* Initialize Lua */
    log_debug("Initializing Lua");
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    init_lua_module(L);

    /* Run the config file */
    log_info("Loading config file");
    if (luaL_dofile(L, config_path)) {
        log_error("Error while loading config file: %s", lua_tostring(L, -1));
        return 1;
    }

    /* Create the libpulse threaded main loop */
    log_debug("Preparing to connect to PulseAudio");
    pa_mainloop* loop = pa_mainloop_new();
    if (!loop) {
        log_error("Can't create main loop");
        return 1;
    }
    paloop = loop;

    pa_mainloop_api* api = pa_mainloop_get_api(loop);
    if (!api) {
        log_error("Can't get main loop API");
        return 1;
    }

    pa_context* ctx = pa_context_new(api, "pustule");
    if (!ctx) {
        log_error("Can't get PulseAudio context");
        return 1;
    }
    pactx = ctx;

    /* Connect and run the event loop */
    log_debug("Connecting to PulseAudio");
    pa_context_set_state_callback(ctx, state_callback, NULL);
    pa_context_connect(pactx, NULL, PA_CONTEXT_NOAUTOSPAWN | PA_CONTEXT_NOFAIL, NULL);

    log_info("Running pustule");
    int ret = pa_mainloop_run(loop, NULL);

    /* Cleanup */
    lua_close(L);

    return ret;
}