commits
tags
#include <locale.h>
#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "app.h"
#include "ui.h"
static void build_default_output_dir(char *out, size_t cap) {
const char *home = getenv("HOME");
if (!home) home = "/tmp";
snprintf(out, cap, "%s/Music/ytmdl", home);
}
static void print_usage(const char *prog) {
fprintf(stderr,
"Usage: %s [-o output_dir] [-f audio_format]\n"
" -o Directory to save downloaded audio files (default: ~/Music/ytmdl)\n"
" -f Audio format: mp3, m4a, flac, opus, wav, vorbis (default: mp3)\n",
prog);
}
int main(int argc, char **argv) {
char output_dir[OUTPUT_DIR_CAP];
build_default_output_dir(output_dir, sizeof(output_dir));
char audio_format[AUDIO_FORMAT_CAP] = "mp3";
int opt;
while ((opt = getopt(argc, argv, "o:f:h")) != -1) {
switch (opt) {
case 'o':
snprintf(output_dir, sizeof(output_dir), "%s", optarg);
break;
case 'f':
snprintf(audio_format, sizeof(audio_format), "%s", optarg);
break;
case 'h':
default:
print_usage(argv[0]);
return opt == 'h' ? 0 : 1;
}
}
setlocale(LC_ALL, "");
/* Heap-allocated: Queue's fixed-size item array makes App several MB,
* too large to safely put on the stack. */
App *app = malloc(sizeof(App));
if (!app) {
fprintf(stderr, "Out of memory\n");
return 1;
}
app_init(app, output_dir, audio_format);
app_start_workers(app);
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
curs_set(1);
timeout(150); /* ms; also drives periodic redraws for background progress */
/* Disable software flow control (IXON/IXOFF) so Ctrl+Q/Ctrl+S reach the
* app as normal keys instead of being swallowed by the tty driver. */
struct termios term;
if (tcgetattr(STDIN_FILENO, &term) == 0) {
term.c_iflag &= ~(IXON | IXOFF);
tcsetattr(STDIN_FILENO, TCSANOW, &term);
}
UiState ui;
ui_init(&ui);
while (!ui.quit_requested) {
ui_draw(app, &ui);
int ch = getch();
if (ch != ERR) {
ui_handle_key(app, &ui, ch);
}
}
ui_destroy(&ui);
endwin();
app_shutdown(app);
free(app);
return 0;
}