X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fmain.c;h=2edf2d4ecc0d3625bb67263a384724f185d19934;hb=607bf2d55826f861d12b774884cb201bc683051c;hp=668d5aa3350a197feccaeb7ea488e08d4f9db9eb;hpb=2fa18f35d878e280bbd8299aa4048bb59e183165;p=ncmpc.git diff --git a/src/main.c b/src/main.c index 668d5aa..2edf2d4 100644 --- a/src/main.c +++ b/src/main.c @@ -1,48 +1,57 @@ -/* - * $Id$ - * - * (c) 2004 by Kalle Wallin - * +/* ncmpc (Ncurses MPD Client) + * (c) 2004-2009 The Music Player Daemon Project + * Project homepage: http://musicpd.org + * This program 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 2 of the License, or * (at your option) any later version. - * + * This program 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 this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ #include "config.h" #include "ncmpc.h" #include "mpdclient.h" #include "charset.h" #include "options.h" -#include "conf.h" #include "command.h" #include "ncu.h" #include "screen.h" #include "screen_utils.h" #include "strfsong.h" #include "i18n.h" -#include "gcc.h" + +#ifndef NCMPC_MINI +#include "conf.h" +#endif #ifdef ENABLE_LYRICS_SCREEN #include "lyrics.h" #endif +#ifdef ENABLE_LIRC +#include "lirc.h" +#endif + #include #include #include #include +#ifdef ENABLE_LOCALE +#include +#endif + /* time between mpd updates [s] */ -static const float MPD_UPDATE_TIME = 0.5; +static const guint update_interval = 500; #define BUFSIZE 1024 @@ -61,15 +70,18 @@ error_msg(const gchar *msg) if ((p = strchr(msg, '}')) == NULL) return msg; - while (p && *p && (*p=='}' || *p==' ')) + do { p++; + } while (*p == '}' || * p== ' '); return p; } static void -error_callback(mpd_unused mpdclient_t *c, gint error, const gchar *msg) +error_callback(G_GNUC_UNUSED mpdclient_t *c, gint error, const gchar *_msg) { + char *msg = utf8_to_locale(_msg); + error = error & 0xFF; switch (error) { case MPD_ERROR_CONNPORT: @@ -85,8 +97,11 @@ error_callback(mpd_unused mpdclient_t *c, gint error, const gchar *msg) doupdate(); connected = FALSE; } + + g_free(msg); } +#ifndef NCMPC_MINI static void update_xterm_title(void) { @@ -111,12 +126,15 @@ update_xterm_title(void) set_xterm_title("%s", title); } } +#endif static void exit_and_cleanup(void) { screen_exit(); +#ifndef NCMPC_MINI set_xterm_title(""); +#endif printf("\n"); if (mpd) { @@ -128,24 +146,22 @@ exit_and_cleanup(void) g_free(options.password); g_free(options.list_format); g_free(options.status_format); +#ifndef NCMPC_MINI g_free(options.scroll_sep); +#endif } static void -catch_sigint(mpd_unused int sig) +catch_sigint(G_GNUC_UNUSED int sig) { g_main_loop_quit(main_loop); } static void -catch_sigcont(mpd_unused int sig) +catch_sigcont(G_GNUC_UNUSED int sig) { -#ifdef ENABLE_RAW_MODE - reset_prog_mode(); /* restore tty modes */ - refresh(); -#endif - screen_resize(); + screen_resize(mpd); } void @@ -159,7 +175,7 @@ sigstop(void) static guint timer_sigwinch_id; static gboolean -timer_sigwinch(mpd_unused gpointer data) +timer_sigwinch(G_GNUC_UNUSED gpointer data) { /* the following causes the screen to flicker. There might be better solutions, but I believe it isn't all that @@ -167,13 +183,13 @@ timer_sigwinch(mpd_unused gpointer data) endwin(); refresh(); - screen_resize(); + screen_resize(mpd); return FALSE; } static void -catch_sigwinch(mpd_unused int sig) +catch_sigwinch(G_GNUC_UNUSED int sig) { if (timer_sigwinch_id != 0) g_source_remove(timer_sigwinch_id); @@ -189,7 +205,7 @@ timer_mpd_update(gpointer data); * broken. It tries to recover by reconnecting periodically. */ static gboolean -timer_reconnect(mpd_unused gpointer data) +timer_reconnect(G_GNUC_UNUSED gpointer data) { int ret; @@ -211,12 +227,14 @@ timer_reconnect(mpd_unused gpointer data) return FALSE; } +#ifndef NCMPC_MINI /* quit if mpd is pre 0.11.0 - song id not supported by mpd */ if (MPD_VERSION_LT(mpd, 0, 11, 0)) { - screen_status_printf(_("Error: MPD version %d.%d.%d is to old (0.11.0 needed).\n"), + screen_status_printf(_("Error: MPD version %d.%d.%d is to old (%s needed)"), mpd->connection->version[0], mpd->connection->version[1], - mpd->connection->version[2]); + mpd->connection->version[2], + "0.11.0"); mpdclient_disconnect(mpd); doupdate(); @@ -224,8 +242,9 @@ timer_reconnect(mpd_unused gpointer data) g_timeout_add(30000, timer_reconnect, NULL); return FALSE; } +#endif - screen_status_printf(_("Connected to %s!"), options.host); + screen_status_printf(_("Connected to %s"), options.host); doupdate(); connected = TRUE; @@ -247,8 +266,10 @@ timer_mpd_update(gpointer data) reconnect_source_id = g_timeout_add(1000, timer_reconnect, NULL); +#ifndef NCMPC_MINI if (options.enable_xterm_title) update_xterm_title(); +#endif screen_update(mpd); @@ -260,52 +281,74 @@ timer_mpd_update(gpointer data) * 500ms. It is used for delayed seeking. */ static gboolean -timer_idle(mpd_unused gpointer data) +timer_idle(G_GNUC_UNUSED gpointer data) { screen_idle(mpd); return TRUE; } -static gboolean -keyboard_event(mpd_unused GIOChannel *source, - mpd_unused GIOCondition condition, mpd_unused gpointer data) +void begin_input_event(void) { - command_t cmd; - /* remove the idle timeout; add it later with fresh interval */ g_source_remove(idle_source_id); +} - if ((cmd=get_keyboard_command()) != CMD_NONE) { - if (cmd == CMD_QUIT) { - g_main_loop_quit(main_loop); - return FALSE; - } +void end_input_event(void) +{ + screen_update(mpd); + + idle_source_id = g_timeout_add(idle_interval, timer_idle, NULL); +} - screen_cmd(mpd, cmd); +int do_input_event(command_t cmd) +{ + if (cmd == CMD_QUIT) { + g_main_loop_quit(main_loop); + return -1; + } + + screen_cmd(mpd, cmd); - if (cmd == CMD_VOLUME_UP || cmd == CMD_VOLUME_DOWN) { - /* make sure we dont update the volume yet */ - g_source_remove(update_source_id); - update_source_id = g_timeout_add((guint)(MPD_UPDATE_TIME * 1000), - timer_mpd_update, - GINT_TO_POINTER(TRUE)); - } + if (cmd == CMD_VOLUME_UP || cmd == CMD_VOLUME_DOWN) { + /* make sure we dont update the volume yet */ + g_source_remove(update_source_id); + update_source_id = g_timeout_add(update_interval, + timer_mpd_update, + GINT_TO_POINTER(TRUE)); } - screen_update(mpd); + return 0; +} - idle_source_id = g_timeout_add(idle_interval, timer_idle, NULL); +static gboolean +keyboard_event(G_GNUC_UNUSED GIOChannel *source, + G_GNUC_UNUSED GIOCondition condition, + G_GNUC_UNUSED gpointer data) +{ + command_t cmd; + + begin_input_event(); + + if ((cmd=get_keyboard_command()) != CMD_NONE) + if (do_input_event(cmd) != 0) + return FALSE; + + end_input_event(); return TRUE; } +#ifndef NCMPC_MINI /** * Check the configured key bindings for errors, and display a status * message every 10 seconds. */ static gboolean -timer_check_key_bindings(mpd_unused gpointer data) +timer_check_key_bindings(G_GNUC_UNUSED gpointer data) { char buf[256]; +#ifdef ENABLE_KEYDEF_SCREEN + char comment[64]; +#endif gboolean key_error; key_error = check_key_bindings(NULL, buf, sizeof(buf)); @@ -314,21 +357,39 @@ timer_check_key_bindings(mpd_unused gpointer data) process */ return FALSE; +#ifdef ENABLE_KEYDEF_SCREEN + g_strchomp(buf); + g_strlcat(buf, " (", sizeof(buf)); + /* to translators: a key was bound twice in the key editor, + and this is a hint for the user what to press to correct + that */ + g_snprintf(comment, sizeof(comment), _("press %s for the key editor"), + get_key_names(CMD_SCREEN_KEYDEF, 0)); + g_strlcat(buf, comment, sizeof(buf)); + g_strlcat(buf, ")", sizeof(buf)); +#endif + screen_status_printf("%s", buf); + doupdate(); return TRUE; } +#endif int main(int argc, const char *argv[]) { struct sigaction act; -#ifdef HAVE_LOCALE_H +#ifdef ENABLE_LOCALE const char *charset = NULL; #endif GIOChannel *keyboard_channel; +#ifdef ENABLE_LIRC + int lirc_socket; + GIOChannel *lirc_channel = NULL; +#endif -#ifdef HAVE_LOCALE_H +#ifdef ENABLE_LOCALE /* time and date formatting */ setlocale(LC_TIME,""); /* care about sorting order etc */ @@ -339,12 +400,15 @@ main(int argc, const char *argv[]) charset = charset_init(); /* initialize i18n support */ +#endif + #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR); +#ifdef ENABLE_LOCALE bind_textdomain_codeset(GETTEXT_PACKAGE, charset); - textdomain(GETTEXT_PACKAGE); #endif + textdomain(GETTEXT_PACKAGE); #endif /* initialize options */ @@ -353,11 +417,13 @@ main(int argc, const char *argv[]) /* parse command line options - 1 pass get configuration files */ options_parse(argc, argv); +#ifndef NCMPC_MINI /* read configuration */ - read_configuration(&options); + read_configuration(); /* check key bindings */ check_key_bindings(NULL, NULL, 0); +#endif /* parse command line options - 2 pass */ options_parse(argc, argv); @@ -372,8 +438,7 @@ main(int argc, const char *argv[]) } /* setup signal behavior - SIGTERM */ - sigemptyset(&act.sa_mask); - act.sa_flags = 0; + act.sa_handler = catch_sigint; if (sigaction(SIGTERM, &act, NULL) < 0) { perror("sigaction()"); @@ -381,8 +446,7 @@ main(int argc, const char *argv[]) } /* setup signal behavior - SIGCONT */ - sigemptyset(&act.sa_mask); - act.sa_flags = 0; + act.sa_handler = catch_sigcont; if (sigaction(SIGCONT, &act, NULL) < 0) { perror("sigaction(SIGCONT)"); @@ -390,8 +454,7 @@ main(int argc, const char *argv[]) } /* setup signal behaviour - SIGHUP*/ - sigemptyset(&act.sa_mask); - act.sa_flags = 0; + act.sa_handler = catch_sigint; if (sigaction(SIGHUP, &act, NULL) < 0) { perror("sigaction(SIGHUP)"); @@ -400,6 +463,7 @@ main(int argc, const char *argv[]) /* setup SIGWINCH */ + act.sa_flags = SA_RESTART; act.sa_handler = catch_sigwinch; if (sigaction(SIGWINCH, &act, NULL) < 0) { perror("sigaction(SIGWINCH)"); @@ -408,10 +472,9 @@ main(int argc, const char *argv[]) /* ignore SIGPIPE */ - act.sa_flags = SA_RESTART; act.sa_handler = SIG_IGN; - if (sigaction(SIGWINCH, &act, NULL) < 0) { - perror("sigaction(SIGWINCH)"); + if (sigaction(SIGPIPE, &act, NULL) < 0) { + perror("sigaction(SIGPIPE)"); exit(EXIT_FAILURE); } @@ -435,15 +498,28 @@ main(int argc, const char *argv[]) keyboard_channel = g_io_channel_unix_new(STDIN_FILENO); g_io_add_watch(keyboard_channel, G_IO_IN, keyboard_event, NULL); +#ifdef ENABLE_LIRC + /* watch out for lirc input */ + lirc_socket = ncmpc_lirc_open(); + 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 + /* attempt to connect */ reconnect_source_id = g_timeout_add(1, timer_reconnect, NULL); - update_source_id = g_timeout_add((guint)(MPD_UPDATE_TIME * 1000), + update_source_id = g_timeout_add(update_interval, timer_mpd_update, GINT_TO_POINTER(TRUE)); +#ifndef NCMPC_MINI g_timeout_add(10000, timer_check_key_bindings, NULL); +#endif idle_source_id = g_timeout_add(idle_interval, timer_idle, NULL); + screen_paint(mpd); + g_main_loop_run(main_loop); /* cleanup */ @@ -451,7 +527,18 @@ main(int argc, const char *argv[]) g_main_loop_unref(main_loop); g_io_channel_unref(keyboard_channel); +#ifdef ENABLE_LIRC + if (lirc_socket >= 0) + g_io_channel_unref(lirc_channel); + ncmpc_lirc_close(); +#endif + exit_and_cleanup(); + +#ifdef ENABLE_LYRICS_SCREEN + lyrics_deinit(); +#endif + ncu_deinit(); return 0;