X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fmain.c;h=8bfa03a86cff4bc8c0e9e06a55f7660b13159bf1;hb=9b08b8d793f6ee02e021f013397eaf3b22348283;hp=7e5a6cb3000c35605b62eb4728da2898bfe36889;hpb=323d2239df7d8b6a3b8005f14c7e90b5271a77e9;p=ncmpc.git diff --git a/src/main.c b/src/main.c index 7e5a6cb..8bfa03a 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,5 @@ /* ncmpc (Ncurses MPD Client) - * (c) 2004-2010 The Music Player Daemon Project + * (c) 2004-2017 The Music Player Daemon Project * Project homepage: http://musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -20,7 +20,7 @@ #include "config.h" #include "ncmpc.h" #include "mpdclient.h" -#include "gidle.h" +#include "callbacks.h" #include "charset.h" #include "options.h" #include "command.h" @@ -31,6 +31,9 @@ #include "strfsong.h" #include "i18n.h" #include "player_command.h" +#include "keyboard.h" +#include "lirc.h" +#include "signals.h" #ifndef NCMPC_MINI #include "conf.h" @@ -40,10 +43,6 @@ #include "lyrics.h" #endif -#ifdef ENABLE_LIRC -#include "lirc.h" -#endif - #include #include @@ -64,7 +63,6 @@ static const guint update_interval = 500; static struct mpdclient *mpd = NULL; static GMainLoop *main_loop; static guint reconnect_source_id, update_source_id; -static int sigwinch_pipes[2]; #ifndef NCMPC_MINI static guint check_key_bindings_source_id; @@ -74,16 +72,10 @@ static guint check_key_bindings_source_id; static void update_xterm_title(void) { - struct mpd_status *status = NULL; - const struct mpd_song *song = NULL; - if (mpd) { - status = mpd->status; - song = mpd->song; - } + const struct mpd_song *song = mpd->song; char tmp[BUFSIZE]; - if (options.xterm_title_format && status && song && - mpd_status_get_state(status) == MPD_STATE_PLAY) + if (options.xterm_title_format && mpd->playing && song) strfsong(tmp, BUFSIZE, options.xterm_title_format, song); else g_strlcpy(tmp, PACKAGE " version " VERSION, BUFSIZE); @@ -96,75 +88,6 @@ update_xterm_title(void) } #endif -static void -exit_and_cleanup(void) -{ - screen_exit(); -#ifndef NCMPC_MINI - set_xterm_title(""); -#endif - printf("\n"); - - if (mpd) { - mpdclient_disconnect(mpd); - mpdclient_free(mpd); - } -} - -#ifndef WIN32 -static void -catch_sigint(gcc_unused int sig) -{ - g_main_loop_quit(main_loop); -} - - -static void -catch_sigcont(gcc_unused int sig) -{ - char irrelevant = 'a'; - if (1 != write(sigwinch_pipes[1], &irrelevant, 1)) - exit(EXIT_FAILURE); -} - -void -sigstop(void) -{ - def_prog_mode(); /* save the tty modes */ - endwin(); /* end curses mode temporarily */ - kill(0, SIGSTOP); /* issue SIGSTOP */ -} - -static gboolean -sigwinch_event(gcc_unused GIOChannel *source, - gcc_unused GIOCondition condition, gcc_unused gpointer data) -{ - char ignoreme[64]; - if (1 > read(sigwinch_pipes[0], ignoreme, 64)) - exit(EXIT_FAILURE); - - endwin(); - refresh(); - screen_resize(mpd); - - return TRUE; -} - -static void -catch_sigwinch(gcc_unused int sig) -{ - char irrelevant = 'a'; - if (1 != write(sigwinch_pipes[1], &irrelevant, 1)) - exit(EXIT_FAILURE); -} -#endif /* WIN32 */ - -static void -idle_callback(enum mpd_error error, - gcc_unused enum mpd_server_error server_error, - const char *message, enum mpd_idle events, - gcc_unused void *ctx); - static gboolean timer_mpd_update(gpointer data); @@ -191,10 +114,7 @@ disable_update_timer(void) static bool should_enable_update_timer(void) { - return (mpdclient_is_connected(mpd) && - (mpd->source == NULL || /* "idle" not supported */ - (mpd->status != NULL && - mpd_status_get_state(mpd->status) == MPD_STATE_PLAY))) + return mpd->playing #ifndef NCMPC_MINI || options.display_time #endif @@ -210,16 +130,11 @@ auto_update_timer(void) disable_update_timer(); } -static void -check_reconnect(void); - static void do_mpd_update(void) { if (mpdclient_is_connected(mpd) && - (mpd->source == NULL || mpd->events != 0 || - (mpd->status != NULL && - mpd_status_get_state(mpd->status) == MPD_STATE_PLAY))) + (mpd->events != 0 || mpd->playing)) mpdclient_update(mpd); #ifndef NCMPC_MINI @@ -229,9 +144,6 @@ do_mpd_update(void) screen_update(mpd); mpd->events = 0; - - mpdclient_put_connection(mpd); - check_reconnect(); } static char * @@ -273,7 +185,7 @@ default_settings_name(void) static gboolean timer_reconnect(gcc_unused gpointer data) { - assert(!mpdclient_is_connected(mpd)); + assert(mpdclient_is_dead(mpd)); reconnect_source_id = 0; @@ -283,20 +195,19 @@ timer_reconnect(gcc_unused gpointer data) g_free(name); doupdate(); - mpdclient_disconnect(mpd); - if (!mpdclient_connect(mpd, options.host, options.port, - options.timeout_ms, - options.password)) { - /* try again in 5 seconds */ - reconnect_source_id = g_timeout_add(5000, - timer_reconnect, NULL); - return FALSE; - } + mpdclient_connect(mpd); - struct mpd_connection *connection = mpdclient_get_connection(mpd); + return FALSE; +} + +void +mpdclient_connected_callback(void) +{ + assert(reconnect_source_id == 0); #ifndef NCMPC_MINI /* quit if mpd is pre 0.14 - song id not supported by mpd */ + struct mpd_connection *connection = mpdclient_get_connection(mpd); if (mpd_connection_cmp_server_version(connection, 0, 16, 0) < 0) { const unsigned *version = mpd_connection_get_server_version(connection); @@ -309,13 +220,10 @@ timer_reconnect(gcc_unused gpointer data) /* try again after 30 seconds */ reconnect_source_id = g_timeout_add(30000, timer_reconnect, NULL); - return FALSE; + return; } #endif - mpd->source = mpd_glib_new(connection, - idle_callback, mpd); - screen_status_clear_message(); doupdate(); @@ -325,75 +233,41 @@ timer_reconnect(gcc_unused gpointer data) do_mpd_update(); auto_update_timer(); +} - return FALSE; +void +mpdclient_failed_callback(void) +{ + assert(reconnect_source_id == 0); + + /* try again in 5 seconds */ + reconnect_source_id = g_timeout_add(5000, + timer_reconnect, NULL); } -static void -check_reconnect(void) +void +mpdclient_lost_callback(void) { - if (!mpdclient_is_connected(mpd) && reconnect_source_id == 0) - /* reconnect when the connection is lost */ - reconnect_source_id = g_timeout_add(1000, timer_reconnect, - NULL); + assert(reconnect_source_id == 0); + + screen_update(mpd); + + reconnect_source_id = g_timeout_add(1000, timer_reconnect, NULL); } /** * This function is called by the gidle.c library when MPD sends us an * idle event (or when the connection dies). */ -static void -idle_callback(enum mpd_error error, enum mpd_server_error server_error, - const char *message, enum mpd_idle events, - void *ctx) +void +mpdclient_idle_callback(gcc_unused enum mpd_idle events) { - struct mpdclient *c = ctx; - - c->idle = false; - - assert(mpdclient_is_connected(c)); - - if (error != MPD_ERROR_SUCCESS) { - if (error == MPD_ERROR_SERVER && - server_error == MPD_SERVER_ERROR_UNKNOWN_CMD) { - /* the "idle" command is not supported - fall - back to timer based polling */ - mpd_glib_free(c->source); - c->source = NULL; - auto_update_timer(); - return; - } - - char *allocated; - if (error == MPD_ERROR_SERVER) - message = allocated = utf8_to_locale(message); - else - allocated = NULL; - screen_status_message(message); - g_free(allocated); - screen_bell(); - doupdate(); - - mpdclient_disconnect(c); - screen_update(mpd); - reconnect_source_id = g_timeout_add(1000, timer_reconnect, - NULL); - return; - } - - c->events |= events; - mpdclient_update(c); - #ifndef NCMPC_MINI if (options.enable_xterm_title) update_xterm_title(); #endif screen_update(mpd); - c->events = 0; - - mpdclient_put_connection(c); - check_reconnect(); auto_update_timer(); } @@ -419,16 +293,15 @@ void end_input_event(void) screen_update(mpd); mpd->events = 0; - mpdclient_put_connection(mpd); - check_reconnect(); auto_update_timer(); } -int do_input_event(command_t cmd) +bool +do_input_event(command_t cmd) { if (cmd == CMD_QUIT) { g_main_loop_quit(main_loop); - return -1; + return false; } screen_cmd(mpd, cmd); @@ -437,23 +310,7 @@ int do_input_event(command_t cmd) /* make sure we don't update the volume yet */ disable_update_timer(); - return 0; -} - -static gboolean -keyboard_event(gcc_unused GIOChannel *source, - gcc_unused GIOCondition condition, - gcc_unused gpointer data) -{ - begin_input_event(); - - command_t cmd = get_keyboard_command(); - if (cmd != CMD_NONE) - if (do_input_event(cmd) != 0) - return FALSE; - - end_input_event(); - return TRUE; + return true; } #ifndef NCMPC_MINI @@ -539,59 +396,6 @@ main(int argc, const char *argv[]) /* parse command line options - 2 pass */ options_parse(argc, argv); -#ifndef WIN32 - /* setup signal behavior - SIGINT */ - struct sigaction act; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - act.sa_handler = catch_sigint; - if (sigaction(SIGINT, &act, NULL) < 0) { - perror("signal"); - exit(EXIT_FAILURE); - } - - /* setup signal behavior - SIGTERM */ - - act.sa_handler = catch_sigint; - if (sigaction(SIGTERM, &act, NULL) < 0) { - perror("sigaction()"); - exit(EXIT_FAILURE); - } - - /* setup signal behavior - SIGCONT */ - - act.sa_handler = catch_sigcont; - if (sigaction(SIGCONT, &act, NULL) < 0) { - perror("sigaction(SIGCONT)"); - exit(EXIT_FAILURE); - } - - /* setup signal behaviour - SIGHUP*/ - - act.sa_handler = catch_sigint; - if (sigaction(SIGHUP, &act, NULL) < 0) { - perror("sigaction(SIGHUP)"); - exit(EXIT_FAILURE); - } - - /* setup SIGWINCH */ - - act.sa_flags = SA_RESTART; - act.sa_handler = catch_sigwinch; - if (sigaction(SIGWINCH, &act, NULL) < 0) { - perror("sigaction(SIGWINCH)"); - exit(EXIT_FAILURE); - } - - /* ignore SIGPIPE */ - - act.sa_handler = SIG_IGN; - if (sigaction(SIGPIPE, &act, NULL) < 0) { - perror("sigaction(SIGPIPE)"); - exit(EXIT_FAILURE); - } -#endif - ncu_init(); #ifdef ENABLE_LYRICS_SCREEN @@ -599,7 +403,9 @@ main(int argc, const char *argv[]) #endif /* create mpdclient instance */ - mpd = mpdclient_new(); + mpd = mpdclient_new(options.host, options.port, + options.timeout_ms, + options.password); /* initialize curses */ screen_init(mpd); @@ -608,34 +414,15 @@ main(int argc, const char *argv[]) main_loop = g_main_loop_new(NULL, FALSE); /* watch out for keyboard input */ - GIOChannel *keyboard_channel = g_io_channel_unix_new(STDIN_FILENO); - g_io_add_watch(keyboard_channel, G_IO_IN, keyboard_event, NULL); + keyboard_init(); -#ifdef ENABLE_LIRC /* watch out for lirc input */ - int lirc_socket = ncmpc_lirc_open(); - GIOChannel *lirc_channel = NULL; - if (lirc_socket >= 0) { - lirc_channel = g_io_channel_unix_new(lirc_socket); - g_io_add_watch(lirc_channel, G_IO_IN, lirc_event, NULL); - } -#endif + ncmpc_lirc_init(); -#ifndef WIN32 - GIOChannel *sigwinch_channel = NULL; - if (!pipe(sigwinch_pipes) && - !fcntl(sigwinch_pipes[1], F_SETFL, O_NONBLOCK)) { - sigwinch_channel = g_io_channel_unix_new(sigwinch_pipes[0]); - g_io_add_watch(sigwinch_channel, G_IO_IN, sigwinch_event, NULL); - } - else { - perror("sigwinch pipe creation failed"); - exit(EXIT_FAILURE); - } -#endif + signals_init(main_loop, mpd); /* attempt to connect */ - reconnect_source_id = g_timeout_add(1, timer_reconnect, NULL); + reconnect_source_id = g_idle_add(timer_reconnect, NULL); auto_update_timer(); @@ -646,6 +433,7 @@ main(int argc, const char *argv[]) screen_paint(mpd); g_main_loop_run(main_loop); + g_main_loop_unref(main_loop); /* cleanup */ @@ -661,19 +449,16 @@ main(int argc, const char *argv[]) g_source_remove(check_key_bindings_source_id); #endif - g_main_loop_unref(main_loop); - g_io_channel_unref(keyboard_channel); - g_io_channel_unref(sigwinch_channel); - close(sigwinch_pipes[0]); - close(sigwinch_pipes[1]); - -#ifdef ENABLE_LIRC - if (lirc_socket >= 0) - g_io_channel_unref(lirc_channel); - ncmpc_lirc_close(); + signals_deinit(); + ncmpc_lirc_deinit(); + + screen_exit(); +#ifndef NCMPC_MINI + set_xterm_title(""); #endif + printf("\n"); - exit_and_cleanup(); + mpdclient_free(mpd); #ifdef ENABLE_LYRICS_SCREEN lyrics_deinit();