diff --git a/src/main.c b/src/main.c
index 15ecf45322c7fba25a4d46e8d5951b8dc190dd43..6a6ba34f36bf4ff5c3b9ca8adfe3e8c414a10cfc 100644 (file)
--- a/src/main.c
+++ b/src/main.c
/*
- * (c) 2004 by Kalle Wallin (kaw@linux.se)
+ * $Id$
+ *
+ * (c) 2004 by Kalle Wallin <kaw@linux.se>
*
* 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
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
+#include <string.h>
+#include <ncurses.h>
#include <glib.h>
#include "config.h"
#include "ncmpc.h"
-#include "libmpdclient.h"
+#include "mpdclient.h"
#include "support.h"
-#include "mpc.h"
#include "options.h"
+#include "conf.h"
#include "command.h"
+#include "src_lyrics.h"
#include "screen.h"
-#include "conf.h"
+#include "screen_utils.h"
+#include "strfsong.h"
-static mpd_client_t *mpc = NULL;
-static GTimer *timer = NULL;
+#define BUFSIZE 1024
-void
+static mpdclient_t *mpd = NULL;
+static gboolean connected = FALSE;
+static GTimer *timer = NULL;
+
+static const gchar *
+error_msg(const gchar *msg)
+{
+ gchar *p;
+
+ if( (p=strchr(msg, '}' )) == NULL )
+ return msg;
+ while( p && *p && (*p=='}' || *p==' ') )
+ p++;
+
+ return p;
+}
+
+static void
+error_callback(mpdclient_t *c, gint error, const gchar *msg)
+{
+ gint code = GET_ACK_ERROR_CODE(error);
+
+ error = error & 0xFF;
+ D("Error [%d:%d]> \"%s\"\n", error, code, msg);
+ switch (error) {
+ case MPD_ERROR_CONNPORT:
+ case MPD_ERROR_NORESPONSE:
+ break;
+ case MPD_ERROR_ACK:
+ screen_status_printf("%s", error_msg(msg));
+ screen_bell();
+ break;
+ default:
+ screen_status_printf("%s", msg);
+ screen_bell();
+ doupdate();
+ connected = FALSE;
+ }
+}
+
+static void
+update_xterm_title(void)
+{
+ static char title[BUFSIZE];
+ char tmp[BUFSIZE];
+ mpd_Status *status = NULL;
+ mpd_Song *song = NULL;
+
+ if( mpd )
+ {
+ status = mpd->status;
+ song = mpd->song;
+ }
+
+ if(options.xterm_title_format && status && song && IS_PLAYING(status->state))
+ {
+ strfsong(tmp, BUFSIZE, options.xterm_title_format, song);
+ }
+ else
+ g_strlcpy(tmp, PACKAGE " version " VERSION, BUFSIZE);
+
+ if( strncmp(title,tmp,BUFSIZE) )
+ {
+ g_strlcpy(title, tmp, BUFSIZE);
+ set_xterm_title("%s", title);
+ }
+}
+
+static void
exit_and_cleanup(void)
{
screen_exit();
+ set_xterm_title("");
printf("\n");
- charset_close();
- if( mpc )
+ if( mpd )
{
- if( mpc_error(mpc) )
- fprintf(stderr,"Error: %s\n", mpc_error_str(mpc));
- mpc_close(mpc);
+ mpdclient_disconnect(mpd);
+ mpd = mpdclient_free(mpd);
}
g_free(options.host);
g_free(options.password);
+ g_free(options.list_format);
+ g_free(options.status_format);
+ g_free(options.scroll_sep);
if( timer )
g_timer_destroy(timer);
}
-void
+static void
catch_sigint( int sig )
{
- printf( _("\nExiting...\n"));
- exit(EXIT_SUCCESS);
+ printf("\n%s\n", _("Exiting..."));
+ exit(EXIT_SUCCESS);
}
-int
-main(int argc, const char *argv[])
-{
- options_t *options;
- struct sigaction act;
- gboolean connected;
- /* initialize i18n support */
-#ifdef ENABLE_NLS
- setlocale(LC_MESSAGES, "");
- bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
- textdomain(GETTEXT_PACKAGE);
+static void
+catch_sigcont( int sig )
+{
+ D("catch_sigcont()\n");
+#ifdef ENABLE_RAW_MODE
+ reset_prog_mode(); /* restore tty modes */
+ refresh();
#endif
+ screen_resize();
+}
- /* initialize options */
- options = options_init();
+void
+sigstop(void)
+{
+ def_prog_mode(); /* save the tty modes */
+ endwin(); /* end curses mode temporarily */
+ kill(0, SIGSTOP); /* issue SIGSTOP */
+}
- /* parse command line options - 1 pass get configuration files */
- options_parse(argc, argv);
-
- /* read configuration */
- read_configuration(options);
-
- /* check key bindings */
- if( check_key_bindings() )
+#ifndef NDEBUG
+void
+D(const char *format, ...)
+{
+ if( options.debug )
{
- fprintf(stderr, _("Confusing key bindings - exiting!\n"));
- exit(EXIT_FAILURE);
+ gchar *msg;
+ va_list ap;
+
+ va_start(ap,format);
+ msg = g_strdup_vprintf(format,ap);
+ va_end(ap);
+ fprintf(stderr, "%s", msg);
+ g_free(msg);
}
+}
+#endif
- /* parse command line options - 2 pass */
- options_parse(argc, argv);
+int
+main(int argc, const char *argv[])
+{
+ options_t *options;
+ struct sigaction act;
+ const char *charset = NULL;
+ gboolean key_error;
- /* initialize local charset */
- if( charset_init() )
- exit(EXIT_FAILURE);
+#ifdef HAVE_LOCALE_H
+ /* time and date formatting */
+ setlocale(LC_TIME,"");
+ /* care about sorting order etc */
+ setlocale(LC_COLLATE,"");
+ /* charset */
+ setlocale(LC_CTYPE,"");
+ /* initialize charset conversions */
+ charset_init(g_get_charset(&charset));
+ D("charset: %s\n", charset);
+#endif
- /* setup signal behavior - SIGINT */
- 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 */
- sigemptyset( &act.sa_mask );
- act.sa_flags = 0;
- act.sa_handler = catch_sigint;
- if( sigaction( SIGTERM, &act, NULL )<0 )
- {
- perror("sigaction()");
- exit(EXIT_FAILURE);
- }
+ /* initialize i18n support */
+#ifdef ENABLE_NLS
+ setlocale(LC_MESSAGES, "");
+ bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
+ bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
+ textdomain(GETTEXT_PACKAGE);
+#endif
- /* set xterm title */
- if( g_getenv("DISPLAY") )
- printf("%c]0;%s%c", '\033', PACKAGE " version " VERSION, '\007');
+ /* initialize options */
+ options = options_init();
- /* install exit function */
- atexit(exit_and_cleanup);
+ /* parse command line options - 1 pass get configuration files */
+ options_parse(argc, argv);
- /* connect to our music player daemon */
- mpc = mpc_connect(options->host, options->port, options->password);
- if( mpc_error(mpc) )
- exit(EXIT_FAILURE);
+ /* read configuration */
+ read_configuration(options);
- /* initialize curses */
- screen_init();
+ /* check key bindings */
+ key_error = check_key_bindings(NULL, NULL, 0);
- /* initialize timer */
- timer = g_timer_new();
+ /* parse command line options - 2 pass */
+ options_parse(argc, argv);
- connected = TRUE;
- while( connected || options->reconnect )
- {
- static gdouble t = G_MAXDOUBLE;
-
- if( connected && t>=MPD_UPDATE_TIME )
- {
- mpc_update(mpc);
- if( mpc_error(mpc) == MPD_ERROR_ACK )
- {
- screen_status_printf("%s", mpc_error_str(mpc));
- mpd_clearError(mpc->connection);
- mpd_finishCommand(mpc->connection);
- }
- else if( mpc_error(mpc) )
- {
- screen_status_printf(_("Lost connection to %s"), options->host);
- connected = FALSE;
- doupdate();
- mpd_clearError(mpc->connection);
- mpd_closeConnection(mpc->connection);
- mpc->connection = NULL;
- }
- else
- mpd_finishCommand(mpc->connection);
- g_timer_start(timer);
+ /* setup signal behavior - SIGINT */
+ sigemptyset( &act.sa_mask );
+ act.sa_flags = 0;
+ act.sa_handler = catch_sigint;
+ if( sigaction(SIGINT, &act, NULL)<0 ) {
+ perror("signal");
+ exit(EXIT_FAILURE);
}
- if( connected )
- {
- command_t cmd;
-
- screen_update(mpc);
- if( (cmd=get_keyboard_command()) != CMD_NONE )
- {
- screen_cmd(mpc, cmd);
- if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
- /* make shure we dont update the volume yet */
- g_timer_start(timer);
- }
- else
- screen_idle(mpc);
+ /* 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()");
+ exit(EXIT_FAILURE);
}
- else if( options->reconnect )
- {
- sleep(MPD_RECONNECT_TIMEOUT);
- screen_status_printf(_("Connecting to %s... [Press Ctrl-C to abort]"),
- options->host);
- if( mpc_reconnect(mpc,
- options->host,
- options->port,
- options->password) == 0 )
- {
- screen_status_printf(_("Connected to %s!"), options->host);
- connected = TRUE;
- }
- doupdate();
+
+ /* 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)");
+ exit(EXIT_FAILURE);
}
- t = g_timer_elapsed(timer, NULL);
- }
+ /* 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)");
+ exit(EXIT_FAILURE);
+ }
+
+ /* install exit function */
+ atexit(exit_and_cleanup);
+
+ ncurses_init();
+
+ src_lyr_init ();
+
+ /* connect to our music player daemon */
+ mpd = mpdclient_new();
+
+ if (mpdclient_connect(mpd,
+ options->host,
+ options->port,
+ 10.0,
+ options->password))
+ exit(EXIT_FAILURE);
- exit(EXIT_FAILURE);
+ /* if no password is used, but the mpd wants one, the connection
+ might be established but no status information is avaiable */
+ mpdclient_update(mpd);
+ if (!mpd->status)
+ screen_auth(mpd);
+
+ if (!mpd->status)
+ exit(EXIT_FAILURE);
+
+ connected = TRUE;
+ D("Connected to MPD version %d.%d.%d\n",
+ mpd->connection->version[0],
+ mpd->connection->version[1],
+ mpd->connection->version[2]);
+
+ /* quit if mpd is pre 0.11.0 - song id not supported by mpd */
+ if( MPD_VERSION_LT(mpd, 0,11,0) ) {
+ fprintf(stderr,
+ _("Error: MPD version %d.%d.%d is to old (0.11.0 needed).\n"),
+ mpd->connection->version[0],
+ mpd->connection->version[1],
+ mpd->connection->version[2]);
+ exit(EXIT_FAILURE);
+ }
+
+ /* initialize curses */
+ screen_init(mpd);
+ /* install error callback function */
+ mpdclient_install_error_callback(mpd, error_callback);
+
+ /* initialize timer */
+ timer = g_timer_new();
+
+ connected = TRUE;
+ while (connected || options->reconnect) {
+ static gdouble t = G_MAXDOUBLE;
+
+ if( key_error ) {
+ char buf[BUFSIZE];
+
+ key_error=check_key_bindings(NULL, buf, BUFSIZE);
+ screen_status_printf("%s", buf);
+ }
+
+ if( connected && (t>=MPD_UPDATE_TIME || mpd->need_update) ) {
+ mpdclient_update(mpd);
+ g_timer_start(timer);
+ }
+
+ if( connected ) {
+ command_t cmd;
+
+ screen_update(mpd);
+ if( (cmd=get_keyboard_command()) != CMD_NONE )
+ {
+ screen_cmd(mpd, cmd);
+ if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
+ /* make shure we dont update the volume yet */
+ g_timer_start(timer);
+ }
+ else
+ screen_idle(mpd);
+ } else if (options->reconnect) {
+ screen_status_printf(_("Connecting to %s... [Press %s to abort]"),
+ options->host, get_key_names(CMD_QUIT,0) );
+
+ if( get_keyboard_command_with_timeout(MPD_RECONNECT_TIME)==CMD_QUIT)
+ exit(EXIT_SUCCESS);
+
+ if (mpdclient_connect(mpd,
+ options->host, options->port,
+ 1.5,
+ options->password) == 0) {
+ screen_status_printf(_("Connected to %s!"), options->host);
+ connected = TRUE;
+ }
+
+ doupdate();
+ }
+
+ if (options->enable_xterm_title)
+ update_xterm_title();
+
+ t = g_timer_elapsed(timer, NULL);
+ }
+ exit(EXIT_FAILURE);
}
+